9362a10
ZhenYi
refactor: remove OAuth-related modules and update references for identity service integration
9362a10
import { serviceFetch } from './http'
import { jwtManager } from './manager'
import { type JwtManager, JwtManagerError } from './types'
export interface SocketOptions {
issuer: string
url: string
manager?: JwtManager
}
function issuerUrl(raw: string): string {
const url = new URL(raw)
if (
url.origin !== raw ||
url.username ||
url.password ||
(url.protocol !== 'https:' &&
!(url.protocol === 'http:' && ['localhost', '127.0.0.1', '[::1]'].includes(url.hostname)))
) {
throw new JwtManagerError('issuer_invalid', 'Issuer must be an HTTPS origin or loopback HTTP origin')
}
return raw
}
export async function connectSocket(options: SocketOptions): Promise<WebSocket> {
const issuer = issuerUrl(options.issuer)
const url = new URL(options.url, location.href)
if (
url.protocol !== 'wss:' &&
!(url.protocol === 'ws:' && ['localhost', '127.0.0.1', '[::1]'].includes(url.hostname))
) {
throw new JwtManagerError('socket_url_invalid', 'Socket URL requires WSS or loopback WS')
}
const response = await serviceFetch('auth', `${issuer}/api/v1/oauth/socket-tickets`, {
baseUrl: issuer,
method: 'POST',
manager: options.manager ?? jwtManager,
credentials: 'include',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ origin: location.origin }),
signal: AbortSignal.timeout(10_000),
})
const body = (await response.json()) as { ticket?: string }
if (!response.ok || !body.ticket) throw new JwtManagerError('socket_ticket_failed', 'Socket ticket issuance failed')
url.searchParams.set('ticket', body.ticket)
return new WebSocket(url)
}