feat: add boss key
This commit is contained in:
1 parent
e7087bc4b1
commit
bc775d4fd6
10 files changed
+168
-6
No files matched your search
+7
-1
@@ -4,15 +4,21 @@ import { AppModule } from './app.module';
|
||||
import { logger } from '../utils/logger';
|
||||
import { TokenManagerService } from './modules/proxy/token-manager.service';
|
||||
|
||||
import { ProxyConfig } from '../types/config';
|
||||
import { setServerConfig } from './server-config';
|
||||
|
||||
let app: NestFastifyApplication | null = null;
|
||||
let currentPort: number = 0;
|
||||
|
||||
export async function bootstrapNestServer(port: number = 8045): Promise<boolean> {
|
||||
export async function bootstrapNestServer(config: ProxyConfig): Promise<boolean> {
|
||||
const port = config.port || 8045;
|
||||
if (app) {
|
||||
logger.info('NestJS server already running.');
|
||||
return true;
|
||||
}
|
||||
|
||||
setServerConfig(config);
|
||||
|
||||
try {
|
||||
app = await NestFactory.create<NestFastifyApplication>(AppModule, new FastifyAdapter(), {
|
||||
logger: ['error', 'warn', 'log'],
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
import { Controller, Get, Post, Body, Res, HttpStatus } from '@nestjs/common';
|
||||
import { Controller, Get, Post, Body, Res, HttpStatus, UseGuards } from '@nestjs/common';
|
||||
import { FastifyReply } from 'fastify';
|
||||
import { ProxyService } from './proxy.service';
|
||||
import { Observable } from 'rxjs';
|
||||
import { OpenAIChatRequest, AnthropicChatRequest } from './interfaces/request-interfaces';
|
||||
import { ProxyGuard } from './proxy.guard';
|
||||
|
||||
@Controller('v1')
|
||||
@UseGuards(ProxyGuard)
|
||||
export class ProxyController {
|
||||
constructor(private readonly proxyService: ProxyService) {}
|
||||
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
import {
|
||||
CanActivate,
|
||||
ExecutionContext,
|
||||
Injectable,
|
||||
UnauthorizedException,
|
||||
Logger,
|
||||
} from '@nestjs/common';
|
||||
import { getServerConfig } from '../../server-config';
|
||||
|
||||
@Injectable()
|
||||
export class ProxyGuard implements CanActivate {
|
||||
private readonly logger = new Logger(ProxyGuard.name);
|
||||
|
||||
canActivate(context: ExecutionContext): boolean {
|
||||
const config = getServerConfig();
|
||||
|
||||
// 1. Check for API Key in config
|
||||
const apiKey = config?.api_key;
|
||||
|
||||
// 2. Bypass if no api_key set (Open Mode) or config missing
|
||||
if (!apiKey || apiKey.trim() === '') {
|
||||
return true;
|
||||
}
|
||||
|
||||
const request = context.switchToHttp().getRequest();
|
||||
const headers = request.headers;
|
||||
|
||||
// 3. Extract Token from Headers
|
||||
let clientToken: string | undefined;
|
||||
|
||||
// A. standard 'authorization: Bearer <token>'
|
||||
if (headers['authorization']) {
|
||||
const parts = headers['authorization'].split(' ');
|
||||
if (parts.length === 2 && parts[0].toLowerCase() === 'bearer') {
|
||||
clientToken = parts[1];
|
||||
}
|
||||
}
|
||||
|
||||
// B. 'x-api-key' (Anthropic)
|
||||
if (!clientToken && headers['x-api-key']) {
|
||||
clientToken = headers['x-api-key'] as string;
|
||||
}
|
||||
|
||||
// C. 'x-goog-api-key' (Gemini)
|
||||
if (!clientToken && headers['x-goog-api-key']) {
|
||||
clientToken = headers['x-goog-api-key'] as string;
|
||||
}
|
||||
|
||||
// 4. Validate
|
||||
if (clientToken === apiKey) {
|
||||
return true;
|
||||
}
|
||||
|
||||
this.logger.warn(`Blocked unauthorized access from ${request.ip}`);
|
||||
throw new UnauthorizedException('Invalid API Key');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
import { ProxyConfig } from '../types/config';
|
||||
|
||||
let serverConfig: ProxyConfig | null = null;
|
||||
|
||||
export function setServerConfig(config: ProxyConfig) {
|
||||
serverConfig = config;
|
||||
}
|
||||
|
||||
export function getServerConfig(): ProxyConfig | null {
|
||||
return serverConfig;
|
||||
}
|
||||
Reference in new issue
Block a user