From 864827f788cd1671a4db2ebc159c1c8ab031b7ad Mon Sep 17 00:00:00 2001 From: anatawa12 Date: Thu, 23 Nov 2023 18:56:20 +0900 Subject: Hard mute (#12376) * feat(backend,misskey-js): hard mute storage in backend * fix(backend,misskey-js): mute word record type * chore(frontend): generalize XWordMute * feat(frontend): configure hard mute * feat(frontend): hard mute notes on the timelines * lint(backend,frontend): fix lint failure * chore(misskey-js): update api.md * fix(backend): test failure * chore(frontend): check word mute for reply * chore: limit hard mute count --- .../backend/src/server/api/endpoints/i/update.ts | 34 +++++++++++++++++----- 1 file changed, 27 insertions(+), 7 deletions(-) (limited to 'packages/backend/src/server/api/endpoints') diff --git a/packages/backend/src/server/api/endpoints/i/update.ts b/packages/backend/src/server/api/endpoints/i/update.ts index b00aa87bee..8ba29c5658 100644 --- a/packages/backend/src/server/api/endpoints/i/update.ts +++ b/packages/backend/src/server/api/endpoints/i/update.ts @@ -123,6 +123,11 @@ export const meta = { }, } as const; +const muteWords = { type: 'array', items: { oneOf: [ + { type: 'array', items: { type: 'string' } }, + { type: 'string' } +] } } as const; + export const paramDef = { type: 'object', properties: { @@ -171,7 +176,8 @@ export const paramDef = { autoSensitive: { type: 'boolean' }, ffVisibility: { type: 'string', enum: ['public', 'followers', 'private'] }, pinnedPageId: { type: 'string', format: 'misskey:id', nullable: true }, - mutedWords: { type: 'array' }, + mutedWords: muteWords, + hardMutedWords: muteWords, mutedInstances: { type: 'array', items: { type: 'string', } }, @@ -234,16 +240,20 @@ export default class extends Endpoint { // eslint- if (ps.location !== undefined) profileUpdates.location = ps.location; if (ps.birthday !== undefined) profileUpdates.birthday = ps.birthday; if (ps.ffVisibility !== undefined) profileUpdates.ffVisibility = ps.ffVisibility; - if (ps.mutedWords !== undefined) { + + function checkMuteWordCount(mutedWords: (string[] | string)[], limit: number) { // TODO: ちゃんと数える const length = JSON.stringify(ps.mutedWords).length; - if (length > (await this.roleService.getUserPolicies(user.id)).wordMuteLimit) { + if (length > limit) { throw new ApiError(meta.errors.tooManyMutedWords); } + } + + function validateMuteWordRegex(mutedWords: (string[] | string)[]) { + for (const mutedWord of mutedWords) { + if (typeof mutedWord !== "string") continue; - // validate regular expression syntax - ps.mutedWords.filter(x => !Array.isArray(x)).forEach(x => { - const regexp = x.match(/^\/(.+)\/(.*)$/); + const regexp = mutedWord.match(/^\/(.+)\/(.*)$/); if (!regexp) throw new ApiError(meta.errors.invalidRegexp); try { @@ -251,11 +261,21 @@ export default class extends Endpoint { // eslint- } catch (err) { throw new ApiError(meta.errors.invalidRegexp); } - }); + } + } + + if (ps.mutedWords !== undefined) { + checkMuteWordCount(ps.mutedWords, (await this.roleService.getUserPolicies(user.id)).wordMuteLimit); + validateMuteWordRegex(ps.mutedWords); profileUpdates.mutedWords = ps.mutedWords; profileUpdates.enableWordMute = ps.mutedWords.length > 0; } + if (ps.hardMutedWords !== undefined) { + checkMuteWordCount(ps.hardMutedWords, (await this.roleService.getUserPolicies(user.id)).wordMuteLimit); + validateMuteWordRegex(ps.hardMutedWords); + profileUpdates.hardMutedWords = ps.hardMutedWords; + } if (ps.mutedInstances !== undefined) profileUpdates.mutedInstances = ps.mutedInstances; if (ps.notificationRecieveConfig !== undefined) profileUpdates.notificationRecieveConfig = ps.notificationRecieveConfig; if (typeof ps.isLocked === 'boolean') updates.isLocked = ps.isLocked; -- cgit v1.2.3-freya