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