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