mirror of
https://github.com/rustfs/console.git
synced 2026-08-28 19:47:21 +08:00
84 lines
2.6 KiB
TypeScript
84 lines
2.6 KiB
TypeScript
import type { OidcProvider } from "@/types/config"
|
|
import { isSafeRedirectPath } from "@/lib/routes"
|
|
|
|
export interface OidcLogoutSession {
|
|
logoutToken: string
|
|
}
|
|
|
|
/**
|
|
* Fetch configured OIDC providers from the server.
|
|
*/
|
|
export async function fetchOidcProviders(serverHost: string): Promise<OidcProvider[]> {
|
|
try {
|
|
const url = `${serverHost}/rustfs/admin/v3/oidc/providers`
|
|
const response = await fetch(url, { method: "GET" })
|
|
if (!response.ok) return []
|
|
return await response.json()
|
|
} catch {
|
|
return []
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Build the backend OIDC authorization endpoint URL.
|
|
*/
|
|
export function buildOidcLoginUrl(serverHost: string, providerId: string, redirectAfter?: string): string {
|
|
let url = `${serverHost}/rustfs/admin/v3/oidc/authorize/${encodeURIComponent(providerId)}`
|
|
if (redirectAfter) {
|
|
url += `?redirect_after=${encodeURIComponent(redirectAfter)}`
|
|
}
|
|
return url
|
|
}
|
|
|
|
/**
|
|
* Redirect the browser to the OIDC authorization endpoint.
|
|
*/
|
|
export function initiateOidcLogin(serverHost: string, providerId: string, redirectAfter?: string): void {
|
|
const url = buildOidcLoginUrl(serverHost, providerId, redirectAfter)
|
|
window.location.href = new URL(url, window.location.origin).href
|
|
}
|
|
|
|
/**
|
|
* Build the backend logout endpoint URL. The backend decides whether to perform
|
|
* RP-initiated logout with the IdP or fall back to the console login page.
|
|
*/
|
|
export function buildOidcLogoutUrl(serverHost: string, logoutToken: string): string {
|
|
const base = serverHost.replace(/\/$/, "")
|
|
return `${base}/rustfs/admin/v3/oidc/logout?logout_token=${encodeURIComponent(logoutToken)}`
|
|
}
|
|
|
|
/**
|
|
* Parse STS credentials from the URL hash fragment (set by OIDC callback).
|
|
* Expected format:
|
|
* #accessKey=...&secretKey=...&sessionToken=...&expiration=...&redirect=/path&logoutToken=...
|
|
*/
|
|
export function parseOidcCallback(hash: string): {
|
|
accessKey: string
|
|
secretKey: string
|
|
sessionToken: string
|
|
expiration: string
|
|
redirect: string
|
|
logoutToken?: string
|
|
} | null {
|
|
// Strip leading # from hash
|
|
const cleaned = hash.replace(/^#\/?/, "")
|
|
if (!cleaned) return null
|
|
|
|
const params = new URLSearchParams(cleaned)
|
|
const accessKey = params.get("accessKey")
|
|
const secretKey = params.get("secretKey")
|
|
const sessionToken = params.get("sessionToken")
|
|
const logoutToken = params.get("logoutToken") ?? undefined
|
|
|
|
if (!accessKey || !secretKey || !sessionToken) return null
|
|
|
|
return {
|
|
accessKey,
|
|
secretKey,
|
|
sessionToken,
|
|
expiration: params.get("expiration") ?? "",
|
|
redirect: isSafeRedirectPath(params.get("redirect") ?? "", "/"),
|
|
logoutToken: logoutToken || undefined,
|
|
}
|
|
}
|