Files
logbuch/app/login/actions.ts
T

55 lines
1.5 KiB
TypeScript

'use server';
import { headers } from 'next/headers';
import { redirect } from 'next/navigation';
import { verifyCredentials, getBeoDisplayName } from '@/lib/auth';
import { createSession } from '@/lib/session';
import { checkRateLimit } from '@/lib/ratelimit';
export async function login(
_prevState: { error: string } | undefined,
formData: FormData
): Promise<{ error: string }> {
const headersList = await headers();
const ip =
headersList.get('x-forwarded-for')?.split(',')[0].trim() ??
headersList.get('x-real-ip') ??
'unknown';
const { allowed, remainingMs } = checkRateLimit(ip);
if (!allowed) {
const minutes = Math.ceil(remainingMs / 60000);
return { error: `Zu viele Anmeldeversuche. Bitte ${minutes} Minute${minutes !== 1 ? 'n' : ''} warten.` };
}
const login = (formData.get('username') as string)?.trim();
const password = formData.get('password') as string;
if (!login || !password) {
return { error: 'Bitte Kürzel/Nachname und Passwort eingeben.' };
}
const result = await verifyCredentials(login, password);
if (!result || !result.valid) {
return { error: 'Ungültiger Benutzername oder Passwort.' };
}
const mustChange = result.beo.MustChangePassword === 1 || !result.beo.pw;
await createSession({
kuerzel: result.beo.kürzel ?? login,
beoId: result.beo.id,
beoName: getBeoDisplayName(result.beo),
mustChangePassword: mustChange,
isAuthenticated: true,
role: result.beo.role ?? null,
});
if (mustChange) {
redirect('/change-password');
}
redirect('/');
}