]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blob - server/models/account/account.ts
07539a04eb561e640291dfa971ee862a8ecc8eed
[github/Chocobozzz/PeerTube.git] / server / models / account / account.ts
1 import * as Sequelize from 'sequelize'
2 import {
3 AllowNull,
4 BeforeDestroy,
5 BelongsTo,
6 Column,
7 CreatedAt,
8 Default,
9 DefaultScope,
10 ForeignKey,
11 HasMany,
12 Is,
13 Model,
14 Table,
15 UpdatedAt
16 } from 'sequelize-typescript'
17 import { Account } from '../../../shared/models/actors'
18 import { isAccountDescriptionValid } from '../../helpers/custom-validators/accounts'
19 import { sendDeleteActor } from '../../lib/activitypub/send'
20 import { ActorModel } from '../activitypub/actor'
21 import { ApplicationModel } from '../application/application'
22 import { AvatarModel } from '../avatar/avatar'
23 import { ServerModel } from '../server/server'
24 import { getSort, throwIfNotValid } from '../utils'
25 import { VideoChannelModel } from '../video/video-channel'
26 import { VideoCommentModel } from '../video/video-comment'
27 import { UserModel } from './user'
28
29 @DefaultScope({
30 include: [
31 {
32 model: () => ActorModel,
33 required: true,
34 include: [
35 {
36 model: () => ServerModel,
37 required: false
38 },
39 {
40 model: () => AvatarModel,
41 required: false
42 }
43 ]
44 }
45 ]
46 })
47 @Table({
48 tableName: 'account',
49 indexes: [
50 {
51 fields: [ 'actorId' ],
52 unique: true
53 },
54 {
55 fields: [ 'applicationId' ]
56 },
57 {
58 fields: [ 'userId' ]
59 }
60 ]
61 })
62 export class AccountModel extends Model<AccountModel> {
63
64 @AllowNull(false)
65 @Column
66 name: string
67
68 @AllowNull(true)
69 @Default(null)
70 @Is('AccountDescription', value => throwIfNotValid(value, isAccountDescriptionValid, 'description'))
71 @Column
72 description: string
73
74 @CreatedAt
75 createdAt: Date
76
77 @UpdatedAt
78 updatedAt: Date
79
80 @ForeignKey(() => ActorModel)
81 @Column
82 actorId: number
83
84 @BelongsTo(() => ActorModel, {
85 foreignKey: {
86 allowNull: false
87 },
88 onDelete: 'cascade'
89 })
90 Actor: ActorModel
91
92 @ForeignKey(() => UserModel)
93 @Column
94 userId: number
95
96 @BelongsTo(() => UserModel, {
97 foreignKey: {
98 allowNull: true
99 },
100 onDelete: 'cascade'
101 })
102 User: UserModel
103
104 @ForeignKey(() => ApplicationModel)
105 @Column
106 applicationId: number
107
108 @BelongsTo(() => ApplicationModel, {
109 foreignKey: {
110 allowNull: true
111 },
112 onDelete: 'cascade'
113 })
114 Application: ApplicationModel
115
116 @HasMany(() => VideoChannelModel, {
117 foreignKey: {
118 allowNull: false
119 },
120 onDelete: 'cascade',
121 hooks: true
122 })
123 VideoChannels: VideoChannelModel[]
124
125 @HasMany(() => VideoCommentModel, {
126 foreignKey: {
127 allowNull: false
128 },
129 onDelete: 'cascade',
130 hooks: true
131 })
132 VideoComments: VideoCommentModel[]
133
134 @BeforeDestroy
135 static async sendDeleteIfOwned (instance: AccountModel, options) {
136 if (!instance.Actor) {
137 instance.Actor = await instance.$get('Actor', { transaction: options.transaction }) as ActorModel
138 }
139
140 if (instance.isOwned()) {
141 return sendDeleteActor(instance.Actor, options.transaction)
142 }
143
144 return undefined
145 }
146
147 static load (id: number) {
148 return AccountModel.findById(id)
149 }
150
151 static loadByUUID (uuid: string) {
152 const query = {
153 include: [
154 {
155 model: ActorModel,
156 required: true,
157 where: {
158 uuid
159 }
160 }
161 ]
162 }
163
164 return AccountModel.findOne(query)
165 }
166
167 static loadLocalByName (name: string) {
168 const query = {
169 where: {
170 [ Sequelize.Op.or ]: [
171 {
172 userId: {
173 [ Sequelize.Op.ne ]: null
174 }
175 },
176 {
177 applicationId: {
178 [ Sequelize.Op.ne ]: null
179 }
180 }
181 ]
182 },
183 include: [
184 {
185 model: ActorModel,
186 required: true,
187 where: {
188 preferredUsername: name
189 }
190 }
191 ]
192 }
193
194 return AccountModel.findOne(query)
195 }
196
197 static loadByNameAndHost (name: string, host: string) {
198 const query = {
199 include: [
200 {
201 model: ActorModel,
202 required: true,
203 where: {
204 preferredUsername: name
205 },
206 include: [
207 {
208 model: ServerModel,
209 required: true,
210 where: {
211 host
212 }
213 }
214 ]
215 }
216 ]
217 }
218
219 return AccountModel.findOne(query)
220 }
221
222 static loadByUrl (url: string, transaction?: Sequelize.Transaction) {
223 const query = {
224 include: [
225 {
226 model: ActorModel,
227 required: true,
228 where: {
229 url
230 }
231 }
232 ],
233 transaction
234 }
235
236 return AccountModel.findOne(query)
237 }
238
239 static listForApi (start: number, count: number, sort: string) {
240 const query = {
241 offset: start,
242 limit: count,
243 order: getSort(sort)
244 }
245
246 return AccountModel.findAndCountAll(query)
247 .then(({ rows, count }) => {
248 return {
249 data: rows,
250 total: count
251 }
252 })
253 }
254
255 toFormattedJSON (): Account {
256 const actor = this.Actor.toFormattedJSON()
257 const account = {
258 id: this.id,
259 displayName: this.getDisplayName(),
260 description: this.description,
261 createdAt: this.createdAt,
262 updatedAt: this.updatedAt
263 }
264
265 return Object.assign(actor, account)
266 }
267
268 toActivityPubObject () {
269 const obj = this.Actor.toActivityPubObject(this.name, 'Account')
270
271 return Object.assign(obj, {
272 summary: this.description
273 })
274 }
275
276 isOwned () {
277 return this.Actor.isOwned()
278 }
279
280 getDisplayName () {
281 return this.name
282 }
283 }