diff --git a/locales/en-US.yml b/locales/en-US.yml index 17268af1cb..c828c5c2f8 100644 --- a/locales/en-US.yml +++ b/locales/en-US.yml @@ -2096,6 +2096,7 @@ _role: canSearchNotes: "Usage of note search" canSearchUsers: "User search" canUseTranslator: "Translator usage" + canCreateChannel: "Can create channels" avatarDecorationLimit: "Maximum number of avatar decorations" canImportAntennas: "Can import antennas" canImportBlocking: "Can import blocking" diff --git a/locales/ja-JP.yml b/locales/ja-JP.yml index 45d2efdf35..50a4e83548 100644 --- a/locales/ja-JP.yml +++ b/locales/ja-JP.yml @@ -2121,6 +2121,7 @@ _role: canSearchNotes: "ノート検索の利用" canSearchUsers: "ユーザー検索の利用" canUseTranslator: "翻訳機能の利用" + canCreateChannel: "チャンネルの作成" avatarDecorationLimit: "アイコンデコレーションの最大取付個数" canImportAntennas: "アンテナのインポートを許可" canImportBlocking: "ブロックのインポートを許可" diff --git a/packages/backend/src/core/RoleService.ts b/packages/backend/src/core/RoleService.ts index 2ffee69c21..7fd26726a7 100644 --- a/packages/backend/src/core/RoleService.ts +++ b/packages/backend/src/core/RoleService.ts @@ -47,6 +47,7 @@ export type RolePolicies = { canSearchUsers: boolean; canUseTranslator: boolean; canHideAds: boolean; + canCreateChannel: boolean; driveCapacityMb: number; maxFileSizeMb: number; alwaysMarkNsfw: boolean; @@ -88,6 +89,7 @@ export const DEFAULT_POLICIES: RolePolicies = { canSearchUsers: true, canUseTranslator: true, canHideAds: false, + canCreateChannel: true, driveCapacityMb: 100, maxFileSizeMb: 30, alwaysMarkNsfw: false, @@ -410,6 +412,7 @@ export class RoleService implements OnApplicationShutdown, OnModuleInit { canSearchUsers: calc('canSearchUsers', vs => vs.some(v => v === true)), canUseTranslator: calc('canUseTranslator', vs => vs.some(v => v === true)), canHideAds: calc('canHideAds', vs => vs.some(v => v === true)), + canCreateChannel: calc('canCreateChannel', vs => vs.some(v => v === true)), driveCapacityMb: calc('driveCapacityMb', vs => Math.max(...vs)), maxFileSizeMb: calc('maxFileSizeMb', vs => Math.max(...vs)), alwaysMarkNsfw: calc('alwaysMarkNsfw', vs => vs.some(v => v === true)), diff --git a/packages/backend/src/models/json-schema/role.ts b/packages/backend/src/models/json-schema/role.ts index b9000152d4..eaed3ac710 100644 --- a/packages/backend/src/models/json-schema/role.ts +++ b/packages/backend/src/models/json-schema/role.ts @@ -224,6 +224,10 @@ export const packedRolePoliciesSchema = { type: 'boolean', optional: false, nullable: false, }, + canCreateChannel: { + type: 'boolean', + optional: false, nullable: false, + }, driveCapacityMb: { type: 'integer', optional: false, nullable: false, diff --git a/packages/backend/src/server/api/endpoints/channels/create.ts b/packages/backend/src/server/api/endpoints/channels/create.ts index 8d49b6fd0f..0536f7a775 100644 --- a/packages/backend/src/server/api/endpoints/channels/create.ts +++ b/packages/backend/src/server/api/endpoints/channels/create.ts @@ -22,6 +22,8 @@ export const meta = { kind: 'write:channels', + requiredRolePolicy: 'canCreateChannel', + limit: { duration: ms('1hour'), max: 10, diff --git a/packages/frontend/src/pages/admin/roles.editor.vue b/packages/frontend/src/pages/admin/roles.editor.vue index 7de973a394..e8527b0761 100644 --- a/packages/frontend/src/pages/admin/roles.editor.vue +++ b/packages/frontend/src/pages/admin/roles.editor.vue @@ -387,6 +387,26 @@ SPDX-License-Identifier: AGPL-3.0-only + + + +
+ + + + + + + + + +
+
+