mirror of
https://github.com/NanmiCoder/cc-haha
synced 2026-07-16 13:03:31 +08:00
The classifier should not treat every /sdk path as trusted by pathname, because LAN-exposed servers already have a narrower local SDK trust boundary. Constraint: Desktop local chat, Tauri WebView, loopback adapters, and local SDK routes must remain tokenless. Rejected: Path-only /sdk trust | a non-local caller could reach the SDK route through a LAN-bound server. Confidence: high Scope-risk: narrow Directive: Keep remote /sdk and hostile-origin loopback requests in the H5/browser bucket unless a dedicated SDK auth layer is verified. Tested: bun test src/server/__tests__/h5-access-policy.test.ts
64 lines
1.4 KiB
TypeScript
64 lines
1.4 KiB
TypeScript
export type H5RequestKind = 'local-trusted' | 'internal-sdk' | 'h5-browser'
|
|
|
|
const LOCAL_HOSTS = new Set(['localhost', '127.0.0.1', '::1'])
|
|
const LOCAL_ORIGINS = new Set([
|
|
'http://tauri.localhost',
|
|
'https://tauri.localhost',
|
|
'tauri://localhost',
|
|
])
|
|
|
|
export function normalizeHostname(hostname: string): string {
|
|
return hostname.trim().replace(/^\[/, '').replace(/\]$/, '').toLowerCase()
|
|
}
|
|
|
|
export function isLoopbackHost(hostname: string): boolean {
|
|
return LOCAL_HOSTS.has(normalizeHostname(hostname))
|
|
}
|
|
|
|
function isLocalOrigin(origin: string | null): boolean {
|
|
if (!origin) return true
|
|
if (LOCAL_ORIGINS.has(origin)) return true
|
|
|
|
try {
|
|
return isLoopbackHost(new URL(origin).hostname)
|
|
} catch {
|
|
return false
|
|
}
|
|
}
|
|
|
|
export function classifyH5Request(request: Request, url: URL): H5RequestKind {
|
|
const localTrusted = isLoopbackHost(url.hostname) && isLocalOrigin(request.headers.get('Origin'))
|
|
|
|
if (url.pathname.startsWith('/sdk/') && localTrusted) {
|
|
return 'internal-sdk'
|
|
}
|
|
|
|
if (localTrusted) {
|
|
return 'local-trusted'
|
|
}
|
|
|
|
return 'h5-browser'
|
|
}
|
|
|
|
export function shouldRequireH5Token({
|
|
request,
|
|
url,
|
|
h5Enabled,
|
|
explicitAuthRequired,
|
|
}: {
|
|
request: Request
|
|
url: URL
|
|
h5Enabled: boolean
|
|
explicitAuthRequired: boolean
|
|
}): boolean {
|
|
if (explicitAuthRequired) {
|
|
return true
|
|
}
|
|
|
|
if (!h5Enabled) {
|
|
return false
|
|
}
|
|
|
|
return classifyH5Request(request, url) === 'h5-browser'
|
|
}
|