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