diff options
| author | Sayamame-beans <61457993+Sayamame-beans@users.noreply.github.com> | 2024-07-14 09:31:05 +0900 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-07-14 09:31:05 +0900 |
| commit | 7afa593d114335368d9031b6e1d5b1edbc4ea9c9 (patch) | |
| tree | 17b57ed871c29b4f27aee48f5a5af3b269a0379c /packages/backend/src/server/api/endpoints | |
| parent | fix(backend): 一般ユーザーから見たユーザーのバッジの一覧... (diff) | |
| download | sharkey-7afa593d114335368d9031b6e1d5b1edbc4ea9c9.tar.gz sharkey-7afa593d114335368d9031b6e1d5b1edbc4ea9c9.tar.bz2 sharkey-7afa593d114335368d9031b6e1d5b1edbc4ea9c9.zip | |
Feat: ユーザーのアイコン/バナーの変更可否をロールで設定可能に (#14078)
* feat: implement role policy "canUpdateBioMedia"
* docs(changelog): update changelog
* docs(changelog): update changelog
* chore: regenerate misskey-js type definitions
* chore: Apply suggestion from code review
Co-authored-by: anatawa12 <anatawa12@icloud.com>
* chore: fix unnecessarily strict inequality check
* chore: policies should be gotten only once
---------
Co-authored-by: anatawa12 <anatawa12@icloud.com>
Diffstat (limited to 'packages/backend/src/server/api/endpoints')
| -rw-r--r-- | packages/backend/src/server/api/endpoints/i/update.ts | 23 |
1 files changed, 17 insertions, 6 deletions
diff --git a/packages/backend/src/server/api/endpoints/i/update.ts b/packages/backend/src/server/api/endpoints/i/update.ts index b39b52bc41..a1e2fa5e4c 100644 --- a/packages/backend/src/server/api/endpoints/i/update.ts +++ b/packages/backend/src/server/api/endpoints/i/update.ts @@ -25,7 +25,7 @@ import { UserFollowingService } from '@/core/UserFollowingService.js'; import { AccountUpdateService } from '@/core/AccountUpdateService.js'; import { HashtagService } from '@/core/HashtagService.js'; import { DI } from '@/di-symbols.js'; -import { RoleService } from '@/core/RoleService.js'; +import { RolePolicies, RoleService } from '@/core/RoleService.js'; import { CacheService } from '@/core/CacheService.js'; import { RemoteUserResolveService } from '@/core/RemoteUserResolveService.js'; import { DriveFileEntityService } from '@/core/entities/DriveFileEntityService.js'; @@ -256,6 +256,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint- const profileUpdates = {} as Partial<MiUserProfile>; const profile = await this.userProfilesRepository.findOneByOrFail({ userId: user.id }); + let policies: RolePolicies | null = null; if (ps.name !== undefined) { if (ps.name === null) { @@ -296,14 +297,16 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint- } if (ps.mutedWords !== undefined) { - checkMuteWordCount(ps.mutedWords, (await this.roleService.getUserPolicies(user.id)).wordMuteLimit); + policies ??= await this.roleService.getUserPolicies(user.id); + checkMuteWordCount(ps.mutedWords, policies.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); + policies ??= await this.roleService.getUserPolicies(user.id); + checkMuteWordCount(ps.hardMutedWords, policies.wordMuteLimit); validateMuteWordRegex(ps.hardMutedWords); profileUpdates.hardMutedWords = ps.hardMutedWords; } @@ -322,13 +325,17 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint- if (typeof ps.injectFeaturedNote === 'boolean') profileUpdates.injectFeaturedNote = ps.injectFeaturedNote; if (typeof ps.receiveAnnouncementEmail === 'boolean') profileUpdates.receiveAnnouncementEmail = ps.receiveAnnouncementEmail; if (typeof ps.alwaysMarkNsfw === 'boolean') { - if ((await roleService.getUserPolicies(user.id)).alwaysMarkNsfw) throw new ApiError(meta.errors.restrictedByRole); + policies ??= await this.roleService.getUserPolicies(user.id); + if (policies.alwaysMarkNsfw) throw new ApiError(meta.errors.restrictedByRole); profileUpdates.alwaysMarkNsfw = ps.alwaysMarkNsfw; } if (typeof ps.autoSensitive === 'boolean') profileUpdates.autoSensitive = ps.autoSensitive; if (ps.emailNotificationTypes !== undefined) profileUpdates.emailNotificationTypes = ps.emailNotificationTypes; if (ps.avatarId) { + policies ??= await this.roleService.getUserPolicies(user.id); + if (!policies.canUpdateBioMedia) throw new ApiError(meta.errors.restrictedByRole); + const avatar = await this.driveFilesRepository.findOneBy({ id: ps.avatarId }); if (avatar == null || avatar.userId !== user.id) throw new ApiError(meta.errors.noSuchAvatar); @@ -344,6 +351,9 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint- } if (ps.bannerId) { + policies ??= await this.roleService.getUserPolicies(user.id); + if (!policies.canUpdateBioMedia) throw new ApiError(meta.errors.restrictedByRole); + const banner = await this.driveFilesRepository.findOneBy({ id: ps.bannerId }); if (banner == null || banner.userId !== user.id) throw new ApiError(meta.errors.noSuchBanner); @@ -359,14 +369,15 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint- } if (ps.avatarDecorations) { + policies ??= await this.roleService.getUserPolicies(user.id); const decorations = await this.avatarDecorationService.getAll(true); - const [myRoles, myPolicies] = await Promise.all([this.roleService.getUserRoles(user.id), this.roleService.getUserPolicies(user.id)]); + const myRoles = await this.roleService.getUserRoles(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); + if (ps.avatarDecorations.length > policies.avatarDecorationLimit) throw new ApiError(meta.errors.restrictedByRole); updates.avatarDecorations = ps.avatarDecorations.filter(d => decorationIds.includes(d.id)).map(d => ({ id: d.id, |