ultisuite-client/lib/auth/authentik-user-url.ts
R3D347HR4Y 359931c2f3
Some checks are pending
E2E / Playwright e2e (push) Waiting to run
feat: implement forgot password and signup flows with new layouts and components
- Added new layout and page components for forgot password and signup functionalities, enhancing user experience.
- Integrated authentication flow handling for password recovery and account creation, utilizing dynamic metadata.
- Updated login form to include links for forgot password and signup, improving navigation between authentication states.
- Refactored CSS styles for login components to ensure consistent design across different authentication pages.
2026-06-19 22:34:23 +02:00

118 lines
3.4 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* URLs Authentik (portail utilisateur + flows self-service).
* Issuer attendu : `https://host/auth/application/o/<slug>/`.
*/
import { getAuthentikBase } from "@/lib/auth/oidc-config"
import type { MailThemeMode } from "@/lib/mail-settings/types"
export type AuthentikUserSettingsTab =
| "details"
| "sessions"
| "mfa"
| "sources"
const TAB_PAGE: Record<AuthentikUserSettingsTab, string> = {
details: "page-details",
sessions: "page-sessions",
mfa: "page-mfa",
sources: "page-sources",
}
/** Flows Authentik par défaut pour self-service (modifiables côté admin). */
export const AUTHENTIK_SELF_SERVICE_FLOWS = {
passwordChange: "default-password-change",
recovery: "ulti-recovery",
totpSetup: "default-authenticator-totp-setup",
webauthnSetup: "default-authenticator-webauthn-setup",
staticSetup: "default-authenticator-static-setup",
} as const
export type AuthentikUrlOptions = {
tab?: AuthentikUserSettingsTab
flowSlug?: string
/** Thème Authentik (`?theme=`) aligné sur lapp Ulti. */
theme?: "light" | "dark"
}
function authentikBaseUrl(): string | null {
try {
return getAuthentikBase().replace(/\/$/, "")
} catch {
return null
}
}
function userSettingsHash(tab?: AuthentikUserSettingsTab): string {
if (!tab || tab === "details") return "#/settings"
const page = TAB_PAGE[tab]
const params = encodeURIComponent(JSON.stringify({ page }))
return `#/settings;${params}`
}
function withAuthentikTheme(url: string, theme?: "light" | "dark"): string {
if (!theme) return url
try {
const parsed = new URL(url)
parsed.searchParams.set("theme", theme)
return parsed.toString()
} catch {
return url
}
}
/** Thème effectif pour Authentik à partir des réglages Ulti. */
export function resolveAuthentikTheme(
themeMode: MailThemeMode,
resolvedTheme?: string | null
): "light" | "dark" {
if (themeMode === "light" || themeMode === "dark") return themeMode
if (resolvedTheme === "dark" || resolvedTheme === "light") return resolvedTheme
if (typeof document !== "undefined") {
return document.documentElement.classList.contains("dark") ? "dark" : "light"
}
return "light"
}
function userSettingsPath(tab?: AuthentikUserSettingsTab): string {
const hash = userSettingsHash(tab)
return `/if/user/${hash}`
}
/** Page « Paramètres » du portail utilisateur Authentik. */
export function authentikUserSettingsUrl(
tab: AuthentikUserSettingsTab = "details",
theme?: "light" | "dark"
): string | null {
const base = authentikBaseUrl()
if (!base) return null
return withAuthentikTheme(`${base}${userSettingsPath(tab)}`, theme)
}
/** Flow Authentik (mot de passe, MFA, etc.). */
export function authentikFlowUrl(
flowSlug: string,
theme?: "light" | "dark"
): string | null {
const base = authentikBaseUrl()
const slug = flowSlug.trim().replace(/^\/+|\/+$/g, "")
if (!base || !slug) return null
return withAuthentikTheme(`${base}/if/flow/${slug}/`, theme)
}
export function authentikPasswordChangeFlowUrl(
theme?: "light" | "dark"
): string | null {
return authentikFlowUrl(AUTHENTIK_SELF_SERVICE_FLOWS.passwordChange, theme)
}
/** URL Authentik (flow ou onglet réglages) avec thème. */
export function buildAuthentikUrl(options: AuthentikUrlOptions): string | null {
const { tab, flowSlug, theme } = options
if (flowSlug) {
const flowUrl = authentikFlowUrl(flowSlug, theme)
if (flowUrl) return flowUrl
}
return authentikUserSettingsUrl(tab ?? "details", theme)
}