summaryrefslogtreecommitdiff
path: root/packages/backend/src/server/api/endpoints/i/update.ts
diff options
context:
space:
mode:
authorMarie <Marie@kaifa.ch>2023-12-23 02:09:23 +0100
committerMarie <Marie@kaifa.ch>2023-12-23 02:09:23 +0100
commit5db583a3eb61d50de14d875ebf7ecef20490e313 (patch)
tree783dd43d2ac660c32e745a4485d499e9ddc43324 /packages/backend/src/server/api/endpoints/i/update.ts
parentadd: Custom MOTDs (diff)
parentUpdate CHANGELOG.md (diff)
downloadsharkey-5db583a3eb61d50de14d875ebf7ecef20490e313.tar.gz
sharkey-5db583a3eb61d50de14d875ebf7ecef20490e313.tar.bz2
sharkey-5db583a3eb61d50de14d875ebf7ecef20490e313.zip
merge: upstream
Diffstat (limited to 'packages/backend/src/server/api/endpoints/i/update.ts')
-rw-r--r--packages/backend/src/server/api/endpoints/i/update.ts52
1 files changed, 40 insertions, 12 deletions
diff --git a/packages/backend/src/server/api/endpoints/i/update.ts b/packages/backend/src/server/api/endpoints/i/update.ts
index aa730716bd..22079de042 100644
--- a/packages/backend/src/server/api/endpoints/i/update.ts
+++ b/packages/backend/src/server/api/endpoints/i/update.ts
@@ -135,6 +135,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: {
@@ -145,12 +150,14 @@ export const paramDef = {
listenbrainz: { ...listenbrainzSchema, nullable: true },
lang: { type: 'string', enum: [null, ...Object.keys(langmap)] as string[], nullable: true },
avatarId: { type: 'string', format: 'misskey:id', nullable: true },
- avatarDecorations: { type: 'array', maxItems: 1, items: {
+ avatarDecorations: { type: 'array', maxItems: 16, items: {
type: 'object',
properties: {
id: { type: 'string', format: 'misskey:id' },
angle: { type: 'number', nullable: true, maximum: 0.5, minimum: -0.5 },
flipH: { type: 'boolean', nullable: true },
+ offsetX: { type: 'number', nullable: true, maximum: 0.25, minimum: -0.25 },
+ offsetY: { type: 'number', nullable: true, maximum: 0.25, minimum: -0.25 },
},
required: ['id'],
} },
@@ -185,9 +192,11 @@ export const paramDef = {
receiveAnnouncementEmail: { type: 'boolean' },
alwaysMarkNsfw: { type: 'boolean' },
autoSensitive: { type: 'boolean' },
- ffVisibility: { type: 'string', enum: ['public', 'followers', 'private'] },
+ followingVisibility: { type: 'string', enum: ['public', 'followers', 'private'] },
+ followersVisibility: { 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',
} },
@@ -250,17 +259,22 @@ 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.listenbrainz !== undefined) profileUpdates.listenbrainz = ps.listenbrainz;
- if (ps.ffVisibility !== undefined) profileUpdates.ffVisibility = ps.ffVisibility;
- if (ps.mutedWords !== undefined) {
+ if (ps.followingVisibility !== undefined) profileUpdates.followingVisibility = ps.followingVisibility;
+ if (ps.followersVisibility !== undefined) profileUpdates.followersVisibility = ps.followersVisibility;
+
+ function checkMuteWordCount(mutedWords: (string[] | string)[], limit: number) {
// TODO: ちゃんと数える
- const length = JSON.stringify(ps.mutedWords).length;
- if (length > (await this.roleService.getUserPolicies(user.id)).wordMuteLimit) {
+ const length = JSON.stringify(mutedWords).length;
+ 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 {
@@ -268,11 +282,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;
@@ -341,16 +365,20 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
if (ps.avatarDecorations) {
const decorations = await this.avatarDecorationService.getAll(true);
- const myRoles = await this.roleService.getUserRoles(user.id);
+ const [myRoles, myPolicies] = await Promise.all([this.roleService.getUserRoles(user.id), this.roleService.getUserPolicies(user.id)]);
const allRoles = await this.roleService.getRoles();
const decorationIds = decorations
.filter(d => d.roleIdsThatCanBeUsedThisDecoration.filter(roleId => allRoles.some(r => r.id === roleId)).length === 0 || myRoles.some(r => d.roleIdsThatCanBeUsedThisDecoration.includes(r.id)))
.map(d => d.id);
+ if (ps.avatarDecorations.length > myPolicies.avatarDecorationLimit) throw new ApiError(meta.errors.restrictedByRole);
+
updates.avatarDecorations = ps.avatarDecorations.filter(d => decorationIds.includes(d.id)).map(d => ({
id: d.id,
angle: d.angle ?? 0,
flipH: d.flipH ?? false,
+ offsetX: d.offsetX ?? 0,
+ offsetY: d.offsetY ?? 0,
}));
}