diff --git a/CHANGELOG.md b/CHANGELOG.md
index a2d2e62a62..cc8f9c5081 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,7 @@
### General
- Feat: UserWebhookとSystemWebhookのテスト送信機能を追加 (#14445)
+- Enhance: ユーザーによるコンテンツインポートの可否をロールポリシーで制御できるように
### Client
- Feat: ノート単体・ユーザーのノート・クリップのノートの埋め込み機能
diff --git a/locales/index.d.ts b/locales/index.d.ts
index 798cb89f83..f234262195 100644
--- a/locales/index.d.ts
+++ b/locales/index.d.ts
@@ -6766,6 +6766,26 @@ export interface Locale extends ILocale {
* アイコンデコレーションの最大取付個数
*/
"avatarDecorationLimit": string;
+ /**
+ * アンテナのインポートを許可
+ */
+ "canImportAntennas": string;
+ /**
+ * ブロックのインポートを許可
+ */
+ "canImportBlocking": string;
+ /**
+ * フォローのインポートを許可
+ */
+ "canImportFollowing": string;
+ /**
+ * ミュートのインポートを許可
+ */
+ "canImportMuting": string;
+ /**
+ * リストのインポートを許可
+ */
+ "canImportUserLists": string;
};
"_condition": {
/**
diff --git a/locales/ja-JP.yml b/locales/ja-JP.yml
index 726e4f4ef4..8e48508e78 100644
--- a/locales/ja-JP.yml
+++ b/locales/ja-JP.yml
@@ -1748,6 +1748,11 @@ _role:
canSearchNotes: "ノート検索の利用"
canUseTranslator: "翻訳機能の利用"
avatarDecorationLimit: "アイコンデコレーションの最大取付個数"
+ canImportAntennas: "アンテナのインポートを許可"
+ canImportBlocking: "ブロックのインポートを許可"
+ canImportFollowing: "フォローのインポートを許可"
+ canImportMuting: "ミュートのインポートを許可"
+ canImportUserLists: "リストのインポートを許可"
_condition:
roleAssignedTo: "マニュアルロールにアサイン済み"
isLocal: "ローカルユーザー"
diff --git a/packages/backend/src/core/RoleService.ts b/packages/backend/src/core/RoleService.ts
index 0210012a03..24752edcf6 100644
--- a/packages/backend/src/core/RoleService.ts
+++ b/packages/backend/src/core/RoleService.ts
@@ -58,6 +58,11 @@ export type RolePolicies = {
userEachUserListsLimit: number;
rateLimitFactor: number;
avatarDecorationLimit: number;
+ canImportAntennas: boolean;
+ canImportBlocking: boolean;
+ canImportFollowing: boolean;
+ canImportMuting: boolean;
+ canImportUserLists: boolean;
};
export const DEFAULT_POLICIES: RolePolicies = {
@@ -87,6 +92,11 @@ export const DEFAULT_POLICIES: RolePolicies = {
userEachUserListsLimit: 50,
rateLimitFactor: 1,
avatarDecorationLimit: 1,
+ canImportAntennas: true,
+ canImportBlocking: true,
+ canImportFollowing: true,
+ canImportMuting: true,
+ canImportUserLists: true,
};
@Injectable()
@@ -387,6 +397,11 @@ export class RoleService implements OnApplicationShutdown, OnModuleInit {
userEachUserListsLimit: calc('userEachUserListsLimit', vs => Math.max(...vs)),
rateLimitFactor: calc('rateLimitFactor', vs => Math.max(...vs)),
avatarDecorationLimit: calc('avatarDecorationLimit', vs => Math.max(...vs)),
+ canImportAntennas: calc('canImportAntennas', vs => vs.some(v => v === true)),
+ canImportBlocking: calc('canImportBlocking', vs => vs.some(v => v === true)),
+ canImportFollowing: calc('canImportFollowing', vs => vs.some(v => v === true)),
+ canImportMuting: calc('canImportMuting', vs => vs.some(v => v === true)),
+ canImportUserLists: calc('canImportUserLists', 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 7366f05356..3537de94c8 100644
--- a/packages/backend/src/models/json-schema/role.ts
+++ b/packages/backend/src/models/json-schema/role.ts
@@ -272,6 +272,26 @@ export const packedRolePoliciesSchema = {
type: 'integer',
optional: false, nullable: false,
},
+ canImportAntennas: {
+ type: 'boolean',
+ optional: false, nullable: false,
+ },
+ canImportBlocking: {
+ type: 'boolean',
+ optional: false, nullable: false,
+ },
+ canImportFollowing: {
+ type: 'boolean',
+ optional: false, nullable: false,
+ },
+ canImportMuting: {
+ type: 'boolean',
+ optional: false, nullable: false,
+ },
+ canImportUserLists: {
+ type: 'boolean',
+ optional: false, nullable: false,
+ },
},
} as const;
diff --git a/packages/backend/src/server/api/endpoints/i/import-antennas.ts b/packages/backend/src/server/api/endpoints/i/import-antennas.ts
index bc46163e3d..bdf6c065e8 100644
--- a/packages/backend/src/server/api/endpoints/i/import-antennas.ts
+++ b/packages/backend/src/server/api/endpoints/i/import-antennas.ts
@@ -16,6 +16,7 @@ import { ApiError } from '../../error.js';
export const meta = {
secure: true,
requireCredential: true,
+ requireRolePolicy: 'canImportAntennas',
prohibitMoved: true,
limit: {
diff --git a/packages/backend/src/server/api/endpoints/i/import-blocking.ts b/packages/backend/src/server/api/endpoints/i/import-blocking.ts
index 2606108539..d7bb6bcd22 100644
--- a/packages/backend/src/server/api/endpoints/i/import-blocking.ts
+++ b/packages/backend/src/server/api/endpoints/i/import-blocking.ts
@@ -15,6 +15,7 @@ import { ApiError } from '../../error.js';
export const meta = {
secure: true,
requireCredential: true,
+ requireRolePolicy: 'canImportBlocking',
prohibitMoved: true,
limit: {
diff --git a/packages/backend/src/server/api/endpoints/i/import-following.ts b/packages/backend/src/server/api/endpoints/i/import-following.ts
index d5e824df27..e03192d8c6 100644
--- a/packages/backend/src/server/api/endpoints/i/import-following.ts
+++ b/packages/backend/src/server/api/endpoints/i/import-following.ts
@@ -15,6 +15,7 @@ import { ApiError } from '../../error.js';
export const meta = {
secure: true,
requireCredential: true,
+ requireRolePolicy: 'canImportFollowing',
prohibitMoved: true,
limit: {
duration: ms('1hour'),
diff --git a/packages/backend/src/server/api/endpoints/i/import-muting.ts b/packages/backend/src/server/api/endpoints/i/import-muting.ts
index 0f5800404e..76b285bb7e 100644
--- a/packages/backend/src/server/api/endpoints/i/import-muting.ts
+++ b/packages/backend/src/server/api/endpoints/i/import-muting.ts
@@ -15,6 +15,7 @@ import { ApiError } from '../../error.js';
export const meta = {
secure: true,
requireCredential: true,
+ requireRolePolicy: 'canImportMuting',
prohibitMoved: true,
limit: {
diff --git a/packages/backend/src/server/api/endpoints/i/import-user-lists.ts b/packages/backend/src/server/api/endpoints/i/import-user-lists.ts
index bacdd5c88f..76ecfd082c 100644
--- a/packages/backend/src/server/api/endpoints/i/import-user-lists.ts
+++ b/packages/backend/src/server/api/endpoints/i/import-user-lists.ts
@@ -15,6 +15,7 @@ import { ApiError } from '../../error.js';
export const meta = {
secure: true,
requireCredential: true,
+ requireRolePolicy: 'canImportUserLists',
prohibitMoved: true,
limit: {
duration: ms('1hour'),
diff --git a/packages/frontend-shared/js/const.ts b/packages/frontend-shared/js/const.ts
index 8391fb638c..b62a69ba24 100644
--- a/packages/frontend-shared/js/const.ts
+++ b/packages/frontend-shared/js/const.ts
@@ -98,6 +98,11 @@ export const ROLE_POLICIES = [
'userEachUserListsLimit',
'rateLimitFactor',
'avatarDecorationLimit',
+ 'canImportAntennas',
+ 'canImportBlocking',
+ 'canImportFollowing',
+ 'canImportMuting',
+ 'canImportUserLists',
] as const;
// なんか動かない
diff --git a/packages/frontend/src/pages/admin/roles.editor.vue b/packages/frontend/src/pages/admin/roles.editor.vue
index b0137abb3f..ae01432d0c 100644
--- a/packages/frontend/src/pages/admin/roles.editor.vue
+++ b/packages/frontend/src/pages/admin/roles.editor.vue
@@ -590,6 +590,106 @@ SPDX-License-Identifier: AGPL-3.0-only
+
+
+ {{ i18n.ts._role._options.canImportAntennas }}
+
+ {{ i18n.ts._role.useBaseValue }}
+ {{ role.policies.canImportAntennas.value ? i18n.ts.yes : i18n.ts.no }}
+
+
+
+
+ {{ i18n.ts._role.useBaseValue }}
+
+
+ {{ i18n.ts.enable }}
+
+
+ {{ i18n.ts._role.priority }}
+
+
+
+
+
+ {{ i18n.ts._role._options.canImportBlocking }}
+
+ {{ i18n.ts._role.useBaseValue }}
+ {{ role.policies.canImportBlocking.value ? i18n.ts.yes : i18n.ts.no }}
+
+
+
+
+ {{ i18n.ts._role.useBaseValue }}
+
+
+ {{ i18n.ts.enable }}
+
+
+ {{ i18n.ts._role.priority }}
+
+
+
+
+
+ {{ i18n.ts._role._options.canImportFollowing }}
+
+ {{ i18n.ts._role.useBaseValue }}
+ {{ role.policies.canImportFollowing.value ? i18n.ts.yes : i18n.ts.no }}
+
+
+
+
+ {{ i18n.ts._role.useBaseValue }}
+
+
+ {{ i18n.ts.enable }}
+
+
+ {{ i18n.ts._role.priority }}
+
+
+
+
+
+ {{ i18n.ts._role._options.canImportMuting }}
+
+ {{ i18n.ts._role.useBaseValue }}
+ {{ role.policies.canImportMuting.value ? i18n.ts.yes : i18n.ts.no }}
+
+
+
+
+ {{ i18n.ts._role.useBaseValue }}
+
+
+ {{ i18n.ts.enable }}
+
+
+ {{ i18n.ts._role.priority }}
+
+
+
+
+
+ {{ i18n.ts._role._options.canImportUserLists }}
+
+ {{ i18n.ts._role.useBaseValue }}
+ {{ role.policies.canImportUserLists.value ? i18n.ts.yes : i18n.ts.no }}
+
+
+
+
+ {{ i18n.ts._role.useBaseValue }}
+
+
+ {{ i18n.ts.enable }}
+
+
+ {{ i18n.ts._role.priority }}
+
+
+
diff --git a/packages/frontend/src/pages/admin/roles.vue b/packages/frontend/src/pages/admin/roles.vue
index 7e29f6e0d8..511e3c0fdf 100644
--- a/packages/frontend/src/pages/admin/roles.vue
+++ b/packages/frontend/src/pages/admin/roles.vue
@@ -214,6 +214,46 @@ SPDX-License-Identifier: AGPL-3.0-only
+
+ {{ i18n.ts._role._options.canImportAntennas }}
+ {{ policies.canImportAntennas ? i18n.ts.yes : i18n.ts.no }}
+
+ {{ i18n.ts.enable }}
+
+
+
+
+ {{ i18n.ts._role._options.canImportBlocking }}
+ {{ policies.canImportBlocking ? i18n.ts.yes : i18n.ts.no }}
+
+ {{ i18n.ts.enable }}
+
+
+
+
+ {{ i18n.ts._role._options.canImportFollowing }}
+ {{ policies.canImportFollowing ? i18n.ts.yes : i18n.ts.no }}
+
+ {{ i18n.ts.enable }}
+
+
+
+
+ {{ i18n.ts._role._options.canImportMuting }}
+ {{ policies.canImportMuting ? i18n.ts.yes : i18n.ts.no }}
+
+ {{ i18n.ts.enable }}
+
+
+
+
+ {{ i18n.ts._role._options.canImportUserLists }}
+ {{ policies.canImportUserLists ? i18n.ts.yes : i18n.ts.no }}
+
+ {{ i18n.ts.enable }}
+
+
+
{{ i18n.ts.save }}
diff --git a/packages/frontend/src/pages/settings/import-export.vue b/packages/frontend/src/pages/settings/import-export.vue
index 9bb3957a84..5acbc50756 100644
--- a/packages/frontend/src/pages/settings/import-export.vue
+++ b/packages/frontend/src/pages/settings/import-export.vue
@@ -45,7 +45,7 @@ SPDX-License-Identifier: AGPL-3.0-only
{{ i18n.ts.export }}
-
+
{{ i18n.ts.import }}
@@ -63,7 +63,7 @@ SPDX-License-Identifier: AGPL-3.0-only
{{ i18n.ts.export }}
-
+
{{ i18n.ts.import }}
{{ i18n.ts.import }}
@@ -78,7 +78,7 @@ SPDX-License-Identifier: AGPL-3.0-only
{{ i18n.ts.export }}
-
+
{{ i18n.ts.import }}
{{ i18n.ts.import }}
@@ -93,7 +93,7 @@ SPDX-License-Identifier: AGPL-3.0-only
{{ i18n.ts.export }}
-
+
{{ i18n.ts.import }}
{{ i18n.ts.import }}
@@ -108,7 +108,7 @@ SPDX-License-Identifier: AGPL-3.0-only
{{ i18n.ts.export }}
-
+
{{ i18n.ts.import }}
{{ i18n.ts.import }}
diff --git a/packages/misskey-js/src/autogen/types.ts b/packages/misskey-js/src/autogen/types.ts
index 672d75e267..5d5bc52956 100644
--- a/packages/misskey-js/src/autogen/types.ts
+++ b/packages/misskey-js/src/autogen/types.ts
@@ -4822,6 +4822,11 @@ export type components = {
userEachUserListsLimit: number;
rateLimitFactor: number;
avatarDecorationLimit: number;
+ canImportAntennas: boolean;
+ canImportBlocking: boolean;
+ canImportFollowing: boolean;
+ canImportMuting: boolean;
+ canImportUserLists: boolean;
};
ReversiGameLite: {
/** Format: id */