mirror of
https://github.com/hansjone/oclaw.git
synced 2026-10-17 20:50:49 +08:00
Speed up uds-auth login: paint badge first, lazy /api/me.
Skip startup /api/me until QR load, stop blocking me on workspace provision, and register the footer login entry before heavy ACL gates so login appears immediately. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
parent
1c461285fc
commit
81ff8eb19f
4 changed files with 104 additions and 134 deletions
|
|
@ -486,8 +486,7 @@ window.__ModuleLoader__.load({
|
||||||
}
|
}
|
||||||
|
|
||||||
function clearSessionIfAnonymous(sessions) {
|
function clearSessionIfAnonymous(sessions) {
|
||||||
// Wait for first /api/me so we do not wipe a real session during bootstrap.
|
// No startup /api/me — treat as anonymous until QR-triggered me sets logged-in.
|
||||||
if (!isUdsAuthReady()) return
|
|
||||||
if (isLoggedInInUi()) return
|
if (isLoggedInInUi()) return
|
||||||
try {
|
try {
|
||||||
if (sessions && typeof sessions.clear === 'function') sessions.clear()
|
if (sessions && typeof sessions.clear === 'function') sessions.clear()
|
||||||
|
|
@ -983,7 +982,7 @@ function reloadAfterLogin() {
|
||||||
const [user, setUser] = useState(null)
|
const [user, setUser] = useState(null)
|
||||||
|
|
||||||
|
|
||||||
const [loading, setLoading] = useState(true)
|
const [loading, setLoading] = useState(false)
|
||||||
const [config, setConfig] = useState({ loginSystemCode: '100000455558', originSystemCode: '' })
|
const [config, setConfig] = useState({ loginSystemCode: '100000455558', originSystemCode: '' })
|
||||||
const [qrStatus, setQrStatus] = useState('')
|
const [qrStatus, setQrStatus] = useState('')
|
||||||
const [qrImg, setQrImg] = useState('')
|
const [qrImg, setQrImg] = useState('')
|
||||||
|
|
@ -1050,7 +1049,7 @@ function reloadAfterLogin() {
|
||||||
if (!me?.authenticated || !me?.data) {
|
if (!me?.authenticated || !me?.data) {
|
||||||
setUser(null)
|
setUser(null)
|
||||||
window.dispatchEvent(new Event('uds-auth-changed'))
|
window.dispatchEvent(new Event('uds-auth-changed'))
|
||||||
return
|
return false
|
||||||
}
|
}
|
||||||
const d = me.data
|
const d = me.data
|
||||||
setUser({
|
setUser({
|
||||||
|
|
@ -1063,9 +1062,11 @@ function reloadAfterLogin() {
|
||||||
permissions: d.permissions || {},
|
permissions: d.permissions || {},
|
||||||
})
|
})
|
||||||
window.dispatchEvent(new Event('uds-auth-changed'))
|
window.dispatchEvent(new Event('uds-auth-changed'))
|
||||||
|
return true
|
||||||
} catch {
|
} catch {
|
||||||
setUser(null)
|
setUser(null)
|
||||||
window.dispatchEvent(new Event('uds-auth-changed'))
|
window.dispatchEvent(new Event('uds-auth-changed'))
|
||||||
|
return false
|
||||||
} finally {
|
} finally {
|
||||||
document.documentElement.setAttribute('data-uds-auth-ready', '1')
|
document.documentElement.setAttribute('data-uds-auth-ready', '1')
|
||||||
setLoading(false)
|
setLoading(false)
|
||||||
|
|
@ -1078,8 +1079,23 @@ function reloadAfterLogin() {
|
||||||
setQrFailed(false)
|
setQrFailed(false)
|
||||||
setQrStatus(t('ui.qrGenerating'))
|
setQrStatus(t('ui.qrGenerating'))
|
||||||
setQrImg('')
|
setQrImg('')
|
||||||
|
// Me check in background — never block QR paint on /api/me.
|
||||||
|
void refreshUser().then((loggedIn) => {
|
||||||
|
if (!loggedIn) return
|
||||||
|
stopQr()
|
||||||
|
setQrStatus('')
|
||||||
|
setQrImg('')
|
||||||
|
setOpen(false)
|
||||||
|
}).catch(() => {})
|
||||||
try {
|
try {
|
||||||
const started = await fetchJson('/uds-auth/qr-start')
|
const started = await fetchJson('/uds-auth/qr-start')
|
||||||
|
// Already signed in while QR was starting — drop the code.
|
||||||
|
if (document.documentElement.getAttribute('data-uds-logged-in') === '1') {
|
||||||
|
stopQr()
|
||||||
|
setQrStatus('')
|
||||||
|
setQrImg('')
|
||||||
|
return
|
||||||
|
}
|
||||||
const { qrCodeStr, qrCodeKey, qrCodeValue, loginSystemCode, originSystemCode } = started
|
const { qrCodeStr, qrCodeKey, qrCodeValue, loginSystemCode, originSystemCode } = started
|
||||||
qrRef.current.key = qrCodeKey
|
qrRef.current.key = qrCodeKey
|
||||||
qrRef.current.value = qrCodeValue
|
qrRef.current.value = qrCodeValue
|
||||||
|
|
@ -1198,7 +1214,7 @@ function reloadAfterLogin() {
|
||||||
}, [fbUser, fbPass, refreshUser])
|
}, [fbUser, fbPass, refreshUser])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
refreshUser()
|
// Do NOT call /api/me on mount — only when loading the login QR (startQr).
|
||||||
fetchJson('/uds-auth/config.get')
|
fetchJson('/uds-auth/config.get')
|
||||||
.then((data) => { if (data?.value) setConfig((prev) => ({ ...prev, ...data.value })) })
|
.then((data) => { if (data?.value) setConfig((prev) => ({ ...prev, ...data.value })) })
|
||||||
.catch(() => {})
|
.catch(() => {})
|
||||||
|
|
@ -1206,7 +1222,7 @@ function reloadAfterLogin() {
|
||||||
.then((st) => setFallbackEnabled(!!st.enabled))
|
.then((st) => setFallbackEnabled(!!st.enabled))
|
||||||
.catch(() => { /* keep default true — do not hide emergency login */ })
|
.catch(() => { /* keep default true — do not hide emergency login */ })
|
||||||
return () => { stopQr() }
|
return () => { stopQr() }
|
||||||
}, [refreshUser, stopQr])
|
}, [stopQr])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!open || user) return undefined
|
if (!open || user) return undefined
|
||||||
|
|
@ -1248,7 +1264,7 @@ function reloadAfterLogin() {
|
||||||
|
|
||||||
const displayName = user
|
const displayName = user
|
||||||
? (user.userName || user.name || (t('ui.userPrefix') + user.empNo))
|
? (user.userName || user.name || (t('ui.userPrefix') + user.empNo))
|
||||||
: (loading ? '...' : t('ui.notLoggedIn'))
|
: t('ui.notLoggedIn')
|
||||||
const initials = String(displayName).slice(0, 2).toUpperCase()
|
const initials = String(displayName).slice(0, 2).toUpperCase()
|
||||||
const label = roleLabel(user?.role)
|
const label = roleLabel(user?.role)
|
||||||
const perms = user?.permissions || {}
|
const perms = user?.permissions || {}
|
||||||
|
|
@ -1405,6 +1421,30 @@ function reloadAfterLogin() {
|
||||||
localeHost = ctx
|
localeHost = ctx
|
||||||
translate = makeTranslator(ctx)
|
translate = makeTranslator(ctx)
|
||||||
|
|
||||||
|
// --- Critical path: login badge must paint first ---
|
||||||
|
// Sync ACL + CSS before any React mount so 「未登录」is styled and locked immediately.
|
||||||
|
{
|
||||||
|
const root = document.documentElement
|
||||||
|
if (!root.getAttribute('data-uds-logged-in')) root.setAttribute('data-uds-logged-in', '0')
|
||||||
|
if (!root.getAttribute('data-uds-auth-ready')) root.setAttribute('data-uds-auth-ready', '0')
|
||||||
|
if (!root.getAttribute('data-uds-can-create-ws')) root.setAttribute('data-uds-can-create-ws', '0')
|
||||||
|
if (!root.getAttribute('data-uds-can-settings')) root.setAttribute('data-uds-can-settings', '0')
|
||||||
|
}
|
||||||
|
if (!document.getElementById('uds-auth-client-css')) {
|
||||||
|
const tag = document.createElement('style')
|
||||||
|
tag.id = 'uds-auth-client-css'
|
||||||
|
tag.setAttribute('data-plugin', name)
|
||||||
|
tag.textContent = CSS
|
||||||
|
document.head.appendChild(tag)
|
||||||
|
}
|
||||||
|
// Register login entry before heavy gates / settings section.
|
||||||
|
ctx.slots.inject('sidebar.footer.action', () => ctx.slots.register({
|
||||||
|
name: 'sidebar.footer.action',
|
||||||
|
id: 'uds-auth-login',
|
||||||
|
order: 100,
|
||||||
|
label: 'UAC',
|
||||||
|
}, AuthBadge))
|
||||||
|
|
||||||
ctx.effect(() => {
|
ctx.effect(() => {
|
||||||
if (!ctx.locale || typeof ctx.locale.register !== 'function') return undefined
|
if (!ctx.locale || typeof ctx.locale.register !== 'function') return undefined
|
||||||
try {
|
try {
|
||||||
|
|
@ -1431,68 +1471,18 @@ function reloadAfterLogin() {
|
||||||
})
|
})
|
||||||
} catch { /* connection may be unavailable */ }
|
} catch { /* connection may be unavailable */ }
|
||||||
|
|
||||||
|
// Settings gear: CSS hides it when data-uds-can-settings=0 (no slot override —
|
||||||
|
// registering sidebar.settings early used to crash / delay the whole plugin).
|
||||||
|
|
||||||
// Default ACL attrs before /api/me — anonymous stays locked until AuthBadge confirms.
|
// Settings page section — after login badge; not on the critical path for first paint.
|
||||||
ctx.effect(() => {
|
ctx.slots.inject('settings.section', () => ctx.slots.register({
|
||||||
const root = document.documentElement
|
name: 'settings.section',
|
||||||
// Cookie alone is not enough; lock until /api/me sets real identity.
|
id: 'uds-auth',
|
||||||
if (!getEmpNo()) {
|
order: 22,
|
||||||
root.setAttribute('data-uds-logged-in', '0')
|
label: () => t('ui.settingsTitle'),
|
||||||
} else if (!root.getAttribute('data-uds-logged-in')) {
|
locale: LOCALE_NS,
|
||||||
// Optimistic cookie presence; AuthBadge will correct to 0/1.
|
icon: 'users',
|
||||||
root.setAttribute('data-uds-logged-in', '0')
|
}, AuthSettingsSection))
|
||||||
}
|
|
||||||
if (!root.getAttribute('data-uds-auth-ready')) {
|
|
||||||
root.setAttribute('data-uds-auth-ready', '0')
|
|
||||||
}
|
|
||||||
if (!root.getAttribute('data-uds-can-create-ws')) {
|
|
||||||
root.setAttribute('data-uds-can-create-ws', '0')
|
|
||||||
}
|
|
||||||
if (!root.getAttribute('data-uds-can-settings')) {
|
|
||||||
root.setAttribute('data-uds-can-settings', '0')
|
|
||||||
}
|
|
||||||
return undefined
|
|
||||||
}, 'uds-auth: bootstrap-acl-attrs')
|
|
||||||
|
|
||||||
|
|
||||||
ctx.effect(() => {
|
|
||||||
const tag = document.createElement('style')
|
|
||||||
tag.id = 'uds-auth-client-css'
|
|
||||||
tag.setAttribute('data-plugin', name)
|
|
||||||
tag.textContent = CSS
|
|
||||||
document.head.appendChild(tag)
|
|
||||||
return () => tag.remove()
|
|
||||||
}, 'uds-auth: styles')
|
|
||||||
|
|
||||||
ctx.effect(() => {
|
|
||||||
let settingsGateDispose = null
|
|
||||||
const syncSettingsGate = async () => {
|
|
||||||
let canSettings = false
|
|
||||||
try {
|
|
||||||
const me = await fetchJson('/uds-auth/api/me')
|
|
||||||
canSettings = !!(me?.data?.permissions?.canAccessSettings)
|
|
||||||
} catch { canSettings = false }
|
|
||||||
if (canSettings) {
|
|
||||||
if (settingsGateDispose) { try { settingsGateDispose() } catch {} settingsGateDispose = null }
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if (settingsGateDispose) return
|
|
||||||
settingsGateDispose = ctx.slots.register({
|
|
||||||
name: 'sidebar.settings',
|
|
||||||
id: 'uds-auth-settings-gate',
|
|
||||||
order: 9999,
|
|
||||||
}, function UdsAuthSettingsGate() { return null })
|
|
||||||
}
|
|
||||||
syncSettingsGate()
|
|
||||||
const mePoll = setInterval(syncSettingsGate, 15000)
|
|
||||||
const onFocus = () => { syncSettingsGate() }
|
|
||||||
window.addEventListener('focus', onFocus)
|
|
||||||
return () => {
|
|
||||||
clearInterval(mePoll)
|
|
||||||
window.removeEventListener('focus', onFocus)
|
|
||||||
if (settingsGateDispose) { try { settingsGateDispose() } catch {} }
|
|
||||||
}
|
|
||||||
}, 'uds-auth: settings-gate')
|
|
||||||
|
|
||||||
|
|
||||||
// Defense in depth: never show Host session rows while UDS cookies are absent.
|
// Defense in depth: never show Host session rows while UDS cookies are absent.
|
||||||
|
|
@ -1660,27 +1650,37 @@ function reloadAfterLogin() {
|
||||||
disposers = []
|
disposers = []
|
||||||
}
|
}
|
||||||
// Deny folder pick by default — no race with native directory picker.
|
// Deny folder pick by default — no race with native directory picker.
|
||||||
installGate()
|
const sync = () => {
|
||||||
const sync = async () => {
|
// Attrs come from QR-triggered /api/me via AuthBadge — do not poll me here.
|
||||||
let canCreate = false
|
const canCreate = document.documentElement.getAttribute('data-uds-can-create-ws') === '1'
|
||||||
try {
|
|
||||||
const me = await fetchJson('/uds-auth/api/me')
|
|
||||||
canCreate = !!(me && me.data && me.data.permissions && me.data.permissions.canCreateWorkspace)
|
|
||||||
} catch { canCreate = false }
|
|
||||||
if (canCreate) clearGate()
|
if (canCreate) clearGate()
|
||||||
else installGate()
|
else installGate()
|
||||||
}
|
}
|
||||||
|
const injectOffs = [
|
||||||
|
'sidebar.workspaces.directoryFlow',
|
||||||
|
'conversation.hero.workspace.directoryFlow',
|
||||||
|
].map((slotName) => {
|
||||||
|
try {
|
||||||
|
return ctx.slots.inject(slotName, () => { sync() })
|
||||||
|
} catch {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
})
|
||||||
sync()
|
sync()
|
||||||
const timer = setInterval(sync, 15000)
|
|
||||||
const onFocus = () => { sync() }
|
|
||||||
const onAuth = () => { sync() }
|
const onAuth = () => { sync() }
|
||||||
window.addEventListener('focus', onFocus)
|
|
||||||
window.addEventListener('uds-auth-changed', onAuth)
|
window.addEventListener('uds-auth-changed', onAuth)
|
||||||
|
const mo = new MutationObserver(sync)
|
||||||
|
mo.observe(document.documentElement, {
|
||||||
|
attributes: true,
|
||||||
|
attributeFilter: ['data-uds-can-create-ws', 'data-uds-logged-in'],
|
||||||
|
})
|
||||||
return () => {
|
return () => {
|
||||||
clearInterval(timer)
|
|
||||||
window.removeEventListener('focus', onFocus)
|
|
||||||
window.removeEventListener('uds-auth-changed', onAuth)
|
window.removeEventListener('uds-auth-changed', onAuth)
|
||||||
|
mo.disconnect()
|
||||||
clearGate()
|
clearGate()
|
||||||
|
for (const off of injectOffs) {
|
||||||
|
try { if (typeof off === 'function') off() } catch { /* ignore */ }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}, 'uds-auth: directory-flow-gate')
|
}, 'uds-auth: directory-flow-gate')
|
||||||
|
|
||||||
|
|
@ -1796,40 +1796,26 @@ function reloadAfterLogin() {
|
||||||
workspaceDispose = null
|
workspaceDispose = null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Deny open-workspace by default until /api/me proves canCreateWorkspace.
|
// Deny open-workspace by default until QR-triggered /api/me proves canCreateWorkspace.
|
||||||
if (!canOpenWorkspace()) installWorkspaceLock()
|
|
||||||
freezeChoosers()
|
freezeChoosers()
|
||||||
|
|
||||||
const syncWorkspaceSlot = async () => {
|
const syncWorkspaceSlot = () => {
|
||||||
let canCreate = document.documentElement.getAttribute('data-uds-can-create-ws') === '1'
|
// Use AuthBadge DOM attrs only — no default /api/me.
|
||||||
try {
|
const canCreate = document.documentElement.getAttribute('data-uds-can-create-ws') === '1'
|
||||||
const me = await fetchJson('/uds-auth/api/me')
|
|
||||||
const user = me && me.authenticated && me.data ? me.data : null
|
|
||||||
const perms = user && user.permissions ? user.permissions : {}
|
|
||||||
canCreate = !!perms.canCreateWorkspace
|
|
||||||
document.documentElement.setAttribute('data-uds-logged-in', user ? '1' : '0')
|
|
||||||
document.documentElement.setAttribute('data-uds-can-create-ws', canCreate ? '1' : '0')
|
|
||||||
document.documentElement.setAttribute(
|
|
||||||
'data-uds-can-settings',
|
|
||||||
user && perms.canAccessSettings ? '1' : '0',
|
|
||||||
)
|
|
||||||
} catch {
|
|
||||||
if (!getEmpNo()) {
|
|
||||||
canCreate = false
|
|
||||||
document.documentElement.setAttribute('data-uds-logged-in', '0')
|
|
||||||
document.documentElement.setAttribute('data-uds-can-create-ws', '0')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (canCreate) clearWorkspaceLock()
|
if (canCreate) clearWorkspaceLock()
|
||||||
else installWorkspaceLock()
|
else installWorkspaceLock()
|
||||||
freezeChoosers()
|
freezeChoosers()
|
||||||
}
|
}
|
||||||
|
let workspaceInjectOff = null
|
||||||
|
try {
|
||||||
|
workspaceInjectOff = ctx.slots.inject('conversation.hero.workspace', () => {
|
||||||
|
syncWorkspaceSlot()
|
||||||
|
})
|
||||||
|
} catch { /* ignore */ }
|
||||||
syncWorkspaceSlot()
|
syncWorkspaceSlot()
|
||||||
const timer = setInterval(syncWorkspaceSlot, 10000)
|
|
||||||
const onAuth = () => { syncWorkspaceSlot() }
|
const onAuth = () => { syncWorkspaceSlot() }
|
||||||
window.addEventListener('uds-auth-changed', onAuth)
|
window.addEventListener('uds-auth-changed', onAuth)
|
||||||
window.addEventListener('focus', onAuth)
|
const mo = new MutationObserver(() => { freezeChoosers(); syncWorkspaceSlot() })
|
||||||
const mo = new MutationObserver(() => { freezeChoosers() })
|
|
||||||
mo.observe(document.documentElement, {
|
mo.observe(document.documentElement, {
|
||||||
childList: true,
|
childList: true,
|
||||||
subtree: true,
|
subtree: true,
|
||||||
|
|
@ -1838,14 +1824,13 @@ function reloadAfterLogin() {
|
||||||
})
|
})
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
clearInterval(timer)
|
|
||||||
mo.disconnect()
|
mo.disconnect()
|
||||||
document.removeEventListener('click', block, true)
|
document.removeEventListener('click', block, true)
|
||||||
document.removeEventListener('pointerdown', block, true)
|
document.removeEventListener('pointerdown', block, true)
|
||||||
document.removeEventListener('mousedown', block, true)
|
document.removeEventListener('mousedown', block, true)
|
||||||
window.removeEventListener('uds-auth-changed', onAuth)
|
window.removeEventListener('uds-auth-changed', onAuth)
|
||||||
window.removeEventListener('focus', onAuth)
|
|
||||||
clearWorkspaceLock()
|
clearWorkspaceLock()
|
||||||
|
try { if (typeof workspaceInjectOff === 'function') workspaceInjectOff() } catch { /* ignore */ }
|
||||||
}
|
}
|
||||||
}, 'uds-auth: workspace-click-lock')
|
}, 'uds-auth: workspace-click-lock')
|
||||||
ctx.effect(() => {
|
ctx.effect(() => {
|
||||||
|
|
@ -1941,27 +1926,6 @@ function reloadAfterLogin() {
|
||||||
window.removeEventListener('uds-auth-changed', onAuth)
|
window.removeEventListener('uds-auth-changed', onAuth)
|
||||||
}
|
}
|
||||||
}, 'uds-auth: session-only-sidebar')
|
}, 'uds-auth: session-only-sidebar')
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// sidebar.footer.action; layout effect lays footArea as one row: Settings | UAC login
|
|
||||||
ctx.slots.inject('sidebar.footer.action', () => ctx.slots.register({
|
|
||||||
name: 'sidebar.footer.action',
|
|
||||||
id: 'uds-auth-login',
|
|
||||||
order: 100,
|
|
||||||
label: 'UAC',
|
|
||||||
}, AuthBadge))
|
|
||||||
|
|
||||||
ctx.slots.inject('settings.section', () => ctx.slots.register({
|
|
||||||
name: 'settings.section',
|
|
||||||
id: 'uds-auth',
|
|
||||||
order: 22,
|
|
||||||
label: () => t('ui.settingsTitle'),
|
|
||||||
locale: LOCALE_NS,
|
|
||||||
icon: 'users',
|
|
||||||
}, AuthSettingsSection))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.name = name
|
exports.name = name
|
||||||
|
|
|
||||||
|
|
@ -724,7 +724,14 @@ function handleRequest(req, res) {
|
||||||
// 基础端点
|
// 基础端点
|
||||||
if (url === '/api/me' && method === 'GET') {
|
if (url === '/api/me' && method === 'GET') {
|
||||||
if (ctx2.empNo) {
|
if (ctx2.empNo) {
|
||||||
try { ctx2.provisionedWorkspace = await ensureUserWorkspace(ctx2.empNo) } catch { ctx2.provisionedWorkspace = null }
|
// Never block login badge / ACL on workspaceRegistry (can wait up to 30s).
|
||||||
|
// Serve cached mapping immediately; provision in background.
|
||||||
|
try {
|
||||||
|
ctx2.provisionedWorkspace = _userWorkspaces?.get?.(ctx2.empNo) || null
|
||||||
|
} catch {
|
||||||
|
ctx2.provisionedWorkspace = null
|
||||||
|
}
|
||||||
|
void ensureUserWorkspace(ctx2.empNo).catch(() => {})
|
||||||
}
|
}
|
||||||
await _apiHandlers.getCurrentUser(ctx2); return
|
await _apiHandlers.getCurrentUser(ctx2); return
|
||||||
}
|
}
|
||||||
|
|
@ -788,7 +795,7 @@ function notifyWorkspaceRegistryReady(registry) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Wait until workspaceRegistry inject fires (or timeout). */
|
/** Wait until workspaceRegistry inject fires (or timeout). */
|
||||||
function whenWorkspaceRegistry(timeoutMs = 30000) {
|
function whenWorkspaceRegistry(timeoutMs = 2500) {
|
||||||
if (_workspaceRegistry) return Promise.resolve(_workspaceRegistry)
|
if (_workspaceRegistry) return Promise.resolve(_workspaceRegistry)
|
||||||
return new Promise((resolve) => {
|
return new Promise((resolve) => {
|
||||||
const entry = {
|
const entry = {
|
||||||
|
|
@ -808,7 +815,7 @@ async function ensureUserWorkspace(empNo) {
|
||||||
try {
|
try {
|
||||||
let registry = _workspaceRegistry
|
let registry = _workspaceRegistry
|
||||||
if (!registry) {
|
if (!registry) {
|
||||||
registry = await whenWorkspaceRegistry(30000)
|
registry = await whenWorkspaceRegistry(2500)
|
||||||
}
|
}
|
||||||
const root = _currentConfig?.workspaceRoot
|
const root = _currentConfig?.workspaceRoot
|
||||||
if (!registry) {
|
if (!registry) {
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ export function directRequest(url, opts = {}) {
|
||||||
if (body && headers['Content-Length'] == null && headers['content-length'] == null) {
|
if (body && headers['Content-Length'] == null && headers['content-length'] == null) {
|
||||||
headers['Content-Length'] = body.length
|
headers['Content-Length'] = body.length
|
||||||
}
|
}
|
||||||
const timeoutMs = opts.timeoutMs ?? 8000
|
const timeoutMs = opts.timeoutMs ?? 3000
|
||||||
|
|
||||||
// Fresh Agent — never inherit globalAgent (often patched by proxy bootstraps).
|
// Fresh Agent — never inherit globalAgent (often patched by proxy bootstraps).
|
||||||
const agent = new lib.Agent({ keepAlive: false })
|
const agent = new lib.Agent({ keepAlive: false })
|
||||||
|
|
@ -71,7 +71,7 @@ export async function searchUserByEmpNoToken({
|
||||||
empNoHeader = 'X-Emp-No',
|
empNoHeader = 'X-Emp-No',
|
||||||
authValueHeader = 'X-Auth-Value',
|
authValueHeader = 'X-Auth-Value',
|
||||||
origin,
|
origin,
|
||||||
timeoutMs = 8000,
|
timeoutMs = 3000,
|
||||||
}) {
|
}) {
|
||||||
if (!userSearchUrl || !empNo || !token) {
|
if (!userSearchUrl || !empNo || !token) {
|
||||||
return { ok: false, reason: 'missing_args' }
|
return { ok: false, reason: 'missing_args' }
|
||||||
|
|
|
||||||
|
|
@ -65,7 +65,6 @@
|
||||||
"immediately": true,
|
"immediately": true,
|
||||||
"inject": [
|
"inject": [
|
||||||
"@deepseek-ai/dsh-client-ui-slots",
|
"@deepseek-ai/dsh-client-ui-slots",
|
||||||
"@deepseek-ai/dsh-client-ui-layout",
|
|
||||||
"@deepseek-ai/dsh-client-locale"
|
"@deepseek-ai/dsh-client-locale"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue