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
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:
parent
6e2d513cc7
commit
7d10290389
1
.gitignore
vendored
1
.gitignore
vendored
@ -7,3 +7,4 @@ coverage/
|
||||
!.env.example
|
||||
.DS_Store
|
||||
.pnpm-store/
|
||||
test-results/
|
||||
|
||||
@ -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'));
|
||||
|
||||
@ -1,4 +0,0 @@
|
||||
{
|
||||
"status": "passed",
|
||||
"failedTests": []
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user