Commit 2ba13431 by Xianquan Committed by GitHub

chore: suppress API input Zod error noise (#6952)

* chore: suppress external api zod input noise

* chore: migrate api input parsing

* chore: update pro api input parsing

* fix: stabilize image caption child response id

* refactor: simplify zod error response handling
parent edd12c8a
# Zod 请求入参错误降噪设计
## 背景
当前 `NextEntry` 捕获到任意 `ZodError` 后都会返回 400,并继续通过 `jsonRes -> processError` 以 error 级别记录 `Zod validation error`。这会把外部调用方传错 `body``query``params` 的场景当作系统异常上报到 Otel,产生大量噪音。
需求目标是只降级“API 请求入参 schema.parse 失败”的 `ZodError`,其他 `ZodError` 仍视为内部代码或业务数据 bug,保留 error 级别日志和 Otel 告警。
## 判断边界
1. 只处理由 API 边界 helper 显式标记的 `ZodError`
2. 直接请求入参 parse 必须通过 helper 表达:
- `parseApiInput({ req, bodySchema: SomeSchema })`
- `parseApiInput({ req, querySchema: SomeSchema })`
- `parseApiInput({ req, paramsSchema: SomeSchema })`
3. 只要错误是 `parseApiInput` 抛出的 `ApiRequestInputParseError`,就视为客户端请求入参错误并降级。
4. 不使用 api key header 作为降级条件。入参 parse 通常发生在鉴权前,调用方漏传 api key 时也可能先触发 body/query/params 校验失败;如果继续依赖 header,会把这类客户端错误误上报为系统异常。
5. 没有显式标记的普通 `ZodError` 按内部错误处理,避免把系统 bug 静默降级。
## 使用方法
### API 路由入参 parse
API 路由需要校验 `req.body``req.query``req.params` 时,使用 `parseApiInput`,不要直接写 `Schema.parse(req.body)`
```ts
import { parseApiInput } from '@fastgpt/service/common/zod/requestParseError';
async function handler(req: NextApiRequest, res: NextApiResponse) {
const { body, query } = parseApiInput({
req,
bodySchema: CreateSomethingBodySchema,
querySchema: GetSomethingQuerySchema
});
}
```
如果 API 入口使用的是 `ApiRequestProps<T>`,用法不变:
```ts
export async function handler(req: ApiRequestProps<SearchDatasetTestBody>) {
const { body } = parseApiInput({ req, bodySchema: SearchDatasetTestBodySchema });
}
```
`parseApiInput` 会在 Zod 校验失败时抛出 `ApiRequestInputParseError`。该错误会保留:
- `context.inputSource`:失败来源是 `body``query` 还是 `params`
- `cause`:原始 `ZodError`,用于响应中的 `zodError` 和日志结构化数据
### 降级条件
`NextEntry` 只在以下条件满足时,将错误视为 API 入参错误:
1. 错误是 `parseApiInput` 抛出的 `ApiRequestInputParseError`
满足时返回 400,不调用 `setSpanError``processError` 不调用 logger。否则走内部错误路径:HTTP 500、`setSpanError`、error 日志。
### 不要使用的场景
不要把内部业务数据、数据库记录、模型返回、工具调用参数等 schema 校验改成 `parseApiInput`。这些失败代表系统内部数据不符合预期,应该继续抛普通 `ZodError` 并触发 Otel 告警。
```ts
// 内部业务校验:保留普通 parse,让异常继续按 bug 上报
const runtimeConfig = RuntimeConfigSchema.parse(configFromDb);
```
### 迁移建议
优先迁移会被 SDK、curl、Postman、第三方服务直接调用,并且通过 api key 鉴权的入口,例如:
- `/api/v1/chat/completions`
- `/api/v2/chat/completions`
- `/api/v2/chat/stop`
- 数据集搜索测试等开放 API 入口
纯 Web 控制台内部接口可以暂不迁移;一旦迁移到 `parseApiInput`,该接口的入参错误就会被视为客户端请求错误并返回 400,不再触发错误级 Otel。
## 错误行为示例
### API 入参错误
请求满足以下条件时:
- API 路由使用 `parseApiInput({ req, bodySchema })`
- `bodySchema` 校验失败
处理结果:
- HTTP:返回 400
- Otel:不调用 `setSpanError`,不会按系统异常上报
- 日志:不调用 `logger.info/error`,避免通过 logger 进入 Otel
- Console:不主动打印到 console;调用方可从 400 响应体中的 `zodError` 看到校验详情
响应体示例:
```json
{
"code": 400,
"statusText": "error",
"message": "Data validation error",
"data": null,
"zodError": [
{
"expected": "string",
"code": "invalid_type",
"path": ["appId"],
"message": "Invalid input: expected string, received undefined"
}
]
}
```
该场景没有 logger 结构化日志。若后续需要排查调用方参数问题,应优先使用客户端收到的 400 响应体,或在专门的非 Otel 采样渠道中另行设计。
### 内部 ZodError
如果错误来自内部业务校验,例如:
```ts
const runtimeConfig = RuntimeConfigSchema.parse(configFromDb);
```
即使请求头携带 api key,也不会降级:
- HTTP:返回 500
- Otel:调用 `setSpanError`,按系统异常上报
- 日志:`logger.error('Zod validation error', { url, data: zodError, error })`
日志结构示例:
```ts
logger.error('Zod validation error', {
url: '/api/v2/chat/completions',
data: [
{
expected: 'string',
code: 'invalid_type',
path: ['model'],
message: 'Invalid input: expected string, received undefined'
}
],
error
});
```
## 实现方案
1. 新增 `packages/service/common/zod/requestParseError.ts`
- 提供 `parseApiInput({ req, bodySchema, querySchema, paramsSchema })`
- helper 内部按 schema 类型调用 `schema.parse(req.body/query/params)`
- 捕获 `ZodError` 后抛出 `ApiRequestInputParseError`,并在包装错误上保留原始 `ZodError``inputSource`
- 提供 `getZodParseErrorInputSource(error)` 供统一入口读取。
2. 调整 `NextEntry`
- 捕获 `ZodError` 后先调用分类器。
- 若确认为 API 请求入参错误:返回 400,不调用 `setSpanError`,span 状态保持非 error,仅设置 `http.response.status_code=400`
- 若不是请求入参错误:走 500 + `setSpanError`,保留内部 bug 告警语义。
3. 调整 `jsonRes/processError`
- 支持传入 `zodParseErrorContext`
- 有 context 时不调用 logger,避免通过 logger 进入 Otel。
- 无 context 的 `ZodError` 仍以 error 级别记录。
## TODO
- [x] 编写需求/设计文档
- [x] 新增 Zod 请求入参错误分类工具
- [x] 接入 `NextEntry``jsonRes/processError`
- [x] 先迁移外部 API 高频入口的 body parse:v1/v2 chat completions、v2 chat stop、dataset searchTest
- [x] 补充单元测试覆盖 body/query/params、内部 ZodError、日志降级
- [x] 运行局部测试
...@@ -108,6 +108,24 @@ FastGPT 是一个 AI Agent 构建平台,通过 Flow 提供开箱即用的数据 ...@@ -108,6 +108,24 @@ FastGPT 是一个 AI Agent 构建平台,通过 Flow 提供开箱即用的数据
[FastGPT 代码规范](./.codex/code/syntax.md) [FastGPT 代码规范](./.codex/code/syntax.md)
### API 入参校验
- 编写或修改 NextJS API 路由时,如果需要校验接口入参(`req.body``req.query``req.params`),必须使用 `parseApiInput`,不要直接写 `SomeSchema.parse(req.body)``SomeSchema.parse(req.query)``SomeSchema.parse(req.params)`
- `parseApiInput``@fastgpt/service/common/zod/requestParseError` 导入,用法示例:
```ts
import { parseApiInput } from '@fastgpt/service/common/zod/requestParseError';
const { body, query } = parseApiInput({
req,
bodySchema: CreateSomethingBodySchema,
querySchema: GetSomethingQuerySchema
});
```
- 这个 helper 只用于 API 边界的请求入参校验。内部业务数据、数据库记录、模型返回、工具调用参数等 schema 校验仍使用普通 `Schema.parse(...)`,因为这些错误应按内部 bug 上报。
- 相关设计见 [Zod 请求入参错误降噪设计](./.codex/design/api/zod-request-parse-error-handling.md)
### 函数注释 ### 函数注释
- 编写或拆分函数时,必须关注函数注释。对导出函数、核心业务函数、hook、复杂工具函数、跨模块复用函数,优先使用 `/** ... */` 形式补充函数级注释。 - 编写或拆分函数时,必须关注函数注释。对导出函数、核心业务函数、hook、复杂工具函数、跨模块复用函数,优先使用 `/** ... */` 形式补充函数级注释。
......
import { jsonRes } from '../response'; import { jsonRes } from '../response';
import type { NextApiRequest, NextApiResponse } from 'next'; import type { NextApiRequest, NextApiResponse } from 'next';
import { SpanStatusCode } from '@opentelemetry/api';
import { withNextCors } from './cors'; import { withNextCors } from './cors';
import { type ApiRequestProps } from '../../type/next'; import { type ApiRequestProps } from '../../type/next';
import { getLogger, LogCategories, withContext } from '../logger'; import { getLogger, LogCategories, withContext } from '../logger';
...@@ -8,6 +7,7 @@ import { setSpanError, withActiveSpan } from '../tracing'; ...@@ -8,6 +7,7 @@ import { setSpanError, withActiveSpan } from '../tracing';
import { ZodError } from 'zod'; import { ZodError } from 'zod';
import { randomUUID } from 'crypto'; import { randomUUID } from 'crypto';
import { getClientIpFromRequest } from '../security/clientIp'; import { getClientIpFromRequest } from '../security/clientIp';
import { ApiRequestInputParseError, getZodParseErrorInputSource } from '../zod/requestParseError';
export type NextApiHandler<T = any> = ( export type NextApiHandler<T = any> = (
req: ApiRequestProps, req: ApiRequestProps,
...@@ -135,14 +135,21 @@ export const NextEntry = ({ ...@@ -135,14 +135,21 @@ export const NextEntry = ({
span.setAttribute('http.response.status_code', res.statusCode); span.setAttribute('http.response.status_code', res.statusCode);
} catch (error) { } catch (error) {
// Handle Zod validation errors // Handle Zod validation errors. Only explicit API input parse errors can be downgraded.
if (error instanceof ZodError) { if (error instanceof ZodError || error instanceof ApiRequestInputParseError) {
span.setAttribute('http.response.status_code', 400); const requestInputErrorContext = getZodParseErrorInputSource(error);
span.setStatus({ if (!requestInputErrorContext) {
code: SpanStatusCode.ERROR, span.setAttribute('http.response.status_code', 500);
message: 'Data validation error' setSpanError(span, error);
return jsonRes(res, {
code: 500,
error,
url: req.url
}); });
}
span.setAttribute('http.response.status_code', 400);
return jsonRes(res, { return jsonRes(res, {
code: 400, code: 400,
message: 'Data validation error', message: 'Data validation error',
......
...@@ -7,6 +7,7 @@ import { clearCookie } from '../../support/permission/auth/common'; ...@@ -7,6 +7,7 @@ import { clearCookie } from '../../support/permission/auth/common';
import { ZodError } from 'zod'; import { ZodError } from 'zod';
import type Stream from 'node:stream'; import type Stream from 'node:stream';
import { getLogger, LogCategories } from '../logger'; import { getLogger, LogCategories } from '../logger';
import { ApiRequestInputParseError, getZodError } from '../zod/requestParseError';
const logger = getLogger(LogCategories.HTTP.ERROR); const logger = getLogger(LogCategories.HTTP.ERROR);
...@@ -58,6 +59,16 @@ function resolveHttpStatusForApiError( ...@@ -58,6 +59,16 @@ function resolveHttpStatusForApiError(
return 500; return 500;
} }
function parseZodErrorMessage(error: ZodError | ApiRequestInputParseError) {
const zodSourceError = getZodError(error);
try {
return JSON.parse(zodSourceError?.message || error.message);
} catch {
return undefined;
}
}
/** /**
* 通用错误处理函数,提取错误信息并分类记录日志 * 通用错误处理函数,提取错误信息并分类记录日志
* @param params - 包含错误对象、URL和默认状态码的参数 * @param params - 包含错误对象、URL和默认状态码的参数
...@@ -111,13 +122,13 @@ export function processError(params: { ...@@ -111,13 +122,13 @@ export function processError(params: {
// 3. 根据错误类型记录不同级别的日志 // 3. 根据错误类型记录不同级别的日志
if (error instanceof UserError) { if (error instanceof UserError) {
logger.info('Request error', { url, message: msg }); logger.info('Request error', { url, message: msg });
} else if (error instanceof ZodError) { } else if (error instanceof ZodError || error instanceof ApiRequestInputParseError) {
zodError = (() => { zodError = parseZodErrorMessage(error);
try {
return JSON.parse(error.message); if (!(error instanceof ApiRequestInputParseError)) {
} catch (error) {}
})();
logger.error('Zod validation error', { url, data: zodError, error }); logger.error('Zod validation error', { url, data: zodError, error });
}
msg = error.message; msg = error.message;
} else { } else {
logger.error('System unexpected error', { url, message: msg, error }); logger.error('System unexpected error', { url, message: msg, error });
......
import { ZodError, type z } from 'zod';
export type ZodRequestInputSource = 'body' | 'query' | 'params';
export type ZodRequestParseErrorContext = {
inputSource: ZodRequestInputSource;
};
export class ApiRequestInputParseError extends Error {
context: ZodRequestParseErrorContext;
cause: ZodError;
/**
* 表示 API 请求入参校验失败。只由 `parseApiInput` 创建,用于和内部 `ZodError` 明确区分。
*/
constructor(error: ZodError, context: ZodRequestParseErrorContext) {
super(error.message);
this.name = 'ApiRequestInputParseError';
this.context = context;
this.cause = error;
}
}
function parseRequestInput<T extends z.ZodTypeAny>(
schema: T,
req: Partial<Record<ZodRequestInputSource, unknown>>,
inputSource: ZodRequestInputSource
): z.output<T> {
try {
return schema.parse(req[inputSource]);
} catch (error) {
if (error instanceof ZodError) {
throw new ApiRequestInputParseError(error, { inputSource });
}
throw error;
}
}
type ParseApiInputProps<
B extends z.ZodTypeAny | undefined,
Q extends z.ZodTypeAny | undefined,
P extends z.ZodTypeAny | undefined
> = {
req: Partial<Record<ZodRequestInputSource, unknown>>;
bodySchema?: B;
querySchema?: Q;
paramsSchema?: P;
};
type ParseApiInputResult<
B extends z.ZodTypeAny | undefined,
Q extends z.ZodTypeAny | undefined,
P extends z.ZodTypeAny | undefined
> = (B extends z.ZodTypeAny ? { body: z.output<B> } : object) &
(Q extends z.ZodTypeAny ? { query: z.output<Q> } : object) &
(P extends z.ZodTypeAny ? { params: z.output<P> } : object);
/**
* 在 API 边界解析请求入参,并把失败的 `ZodError` 包装成明确的 API 入参错误。
* 只有该错误会被入口层视为可降级的外部调用参数错误,普通 `ZodError` 仍按内部 bug 处理。
*/
export function parseApiInput<
B extends z.ZodTypeAny | undefined = undefined,
Q extends z.ZodTypeAny | undefined = undefined,
P extends z.ZodTypeAny | undefined = undefined
>({
req,
bodySchema,
querySchema,
paramsSchema
}: ParseApiInputProps<B, Q, P>): ParseApiInputResult<B, Q, P> {
return {
...(bodySchema ? { body: parseRequestInput(bodySchema, req, 'body') } : {}),
...(querySchema ? { query: parseRequestInput(querySchema, req, 'query') } : {}),
...(paramsSchema ? { params: parseRequestInput(paramsSchema, req, 'params') } : {})
} as ParseApiInputResult<B, Q, P>;
}
export function getZodParseErrorInputSource(error: unknown) {
return error instanceof ApiRequestInputParseError ? error.context : undefined;
}
export function getZodError(error: unknown) {
if (error instanceof ApiRequestInputParseError) return error.cause;
if (error instanceof ZodError) return error;
}
...@@ -79,6 +79,7 @@ export const createImageCaptionChildNodeResponse = ({ ...@@ -79,6 +79,7 @@ export const createImageCaptionChildNodeResponse = ({
queries: string[]; queries: string[];
}) => }) =>
createDatasetSearchChildNodeResponse({ createDatasetSearchChildNodeResponse({
requestId: requestIds?.[0],
requestIds, requestIds,
usage, usage,
seconds, seconds,
......
import { beforeEach, describe, expect, it, vi } from 'vitest';
import { z } from 'zod';
import { ApiRequestInputParseError } from '../../../common/zod/requestParseError';
vi.unmock('@fastgpt/service/common/response');
const logger = {
info: vi.fn(),
error: vi.fn()
};
vi.mock('@fastgpt/service/common/logger', () => ({
getLogger: () => logger,
LogCategories: {
HTTP: {
ERROR: 'http.error'
}
}
}));
const { processError } = await import('../../../common/response');
function buildZodError() {
try {
z.object({ name: z.string() }).parse({});
} catch (error) {
return error as z.ZodError;
}
throw new Error('Expected zod parse to fail');
}
describe('processError zod logging', () => {
beforeEach(() => {
logger.info.mockClear();
logger.error.mockClear();
});
it('does not log request input ZodError through the otel logger', () => {
const error = new ApiRequestInputParseError(buildZodError(), { inputSource: 'body' });
const processed = processError({
error,
url: '/api/test',
defaultCode: 400
});
expect(processed.httpStatus).toBe(400);
expect(processed.zodError).toBeTruthy();
expect(logger.info).not.toHaveBeenCalled();
expect(logger.error).not.toHaveBeenCalled();
});
it('does not require an api key header context to suppress request input ZodError logs', () => {
const error = new ApiRequestInputParseError(buildZodError(), { inputSource: 'query' });
const processed = processError({
error,
url: '/api/test',
defaultCode: 400
});
expect(processed.httpStatus).toBe(400);
expect(processed.zodError).toBeTruthy();
expect(logger.info).not.toHaveBeenCalled();
expect(logger.error).not.toHaveBeenCalled();
});
it('keeps unclassified ZodError at error level', () => {
const error = buildZodError();
processError({
error,
url: '/api/test',
defaultCode: 500
});
expect(logger.error).toHaveBeenCalledWith(
'Zod validation error',
expect.objectContaining({
url: '/api/test',
error
})
);
expect(logger.info).not.toHaveBeenCalled();
});
});
import { describe, expect, it } from 'vitest';
import { z } from 'zod';
import {
ApiRequestInputParseError,
getZodParseErrorInputSource,
parseApiInput
} from '../../../common/zod/requestParseError';
const schema = z.object({
name: z.string()
});
describe('getZodParseErrorInputSource', () => {
it('returns parsed inputs for provided schemas', () => {
const result = parseApiInput({
req: {
body: { name: 'body-name' },
query: { name: 'query-name' },
params: { name: 'params-name' }
},
bodySchema: schema,
querySchema: schema,
paramsSchema: schema
});
expect(result.body.name).toBe('body-name');
expect(result.query.name).toBe('query-name');
expect(result.params.name).toBe('params-name');
});
it('detects direct req.body parse failures in API-like routes', () => {
try {
parseApiInput({ req: { body: {}, query: {}, params: {} }, bodySchema: schema });
} catch (error) {
expect(error).toBeInstanceOf(ApiRequestInputParseError);
expect((error as ApiRequestInputParseError).cause).toBeInstanceOf(z.ZodError);
expect(getZodParseErrorInputSource(error)?.inputSource).toBe('body');
}
});
it('detects direct req.query parse failures in API-like routes', () => {
try {
parseApiInput({ req: { body: {}, query: {}, params: {} }, querySchema: schema });
} catch (error) {
expect(error).toBeInstanceOf(ApiRequestInputParseError);
expect(getZodParseErrorInputSource(error)?.inputSource).toBe('query');
}
});
it('detects direct req.params parse failures in API-like routes', () => {
try {
parseApiInput({ req: { body: {}, query: {}, params: {} }, paramsSchema: schema });
} catch (error) {
expect(error).toBeInstanceOf(ApiRequestInputParseError);
expect(getZodParseErrorInputSource(error)?.inputSource).toBe('params');
}
});
it('does not classify internal schema parse failures', () => {
try {
schema.parse({});
} catch (error) {
expect(error).toBeInstanceOf(z.ZodError);
expect(getZodParseErrorInputSource(error)).toBeUndefined();
}
});
});
Subproject commit fa441cde179aac9113f67941216c8d990c5ba681 Subproject commit 77d430d5b9223735d65a57e64f46224b2c68ff3f
...@@ -12,6 +12,7 @@ import { ...@@ -12,6 +12,7 @@ import {
type SkillDebugRecordsBody type SkillDebugRecordsBody
} from '@fastgpt/global/core/agentSkills/api'; } from '@fastgpt/global/core/agentSkills/api';
import type { GetRecordsV2ResponseType } from '@fastgpt/global/openapi/core/chat/record/api'; import type { GetRecordsV2ResponseType } from '@fastgpt/global/openapi/core/chat/record/api';
import { parseApiInput } from '@fastgpt/service/common/zod/requestParseError';
const commonField = `obj value adminFeedback userGoodFeedback userBadFeedback time hideInUI durationSeconds errorMsg ${DispatchNodeResponseKeyEnum.nodeResponse}`; const commonField = `obj value adminFeedback userGoodFeedback userBadFeedback time hideInUI durationSeconds errorMsg ${DispatchNodeResponseKeyEnum.nodeResponse}`;
...@@ -19,8 +20,10 @@ async function handler( ...@@ -19,8 +20,10 @@ async function handler(
req: ApiRequestProps<SkillDebugRecordsBody>, req: ApiRequestProps<SkillDebugRecordsBody>,
_res: ApiResponseType<any> _res: ApiResponseType<any>
): Promise<GetRecordsV2ResponseType> { ): Promise<GetRecordsV2ResponseType> {
const { skillId, chatId, pageSize, initialId, nextId, prevId } = const { skillId, chatId, pageSize, initialId, nextId, prevId } = parseApiInput({
SkillDebugRecordsBodySchema.parse(req.body); req,
bodySchema: SkillDebugRecordsBodySchema
}).body;
if (!skillId) throw new UserError('skillId is required'); if (!skillId) throw new UserError('skillId is required');
if (!chatId) throw new UserError('chatId is required'); if (!chatId) throw new UserError('chatId is required');
......
...@@ -21,12 +21,13 @@ import { ...@@ -21,12 +21,13 @@ import {
} from '@fastgpt/global/openapi/core/ai/agent/api'; } from '@fastgpt/global/openapi/core/ai/agent/api';
import { type OutLinkChatAuthProps } from '@fastgpt/global/support/permission/chat'; import { type OutLinkChatAuthProps } from '@fastgpt/global/support/permission/chat';
import { type ChatCompletionMessageParam } from '@fastgpt/global/core/ai/llm/type'; import { type ChatCompletionMessageParam } from '@fastgpt/global/core/ai/llm/type';
import { parseApiInput } from '@fastgpt/service/common/zod/requestParseError';
async function handler( async function handler(
req: ApiRequestProps, req: ApiRequestProps,
_res: NextApiResponse _res: NextApiResponse
): Promise<CreateQuestionGuideResponseType> { ): Promise<CreateQuestionGuideResponseType> {
const { messages } = CreateQuestionGuideBodySchema.parse(req.body); const { messages } = parseApiInput({ req, bodySchema: CreateQuestionGuideBodySchema }).body;
const { tmbId, teamId } = await authChatCert({ const { tmbId, teamId } = await authChatCert({
req, req,
......
...@@ -3,6 +3,7 @@ import { NextAPI } from '@/service/middleware/entry'; ...@@ -3,6 +3,7 @@ import { NextAPI } from '@/service/middleware/entry';
import { type ApiRequestProps } from '@fastgpt/service/type/next'; import { type ApiRequestProps } from '@fastgpt/service/type/next';
import { authChatCrud } from '@/service/support/permission/auth/chat'; import { authChatCrud } from '@/service/support/permission/auth/chat';
import { MongoSandboxInstance } from '@fastgpt/service/core/ai/sandbox/schema'; import { MongoSandboxInstance } from '@fastgpt/service/core/ai/sandbox/schema';
import { parseApiInput } from '@fastgpt/service/common/zod/requestParseError';
import { import {
SandboxCheckExistBodySchema, SandboxCheckExistBodySchema,
type SandboxCheckExistResponse type SandboxCheckExistResponse
...@@ -19,7 +20,7 @@ async function handler( ...@@ -19,7 +20,7 @@ async function handler(
} }
// 解析请求体 // 解析请求体
const body = SandboxCheckExistBodySchema.parse(req.body); const body = parseApiInput({ req, bodySchema: SandboxCheckExistBodySchema }).body;
const { appId, chatId, outLinkAuthData } = body; const { appId, chatId, outLinkAuthData } = body;
// 统一鉴权 // 统一鉴权
......
...@@ -5,6 +5,7 @@ import { authChatCrud } from '@/service/support/permission/auth/chat'; ...@@ -5,6 +5,7 @@ import { authChatCrud } from '@/service/support/permission/auth/chat';
import { getSandboxClient } from '@fastgpt/service/core/ai/sandbox/controller'; import { getSandboxClient } from '@fastgpt/service/core/ai/sandbox/controller';
import archiver from 'archiver'; import archiver from 'archiver';
import { SandboxDownloadBodySchema } from '@fastgpt/global/openapi/core/ai/sandbox/api'; import { SandboxDownloadBodySchema } from '@fastgpt/global/openapi/core/ai/sandbox/api';
import { parseApiInput } from '@fastgpt/service/common/zod/requestParseError';
import { import {
isSandboxPathDirectory, isSandboxPathDirectory,
getSandboxFileContent, getSandboxFileContent,
...@@ -12,7 +13,10 @@ import { ...@@ -12,7 +13,10 @@ import {
} from '@/service/core/sandbox/fileService'; } from '@/service/core/sandbox/fileService';
async function handler(req: ApiRequestProps, res: NextApiResponse): Promise<void> { async function handler(req: ApiRequestProps, res: NextApiResponse): Promise<void> {
const { appId, chatId, path, outLinkAuthData } = SandboxDownloadBodySchema.parse(req.body); const { appId, chatId, path, outLinkAuthData } = parseApiInput({
req,
bodySchema: SandboxDownloadBodySchema
}).body;
const { uid } = await authChatCrud({ const { uid } = await authChatCrud({
req, req,
......
...@@ -8,12 +8,16 @@ import { ...@@ -8,12 +8,16 @@ import {
type SandboxListResponse type SandboxListResponse
} from '@fastgpt/global/openapi/core/ai/sandbox/api'; } from '@fastgpt/global/openapi/core/ai/sandbox/api';
import { listSandboxDirectory } from '@/service/core/sandbox/fileService'; import { listSandboxDirectory } from '@/service/core/sandbox/fileService';
import { parseApiInput } from '@fastgpt/service/common/zod/requestParseError';
async function handler( async function handler(
req: ApiRequestProps, req: ApiRequestProps,
res: NextApiResponse<SandboxListResponse> res: NextApiResponse<SandboxListResponse>
): Promise<SandboxListResponse> { ): Promise<SandboxListResponse> {
const { appId, chatId, path, outLinkAuthData } = SandboxListBodySchema.parse(req.body); const { appId, chatId, path, outLinkAuthData } = parseApiInput({
req,
bodySchema: SandboxListBodySchema
}).body;
const { uid } = await authChatCrud({ const { uid } = await authChatCrud({
req, req,
......
...@@ -5,9 +5,13 @@ import { authChatCrud } from '@/service/support/permission/auth/chat'; ...@@ -5,9 +5,13 @@ import { authChatCrud } from '@/service/support/permission/auth/chat';
import { getSandboxClient } from '@fastgpt/service/core/ai/sandbox/controller'; import { getSandboxClient } from '@fastgpt/service/core/ai/sandbox/controller';
import { SandboxReadBodySchema } from '@fastgpt/global/openapi/core/ai/sandbox/api'; import { SandboxReadBodySchema } from '@fastgpt/global/openapi/core/ai/sandbox/api';
import { getSandboxFileContent } from '@/service/core/sandbox/fileService'; import { getSandboxFileContent } from '@/service/core/sandbox/fileService';
import { parseApiInput } from '@fastgpt/service/common/zod/requestParseError';
async function handler(req: ApiRequestProps, res: NextApiResponse): Promise<void> { async function handler(req: ApiRequestProps, res: NextApiResponse): Promise<void> {
const { appId, chatId, path, outLinkAuthData } = SandboxReadBodySchema.parse(req.body); const { appId, chatId, path, outLinkAuthData } = parseApiInput({
req,
bodySchema: SandboxReadBodySchema
}).body;
const { uid } = await authChatCrud({ const { uid } = await authChatCrud({
req, req,
......
...@@ -8,12 +8,16 @@ import { ...@@ -8,12 +8,16 @@ import {
type SandboxWriteResponse type SandboxWriteResponse
} from '@fastgpt/global/openapi/core/ai/sandbox/api'; } from '@fastgpt/global/openapi/core/ai/sandbox/api';
import { writeSandboxFile } from '@/service/core/sandbox/fileService'; import { writeSandboxFile } from '@/service/core/sandbox/fileService';
import { parseApiInput } from '@fastgpt/service/common/zod/requestParseError';
async function handler( async function handler(
req: ApiRequestProps, req: ApiRequestProps,
res: NextApiResponse<SandboxWriteResponse> res: NextApiResponse<SandboxWriteResponse>
): Promise<SandboxWriteResponse> { ): Promise<SandboxWriteResponse> {
const { appId, chatId, path, content, outLinkAuthData } = SandboxWriteBodySchema.parse(req.body); const { appId, chatId, path, content, outLinkAuthData } = parseApiInput({
req,
bodySchema: SandboxWriteBodySchema
}).body;
const { uid } = await authChatCrud({ const { uid } = await authChatCrud({
req, req,
......
...@@ -2,6 +2,7 @@ import type { ApiRequestProps, ApiResponseType } from '@fastgpt/service/type/nex ...@@ -2,6 +2,7 @@ import type { ApiRequestProps, ApiResponseType } from '@fastgpt/service/type/nex
import { NextAPI } from '@/service/middleware/entry'; import { NextAPI } from '@/service/middleware/entry';
import { MongoChatItem } from '@fastgpt/service/core/chat/chatItemSchema'; import { MongoChatItem } from '@fastgpt/service/core/chat/chatItemSchema';
import { authChatCrud } from '@/service/support/permission/auth/chat'; import { authChatCrud } from '@/service/support/permission/auth/chat';
import { parseApiInput } from '@fastgpt/service/common/zod/requestParseError';
import { import {
AdminUpdateFeedbackBodySchema, AdminUpdateFeedbackBodySchema,
AdminUpdateFeedbackResponseSchema, AdminUpdateFeedbackResponseSchema,
...@@ -12,8 +13,10 @@ async function handler( ...@@ -12,8 +13,10 @@ async function handler(
req: ApiRequestProps, req: ApiRequestProps,
_res: ApiResponseType<any> _res: ApiResponseType<any>
): Promise<AdminUpdateFeedbackResponseType> { ): Promise<AdminUpdateFeedbackResponseType> {
const { appId, chatId, dataId, datasetId, feedbackDataId, q, a } = const { appId, chatId, dataId, datasetId, feedbackDataId, q, a } = parseApiInput({
AdminUpdateFeedbackBodySchema.parse(req.body); req,
bodySchema: AdminUpdateFeedbackBodySchema
}).body;
await authChatCrud({ await authChatCrud({
req, req,
......
...@@ -5,6 +5,7 @@ import { MongoChatItem } from '@fastgpt/service/core/chat/chatItemSchema'; ...@@ -5,6 +5,7 @@ import { MongoChatItem } from '@fastgpt/service/core/chat/chatItemSchema';
import { authChatCrud } from '@/service/support/permission/auth/chat'; import { authChatCrud } from '@/service/support/permission/auth/chat';
import { mongoSessionRun } from '@fastgpt/service/common/mongo/sessionRun'; import { mongoSessionRun } from '@fastgpt/service/common/mongo/sessionRun';
import { updateChatFeedbackCount } from '@fastgpt/service/core/chat/controller'; import { updateChatFeedbackCount } from '@fastgpt/service/core/chat/controller';
import { parseApiInput } from '@fastgpt/service/common/zod/requestParseError';
import { import {
CloseCustomFeedbackBodySchema, CloseCustomFeedbackBodySchema,
CloseCustomFeedbackResponseSchema, CloseCustomFeedbackResponseSchema,
...@@ -15,7 +16,10 @@ async function handler( ...@@ -15,7 +16,10 @@ async function handler(
req: ApiRequestProps, req: ApiRequestProps,
_res: ApiResponseType<any> _res: ApiResponseType<any>
): Promise<CloseCustomFeedbackResponseType> { ): Promise<CloseCustomFeedbackResponseType> {
const { appId, chatId, dataId, index } = CloseCustomFeedbackBodySchema.parse(req.body); const { appId, chatId, dataId, index } = parseApiInput({
req,
bodySchema: CloseCustomFeedbackBodySchema
}).body;
await authChatCrud({ await authChatCrud({
req, req,
......
...@@ -7,6 +7,7 @@ import { mongoSessionRun } from '@fastgpt/service/common/mongo/sessionRun'; ...@@ -7,6 +7,7 @@ import { mongoSessionRun } from '@fastgpt/service/common/mongo/sessionRun';
import { updateChatFeedbackCount } from '@fastgpt/service/core/chat/controller'; import { updateChatFeedbackCount } from '@fastgpt/service/core/chat/controller';
import { MongoAppChatLog } from '@fastgpt/service/core/app/logs/chatLogsSchema'; import { MongoAppChatLog } from '@fastgpt/service/core/app/logs/chatLogsSchema';
import { ChatRoleEnum } from '@fastgpt/global/core/chat/constants'; import { ChatRoleEnum } from '@fastgpt/global/core/chat/constants';
import { parseApiInput } from '@fastgpt/service/common/zod/requestParseError';
import { import {
UpdateUserFeedbackBodySchema, UpdateUserFeedbackBodySchema,
UpdateUserFeedbackResponseSchema, UpdateUserFeedbackResponseSchema,
...@@ -17,8 +18,10 @@ async function handler( ...@@ -17,8 +18,10 @@ async function handler(
req: ApiRequestProps, req: ApiRequestProps,
res: NextApiResponse res: NextApiResponse
): Promise<UpdateUserFeedbackResponseType> { ): Promise<UpdateUserFeedbackResponseType> {
const { appId, chatId, dataId, userBadFeedback, userGoodFeedback } = const { appId, chatId, dataId, userBadFeedback, userGoodFeedback } = parseApiInput({
UpdateUserFeedbackBodySchema.parse(req.body); req,
bodySchema: UpdateUserFeedbackBodySchema
}).body;
const { teamId } = await authChatCrud({ const { teamId } = await authChatCrud({
req, req,
......
...@@ -3,9 +3,13 @@ import { NextAPI } from '@/service/middleware/entry'; ...@@ -3,9 +3,13 @@ import { NextAPI } from '@/service/middleware/entry';
import { getS3ChatSource } from '@fastgpt/service/common/s3/sources/chat'; import { getS3ChatSource } from '@fastgpt/service/common/s3/sources/chat';
import { authChatCrud } from '@/service/support/permission/auth/chat'; import { authChatCrud } from '@/service/support/permission/auth/chat';
import { PresignChatFileGetUrlSchema } from '@fastgpt/global/openapi/core/chat/file/api'; import { PresignChatFileGetUrlSchema } from '@fastgpt/global/openapi/core/chat/file/api';
import { parseApiInput } from '@fastgpt/service/common/zod/requestParseError';
async function handler(req: ApiRequestProps): Promise<string> { async function handler(req: ApiRequestProps): Promise<string> {
const { key, appId, mode, outLinkAuthData } = PresignChatFileGetUrlSchema.parse(req.body); const { key, appId, mode, outLinkAuthData } = parseApiInput({
req,
bodySchema: PresignChatFileGetUrlSchema
}).body;
await authChatCrud({ await authChatCrud({
req, req,
......
...@@ -10,10 +10,13 @@ import { PresignChatFilePostUrlSchema } from '@fastgpt/global/openapi/core/chat/ ...@@ -10,10 +10,13 @@ import { PresignChatFilePostUrlSchema } from '@fastgpt/global/openapi/core/chat/
import { getTeamPlanStatus } from '@fastgpt/service/support/wallet/sub/utils'; import { getTeamPlanStatus } from '@fastgpt/service/support/wallet/sub/utils';
import { S3ErrEnum } from '@fastgpt/global/common/error/code/s3'; import { S3ErrEnum } from '@fastgpt/global/common/error/code/s3';
import { serviceEnv } from '@fastgpt/service/env'; import { serviceEnv } from '@fastgpt/service/env';
import { parseApiInput } from '@fastgpt/service/common/zod/requestParseError';
async function handler(req: ApiRequestProps): Promise<CreatePostPresignedUrlResponseType> { async function handler(req: ApiRequestProps): Promise<CreatePostPresignedUrlResponseType> {
const { filename, appId, chatId, outLinkAuthData, fileSelectConfig } = const { filename, appId, chatId, outLinkAuthData, fileSelectConfig } = parseApiInput({
PresignChatFilePostUrlSchema.parse(req.body); req,
bodySchema: PresignChatFilePostUrlSchema
}).body;
const { teamId, uid } = await authChatCrud({ const { teamId, uid } = await authChatCrud({
req, req,
......
...@@ -10,9 +10,10 @@ import { authApp } from '@fastgpt/service/support/permission/app/auth'; ...@@ -10,9 +10,10 @@ import { authApp } from '@fastgpt/service/support/permission/app/auth';
import { AppReadChatLogPerVal } from '@fastgpt/global/support/permission/app/constant'; import { AppReadChatLogPerVal } from '@fastgpt/global/support/permission/app/constant';
import { ChatBatchDeleteBodySchema } from '@fastgpt/global/openapi/core/chat/history/api'; import { ChatBatchDeleteBodySchema } from '@fastgpt/global/openapi/core/chat/history/api';
import { deleteSandboxesByChatIds } from '@fastgpt/service/core/ai/sandbox/controller'; import { deleteSandboxesByChatIds } from '@fastgpt/service/core/ai/sandbox/controller';
import { parseApiInput } from '@fastgpt/service/common/zod/requestParseError';
async function handler(req: ApiRequestProps, res: NextApiResponse) { async function handler(req: ApiRequestProps, res: NextApiResponse) {
const { appId, chatIds } = ChatBatchDeleteBodySchema.parse(req.body); const { appId, chatIds } = parseApiInput({ req, bodySchema: ChatBatchDeleteBodySchema }).body;
await authApp({ await authApp({
req, req,
......
...@@ -4,10 +4,11 @@ import { DelChatHistorySchema } from '@fastgpt/global/openapi/core/chat/history/ ...@@ -4,10 +4,11 @@ import { DelChatHistorySchema } from '@fastgpt/global/openapi/core/chat/history/
import { authChatCrud } from '@/service/support/permission/auth/chat'; import { authChatCrud } from '@/service/support/permission/auth/chat';
import { NextAPI } from '@/service/middleware/entry'; import { NextAPI } from '@/service/middleware/entry';
import { type ApiRequestProps } from '@fastgpt/service/type/next'; import { type ApiRequestProps } from '@fastgpt/service/type/next';
import { parseApiInput } from '@fastgpt/service/common/zod/requestParseError';
/* delete single chat history (soft delete) */ /* delete single chat history (soft delete) */
export async function handler(req: ApiRequestProps, res: NextApiResponse) { export async function handler(req: ApiRequestProps, res: NextApiResponse) {
const { appId, chatId } = DelChatHistorySchema.parse(req.query); const { appId, chatId } = parseApiInput({ req, querySchema: DelChatHistorySchema }).query;
await authChatCrud({ await authChatCrud({
req, req,
......
...@@ -14,6 +14,7 @@ import { parsePaginationRequest } from '@fastgpt/service/common/api/pagination'; ...@@ -14,6 +14,7 @@ import { parsePaginationRequest } from '@fastgpt/service/common/api/pagination';
import { addMonths } from 'date-fns'; import { addMonths } from 'date-fns';
import { ObjectIdSchema } from '@fastgpt/global/common/type/mongo'; import { ObjectIdSchema } from '@fastgpt/global/common/type/mongo';
import { MongoApp } from '@fastgpt/service/core/app/schema'; import { MongoApp } from '@fastgpt/service/core/app/schema';
import { parseApiInput } from '@fastgpt/service/common/zod/requestParseError';
/* get chat histories list */ /* get chat histories list */
export async function handler( export async function handler(
...@@ -31,7 +32,7 @@ export async function handler( ...@@ -31,7 +32,7 @@ export async function handler(
endCreateTime, endCreateTime,
startUpdateTime, startUpdateTime,
endUpdateTime endUpdateTime
} = GetHistoriesBodySchema.parse(req.body); } = parseApiInput({ req, bodySchema: GetHistoriesBodySchema }).body;
const { offset, pageSize } = parsePaginationRequest(req); const { offset, pageSize } = parsePaginationRequest(req);
const match = await (async () => { const match = await (async () => {
......
...@@ -12,14 +12,17 @@ import { ...@@ -12,14 +12,17 @@ import {
} from '@fastgpt/global/openapi/core/chat/history/api'; } from '@fastgpt/global/openapi/core/chat/history/api';
import { addMonths } from 'date-fns'; import { addMonths } from 'date-fns';
import { ObjectIdSchema } from '@fastgpt/global/common/type/mongo'; import { ObjectIdSchema } from '@fastgpt/global/common/type/mongo';
import { parseApiInput } from '@fastgpt/service/common/zod/requestParseError';
/* Batch get chatGenerateStatus / hasBeenRead for sidebar sync */ /* Batch get chatGenerateStatus / hasBeenRead for sidebar sync */
export async function handler( export async function handler(
req: ApiRequestProps, req: ApiRequestProps,
_res: ApiResponseType _res: ApiResponseType
): Promise<GetHistoryStatusResponseType> { ): Promise<GetHistoryStatusResponseType> {
const { appId, chatIds, shareId, outLinkUid, teamId, teamToken } = const { appId, chatIds, shareId, outLinkUid, teamId, teamToken } = parseApiInput({
GetHistoryStatusBodySchema.parse(req.body); req,
bodySchema: GetHistoryStatusBodySchema
}).body;
const match = await (async () => { const match = await (async () => {
if (shareId && outLinkUid) { if (shareId && outLinkUid) {
......
...@@ -4,10 +4,11 @@ import { authChatCrud } from '@/service/support/permission/auth/chat'; ...@@ -4,10 +4,11 @@ import { authChatCrud } from '@/service/support/permission/auth/chat';
import { NextAPI } from '@/service/middleware/entry'; import { NextAPI } from '@/service/middleware/entry';
import { type ApiRequestProps, type ApiResponseType } from '@fastgpt/service/type/next'; import { type ApiRequestProps, type ApiResponseType } from '@fastgpt/service/type/next';
import { WritePermissionVal } from '@fastgpt/global/support/permission/constant'; import { WritePermissionVal } from '@fastgpt/global/support/permission/constant';
import { parseApiInput } from '@fastgpt/service/common/zod/requestParseError';
/** 将对话标为已读(例如用户在本页看完流式回复后) */ /** 将对话标为已读(例如用户在本页看完流式回复后) */
export async function handler(req: ApiRequestProps, _res: ApiResponseType): Promise<void> { export async function handler(req: ApiRequestProps, _res: ApiResponseType): Promise<void> {
const body = MarkChatReadBodySchema.parse(req.body); const body = parseApiInput({ req, bodySchema: MarkChatReadBodySchema }).body;
await authChatCrud({ await authChatCrud({
req, req,
......
...@@ -5,10 +5,14 @@ import { authChatCrud } from '@/service/support/permission/auth/chat'; ...@@ -5,10 +5,14 @@ import { authChatCrud } from '@/service/support/permission/auth/chat';
import { NextAPI } from '@/service/middleware/entry'; import { NextAPI } from '@/service/middleware/entry';
import { type ApiRequestProps } from '@fastgpt/service/type/next'; import { type ApiRequestProps } from '@fastgpt/service/type/next';
import { WritePermissionVal } from '@fastgpt/global/support/permission/constant'; import { WritePermissionVal } from '@fastgpt/global/support/permission/constant';
import { parseApiInput } from '@fastgpt/service/common/zod/requestParseError';
/* update chat history: title, customTitle, top */ /* update chat history: title, customTitle, top */
export async function handler(req: ApiRequestProps, res: NextApiResponse) { export async function handler(req: ApiRequestProps, res: NextApiResponse) {
const { appId, chatId, title, customTitle, top } = UpdateHistoryBodySchema.parse(req.body); const { appId, chatId, title, customTitle, top } = parseApiInput({
req,
bodySchema: UpdateHistoryBodySchema
}).body;
await authChatCrud({ await authChatCrud({
req, req,
authToken: true, authToken: true,
......
...@@ -15,9 +15,10 @@ import { AppErrEnum } from '@fastgpt/global/common/error/code/app'; ...@@ -15,9 +15,10 @@ import { AppErrEnum } from '@fastgpt/global/common/error/code/app';
import { authCert } from '@fastgpt/service/support/permission/auth/common'; import { authCert } from '@fastgpt/service/support/permission/auth/common';
import { InitChatQuerySchema } from '@fastgpt/global/openapi/core/chat/controler/api'; import { InitChatQuerySchema } from '@fastgpt/global/openapi/core/chat/controler/api';
import { ChatGenerateStatusEnum } from '@fastgpt/global/core/chat/constants'; import { ChatGenerateStatusEnum } from '@fastgpt/global/core/chat/constants';
import { parseApiInput } from '@fastgpt/service/common/zod/requestParseError';
async function handler(req: NextApiRequest, res: NextApiResponse): Promise<InitChatResponseType> { async function handler(req: NextApiRequest, res: NextApiResponse): Promise<InitChatResponseType> {
const { appId, chatId } = InitChatQuerySchema.parse(req.query); const { appId, chatId } = parseApiInput({ req, querySchema: InitChatQuerySchema }).query;
try { try {
// auth app permission // auth app permission
......
...@@ -16,6 +16,7 @@ import { ...@@ -16,6 +16,7 @@ import {
import { GetChatTypeEnum } from '@fastgpt/global/core/chat/constants'; import { GetChatTypeEnum } from '@fastgpt/global/core/chat/constants';
import { parsePaginationRequest } from '@fastgpt/service/common/api/pagination'; import { parsePaginationRequest } from '@fastgpt/service/common/api/pagination';
import { addPreviewUrlToChatItems } from '@fastgpt/service/core/chat/utils'; import { addPreviewUrlToChatItems } from '@fastgpt/service/core/chat/utils';
import { parseApiInput } from '@fastgpt/service/common/zod/requestParseError';
import { import {
GetPaginationRecordsBodySchema, GetPaginationRecordsBodySchema,
GetPaginationRecordsResponseSchema, GetPaginationRecordsResponseSchema,
...@@ -32,7 +33,7 @@ export async function handler( ...@@ -32,7 +33,7 @@ export async function handler(
loadCustomFeedbacks = false, loadCustomFeedbacks = false,
type = GetChatTypeEnum.normal, type = GetChatTypeEnum.normal,
...authProps ...authProps
} = GetPaginationRecordsBodySchema.parse(req.body); } = parseApiInput({ req, bodySchema: GetPaginationRecordsBodySchema }).body;
const { offset, pageSize } = parsePaginationRequest(req); const { offset, pageSize } = parsePaginationRequest(req);
......
...@@ -15,6 +15,7 @@ import { ...@@ -15,6 +15,7 @@ import {
import { GetChatTypeEnum } from '@fastgpt/global/core/chat/constants'; import { GetChatTypeEnum } from '@fastgpt/global/core/chat/constants';
import type { AIChatItemValueItemType } from '@fastgpt/global/core/chat/type'; import type { AIChatItemValueItemType } from '@fastgpt/global/core/chat/type';
import { addPreviewUrlToChatItems } from '@fastgpt/service/core/chat/utils'; import { addPreviewUrlToChatItems } from '@fastgpt/service/core/chat/utils';
import { parseApiInput } from '@fastgpt/service/common/zod/requestParseError';
import { import {
GetRecordsV2BodySchema, GetRecordsV2BodySchema,
type GetRecordsV2ResponseType type GetRecordsV2ResponseType
...@@ -96,7 +97,7 @@ async function handler( ...@@ -96,7 +97,7 @@ async function handler(
nextId, nextId,
prevId, prevId,
includeDeleted = false includeDeleted = false
} = GetRecordsV2BodySchema.parse(req.body); } = parseApiInput({ req, bodySchema: GetRecordsV2BodySchema }).body;
if (!appId || !chatId) { if (!appId || !chatId) {
return { return {
......
...@@ -7,13 +7,16 @@ import { type ChatHistoryItemResType } from '@fastgpt/global/core/chat/type'; ...@@ -7,13 +7,16 @@ import { type ChatHistoryItemResType } from '@fastgpt/global/core/chat/type';
import { filterPublicNodeResponseData } from '@fastgpt/global/core/chat/utils'; import { filterPublicNodeResponseData } from '@fastgpt/global/core/chat/utils';
import { MongoChatItemResponse } from '@fastgpt/service/core/chat/chatItemResponseSchema'; import { MongoChatItemResponse } from '@fastgpt/service/core/chat/chatItemResponseSchema';
import { GetResDataQuerySchema } from '@fastgpt/global/openapi/core/chat/record/api'; import { GetResDataQuerySchema } from '@fastgpt/global/openapi/core/chat/record/api';
import { parseApiInput } from '@fastgpt/service/common/zod/requestParseError';
export async function handler( export async function handler(
req: ApiRequestProps, req: ApiRequestProps,
res: ApiResponseType<any> res: ApiResponseType<any>
): Promise<ChatHistoryItemResType[]> { ): Promise<ChatHistoryItemResType[]> {
const { appId, chatId, dataId, shareId, outLinkUid, teamId, teamToken } = const { appId, chatId, dataId, shareId, outLinkUid, teamId, teamToken } = parseApiInput({
GetResDataQuerySchema.parse(req.query); req,
querySchema: GetResDataQuerySchema
}).query;
if (!appId || !chatId || !dataId) { if (!appId || !chatId || !dataId) {
return []; return [];
} }
......
...@@ -9,6 +9,7 @@ import { getTTSModel } from '@fastgpt/service/core/ai/model'; ...@@ -9,6 +9,7 @@ import { getTTSModel } from '@fastgpt/service/core/ai/model';
import { MongoTTSBuffer } from '@fastgpt/service/common/buffer/tts/schema'; import { MongoTTSBuffer } from '@fastgpt/service/common/buffer/tts/schema';
import { type ApiRequestProps } from '@fastgpt/service/type/next'; import { type ApiRequestProps } from '@fastgpt/service/type/next';
import { GetChatSpeechBodySchema } from '@fastgpt/global/openapi/core/chat/record/api'; import { GetChatSpeechBodySchema } from '@fastgpt/global/openapi/core/chat/record/api';
import { parseApiInput } from '@fastgpt/service/common/zod/requestParseError';
/* /*
1. get tts from chatItem store 1. get tts from chatItem store
...@@ -17,7 +18,7 @@ import { GetChatSpeechBodySchema } from '@fastgpt/global/openapi/core/chat/recor ...@@ -17,7 +18,7 @@ import { GetChatSpeechBodySchema } from '@fastgpt/global/openapi/core/chat/recor
*/ */
async function handler(req: ApiRequestProps, res: NextApiResponse) { async function handler(req: ApiRequestProps, res: NextApiResponse) {
try { try {
const { ttsConfig, input } = GetChatSpeechBodySchema.parse(req.body); const { ttsConfig, input } = parseApiInput({ req, bodySchema: GetChatSpeechBodySchema }).body;
if (!ttsConfig.model || !ttsConfig.voice) { if (!ttsConfig.model || !ttsConfig.voice) {
throw new Error('model or voice not found'); throw new Error('model or voice not found');
......
...@@ -6,6 +6,7 @@ import type { ApiRequestProps } from '@fastgpt/service/type/next'; ...@@ -6,6 +6,7 @@ import type { ApiRequestProps } from '@fastgpt/service/type/next';
import { authCert } from '@fastgpt/service/support/permission/auth/common'; import { authCert } from '@fastgpt/service/support/permission/auth/common';
import { authDataset } from '@fastgpt/service/support/permission/dataset/auth'; import { authDataset } from '@fastgpt/service/support/permission/dataset/auth';
import { ManagePermissionVal } from '@fastgpt/global/support/permission/constant'; import { ManagePermissionVal } from '@fastgpt/global/support/permission/constant';
import { parseApiInput } from '@fastgpt/service/common/zod/requestParseError';
import { import {
GetApiDatasetPathNamesBodySchema, GetApiDatasetPathNamesBodySchema,
GetApiDatasetPathNamesResponseSchema, GetApiDatasetPathNamesResponseSchema,
...@@ -38,7 +39,7 @@ async function handler( ...@@ -38,7 +39,7 @@ async function handler(
datasetId, datasetId,
parentId, parentId,
apiDatasetServer: bodyApiDatasetServer apiDatasetServer: bodyApiDatasetServer
} = GetApiDatasetPathNamesBodySchema.parse(req.body); } = parseApiInput({ req, bodySchema: GetApiDatasetPathNamesBodySchema }).body;
if (!parentId) return GetApiDatasetPathNamesResponseSchema.parse(''); if (!parentId) return GetApiDatasetPathNamesResponseSchema.parse('');
......
...@@ -3,6 +3,7 @@ import { ReadPermissionVal } from '@fastgpt/global/support/permission/constant'; ...@@ -3,6 +3,7 @@ import { ReadPermissionVal } from '@fastgpt/global/support/permission/constant';
import { getApiDatasetRequest } from '@fastgpt/service/core/dataset/apiDataset'; import { getApiDatasetRequest } from '@fastgpt/service/core/dataset/apiDataset';
import { authDataset } from '@fastgpt/service/support/permission/dataset/auth'; import { authDataset } from '@fastgpt/service/support/permission/dataset/auth';
import type { ApiRequestProps } from '@fastgpt/service/type/next'; import type { ApiRequestProps } from '@fastgpt/service/type/next';
import { parseApiInput } from '@fastgpt/service/common/zod/requestParseError';
import { import {
GetApiDatasetFileListBodySchema, GetApiDatasetFileListBodySchema,
GetApiDatasetFileListResponseSchema, GetApiDatasetFileListResponseSchema,
...@@ -13,7 +14,11 @@ import { ...@@ -13,7 +14,11 @@ import {
async function handler( async function handler(
req: ApiRequestProps<GetApiDatasetFileListBody> req: ApiRequestProps<GetApiDatasetFileListBody>
): Promise<GetApiDatasetFileListResponse> { ): Promise<GetApiDatasetFileListResponse> {
const { datasetId, searchKey = '', parentId } = GetApiDatasetFileListBodySchema.parse(req.body); const {
datasetId,
searchKey = '',
parentId
} = parseApiInput({ req, bodySchema: GetApiDatasetFileListBodySchema }).body;
const { dataset } = await authDataset({ const { dataset } = await authDataset({
req, req,
......
...@@ -3,6 +3,7 @@ import { NextAPI } from '@/service/middleware/entry'; ...@@ -3,6 +3,7 @@ import { NextAPI } from '@/service/middleware/entry';
import { authDataset } from '@fastgpt/service/support/permission/dataset/auth'; import { authDataset } from '@fastgpt/service/support/permission/dataset/auth';
import { ReadPermissionVal } from '@fastgpt/global/support/permission/constant'; import { ReadPermissionVal } from '@fastgpt/global/support/permission/constant';
import { MongoDatasetCollection } from '@fastgpt/service/core/dataset/collection/schema'; import { MongoDatasetCollection } from '@fastgpt/service/core/dataset/collection/schema';
import { parseApiInput } from '@fastgpt/service/common/zod/requestParseError';
import { import {
GetApiDatasetFileListExistIdQuerySchema, GetApiDatasetFileListExistIdQuerySchema,
GetApiDatasetFileListExistIdResponseSchema, GetApiDatasetFileListExistIdResponseSchema,
...@@ -13,7 +14,10 @@ import { ...@@ -13,7 +14,10 @@ import {
async function handler( async function handler(
req: ApiRequestProps<unknown, GetApiDatasetFileListExistIdQuery> req: ApiRequestProps<unknown, GetApiDatasetFileListExistIdQuery>
): Promise<GetApiDatasetFileListExistIdResponse> { ): Promise<GetApiDatasetFileListExistIdResponse> {
const { datasetId } = GetApiDatasetFileListExistIdQuerySchema.parse(req.query); const { datasetId } = parseApiInput({
req,
querySchema: GetApiDatasetFileListExistIdQuerySchema
}).query;
const { dataset } = await authDataset({ const { dataset } = await authDataset({
req, req,
......
...@@ -6,6 +6,7 @@ import { addAuditLog } from '@fastgpt/service/support/user/audit/util'; ...@@ -6,6 +6,7 @@ import { addAuditLog } from '@fastgpt/service/support/user/audit/util';
import { AuditEventEnum } from '@fastgpt/global/support/user/audit/constants'; import { AuditEventEnum } from '@fastgpt/global/support/user/audit/constants';
import { getI18nDatasetType } from '@fastgpt/service/support/user/audit/util'; import { getI18nDatasetType } from '@fastgpt/service/support/user/audit/util';
import type { ApiRequestProps } from '@fastgpt/service/type/next'; import type { ApiRequestProps } from '@fastgpt/service/type/next';
import { parseApiInput } from '@fastgpt/service/common/zod/requestParseError';
import { import {
CreateCollectionBodySchema, CreateCollectionBodySchema,
CreateCollectionResponseSchema, CreateCollectionResponseSchema,
...@@ -13,7 +14,7 @@ import { ...@@ -13,7 +14,7 @@ import {
} from '@fastgpt/global/openapi/core/dataset/collection/createApi'; } from '@fastgpt/global/openapi/core/dataset/collection/createApi';
async function handler(req: ApiRequestProps): Promise<CreateCollectionResponseType> { async function handler(req: ApiRequestProps): Promise<CreateCollectionResponseType> {
const body = CreateCollectionBodySchema.parse(req.body); const body = parseApiInput({ req, bodySchema: CreateCollectionBodySchema }).body;
const { teamId, tmbId, dataset } = await authDataset({ const { teamId, tmbId, dataset } = await authDataset({
req, req,
......
...@@ -5,9 +5,13 @@ import { type ApiRequestProps } from '@fastgpt/service/type/next'; ...@@ -5,9 +5,13 @@ import { type ApiRequestProps } from '@fastgpt/service/type/next';
import { getApiDatasetRequest } from '@fastgpt/service/core/dataset/apiDataset'; import { getApiDatasetRequest } from '@fastgpt/service/core/dataset/apiDataset';
import { createApiDatasetCollection } from './apiCollectionV2'; import { createApiDatasetCollection } from './apiCollectionV2';
import { CreateApiCollectionBodySchema } from '@fastgpt/global/openapi/core/dataset/collection/createApi'; import { CreateApiCollectionBodySchema } from '@fastgpt/global/openapi/core/dataset/collection/createApi';
import { parseApiInput } from '@fastgpt/service/common/zod/requestParseError';
async function handler(req: ApiRequestProps) { async function handler(req: ApiRequestProps) {
const { apiFileId, ...body } = CreateApiCollectionBodySchema.parse(req.body); const { apiFileId, ...body } = parseApiInput({
req,
bodySchema: CreateApiCollectionBodySchema
}).body;
const { teamId, tmbId, dataset } = await authDataset({ const { teamId, tmbId, dataset } = await authDataset({
req, req,
......
...@@ -20,9 +20,10 @@ import { type DatasetSchemaType } from '@fastgpt/global/core/dataset/type'; ...@@ -20,9 +20,10 @@ import { type DatasetSchemaType } from '@fastgpt/global/core/dataset/type';
import { RootCollectionId } from '@fastgpt/global/core/dataset/collection/constants'; import { RootCollectionId } from '@fastgpt/global/core/dataset/collection/constants';
import type { DatasetPermission } from '@fastgpt/global/support/permission/dataset/controller'; import type { DatasetPermission } from '@fastgpt/global/support/permission/dataset/controller';
import { checkDatasetIndexLimit } from '@fastgpt/service/support/permission/teamLimit'; import { checkDatasetIndexLimit } from '@fastgpt/service/support/permission/teamLimit';
import { parseApiInput } from '@fastgpt/service/common/zod/requestParseError';
async function handler(req: ApiRequestProps<CreateApiCollectionV2BodyType>) { async function handler(req: ApiRequestProps<CreateApiCollectionV2BodyType>) {
const body = CreateApiCollectionV2BodySchema.parse(req.body); const body = parseApiInput({ req, bodySchema: CreateApiCollectionV2BodySchema }).body;
const { teamId, tmbId, dataset } = await authDataset({ const { teamId, tmbId, dataset } = await authDataset({
req, req,
......
...@@ -12,9 +12,13 @@ import { CommonErrEnum } from '@fastgpt/global/common/error/code/common'; ...@@ -12,9 +12,13 @@ import { CommonErrEnum } from '@fastgpt/global/common/error/code/common';
import { getS3DatasetSource } from '@fastgpt/service/common/s3/sources/dataset'; import { getS3DatasetSource } from '@fastgpt/service/common/s3/sources/dataset';
import { isS3ObjectKey } from '@fastgpt/service/common/s3/utils'; import { isS3ObjectKey } from '@fastgpt/service/common/s3/utils';
import { checkDatasetIndexLimit } from '@fastgpt/service/support/permission/teamLimit'; import { checkDatasetIndexLimit } from '@fastgpt/service/support/permission/teamLimit';
import { parseApiInput } from '@fastgpt/service/common/zod/requestParseError';
async function handler(req: ApiRequestProps): Promise<CreateCollectionWithResultResponseType> { async function handler(req: ApiRequestProps): Promise<CreateCollectionWithResultResponseType> {
const { fileId, customPdfParse, ...body } = CreateCollectionByFileIdBodySchema.parse(req.body); const { fileId, customPdfParse, ...body } = parseApiInput({
req,
bodySchema: CreateCollectionByFileIdBodySchema
}).body;
const { teamId, tmbId, dataset } = await authDataset({ const { teamId, tmbId, dataset } = await authDataset({
req, req,
......
...@@ -9,9 +9,10 @@ import { ...@@ -9,9 +9,10 @@ import {
type CreateCollectionWithResultResponseType type CreateCollectionWithResultResponseType
} from '@fastgpt/global/openapi/core/dataset/collection/createApi'; } from '@fastgpt/global/openapi/core/dataset/collection/createApi';
import { checkDatasetIndexLimit } from '@fastgpt/service/support/permission/teamLimit'; import { checkDatasetIndexLimit } from '@fastgpt/service/support/permission/teamLimit';
import { parseApiInput } from '@fastgpt/service/common/zod/requestParseError';
async function handler(req: ApiRequestProps): Promise<CreateCollectionWithResultResponseType> { async function handler(req: ApiRequestProps): Promise<CreateCollectionWithResultResponseType> {
const { link, ...body } = CreateLinkCollectionBodySchema.parse(req.body); const { link, ...body } = parseApiInput({ req, bodySchema: CreateLinkCollectionBodySchema }).body;
const { teamId, tmbId, dataset } = await authDataset({ const { teamId, tmbId, dataset } = await authDataset({
req, req,
......
...@@ -12,9 +12,13 @@ import { ...@@ -12,9 +12,13 @@ import {
type CreateCollectionWithResultResponseType type CreateCollectionWithResultResponseType
} from '@fastgpt/global/openapi/core/dataset/collection/createApi'; } from '@fastgpt/global/openapi/core/dataset/collection/createApi';
import { checkDatasetIndexLimit } from '@fastgpt/service/support/permission/teamLimit'; import { checkDatasetIndexLimit } from '@fastgpt/service/support/permission/teamLimit';
import { parseApiInput } from '@fastgpt/service/common/zod/requestParseError';
async function handler(req: ApiRequestProps): Promise<CreateCollectionWithResultResponseType> { async function handler(req: ApiRequestProps): Promise<CreateCollectionWithResultResponseType> {
const { name, text, ...body } = CreateTextCollectionBodySchema.parse(req.body); const { name, text, ...body } = parseApiInput({
req,
bodySchema: CreateTextCollectionBodySchema
}).body;
const { teamId, tmbId, dataset } = await authDataset({ const { teamId, tmbId, dataset } = await authDataset({
req, req,
......
...@@ -9,14 +9,15 @@ import { addAuditLog } from '@fastgpt/service/support/user/audit/util'; ...@@ -9,14 +9,15 @@ import { addAuditLog } from '@fastgpt/service/support/user/audit/util';
import { AuditEventEnum } from '@fastgpt/global/support/user/audit/constants'; import { AuditEventEnum } from '@fastgpt/global/support/user/audit/constants';
import { getI18nDatasetType } from '@fastgpt/service/support/user/audit/util'; import { getI18nDatasetType } from '@fastgpt/service/support/user/audit/util';
import type { ApiRequestProps } from '@fastgpt/service/type/next'; import type { ApiRequestProps } from '@fastgpt/service/type/next';
import { parseApiInput } from '@fastgpt/service/common/zod/requestParseError';
import { import {
DeleteCollectionBodySchema, DeleteCollectionBodySchema,
DeleteCollectionQuerySchema DeleteCollectionQuerySchema
} from '@fastgpt/global/openapi/core/dataset/collection/api'; } from '@fastgpt/global/openapi/core/dataset/collection/api';
async function handler(req: ApiRequestProps) { async function handler(req: ApiRequestProps) {
const { id } = DeleteCollectionQuerySchema.parse(req.query); const { id } = parseApiInput({ req, querySchema: DeleteCollectionQuerySchema }).query;
const { collectionIds } = DeleteCollectionBodySchema.parse(req.body); const { collectionIds } = parseApiInput({ req, bodySchema: DeleteCollectionBodySchema }).body;
const deletedIds = id ? [id] : collectionIds; const deletedIds = id ? [id] : collectionIds;
......
...@@ -13,13 +13,14 @@ import { getS3DatasetSource } from '@fastgpt/service/common/s3/sources/dataset'; ...@@ -13,13 +13,14 @@ import { getS3DatasetSource } from '@fastgpt/service/common/s3/sources/dataset';
import { isS3ObjectKey } from '@fastgpt/service/common/s3/utils'; import { isS3ObjectKey } from '@fastgpt/service/common/s3/utils';
import type { ApiRequestProps } from '@fastgpt/service/type/next'; import type { ApiRequestProps } from '@fastgpt/service/type/next';
import type { GetCollectionDetailResponseType } from '@fastgpt/global/openapi/core/dataset/collection/api'; import type { GetCollectionDetailResponseType } from '@fastgpt/global/openapi/core/dataset/collection/api';
import { parseApiInput } from '@fastgpt/service/common/zod/requestParseError';
import { import {
GetCollectionDetailQuerySchema, GetCollectionDetailQuerySchema,
GetCollectionDetailResponseSchema GetCollectionDetailResponseSchema
} from '@fastgpt/global/openapi/core/dataset/collection/api'; } from '@fastgpt/global/openapi/core/dataset/collection/api';
async function handler(req: ApiRequestProps): Promise<GetCollectionDetailResponseType> { async function handler(req: ApiRequestProps): Promise<GetCollectionDetailResponseType> {
const { id } = GetCollectionDetailQuerySchema.parse(req.query); const { id } = parseApiInput({ req, querySchema: GetCollectionDetailQuerySchema }).query;
// 凭证校验 // 凭证校验
const { collection, permission } = await authDatasetCollection({ const { collection, permission } = await authDatasetCollection({
......
...@@ -15,10 +15,11 @@ import { sanitizeCsvField } from '@fastgpt/service/common/file/csv'; ...@@ -15,10 +15,11 @@ import { sanitizeCsvField } from '@fastgpt/service/common/file/csv';
import { replaceS3KeyToPreviewUrl } from '@fastgpt/service/core/dataset/utils'; import { replaceS3KeyToPreviewUrl } from '@fastgpt/service/core/dataset/utils';
import { addDays } from 'date-fns'; import { addDays } from 'date-fns';
import { ExportCollectionBodySchema } from '@fastgpt/global/openapi/core/dataset/collection/api'; import { ExportCollectionBodySchema } from '@fastgpt/global/openapi/core/dataset/collection/api';
import { parseApiInput } from '@fastgpt/service/common/zod/requestParseError';
const logger = getLogger(LogCategories.MODULE.DATASET.COLLECTION); const logger = getLogger(LogCategories.MODULE.DATASET.COLLECTION);
async function handler(req: ApiRequestProps, res: NextApiResponse) { async function handler(req: ApiRequestProps, res: NextApiResponse) {
const parseBody = ExportCollectionBodySchema.parse(req.body); const parseBody = parseApiInput({ req, bodySchema: ExportCollectionBodySchema }).body;
const collectionId = parseBody.collectionId; const collectionId = parseBody.collectionId;
const { const {
......
...@@ -13,6 +13,7 @@ import { readFromSecondary } from '@fastgpt/service/common/mongo/utils'; ...@@ -13,6 +13,7 @@ import { readFromSecondary } from '@fastgpt/service/common/mongo/utils';
import { collectionTagsToTagLabel } from '@fastgpt/service/core/dataset/collection/utils'; import { collectionTagsToTagLabel } from '@fastgpt/service/core/dataset/collection/utils';
import { replaceRegChars } from '@fastgpt/global/common/string/tools'; import { replaceRegChars } from '@fastgpt/global/common/string/tools';
import { z } from 'zod'; import { z } from 'zod';
import { parseApiInput } from '@fastgpt/service/common/zod/requestParseError';
const BodySchema = z.object({ const BodySchema = z.object({
pageNum: z.number().int().min(1).default(1), pageNum: z.number().int().min(1).default(1),
...@@ -27,7 +28,7 @@ const BodySchema = z.object({ ...@@ -27,7 +28,7 @@ const BodySchema = z.object({
async function handler(req: NextApiRequest) { async function handler(req: NextApiRequest) {
const { pageNum, pageSize, datasetId, parentId, searchText, selectFolder, filterTags, simple } = const { pageNum, pageSize, datasetId, parentId, searchText, selectFolder, filterTags, simple } =
BodySchema.parse(req.body); parseApiInput({ req, bodySchema: BodySchema }).body;
const regexText = searchText ? replaceRegChars(searchText) : ''; const regexText = searchText ? replaceRegChars(searchText) : '';
// auth dataset and get my role // auth dataset and get my role
......
...@@ -11,6 +11,7 @@ import { MongoDatasetData } from '@fastgpt/service/core/dataset/data/schema'; ...@@ -11,6 +11,7 @@ import { MongoDatasetData } from '@fastgpt/service/core/dataset/data/schema';
import { MongoDatasetTraining } from '@fastgpt/service/core/dataset/training/schema'; import { MongoDatasetTraining } from '@fastgpt/service/core/dataset/training/schema';
import { replaceRegChars } from '@fastgpt/global/common/string/tools'; import { replaceRegChars } from '@fastgpt/global/common/string/tools';
import type { ApiRequestProps } from '@fastgpt/service/type/next'; import type { ApiRequestProps } from '@fastgpt/service/type/next';
import { parseApiInput } from '@fastgpt/service/common/zod/requestParseError';
import { import {
ListCollectionV2BodySchema, ListCollectionV2BodySchema,
ListCollectionV2ResponseSchema, ListCollectionV2ResponseSchema,
...@@ -18,21 +19,21 @@ import { ...@@ -18,21 +19,21 @@ import {
} from '@fastgpt/global/openapi/core/dataset/collection/api'; } from '@fastgpt/global/openapi/core/dataset/collection/api';
async function handler(req: ApiRequestProps): Promise<ListCollectionV2ResponseType> { async function handler(req: ApiRequestProps): Promise<ListCollectionV2ResponseType> {
let { const {
datasetId, datasetId,
parentId, parentId,
searchText, searchText: rawSearchText,
selectFolder, selectFolder,
filterTags, filterTags,
simple, simple,
pageSize: rawPageSize, pageSize: rawPageSize,
offset: rawOffset, offset: rawOffset,
pageNum: rawPageNum pageNum: rawPageNum
} = ListCollectionV2BodySchema.parse(req.body); } = parseApiInput({ req, bodySchema: ListCollectionV2BodySchema }).body;
let pageSize = Math.min(Number(rawPageSize ?? 10), 100); const pageSize = Math.min(Number(rawPageSize ?? 10), 100);
let offset = const offset =
rawOffset !== undefined ? Number(rawOffset) : (Number(rawPageNum ?? 1) - 1) * pageSize; rawOffset !== undefined ? Number(rawOffset) : (Number(rawPageNum ?? 1) - 1) * pageSize;
searchText = searchText?.replace(/'/g, ''); const searchText = rawSearchText?.replace(/'/g, '');
// auth dataset and get my role // auth dataset and get my role
const { teamId, permission } = await authDataset({ const { teamId, permission } = await authDataset({
......
...@@ -9,6 +9,7 @@ import { getCollectionWithDataset } from '@fastgpt/service/core/dataset/controll ...@@ -9,6 +9,7 @@ import { getCollectionWithDataset } from '@fastgpt/service/core/dataset/controll
import { getApiDatasetRequest } from '@fastgpt/service/core/dataset/apiDataset'; import { getApiDatasetRequest } from '@fastgpt/service/core/dataset/apiDataset';
import { isS3ObjectKey } from '@fastgpt/service/common/s3/utils'; import { isS3ObjectKey } from '@fastgpt/service/common/s3/utils';
import { getS3DatasetSource } from '@fastgpt/service/common/s3/sources/dataset'; import { getS3DatasetSource } from '@fastgpt/service/common/s3/sources/dataset';
import { parseApiInput } from '@fastgpt/service/common/zod/requestParseError';
import { import {
ReadCollectionSourceBodySchema, ReadCollectionSourceBodySchema,
ReadCollectionSourceResponseSchema, ReadCollectionSourceResponseSchema,
...@@ -17,7 +18,7 @@ import { ...@@ -17,7 +18,7 @@ import {
async function handler(req: ApiRequestProps): Promise<ReadCollectionSourceResponseType> { async function handler(req: ApiRequestProps): Promise<ReadCollectionSourceResponseType> {
const { collectionId, appId, chatId, chatItemDataId, shareId, outLinkUid, teamId, teamToken } = const { collectionId, appId, chatId, chatItemDataId, shareId, outLinkUid, teamId, teamToken } =
ReadCollectionSourceBodySchema.parse(req.body); parseApiInput({ req, bodySchema: ReadCollectionSourceBodySchema }).body;
const { collection } = await (async () => { const { collection } = await (async () => {
if (!appId || !chatId || !chatItemDataId) { if (!appId || !chatId || !chatItemDataId) {
......
...@@ -12,16 +12,19 @@ import type { DatasetCollectionsListItemType } from '@fastgpt/global/openapi/cor ...@@ -12,16 +12,19 @@ import type { DatasetCollectionsListItemType } from '@fastgpt/global/openapi/cor
import { parsePaginationRequest } from '@fastgpt/service/common/api/pagination'; import { parsePaginationRequest } from '@fastgpt/service/common/api/pagination';
import { replaceRegChars } from '@fastgpt/global/common/string/tools'; import { replaceRegChars } from '@fastgpt/global/common/string/tools';
import { ScrollCollectionsBodySchema } from '@fastgpt/global/openapi/core/dataset/collection/api'; import { ScrollCollectionsBodySchema } from '@fastgpt/global/openapi/core/dataset/collection/api';
import { parseApiInput } from '@fastgpt/service/common/zod/requestParseError';
async function handler( async function handler(
req: ApiRequestProps req: ApiRequestProps
): Promise<PaginationResponse<DatasetCollectionsListItemType>> { ): Promise<PaginationResponse<DatasetCollectionsListItemType>> {
const { datasetId, parentId, searchText, selectFolder, filterTags, simple } = const { datasetId, parentId, searchText, selectFolder, filterTags, simple } = parseApiInput({
ScrollCollectionsBodySchema.parse(req.body); req,
let { offset, pageSize } = parsePaginationRequest(req); bodySchema: ScrollCollectionsBodySchema
}).body;
const { offset, pageSize: rawPageSize } = parsePaginationRequest(req);
const regexText = searchText ? replaceRegChars(searchText) : ''; const regexText = searchText ? replaceRegChars(searchText) : '';
pageSize = Math.min(pageSize, 30); const pageSize = Math.min(rawPageSize, 30);
// auth dataset and get my role // auth dataset and get my role
const { teamId, permission } = await authDataset({ const { teamId, permission } = await authDataset({
......
...@@ -3,6 +3,7 @@ import { NextAPI } from '@/service/middleware/entry'; ...@@ -3,6 +3,7 @@ import { NextAPI } from '@/service/middleware/entry';
import { WritePermissionVal } from '@fastgpt/global/support/permission/constant'; import { WritePermissionVal } from '@fastgpt/global/support/permission/constant';
import { type ApiRequestProps } from '@fastgpt/service/type/next'; import { type ApiRequestProps } from '@fastgpt/service/type/next';
import { syncCollection } from '@fastgpt/service/core/dataset/collection/utils'; import { syncCollection } from '@fastgpt/service/core/dataset/collection/utils';
import { parseApiInput } from '@fastgpt/service/common/zod/requestParseError';
import { import {
SyncCollectionBodySchema, SyncCollectionBodySchema,
SyncCollectionResponseSchema, SyncCollectionResponseSchema,
...@@ -18,7 +19,7 @@ import { ...@@ -18,7 +19,7 @@ import {
5. Delete old collection 5. Delete old collection
*/ */
async function handler(req: ApiRequestProps): Promise<SyncCollectionResponseType> { async function handler(req: ApiRequestProps): Promise<SyncCollectionResponseType> {
const { collectionId } = SyncCollectionBodySchema.parse(req.body); const { collectionId } = parseApiInput({ req, bodySchema: SyncCollectionBodySchema }).body;
const { collection } = await authDatasetCollection({ const { collection } = await authDatasetCollection({
req, req,
......
...@@ -9,6 +9,7 @@ import { authDatasetCollection } from '@fastgpt/service/support/permission/datas ...@@ -9,6 +9,7 @@ import { authDatasetCollection } from '@fastgpt/service/support/permission/datas
import { MongoDatasetData } from '@fastgpt/service/core/dataset/data/schema'; import { MongoDatasetData } from '@fastgpt/service/core/dataset/data/schema';
import { type ApiRequestProps } from '@fastgpt/service/type/next'; import { type ApiRequestProps } from '@fastgpt/service/type/next';
import { Types } from '@fastgpt/service/common/mongo'; import { Types } from '@fastgpt/service/common/mongo';
import { parseApiInput } from '@fastgpt/service/common/zod/requestParseError';
import { import {
GetCollectionTrainingDetailQuerySchema, GetCollectionTrainingDetailQuerySchema,
GetCollectionTrainingDetailResponseSchema, GetCollectionTrainingDetailResponseSchema,
...@@ -25,7 +26,10 @@ const defaultCounts: Record<TrainingModeEnum, number> = { ...@@ -25,7 +26,10 @@ const defaultCounts: Record<TrainingModeEnum, number> = {
}; };
async function handler(req: ApiRequestProps): Promise<GetCollectionTrainingDetailResponseType> { async function handler(req: ApiRequestProps): Promise<GetCollectionTrainingDetailResponseType> {
const { collectionId } = GetCollectionTrainingDetailQuerySchema.parse(req.query); const { collectionId } = parseApiInput({
req,
querySchema: GetCollectionTrainingDetailQuerySchema
}).query;
const { collection } = await authDatasetCollection({ const { collection } = await authDatasetCollection({
req, req,
......
...@@ -19,6 +19,7 @@ import { addAuditLog } from '@fastgpt/service/support/user/audit/util'; ...@@ -19,6 +19,7 @@ import { addAuditLog } from '@fastgpt/service/support/user/audit/util';
import { AuditEventEnum } from '@fastgpt/global/support/user/audit/constants'; import { AuditEventEnum } from '@fastgpt/global/support/user/audit/constants';
import { getI18nDatasetType } from '@fastgpt/service/support/user/audit/util'; import { getI18nDatasetType } from '@fastgpt/service/support/user/audit/util';
import { UpdateDatasetCollectionBodySchema } from '@fastgpt/global/openapi/core/dataset/collection/api'; import { UpdateDatasetCollectionBodySchema } from '@fastgpt/global/openapi/core/dataset/collection/api';
import { parseApiInput } from '@fastgpt/service/common/zod/requestParseError';
// Set folder collection children forbid status // Set folder collection children forbid status
const updateFolderChildrenForbid = async ({ const updateFolderChildrenForbid = async ({
...@@ -67,8 +68,17 @@ const updateFolderChildrenForbid = async ({ ...@@ -67,8 +68,17 @@ const updateFolderChildrenForbid = async ({
}; };
async function handler(req: ApiRequestProps) { async function handler(req: ApiRequestProps) {
let { datasetId, externalFileId, id, parentId, name, tags, forbid, createTime } = const {
UpdateDatasetCollectionBodySchema.parse(req.body); datasetId,
externalFileId,
id: parsedCollectionId,
parentId,
name,
tags,
forbid,
createTime
} = parseApiInput({ req, bodySchema: UpdateDatasetCollectionBodySchema }).body;
let id = parsedCollectionId;
// 通过 externalFileId 查找 collection:先鉴权 dataset,再查询 // 通过 externalFileId 查找 collection:先鉴权 dataset,再查询
if (datasetId && externalFileId) { if (datasetId && externalFileId) {
......
...@@ -31,6 +31,7 @@ import { AuditEventEnum } from '@fastgpt/global/support/user/audit/constants'; ...@@ -31,6 +31,7 @@ import { AuditEventEnum } from '@fastgpt/global/support/user/audit/constants';
import { getI18nDatasetType } from '@fastgpt/service/support/user/audit/util'; import { getI18nDatasetType } from '@fastgpt/service/support/user/audit/util';
import { MongoResourcePermission } from '@fastgpt/service/support/permission/schema'; import { MongoResourcePermission } from '@fastgpt/service/support/permission/schema';
import { getS3AvatarSource } from '@fastgpt/service/common/s3/sources/avatar'; import { getS3AvatarSource } from '@fastgpt/service/common/s3/sources/avatar';
import { parseApiInput } from '@fastgpt/service/common/zod/requestParseError';
async function handler(req: ApiRequestProps): Promise<CreateDatasetResponse> { async function handler(req: ApiRequestProps): Promise<CreateDatasetResponse> {
const { const {
...@@ -43,7 +44,7 @@ async function handler(req: ApiRequestProps): Promise<CreateDatasetResponse> { ...@@ -43,7 +44,7 @@ async function handler(req: ApiRequestProps): Promise<CreateDatasetResponse> {
agentModel = getDatasetModel()?.model, agentModel = getDatasetModel()?.model,
vlmModel = getDefaultVLMModel()?.model, vlmModel = getDefaultVLMModel()?.model,
apiDatasetServer apiDatasetServer
} = CreateDatasetBodySchema.parse(req.body); } = parseApiInput({ req, bodySchema: CreateDatasetBodySchema }).body;
// auth // auth
const { teamId, tmbId, userId } = parentId const { teamId, tmbId, userId } = parentId
......
...@@ -40,9 +40,13 @@ import { getS3AvatarSource } from '@fastgpt/service/common/s3/sources/avatar'; ...@@ -40,9 +40,13 @@ import { getS3AvatarSource } from '@fastgpt/service/common/s3/sources/avatar';
import { createCollectionAndInsertData } from '@fastgpt/service/core/dataset/collection/controller'; import { createCollectionAndInsertData } from '@fastgpt/service/core/dataset/collection/controller';
import { S3PrivateBucket } from '@fastgpt/service/common/s3/buckets/private'; import { S3PrivateBucket } from '@fastgpt/service/common/s3/buckets/private';
import { getFileS3Key } from '@fastgpt/service/common/s3/utils'; import { getFileS3Key } from '@fastgpt/service/common/s3/utils';
import { parseApiInput } from '@fastgpt/service/common/zod/requestParseError';
async function handler(req: ApiRequestProps): Promise<CreateDatasetWithFilesResponse> { async function handler(req: ApiRequestProps): Promise<CreateDatasetWithFilesResponse> {
const { datasetParams, files } = CreateDatasetWithFilesBodySchema.parse(req.body); const { datasetParams, files } = parseApiInput({
req,
bodySchema: CreateDatasetWithFilesBodySchema
}).body;
const { const {
parentId, parentId,
name, name,
......
...@@ -6,6 +6,7 @@ import { addAuditLog } from '@fastgpt/service/support/user/audit/util'; ...@@ -6,6 +6,7 @@ import { addAuditLog } from '@fastgpt/service/support/user/audit/util';
import { AuditEventEnum } from '@fastgpt/global/support/user/audit/constants'; import { AuditEventEnum } from '@fastgpt/global/support/user/audit/constants';
import { getI18nDatasetType } from '@fastgpt/service/support/user/audit/util'; import { getI18nDatasetType } from '@fastgpt/service/support/user/audit/util';
import { type ApiRequestProps } from '@fastgpt/service/type/next'; import { type ApiRequestProps } from '@fastgpt/service/type/next';
import { parseApiInput } from '@fastgpt/service/common/zod/requestParseError';
import { import {
DeleteDatasetDataQuerySchema, DeleteDatasetDataQuerySchema,
DeleteDatasetDataResponseSchema, DeleteDatasetDataResponseSchema,
...@@ -13,7 +14,7 @@ import { ...@@ -13,7 +14,7 @@ import {
} from '@fastgpt/global/openapi/core/dataset/data/api'; } from '@fastgpt/global/openapi/core/dataset/data/api';
async function handler(req: ApiRequestProps): Promise<DeleteDatasetDataResponse> { async function handler(req: ApiRequestProps): Promise<DeleteDatasetDataResponse> {
const { id: dataId } = DeleteDatasetDataQuerySchema.parse(req.query); const { id: dataId } = parseApiInput({ req, querySchema: DeleteDatasetDataQuerySchema }).query;
// 凭证校验 // 凭证校验
const { datasetData, tmbId, teamId, collection } = await authDatasetData({ const { datasetData, tmbId, teamId, collection } = await authDatasetData({
......
...@@ -2,6 +2,7 @@ import { NextAPI } from '@/service/middleware/entry'; ...@@ -2,6 +2,7 @@ import { NextAPI } from '@/service/middleware/entry';
import { ReadPermissionVal } from '@fastgpt/global/support/permission/constant'; import { ReadPermissionVal } from '@fastgpt/global/support/permission/constant';
import { authDatasetData } from '@fastgpt/service/support/permission/dataset/auth'; import { authDatasetData } from '@fastgpt/service/support/permission/dataset/auth';
import type { ApiRequestProps } from '@fastgpt/service/type/next'; import type { ApiRequestProps } from '@fastgpt/service/type/next';
import { parseApiInput } from '@fastgpt/service/common/zod/requestParseError';
import { import {
GetDatasetDataDetailQuerySchema, GetDatasetDataDetailQuerySchema,
GetDatasetDataDetailResponseSchema, GetDatasetDataDetailResponseSchema,
...@@ -9,7 +10,7 @@ import { ...@@ -9,7 +10,7 @@ import {
} from '@fastgpt/global/openapi/core/dataset/data/api'; } from '@fastgpt/global/openapi/core/dataset/data/api';
async function handler(req: ApiRequestProps): Promise<GetDatasetDataDetailResponse> { async function handler(req: ApiRequestProps): Promise<GetDatasetDataDetailResponse> {
const { id: dataId } = GetDatasetDataDetailQuerySchema.parse(req.query); const { id: dataId } = parseApiInput({ req, querySchema: GetDatasetDataDetailQuerySchema }).query;
const { datasetData } = await authDatasetData({ const { datasetData } = await authDatasetData({
req, req,
......
...@@ -9,6 +9,7 @@ import { ChatErrEnum } from '@fastgpt/global/common/error/code/chat'; ...@@ -9,6 +9,7 @@ import { ChatErrEnum } from '@fastgpt/global/common/error/code/chat';
import { i18nT } from '@fastgpt/global/common/i18n/utils'; import { i18nT } from '@fastgpt/global/common/i18n/utils';
import { formatDatasetDataValue } from '@fastgpt/service/core/dataset/data/controller'; import { formatDatasetDataValue } from '@fastgpt/service/core/dataset/data/controller';
import { UserError } from '@fastgpt/global/common/error/utils'; import { UserError } from '@fastgpt/global/common/error/utils';
import { parseApiInput } from '@fastgpt/service/common/zod/requestParseError';
import { import {
GetQuoteDataBodySchema, GetQuoteDataBodySchema,
GetQuoteDataResponseSchema, GetQuoteDataResponseSchema,
...@@ -16,7 +17,7 @@ import { ...@@ -16,7 +17,7 @@ import {
} from '@fastgpt/global/openapi/core/dataset/data/api'; } from '@fastgpt/global/openapi/core/dataset/data/api';
async function handler(req: ApiRequestProps): Promise<GetQuoteDataResponse> { async function handler(req: ApiRequestProps): Promise<GetQuoteDataResponse> {
const body = GetQuoteDataBodySchema.parse(req.body); const body = parseApiInput({ req, bodySchema: GetQuoteDataBodySchema }).body;
const { id: dataId } = body; const { id: dataId } = body;
// Auth // Auth
......
...@@ -11,9 +11,13 @@ import { AuditEventEnum } from '@fastgpt/global/support/user/audit/constants'; ...@@ -11,9 +11,13 @@ import { AuditEventEnum } from '@fastgpt/global/support/user/audit/constants';
import { addAuditLog, getI18nDatasetType } from '@fastgpt/service/support/user/audit/util'; import { addAuditLog, getI18nDatasetType } from '@fastgpt/service/support/user/audit/util';
import { authDatasetData } from '@fastgpt/service/support/permission/dataset/auth'; import { authDatasetData } from '@fastgpt/service/support/permission/dataset/auth';
import type { ApiRequestProps } from '@fastgpt/service/type/next'; import type { ApiRequestProps } from '@fastgpt/service/type/next';
import { parseApiInput } from '@fastgpt/service/common/zod/requestParseError';
async function handler(req: ApiRequestProps): Promise<DatasetDataIndexResponse> { async function handler(req: ApiRequestProps): Promise<DatasetDataIndexResponse> {
const { dataId, type, text } = CreateDatasetDataIndexBodySchema.parse(req.body); const { dataId, type, text } = parseApiInput({
req,
bodySchema: CreateDatasetDataIndexBodySchema
}).body;
const { datasetData, tmbId, teamId, collection } = await authDatasetData({ const { datasetData, tmbId, teamId, collection } = await authDatasetData({
req, req,
......
...@@ -10,9 +10,13 @@ import { AuditEventEnum } from '@fastgpt/global/support/user/audit/constants'; ...@@ -10,9 +10,13 @@ import { AuditEventEnum } from '@fastgpt/global/support/user/audit/constants';
import { addAuditLog, getI18nDatasetType } from '@fastgpt/service/support/user/audit/util'; import { addAuditLog, getI18nDatasetType } from '@fastgpt/service/support/user/audit/util';
import { authDatasetData } from '@fastgpt/service/support/permission/dataset/auth'; import { authDatasetData } from '@fastgpt/service/support/permission/dataset/auth';
import type { ApiRequestProps } from '@fastgpt/service/type/next'; import type { ApiRequestProps } from '@fastgpt/service/type/next';
import { parseApiInput } from '@fastgpt/service/common/zod/requestParseError';
async function handler(req: ApiRequestProps): Promise<DeleteDatasetDataIndexResponse> { async function handler(req: ApiRequestProps): Promise<DeleteDatasetDataIndexResponse> {
const { dataId, indexDataId } = DeleteDatasetDataIndexBodySchema.parse(req.body); const { dataId, indexDataId } = parseApiInput({
req,
bodySchema: DeleteDatasetDataIndexBodySchema
}).body;
const { datasetData, tmbId, teamId, collection } = await authDatasetData({ const { datasetData, tmbId, teamId, collection } = await authDatasetData({
req, req,
......
...@@ -11,9 +11,13 @@ import { AuditEventEnum } from '@fastgpt/global/support/user/audit/constants'; ...@@ -11,9 +11,13 @@ import { AuditEventEnum } from '@fastgpt/global/support/user/audit/constants';
import { addAuditLog, getI18nDatasetType } from '@fastgpt/service/support/user/audit/util'; import { addAuditLog, getI18nDatasetType } from '@fastgpt/service/support/user/audit/util';
import { authDatasetData } from '@fastgpt/service/support/permission/dataset/auth'; import { authDatasetData } from '@fastgpt/service/support/permission/dataset/auth';
import type { ApiRequestProps } from '@fastgpt/service/type/next'; import type { ApiRequestProps } from '@fastgpt/service/type/next';
import { parseApiInput } from '@fastgpt/service/common/zod/requestParseError';
async function handler(req: ApiRequestProps): Promise<DatasetDataIndexResponse> { async function handler(req: ApiRequestProps): Promise<DatasetDataIndexResponse> {
const { dataId, indexDataId, type, text } = UpdateDatasetDataIndexBodySchema.parse(req.body); const { dataId, indexDataId, type, text } = parseApiInput({
req,
bodySchema: UpdateDatasetDataIndexBodySchema
}).body;
const { datasetData, tmbId, teamId, collection } = await authDatasetData({ const { datasetData, tmbId, teamId, collection } = await authDatasetData({
req, req,
......
...@@ -16,6 +16,7 @@ import { addAuditLog } from '@fastgpt/service/support/user/audit/util'; ...@@ -16,6 +16,7 @@ import { addAuditLog } from '@fastgpt/service/support/user/audit/util';
import { AuditEventEnum } from '@fastgpt/global/support/user/audit/constants'; import { AuditEventEnum } from '@fastgpt/global/support/user/audit/constants';
import { getI18nDatasetType } from '@fastgpt/service/support/user/audit/util'; import { getI18nDatasetType } from '@fastgpt/service/support/user/audit/util';
import { type ApiRequestProps } from '@fastgpt/service/type/next'; import { type ApiRequestProps } from '@fastgpt/service/type/next';
import { parseApiInput } from '@fastgpt/service/common/zod/requestParseError';
import { import {
InsertDataBodySchema, InsertDataBodySchema,
InsertDataResponseSchema, InsertDataResponseSchema,
...@@ -23,7 +24,10 @@ import { ...@@ -23,7 +24,10 @@ import {
} from '@fastgpt/global/openapi/core/dataset/data/api'; } from '@fastgpt/global/openapi/core/dataset/data/api';
async function handler(req: ApiRequestProps): Promise<InsertDataResponse> { async function handler(req: ApiRequestProps): Promise<InsertDataResponse> {
const { collectionId, q, a, indexes } = InsertDataBodySchema.parse(req.body); const { collectionId, q, a, indexes } = parseApiInput({
req,
bodySchema: InsertDataBodySchema
}).body;
// 凭证校验 // 凭证校验
const { teamId, tmbId, collection } = await authDatasetCollection({ const { teamId, tmbId, collection } = await authDatasetCollection({
......
...@@ -18,9 +18,10 @@ import { getVlmModel } from '@fastgpt/service/core/ai/model'; ...@@ -18,9 +18,10 @@ import { getVlmModel } from '@fastgpt/service/core/ai/model';
import { createTrainingUsage } from '@fastgpt/service/support/wallet/usage/controller'; import { createTrainingUsage } from '@fastgpt/service/support/wallet/usage/controller';
import { mongoSessionRun } from '@fastgpt/service/common/mongo/sessionRun'; import { mongoSessionRun } from '@fastgpt/service/common/mongo/sessionRun';
import { DatasetCollectionDataProcessModeEnum } from '@fastgpt/global/core/dataset/constants'; import { DatasetCollectionDataProcessModeEnum } from '@fastgpt/global/core/dataset/constants';
import { parseApiInput } from '@fastgpt/service/common/zod/requestParseError';
async function handler(req: ApiRequestProps): Promise<PushDataResponseType> { async function handler(req: ApiRequestProps): Promise<PushDataResponseType> {
const body = PushDataBodySchema.parse(req.body); const body = parseApiInput({ req, bodySchema: PushDataBodySchema }).body;
// Adapter 4.9.0: support legacy trainingMode field // Adapter 4.9.0: support legacy trainingMode field
body.trainingType = body.trainingType || body.trainingMode; body.trainingType = body.trainingType || body.trainingMode;
......
...@@ -10,6 +10,7 @@ import { type ApiRequestProps } from '@fastgpt/service/type/next'; ...@@ -10,6 +10,7 @@ import { type ApiRequestProps } from '@fastgpt/service/type/next';
import { addAuditLog } from '@fastgpt/service/support/user/audit/util'; import { addAuditLog } from '@fastgpt/service/support/user/audit/util';
import { AuditEventEnum } from '@fastgpt/global/support/user/audit/constants'; import { AuditEventEnum } from '@fastgpt/global/support/user/audit/constants';
import { getI18nDatasetType } from '@fastgpt/service/support/user/audit/util'; import { getI18nDatasetType } from '@fastgpt/service/support/user/audit/util';
import { parseApiInput } from '@fastgpt/service/common/zod/requestParseError';
import { import {
UpdateDatasetDataBodySchema, UpdateDatasetDataBodySchema,
UpdateDatasetDataResponseSchema, UpdateDatasetDataResponseSchema,
...@@ -17,7 +18,10 @@ import { ...@@ -17,7 +18,10 @@ import {
} from '@fastgpt/global/openapi/core/dataset/data/api'; } from '@fastgpt/global/openapi/core/dataset/data/api';
async function handler(req: ApiRequestProps): Promise<UpdateDatasetDataResponse> { async function handler(req: ApiRequestProps): Promise<UpdateDatasetDataResponse> {
const { dataId, q, a, indexes } = UpdateDatasetDataBodySchema.parse(req.body); const { dataId, q, a, indexes } = parseApiInput({
req,
bodySchema: UpdateDatasetDataBodySchema
}).body;
const hasIndexes = Object.hasOwn(req.body, 'indexes'); const hasIndexes = Object.hasOwn(req.body, 'indexes');
// auth data permission // auth data permission
......
...@@ -17,12 +17,16 @@ import { ...@@ -17,12 +17,16 @@ import {
type GetDatasetDataListResponse type GetDatasetDataListResponse
} from '@fastgpt/global/openapi/core/dataset/data/api'; } from '@fastgpt/global/openapi/core/dataset/data/api';
import { S3Buckets } from '@fastgpt/service/common/s3/config/constants'; import { S3Buckets } from '@fastgpt/service/common/s3/config/constants';
import { parseApiInput } from '@fastgpt/service/common/zod/requestParseError';
async function handler(req: ApiRequestProps): Promise<GetDatasetDataListResponse> { async function handler(req: ApiRequestProps): Promise<GetDatasetDataListResponse> {
const { searchText = '', collectionId } = GetDatasetDataListBodySchema.parse(req.body); const { searchText = '', collectionId } = parseApiInput({
let { offset, pageSize } = parsePaginationRequest(req); req,
bodySchema: GetDatasetDataListBodySchema
}).body;
const { offset, pageSize: rawPageSize } = parsePaginationRequest(req);
pageSize = Math.min(pageSize, 30); const pageSize = Math.min(rawPageSize, 30);
const { teamId, collection } = await authDatasetCollection({ const { teamId, collection } = await authDatasetCollection({
req, req,
......
...@@ -11,9 +11,10 @@ import { addDatasetDeleteJob } from '@fastgpt/service/core/dataset/delete'; ...@@ -11,9 +11,10 @@ import { addDatasetDeleteJob } from '@fastgpt/service/core/dataset/delete';
import { mongoSessionRun } from '@fastgpt/service/common/mongo/sessionRun'; import { mongoSessionRun } from '@fastgpt/service/common/mongo/sessionRun';
import { deleteDatasetsImmediate } from '@fastgpt/service/core/dataset/delete/processor'; import { deleteDatasetsImmediate } from '@fastgpt/service/core/dataset/delete/processor';
import type { ApiRequestProps } from '@fastgpt/service/type/next'; import type { ApiRequestProps } from '@fastgpt/service/type/next';
import { parseApiInput } from '@fastgpt/service/common/zod/requestParseError';
async function handler(req: ApiRequestProps) { async function handler(req: ApiRequestProps) {
const { id: datasetId } = DeleteDatasetQuerySchema.parse(req.query); const { id: datasetId } = parseApiInput({ req, querySchema: DeleteDatasetQuerySchema }).query;
// auth owner // auth owner
const { teamId, tmbId, dataset } = await authDataset({ const { teamId, tmbId, dataset } = await authDataset({
......
...@@ -9,9 +9,10 @@ import { ...@@ -9,9 +9,10 @@ import {
} from '@fastgpt/global/openapi/core/dataset/api'; } from '@fastgpt/global/openapi/core/dataset/api';
import { getDatasetSyncDatasetStatus } from '@fastgpt/service/core/dataset/datasetSync'; import { getDatasetSyncDatasetStatus } from '@fastgpt/service/core/dataset/datasetSync';
import { filterApiDatasetServerPublicData } from '@fastgpt/global/core/dataset/apiDataset/utils'; import { filterApiDatasetServerPublicData } from '@fastgpt/global/core/dataset/apiDataset/utils';
import { parseApiInput } from '@fastgpt/service/common/zod/requestParseError';
async function handler(req: ApiRequestProps): Promise<GetDatasetDetailResponse> { async function handler(req: ApiRequestProps): Promise<GetDatasetDetailResponse> {
const { id: datasetId } = GetDatasetDetailQuerySchema.parse(req.query); const { id: datasetId } = parseApiInput({ req, querySchema: GetDatasetDetailQuerySchema }).query;
// 凭证校验 // 凭证校验
const { dataset, permission } = await authDataset({ const { dataset, permission } = await authDataset({
......
...@@ -16,6 +16,7 @@ import { CommonErrEnum } from '@fastgpt/global/common/error/code/common'; ...@@ -16,6 +16,7 @@ import { CommonErrEnum } from '@fastgpt/global/common/error/code/common';
import { getEmbeddingModel, getLLMModel } from '@fastgpt/service/core/ai/model'; import { getEmbeddingModel, getLLMModel } from '@fastgpt/service/core/ai/model';
import { replaceS3KeyToPreviewUrl } from '@fastgpt/service/core/dataset/utils'; import { replaceS3KeyToPreviewUrl } from '@fastgpt/service/core/dataset/utils';
import { addDays } from 'date-fns'; import { addDays } from 'date-fns';
import { parseApiInput } from '@fastgpt/service/common/zod/requestParseError';
import { import {
GetPreviewChunksBodySchema, GetPreviewChunksBodySchema,
GetPreviewChunksResponseSchema, GetPreviewChunksResponseSchema,
...@@ -35,7 +36,7 @@ async function handler( ...@@ -35,7 +36,7 @@ async function handler(
datasetId, datasetId,
externalFileId, externalFileId,
...chunkSettings ...chunkSettings
} = GetPreviewChunksBodySchema.parse(req.body); } = parseApiInput({ req, bodySchema: GetPreviewChunksBodySchema }).body;
if (!sourceId) { if (!sourceId) {
throw new Error('sourceId is empty'); throw new Error('sourceId is empty');
......
...@@ -5,6 +5,7 @@ import { ReadPermissionVal } from '@fastgpt/global/support/permission/constant'; ...@@ -5,6 +5,7 @@ import { ReadPermissionVal } from '@fastgpt/global/support/permission/constant';
import { addHours } from 'date-fns'; import { addHours } from 'date-fns';
import { S3Buckets } from '@fastgpt/service/common/s3/config/constants'; import { S3Buckets } from '@fastgpt/service/common/s3/config/constants';
import { isS3ObjectKey, jwtSignS3DownloadToken } from '@fastgpt/service/common/s3/utils'; import { isS3ObjectKey, jwtSignS3DownloadToken } from '@fastgpt/service/common/s3/utils';
import { parseApiInput } from '@fastgpt/service/common/zod/requestParseError';
import { import {
GetSearchTestImagePreviewUrlsBodySchema, GetSearchTestImagePreviewUrlsBodySchema,
GetSearchTestImagePreviewUrlsResponseSchema, GetSearchTestImagePreviewUrlsResponseSchema,
...@@ -15,7 +16,10 @@ import { ...@@ -15,7 +16,10 @@ import {
async function handler( async function handler(
req: ApiRequestProps<GetSearchTestImagePreviewUrlsBody> req: ApiRequestProps<GetSearchTestImagePreviewUrlsBody>
): Promise<GetSearchTestImagePreviewUrlsResponse> { ): Promise<GetSearchTestImagePreviewUrlsResponse> {
const { datasetId, keys } = GetSearchTestImagePreviewUrlsBodySchema.parse(req.body); const { datasetId, keys } = parseApiInput({
req,
bodySchema: GetSearchTestImagePreviewUrlsBodySchema
}).body;
const { teamId } = await authDataset({ const { teamId } = await authDataset({
datasetId, datasetId,
per: ReadPermissionVal, per: ReadPermissionVal,
......
...@@ -11,11 +11,15 @@ import { ...@@ -11,11 +11,15 @@ import {
type PresignDatasetFilePostUrlBody type PresignDatasetFilePostUrlBody
} from '@fastgpt/global/openapi/core/dataset/file/api'; } from '@fastgpt/global/openapi/core/dataset/file/api';
import type { CreatePostPresignedUrlResponseType } from '@fastgpt/global/common/file/s3/type'; import type { CreatePostPresignedUrlResponseType } from '@fastgpt/global/common/file/s3/type';
import { parseApiInput } from '@fastgpt/service/common/zod/requestParseError';
async function handler( async function handler(
req: ApiRequestProps<PresignDatasetFilePostUrlBody> req: ApiRequestProps<PresignDatasetFilePostUrlBody>
): Promise<CreatePostPresignedUrlResponseType> { ): Promise<CreatePostPresignedUrlResponseType> {
const { filename, datasetId } = PresignDatasetFilePostUrlBodySchema.parse(req.body); const { filename, datasetId } = parseApiInput({
req,
bodySchema: PresignDatasetFilePostUrlBodySchema
}).body;
const { teamId, userId } = await authDataset({ const { teamId, userId } = await authDataset({
datasetId, datasetId,
......
...@@ -9,6 +9,7 @@ import { imageFileType } from '@fastgpt/global/common/file/constants'; ...@@ -9,6 +9,7 @@ import { imageFileType } from '@fastgpt/global/common/file/constants';
import { parseAllowedExtensions } from '@fastgpt/service/common/s3/utils/uploadConstraints'; import { parseAllowedExtensions } from '@fastgpt/service/common/s3/utils/uploadConstraints';
import { getFileS3Key } from '@fastgpt/service/common/s3/utils'; import { getFileS3Key } from '@fastgpt/service/common/s3/utils';
import { S3PrivateBucket } from '@fastgpt/service/common/s3/buckets/private'; import { S3PrivateBucket } from '@fastgpt/service/common/s3/buckets/private';
import { parseApiInput } from '@fastgpt/service/common/zod/requestParseError';
import { import {
PresignSearchTestImageBodySchema, PresignSearchTestImageBodySchema,
PresignSearchTestImageResponseSchema, PresignSearchTestImageResponseSchema,
...@@ -19,7 +20,10 @@ import { ...@@ -19,7 +20,10 @@ import {
async function handler( async function handler(
req: ApiRequestProps<PresignSearchTestImageBody> req: ApiRequestProps<PresignSearchTestImageBody>
): Promise<PresignSearchTestImageResponse> { ): Promise<PresignSearchTestImageResponse> {
const { datasetId, filename } = PresignSearchTestImageBodySchema.parse(req.body); const { datasetId, filename } = parseApiInput({
req,
bodySchema: PresignSearchTestImageBodySchema
}).body;
const { teamId, userId } = await authDataset({ const { teamId, userId } = await authDataset({
datasetId, datasetId,
per: ReadPermissionVal, per: ReadPermissionVal,
......
...@@ -16,13 +16,17 @@ import { authUserPer } from '@fastgpt/service/support/permission/user/auth'; ...@@ -16,13 +16,17 @@ import { authUserPer } from '@fastgpt/service/support/permission/user/auth';
import type { ApiRequestProps } from '@fastgpt/service/type/next'; import type { ApiRequestProps } from '@fastgpt/service/type/next';
import { addAuditLog } from '@fastgpt/service/support/user/audit/util'; import { addAuditLog } from '@fastgpt/service/support/user/audit/util';
import { AuditEventEnum } from '@fastgpt/global/support/user/audit/constants'; import { AuditEventEnum } from '@fastgpt/global/support/user/audit/constants';
import { parseApiInput } from '@fastgpt/service/common/zod/requestParseError';
import { import {
CreateDatasetFolderBodySchema, CreateDatasetFolderBodySchema,
type CreateDatasetFolderBody type CreateDatasetFolderBody
} from '@fastgpt/global/openapi/core/dataset/api'; } from '@fastgpt/global/openapi/core/dataset/api';
async function handler(req: ApiRequestProps<CreateDatasetFolderBody>) { async function handler(req: ApiRequestProps<CreateDatasetFolderBody>) {
const { parentId, name, intro } = CreateDatasetFolderBodySchema.parse(req.body); const { parentId, name, intro } = parseApiInput({
req,
bodySchema: CreateDatasetFolderBodySchema
}).body;
const { teamId, tmbId } = parentId const { teamId, tmbId } = parentId
? await authDataset({ ? await authDataset({
......
...@@ -3,6 +3,7 @@ import { type ApiRequestProps } from '@fastgpt/service/type/next'; ...@@ -3,6 +3,7 @@ import { type ApiRequestProps } from '@fastgpt/service/type/next';
import { ReadPermissionVal } from '@fastgpt/global/support/permission/constant'; import { ReadPermissionVal } from '@fastgpt/global/support/permission/constant';
import { authDataset } from '@fastgpt/service/support/permission/dataset/auth'; import { authDataset } from '@fastgpt/service/support/permission/dataset/auth';
import { DatasetErrEnum } from '@fastgpt/global/common/error/code/dataset'; import { DatasetErrEnum } from '@fastgpt/global/common/error/code/dataset';
import { parseApiInput } from '@fastgpt/service/common/zod/requestParseError';
import { import {
GetDatasetPermissionQuerySchema, GetDatasetPermissionQuerySchema,
GetDatasetPermissionResponseSchema, GetDatasetPermissionResponseSchema,
...@@ -10,7 +11,10 @@ import { ...@@ -10,7 +11,10 @@ import {
} from '@fastgpt/global/openapi/core/dataset/api'; } from '@fastgpt/global/openapi/core/dataset/api';
async function handler(req: ApiRequestProps): Promise<GetDatasetPermissionResponse> { async function handler(req: ApiRequestProps): Promise<GetDatasetPermissionResponse> {
const { id: datasetId } = GetDatasetPermissionQuerySchema.parse(req.query); const { id: datasetId } = parseApiInput({
req,
querySchema: GetDatasetPermissionQuerySchema
}).query;
try { try {
const { permission, dataset } = await authDataset({ const { permission, dataset } = await authDataset({
......
...@@ -17,13 +17,17 @@ import { getOrgIdSetWithParentByTmbId } from '@fastgpt/service/support/permissio ...@@ -17,13 +17,17 @@ import { getOrgIdSetWithParentByTmbId } from '@fastgpt/service/support/permissio
import { addSourceMember } from '@fastgpt/service/support/user/utils'; import { addSourceMember } from '@fastgpt/service/support/user/utils';
import { getEmbeddingModel } from '@fastgpt/service/core/ai/model'; import { getEmbeddingModel } from '@fastgpt/service/core/ai/model';
import { sumPer } from '@fastgpt/global/support/permission/utils'; import { sumPer } from '@fastgpt/global/support/permission/utils';
import { parseApiInput } from '@fastgpt/service/common/zod/requestParseError';
import { import {
GetDatasetListBodySchema, GetDatasetListBodySchema,
type GetDatasetListResponse type GetDatasetListResponse
} from '@fastgpt/global/openapi/core/dataset/api'; } from '@fastgpt/global/openapi/core/dataset/api';
async function handler(req: ApiRequestProps): Promise<GetDatasetListResponse> { async function handler(req: ApiRequestProps): Promise<GetDatasetListResponse> {
const { parentId, type, searchKey } = GetDatasetListBodySchema.parse(req.body); const { parentId, type, searchKey } = parseApiInput({
req,
bodySchema: GetDatasetListBodySchema
}).body;
// Auth user permission // Auth user permission
const [{ tmbId, teamId, permission: teamPer }] = await Promise.all([ const [{ tmbId, teamId, permission: teamPer }] = await Promise.all([
......
...@@ -20,6 +20,7 @@ import { ...@@ -20,6 +20,7 @@ import {
type SearchDatasetTestBody, type SearchDatasetTestBody,
type SearchDatasetTestResponse type SearchDatasetTestResponse
} from '@fastgpt/global/openapi/core/dataset/api'; } from '@fastgpt/global/openapi/core/dataset/api';
import { parseApiInput } from '@fastgpt/service/common/zod/requestParseError';
export async function handler( export async function handler(
req: ApiRequestProps<SearchDatasetTestBody> req: ApiRequestProps<SearchDatasetTestBody>
...@@ -45,7 +46,7 @@ export async function handler( ...@@ -45,7 +46,7 @@ export async function handler(
datasetDeepSearchModel, datasetDeepSearchModel,
datasetDeepSearchMaxTimes, datasetDeepSearchMaxTimes,
datasetDeepSearchBg datasetDeepSearchBg
} = SearchDatasetTestBodySchema.parse(req.body); } = parseApiInput({ req, bodySchema: SearchDatasetTestBodySchema }).body;
const start = Date.now(); const start = Date.now();
......
...@@ -3,6 +3,7 @@ import { MongoDatasetTraining } from '@fastgpt/service/core/dataset/training/sch ...@@ -3,6 +3,7 @@ import { MongoDatasetTraining } from '@fastgpt/service/core/dataset/training/sch
import { authDatasetCollection } from '@fastgpt/service/support/permission/dataset/auth'; import { authDatasetCollection } from '@fastgpt/service/support/permission/dataset/auth';
import { NextAPI } from '@/service/middleware/entry'; import { NextAPI } from '@/service/middleware/entry';
import { type ApiRequestProps } from '@fastgpt/service/type/next'; import { type ApiRequestProps } from '@fastgpt/service/type/next';
import { parseApiInput } from '@fastgpt/service/common/zod/requestParseError';
import { import {
DeleteTrainingDataBodySchema, DeleteTrainingDataBodySchema,
DeleteTrainingDataResponseSchema, DeleteTrainingDataResponseSchema,
...@@ -10,7 +11,10 @@ import { ...@@ -10,7 +11,10 @@ import {
} from '@fastgpt/global/openapi/core/dataset/training/api'; } from '@fastgpt/global/openapi/core/dataset/training/api';
async function handler(req: ApiRequestProps): Promise<DeleteTrainingDataResponse> { async function handler(req: ApiRequestProps): Promise<DeleteTrainingDataResponse> {
const { datasetId, collectionId, dataId } = DeleteTrainingDataBodySchema.parse(req.body); const { datasetId, collectionId, dataId } = parseApiInput({
req,
bodySchema: DeleteTrainingDataBodySchema
}).body;
const { teamId } = await authDatasetCollection({ const { teamId } = await authDatasetCollection({
req, req,
......
...@@ -5,6 +5,7 @@ import { MongoDatasetData } from '@fastgpt/service/core/dataset/data/schema'; ...@@ -5,6 +5,7 @@ import { MongoDatasetData } from '@fastgpt/service/core/dataset/data/schema';
import { MongoDatasetTraining } from '@fastgpt/service/core/dataset/training/schema'; import { MongoDatasetTraining } from '@fastgpt/service/core/dataset/training/schema';
import { ReadPermissionVal } from '@fastgpt/global/support/permission/constant'; import { ReadPermissionVal } from '@fastgpt/global/support/permission/constant';
import { readFromSecondary } from '@fastgpt/service/common/mongo/utils'; import { readFromSecondary } from '@fastgpt/service/common/mongo/utils';
import { parseApiInput } from '@fastgpt/service/common/zod/requestParseError';
import { import {
GetDatasetTrainingQueueQuerySchema, GetDatasetTrainingQueueQuerySchema,
GetDatasetTrainingQueueResponseSchema, GetDatasetTrainingQueueResponseSchema,
...@@ -12,7 +13,10 @@ import { ...@@ -12,7 +13,10 @@ import {
} from '@fastgpt/global/openapi/core/dataset/training/api'; } from '@fastgpt/global/openapi/core/dataset/training/api';
async function handler(req: ApiRequestProps): Promise<GetDatasetTrainingQueueResponse> { async function handler(req: ApiRequestProps): Promise<GetDatasetTrainingQueueResponse> {
const { datasetId } = GetDatasetTrainingQueueQuerySchema.parse(req.query); const { datasetId } = parseApiInput({
req,
querySchema: GetDatasetTrainingQueueQuerySchema
}).query;
const { teamId } = await authDataset({ const { teamId } = await authDataset({
req, req,
......
...@@ -11,9 +11,13 @@ import { ...@@ -11,9 +11,13 @@ import {
type GetTrainingDataDetailResponse type GetTrainingDataDetailResponse
} from '@fastgpt/global/openapi/core/dataset/training/api'; } from '@fastgpt/global/openapi/core/dataset/training/api';
import { S3Buckets } from '@fastgpt/service/common/s3/config/constants'; import { S3Buckets } from '@fastgpt/service/common/s3/config/constants';
import { parseApiInput } from '@fastgpt/service/common/zod/requestParseError';
async function handler(req: ApiRequestProps): Promise<GetTrainingDataDetailResponse> { async function handler(req: ApiRequestProps): Promise<GetTrainingDataDetailResponse> {
const { datasetId, collectionId, dataId } = GetTrainingDataDetailBodySchema.parse(req.body); const { datasetId, collectionId, dataId } = parseApiInput({
req,
bodySchema: GetTrainingDataDetailBodySchema
}).body;
const { teamId } = await authDatasetCollection({ const { teamId } = await authDatasetCollection({
req, req,
......
...@@ -5,6 +5,7 @@ import { readFromSecondary } from '@fastgpt/service/common/mongo/utils'; ...@@ -5,6 +5,7 @@ import { readFromSecondary } from '@fastgpt/service/common/mongo/utils';
import { MongoDatasetTraining } from '@fastgpt/service/core/dataset/training/schema'; import { MongoDatasetTraining } from '@fastgpt/service/core/dataset/training/schema';
import { authDatasetCollection } from '@fastgpt/service/support/permission/dataset/auth'; import { authDatasetCollection } from '@fastgpt/service/support/permission/dataset/auth';
import { type ApiRequestProps } from '@fastgpt/service/type/next'; import { type ApiRequestProps } from '@fastgpt/service/type/next';
import { parseApiInput } from '@fastgpt/service/common/zod/requestParseError';
import { import {
GetTrainingErrorBodySchema, GetTrainingErrorBodySchema,
GetTrainingErrorResponseSchema, GetTrainingErrorResponseSchema,
...@@ -12,7 +13,7 @@ import { ...@@ -12,7 +13,7 @@ import {
} from '@fastgpt/global/openapi/core/dataset/training/api'; } from '@fastgpt/global/openapi/core/dataset/training/api';
async function handler(req: ApiRequestProps): Promise<GetTrainingErrorResponse> { async function handler(req: ApiRequestProps): Promise<GetTrainingErrorResponse> {
const { collectionId } = GetTrainingErrorBodySchema.parse(req.body); const { collectionId } = parseApiInput({ req, bodySchema: GetTrainingErrorBodySchema }).body;
const { offset, pageSize } = parsePaginationRequest(req); const { offset, pageSize } = parsePaginationRequest(req);
const { collection } = await authDatasetCollection({ const { collection } = await authDatasetCollection({
......
...@@ -10,6 +10,7 @@ import { getLLMModel, getEmbeddingModel, getVlmModel } from '@fastgpt/service/co ...@@ -10,6 +10,7 @@ import { getLLMModel, getEmbeddingModel, getVlmModel } from '@fastgpt/service/co
import { TrainingModeEnum } from '@fastgpt/global/core/dataset/constants'; import { TrainingModeEnum } from '@fastgpt/global/core/dataset/constants';
import { type ApiRequestProps } from '@fastgpt/service/type/next'; import { type ApiRequestProps } from '@fastgpt/service/type/next';
import { OwnerPermissionVal } from '@fastgpt/global/support/permission/constant'; import { OwnerPermissionVal } from '@fastgpt/global/support/permission/constant';
import { parseApiInput } from '@fastgpt/service/common/zod/requestParseError';
import { import {
RebuildEmbeddingBodySchema, RebuildEmbeddingBodySchema,
RebuildEmbeddingResponseSchema, RebuildEmbeddingResponseSchema,
...@@ -17,7 +18,10 @@ import { ...@@ -17,7 +18,10 @@ import {
} from '@fastgpt/global/openapi/core/dataset/training/api'; } from '@fastgpt/global/openapi/core/dataset/training/api';
async function handler(req: ApiRequestProps): Promise<RebuildEmbeddingResponse> { async function handler(req: ApiRequestProps): Promise<RebuildEmbeddingResponse> {
const { datasetId, vectorModel } = RebuildEmbeddingBodySchema.parse(req.body); const { datasetId, vectorModel } = parseApiInput({
req,
bodySchema: RebuildEmbeddingBodySchema
}).body;
const { teamId, tmbId, dataset } = await authDataset({ const { teamId, tmbId, dataset } = await authDataset({
req, req,
......
...@@ -5,6 +5,7 @@ import { TeamErrEnum } from '@fastgpt/global/common/error/code/team'; ...@@ -5,6 +5,7 @@ import { TeamErrEnum } from '@fastgpt/global/common/error/code/team';
import { authAppByTmbId } from '@fastgpt/service/support/permission/app/auth'; import { authAppByTmbId } from '@fastgpt/service/support/permission/app/auth';
import { ReadPermissionVal } from '@fastgpt/global/support/permission/constant'; import { ReadPermissionVal } from '@fastgpt/global/support/permission/constant';
import { MongoMcpKey } from '@fastgpt/service/support/mcp/schema'; import { MongoMcpKey } from '@fastgpt/service/support/mcp/schema';
import { parseApiInput } from '@fastgpt/service/common/zod/requestParseError';
import { import {
McpCreateBodySchema, McpCreateBodySchema,
McpCreateResponseSchema, McpCreateResponseSchema,
...@@ -25,7 +26,7 @@ async function handler( ...@@ -25,7 +26,7 @@ async function handler(
return Promise.reject(TeamErrEnum.unPermission); return Promise.reject(TeamErrEnum.unPermission);
} }
const { name, apps } = McpCreateBodySchema.parse(req.body); const { name, apps } = parseApiInput({ req, bodySchema: McpCreateBodySchema }).body;
// Count mcp length // Count mcp length
const totalMcp = await MongoMcpKey.countDocuments({ teamId }); const totalMcp = await MongoMcpKey.countDocuments({ teamId });
......
...@@ -3,6 +3,7 @@ import { NextAPI } from '@/service/middleware/entry'; ...@@ -3,6 +3,7 @@ import { NextAPI } from '@/service/middleware/entry';
import { authMcp } from '@fastgpt/service/support/permission/mcp/auth'; import { authMcp } from '@fastgpt/service/support/permission/mcp/auth';
import { WritePermissionVal } from '@fastgpt/global/support/permission/constant'; import { WritePermissionVal } from '@fastgpt/global/support/permission/constant';
import { MongoMcpKey } from '@fastgpt/service/support/mcp/schema'; import { MongoMcpKey } from '@fastgpt/service/support/mcp/schema';
import { parseApiInput } from '@fastgpt/service/common/zod/requestParseError';
import { import {
McpDeleteQuerySchema, McpDeleteQuerySchema,
McpDeleteResponseSchema, McpDeleteResponseSchema,
...@@ -13,7 +14,7 @@ async function handler( ...@@ -13,7 +14,7 @@ async function handler(
req: ApiRequestProps, req: ApiRequestProps,
res: ApiResponseType<any> res: ApiResponseType<any>
): Promise<McpDeleteResponseType> { ): Promise<McpDeleteResponseType> {
const { id } = McpDeleteQuerySchema.parse(req.query); const { id } = parseApiInput({ req, querySchema: McpDeleteQuerySchema }).query;
await authMcp({ await authMcp({
req, req,
......
...@@ -4,6 +4,7 @@ import { authMcp } from '@fastgpt/service/support/permission/mcp/auth'; ...@@ -4,6 +4,7 @@ import { authMcp } from '@fastgpt/service/support/permission/mcp/auth';
import { ReadPermissionVal, WritePermissionVal } from '@fastgpt/global/support/permission/constant'; import { ReadPermissionVal, WritePermissionVal } from '@fastgpt/global/support/permission/constant';
import { authAppByTmbId } from '@fastgpt/service/support/permission/app/auth'; import { authAppByTmbId } from '@fastgpt/service/support/permission/app/auth';
import { MongoMcpKey } from '@fastgpt/service/support/mcp/schema'; import { MongoMcpKey } from '@fastgpt/service/support/mcp/schema';
import { parseApiInput } from '@fastgpt/service/common/zod/requestParseError';
import { import {
McpUpdateBodySchema, McpUpdateBodySchema,
McpUpdateResponseSchema, McpUpdateResponseSchema,
...@@ -14,7 +15,7 @@ async function handler( ...@@ -14,7 +15,7 @@ async function handler(
req: ApiRequestProps, req: ApiRequestProps,
res: ApiResponseType<any> res: ApiResponseType<any>
): Promise<McpUpdateResponseType> { ): Promise<McpUpdateResponseType> {
const { id: mcpId, name, apps } = McpUpdateBodySchema.parse(req.body); const { id: mcpId, name, apps } = parseApiInput({ req, bodySchema: McpUpdateBodySchema }).body;
const { tmbId } = await authMcp({ const { tmbId } = await authMcp({
req, req,
authToken: true, authToken: true,
......
...@@ -64,11 +64,12 @@ import { formatTime2YMDHM } from '@fastgpt/global/common/string/time'; ...@@ -64,11 +64,12 @@ import { formatTime2YMDHM } from '@fastgpt/global/common/string/time';
import { LimitTypeEnum, teamFrequencyLimit } from '@fastgpt/service/common/api/frequencyLimit'; import { LimitTypeEnum, teamFrequencyLimit } from '@fastgpt/service/common/api/frequencyLimit';
import { getIpFromRequest } from '@fastgpt/service/common/geo'; import { getIpFromRequest } from '@fastgpt/service/common/geo';
import { pushTrack } from '@fastgpt/service/common/middle/tracks/utils'; import { pushTrack } from '@fastgpt/service/common/middle/tracks/utils';
import { parseApiInput } from '@fastgpt/service/common/zod/requestParseError';
const logger = getLogger(LogCategories.MODULE.CHAT.ITEM); const logger = getLogger(LogCategories.MODULE.CHAT.ITEM);
async function handler(req: NextApiRequest, res: NextApiResponse) { async function handler(req: NextApiRequest, res: NextApiResponse) {
const completionProps = CompletionsPropsSchema.parse(req.body); const { body: completionProps } = parseApiInput({ req, bodySchema: CompletionsPropsSchema });
const { const {
chatId, chatId,
appId, appId,
......
...@@ -74,10 +74,12 @@ import { ...@@ -74,10 +74,12 @@ import {
ChatGenerateStatusEnum, ChatGenerateStatusEnum,
STREAM_RESUME_REQUEST_HEADER STREAM_RESUME_REQUEST_HEADER
} from '@fastgpt/global/core/chat/constants'; } from '@fastgpt/global/core/chat/constants';
import { parseApiInput } from '@fastgpt/service/common/zod/requestParseError';
const logger = getLogger(LogCategories.MODULE.CHAT.ITEM); const logger = getLogger(LogCategories.MODULE.CHAT.ITEM);
async function handler(req: NextApiRequest, res: NextApiResponse) { async function handler(req: NextApiRequest, res: NextApiResponse) {
let { const completionBody = parseApiInput({ req, bodySchema: CompletionsPropsSchema }).body;
const {
chatId, chatId,
appId, appId,
customUid, customUid,
...@@ -89,14 +91,12 @@ async function handler(req: NextApiRequest, res: NextApiResponse) { ...@@ -89,14 +91,12 @@ async function handler(req: NextApiRequest, res: NextApiResponse) {
teamToken, teamToken,
stream, stream,
detail,
retainDatasetCite,
showSkillReferences, showSkillReferences,
messages, messages,
variables,
responseChatItemId, responseChatItemId,
metadata metadata
} = CompletionsPropsSchema.parse(req.body); } = completionBody;
let { detail, retainDatasetCite, variables } = completionBody;
const originIp = getIpFromRequest(req); const originIp = getIpFromRequest(req);
......
...@@ -9,9 +9,12 @@ import { ...@@ -9,9 +9,12 @@ import {
StopV2ChatSchema, StopV2ChatSchema,
type StopV2ChatResponse type StopV2ChatResponse
} from '@fastgpt/global/openapi/core/chat/controler/api'; } from '@fastgpt/global/openapi/core/chat/controler/api';
import { parseApiInput } from '@fastgpt/service/common/zod/requestParseError';
async function handler(req: NextApiRequest, res: NextApiResponse): Promise<StopV2ChatResponse> { async function handler(req: NextApiRequest, res: NextApiResponse): Promise<StopV2ChatResponse> {
const { appId, chatId, outLinkAuthData } = StopV2ChatSchema.parse(req.body); const {
body: { appId, chatId, outLinkAuthData }
} = parseApiInput({ req, bodySchema: StopV2ChatSchema });
await authChatCrud({ await authChatCrud({
req, req,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment