From 5ecaf5095ecd4678dd3e05abcc5b0781f6fddb93 Mon Sep 17 00:00:00 2001
From: syuilo <4439005+syuilo@users.noreply.github.com>
Date: Sat, 12 Jul 2025 15:13:35 +0900
Subject: [PATCH] =?UTF-8?q?enhance:=20=E3=82=A6=E3=82=A9=E3=83=BC=E3=82=BF?=
=?UTF-8?q?=E3=83=BC=E3=83=9E=E3=83=BC=E3=82=AF=E6=A9=9F=E8=83=BD=E3=82=92?=
=?UTF-8?q?=E3=83=AD=E3=83=BC=E3=83=AB=E3=81=A7=E5=88=B6=E5=BE=A1=E5=8F=AF?=
=?UTF-8?q?=E8=83=BD=E3=81=AB?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
CHANGELOG.md | 1 +
locales/index.d.ts | 4 ++++
locales/ja-JP.yml | 1 +
packages/backend/src/core/RoleService.ts | 3 +++
.../backend/src/models/json-schema/role.ts | 4 ++++
packages/frontend-shared/js/const.ts | 1 +
.../frontend/src/composables/use-uploader.ts | 7 +++++--
.../frontend/src/pages/admin/roles.editor.vue | 20 +++++++++++++++++++
packages/frontend/src/pages/admin/roles.vue | 8 ++++++++
.../frontend/src/pages/settings/drive.vue | 2 +-
packages/misskey-js/src/autogen/types.ts | 1 +
11 files changed, 49 insertions(+), 3 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 869ecff00e..27810a5b72 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5,6 +5,7 @@
- Feat: クリップ内でノートを検索できるように
- Feat: Playを検索できるように
- Feat: モデレーションにおいて、特定のドライブファイルを添付しているチャットメッセージを一覧できるように
+- Enhance: ウォーターマーク機能をロールで制御可能に
### Client
- Feat: モデログを検索できるように
diff --git a/locales/index.d.ts b/locales/index.d.ts
index d5ec9f5d77..ceb3cc672d 100644
--- a/locales/index.d.ts
+++ b/locales/index.d.ts
@@ -7795,6 +7795,10 @@ export interface Locale extends ILocale {
* サーバーサイドのノートの下書きの作成可能数
*/
"noteDraftLimit": string;
+ /**
+ * ウォーターマーク機能の使用可否
+ */
+ "watermarkAvailable": string;
};
"_condition": {
/**
diff --git a/locales/ja-JP.yml b/locales/ja-JP.yml
index 760f89ef64..6af846f7ee 100644
--- a/locales/ja-JP.yml
+++ b/locales/ja-JP.yml
@@ -2019,6 +2019,7 @@ _role:
uploadableFileTypes_caption: "MIMEタイプを指定します。改行で区切って複数指定できるほか、アスタリスク(*)でワイルドカード指定できます。(例: image/*)"
uploadableFileTypes_caption2: "ファイルによっては種別を判定できないことがあります。そのようなファイルを許可する場合は {x} を指定に追加してください。"
noteDraftLimit: "サーバーサイドのノートの下書きの作成可能数"
+ watermarkAvailable: "ウォーターマーク機能の使用可否"
_condition:
roleAssignedTo: "マニュアルロールにアサイン済み"
isLocal: "ローカルユーザー"
diff --git a/packages/backend/src/core/RoleService.ts b/packages/backend/src/core/RoleService.ts
index 314f7e221a..cddfc0094e 100644
--- a/packages/backend/src/core/RoleService.ts
+++ b/packages/backend/src/core/RoleService.ts
@@ -67,6 +67,7 @@ export type RolePolicies = {
chatAvailability: 'available' | 'readonly' | 'unavailable';
uploadableFileTypes: string[];
noteDraftLimit: number;
+ watermarkAvailable: boolean;
};
export const DEFAULT_POLICIES: RolePolicies = {
@@ -111,6 +112,7 @@ export const DEFAULT_POLICIES: RolePolicies = {
'audio/*',
],
noteDraftLimit: 10,
+ watermarkAvailable: true,
};
@Injectable()
@@ -433,6 +435,7 @@ export class RoleService implements OnApplicationShutdown, OnModuleInit {
return [...set];
}),
noteDraftLimit: calc('noteDraftLimit', vs => Math.max(...vs)),
+ watermarkAvailable: calc('watermarkAvailable', 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 a3f679129d..c9cdbd5d89 100644
--- a/packages/backend/src/models/json-schema/role.ts
+++ b/packages/backend/src/models/json-schema/role.ts
@@ -313,6 +313,10 @@ export const packedRolePoliciesSchema = {
type: 'integer',
optional: false, nullable: false,
},
+ watermarkAvailable: {
+ type: 'boolean',
+ optional: false, nullable: false,
+ },
},
} as const;
diff --git a/packages/frontend-shared/js/const.ts b/packages/frontend-shared/js/const.ts
index 4498a5e2b2..5c33c38f44 100644
--- a/packages/frontend-shared/js/const.ts
+++ b/packages/frontend-shared/js/const.ts
@@ -112,6 +112,7 @@ export const ROLE_POLICIES = [
'chatAvailability',
'uploadableFileTypes',
'noteDraftLimit',
+ 'watermarkAvailable',
] as const;
export const MFM_TAGS = ['tada', 'jelly', 'twitch', 'shake', 'spin', 'jump', 'bounce', 'flip', 'x2', 'x3', 'x4', 'scale', 'position', 'fg', 'bg', 'border', 'font', 'blur', 'rainbow', 'sparkle', 'rotate', 'ruby', 'unixtime'];
diff --git a/packages/frontend/src/composables/use-uploader.ts b/packages/frontend/src/composables/use-uploader.ts
index 6f4ed81f82..826d8c5203 100644
--- a/packages/frontend/src/composables/use-uploader.ts
+++ b/packages/frontend/src/composables/use-uploader.ts
@@ -104,6 +104,8 @@ export function useUploader(options: {
multiple?: boolean;
features?: UploaderFeatures;
} = {}) {
+ const $i = ensureSignin();
+
const events = new EventEmitter<{
'itemUploaded': (ctx: { item: UploaderItem; }) => void;
}>();
@@ -132,7 +134,7 @@ export function useUploader(options: {
uploaded: null,
uploadFailed: false,
compressionLevel: prefer.s.defaultImageCompressionLevel,
- watermarkPresetId: uploaderFeatures.value.watermark ? prefer.s.defaultWatermarkPresetId : null,
+ watermarkPresetId: uploaderFeatures.value.watermark && $i.policies.watermarkAvailable ? prefer.s.defaultWatermarkPresetId : null,
file: markRaw(file),
});
const reactiveItem = items.value.at(-1)!;
@@ -264,6 +266,7 @@ export function useUploader(options: {
if (
uploaderFeatures.value.watermark &&
+ $i.policies.watermarkAvailable &&
WATERMARK_SUPPORTED_TYPES.includes(item.file.type) &&
!item.preprocessing &&
!item.uploading &&
@@ -500,7 +503,7 @@ export function useUploader(options: {
let preprocessedFile: Blob | File = item.file;
- const needsWatermark = item.watermarkPresetId != null && WATERMARK_SUPPORTED_TYPES.includes(preprocessedFile.type);
+ const needsWatermark = item.watermarkPresetId != null && WATERMARK_SUPPORTED_TYPES.includes(preprocessedFile.type) && $i.policies.watermarkAvailable;
const preset = prefer.s.watermarkPresets.find(p => p.id === item.watermarkPresetId);
if (needsWatermark && preset != null) {
const canvas = window.document.createElement('canvas');
diff --git a/packages/frontend/src/pages/admin/roles.editor.vue b/packages/frontend/src/pages/admin/roles.editor.vue
index a266e1df6f..c172e22688 100644
--- a/packages/frontend/src/pages/admin/roles.editor.vue
+++ b/packages/frontend/src/pages/admin/roles.editor.vue
@@ -780,6 +780,26 @@ SPDX-License-Identifier: AGPL-3.0-only
+
+