'use client'; import { Suspense, useEffect, useState } from 'react'; import { useRouter, useSearchParams } from 'next/navigation'; const OIDC_ERROR_LABELS: Record = { no_code: 'No authorization code received from provider.', oidc_not_configured: 'OIDC provider not configured.', token_exchange: 'Failed to exchange token with provider.', }; function authentikBase(url?: string | null) { if (!url) return null; try { return new URL(url).origin.replace(/\/$/, ''); } catch { return null; } } function authentikUrl() { const baseHost = authentikBase(process.env.NEXT_PUBLIC_AUTHENTIK_ISSUER); const clientId = process.env.NEXT_PUBLIC_AUTHENTIK_CLIENT_ID; const base = process.env.NEXT_PUBLIC_BASE_URL ?? (typeof window !== 'undefined' ? window.location.origin : ''); if (!baseHost || !clientId) return null; return `${baseHost}/application/o/authorize/?${new URLSearchParams({ response_type: 'code', client_id: clientId, redirect_uri: `${base}/api/auth/callback`, scope: 'openid email profile', })}`; } function LoginForm() { const router = useRouter(); const params = useSearchParams(); const [username, setUsername] = useState(''); const [password, setPassword] = useState(''); const [loading, setLoading] = useState(false); const [error, setError] = useState(''); const oidcUrl = typeof window !== 'undefined' ? authentikUrl() : null; useEffect(() => { const e = params.get('error'); if (e) setError(OIDC_ERROR_LABELS[e] ?? `Auth error: ${e}`); }, [params]); const submit = async (e: React.FormEvent) => { e.preventDefault(); if (!username || !password || loading) return; setLoading(true); setError(''); try { const res = await fetch('/api/auth/login', { method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify({ username, password }), }); if (res.ok) { router.push('/dashboard'); } else { const j = await res.json().catch(() => ({})); setError(j.error ?? `Login failed (${res.status})`); setLoading(false); } } catch { setError('Network error — check your connection and try again.'); setLoading(false); } }; return (
cvfs
Sign in to your account
setUsername(e.target.value)} placeholder="admin" disabled={loading} />
setPassword(e.target.value)} placeholder="••••••••" disabled={loading} />
{error && (
{error}
)}
{oidcUrl && ( <>

or
)}

cvfs — CV File System

); } export default function LoginPage() { return ( ); }