From 85c20aaeb90ef0e0f44c377e62c323fde275cdde Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Thu, 11 May 2023 16:16:27 +0200 Subject: Set actor preferred name case insensitive --- server/models/account/account-video-rate.ts | 6 +++-- server/models/account/account.ts | 10 +++----- server/models/actor/actor-follow.ts | 22 +++++------------- server/models/actor/actor.ts | 36 ++++++++++++++++++++--------- server/models/video/video-channel.ts | 19 ++++++++------- 5 files changed, 49 insertions(+), 44 deletions(-) (limited to 'server/models') diff --git a/server/models/account/account-video-rate.ts b/server/models/account/account-video-rate.ts index 9e7ef4394..18ff07d53 100644 --- a/server/models/account/account-video-rate.ts +++ b/server/models/account/account-video-rate.ts @@ -189,8 +189,10 @@ export class AccountVideoRateModel extends Model>> { { model: ActorModel, required: true, - where: { - preferredUsername: name - } + where: ActorModel.wherePreferredUsername(name) } ] } @@ -321,9 +319,7 @@ export class AccountModel extends Model>> { { model: ActorModel, required: true, - where: { - preferredUsername: name - }, + where: ActorModel.wherePreferredUsername(name), include: [ { model: ServerModel, diff --git a/server/models/actor/actor-follow.ts b/server/models/actor/actor-follow.ts index 32e5d78b0..0f199d208 100644 --- a/server/models/actor/actor-follow.ts +++ b/server/models/actor/actor-follow.ts @@ -37,8 +37,8 @@ import { logger } from '../../helpers/logger' import { ACTOR_FOLLOW_SCORE, CONSTRAINTS_FIELDS, FOLLOW_STATES, SERVER_ACTOR_NAME, SORTABLE_COLUMNS } from '../../initializers/constants' import { AccountModel } from '../account/account' import { ServerModel } from '../server/server' -import { doesExist } from '../shared/query' import { buildSQLAttributes, createSafeIn, getSort, searchAttribute, throwIfNotValid } from '../shared' +import { doesExist } from '../shared/query' import { VideoChannelModel } from '../video/video-channel' import { ActorModel, unusedActorAttributesForAPI } from './actor' import { InstanceListFollowersQueryBuilder, ListFollowersOptions } from './sql/instance-list-followers-query-builder' @@ -265,9 +265,7 @@ export class ActorFollowModel extends Model)[] = unique: true }, { - fields: [ 'preferredUsername', 'serverId' ], + fields: [ fn('lower', col('preferredUsername')), 'serverId' ], + name: 'actor_preferred_username_lower_server_id', unique: true, where: { serverId: { @@ -139,7 +140,8 @@ export const unusedActorAttributesForAPI: (keyof AttributesOnly)[] = } }, { - fields: [ 'preferredUsername' ], + fields: [ fn('lower', col('preferredUsername')) ], + name: 'actor_preferred_username_lower', unique: true, where: { serverId: null @@ -327,6 +329,12 @@ export class ActorModel extends Model>> { // --------------------------------------------------------------------------- + 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 @@ -372,8 +380,12 @@ export class ActorModel extends Model>> { const fun = () => { const query = { where: { - preferredUsername, - serverId: null + [Op.and]: [ + this.wherePreferredUsername(preferredUsername), + { + serverId: null + } + ] }, transaction } @@ -395,8 +407,12 @@ export class ActorModel extends Model>> { const query = { attributes: [ 'url' ], where: { - preferredUsername, - serverId: null + [Op.and]: [ + this.wherePreferredUsername(preferredUsername), + { + serverId: null + } + ] }, transaction } @@ -405,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, @@ -415,9 +431,7 @@ export class ActorModel extends Model>> { static loadByNameAndHost (preferredUsername: string, host: string): Promise { const query = { - where: { - preferredUsername - }, + where: this.wherePreferredUsername(preferredUsername), include: [ { model: ServerModel, diff --git a/server/models/video/video-channel.ts b/server/models/video/video-channel.ts index 67fccab68..306bc6ade 100644 --- a/server/models/video/video-channel.ts +++ b/server/models/video/video-channel.ts @@ -130,13 +130,16 @@ export type SummaryOptions = { for (const handle of options.handles || []) { const [ preferredUsername, host ] = handle.split('@') + const sanitizedPreferredUsername = VideoChannelModel.sequelize.escape(preferredUsername.toLowerCase()) + const sanitizedHost = VideoChannelModel.sequelize.escape(host) + if (!host || host === WEBSERVER.HOST) { - or.push(`("preferredUsername" = ${VideoChannelModel.sequelize.escape(preferredUsername)} AND "serverId" IS NULL)`) + or.push(`(LOWER("preferredUsername") = ${sanitizedPreferredUsername} AND "serverId" IS NULL)`) } else { or.push( `(` + - `"preferredUsername" = ${VideoChannelModel.sequelize.escape(preferredUsername)} ` + - `AND "host" = ${VideoChannelModel.sequelize.escape(host)}` + + `LOWER("preferredUsername") = ${sanitizedPreferredUsername} ` + + `AND "host" = ${sanitizedHost}` + `)` ) } @@ -698,8 +701,10 @@ export class VideoChannelModel extends Model