fix: add the missing /verify-email page
SonarQube Analysis / sonarqube (pull_request) Successful in 3m42s
Tests / backend-unit (pull_request) Successful in 59s
Tests / backend-integration (pull_request) Successful in 1m30s
Tests / frontend-e2e (pull_request) Failing after 5m21s

Verification emails linked to /verify-email?token=..., but no such route
existed in main.tsx and nothing in the frontend ever called
POST /api/customers/verify-email. The SPA catch-all served index.html, no
route matched, and the page rendered blank -- so the token was never
redeemed and accounts stayed unverified forever.

The gap was invisible until SMTP was configured, because no verification
email had ever actually been delivered.

Adds VerifyEmail.tsx (verifying / verified / failed states), a verifyEmail
call in customerApi, and the route. The request is pinned to a single
firing via a ref: the endpoint deletes the token on success, so StrictMode's
double effect invocation in dev would otherwise overwrite the success state
with "invalid or expired token".

Verified end to end against a local stack: a real token flips
customers.email_verified to true and is consumed from customer_tokens.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-08-15 18:16:32 -05:00
co-authored by Claude Opus 5
parent e7fb7271f0
commit b7c8c37447
4 changed files with 113 additions and 0 deletions
+2
View File
@@ -9,6 +9,7 @@ import Login from './customer/Login';
import Register from './customer/Register';
import Account from './customer/Account';
import PrivacyPolicy from './customer/PrivacyPolicy';
import VerifyEmail from './customer/VerifyEmail';
import Cart from './cart/Cart';
import { CustomerAuthProvider } from './customer/CustomerAuthContext';
import { CartProvider } from './cart/CartContext';
@@ -33,6 +34,7 @@ function Root() {
<Route path="/account" element={<Account />} />
<Route path="/cart" element={<Cart />} />
<Route path="/privacy" element={<PrivacyPolicy />} />
<Route path="/verify-email" element={<VerifyEmail />} />
</Routes>
</BrowserRouter>
</ConfigProvider>