diff --git a/client/shared/model/message.ts b/client/shared/model/message.ts index 3b379d56..186d53c3 100644 --- a/client/shared/model/message.ts +++ b/client/shared/model/message.ts @@ -105,14 +105,15 @@ export async function fetchConverseLastMessages( * @param messageId 消息ID * @returns 消息附近的信息 */ -export async function fetchNearbyMessage( - converseId: string, - messageId: string -): Promise { - const { data } = await request.post('/api/chat/message/fetchNearbyMessage', { - converseId, - messageId, - }); +export async function fetchNearbyMessage(params: { + groupId?: string; + converseId: string; + messageId: string; +}): Promise { + const { data } = await request.post( + '/api/chat/message/fetchNearbyMessage', + params + ); return data; } diff --git a/client/web/src/routes/Main/Content/Inbox/Content/Message.tsx b/client/web/src/routes/Main/Content/Inbox/Content/Message.tsx index 9d863c66..97ea0129 100644 --- a/client/web/src/routes/Main/Content/Inbox/Content/Message.tsx +++ b/client/web/src/routes/Main/Content/Inbox/Content/Message.tsx @@ -28,7 +28,11 @@ export const InboxMessageContent: React.FC = React.memo((props) => { return (
- +
@@ -38,15 +42,17 @@ export const InboxMessageContent: React.FC = React.memo((props) => { InboxMessageContent.displayName = 'InboxMessageContent'; export const NearbyMessages: React.FC<{ + groupId?: string; converseId: string; messageId: string; }> = React.memo((props) => { const { value = [], loading } = useAsync(async () => { try { - const list = await model.message.fetchNearbyMessage( - props.converseId, - props.messageId - ); + const list = await model.message.fetchNearbyMessage({ + groupId: props.groupId, + converseId: props.converseId, + messageId: props.messageId, + }); return list; } catch (err) { diff --git a/server/packages/sdk/src/structs/group.ts b/server/packages/sdk/src/structs/group.ts index 1b966822..dbfc3cb1 100644 --- a/server/packages/sdk/src/structs/group.ts +++ b/server/packages/sdk/src/structs/group.ts @@ -11,6 +11,8 @@ interface GroupMemberStruct { roles?: string[]; // 角色 userId: string; + + muteUntil?: string; } export interface GroupPanelStruct { diff --git a/server/services/core/chat/converse.service.ts b/server/services/core/chat/converse.service.ts index 8ee0bed5..d3839d71 100644 --- a/server/services/core/chat/converse.service.ts +++ b/server/services/core/chat/converse.service.ts @@ -7,6 +7,7 @@ import { UserStruct, call, DataNotFoundError, + NoPermissionError, } from 'tailchat-server-sdk'; import type { ConverseDocument, @@ -225,7 +226,7 @@ class ConverseService extends TcService { const memebers = converse.members ?? []; if (!memebers.map((member) => String(member)).includes(userId)) { - throw new Error(t('没有获取会话信息权限')); + throw new NoPermissionError(t('没有获取会话信息权限')); } return await this.transformDocuments(ctx, {}, converse); diff --git a/server/services/core/chat/message.service.ts b/server/services/core/chat/message.service.ts index d80ecd2d..29f7cf53 100644 --- a/server/services/core/chat/message.service.ts +++ b/server/services/core/chat/message.service.ts @@ -13,6 +13,8 @@ import { NoPermissionError, call, PERMISSION, + NotFoundError, + SYSTEM_USERID, } from 'tailchat-server-sdk'; import type { Group } from '../../../models/group/group'; import { isValidStr } from '../../../lib/utils'; @@ -36,6 +38,7 @@ class MessageService extends TcService { }); this.registerAction('fetchNearbyMessage', this.fetchNearbyMessage, { params: { + groupId: { type: 'string', optional: true }, converseId: 'string', messageId: 'string', num: { type: 'number', optional: true }, @@ -109,13 +112,18 @@ class MessageService extends TcService { */ async fetchNearbyMessage( ctx: TcContext<{ + groupId?: string; converseId: string; messageId: string; num?: number; }> ) { - const { converseId, messageId, num = 5 } = ctx.params; + const { groupId, converseId, messageId, num = 5 } = ctx.params; const { t } = ctx.meta; + + // 鉴权是否能获取到会话内容 + await this.checkConversePermission(ctx, converseId, groupId); + const message = await this.adapter.model .findOne({ _id: new Types.ObjectId(messageId), @@ -176,11 +184,10 @@ class MessageService extends TcService { /** * 鉴权 */ + await this.checkConversePermission(ctx, converseId, groupId); // 鉴权是否能获取到会话内容 if (isValidStr(groupId)) { - // 是群组消息 - const groupInfo: Group = await ctx.call('group.getGroupInfo', { - groupId, - }); + // 是群组消息, 鉴权是否禁言 + const groupInfo = await call(ctx).getGroupInfo(groupId); const member = groupInfo.members.find((m) => String(m.userId) === userId); if (member) { // 因为有机器人,所以如果没有在成员列表中找到不报错 @@ -441,6 +448,50 @@ class MessageService extends TcService { return true; } + + /** + * 校验会话权限,如果没有抛出异常则视为正常 + */ + private async checkConversePermission( + ctx: TcContext, + converseId: string, + groupId?: string + ) { + const userId = ctx.meta.userId; + const t = ctx.meta.t; + if (userId === SYSTEM_USERID) { + return; + } + + // 鉴权是否能获取到会话内容 + if (groupId) { + // 是群组 + const group = await call(ctx).getGroupInfo(groupId); + console.log('group.members', group.members, group); + if (group.members.findIndex((m) => String(m.userId) === userId) === -1) { + // 不存在该用户 + throw new NoPermissionError(t('没有当前会话权限')); + } + } else { + // 是普通会话 + const converse = await ctx.call< + any, + { + converseId: string; + } + >('chat.converse.findConverseInfo', { + converseId, + }); + + if (!converse) { + throw new NotFoundError(t('没有找到会话信息')); + } + const memebers = converse.members ?? []; + if (memebers.findIndex((member) => String(member) === userId) === -1) { + throw new NoPermissionError(t('没有当前会话权限')); + } + } + } } export default MessageService;