d8a7ce4b4a5a6f26e62fbd91322e2a6d512f4b2c
[oweals/peertube.git] / server / models / account / account-blocklist.ts
1 import { BelongsTo, Column, CreatedAt, ForeignKey, Model, Scopes, Table, UpdatedAt } from 'sequelize-typescript'
2 import { AccountModel } from './account'
3 import { getSort, searchAttribute } from '../utils'
4 import { AccountBlock } from '../../../shared/models/blocklist'
5 import { Op } from 'sequelize'
6 import * as Bluebird from 'bluebird'
7 import { MAccountBlocklist, MAccountBlocklistAccounts, MAccountBlocklistFormattable } from '@server/typings/models'
8
9 enum ScopeNames {
10   WITH_ACCOUNTS = 'WITH_ACCOUNTS'
11 }
12
13 @Scopes(() => ({
14   [ScopeNames.WITH_ACCOUNTS]: {
15     include: [
16       {
17         model: AccountModel,
18         required: true,
19         as: 'ByAccount'
20       },
21       {
22         model: AccountModel,
23         required: true,
24         as: 'BlockedAccount'
25       }
26     ]
27   }
28 }))
29
30 @Table({
31   tableName: 'accountBlocklist',
32   indexes: [
33     {
34       fields: [ 'accountId', 'targetAccountId' ],
35       unique: true
36     },
37     {
38       fields: [ 'targetAccountId' ]
39     }
40   ]
41 })
42 export class AccountBlocklistModel extends Model<AccountBlocklistModel> {
43
44   @CreatedAt
45   createdAt: Date
46
47   @UpdatedAt
48   updatedAt: Date
49
50   @ForeignKey(() => AccountModel)
51   @Column
52   accountId: number
53
54   @BelongsTo(() => AccountModel, {
55     foreignKey: {
56       name: 'accountId',
57       allowNull: false
58     },
59     as: 'ByAccount',
60     onDelete: 'CASCADE'
61   })
62   ByAccount: AccountModel
63
64   @ForeignKey(() => AccountModel)
65   @Column
66   targetAccountId: number
67
68   @BelongsTo(() => AccountModel, {
69     foreignKey: {
70       name: 'targetAccountId',
71       allowNull: false
72     },
73     as: 'BlockedAccount',
74     onDelete: 'CASCADE'
75   })
76   BlockedAccount: AccountModel
77
78   static isAccountMutedByMulti (accountIds: number[], targetAccountId: number) {
79     const query = {
80       attributes: [ 'accountId', 'id' ],
81       where: {
82         accountId: {
83           [Op.in]: accountIds
84         },
85         targetAccountId
86       },
87       raw: true
88     }
89
90     return AccountBlocklistModel.unscoped()
91                                 .findAll(query)
92                                 .then(rows => {
93                                   const result: { [accountId: number]: boolean } = {}
94
95                                   for (const accountId of accountIds) {
96                                     result[accountId] = !!rows.find(r => r.accountId === accountId)
97                                   }
98
99                                   return result
100                                 })
101   }
102
103   static loadByAccountAndTarget (accountId: number, targetAccountId: number): Bluebird<MAccountBlocklist> {
104     const query = {
105       where: {
106         accountId,
107         targetAccountId
108       }
109     }
110
111     return AccountBlocklistModel.findOne(query)
112   }
113
114   static listForApi (parameters: {
115     start: number
116     count: number
117     sort: string
118     search?: string
119     accountId: number
120   }) {
121     const { start, count, sort, search, accountId } = parameters
122
123     const query = {
124       offset: start,
125       limit: count,
126       order: getSort(sort)
127     }
128
129     const where = {
130       accountId
131     }
132
133     if (search) {
134       Object.assign(where, {
135         [Op.or]: [
136           searchAttribute(search, '$BlockedAccount.name$'),
137           searchAttribute(search, '$BlockedAccount.Actor.url$')
138         ]
139       })
140     }
141
142     Object.assign(query, { where })
143
144     return AccountBlocklistModel
145       .scope([ ScopeNames.WITH_ACCOUNTS ])
146       .findAndCountAll<MAccountBlocklistAccounts>(query)
147       .then(({ rows, count }) => {
148         return { total: count, data: rows }
149       })
150   }
151
152   toFormattedJSON (this: MAccountBlocklistFormattable): AccountBlock {
153     return {
154       byAccount: this.ByAccount.toFormattedJSON(),
155       blockedAccount: this.BlockedAccount.toFormattedJSON(),
156       createdAt: this.createdAt
157     }
158   }
159 }