diff --git a/locales/ja-JP.yml b/locales/ja-JP.yml index 79856447a..786d41ca4 100644 --- a/locales/ja-JP.yml +++ b/locales/ja-JP.yml @@ -952,6 +952,7 @@ _role: isPublic: "ロールを公開" descriptionOfIsPublic: "ロールにアサインされたユーザーを誰でも見ることができます。また、ユーザーのプロフィールでこのロールが表示されます。" options: "オプション" + policies: "ポリシー" baseRole: "ベースロール" useBaseValue: "ベースロールの値を使用" chooseRoleToAssign: "アサインするロールを選択" diff --git a/packages/backend/migration/1673783015567-Policies.js b/packages/backend/migration/1673783015567-Policies.js new file mode 100644 index 000000000..8b36921d4 --- /dev/null +++ b/packages/backend/migration/1673783015567-Policies.js @@ -0,0 +1,13 @@ +export class Policies1673783015567 { + name = 'Policies1673783015567' + + async up(queryRunner) { + await queryRunner.query(`ALTER TABLE "role" RENAME COLUMN "options" TO "policies"`); + await queryRunner.query(`ALTER TABLE "meta" RENAME COLUMN "defaultRoleOverride" TO "policies"`); + } + + async down(queryRunner) { + await queryRunner.query(`ALTER TABLE "meta" RENAME COLUMN "policies" TO "defaultRoleOverride"`); + await queryRunner.query(`ALTER TABLE "role" RENAME COLUMN "policies" TO "options"`); + } +} diff --git a/packages/backend/src/core/DriveService.ts b/packages/backend/src/core/DriveService.ts index 9002c96a6..598a457e8 100644 --- a/packages/backend/src/core/DriveService.ts +++ b/packages/backend/src/core/DriveService.ts @@ -479,8 +479,8 @@ export class DriveService { if (user && !isLink) { const usage = await this.driveFileEntityService.calcDriveUsageOf(user); - const role = await this.roleService.getUserRoleOptions(user.id); - const driveCapacity = 1024 * 1024 * role.driveCapacityMb; + const policies = await this.roleService.getUserPolicies(user.id); + const driveCapacity = 1024 * 1024 * policies.driveCapacityMb; this.registerLogger.debug('drive capacity override applied'); this.registerLogger.debug(`overrideCap: ${driveCapacity}bytes, usage: ${usage}bytes, u+s: ${usage + info.size}bytes`); diff --git a/packages/backend/src/core/NoteCreateService.ts b/packages/backend/src/core/NoteCreateService.ts index 112b84fdf..3dc44a25f 100644 --- a/packages/backend/src/core/NoteCreateService.ts +++ b/packages/backend/src/core/NoteCreateService.ts @@ -226,7 +226,7 @@ export class NoteCreateService { if (data.channel != null) data.localOnly = true; if (data.visibility === 'public' && data.channel == null) { - if ((await this.roleService.getUserRoleOptions(user.id)).canPublicNote === false) { + if ((await this.roleService.getUserPolicies(user.id)).canPublicNote === false) { data.visibility = 'home'; } } diff --git a/packages/backend/src/core/NotePiningService.ts b/packages/backend/src/core/NotePiningService.ts index bc038e17a..bb6def1ed 100644 --- a/packages/backend/src/core/NotePiningService.ts +++ b/packages/backend/src/core/NotePiningService.ts @@ -57,7 +57,7 @@ export class NotePiningService { const pinings = await this.userNotePiningsRepository.findBy({ userId: user.id }); - if (pinings.length >= (await this.roleService.getUserRoleOptions(user.id)).pinLimit) { + if (pinings.length >= (await this.roleService.getUserPolicies(user.id)).pinLimit) { throw new IdentifiableError('15a018eb-58e5-4da1-93be-330fcc5e4e1a', 'You can not pin notes any more.'); } diff --git a/packages/backend/src/core/RoleService.ts b/packages/backend/src/core/RoleService.ts index 42b477d9e..abad05830 100644 --- a/packages/backend/src/core/RoleService.ts +++ b/packages/backend/src/core/RoleService.ts @@ -13,7 +13,7 @@ import { UserEntityService } from '@/core/entities/UserEntityService.js'; import { StreamMessages } from '@/server/api/stream/types.js'; import type { OnApplicationShutdown } from '@nestjs/common'; -export type RoleOptions = { +export type RolePolicies = { gtlAvailable: boolean; ltlAvailable: boolean; canPublicNote: boolean; @@ -31,7 +31,7 @@ export type RoleOptions = { rateLimitFactor: number; }; -export const DEFAULT_ROLE: RoleOptions = { +export const DEFAULT_POLICIES: RolePolicies = { gtlAvailable: true, ltlAvailable: true, canPublicNote: true, @@ -195,26 +195,26 @@ export class RoleService implements OnApplicationShutdown { } @bindThis - public async getUserRoleOptions(userId: User['id'] | null): Promise { + public async getUserPolicies(userId: User['id'] | null): Promise { const meta = await this.metaService.fetch(); - const baseRoleOptions = { ...DEFAULT_ROLE, ...meta.defaultRoleOverride }; + const basePolicies = { ...DEFAULT_POLICIES, ...meta.policies }; - if (userId == null) return baseRoleOptions; + if (userId == null) return basePolicies; const roles = await this.getUserRoles(userId); - function calc(name: T, aggregate: (values: RoleOptions[T][]) => RoleOptions[T]) { - if (roles.length === 0) return baseRoleOptions[name]; + function calc(name: T, aggregate: (values: RolePolicies[T][]) => RolePolicies[T]) { + if (roles.length === 0) return basePolicies[name]; - const options = roles.map(role => role.options[name] ?? { priority: 0, useDefault: true }); + const policies = roles.map(role => role.policies[name] ?? { priority: 0, useDefault: true }); - const p2 = options.filter(option => option.priority === 2); - if (p2.length > 0) return aggregate(p2.map(option => option.useDefault ? baseRoleOptions[name] : option.value)); + const p2 = policies.filter(policy => policy.priority === 2); + if (p2.length > 0) return aggregate(p2.map(policy => policy.useDefault ? basePolicies[name] : policy.value)); - const p1 = options.filter(option => option.priority === 1); - if (p1.length > 0) return aggregate(p2.map(option => option.useDefault ? baseRoleOptions[name] : option.value)); + const p1 = policies.filter(policy => policy.priority === 1); + if (p1.length > 0) return aggregate(p2.map(policy => policy.useDefault ? basePolicies[name] : policy.value)); - return aggregate(options.map(option => option.useDefault ? baseRoleOptions[name] : option.value)); + return aggregate(policies.map(policy => policy.useDefault ? basePolicies[name] : policy.value)); } return { diff --git a/packages/backend/src/core/UserListService.ts b/packages/backend/src/core/UserListService.ts index 18c9787fa..fc4873830 100644 --- a/packages/backend/src/core/UserListService.ts +++ b/packages/backend/src/core/UserListService.ts @@ -35,7 +35,7 @@ export class UserListService { const currentCount = await this.userListJoiningsRepository.countBy({ userListId: list.id, }); - if (currentCount > (await this.roleService.getUserRoleOptions(me.id)).userEachUserListsLimit) { + if (currentCount > (await this.roleService.getUserPolicies(me.id)).userEachUserListsLimit) { throw new Error('Too many users'); } diff --git a/packages/backend/src/core/entities/RoleEntityService.ts b/packages/backend/src/core/entities/RoleEntityService.ts index 6a1477565..52f337446 100644 --- a/packages/backend/src/core/entities/RoleEntityService.ts +++ b/packages/backend/src/core/entities/RoleEntityService.ts @@ -6,7 +6,7 @@ import type { Packed } from '@/misc/schema.js'; import type { User } from '@/models/entities/User.js'; import type { Role } from '@/models/entities/Role.js'; import { bindThis } from '@/decorators.js'; -import { DEFAULT_ROLE } from '@/core/RoleService.js'; +import { DEFAULT_POLICIES } from '@/core/RoleService.js'; import { UserEntityService } from './UserEntityService.js'; @Injectable() @@ -40,9 +40,9 @@ export class RoleEntityService { roleId: role.id, }); - const roleOptions = { ...role.options }; - for (const [k, v] of Object.entries(DEFAULT_ROLE)) { - if (roleOptions[k] == null) roleOptions[k] = { + const policies = { ...role.policies }; + for (const [k, v] of Object.entries(DEFAULT_POLICIES)) { + if (policies[k] == null) policies[k] = { useDefault: true, priority: 0, value: v, @@ -62,7 +62,7 @@ export class RoleEntityService { isAdministrator: role.isAdministrator, isModerator: role.isModerator, canEditMembersByModerator: role.canEditMembersByModerator, - options: roleOptions, + policies: policies, usersCount: assigns.length, ...(opts.detail ? { users: this.userEntityService.packMany(assigns.map(x => x.userId), me), diff --git a/packages/backend/src/core/entities/UserEntityService.ts b/packages/backend/src/core/entities/UserEntityService.ts index 6b754150c..bf6f6f455 100644 --- a/packages/backend/src/core/entities/UserEntityService.ts +++ b/packages/backend/src/core/entities/UserEntityService.ts @@ -423,7 +423,7 @@ export class UserEntityService implements OnModuleInit { bannerUrl: user.banner ? this.driveFileEntityService.getPublicUrl(user.banner, false) : null, bannerBlurhash: user.banner?.blurhash ?? null, isLocked: user.isLocked, - isSilenced: this.roleService.getUserRoleOptions(user.id).then(r => !r.canPublicNote), + isSilenced: this.roleService.getUserPolicies(user.id).then(r => !r.canPublicNote), isSuspended: user.isSuspended ?? falsy, description: profile!.description, location: profile!.location, @@ -496,7 +496,7 @@ export class UserEntityService implements OnModuleInit { } : {}), ...(opts.includeSecrets ? { - role: this.roleService.getUserRoleOptions(user.id), + policies: this.roleService.getUserPolicies(user.id), email: profile!.email, emailVerified: profile!.emailVerified, securityKeysList: profile!.twoFactorEnabled diff --git a/packages/backend/src/models/entities/Meta.ts b/packages/backend/src/models/entities/Meta.ts index e724ba9a4..5d222a6da 100644 --- a/packages/backend/src/models/entities/Meta.ts +++ b/packages/backend/src/models/entities/Meta.ts @@ -458,5 +458,5 @@ export class Meta { @Column('jsonb', { default: { }, }) - public defaultRoleOverride: Record; + public policies: Record; } diff --git a/packages/backend/src/models/entities/Role.ts b/packages/backend/src/models/entities/Role.ts index d8d203493..abd5f864a 100644 --- a/packages/backend/src/models/entities/Role.ts +++ b/packages/backend/src/models/entities/Role.ts @@ -136,7 +136,7 @@ export class Role { @Column('jsonb', { default: { }, }) - public options: Record null) : null; - const baseRoleOptions = { ...DEFAULT_ROLE, ...meta.defaultRoleOverride }; + const basePolicies = { ...DEFAULT_POLICIES, ...meta.policies }; return { software: { @@ -105,8 +105,8 @@ export class NodeinfoServerService { repositoryUrl: meta.repositoryUrl, feedbackUrl: meta.feedbackUrl, disableRegistration: meta.disableRegistration, - disableLocalTimeline: !baseRoleOptions.ltlAvailable, - disableGlobalTimeline: !baseRoleOptions.gtlAvailable, + disableLocalTimeline: !basePolicies.ltlAvailable, + disableGlobalTimeline: !basePolicies.gtlAvailable, emailRequiredForSignup: meta.emailRequiredForSignup, enableHcaptcha: meta.enableHcaptcha, enableRecaptcha: meta.enableRecaptcha, diff --git a/packages/backend/src/server/api/ApiCallService.ts b/packages/backend/src/server/api/ApiCallService.ts index dcc9342a8..395a1c468 100644 --- a/packages/backend/src/server/api/ApiCallService.ts +++ b/packages/backend/src/server/api/ApiCallService.ts @@ -225,7 +225,7 @@ export class ApiCallService implements OnApplicationShutdown { } // TODO: 毎リクエスト計算するのもあれだしキャッシュしたい - const factor = user ? (await this.roleService.getUserRoleOptions(user.id)).rateLimitFactor : 1; + const factor = user ? (await this.roleService.getUserPolicies(user.id)).rateLimitFactor : 1; // Rate limit await this.rateLimiterService.limit(limit as IEndpointMeta['limit'] & { key: NonNullable }, limitActor, factor).catch(err => { @@ -274,9 +274,9 @@ export class ApiCallService implements OnApplicationShutdown { } } - if (ep.meta.requireRoleOption != null && !user!.isRoot) { - const myRole = await this.roleService.getUserRoleOptions(user!.id); - if (!myRole[ep.meta.requireRoleOption]) { + if (ep.meta.requireRolePolicy != null && !user!.isRoot) { + const policies = await this.roleService.getUserPolicies(user!.id); + if (!policies[ep.meta.requireRolePolicy]) { throw new ApiError({ message: 'You are not assigned to a required role.', code: 'ROLE_PERMISSION_DENIED', diff --git a/packages/backend/src/server/api/EndpointsModule.ts b/packages/backend/src/server/api/EndpointsModule.ts index aa88a9dd1..14927da7d 100644 --- a/packages/backend/src/server/api/EndpointsModule.ts +++ b/packages/backend/src/server/api/EndpointsModule.ts @@ -65,7 +65,7 @@ import * as ep___admin_roles_show from './endpoints/admin/roles/show.js'; import * as ep___admin_roles_update from './endpoints/admin/roles/update.js'; import * as ep___admin_roles_assign from './endpoints/admin/roles/assign.js'; import * as ep___admin_roles_unassign from './endpoints/admin/roles/unassign.js'; -import * as ep___admin_roles_updateDefaultRoleOverride from './endpoints/admin/roles/update-default-role-override.js'; +import * as ep___admin_roles_updateDefaultPolicies from './endpoints/admin/roles/update-default-policies.js'; import * as ep___announcements from './endpoints/announcements.js'; import * as ep___antennas_create from './endpoints/antennas/create.js'; import * as ep___antennas_delete from './endpoints/antennas/delete.js'; @@ -399,7 +399,7 @@ const $admin_roles_show: Provider = { provide: 'ep:admin/roles/show', useClass: const $admin_roles_update: Provider = { provide: 'ep:admin/roles/update', useClass: ep___admin_roles_update.default }; const $admin_roles_assign: Provider = { provide: 'ep:admin/roles/assign', useClass: ep___admin_roles_assign.default }; const $admin_roles_unassign: Provider = { provide: 'ep:admin/roles/unassign', useClass: ep___admin_roles_unassign.default }; -const $admin_roles_updateDefaultRoleOverride: Provider = { provide: 'ep:admin/roles/update-default-role-override', useClass: ep___admin_roles_updateDefaultRoleOverride.default }; +const $admin_roles_updateDefaultPolicies: Provider = { provide: 'ep:admin/roles/update-default-policies', useClass: ep___admin_roles_updateDefaultPolicies.default }; const $announcements: Provider = { provide: 'ep:announcements', useClass: ep___announcements.default }; const $antennas_create: Provider = { provide: 'ep:antennas/create', useClass: ep___antennas_create.default }; const $antennas_delete: Provider = { provide: 'ep:antennas/delete', useClass: ep___antennas_delete.default }; @@ -737,7 +737,7 @@ const $retention: Provider = { provide: 'ep:retention', useClass: ep___retention $admin_roles_update, $admin_roles_assign, $admin_roles_unassign, - $admin_roles_updateDefaultRoleOverride, + $admin_roles_updateDefaultPolicies, $announcements, $antennas_create, $antennas_delete, @@ -1069,7 +1069,7 @@ const $retention: Provider = { provide: 'ep:retention', useClass: ep___retention $admin_roles_update, $admin_roles_assign, $admin_roles_unassign, - $admin_roles_updateDefaultRoleOverride, + $admin_roles_updateDefaultPolicies, $announcements, $antennas_create, $antennas_delete, diff --git a/packages/backend/src/server/api/endpoints.ts b/packages/backend/src/server/api/endpoints.ts index f50a3b5dd..54c4206ea 100644 --- a/packages/backend/src/server/api/endpoints.ts +++ b/packages/backend/src/server/api/endpoints.ts @@ -64,7 +64,7 @@ import * as ep___admin_roles_show from './endpoints/admin/roles/show.js'; import * as ep___admin_roles_update from './endpoints/admin/roles/update.js'; import * as ep___admin_roles_assign from './endpoints/admin/roles/assign.js'; import * as ep___admin_roles_unassign from './endpoints/admin/roles/unassign.js'; -import * as ep___admin_roles_updateDefaultRoleOverride from './endpoints/admin/roles/update-default-role-override.js'; +import * as ep___admin_roles_updateDefaultPolicies from './endpoints/admin/roles/update-default-policies.js'; import * as ep___announcements from './endpoints/announcements.js'; import * as ep___antennas_create from './endpoints/antennas/create.js'; import * as ep___antennas_delete from './endpoints/antennas/delete.js'; @@ -396,7 +396,7 @@ const eps = [ ['admin/roles/update', ep___admin_roles_update], ['admin/roles/assign', ep___admin_roles_assign], ['admin/roles/unassign', ep___admin_roles_unassign], - ['admin/roles/update-default-role-override', ep___admin_roles_updateDefaultRoleOverride], + ['admin/roles/update-default-policies', ep___admin_roles_updateDefaultPolicies], ['announcements', ep___announcements], ['antennas/create', ep___antennas_create], ['antennas/delete', ep___antennas_delete], @@ -695,7 +695,7 @@ export interface IEndpointMeta { */ readonly requireAdmin?: boolean; - readonly requireRoleOption?: string; + readonly requireRolePolicy?: string; /** * エンドポイントのリミテーションに関するやつ diff --git a/packages/backend/src/server/api/endpoints/admin/emoji/add-aliases-bulk.ts b/packages/backend/src/server/api/endpoints/admin/emoji/add-aliases-bulk.ts index d114fd3d5..9b6c774f0 100644 --- a/packages/backend/src/server/api/endpoints/admin/emoji/add-aliases-bulk.ts +++ b/packages/backend/src/server/api/endpoints/admin/emoji/add-aliases-bulk.ts @@ -8,7 +8,7 @@ export const meta = { tags: ['admin'], requireCredential: true, - requireRoleOption: 'canManageCustomEmojis', + requireRolePolicy: 'canManageCustomEmojis', } as const; export const paramDef = { diff --git a/packages/backend/src/server/api/endpoints/admin/emoji/add.ts b/packages/backend/src/server/api/endpoints/admin/emoji/add.ts index 52ccb7444..abca1d169 100644 --- a/packages/backend/src/server/api/endpoints/admin/emoji/add.ts +++ b/packages/backend/src/server/api/endpoints/admin/emoji/add.ts @@ -14,7 +14,7 @@ export const meta = { tags: ['admin'], requireCredential: true, - requireRoleOption: 'canManageCustomEmojis', + requireRolePolicy: 'canManageCustomEmojis', errors: { noSuchFile: { diff --git a/packages/backend/src/server/api/endpoints/admin/emoji/copy.ts b/packages/backend/src/server/api/endpoints/admin/emoji/copy.ts index 4d1fdd989..b4fc7fd6f 100644 --- a/packages/backend/src/server/api/endpoints/admin/emoji/copy.ts +++ b/packages/backend/src/server/api/endpoints/admin/emoji/copy.ts @@ -14,7 +14,7 @@ export const meta = { tags: ['admin'], requireCredential: true, - requireRoleOption: 'canManageCustomEmojis', + requireRolePolicy: 'canManageCustomEmojis', errors: { noSuchEmoji: { diff --git a/packages/backend/src/server/api/endpoints/admin/emoji/delete-bulk.ts b/packages/backend/src/server/api/endpoints/admin/emoji/delete-bulk.ts index 27aa4fb1b..ae45105b2 100644 --- a/packages/backend/src/server/api/endpoints/admin/emoji/delete-bulk.ts +++ b/packages/backend/src/server/api/endpoints/admin/emoji/delete-bulk.ts @@ -9,7 +9,7 @@ export const meta = { tags: ['admin'], requireCredential: true, - requireRoleOption: 'canManageCustomEmojis', + requireRolePolicy: 'canManageCustomEmojis', } as const; export const paramDef = { diff --git a/packages/backend/src/server/api/endpoints/admin/emoji/delete.ts b/packages/backend/src/server/api/endpoints/admin/emoji/delete.ts index 253124656..e237d87d3 100644 --- a/packages/backend/src/server/api/endpoints/admin/emoji/delete.ts +++ b/packages/backend/src/server/api/endpoints/admin/emoji/delete.ts @@ -10,7 +10,7 @@ export const meta = { tags: ['admin'], requireCredential: true, - requireRoleOption: 'canManageCustomEmojis', + requireRolePolicy: 'canManageCustomEmojis', errors: { noSuchEmoji: { diff --git a/packages/backend/src/server/api/endpoints/admin/emoji/import-zip.ts b/packages/backend/src/server/api/endpoints/admin/emoji/import-zip.ts index 15f468c18..b4a07324b 100644 --- a/packages/backend/src/server/api/endpoints/admin/emoji/import-zip.ts +++ b/packages/backend/src/server/api/endpoints/admin/emoji/import-zip.ts @@ -5,7 +5,7 @@ import { QueueService } from '@/core/QueueService.js'; export const meta = { secure: true, requireCredential: true, - requireRoleOption: 'canManageCustomEmojis', + requireRolePolicy: 'canManageCustomEmojis', } as const; export const paramDef = { diff --git a/packages/backend/src/server/api/endpoints/admin/emoji/list-remote.ts b/packages/backend/src/server/api/endpoints/admin/emoji/list-remote.ts index 131c9ef22..d9ce97194 100644 --- a/packages/backend/src/server/api/endpoints/admin/emoji/list-remote.ts +++ b/packages/backend/src/server/api/endpoints/admin/emoji/list-remote.ts @@ -11,7 +11,7 @@ export const meta = { tags: ['admin'], requireCredential: true, - requireRoleOption: 'canManageCustomEmojis', + requireRolePolicy: 'canManageCustomEmojis', res: { type: 'array', diff --git a/packages/backend/src/server/api/endpoints/admin/emoji/list.ts b/packages/backend/src/server/api/endpoints/admin/emoji/list.ts index ef2bc936c..1a6096f36 100644 --- a/packages/backend/src/server/api/endpoints/admin/emoji/list.ts +++ b/packages/backend/src/server/api/endpoints/admin/emoji/list.ts @@ -11,7 +11,7 @@ export const meta = { tags: ['admin'], requireCredential: true, - requireRoleOption: 'canManageCustomEmojis', + requireRolePolicy: 'canManageCustomEmojis', res: { type: 'array', diff --git a/packages/backend/src/server/api/endpoints/admin/emoji/remove-aliases-bulk.ts b/packages/backend/src/server/api/endpoints/admin/emoji/remove-aliases-bulk.ts index a70cd8d78..5fc9e024b 100644 --- a/packages/backend/src/server/api/endpoints/admin/emoji/remove-aliases-bulk.ts +++ b/packages/backend/src/server/api/endpoints/admin/emoji/remove-aliases-bulk.ts @@ -8,7 +8,7 @@ export const meta = { tags: ['admin'], requireCredential: true, - requireRoleOption: 'canManageCustomEmojis', + requireRolePolicy: 'canManageCustomEmojis', } as const; export const paramDef = { diff --git a/packages/backend/src/server/api/endpoints/admin/emoji/set-aliases-bulk.ts b/packages/backend/src/server/api/endpoints/admin/emoji/set-aliases-bulk.ts index b33e5662b..8b5ba8fbf 100644 --- a/packages/backend/src/server/api/endpoints/admin/emoji/set-aliases-bulk.ts +++ b/packages/backend/src/server/api/endpoints/admin/emoji/set-aliases-bulk.ts @@ -8,7 +8,7 @@ export const meta = { tags: ['admin'], requireCredential: true, - requireRoleOption: 'canManageCustomEmojis', + requireRolePolicy: 'canManageCustomEmojis', } as const; export const paramDef = { diff --git a/packages/backend/src/server/api/endpoints/admin/emoji/set-category-bulk.ts b/packages/backend/src/server/api/endpoints/admin/emoji/set-category-bulk.ts index 05834bc57..827b5ace7 100644 --- a/packages/backend/src/server/api/endpoints/admin/emoji/set-category-bulk.ts +++ b/packages/backend/src/server/api/endpoints/admin/emoji/set-category-bulk.ts @@ -8,7 +8,7 @@ export const meta = { tags: ['admin'], requireCredential: true, - requireRoleOption: 'canManageCustomEmojis', + requireRolePolicy: 'canManageCustomEmojis', } as const; export const paramDef = { diff --git a/packages/backend/src/server/api/endpoints/admin/emoji/update.ts b/packages/backend/src/server/api/endpoints/admin/emoji/update.ts index 19645cb51..fb0ef1287 100644 --- a/packages/backend/src/server/api/endpoints/admin/emoji/update.ts +++ b/packages/backend/src/server/api/endpoints/admin/emoji/update.ts @@ -9,7 +9,7 @@ export const meta = { tags: ['admin'], requireCredential: true, - requireRoleOption: 'canManageCustomEmojis', + requireRolePolicy: 'canManageCustomEmojis', errors: { noSuchEmoji: { diff --git a/packages/backend/src/server/api/endpoints/admin/meta.ts b/packages/backend/src/server/api/endpoints/admin/meta.ts index fd08a5f84..b39382705 100644 --- a/packages/backend/src/server/api/endpoints/admin/meta.ts +++ b/packages/backend/src/server/api/endpoints/admin/meta.ts @@ -4,7 +4,7 @@ import { Endpoint } from '@/server/api/endpoint-base.js'; import { MetaService } from '@/core/MetaService.js'; import type { Config } from '@/config.js'; import { DI } from '@/di-symbols.js'; -import { DEFAULT_ROLE } from '@/core/RoleService.js'; +import { DEFAULT_POLICIES } from '@/core/RoleService.js'; export const meta = { tags: ['meta'], @@ -440,7 +440,7 @@ export default class extends Endpoint { deeplIsPro: instance.deeplIsPro, enableIpLogging: instance.enableIpLogging, enableActiveEmailValidation: instance.enableActiveEmailValidation, - baseRole: { ...DEFAULT_ROLE, ...instance.defaultRoleOverride }, + policies: { ...DEFAULT_POLICIES, ...instance.policies }, }; }); } diff --git a/packages/backend/src/server/api/endpoints/admin/roles/create.ts b/packages/backend/src/server/api/endpoints/admin/roles/create.ts index a9216a638..f136c6d62 100644 --- a/packages/backend/src/server/api/endpoints/admin/roles/create.ts +++ b/packages/backend/src/server/api/endpoints/admin/roles/create.ts @@ -25,7 +25,7 @@ export const paramDef = { isModerator: { type: 'boolean' }, isAdministrator: { type: 'boolean' }, canEditMembersByModerator: { type: 'boolean' }, - options: { + policies: { type: 'object', }, }, @@ -39,7 +39,7 @@ export const paramDef = { 'isModerator', 'isAdministrator', 'canEditMembersByModerator', - 'options', + 'policies', ], } as const; @@ -70,7 +70,7 @@ export default class extends Endpoint { isAdministrator: ps.isAdministrator, isModerator: ps.isModerator, canEditMembersByModerator: ps.canEditMembersByModerator, - options: ps.options, + policies: ps.policies, }).then(x => this.rolesRepository.findOneByOrFail(x.identifiers[0])); this.globalEventService.publishInternalEvent('roleCreated', created); diff --git a/packages/backend/src/server/api/endpoints/admin/roles/update-default-role-override.ts b/packages/backend/src/server/api/endpoints/admin/roles/update-default-policies.ts similarity index 85% rename from packages/backend/src/server/api/endpoints/admin/roles/update-default-role-override.ts rename to packages/backend/src/server/api/endpoints/admin/roles/update-default-policies.ts index 35da04efd..6006816bc 100644 --- a/packages/backend/src/server/api/endpoints/admin/roles/update-default-role-override.ts +++ b/packages/backend/src/server/api/endpoints/admin/roles/update-default-policies.ts @@ -16,12 +16,12 @@ export const meta = { export const paramDef = { type: 'object', properties: { - options: { + policies: { type: 'object', }, }, required: [ - 'options', + 'policies', ], } as const; @@ -34,9 +34,9 @@ export default class extends Endpoint { ) { super(meta, paramDef, async (ps) => { await this.metaService.update({ - defaultRoleOverride: ps.options, + policies: ps.policies, }); - this.globalEventService.publishInternalEvent('defaultRoleOverrideUpdated', ps.options); + this.globalEventService.publishInternalEvent('policiesUpdated', ps.policies); }); } } diff --git a/packages/backend/src/server/api/endpoints/admin/roles/update.ts b/packages/backend/src/server/api/endpoints/admin/roles/update.ts index 4ca5124ed..fc4c3d8f1 100644 --- a/packages/backend/src/server/api/endpoints/admin/roles/update.ts +++ b/packages/backend/src/server/api/endpoints/admin/roles/update.ts @@ -33,7 +33,7 @@ export const paramDef = { isModerator: { type: 'boolean' }, isAdministrator: { type: 'boolean' }, canEditMembersByModerator: { type: 'boolean' }, - options: { + policies: { type: 'object', }, }, @@ -48,7 +48,7 @@ export const paramDef = { 'isModerator', 'isAdministrator', 'canEditMembersByModerator', - 'options', + 'policies', ], } as const; @@ -79,7 +79,7 @@ export default class extends Endpoint { isModerator: ps.isModerator, isAdministrator: ps.isAdministrator, canEditMembersByModerator: ps.canEditMembersByModerator, - options: ps.options, + policies: ps.policies, }); const updated = await this.rolesRepository.findOneByOrFail({ id: ps.roleId }); this.globalEventService.publishInternalEvent('roleUpdated', updated); diff --git a/packages/backend/src/server/api/endpoints/admin/show-user.ts b/packages/backend/src/server/api/endpoints/admin/show-user.ts index 3f4ec299a..94603cc91 100644 --- a/packages/backend/src/server/api/endpoints/admin/show-user.ts +++ b/packages/backend/src/server/api/endpoints/admin/show-user.ts @@ -52,7 +52,7 @@ export default class extends Endpoint { } const isModerator = await this.roleService.isModerator(user); - const isSilenced = !(await this.roleService.getUserRoleOptions(user.id)).canPublicNote; + const isSilenced = !(await this.roleService.getUserPolicies(user.id)).canPublicNote; const _me = await this.usersRepository.findOneByOrFail({ id: me.id }); if (!await this.roleService.isAdministrator(_me) && await this.roleService.isAdministrator(user)) { @@ -94,6 +94,7 @@ export default class extends Endpoint { lastActiveDate: user.lastActiveDate, moderationNote: profile.moderationNote, signins, + policies: await this.roleService.getUserPolicies(user.id), roles: await this.roleEntityService.packMany(roles, me, { detail: false }), }; }); diff --git a/packages/backend/src/server/api/endpoints/antennas/create.ts b/packages/backend/src/server/api/endpoints/antennas/create.ts index 08625250c..a1553b6a8 100644 --- a/packages/backend/src/server/api/endpoints/antennas/create.ts +++ b/packages/backend/src/server/api/endpoints/antennas/create.ts @@ -92,7 +92,7 @@ export default class extends Endpoint { const currentAntennasCount = await this.antennasRepository.countBy({ userId: me.id, }); - if (currentAntennasCount > (await this.roleService.getUserRoleOptions(me.id)).antennaLimit) { + if (currentAntennasCount > (await this.roleService.getUserPolicies(me.id)).antennaLimit) { throw new ApiError(meta.errors.tooManyAntennas); } diff --git a/packages/backend/src/server/api/endpoints/clips/add-note.ts b/packages/backend/src/server/api/endpoints/clips/add-note.ts index 3cf096c24..f3f9c3477 100644 --- a/packages/backend/src/server/api/endpoints/clips/add-note.ts +++ b/packages/backend/src/server/api/endpoints/clips/add-note.ts @@ -97,7 +97,7 @@ export default class extends Endpoint { const currentCount = await this.clipNotesRepository.countBy({ clipId: clip.id, }); - if (currentCount > (await this.roleService.getUserRoleOptions(me.id)).noteEachClipsLimit) { + if (currentCount > (await this.roleService.getUserPolicies(me.id)).noteEachClipsLimit) { throw new ApiError(meta.errors.tooManyClipNotes); } diff --git a/packages/backend/src/server/api/endpoints/clips/create.ts b/packages/backend/src/server/api/endpoints/clips/create.ts index abc0288c8..c095de702 100644 --- a/packages/backend/src/server/api/endpoints/clips/create.ts +++ b/packages/backend/src/server/api/endpoints/clips/create.ts @@ -54,7 +54,7 @@ export default class extends Endpoint { const currentCount = await this.clipsRepository.countBy({ userId: me.id, }); - if (currentCount > (await this.roleService.getUserRoleOptions(me.id)).clipLimit) { + if (currentCount > (await this.roleService.getUserPolicies(me.id)).clipLimit) { throw new ApiError(meta.errors.tooManyClips); } diff --git a/packages/backend/src/server/api/endpoints/drive.ts b/packages/backend/src/server/api/endpoints/drive.ts index 2a06792dc..e5bbfecbc 100644 --- a/packages/backend/src/server/api/endpoints/drive.ts +++ b/packages/backend/src/server/api/endpoints/drive.ts @@ -47,10 +47,10 @@ export default class extends Endpoint { // Calculate drive usage const usage = await this.driveFileEntityService.calcDriveUsageOf(me.id); - const myRole = await this.roleService.getUserRoleOptions(me.id); + const policies = await this.roleService.getUserPolicies(me.id); return { - capacity: 1024 * 1024 * myRole.driveCapacityMb, + capacity: 1024 * 1024 * policies.driveCapacityMb, usage: usage, }; }); diff --git a/packages/backend/src/server/api/endpoints/i/update.ts b/packages/backend/src/server/api/endpoints/i/update.ts index fe09eca67..b1eaab390 100644 --- a/packages/backend/src/server/api/endpoints/i/update.ts +++ b/packages/backend/src/server/api/endpoints/i/update.ts @@ -173,7 +173,7 @@ export default class extends Endpoint { if (ps.mutedWords !== undefined) { // TODO: ちゃんと数える const length = JSON.stringify(ps.mutedWords).length; - if (length > (await this.roleService.getUserRoleOptions(user.id)).wordMuteLimit) { + if (length > (await this.roleService.getUserPolicies(user.id)).wordMuteLimit) { throw new ApiError(meta.errors.tooManyMutedWords); } diff --git a/packages/backend/src/server/api/endpoints/i/webhooks/create.ts b/packages/backend/src/server/api/endpoints/i/webhooks/create.ts index 3d89b77a7..51fcce6cf 100644 --- a/packages/backend/src/server/api/endpoints/i/webhooks/create.ts +++ b/packages/backend/src/server/api/endpoints/i/webhooks/create.ts @@ -54,7 +54,7 @@ export default class extends Endpoint { const currentWebhooksCount = await this.webhooksRepository.countBy({ userId: me.id, }); - if (currentWebhooksCount > (await this.roleService.getUserRoleOptions(me.id)).webhookLimit) { + if (currentWebhooksCount > (await this.roleService.getUserPolicies(me.id)).webhookLimit) { throw new ApiError(meta.errors.tooManyWebhooks); } diff --git a/packages/backend/src/server/api/endpoints/invite.ts b/packages/backend/src/server/api/endpoints/invite.ts index 9b03cf4bb..5d2c479e7 100644 --- a/packages/backend/src/server/api/endpoints/invite.ts +++ b/packages/backend/src/server/api/endpoints/invite.ts @@ -9,7 +9,7 @@ export const meta = { tags: ['meta'], requireCredential: true, - requireRoleOption: 'canInvite', + requireRolePolicy: 'canInvite', res: { type: 'object', diff --git a/packages/backend/src/server/api/endpoints/meta.ts b/packages/backend/src/server/api/endpoints/meta.ts index f46a32dfe..89fa50317 100644 --- a/packages/backend/src/server/api/endpoints/meta.ts +++ b/packages/backend/src/server/api/endpoints/meta.ts @@ -7,7 +7,7 @@ import { UserEntityService } from '@/core/entities/UserEntityService.js'; import { MetaService } from '@/core/MetaService.js'; import type { Config } from '@/config.js'; import { DI } from '@/di-symbols.js'; -import { DEFAULT_ROLE } from '@/core/RoleService.js'; +import { DEFAULT_POLICIES } from '@/core/RoleService.js'; export const meta = { tags: ['meta'], @@ -334,7 +334,7 @@ export default class extends Endpoint { translatorAvailable: instance.deeplAuthKey != null, - baseRole: { ...DEFAULT_ROLE, ...instance.defaultRoleOverride }, + policies: { ...DEFAULT_POLICIES, ...instance.policies }, ...(ps.detail ? { pinnedPages: instance.pinnedPages, diff --git a/packages/backend/src/server/api/endpoints/notes/global-timeline.ts b/packages/backend/src/server/api/endpoints/notes/global-timeline.ts index 081563493..5d0cdc3fc 100644 --- a/packages/backend/src/server/api/endpoints/notes/global-timeline.ts +++ b/packages/backend/src/server/api/endpoints/notes/global-timeline.ts @@ -62,8 +62,8 @@ export default class extends Endpoint { private activeUsersChart: ActiveUsersChart, ) { super(meta, paramDef, async (ps, me) => { - const role = await this.roleService.getUserRoleOptions(me ? me.id : null); - if (!role.gtlAvailable) { + const policies = await this.roleService.getUserPolicies(me ? me.id : null); + if (!policies.gtlAvailable) { throw new ApiError(meta.errors.gtlDisabled); } diff --git a/packages/backend/src/server/api/endpoints/notes/hybrid-timeline.ts b/packages/backend/src/server/api/endpoints/notes/hybrid-timeline.ts index b2c504448..2819abb12 100644 --- a/packages/backend/src/server/api/endpoints/notes/hybrid-timeline.ts +++ b/packages/backend/src/server/api/endpoints/notes/hybrid-timeline.ts @@ -71,8 +71,8 @@ export default class extends Endpoint { private activeUsersChart: ActiveUsersChart, ) { super(meta, paramDef, async (ps, me) => { - const role = await this.roleService.getUserRoleOptions(me.id); - if (!role.ltlAvailable) { + const policies = await this.roleService.getUserPolicies(me.id); + if (!policies.ltlAvailable) { throw new ApiError(meta.errors.stlDisabled); } diff --git a/packages/backend/src/server/api/endpoints/notes/local-timeline.ts b/packages/backend/src/server/api/endpoints/notes/local-timeline.ts index 6361edc31..f396f7e58 100644 --- a/packages/backend/src/server/api/endpoints/notes/local-timeline.ts +++ b/packages/backend/src/server/api/endpoints/notes/local-timeline.ts @@ -67,8 +67,8 @@ export default class extends Endpoint { private activeUsersChart: ActiveUsersChart, ) { super(meta, paramDef, async (ps, me) => { - const role = await this.roleService.getUserRoleOptions(me ? me.id : null); - if (!role.ltlAvailable) { + const policies = await this.roleService.getUserPolicies(me ? me.id : null); + if (!policies.ltlAvailable) { throw new ApiError(meta.errors.ltlDisabled); } diff --git a/packages/backend/src/server/api/endpoints/users/lists/create.ts b/packages/backend/src/server/api/endpoints/users/lists/create.ts index 22e5e3ce7..a840c1a04 100644 --- a/packages/backend/src/server/api/endpoints/users/lists/create.ts +++ b/packages/backend/src/server/api/endpoints/users/lists/create.ts @@ -55,7 +55,7 @@ export default class extends Endpoint { const currentCount = await this.userListsRepository.countBy({ userId: me.id, }); - if (currentCount > (await this.roleService.getUserRoleOptions(me.id)).userListLimit) { + if (currentCount > (await this.roleService.getUserPolicies(me.id)).userListLimit) { throw new ApiError(meta.errors.tooManyUserLists); } diff --git a/packages/backend/src/server/api/stream/channels/global-timeline.ts b/packages/backend/src/server/api/stream/channels/global-timeline.ts index 185c81386..43d8907fc 100644 --- a/packages/backend/src/server/api/stream/channels/global-timeline.ts +++ b/packages/backend/src/server/api/stream/channels/global-timeline.ts @@ -29,8 +29,8 @@ class GlobalTimelineChannel extends Channel { @bindThis public async init(params: any) { - const role = await this.roleService.getUserRoleOptions(this.user ? this.user.id : null); - if (!role.gtlAvailable) return; + const policies = await this.roleService.getUserPolicies(this.user ? this.user.id : null); + if (!policies.gtlAvailable) return; // Subscribe events this.subscriber.on('notesStream', this.onNote); diff --git a/packages/backend/src/server/api/stream/channels/hybrid-timeline.ts b/packages/backend/src/server/api/stream/channels/hybrid-timeline.ts index a0f75f202..340f67781 100644 --- a/packages/backend/src/server/api/stream/channels/hybrid-timeline.ts +++ b/packages/backend/src/server/api/stream/channels/hybrid-timeline.ts @@ -30,8 +30,8 @@ class HybridTimelineChannel extends Channel { @bindThis public async init(params: any): Promise { - const role = await this.roleService.getUserRoleOptions(this.user ? this.user.id : null); - if (!role.ltlAvailable) return; + const policies = await this.roleService.getUserPolicies(this.user ? this.user.id : null); + if (!policies.ltlAvailable) return; // Subscribe events this.subscriber.on('notesStream', this.onNote); diff --git a/packages/backend/src/server/api/stream/channels/local-timeline.ts b/packages/backend/src/server/api/stream/channels/local-timeline.ts index 7d76f42fe..ea29e30d6 100644 --- a/packages/backend/src/server/api/stream/channels/local-timeline.ts +++ b/packages/backend/src/server/api/stream/channels/local-timeline.ts @@ -28,8 +28,8 @@ class LocalTimelineChannel extends Channel { @bindThis public async init(params: any) { - const role = await this.roleService.getUserRoleOptions(this.user ? this.user.id : null); - if (!role.ltlAvailable) return; + const policies = await this.roleService.getUserPolicies(this.user ? this.user.id : null); + if (!policies.ltlAvailable) return; // Subscribe events this.subscriber.on('notesStream', this.onNote); diff --git a/packages/backend/src/server/api/stream/types.ts b/packages/backend/src/server/api/stream/types.ts index 03837baef..a442529bb 100644 --- a/packages/backend/src/server/api/stream/types.ts +++ b/packages/backend/src/server/api/stream/types.ts @@ -30,7 +30,7 @@ export interface InternalStreamTypes { remoteUserUpdated: Serialized<{ id: User['id']; }>; follow: Serialized<{ followerId: User['id']; followeeId: User['id']; }>; unfollow: Serialized<{ followerId: User['id']; followeeId: User['id']; }>; - defaultRoleOverrideUpdated: Serialized; + policiesUpdated: Serialized; roleCreated: Serialized; roleDeleted: Serialized; roleUpdated: Serialized; diff --git a/packages/frontend/src/pages/admin/roles.editor.vue b/packages/frontend/src/pages/admin/roles.editor.vue index 0f67cec0b..d0be0a8c3 100644 --- a/packages/frontend/src/pages/admin/roles.editor.vue +++ b/packages/frontend/src/pages/admin/roles.editor.vue @@ -36,20 +36,20 @@ - +
- +
- + - + - +
@@ -57,15 +57,15 @@ - +
- + - + - +
@@ -73,15 +73,15 @@ - +
- + - + - +
@@ -89,15 +89,15 @@ - +
- + - + - +
@@ -105,15 +105,15 @@ - +
- + - + - +
@@ -121,15 +121,15 @@ - +
- + - + - +
@@ -137,15 +137,15 @@ - +
- + - + - +
@@ -153,14 +153,14 @@ - +
- + - + - +
@@ -168,14 +168,14 @@ - +
- + - + - +
@@ -183,15 +183,15 @@ - +
- + - + - +
@@ -199,14 +199,14 @@ - +
- + - + - +
@@ -214,14 +214,14 @@ - +
- + - + - +
@@ -229,14 +229,14 @@ - +
- + - + - +
@@ -244,14 +244,14 @@ - +
- + - + - +
@@ -259,14 +259,14 @@ - +
- + - + - +
@@ -306,7 +306,7 @@ import * as os from '@/os'; import { i18n } from '@/i18n'; import { instance } from '@/instance'; -const ROLE_OPTIONS = [ +const ROLE_POLICIES = [ 'gtlAvailable', 'ltlAvailable', 'canPublicNote', @@ -345,13 +345,13 @@ let condFormula = $ref(role?.condFormula ?? { id: uuid(), type: 'isRemote' }); let isPublic = $ref(role?.isPublic ?? false); let canEditMembersByModerator = $ref(role?.canEditMembersByModerator ?? false); -const options = reactive>({}); -for (const ROLE_OPTION of ROLE_OPTIONS) { - const _options = role?.options ?? {}; - options[ROLE_OPTION] = { - useDefault: _options[ROLE_OPTION]?.useDefault ?? true, - priority: _options[ROLE_OPTION]?.priority ?? 0, - value: _options[ROLE_OPTION]?.value ?? instance.baseRole[ROLE_OPTION], +const policies = reactive>({}); +for (const ROLE_POLICY of ROLE_POLICIES) { + const _policies = role?.policies ?? {}; + policies[ROLE_POLICY] = { + useDefault: _policies[ROLE_POLICY]?.useDefault ?? true, + priority: _policies[ROLE_POLICY]?.priority ?? 0, + value: _policies[ROLE_POLICY]?.value ?? instance.policies[ROLE_POLICY], }; } @@ -381,7 +381,7 @@ async function save() { isModerator: rolePermission === 'moderator', isPublic, canEditMembersByModerator, - options, + policies, }); emit('updated'); } else { @@ -395,7 +395,7 @@ async function save() { isModerator: rolePermission === 'moderator', isPublic, canEditMembersByModerator, - options, + policies, }); emit('created', created); } diff --git a/packages/frontend/src/pages/admin/roles.vue b/packages/frontend/src/pages/admin/roles.vue index 1ceead8b6..f074069df 100644 --- a/packages/frontend/src/pages/admin/roles.vue +++ b/packages/frontend/src/pages/admin/roles.vue @@ -10,114 +10,114 @@
- - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + @@ -134,7 +134,7 @@