Fire the e-mail verification exactly once per token
Some checks failed
CD / Build and push images (push) Successful in 39s
CI / Lint, typecheck, test (push) Successful in 1m12s
CI / Auth e2e pack (push) Failing after 1m51s
CI / Build container images (push) Has been skipped
CD / Deploy to Test (push) Successful in 9s
CD / Smoke tests against Test (push) Successful in 1m4s
CD / Promote to Int (push) Successful in 10s

React StrictMode double-invokes effects in development; the second
POST consumed-token 400 could win the state race and show an error
for a successful verification (flaked in CI, passed locally). A ref
guards the single-use call; Playwright test-results are ignored.

Part of #20

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Claude Fable 5 2026-07-05 05:59:25 +02:00
parent 6e2d513cc7
commit 7d10290389
3 changed files with 7 additions and 5 deletions

1
.gitignore vendored
View File

@ -7,3 +7,4 @@ coverage/
!.env.example
.DS_Store
.pnpm-store/
test-results/

View File

@ -1,4 +1,4 @@
import { useEffect, useState } from 'react';
import { useEffect, useRef, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { Link, useSearchParams } from 'react-router-dom';
@ -14,12 +14,17 @@ export function VerifyEmailPage(): React.JSX.Element {
const [resent, setResent] = useState(false);
const token = params.get('token');
// Tokens are single-use: the effect must fire exactly once per token,
// also under React StrictMode's double-invocation in development.
const firedFor = useRef<string | null>(null);
useEffect(() => {
if (!token) {
setState('error');
return;
}
if (firedFor.current === token) return;
firedFor.current = token;
apiPost('/auth/verify-email', { token })
.then(() => setState('success'))
.catch(() => setState('error'));

View File

@ -1,4 +0,0 @@
{
"status": "passed",
"failedTests": []
}