X-Git-Url: https://git.immae.eu/?a=blobdiff_plain;f=server%2Fmodels%2Faccount%2Faccount.ts;h=396959352c3792b9bae35f80f9e68e475e9f1cf7;hb=HEAD;hp=312451abeb1d6e48ce03b2f9796f450d15e911df;hpb=f479685678406a5df864d89615b33d29085ebfc6;p=github%2FChocobozzz%2FPeerTube.git diff --git a/server/models/account/account.ts b/server/models/account/account.ts index 312451abe..396959352 100644 --- a/server/models/account/account.ts +++ b/server/models/account/account.ts @@ -16,33 +16,35 @@ import { Table, UpdatedAt } from 'sequelize-typescript' -import { ModelCache } from '@server/models/model-cache' +import { ModelCache } from '@server/models/shared/model-cache' +import { AttributesOnly } from '@shared/typescript-utils' import { Account, AccountSummary } from '../../../shared/models/actors' import { isAccountDescriptionValid } from '../../helpers/custom-validators/accounts' import { CONSTRAINTS_FIELDS, SERVER_ACTOR_NAME, WEBSERVER } from '../../initializers/constants' -import { sendDeleteActor } from '../../lib/activitypub/send' +import { sendDeleteActor } from '../../lib/activitypub/send/send-delete' import { MAccount, MAccountActor, MAccountAP, MAccountDefault, MAccountFormattable, + MAccountHost, MAccountSummaryFormattable, - MChannelActor + MChannelHost } from '../../types/models' -import { ActorModel } from '../activitypub/actor' -import { ActorFollowModel } from '../activitypub/actor-follow' +import { ActorModel } from '../actor/actor' +import { ActorFollowModel } from '../actor/actor-follow' +import { ActorImageModel } from '../actor/actor-image' import { ApplicationModel } from '../application/application' -import { ActorImageModel } from './actor-image' import { ServerModel } from '../server/server' import { ServerBlocklistModel } from '../server/server-blocklist' -import { getSort, throwIfNotValid } from '../utils' +import { buildSQLAttributes, getSort, throwIfNotValid } from '../shared' +import { UserModel } from '../user/user' import { VideoModel } from '../video/video' import { VideoChannelModel } from '../video/video-channel' import { VideoCommentModel } from '../video/video-comment' import { VideoPlaylistModel } from '../video/video-playlist' import { AccountBlocklistModel } from './account-blocklist' -import { UserModel } from './user' export enum ScopeNames { SUMMARY = 'SUMMARY' @@ -51,7 +53,9 @@ export enum ScopeNames { export type SummaryOptions = { actorRequired?: boolean // Default: true whereActor?: WhereOptions + whereServer?: WhereOptions withAccountBlockerIds?: number[] + forCount?: boolean } @DefaultScope(() => ({ @@ -64,30 +68,31 @@ export type SummaryOptions = { })) @Scopes(() => ({ [ScopeNames.SUMMARY]: (options: SummaryOptions = {}) => { - const whereActor = options.whereActor || undefined - const serverInclude: IncludeOptions = { attributes: [ 'host' ], model: ServerModel.unscoped(), - required: false + required: !!options.whereServer, + where: options.whereServer } - const queryInclude: Includeable[] = [ - { - attributes: [ 'id', 'preferredUsername', 'url', 'serverId', 'avatarId' ], - model: ActorModel.unscoped(), - required: options.actorRequired ?? true, - where: whereActor, - include: [ - serverInclude, + const actorInclude: Includeable = { + attributes: [ 'id', 'preferredUsername', 'url', 'serverId' ], + model: ActorModel.unscoped(), + required: options.actorRequired ?? true, + where: options.whereActor, + include: [ serverInclude ] + } - { - model: ActorImageModel.unscoped(), - as: 'Avatar', - required: false - } - ] - } + if (options.forCount !== true) { + actorInclude.include.push({ + model: ActorImageModel, + as: 'Avatars', + required: false + }) + } + + const queryInclude: Includeable[] = [ + actorInclude ] const query: FindOptions = { @@ -98,7 +103,7 @@ export type SummaryOptions = { queryInclude.push({ attributes: [ 'id' ], model: AccountBlocklistModel.unscoped(), - as: 'BlockedAccounts', + as: 'BlockedBy', required: false, where: { accountId: { @@ -141,7 +146,7 @@ export type SummaryOptions = { } ] }) -export class AccountModel extends Model { +export class AccountModel extends Model>> { @AllowNull(false) @Column @@ -227,10 +232,10 @@ export class AccountModel extends Model { name: 'targetAccountId', allowNull: false }, - as: 'BlockedAccounts', + as: 'BlockedBy', onDelete: 'CASCADE' }) - BlockedAccounts: AccountBlocklistModel[] + BlockedBy: AccountBlocklistModel[] @BeforeDestroy static async sendDeleteIfOwned (instance: AccountModel, options) { @@ -247,6 +252,18 @@ export class AccountModel extends Model { return undefined } + // --------------------------------------------------------------------------- + + static getSQLAttributes (tableName: string, aliasPrefix = '') { + return buildSQLAttributes({ + model: this, + tableName, + aliasPrefix + }) + } + + // --------------------------------------------------------------------------- + static load (id: number, transaction?: Transaction): Promise { return AccountModel.findByPk(id, { transaction }) } @@ -280,9 +297,7 @@ export class AccountModel extends Model { { model: ActorModel, required: true, - where: { - preferredUsername: name - } + where: ActorModel.wherePreferredUsername(name) } ] } @@ -305,9 +320,7 @@ export class AccountModel extends Model { { model: ActorModel, required: true, - where: { - preferredUsername: name - }, + where: ActorModel.wherePreferredUsername(name), include: [ { model: ServerModel, @@ -348,13 +361,10 @@ export class AccountModel extends Model { order: getSort(sort) } - return AccountModel.findAndCountAll(query) - .then(({ rows, count }) => { - return { - data: rows, - total: count - } - }) + return Promise.all([ + AccountModel.count(), + AccountModel.findAll(query) + ]).then(([ total, data ]) => ({ total, data })) } static loadAccountIdFromVideo (videoId: number): Promise { @@ -401,22 +411,16 @@ export class AccountModel extends Model { .findAll(query) } - getClientUrl () { - return WEBSERVER.URL + '/accounts/' + this.Actor.getIdentifier() - } - toFormattedJSON (this: MAccountFormattable): Account { - const actor = this.Actor.toFormattedJSON() - const account = { + return { + ...this.Actor.toFormattedJSON(), + id: this.id, displayName: this.getDisplayName(), description: this.description, - createdAt: this.createdAt, updatedAt: this.updatedAt, - userId: this.userId ? this.userId : undefined + userId: this.userId ?? undefined } - - return Object.assign(actor, account) } toFormattedSummaryJSON (this: MAccountSummaryFormattable): AccountSummary { @@ -424,16 +428,20 @@ export class AccountModel extends Model { return { id: this.id, - name: actor.name, displayName: this.getDisplayName(), + + name: actor.name, url: actor.url, host: actor.host, + avatars: actor.avatars, + + // TODO: remove, deprecated in 4.2 avatar: actor.avatar } } - toActivityPubObject (this: MAccountAP) { - const obj = this.Actor.toActivityPubObject(this.name) + async toActivityPubObject (this: MAccountAP) { + const obj = await this.Actor.toActivityPubObject(this.name) return Object.assign(obj, { summary: this.description @@ -452,11 +460,12 @@ export class AccountModel extends Model { return this.name } - getLocalUrl (this: MAccountActor | MChannelActor) { - return WEBSERVER.URL + `/accounts/` + this.Actor.preferredUsername + // Avoid error when running this method on MAccount... | MChannel... + getClientUrl (this: MAccountHost | MChannelHost) { + return WEBSERVER.URL + '/a/' + this.Actor.getIdentifier() } isBlocked () { - return this.BlockedAccounts && this.BlockedAccounts.length !== 0 + return this.BlockedBy && this.BlockedBy.length !== 0 } }