mirror of
https://github.com/hansjone/oclaw.git
synced 2026-10-19 06:43:17 +08:00
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:
parent
a5ba9d52cc
commit
ee0a49f381
1 changed files with 2 additions and 133 deletions
|
|
@ -61,7 +61,7 @@ function bindWebSocketListenersToIdentity(ws, getIdentity) {
|
||||||
*/
|
*/
|
||||||
function patchWebSocketServerForUdsIdentity(resolveIdentity)
|
function patchWebSocketServerForUdsIdentity(resolveIdentity)
|
||||||
|
|
||||||
// wrap existing upgrades (gateway may register before we patch registerUpgrade)
|
/* wrap existing upgrades */
|
||||||
try {
|
try {
|
||||||
const table = server.upgrades
|
const table = server.upgrades
|
||||||
if (table && typeof table.entries === 'function') {
|
if (table && typeof table.entries === 'function') {
|
||||||
|
|
@ -78,139 +78,8 @@ function patchWebSocketServerForUdsIdentity(resolveIdentity)
|
||||||
table.set(path, { ...route, handler: wrapped })
|
table.set(path, { ...route, handler: wrapped })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch { /* private field / unavailable */ } {
|
} 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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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)
|
const origRegisterUpgrade = server.registerUpgrade?.bind(server)
|
||||||
if (origRegisterUpgrade) {
|
if (origRegisterUpgrade) {
|
||||||
server.registerUpgrade = (route) => origRegisterUpgrade({
|
server.registerUpgrade = (route) => origRegisterUpgrade({
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue