mirror of
https://github.com/shuaiplus/nodewarden.git
synced 2026-06-20 21:00:41 +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:
@@ -72,3 +72,7 @@ export function readKnownDeviceProbe(request: Request): { email: string | null;
|
||||
return { email, deviceIdentifier };
|
||||
}
|
||||
|
||||
export function readActingDeviceIdentifier(request: Request): string | null {
|
||||
return normalizeDeviceIdentifier(request.headers.get('X-NodeWarden-Acting-Device-Id'));
|
||||
}
|
||||
|
||||
|
||||
+28
-2
@@ -1,7 +1,21 @@
|
||||
import { LIMITS } from '../config/limits';
|
||||
|
||||
const CORS_METHODS = 'GET, POST, PUT, DELETE, PATCH, OPTIONS';
|
||||
const CORS_HEADERS = 'Content-Type, Authorization, Accept, Device-Type, Bitwarden-Client-Name, Bitwarden-Client-Version, X-Request-Email, X-Device-Identifier, X-Device-Name';
|
||||
const DEFAULT_CORS_HEADERS = [
|
||||
'Content-Type',
|
||||
'Authorization',
|
||||
'Accept',
|
||||
'Device-Type',
|
||||
'Device-Identifier',
|
||||
'Device-Name',
|
||||
'Bitwarden-Client-Name',
|
||||
'Bitwarden-Client-Version',
|
||||
'Bitwarden-Package-Type',
|
||||
'Is-Prerelease',
|
||||
'X-Request-Email',
|
||||
'X-Device-Identifier',
|
||||
'X-Device-Name',
|
||||
];
|
||||
|
||||
function isTrustedClientOrigin(origin: string): boolean {
|
||||
// Official browser extension / desktop-webview common origins.
|
||||
@@ -25,9 +39,15 @@ function getAllowedOrigin(request: Request): string | null {
|
||||
}
|
||||
|
||||
function buildCorsHeaders(request: Request): Record<string, string> {
|
||||
const requestedHeaders = String(request.headers.get('Access-Control-Request-Headers') || '')
|
||||
.split(',')
|
||||
.map((value) => value.trim())
|
||||
.filter(Boolean);
|
||||
const allowHeaders = Array.from(new Set([...DEFAULT_CORS_HEADERS, ...requestedHeaders]));
|
||||
|
||||
const headers: Record<string, string> = {
|
||||
'Access-Control-Allow-Methods': CORS_METHODS,
|
||||
'Access-Control-Allow-Headers': CORS_HEADERS,
|
||||
'Access-Control-Allow-Headers': allowHeaders.join(', '),
|
||||
'Access-Control-Max-Age': String(LIMITS.cors.preflightMaxAgeSeconds),
|
||||
};
|
||||
|
||||
@@ -44,6 +64,12 @@ export function applyCors(
|
||||
request: Request,
|
||||
response: Response
|
||||
): Response {
|
||||
// WebSocket upgrade responses must be returned untouched.
|
||||
const webSocket = (response as Response & { webSocket?: unknown }).webSocket;
|
||||
if (response.status === 101 || webSocket) {
|
||||
return response;
|
||||
}
|
||||
|
||||
const headers = new Headers(response.headers);
|
||||
const corsHeaders = buildCorsHeaders(request);
|
||||
for (const [k, v] of Object.entries(corsHeaders)) {
|
||||
|
||||
Reference in New Issue
Block a user