Files
tesla-roadtrip/server/routes/owner.ts
T
tony f793b526aa fix(security): owner auth gate, OAuth state cookie binding, 0600 token perms
- Add OWNER_SECRET-based session: signed HMAC cookie, /api/auth/owner login,
  requireOwner middleware. All Tesla routes refuse 401 without it.
- Bind OAuth state to a SameSite=Lax httpOnly cookie at /start, validate
  match in /callback with constant-time compare. Refuses unmatched callbacks.
- Token store now mkdir 0700, writeFile + rename atomic, mode 0600 with
  defensive chmod. Owner-only on disk.
- VIN masked to last 4 in responses; partner-register no longer echoes raw
  Tesla body to clients; coord bounds checked on send-to-nav.
- Client: useTesla also tracks owner status; Connect Tesla button opens an
  OwnerLoginModal when not authenticated, then continues to Tesla OAuth.

Conscious deferrals:
- Explicit CSRF tokens on POST routes: mitigated by SameSite=Lax cookies
  + same-origin CORS. Will revisit if cross-origin clients land.
- At-rest token encryption: deferred for single-user app; tokens are on a
  0700 Dokku volume readable only by the app uid. Will add AES-GCM if we
  multi-tenant.
2026-05-31 22:32:22 +01:00

39 lines
916 B
TypeScript

import { Router } from 'express';
import { env } from '../config/env.js';
import {
clearOwnerCookie,
isOwnerAuthenticated,
setOwnerCookie,
verifyOwnerSecret,
} from '../lib/ownerAuth.js';
const router = Router();
router.get('/api/auth/owner/status', (req, res) => {
res.json({
authenticated: isOwnerAuthenticated(req),
required: !!env.ownerSecret,
});
});
router.post('/api/auth/owner', (req, res) => {
if (!env.ownerSecret) {
res.status(503).json({ ok: false, reason: 'owner_auth_not_configured' });
return;
}
const { secret } = (req.body || {}) as { secret?: unknown };
if (!verifyOwnerSecret(secret)) {
res.status(401).json({ ok: false, reason: 'invalid_secret' });
return;
}
setOwnerCookie(res);
res.json({ ok: true });
});
router.post('/api/auth/owner/logout', (_req, res) => {
clearOwnerCookie(res);
res.json({ ok: true });
});
export default router;