mirror of
https://github.com/hansjone/oclaw.git
synced 2026-10-14 21:43:22 +08:00
Add uds-auth zh/en i18n, UAC-branded settings, and QR expire/fail overlay.
Wire client locale to the DSH host, return stable API error codes with localized messages, and replace bottom refresh with an in-frame retry for expired or offline QR. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
parent
b60c626d41
commit
fd0df9b890
9 changed files with 1183 additions and 202 deletions
|
|
@ -3,6 +3,7 @@
|
|||
*/
|
||||
import { directRequest } from './uds/user-search.js'
|
||||
import { requestIsLoopback } from './skill-credentials.js'
|
||||
import { apiError, resolveLocale } from './i18n.js'
|
||||
|
||||
const DEFAULT_OUTBOUND_HOSTS = [
|
||||
'icenterapi.zte.com.cn',
|
||||
|
|
@ -16,6 +17,10 @@ function sendJSON(res, code, data) {
|
|||
res.end(JSON.stringify(data))
|
||||
}
|
||||
|
||||
function sendErr(req, res, status, code, vars) {
|
||||
return sendJSON(res, status, apiError(code, resolveLocale(req), vars))
|
||||
}
|
||||
|
||||
function readSessionId(req, body) {
|
||||
const h = req.headers || {}
|
||||
return (
|
||||
|
|
@ -76,18 +81,17 @@ export function createAgentAuthHandlers(deps) {
|
|||
|
||||
async function handleAgentCredentials(req, res) {
|
||||
if (!requestIsLoopback(req)) {
|
||||
return sendJSON(res, 403, { error: 'agent-credentials is loopback-only' })
|
||||
return sendErr(req, res, 403, 'loopback_only_credentials')
|
||||
}
|
||||
const method = (req.method || 'GET').toUpperCase()
|
||||
if (method !== 'GET' && method !== 'POST') {
|
||||
return sendJSON(res, 405, { error: 'Method not allowed' })
|
||||
return sendErr(req, res, 405, 'method_not_allowed')
|
||||
}
|
||||
const body = method === 'POST' ? await readJsonBody(req) : {}
|
||||
const { creds, sessionId } = await resolveFromRequest(req, body)
|
||||
if (!creds) {
|
||||
return sendJSON(res, 401, {
|
||||
error: 'no_skill_credentials',
|
||||
message: '请先完成 UDS 扫码登录',
|
||||
...apiError('no_skill_credentials', resolveLocale(req)),
|
||||
sessionId: sessionId || null,
|
||||
})
|
||||
}
|
||||
|
|
@ -100,36 +104,33 @@ export function createAgentAuthHandlers(deps) {
|
|||
|
||||
async function handleOutbound(req, res) {
|
||||
if (!requestIsLoopback(req)) {
|
||||
return sendJSON(res, 403, { error: 'outbound is loopback-only' })
|
||||
return sendErr(req, res, 403, 'loopback_only_outbound')
|
||||
}
|
||||
const method = (req.method || 'POST').toUpperCase()
|
||||
if (method !== 'POST') {
|
||||
return sendJSON(res, 405, { error: 'Method not allowed' })
|
||||
return sendErr(req, res, 405, 'method_not_allowed')
|
||||
}
|
||||
const body = await readJsonBody(req)
|
||||
const { creds } = await resolveFromRequest(req, body)
|
||||
if (!creds) {
|
||||
return sendJSON(res, 401, {
|
||||
error: 'no_skill_credentials',
|
||||
message: '请先完成 UDS 扫码登录',
|
||||
})
|
||||
return sendErr(req, res, 401, 'no_skill_credentials')
|
||||
}
|
||||
|
||||
const targetUrl = body.url
|
||||
if (!targetUrl || typeof targetUrl !== 'string') {
|
||||
return sendJSON(res, 400, { error: 'url required' })
|
||||
return sendErr(req, res, 400, 'url_required')
|
||||
}
|
||||
let parsed
|
||||
try {
|
||||
parsed = new URL(targetUrl)
|
||||
} catch {
|
||||
return sendJSON(res, 400, { error: 'invalid url' })
|
||||
return sendErr(req, res, 400, 'invalid_url')
|
||||
}
|
||||
if (parsed.protocol !== 'https:' && parsed.protocol !== 'http:') {
|
||||
return sendJSON(res, 400, { error: 'unsupported protocol' })
|
||||
return sendErr(req, res, 400, 'unsupported_protocol')
|
||||
}
|
||||
if (!hostAllowed(parsed.hostname)) {
|
||||
return sendJSON(res, 403, { error: 'host_not_allowed', host: parsed.hostname })
|
||||
return sendJSON(res, 403, apiError('host_not_allowed', resolveLocale(req), { host: parsed.hostname }))
|
||||
}
|
||||
|
||||
const upstreamMethod = String(body.method || 'POST').toUpperCase()
|
||||
|
|
@ -170,7 +171,9 @@ export function createAgentAuthHandlers(deps) {
|
|||
json: out.json,
|
||||
}))
|
||||
} catch (err) {
|
||||
return sendJSON(res, 502, { error: 'upstream_failed', message: err.message || String(err) })
|
||||
const payload = apiError('upstream_failed', resolveLocale(req))
|
||||
payload.message = payload.message + ': ' + (err.message || String(err))
|
||||
return sendJSON(res, 502, payload)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue