mirror of
https://github.com/shuaiplus/nodewarden.git
synced 2026-06-20 21:00:41 +00:00
59 lines
2.1 KiB
TypeScript
59 lines
2.1 KiB
TypeScript
import { AuthService } from '../services/auth';
|
|
import type { Env, JWTPayload } from '../types';
|
|
import { errorResponse, jsonResponse } from '../utils/response';
|
|
import { generateUUID } from '../utils/uuid';
|
|
|
|
function extractAccessToken(request: Request): string | null {
|
|
const url = new URL(request.url);
|
|
const queryToken = String(url.searchParams.get('access_token') || '').trim();
|
|
if (queryToken) return queryToken;
|
|
|
|
const authHeader = String(request.headers.get('Authorization') || '').trim();
|
|
const match = authHeader.match(/^Bearer\s+(.+)$/i);
|
|
return match?.[1]?.trim() || null;
|
|
}
|
|
|
|
async function authenticateNotificationsRequest(request: Request, env: Env): Promise<JWTPayload | null> {
|
|
const accessToken = extractAccessToken(request);
|
|
if (!accessToken) return null;
|
|
|
|
const auth = new AuthService(env);
|
|
return auth.verifyAccessToken(`Bearer ${accessToken}`);
|
|
}
|
|
|
|
export async function handleNotificationsNegotiate(request: Request, env: Env): Promise<Response> {
|
|
const payload = await authenticateNotificationsRequest(request, env);
|
|
if (!payload?.sub) return errorResponse('Unauthorized', 401);
|
|
|
|
const connectionId = generateUUID();
|
|
return jsonResponse({
|
|
connectionId,
|
|
connectionToken: connectionId,
|
|
negotiateVersion: 1,
|
|
availableTransports: [
|
|
{
|
|
transport: 'WebSockets',
|
|
transferFormats: ['Text', 'Binary'],
|
|
},
|
|
],
|
|
});
|
|
}
|
|
|
|
export async function handleNotificationsHub(request: Request, env: Env): Promise<Response> {
|
|
const payload = await authenticateNotificationsRequest(request, env);
|
|
if (!payload?.sub) return errorResponse('Unauthorized', 401);
|
|
if (request.headers.get('Upgrade')?.toLowerCase() !== 'websocket') {
|
|
return errorResponse('Expected websocket', 426);
|
|
}
|
|
|
|
const userId = payload.sub;
|
|
const id = env.NOTIFICATIONS_HUB.idFromName(userId);
|
|
const stub = env.NOTIFICATIONS_HUB.get(id);
|
|
const forwardedUrl = new URL(request.url);
|
|
forwardedUrl.searchParams.set('nw_uid', userId);
|
|
if (payload.did) {
|
|
forwardedUrl.searchParams.set('nw_did', payload.did);
|
|
}
|
|
return stub.fetch(new Request(forwardedUrl.toString(), request));
|
|
}
|