summaryrefslogtreecommitdiff
path: root/packages/backend/src/core
diff options
context:
space:
mode:
authorかっこかり <67428053+kakkokari-gtyih@users.noreply.github.com>2025-04-07 19:09:11 +0900
committerGitHub <noreply@github.com>2025-04-07 19:09:11 +0900
commit9d3f3264fdd059f47537da48fd125cdd2f4bad1e (patch)
treededbf1433d0e003465b37e805519c5635b135466 /packages/backend/src/core
parentUpdate CHANGELOG.md (diff)
downloadsharkey-9d3f3264fdd059f47537da48fd125cdd2f4bad1e.tar.gz
sharkey-9d3f3264fdd059f47537da48fd125cdd2f4bad1e.tar.bz2
sharkey-9d3f3264fdd059f47537da48fd125cdd2f4bad1e.zip
enhance: チャットの閲覧を無効化できるように (#15765)
* enhance: チャットの閲覧を無効化できるように * fix * fix * fix * readonlyの説明を追加 * enhance: チャットが無効な場合はチャット関連の設定も隠すように * fix * refactor: ChatServiceからApiに関するドメイン知識を排除
Diffstat (limited to 'packages/backend/src/core')
-rw-r--r--packages/backend/src/core/ChatService.ts36
-rw-r--r--packages/backend/src/core/RoleService.ts12
-rw-r--r--packages/backend/src/core/entities/UserEntityService.ts2
3 files changed, 45 insertions, 5 deletions
diff --git a/packages/backend/src/core/ChatService.ts b/packages/backend/src/core/ChatService.ts
index 3984cefc80..b0e8cfb61c 100644
--- a/packages/backend/src/core/ChatService.ts
+++ b/packages/backend/src/core/ChatService.ts
@@ -95,6 +95,40 @@ export class ChatService {
}
@bindThis
+ public async getChatAvailability(userId: MiUser['id']): Promise<{ read: boolean; write: boolean; }> {
+ const policies = await this.roleService.getUserPolicies(userId);
+
+ switch (policies.chatAvailability) {
+ case 'available':
+ return {
+ read: true,
+ write: true,
+ };
+ case 'readonly':
+ return {
+ read: true,
+ write: false,
+ };
+ case 'unavailable':
+ return {
+ read: false,
+ write: false,
+ };
+ default:
+ throw new Error('invalid chat availability (unreachable)');
+ }
+ }
+
+ /** getChatAvailabilityの糖衣。主にAPI呼び出し時に走らせて、権限的に問題ない場合はそのまま続行する */
+ @bindThis
+ public async checkChatAvailability(userId: MiUser['id'], permission: 'read' | 'write') {
+ const policy = await this.getChatAvailability(userId);
+ if (policy[permission] === false) {
+ throw new Error('ROLE_PERMISSION_DENIED');
+ }
+ }
+
+ @bindThis
public async createMessageToUser(fromUser: { id: MiUser['id']; host: MiUser['host']; }, toUser: MiUser, params: {
text?: string | null;
file?: MiDriveFile | null;
@@ -140,7 +174,7 @@ export class ChatService {
}
}
- if (!(await this.roleService.getUserPolicies(toUser.id)).canChat) {
+ if (!(await this.getChatAvailability(toUser.id)).write) {
throw new Error('recipient is cannot chat (policy)');
}
diff --git a/packages/backend/src/core/RoleService.ts b/packages/backend/src/core/RoleService.ts
index 0a2659ee32..601959cc96 100644
--- a/packages/backend/src/core/RoleService.ts
+++ b/packages/backend/src/core/RoleService.ts
@@ -63,7 +63,7 @@ export type RolePolicies = {
canImportFollowing: boolean;
canImportMuting: boolean;
canImportUserLists: boolean;
- canChat: boolean;
+ chatAvailability: 'available' | 'readonly' | 'unavailable';
};
export const DEFAULT_POLICIES: RolePolicies = {
@@ -98,7 +98,7 @@ export const DEFAULT_POLICIES: RolePolicies = {
canImportFollowing: true,
canImportMuting: true,
canImportUserLists: true,
- canChat: true,
+ chatAvailability: 'available',
};
@Injectable()
@@ -370,6 +370,12 @@ export class RoleService implements OnApplicationShutdown, OnModuleInit {
return aggregate(policies.map(policy => policy.useDefault ? basePolicies[name] : policy.value));
}
+ function aggregateChatAvailability(vs: RolePolicies['chatAvailability'][]) {
+ if (vs.some(v => v === 'available')) return 'available';
+ if (vs.some(v => v === 'readonly')) return 'readonly';
+ return 'unavailable';
+ }
+
return {
gtlAvailable: calc('gtlAvailable', vs => vs.some(v => v === true)),
ltlAvailable: calc('ltlAvailable', vs => vs.some(v => v === true)),
@@ -402,7 +408,7 @@ export class RoleService implements OnApplicationShutdown, OnModuleInit {
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)),
- canChat: calc('canChat', vs => vs.some(v => v === true)),
+ chatAvailability: calc('chatAvailability', aggregateChatAvailability),
};
}
diff --git a/packages/backend/src/core/entities/UserEntityService.ts b/packages/backend/src/core/entities/UserEntityService.ts
index ad8052711c..e252ff509e 100644
--- a/packages/backend/src/core/entities/UserEntityService.ts
+++ b/packages/backend/src/core/entities/UserEntityService.ts
@@ -557,7 +557,7 @@ export class UserEntityService implements OnModuleInit {
followersVisibility: profile!.followersVisibility,
followingVisibility: profile!.followingVisibility,
chatScope: user.chatScope,
- canChat: this.roleService.getUserPolicies(user.id).then(r => r.canChat),
+ canChat: this.roleService.getUserPolicies(user.id).then(r => r.chatAvailability === 'available'),
roles: this.roleService.getUserRoles(user.id).then(roles => roles.filter(role => role.isPublic).sort((a, b) => b.displayOrder - a.displayOrder).map(role => ({
id: role.id,
name: role.name,