Repair dsh-acl WebSocket identity patch syntax.

Restore a valid patchWebSocketServerForUdsIdentity implementation after a bad edit.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
oliver 2026-09-08 09:49:30 +08:00
parent a5ba9d52cc
commit ee0a49f381

View file

@ -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<object|null>} 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({