Auto-commit 2026-05-02 09:37

This commit is contained in:
2026-05-02 09:37:34 -04:00
parent b7600fa937
commit 35d004cde3
3809 changed files with 2315945 additions and 106 deletions

View File

@@ -6,6 +6,7 @@
import { WebSocketServer, WebSocket } from 'ws';
import { CallAnalysisEngine, CallEvent, Anomaly, SentimentAnalysis, AnalysisResult } from '../../src/lib/inference/call-analysis-engine';
import { jwtVerify, SignJWT } from 'jose';
export type AlertType =
| 'anomaly'
@@ -50,14 +51,29 @@ export interface SubscriberSession {
const DEFAULT_CONFIG: Required<AlertServerConfig> = {
port: 8088,
enableAuth: false,
jwtSecret: '',
enableAuth: true,
jwtSecret: process.env.ALERT_SERVER_JWT_SECRET || '',
allowedOrigins: ['http://localhost:3000'],
alertCooldownMs: 5000,
maxSubscribers: 100,
enableCallCorrelation: true,
};
/**
* JWT verification helper
*/
async function verifyJWT(token: string, secret: string): Promise<any | null> {
try {
const decoded = await jwtVerify(token, new TextEncoder().encode(secret), {
algorithms: ['HS256'],
});
return decoded;
} catch (error) {
console.error('[AlertServer] JWT verification failed:', (error as Error).message);
return null;
}
}
export class AlertServer {
private wss: WebSocketServer | null = null;
private config: Required<AlertServerConfig>;
@@ -92,15 +108,36 @@ export class AlertServer {
private handleConnection(ws: WebSocket, req: import('http').IncomingMessage): void {
const url = new URL(req.url || '', `http://${req.headers.host}`);
const sessionId = url.searchParams.get('sessionId') || `sub-${Date.now()}-${Math.random().toString(36).slice(2)}`;
const userId = url.searchParams.get('userId') || undefined;
let userId = url.searchParams.get('userId') || undefined;
const callId = url.searchParams.get('callId') || undefined;
// Origin validation
const origin = req.headers.origin;
if (origin && !this.config.allowedOrigins.includes(origin)) {
ws.close(1008, 'Origin not allowed');
return;
}
// JWT Authentication (if enabled)
if (this.config.enableAuth && this.config.jwtSecret) {
const authHeader = req.headers.authorization;
if (!authHeader || !authHeader.startsWith('Bearer ')) {
ws.close(4001, 'Missing or invalid JWT token');
return;
}
const token = authHeader.substring(7);
const decoded = verifyJWT(token, this.config.jwtSecret);
if (!decoded) {
ws.close(4002, 'Invalid or expired JWT token');
return;
}
// Extract user ID from token if present
userId = (decoded as any).sub || userId;
}
if (this.subscribers.size >= this.config.maxSubscribers) {
ws.close(1013, 'Too many subscribers');
return;