Allow in-process IM/cron session APIs when UDS ALS is unset.

Browser HTTP always enters withUserContext(null|identity); WhatsApp harness
calls session.create/prompt with no ALS frame. Treating undefined as
host-internal restores channel turns broken by the UDS session ACL.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
oliver 2026-09-08 19:43:48 +08:00
parent ba60368f39
commit 564d6ac189

View file

@ -486,8 +486,12 @@ export function installDshAcl(ctx, {
return false return false
} }
// Browser HTTP always enters ALS via withUserContext(null|identity).
// In-process Host callers (WhatsApp/IM, cron fire) never enter ALS → undefined.
// Treat undefined as host-internal and skip UDS ACL (pre-auth behavior).
const assertCanAccess = (request, rowHint) => { const assertCanAccess = (request, rowHint) => {
const identity = getUserContext() const identity = getUserContext()
if (identity === undefined) return
if (!empOf(identity)) throwForbidden('登录后才能访问会话') if (!empOf(identity)) throwForbidden('登录后才能访问会话')
if (canSeeAll(identity)) return if (canSeeAll(identity)) return
const sessionId = extractSessionId(request) const sessionId = extractSessionId(request)
@ -564,6 +568,10 @@ export function installDshAcl(ctx, {
const origCreate = sc.create.bind(sc) const origCreate = sc.create.bind(sc)
sc.create = async (request) => { sc.create = async (request) => {
const identity = getUserContext() const identity = getUserContext()
// WhatsApp / IM harness creates sessions in-process with no UDS ALS.
if (identity === undefined) {
return origCreate(request || {})
}
if (!empOf(identity)) throwForbidden('登录后才能创建会话') if (!empOf(identity)) throwForbidden('登录后才能创建会话')
let req = { ...(request || {}) } let req = { ...(request || {}) }
@ -586,6 +594,8 @@ export function installDshAcl(ctx, {
const waitForIdentity = async (ms = 800) => { const waitForIdentity = async (ms = 800) => {
let identity = getUserContext() let identity = getUserContext()
// Host-internal: do not burn 800ms waiting for a browser cookie that will never appear.
if (identity === undefined) return identity
if (empOf(identity)) return identity if (empOf(identity)) return identity
const deadline = Date.now() + ms const deadline = Date.now() + ms
while (!empOf(identity) && Date.now() < deadline) { while (!empOf(identity) && Date.now() < deadline) {
@ -627,6 +637,7 @@ export function installDshAcl(ctx, {
const origOpenPath = sc.openWorkspacePath.bind(sc) const origOpenPath = sc.openWorkspacePath.bind(sc)
sc.openWorkspacePath = async (request, signal) => { sc.openWorkspacePath = async (request, signal) => {
const identity = getUserContext() const identity = getUserContext()
if (identity === undefined) return origOpenPath(request, signal)
if (!empOf(identity)) throwForbidden('登录后才能访问会话') if (!empOf(identity)) throwForbidden('登录后才能访问会话')
if (!canSeeAll(identity) && !identity.permissions?.canCreateWorkspace) { if (!canSeeAll(identity) && !identity.permissions?.canCreateWorkspace) {
const path = request?.path const path = request?.path