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
+4
-1
@@ -134,7 +134,10 @@ async function main() {
|
||||
for (const [index, person] of people.entries()) {
|
||||
const user = await prisma.user.upsert({
|
||||
where: { email: person.email },
|
||||
update: {},
|
||||
// Remet le compteur d'échecs à zéro : sans cela, des exécutions
|
||||
// répétées des tests finissent par verrouiller le compte au bout de
|
||||
// huit tentatives, et l'échec suivant est incompréhensible.
|
||||
update: { failedAttempts: 0, lockedUntil: null, passwordHash },
|
||||
create: {
|
||||
email: person.email,
|
||||
firstName: person.firstName,
|
||||
|
||||
Reference in new issue
Block a user