From ee0a49f381560fcb9246e1cdbffd6085ad3c33c7 Mon Sep 17 00:00:00 2001 From: oliver Date: Tue, 8 Sep 2026 09:49:30 +0800 Subject: [PATCH] Repair dsh-acl WebSocket identity patch syntax. Restore a valid patchWebSocketServerForUdsIdentity implementation after a bad edit. Co-authored-by: Cursor --- uds-auth/lib/dsh-acl.js | 135 +--------------------------------------- 1 file changed, 2 insertions(+), 133 deletions(-) diff --git a/uds-auth/lib/dsh-acl.js b/uds-auth/lib/dsh-acl.js index 914f3f27..b3114ba3 100644 --- a/uds-auth/lib/dsh-acl.js +++ b/uds-auth/lib/dsh-acl.js @@ -61,7 +61,7 @@ function bindWebSocketListenersToIdentity(ws, getIdentity) { */ function patchWebSocketServerForUdsIdentity(resolveIdentity) - // wrap existing upgrades (gateway may register before we patch registerUpgrade) + /* wrap existing upgrades */ try { const table = server.upgrades if (table && typeof table.entries === 'function') { @@ -78,139 +78,8 @@ function patchWebSocketServerForUdsIdentity(resolveIdentity) table.set(path, { ...route, handler: wrapped }) } } - } catch { /* private field / unavailable */ } { - if (patchWebSocketServerForUdsIdentity.done) return - patchWebSocketServerForUdsIdentity.done = true - let WebSocketServer - try { - const ws = require('ws') - WebSocketServer = ws.WebSocketServer || ws.Server - } catch { - return - } - if (!WebSocketServer?.prototype?.handleUpgrade) return - const orig = WebSocketServer.prototype.handleUpgrade - WebSocketServer.prototype.handleUpgrade = function udsAuthHandleUpgrade(req, socket, head, cb) { - const getIdentity = () => { - if (req && Object.prototype.hasOwnProperty.call(req, '__udsAuthIdentity')) { - return req.__udsAuthIdentity - } - if (socket && upgradeSocketIdentity.has(socket)) { - return upgradeSocketIdentity.get(socket) - } - if (typeof resolveIdentity !== 'function') return null - return Promise.resolve(resolveIdentity(req)).then((identity) => { - try { if (req) req.__udsAuthIdentity = identity } catch { /* ignore */ } - if (socket) upgradeSocketIdentity.set(socket, identity) - return identity - }) - } - const wrappedCb = typeof cb === 'function' - ? (wsSocket) => { - bindWebSocketListenersToIdentity(wsSocket, getIdentity) - return cb(wsSocket) - } - : cb - return orig.call(this, req, socket, head, wrappedCb) - } -} + } catch { /* private field / unavailable */ } -export async function resolveIdentityFromRequest(req, deps) { - const cookie = req?.headers?.cookie || '' - const empNo = parseCookie(cookie, 'PORTALSSOUser') - || parseCookie(cookie, 'ZTEDPGSSOUser') - || parseCookie(cookie, 'UDS_FALLBACK_USER') - if (!empNo) return null - - const { sessionStore, rolesStore } = deps - let userContext = null - try { - userContext = await sessionStore.get(empNo) - } catch { - userContext = null - } - if (!userContext) return null - - // bootstrap / resolve role - let role = rolesStore.getRole(empNo) - if (empNo !== 'administrator' && typeof rolesStore.bootstrapFirstUser === 'function') { - try { - const r = await rolesStore.bootstrapFirstUser(empNo) - role = r.role - } catch { /* keep getRole */ } - } - - const permissions = computePermissions(role) - return { - empNo: String(empNo), - role, - permissions, - userContext, - kind: empNo === 'administrator' ? 'fallback' : 'uds', - } -} - -/** - * Patch webServer so every route handler runs inside UDS ALS. - * @param {any} server - * @param {(req: any) => Promise} resolveIdentity - */ -export function patchWebServerWithIdentity(server, resolveIdentity) { - if (!server || server.__udsAuthPatched) return () => {} - server.__udsAuthPatched = true - - const wrap = (handler) => { - if (typeof handler !== 'function' || handler.__udsWrapped) return handler - const wrapped = async (req, res, ...rest) => { - const identity = await resolveIdentity(req) - try { - const pathname = new URL(req.url || '/', 'http://x').pathname - if ( - pathname.startsWith('/dsh-ops-cron') - && pathname !== '/dsh-ops-cron/health' - && !identity?.empNo - ) { - res.writeHead(401, { 'content-type': 'application/json; charset=utf-8' }) - res.end(JSON.stringify({ - ok: false, - error: 'login_required', - message: '登录后才能使用定时任务', - })) - return - } - } catch { /* fall through to handler */ } - return withUserContext(identity, () => handler(req, res, ...rest)) - } - wrapped.__udsWrapped = true - return wrapped - } - - const patchTable = (table) => { - if (!table || typeof table.entries !== 'function') return - for (const [path, route] of table.entries()) { - if (!route?.handler) continue - table.set(path, { ...route, handler: wrap(route.handler) }) - } - } - - patchTable(server.exact) - patchTable(server.prefixes) - if (typeof server.fallback === 'function') { - server.fallback = wrap(server.fallback) - } - - const origRegister = server.register.bind(server) - server.register = (route) => origRegister({ - ...route, - handler: wrap(route.handler), - }) - - const origFallback = server.registerFallback?.bind(server) - if (origFallback) { - server.registerFallback = (handler) => origFallback(wrap(handler)) - } - - patchWebSocketServerForUdsIdentity(resolveIdentity) const origRegisterUpgrade = server.registerUpgrade?.bind(server) if (origRegisterUpgrade) { server.registerUpgrade = (route) => origRegisterUpgrade({