mirror of
https://github.com/shuaiplus/nodewarden.git
synced 2026-06-20 13:00:39 +00:00
feat: implement NotificationsHub for real-time vault sync notifications
- Added NotificationsHub durable object to handle WebSocket connections for vault sync notifications. - Integrated SignalR protocol for message framing and communication. - Updated storage service methods to return revision date and user ID for vault sync notifications. - Enhanced existing handlers (attachments, ciphers, folders, sends, and import) to notify users of vault sync events. - Created new notifications handler for WebSocket negotiation and binding user IDs. - Updated frontend to establish WebSocket connection for receiving vault sync notifications. - Improved CORS headers to support new notification endpoints. - Bumped wrangler version in package.json to 4.71.0.
This commit is contained in:
+20
-2
@@ -104,6 +104,10 @@ import {
|
||||
handleAdminExportBackup,
|
||||
handleAdminImportBackup,
|
||||
} from './handlers/backup';
|
||||
import {
|
||||
handleNotificationsHub,
|
||||
handleNotificationsNegotiate,
|
||||
} from './handlers/notifications';
|
||||
|
||||
function isSameOriginWriteRequest(request: Request): boolean {
|
||||
const targetOrigin = new URL(request.url).origin;
|
||||
@@ -474,6 +478,14 @@ export async function handleRequest(request: Request, env: Env): Promise<Respons
|
||||
return errorResponse('Server configuration error: JWT_SECRET is not set or too weak', 500);
|
||||
}
|
||||
|
||||
if (path === '/notifications/hub/negotiate' && method === 'POST') {
|
||||
return handleNotificationsNegotiate(request, env);
|
||||
}
|
||||
|
||||
if (path === '/notifications/hub' && method === 'GET') {
|
||||
return handleNotificationsHub(request, env);
|
||||
}
|
||||
|
||||
// All other API endpoints require authentication
|
||||
const auth = new AuthService(env);
|
||||
const authHeader = request.headers.get('Authorization');
|
||||
@@ -483,6 +495,13 @@ export async function handleRequest(request: Request, env: Env): Promise<Respons
|
||||
return errorResponse('Unauthorized', 401);
|
||||
}
|
||||
|
||||
const actingDeviceId = String(payload.did || '').trim();
|
||||
if (actingDeviceId) {
|
||||
const nextHeaders = new Headers(request.headers);
|
||||
nextHeaders.set('X-NodeWarden-Acting-Device-Id', actingDeviceId);
|
||||
request = new Request(request, { headers: nextHeaders });
|
||||
}
|
||||
|
||||
const userId = payload.sub;
|
||||
const storage = new StorageService(env.DB);
|
||||
const currentUser = await storage.getUserById(userId);
|
||||
@@ -566,9 +585,8 @@ export async function handleRequest(request: Request, env: Env): Promise<Respons
|
||||
return handleSync(request, env, userId);
|
||||
}
|
||||
|
||||
// Notifications hub (stub): now requires authentication.
|
||||
if (path.startsWith('/notifications/')) {
|
||||
return new Response(null, { status: 200 });
|
||||
return errorResponse('Not found', 404);
|
||||
}
|
||||
|
||||
// Cipher endpoints
|
||||
|
||||
Reference in New Issue
Block a user