Some checks are pending
E2E / Playwright e2e (push) Waiting to run
- Updated login and signup components to utilize AuthCard for better user experience during redirection. - Introduced AuthentikEmbedDialog for seamless integration of Authentik's identity portal within the application. - Enhanced password recovery and signup flows with dynamic theme handling and improved loading states. - Refactored existing components to streamline authentication processes and improve maintainability.
95 lines
2.9 KiB
TypeScript
95 lines
2.9 KiB
TypeScript
"use client"
|
|
|
|
import Link from "next/link"
|
|
import { useEffect } from "react"
|
|
import { useTheme } from "next-themes"
|
|
import { Loader2 } from "lucide-react"
|
|
import { AuthCard } from "@/components/auth/auth-card"
|
|
import { AuthConnectButton } from "@/components/auth/auth-connect-button"
|
|
import {
|
|
authentikRecoveryFlowUrl,
|
|
resolveAuthentikTheme,
|
|
} from "@/lib/auth/authentik-user-url"
|
|
import { getAuthentikEnrollmentUrl, getForgotPasswordUrl } from "@/lib/auth/oidc-config"
|
|
import { useClientThemeStore } from "@/lib/stores/client-theme-store"
|
|
import { useNativeRuntime } from "@/lib/platform"
|
|
|
|
type LoginPageContentProps = {
|
|
returnTo?: string
|
|
error?: string | null
|
|
}
|
|
|
|
export function LoginPageContent({
|
|
returnTo = "/mail/inbox",
|
|
error = null,
|
|
}: LoginPageContentProps) {
|
|
const native = useNativeRuntime()
|
|
const themeMode = useClientThemeStore((s) => s.themeMode)
|
|
const { resolvedTheme } = useTheme()
|
|
const authentikTheme = resolveAuthentikTheme(themeMode, resolvedTheme)
|
|
const signupHref = native
|
|
? `/signup?returnTo=${encodeURIComponent(returnTo)}`
|
|
: getAuthentikEnrollmentUrl()
|
|
const forgotPasswordHref = native
|
|
? `/forgot-password?returnTo=${encodeURIComponent(returnTo)}`
|
|
: (authentikRecoveryFlowUrl(authentikTheme) ?? getForgotPasswordUrl())
|
|
const oidcHref = `/api/auth/login?returnTo=${encodeURIComponent(returnTo)}`
|
|
const decodedError = error ? decodeURIComponent(error) : null
|
|
|
|
useEffect(() => {
|
|
if (!error) {
|
|
window.location.replace(oidcHref)
|
|
}
|
|
}, [error, oidcHref])
|
|
|
|
const footer = (
|
|
<div className="flex w-full flex-col gap-3 text-center text-sm text-muted-foreground">
|
|
<p>
|
|
Pas encore de compte ?{" "}
|
|
{native ? (
|
|
<Link className="font-medium text-primary underline" href={signupHref}>
|
|
Créer un compte
|
|
</Link>
|
|
) : (
|
|
<a className="font-medium text-primary underline" href={signupHref}>
|
|
Créer un compte
|
|
</a>
|
|
)}
|
|
</p>
|
|
<p>
|
|
{native ? (
|
|
<Link className="font-medium text-primary underline" href={forgotPasswordHref}>
|
|
Mot de passe oublié ?
|
|
</Link>
|
|
) : (
|
|
<a className="font-medium text-primary underline" href={forgotPasswordHref}>
|
|
Mot de passe oublié ?
|
|
</a>
|
|
)}
|
|
</p>
|
|
</div>
|
|
)
|
|
|
|
if (error) {
|
|
return (
|
|
<AuthCard
|
|
title="Connexion"
|
|
description="Connecte-toi avec ton compte UltiSpace pour accéder à ta suite."
|
|
error={decodedError}
|
|
footer={footer}
|
|
>
|
|
<AuthConnectButton href={oidcHref}>Réessayer</AuthConnectButton>
|
|
</AuthCard>
|
|
)
|
|
}
|
|
|
|
return (
|
|
<AuthCard title="Connexion" description="Redirection vers UltiSpace…" footer={footer}>
|
|
<div className="flex justify-center py-8">
|
|
<Loader2 className="size-6 animate-spin text-muted-foreground" aria-hidden />
|
|
<span className="sr-only">Redirection…</span>
|
|
</div>
|
|
</AuthCard>
|
|
)
|
|
}
|