Avoid too many requests and fetching outbox
[oweals/peertube.git] / server / models / account / account.ts
index b26395fd4baeb7a58ee69c3601ee0147e924f10e..20724ae0c16cdb5fc671cc17f7a59a0599b47502 100644 (file)
@@ -1,54 +1,47 @@
 import * as Sequelize from 'sequelize'
 import {
-  AfterDestroy,
-  AllowNull,
-  BelongsTo,
-  Column,
-  CreatedAt,
-  DataType,
-  Default,
-  ForeignKey,
-  HasMany,
-  Is,
-  IsUUID,
-  Model,
-  Table,
+  AllowNull, BeforeDestroy, BelongsTo, Column, CreatedAt, DefaultScope, ForeignKey, HasMany, Model, Table,
   UpdatedAt
 } from 'sequelize-typescript'
-import { isUserUsernameValid } from '../../helpers/custom-validators/users'
-import { sendDeleteAccount } from '../../lib/activitypub/send'
+import { Account } from '../../../shared/models/actors'
+import { logger } from '../../helpers/logger'
+import { sendDeleteActor } from '../../lib/activitypub/send'
 import { ActorModel } from '../activitypub/actor'
 import { ApplicationModel } from '../application/application'
+import { AvatarModel } from '../avatar/avatar'
 import { ServerModel } from '../server/server'
-import { throwIfNotValid } from '../utils'
+import { getSort } from '../utils'
 import { VideoChannelModel } from '../video/video-channel'
+import { VideoCommentModel } from '../video/video-comment'
 import { UserModel } from './user'
 
-@Table({
-  tableName: 'account',
-  indexes: [
-    {
-      fields: [ 'name' ]
-    },
-    {
-      fields: [ 'serverId' ]
-    },
-    {
-      fields: [ 'userId' ],
-      unique: true
-    },
-    {
-      fields: [ 'applicationId' ],
-      unique: true
-    },
+@DefaultScope({
+  include: [
     {
-      fields: [ 'name', 'serverId', 'applicationId' ],
-      unique: true
+      model: () => ActorModel,
+      required: true,
+      include: [
+        {
+          model: () => ServerModel,
+          required: false
+        },
+        {
+          model: () => AvatarModel,
+          required: false
+        }
+      ]
     }
   ]
 })
+@Table({
+  tableName: 'account'
+})
 export class AccountModel extends Model<AccountModel> {
 
+  @AllowNull(false)
+  @Column
+  name: string
+
   @CreatedAt
   createdAt: Date
 
@@ -100,35 +93,44 @@ export class AccountModel extends Model<AccountModel> {
   })
   VideoChannels: VideoChannelModel[]
 
-  @AfterDestroy
-  static sendDeleteIfOwned (instance: AccountModel) {
+  @HasMany(() => VideoCommentModel, {
+    foreignKey: {
+      allowNull: false
+    },
+    onDelete: 'cascade',
+    hooks: true
+  })
+  VideoComments: VideoCommentModel[]
+
+  @BeforeDestroy
+  static async sendDeleteIfOwned (instance: AccountModel, options) {
+    if (!instance.Actor) {
+      instance.Actor = await instance.$get('Actor', { transaction: options.transaction }) as ActorModel
+    }
+
     if (instance.isOwned()) {
-      return sendDeleteAccount(instance, undefined)
+      logger.debug('Sending delete of actor of account %s.', instance.Actor.url)
+      return sendDeleteActor(instance.Actor, options.transaction)
     }
 
     return undefined
   }
 
-  static loadApplication () {
-    return AccountModel.findOne({
-      include: [
-        {
-          model: ApplicationModel,
-          required: true
-        }
-      ]
-    })
-  }
-
   static load (id: number) {
     return AccountModel.findById(id)
   }
 
   static loadByUUID (uuid: string) {
     const query = {
-      where: {
-        uuid
-      }
+      include: [
+        {
+          model: ActorModel,
+          required: true,
+          where: {
+            uuid
+          }
+        }
+      ]
     }
 
     return AccountModel.findOne(query)
@@ -156,25 +158,6 @@ export class AccountModel extends Model<AccountModel> {
     return AccountModel.findOne(query)
   }
 
-  static loadByNameAndHost (name: string, host: string) {
-    const query = {
-      where: {
-        name
-      },
-      include: [
-        {
-          model: ServerModel,
-          required: true,
-          where: {
-            host
-          }
-        }
-      ]
-    }
-
-    return AccountModel.findOne(query)
-  }
-
   static loadByUrl (url: string, transaction?: Sequelize.Transaction) {
     const query = {
       include: [
@@ -192,29 +175,27 @@ export class AccountModel extends Model<AccountModel> {
     return AccountModel.findOne(query)
   }
 
-  static listByFollowersUrls (followersUrls: string[], transaction?: Sequelize.Transaction) {
+  static listForApi (start: number, count: number, sort: string) {
     const query = {
-      include: [
-        {
-          model: ActorModel,
-          required: true,
-          where: {
-            followersUrl: {
-              [ Sequelize.Op.in ]: followersUrls
-            }
-          }
-        }
-      ],
-      transaction
+      offset: start,
+      limit: count,
+      order: [ getSort(sort) ]
     }
 
-    return AccountModel.findAll(query)
+    return AccountModel.findAndCountAll(query)
+      .then(({ rows, count }) => {
+        return {
+          data: rows,
+          total: count
+        }
+      })
   }
 
-  toFormattedJSON () {
+  toFormattedJSON (): Account {
     const actor = this.Actor.toFormattedJSON()
     const account = {
       id: this.id,
+      displayName: this.name,
       createdAt: this.createdAt,
       updatedAt: this.updatedAt
     }
@@ -223,7 +204,7 @@ export class AccountModel extends Model<AccountModel> {
   }
 
   toActivityPubObject () {
-    return this.Actor.toActivityPubObject(this.name, this.uuid, 'Account')
+    return this.Actor.toActivityPubObject(this.name, 'Account')
   }
 
   isOwned () {