Begin moving video channel to actor
[oweals/peertube.git] / server / models / account / account.ts
1 import * as Sequelize from 'sequelize'
2 import {
3   AfterDestroy,
4   AllowNull,
5   BelongsTo,
6   Column,
7   CreatedAt,
8   DefaultScope,
9   ForeignKey,
10   HasMany,
11   Is,
12   Model,
13   Table,
14   UpdatedAt
15 } from 'sequelize-typescript'
16 import { isUserUsernameValid } from '../../helpers/custom-validators/users'
17 import { sendDeleteActor } from '../../lib/activitypub/send'
18 import { ActorModel } from '../activitypub/actor'
19 import { ApplicationModel } from '../application/application'
20 import { ServerModel } from '../server/server'
21 import { throwIfNotValid } from '../utils'
22 import { VideoChannelModel } from '../video/video-channel'
23 import { UserModel } from './user'
24
25 @DefaultScope({
26   include: [
27     {
28       model: () => ActorModel,
29       required: true,
30       include: [
31         {
32           model: () => ServerModel,
33           required: false
34         }
35       ]
36     }
37   ]
38 })
39 @Table({
40   tableName: 'account'
41 })
42 export class AccountModel extends Model<AccountModel> {
43
44   @AllowNull(false)
45   @Is('AccountName', value => throwIfNotValid(value, isUserUsernameValid, 'account name'))
46   @Column
47   name: string
48
49   @CreatedAt
50   createdAt: Date
51
52   @UpdatedAt
53   updatedAt: Date
54
55   @ForeignKey(() => ActorModel)
56   @Column
57   actorId: number
58
59   @BelongsTo(() => ActorModel, {
60     foreignKey: {
61       allowNull: false
62     },
63     onDelete: 'cascade'
64   })
65   Actor: ActorModel
66
67   @ForeignKey(() => UserModel)
68   @Column
69   userId: number
70
71   @BelongsTo(() => UserModel, {
72     foreignKey: {
73       allowNull: true
74     },
75     onDelete: 'cascade'
76   })
77   User: UserModel
78
79   @ForeignKey(() => ApplicationModel)
80   @Column
81   applicationId: number
82
83   @BelongsTo(() => ApplicationModel, {
84     foreignKey: {
85       allowNull: true
86     },
87     onDelete: 'cascade'
88   })
89   Account: ApplicationModel
90
91   @HasMany(() => VideoChannelModel, {
92     foreignKey: {
93       allowNull: false
94     },
95     onDelete: 'cascade',
96     hooks: true
97   })
98   VideoChannels: VideoChannelModel[]
99
100   @AfterDestroy
101   static sendDeleteIfOwned (instance: AccountModel) {
102     if (instance.isOwned()) {
103       return sendDeleteActor(instance.Actor, undefined)
104     }
105
106     return undefined
107   }
108
109   static load (id: number) {
110     return AccountModel.findById(id)
111   }
112
113   static loadByUUID (uuid: string) {
114     const query = {
115       include: [
116         {
117           model: ActorModel,
118           required: true,
119           where: {
120             uuid
121           }
122         }
123       ]
124     }
125
126     return AccountModel.findOne(query)
127   }
128
129   static loadLocalByName (name: string) {
130     const query = {
131       where: {
132         name,
133         [ Sequelize.Op.or ]: [
134           {
135             userId: {
136               [ Sequelize.Op.ne ]: null
137             }
138           },
139           {
140             applicationId: {
141               [ Sequelize.Op.ne ]: null
142             }
143           }
144         ]
145       }
146     }
147
148     return AccountModel.findOne(query)
149   }
150
151   static loadByUrl (url: string, transaction?: Sequelize.Transaction) {
152     const query = {
153       include: [
154         {
155           model: ActorModel,
156           required: true,
157           where: {
158             url
159           }
160         }
161       ],
162       transaction
163     }
164
165     return AccountModel.findOne(query)
166   }
167
168   toFormattedJSON () {
169     const actor = this.Actor.toFormattedJSON()
170     const account = {
171       id: this.id,
172       name: this.name,
173       createdAt: this.createdAt,
174       updatedAt: this.updatedAt
175     }
176
177     return Object.assign(actor, account)
178   }
179
180   toActivityPubObject () {
181     return this.Actor.toActivityPubObject(this.name, 'Account')
182   }
183
184   isOwned () {
185     return this.Actor.isOwned()
186   }
187 }