summaryrefslogtreecommitdiff
path: root/packages/backend/src
diff options
context:
space:
mode:
authoranatawa12 <anatawa12@icloud.com>2023-11-23 18:56:20 +0900
committerGitHub <noreply@github.com>2023-11-23 18:56:20 +0900
commit864827f788cd1671a4db2ebc159c1c8ab031b7ad (patch)
tree689fa67a1f438cc3410446cd893397d91c2d6725 /packages/backend/src
parent絵文字のオートコンプリート強化の対応 (#12365) (diff)
downloadsharkey-864827f788cd1671a4db2ebc159c1c8ab031b7ad.tar.gz
sharkey-864827f788cd1671a4db2ebc159c1c8ab031b7ad.tar.bz2
sharkey-864827f788cd1671a4db2ebc159c1c8ab031b7ad.zip
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
Diffstat (limited to 'packages/backend/src')
-rw-r--r--packages/backend/src/core/entities/UserEntityService.ts1
-rw-r--r--packages/backend/src/models/UserProfile.ts7
-rw-r--r--packages/backend/src/models/json-schema/user.ts12
-rw-r--r--packages/backend/src/server/api/endpoints/i/update.ts34
4 files changed, 46 insertions, 8 deletions
diff --git a/packages/backend/src/core/entities/UserEntityService.ts b/packages/backend/src/core/entities/UserEntityService.ts
index 17e7988176..917f4e06d0 100644
--- a/packages/backend/src/core/entities/UserEntityService.ts
+++ b/packages/backend/src/core/entities/UserEntityService.ts
@@ -473,6 +473,7 @@ export class UserEntityService implements OnModuleInit {
hasPendingReceivedFollowRequest: this.getHasPendingReceivedFollowRequest(user.id),
unreadNotificationsCount: notificationsInfo?.unreadCount,
mutedWords: profile!.mutedWords,
+ hardMutedWords: profile!.hardMutedWords,
mutedInstances: profile!.mutedInstances,
mutingNotificationTypes: [], // 後方互換性のため
notificationRecieveConfig: profile!.notificationRecieveConfig,
diff --git a/packages/backend/src/models/UserProfile.ts b/packages/backend/src/models/UserProfile.ts
index d6d85c5609..8a43b60039 100644
--- a/packages/backend/src/models/UserProfile.ts
+++ b/packages/backend/src/models/UserProfile.ts
@@ -215,7 +215,12 @@ export class MiUserProfile {
@Column('jsonb', {
default: [],
})
- public mutedWords: string[][];
+ public mutedWords: (string[] | string)[];
+
+ @Column('jsonb', {
+ default: [],
+ })
+ public hardMutedWords: (string[] | string)[];
@Column('jsonb', {
default: [],
diff --git a/packages/backend/src/models/json-schema/user.ts b/packages/backend/src/models/json-schema/user.ts
index b0e18db01a..a2ec203e96 100644
--- a/packages/backend/src/models/json-schema/user.ts
+++ b/packages/backend/src/models/json-schema/user.ts
@@ -530,6 +530,18 @@ export const packedMeDetailedOnlySchema = {
},
},
},
+ hardMutedWords: {
+ type: 'array',
+ nullable: false, optional: false,
+ items: {
+ type: 'array',
+ nullable: false, optional: false,
+ items: {
+ type: 'string',
+ nullable: false, optional: false,
+ },
+ },
+ },
mutedInstances: {
type: 'array',
nullable: true, optional: false,
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<typeof meta, typeof paramDef> { // 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<typeof meta, typeof paramDef> { // 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;