Wire authentication into the application
Adds the sign-in screen, sign-out, and a server-side guard on every application route. The guard lives in the layout rather than the proxy because the proxy cannot query the database to check whether a session was revoked — and revocation is the reason sessions are stored there. Sign-in returns one message for an unknown account and for a wrong password, and verifies a dummy hash when the account does not exist, so neither the wording nor the timing enumerates staff addresses. An end-to-end test compares the two messages rather than trusting the code to keep them aligned. The shell now shows the signed-in person and their role from the database instead of hardcoded initials. Playwright signs in once in a setup project and shares the cookie; argon2 is deliberately slow, and logging in per test would also drive the shared failed-attempt counter toward a lockout. The seed resets that counter so repeated local runs cannot lock the demo account. Two test locators had to be scoped to the form: Next's route announcer carries role="alert" and an empty string, which silently satisfied the assertion. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Cr9dkEHwbDgkWPnyGj1Rjv
This commit is contained in:
12 files changed
+361
-19
No files matched your search
@@ -1,7 +1,29 @@
|
||||
import { redirect } from 'next/navigation';
|
||||
import type { ReactNode } from 'react';
|
||||
|
||||
import { AppShell } from '@/components/shell/AppShell';
|
||||
import { currentSession } from '@/server/auth/session';
|
||||
|
||||
export default function AppLayout({ children }: { children: ReactNode }) {
|
||||
return <AppShell>{children}</AppShell>;
|
||||
/**
|
||||
* Toutes les routes applicatives passent par ici.
|
||||
*
|
||||
* Le contrôle est fait côté serveur, dans le layout, et non dans le proxy : le
|
||||
* proxy ne peut pas interroger la base pour vérifier qu'une session n'a pas été
|
||||
* révoquée, et c'est précisément la révocation qui justifie de tenir les
|
||||
* sessions en base (matrice n° 23).
|
||||
*/
|
||||
export default async function AppLayout({ children }: { children: ReactNode }) {
|
||||
const session = await currentSession();
|
||||
if (!session) redirect('/connexion');
|
||||
|
||||
return (
|
||||
<AppShell
|
||||
initials={session.user.initials}
|
||||
fullName={`${session.user.firstName} ${session.user.lastName}`}
|
||||
roleName={session.roleName}
|
||||
accountName={session.accountName}
|
||||
>
|
||||
{children}
|
||||
</AppShell>
|
||||
);
|
||||
}
|
||||
Reference in new issue
Block a user