X-Git-Url: https://git.immae.eu/?a=blobdiff_plain;f=server%2Fmodels%2Factor%2Factor.ts;h=80a646c77f59e669119c61a8337a50d1534353a4;hb=3f0ceab06e5320f62f593c49daa30d963dbc36f9;hp=943b7364f1b07d479cd55f5f95fbac3e35dd446a;hpb=3396e6534592865f184ee2db32a75957c42cb887;p=github%2FChocobozzz%2FPeerTube.git diff --git a/server/models/actor/actor.ts b/server/models/actor/actor.ts index 943b7364f..80a646c77 100644 --- a/server/models/actor/actor.ts +++ b/server/models/actor/actor.ts @@ -1,5 +1,4 @@ -import { values } from 'lodash' -import { literal, Op, QueryTypes, Transaction } from 'sequelize' +import { col, fn, literal, Op, QueryTypes, Transaction, where } from 'sequelize' import { AllowNull, BelongsTo, @@ -18,8 +17,8 @@ import { } from 'sequelize-typescript' import { activityPubContextify } from '@server/lib/activitypub/context' import { getBiggestActorImage } from '@server/lib/actor-image' -import { ModelCache } from '@server/models/model-cache' -import { getLowercaseExtension } from '@shared/core-utils' +import { ModelCache } from '@server/models/shared/model-cache' +import { forceNumber, getLowercaseExtension } from '@shared/core-utils' import { ActivityIconObject, ActivityPubActorType, ActorImageType } from '@shared/models' import { AttributesOnly } from '@shared/typescript-utils' import { @@ -56,7 +55,7 @@ import { import { AccountModel } from '../account/account' import { getServerActor } from '../application/application' import { ServerModel } from '../server/server' -import { isOutdated, throwIfNotValid } from '../utils' +import { buildSQLAttributes, isOutdated, throwIfNotValid } from '../shared' import { VideoModel } from '../video/video' import { VideoChannelModel } from '../video/video-channel' import { ActorFollowModel } from './actor-follow' @@ -66,7 +65,7 @@ enum ScopeNames { FULL = 'FULL' } -export const unusedActorAttributesForAPI = [ +export const unusedActorAttributesForAPI: (keyof AttributesOnly)[] = [ 'publicKey', 'privateKey', 'inboxUrl', @@ -131,7 +130,8 @@ export const unusedActorAttributesForAPI = [ unique: true }, { - fields: [ 'preferredUsername', 'serverId' ], + fields: [ fn('lower', col('preferredUsername')), 'serverId' ], + name: 'actor_preferred_username_lower_server_id', unique: true, where: { serverId: { @@ -140,7 +140,8 @@ export const unusedActorAttributesForAPI = [ } }, { - fields: [ 'preferredUsername' ], + fields: [ fn('lower', col('preferredUsername')) ], + name: 'actor_preferred_username_lower', unique: true, where: { serverId: null @@ -163,7 +164,7 @@ export const unusedActorAttributesForAPI = [ export class ActorModel extends Model>> { @AllowNull(false) - @Column(DataType.ENUM(...values(ACTIVITY_PUB_ACTOR_TYPES))) + @Column(DataType.ENUM(...Object.values(ACTIVITY_PUB_ACTOR_TYPES))) type: ActivityPubActorType @AllowNull(false) @@ -307,6 +308,33 @@ export class ActorModel extends Model>> { }) VideoChannel: VideoChannelModel + // --------------------------------------------------------------------------- + + static getSQLAttributes (tableName: string, aliasPrefix = '') { + return buildSQLAttributes({ + model: this, + tableName, + aliasPrefix + }) + } + + static getSQLAPIAttributes (tableName: string, aliasPrefix = '') { + return buildSQLAttributes({ + model: this, + tableName, + aliasPrefix, + excludeAttributes: unusedActorAttributesForAPI + }) + } + + // --------------------------------------------------------------------------- + + static wherePreferredUsername (preferredUsername: string, colName = 'preferredUsername') { + return where(fn('lower', col(colName)), preferredUsername.toLowerCase()) + } + + // --------------------------------------------------------------------------- + static async load (id: number): Promise { const actorServer = await getServerActor() if (id === actorServer.id) return actorServer @@ -352,8 +380,12 @@ export class ActorModel extends Model>> { const fun = () => { const query = { where: { - preferredUsername, - serverId: null + [Op.and]: [ + this.wherePreferredUsername(preferredUsername, '"ActorModel"."preferredUsername"'), + { + serverId: null + } + ] }, transaction } @@ -375,8 +407,12 @@ export class ActorModel extends Model>> { const query = { attributes: [ 'url' ], where: { - preferredUsername, - serverId: null + [Op.and]: [ + this.wherePreferredUsername(preferredUsername), + { + serverId: null + } + ] }, transaction } @@ -385,7 +421,7 @@ export class ActorModel extends Model>> { } return ModelCache.Instance.doCache({ - cacheType: 'local-actor-name', + cacheType: 'local-actor-url', key: preferredUsername, // The server actor never change, so we can easily cache it whitelist: () => preferredUsername === SERVER_ACTOR_NAME, @@ -395,9 +431,7 @@ export class ActorModel extends Model>> { static loadByNameAndHost (preferredUsername: string, host: string): Promise { const query = { - where: { - preferredUsername - }, + where: this.wherePreferredUsername(preferredUsername, '"ActorModel"."preferredUsername"'), include: [ { model: ServerModel, @@ -447,7 +481,7 @@ export class ActorModel extends Model>> { } static rebuildFollowsCount (ofId: number, type: 'followers' | 'following', transaction?: Transaction) { - const sanitizedOfId = parseInt(ofId + '', 10) + const sanitizedOfId = forceNumber(ofId) const where = { id: sanitizedOfId } let columnToUpdate: string @@ -462,7 +496,7 @@ export class ActorModel extends Model>> { } return ActorModel.update({ - [columnToUpdate]: literal(`(SELECT COUNT(*) FROM "actorFollow" WHERE "${columnOfCount}" = ${sanitizedOfId})`) + [columnToUpdate]: literal(`(SELECT COUNT(*) FROM "actorFollow" WHERE "${columnOfCount}" = ${sanitizedOfId} AND "state" = 'accepted')`) }, { where, transaction }) }