1 import { Op, QueryTypes } from 'sequelize'
2 import { BelongsTo, Column, CreatedAt, ForeignKey, Model, Scopes, Table, UpdatedAt } from 'sequelize-typescript'
3 import { MServerBlocklist, MServerBlocklistAccountServer, MServerBlocklistFormattable } from '@server/types/models'
4 import { ServerBlock } from '@shared/models'
5 import { AttributesOnly } from '@shared/typescript-utils'
6 import { AccountModel } from '../account/account'
7 import { createSafeIn, getSort, searchAttribute } from '../shared'
8 import { ServerModel } from './server'
11 WITH_ACCOUNT = 'WITH_ACCOUNT',
12 WITH_SERVER = 'WITH_SERVER'
16 [ScopeNames.WITH_ACCOUNT]: {
24 [ScopeNames.WITH_SERVER]: {
35 tableName: 'serverBlocklist',
38 fields: [ 'accountId', 'targetServerId' ],
42 fields: [ 'targetServerId' ]
46 export class ServerBlocklistModel extends Model<Partial<AttributesOnly<ServerBlocklistModel>>> {
54 @ForeignKey(() => AccountModel)
58 @BelongsTo(() => AccountModel, {
65 ByAccount: AccountModel
67 @ForeignKey(() => ServerModel)
69 targetServerId: number
71 @BelongsTo(() => ServerModel, {
77 BlockedServer: ServerModel
79 static isServerMutedByAccounts (accountIds: number[], targetServerId: number) {
81 attributes: [ 'accountId', 'id' ],
91 return ServerBlocklistModel.unscoped()
94 const result: { [accountId: number]: boolean } = {}
96 for (const accountId of accountIds) {
97 result[accountId] = !!rows.find(r => r.accountId === accountId)
104 static loadByAccountAndHost (accountId: number, host: string): Promise<MServerBlocklist> {
120 return ServerBlocklistModel.findOne(query)
123 static listHostsBlockedBy (accountIds: number[]): Promise<string[]> {
133 attributes: [ 'host' ],
134 model: ServerModel.unscoped(),
140 return ServerBlocklistModel.findAll(query)
141 .then(entries => entries.map(e => e.BlockedServer.host))
144 static getBlockStatus (byAccountIds: number[], hosts: string[]): Promise<{ host: string, accountId: number }[]> {
145 const rawQuery = `SELECT "server"."host", "serverBlocklist"."accountId" ` +
146 `FROM "serverBlocklist" ` +
147 `INNER JOIN "server" ON "server"."id" = "serverBlocklist"."targetServerId" ` +
148 `WHERE "server"."host" IN (:hosts) ` +
149 `AND "serverBlocklist"."accountId" IN (${createSafeIn(ServerBlocklistModel.sequelize, byAccountIds)})`
151 return ServerBlocklistModel.sequelize.query(rawQuery, {
152 type: QueryTypes.SELECT as QueryTypes.SELECT,
153 replacements: { hosts }
157 static listForApi (parameters: {
164 const { start, count, sort, search, accountId } = parameters
169 order: getSort(sort),
173 ...searchAttribute(search, '$BlockedServer.host$')
178 ServerBlocklistModel.scope(ScopeNames.WITH_SERVER).count(query),
179 ServerBlocklistModel.scope([ ScopeNames.WITH_ACCOUNT, ScopeNames.WITH_SERVER ]).findAll<MServerBlocklistAccountServer>(query)
180 ]).then(([ total, data ]) => ({ total, data }))
183 toFormattedJSON (this: MServerBlocklistFormattable): ServerBlock {
185 byAccount: this.ByAccount.toFormattedJSON(),
186 blockedServer: this.BlockedServer.toFormattedJSON(),
187 createdAt: this.createdAt