src/contexts/JWTContext.tsx implements authentication for the SPA. It wraps the app in App.tsx as JWTProvider and is consumed via hooks/useAuth().
State shape — AuthProps
Reducer actions
Token helpers
verifyToken(token) — decodes JWT with jwt-decode, checks exp against current time.
setSession(token) — writes serviceToken to localStorage and sets axios Authorization: Bearer header. Clears both on logout.
Boot sequence
On mount:- Read
localStorage.serviceToken - If valid →
GET /user/verifyToken - Dispatch
LOGINwith user payload getSocket(user._id)for Socket.IO- If invalid → dispatch
LOGOUTwithisInitialized: true
<Loader /> until initialized.
login(email, password, isForceLogin?)
- Stores
res.data.data.loginToken - Updates context and connects socket
- Throws
error.response.dataon failure (used for MFA / force-login UI)
password field carries the 6-digit TOTP instead.
logout()
disconnectSocket(), hard redirect to /login.
Profile methods
Context value
register and resetPassword are legacy/stub implementations.