Skip to content

Commit ef5ee2a

Browse files
committed
🎨 refactor: refactor the route auth as a middleware
1 parent be4bcca commit ef5ee2a

File tree

7 files changed

+52
-22
lines changed

7 files changed

+52
-22
lines changed

src/app/api/chat/[provider]/route.test.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,11 @@ import { LOBE_CHAT_AUTH_HEADER, OAUTH_AUTHORIZED } from '@/const/auth';
55
import { LobeRuntimeAI } from '@/libs/agent-runtime';
66
import { ChatErrorType } from '@/types/fetch';
77

8-
import { getJWTPayload } from '../auth';
9-
import AgentRuntime from './agentRuntime';
8+
import AgentRuntime from '../agentRuntime';
9+
import { getJWTPayload } from '../auth/utils';
1010
import { POST } from './route';
1111

12-
vi.mock('../auth', () => ({
12+
vi.mock('../auth/utils', () => ({
1313
getJWTPayload: vi.fn(),
1414
checkAuthMethod: vi.fn(),
1515
}));

src/app/api/chat/[provider]/route.ts

+5-17
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,22 @@
11
import { getPreferredRegion } from '@/app/api/config';
22
import { createErrorResponse } from '@/app/api/errorResponse';
3-
import { LOBE_CHAT_AUTH_HEADER, OAUTH_AUTHORIZED } from '@/const/auth';
4-
import { AgentRuntimeError, ChatCompletionErrorPayload } from '@/libs/agent-runtime';
3+
import { ChatCompletionErrorPayload } from '@/libs/agent-runtime';
54
import { ChatErrorType } from '@/types/fetch';
65
import { ChatStreamPayload } from '@/types/openai/chat';
76
import { getTracePayload } from '@/utils/trace';
87

9-
import { checkAuthMethod, getJWTPayload } from '../auth';
10-
import AgentRuntime from './agentRuntime';
8+
import AgentRuntime from '../agentRuntime';
9+
import { checkAuth } from '../auth';
1110

1211
export const runtime = 'edge';
1312

1413
export const preferredRegion = getPreferredRegion();
1514

16-
export const POST = async (req: Request, { params }: { params: { provider: string } }) => {
15+
export const POST = checkAuth(async (req: Request, { params, jwtPayload }) => {
1716
const { provider } = params;
1817

1918
try {
2019
// ============ 1. init chat model ============ //
21-
22-
// get Authorization from header
23-
const authorization = req.headers.get(LOBE_CHAT_AUTH_HEADER);
24-
const oauthAuthorized = !!req.headers.get(OAUTH_AUTHORIZED);
25-
26-
if (!authorization) throw AgentRuntimeError.createError(ChatErrorType.Unauthorized);
27-
28-
// check the Auth With payload
29-
const jwtPayload = await getJWTPayload(authorization);
30-
checkAuthMethod(jwtPayload.accessCode, jwtPayload.apiKey, oauthAuthorized);
31-
3220
const agentRuntime = await AgentRuntime.initializeWithUserPayload(provider, jwtPayload);
3321

3422
// ============ 2. create chat completion ============ //
@@ -55,4 +43,4 @@ export const POST = async (req: Request, { params }: { params: { provider: strin
5543

5644
return createErrorResponse(errorType, { error, ...res, provider });
5745
}
58-
};
46+
});

src/app/api/chat/[provider]/agentRuntime.ts renamed to src/app/api/chat/agentRuntime.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ import {
2828
} from '@/libs/agent-runtime';
2929
import { TraceClient } from '@/libs/traces';
3030

31-
import apiKeyManager from '../apiKeyManager';
31+
import apiKeyManager from './apiKeyManager';
3232

3333
export interface AgentChatOptions {
3434
enableTrace?: boolean;

src/app/api/chat/auth/index.ts

+42
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import { createErrorResponse } from '@/app/api/errorResponse';
2+
import { JWTPayload, LOBE_CHAT_AUTH_HEADER, OAUTH_AUTHORIZED } from '@/const/auth';
3+
import { AgentRuntimeError, ChatCompletionErrorPayload } from '@/libs/agent-runtime';
4+
import { ChatErrorType } from '@/types/fetch';
5+
6+
import { checkAuthMethod, getJWTPayload } from './utils';
7+
8+
type RequestOptions = { params: { provider: string } };
9+
10+
export type RequestHandler = (
11+
req: Request,
12+
options: RequestOptions & { jwtPayload: JWTPayload },
13+
) => Promise<Response>;
14+
15+
export const checkAuth =
16+
(handler: RequestHandler) => async (req: Request, options: RequestOptions) => {
17+
let jwtPayload: JWTPayload;
18+
19+
try {
20+
// get Authorization from header
21+
const authorization = req.headers.get(LOBE_CHAT_AUTH_HEADER);
22+
const oauthAuthorized = !!req.headers.get(OAUTH_AUTHORIZED);
23+
24+
if (!authorization) throw AgentRuntimeError.createError(ChatErrorType.Unauthorized);
25+
26+
// check the Auth With payload
27+
jwtPayload = await getJWTPayload(authorization);
28+
checkAuthMethod(jwtPayload.accessCode, jwtPayload.apiKey, oauthAuthorized);
29+
} catch (e) {
30+
const {
31+
errorType = ChatErrorType.InternalServerError,
32+
error: errorContent,
33+
...res
34+
} = e as ChatCompletionErrorPayload;
35+
36+
const error = errorContent || e;
37+
38+
return createErrorResponse(errorType, { error, ...res, provider: options.params?.provider });
39+
}
40+
41+
return handler(req, { ...options, jwtPayload });
42+
};
File renamed without changes.

src/app/api/plugin/gateway/route.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { PluginRequestPayload } from '@lobehub/chat-plugin-sdk';
22
import { createGatewayOnEdgeRuntime } from '@lobehub/chat-plugins-gateway';
33

4-
import { getJWTPayload } from '@/app/api/chat/auth';
4+
import { getJWTPayload } from '@/app/api/chat/auth/utils';
55
import { createErrorResponse } from '@/app/api/errorResponse';
66
import { getServerConfig } from '@/config/server';
77
import { LOBE_CHAT_AUTH_HEADER, OAUTH_AUTHORIZED } from '@/const/auth';

0 commit comments

Comments
 (0)