b26395fd4baeb7a58ee69c3601ee0147e924f10e
[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   DataType,
9   Default,
10   ForeignKey,
11   HasMany,
12   Is,
13   IsUUID,
14   Model,
15   Table,
16   UpdatedAt
17 } from 'sequelize-typescript'
18 import { isUserUsernameValid } from '../../helpers/custom-validators/users'
19 import { sendDeleteAccount } from '../../lib/activitypub/send'
20 import { ActorModel } from '../activitypub/actor'
21 import { ApplicationModel } from '../application/application'
22 import { ServerModel } from '../server/server'
23 import { throwIfNotValid } from '../utils'
24 import { VideoChannelModel } from '../video/video-channel'
25 import { UserModel } from './user'
26
27 @Table({
28   tableName: 'account',
29   indexes: [
30     {
31       fields: [ 'name' ]
32     },
33     {
34       fields: [ 'serverId' ]
35     },
36     {
37       fields: [ 'userId' ],
38       unique: true
39     },
40     {
41       fields: [ 'applicationId' ],
42       unique: true
43     },
44     {
45       fields: [ 'name', 'serverId', 'applicationId' ],
46       unique: true
47     }
48   ]
49 })
50 export class AccountModel extends Model<AccountModel> {
51
52   @CreatedAt
53   createdAt: Date
54
55   @UpdatedAt
56   updatedAt: Date
57
58   @ForeignKey(() => ActorModel)
59   @Column
60   actorId: number
61
62   @BelongsTo(() => ActorModel, {
63     foreignKey: {
64       allowNull: false
65     },
66     onDelete: 'cascade'
67   })
68   Actor: ActorModel
69
70   @ForeignKey(() => UserModel)
71   @Column
72   userId: number
73
74   @BelongsTo(() => UserModel, {
75     foreignKey: {
76       allowNull: true
77     },
78     onDelete: 'cascade'
79   })
80   User: UserModel
81
82   @ForeignKey(() => ApplicationModel)
83   @Column
84   applicationId: number
85
86   @BelongsTo(() => ApplicationModel, {
87     foreignKey: {
88       allowNull: true
89     },
90     onDelete: 'cascade'
91   })
92   Application: ApplicationModel
93
94   @HasMany(() => VideoChannelModel, {
95     foreignKey: {
96       allowNull: false
97     },
98     onDelete: 'cascade',
99     hooks: true
100   })
101   VideoChannels: VideoChannelModel[]
102
103   @AfterDestroy
104   static sendDeleteIfOwned (instance: AccountModel) {
105     if (instance.isOwned()) {
106       return sendDeleteAccount(instance, undefined)
107     }
108
109     return undefined
110   }
111
112   static loadApplication () {
113     return AccountModel.findOne({
114       include: [
115         {
116           model: ApplicationModel,
117           required: true
118         }
119       ]
120     })
121   }
122
123   static load (id: number) {
124     return AccountModel.findById(id)
125   }
126
127   static loadByUUID (uuid: string) {
128     const query = {
129       where: {
130         uuid
131       }
132     }
133
134     return AccountModel.findOne(query)
135   }
136
137   static loadLocalByName (name: string) {
138     const query = {
139       where: {
140         name,
141         [ Sequelize.Op.or ]: [
142           {
143             userId: {
144               [ Sequelize.Op.ne ]: null
145             }
146           },
147           {
148             applicationId: {
149               [ Sequelize.Op.ne ]: null
150             }
151           }
152         ]
153       }
154     }
155
156     return AccountModel.findOne(query)
157   }
158
159   static loadByNameAndHost (name: string, host: string) {
160     const query = {
161       where: {
162         name
163       },
164       include: [
165         {
166           model: ServerModel,
167           required: true,
168           where: {
169             host
170           }
171         }
172       ]
173     }
174
175     return AccountModel.findOne(query)
176   }
177
178   static loadByUrl (url: string, transaction?: Sequelize.Transaction) {
179     const query = {
180       include: [
181         {
182           model: ActorModel,
183           required: true,
184           where: {
185             url
186           }
187         }
188       ],
189       transaction
190     }
191
192     return AccountModel.findOne(query)
193   }
194
195   static listByFollowersUrls (followersUrls: string[], transaction?: Sequelize.Transaction) {
196     const query = {
197       include: [
198         {
199           model: ActorModel,
200           required: true,
201           where: {
202             followersUrl: {
203               [ Sequelize.Op.in ]: followersUrls
204             }
205           }
206         }
207       ],
208       transaction
209     }
210
211     return AccountModel.findAll(query)
212   }
213
214   toFormattedJSON () {
215     const actor = this.Actor.toFormattedJSON()
216     const account = {
217       id: this.id,
218       createdAt: this.createdAt,
219       updatedAt: this.updatedAt
220     }
221
222     return Object.assign(actor, account)
223   }
224
225   toActivityPubObject () {
226     return this.Actor.toActivityPubObject(this.name, this.uuid, 'Account')
227   }
228
229   isOwned () {
230     return this.Actor.isOwned()
231   }
232 }