UNPKG

@lobehub/chat

Version:

Lobe Chat - an open-source, high-performance chatbot framework that supports speech synthesis, multimodal, and extensible Function Call plugin system. Supports one-click free deployment of your private ChatGPT/LLM web application.

79 lines (61 loc) 2.49 kB
import debug from 'debug'; import { NextRequest } from 'next/server'; import { JWTPayload, LOBE_CHAT_AUTH_HEADER } from '@/const/auth'; import { LobeChatDatabase } from '@/database/type'; import { KeyVaultsGateKeeper } from '@/server/modules/KeyVaultsEncrypt'; const log = debug('lobe-async:context'); export interface AsyncAuthContext { jwtPayload: JWTPayload; secret: string; serverDB?: LobeChatDatabase; userId?: string | null; } /** * Inner function for `createContext` where we create the context. * This is useful for testing when we don't want to mock Next.js' request/response */ export const createAsyncContextInner = async (params?: { jwtPayload?: JWTPayload; secret?: string; userId?: string | null; }): Promise<AsyncAuthContext> => ({ jwtPayload: params?.jwtPayload || {}, secret: params?.secret || '', userId: params?.userId, }); export type AsyncContext = Awaited<ReturnType<typeof createAsyncContextInner>>; export const createAsyncRouteContext = async (request: NextRequest): Promise<AsyncContext> => { // for API-response caching see https://trpc.io/docs/v11/caching log('Creating async route context'); const authorization = request.headers.get('Authorization'); const lobeChatAuthorization = request.headers.get(LOBE_CHAT_AUTH_HEADER); log('Authorization header present: %s', !!authorization); log('LobeChat auth header present: %s', !!lobeChatAuthorization); if (!authorization) { log('No authorization header found'); throw new Error('No authorization header found'); } if (!lobeChatAuthorization) { log('No LobeChat authorization header found'); throw new Error('No LobeChat authorization header found'); } const secret = authorization?.split(' ')[1]; log('Secret extracted from authorization header: %s', !!secret); try { log('Initializing KeyVaultsGateKeeper'); const gateKeeper = await KeyVaultsGateKeeper.initWithEnvKey(); log('Decrypting LobeChat authorization'); const { plaintext } = await gateKeeper.decrypt(lobeChatAuthorization); log('Parsing decrypted authorization data'); const { userId, payload } = JSON.parse(plaintext); log( 'Successfully parsed authorization data - userId: %s, payload keys: %O', userId, Object.keys(payload || {}), ); return createAsyncContextInner({ jwtPayload: payload, secret, userId }); } catch (error) { log('Error creating async route context: %O', error); throw error; } };