Files
auth-portal/apps/api/src/lib/target-app.ts
T
Denozordec c48132e89e fix(api): ошибки типов, скрытые отсутствием typecheck
- jose v6 не экспортирует KeyLike → CryptoKey
- SimpleWebAuthn v13 требует Uint8Array<ArrayBuffer>
- targetType 'credential' в AUDIT_TARGET_TYPES (писался в аудит passkey-ов)
- target-app: начальные значения host/path/search никогда не читались
2026-09-23 14:51:38 +07:00

76 lines
1.8 KiB
TypeScript

import type { AuditSourceApp } from '@authportal/shared'
/** Resolve SSO target app from return_to URL host/path (and OIDC authorize unwrap). */
export function targetAppFromReturnTo(
returnTo: string | undefined | null,
): AuditSourceApp {
if (!returnTo) return 'portal'
let u: URL
try {
u = new URL(returnTo)
} catch {
return 'portal'
}
const host = u.hostname.toLowerCase()
const path = u.pathname.toLowerCase()
const search = u.search
// Portal OIDC authorize as return_to → map via client's redirect_uri
if (path === '/oauth/authorize' || path.endsWith('/oauth/authorize')) {
try {
const redirectUri = new URLSearchParams(search).get('redirect_uri')
if (redirectUri) return targetAppFromReturnTo(redirectUri)
} catch {
/* ignore */
}
}
const hay = `${host} ${path}`
if (/\bvps\b/.test(hay) || host.includes('vps')) return 'vps'
if (
/\bcfdm\b/.test(hay) ||
host.includes('cfdm') ||
host.includes('domain')
) {
return 'cfdm'
}
if (/\bbgp\b/.test(hay) || host.includes('bgp')) return 'bgp'
if (
/\bfw\b/.test(hay) ||
host.includes('firewall') ||
host.includes('evofw')
) {
return 'fw'
}
if (
/\bdns\b/.test(hay) ||
host.includes('technitium') ||
path.includes('/sso/')
) {
return 'dns'
}
if (
/\bcdn\b/.test(hay) ||
host.includes('cdnmanager') ||
host.includes('cdn-manager')
) {
return 'cdn'
}
if (
/\bmm\b/.test(hay) ||
host.includes('mikrotik') ||
host.includes('mmapp')
) {
return 'mm'
}
return 'portal'
}
export function clientUserAgent(
headers: Record<string, string | string[] | undefined>,
): string | null {
const ua = headers['user-agent']
if (typeof ua === 'string' && ua.trim()) return ua.trim().slice(0, 512)
return null
}