Commit Graph

7 Commits

Author SHA1 Message Date
Rob Colbert
896aff1b02 Fix User Settings persona display issue
- Switch frontend sign-in to /api/v1/auth/sign-in endpoint (includes persona)
- Add updateUser() to App context for proper state management
- Fix Settings.tsx save flow to use updateUser() instead of broken localStorage merge
- Remove unused web AuthController (gadget-code/src/controllers/auth.ts)
- Fix UserApiControllerV1 to return flat user object instead of double-wrapped
- Remove SessionType enum and references (dead code)
- Add proper server sign-out call before clearing local state

Resolves issue where User Settings view didn't display persona text even though it existed in the database.
2026-05-12 01:15:00 -04:00
Rob Colbert
009863cf2b fix: resolve drone heartbeat timeouts and JWT expiration bugs
This commit addresses two interrelated issues causing drones to
de-register and users to be forcibly signed out:

## Heartbeat Timeout Fixes

1. Move heartbeat interval to a Web Worker (not subject to browser
   tab throttling). Chrome throttles setInterval in background tabs
   to ~1/min, which causes the 19s heartbeat to miss the drone's
   timeout timer. The Web Worker fires reliably regardless of tab
   visibility.

2. Add visibilitychange handler: when the tab becomes visible again,
   send an immediate heartbeat to reset the drone's timer after any
   throttling that may have occurred.

3. Fix onReleaseSessionLock to clear the heartbeat timer. Previously,
   releasing the lock left the 60s timer running, causing a spurious
   timeout and status emit after the lock was already released.

4. Increase drone heartbeat timeout from 60s to 120s. With the Web
   Worker fix, heartbeats should be reliable, but doubling the timeout
   provides a generous safety margin.

5. Add socket disconnect/reconnect handlers on the drone side. On
   disconnect, clear the heartbeat timer. On reconnect, re-emit drone
   status so the platform knows the drone is alive.

6. Configure Socket.IO pingInterval/pingTimeout explicitly (25s/60s)
   instead of relying on defaults.

## JWT Expiration Fixes

1. Increase WebToken DB record expiration from 1 hour to 7 days. The
   1-hour expiration was the real session lifetime gate (the JWT crypto
   exp was already 24h), and it was far too aggressive for a dev tool.

2. Fix web /auth/renew-token endpoint to use req.user from the session
   cookie instead of verifyJsonWebToken(req.body.token). This eliminates
   the catch-22 where an expired token cannot be used to request its
   own renewal.

3. Fix token refresh response parsing. The API v1 renew-token endpoint
   returns { success: true, token } at the top level, but the frontend
   was looking for json.data?.token, causing every refresh to fail.

4. Add proactive token refresh: check the JWT exp claim before each
   request and refresh if expiring within 5 minutes. This avoids
   unnecessary 401 errors and the resulting socket disconnections.

5. Update socket JWT on token renewal via a callback registered in
   App.tsx. This ensures that future socket reconnections use the new
   token instead of the expired one.

## Files Modified

- gadget-code/frontend/src/workers/heartbeat.worker.ts (NEW)
- gadget-code/frontend/src/lib/socket.ts
- gadget-code/frontend/src/lib/api.ts
- gadget-code/frontend/src/App.tsx
- gadget-code/src/services/session.ts
- gadget-code/src/controllers/auth.ts
- gadget-code/src/services/socket.ts
- gadget-drone/src/gadget-drone.ts
2026-05-11 17:46:09 -04:00
Rob Colbert
190f424361 ensure apiKey is presented to required consumers 2026-05-10 08:25:17 -04:00
Rob Colbert
f353c2153a JWT processing fixed 2026-05-01 16:43:56 -04:00
Rob Colbert
404532012e move from Types.ObjectId to GadgetId (a string) 2026-05-01 14:31:00 -04:00
Rob Colbert
6ee25642b8 fixing imports to restore build
All relevant model interfaces now come from @gadget/api
2026-04-28 12:47:26 -04:00
Rob Colbert
1edc3a85b8 created by merging gadget-code and gadget-drone 2026-04-28 09:20:37 -04:00