Hallo Stroke

Frontend Authentication

JWT auth flow, token refresh, and registration in the SPA.

Auth context

src/contexts/AuthContext.js provides user, login, logout, fetchUser, refreshToken, and loading. Most pages gate content on this context.

Login flow

  1. AuthContext.login (or AdminLogin) calls POST /api/login with {username, password}.
  2. The backend looks up the user by email OR username OR phone, verifies the bcrypt hash, and returns {access_token, refresh_token}.
  3. Both tokens are stored in localStorage.
  4. GET /api/profile is called to hydrate the user state.
  5. Admin login additionally checks profile.role === "admin"; if not admin, tokens are cleared and login rejected.

Token refresh (axios interceptor)

src/api/axios.js has a response interceptor that handles expired access tokens transparently:

Loading diagram...

The interceptor also sets cache-busting headers (no-cache, Pragma, Expires) globally.

Registration (3-step)

State is persisted in sessionStorage across the steps so a refresh doesn't lose progress.

StepRouteCollected
1/registerusername, email, password
2/register/detailsNIK (16 digits), full name, alias (forum pseudonym), WhatsApp
3/preferencesinfo preferences (medical, mental health, 6 religions, "other belief")

Step 3 submits everything via POST /api/register, which encrypts the NIK with AES-GCM before storing.

Password reset

  1. /forgot-passwordGET /api/send-verification-code?phone= → backend stores a UUID reset token and WhatsApps a link {FRONTEND_URL}/reset-password?code=<token>.
  2. /reset-password?code=...POST /api/update-password with {code, new_password} → validates, hashes, clears token.

Logout

POST /api/logout clears the stored refresh token on the backend, then the frontend clears localStorage and redirects.

Committed secret

VAPID_PRIVATE_KEY is committed in .env of the frontend repo. It should not be in the frontend — move it to the backend environment.

On this page