fix: #143 fix message api overreach vulnerability problem

pull/146/head
moonrailgun 3 years ago
parent ad9c9f4f52
commit f7e84cad35

@ -105,14 +105,15 @@ export async function fetchConverseLastMessages(
* @param messageId ID * @param messageId ID
* @returns * @returns
*/ */
export async function fetchNearbyMessage( export async function fetchNearbyMessage(params: {
converseId: string, groupId?: string;
messageId: string converseId: string;
): Promise<ChatMessage[]> { messageId: string;
const { data } = await request.post('/api/chat/message/fetchNearbyMessage', { }): Promise<ChatMessage[]> {
converseId, const { data } = await request.post(
messageId, '/api/chat/message/fetchNearbyMessage',
}); params
);
return data; return data;
} }

@ -28,7 +28,11 @@ export const InboxMessageContent: React.FC<Props> = React.memo((props) => {
return ( return (
<CommonPanelWrapper header={t('提及我的消息')}> <CommonPanelWrapper header={t('提及我的消息')}>
<div className="h-full overflow-auto p-2 pb-18 relative"> <div className="h-full overflow-auto p-2 pb-18 relative">
<NearbyMessages converseId={converseId} messageId={messageId} /> <NearbyMessages
groupId={groupId}
converseId={converseId}
messageId={messageId}
/>
</div> </div>
<JumpToConverseButton groupId={groupId} converseId={converseId} /> <JumpToConverseButton groupId={groupId} converseId={converseId} />
@ -38,15 +42,17 @@ export const InboxMessageContent: React.FC<Props> = React.memo((props) => {
InboxMessageContent.displayName = 'InboxMessageContent'; InboxMessageContent.displayName = 'InboxMessageContent';
export const NearbyMessages: React.FC<{ export const NearbyMessages: React.FC<{
groupId?: string;
converseId: string; converseId: string;
messageId: string; messageId: string;
}> = React.memo((props) => { }> = React.memo((props) => {
const { value = [], loading } = useAsync(async () => { const { value = [], loading } = useAsync(async () => {
try { try {
const list = await model.message.fetchNearbyMessage( const list = await model.message.fetchNearbyMessage({
props.converseId, groupId: props.groupId,
props.messageId converseId: props.converseId,
); messageId: props.messageId,
});
return list; return list;
} catch (err) { } catch (err) {

@ -11,6 +11,8 @@ interface GroupMemberStruct {
roles?: string[]; // 角色 roles?: string[]; // 角色
userId: string; userId: string;
muteUntil?: string;
} }
export interface GroupPanelStruct { export interface GroupPanelStruct {

@ -7,6 +7,7 @@ import {
UserStruct, UserStruct,
call, call,
DataNotFoundError, DataNotFoundError,
NoPermissionError,
} from 'tailchat-server-sdk'; } from 'tailchat-server-sdk';
import type { import type {
ConverseDocument, ConverseDocument,
@ -225,7 +226,7 @@ class ConverseService extends TcService {
const memebers = converse.members ?? []; const memebers = converse.members ?? [];
if (!memebers.map((member) => String(member)).includes(userId)) { if (!memebers.map((member) => String(member)).includes(userId)) {
throw new Error(t('没有获取会话信息权限')); throw new NoPermissionError(t('没有获取会话信息权限'));
} }
return await this.transformDocuments(ctx, {}, converse); return await this.transformDocuments(ctx, {}, converse);

@ -13,6 +13,8 @@ import {
NoPermissionError, NoPermissionError,
call, call,
PERMISSION, PERMISSION,
NotFoundError,
SYSTEM_USERID,
} from 'tailchat-server-sdk'; } from 'tailchat-server-sdk';
import type { Group } from '../../../models/group/group'; import type { Group } from '../../../models/group/group';
import { isValidStr } from '../../../lib/utils'; import { isValidStr } from '../../../lib/utils';
@ -36,6 +38,7 @@ class MessageService extends TcService {
}); });
this.registerAction('fetchNearbyMessage', this.fetchNearbyMessage, { this.registerAction('fetchNearbyMessage', this.fetchNearbyMessage, {
params: { params: {
groupId: { type: 'string', optional: true },
converseId: 'string', converseId: 'string',
messageId: 'string', messageId: 'string',
num: { type: 'number', optional: true }, num: { type: 'number', optional: true },
@ -109,13 +112,18 @@ class MessageService extends TcService {
*/ */
async fetchNearbyMessage( async fetchNearbyMessage(
ctx: TcContext<{ ctx: TcContext<{
groupId?: string;
converseId: string; converseId: string;
messageId: string; messageId: string;
num?: number; num?: number;
}> }>
) { ) {
const { converseId, messageId, num = 5 } = ctx.params; const { groupId, converseId, messageId, num = 5 } = ctx.params;
const { t } = ctx.meta; const { t } = ctx.meta;
// 鉴权是否能获取到会话内容
await this.checkConversePermission(ctx, converseId, groupId);
const message = await this.adapter.model const message = await this.adapter.model
.findOne({ .findOne({
_id: new Types.ObjectId(messageId), _id: new Types.ObjectId(messageId),
@ -176,11 +184,10 @@ class MessageService extends TcService {
/** /**
* *
*/ */
await this.checkConversePermission(ctx, converseId, groupId); // 鉴权是否能获取到会话内容
if (isValidStr(groupId)) { if (isValidStr(groupId)) {
// 是群组消息 // 是群组消息, 鉴权是否禁言
const groupInfo: Group = await ctx.call('group.getGroupInfo', { const groupInfo = await call(ctx).getGroupInfo(groupId);
groupId,
});
const member = groupInfo.members.find((m) => String(m.userId) === userId); const member = groupInfo.members.find((m) => String(m.userId) === userId);
if (member) { if (member) {
// 因为有机器人,所以如果没有在成员列表中找到不报错 // 因为有机器人,所以如果没有在成员列表中找到不报错
@ -441,6 +448,50 @@ class MessageService extends TcService {
return true; 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; export default MessageService;

Loading…
Cancel
Save