[eve-login] Phase 5 — Frontend (token client) #5

Closed
opened 2026-06-25 18:17:00 +02:00 by Sirttas · 0 comments
Owner

Part of Login with EVE Online. (Planning docs removed — this issue is the source of truth.)

Depends on: eveal/mammon#5, eveal/mammon#6, eveal/mammon#7 (Phases 2–4) · Blocks: nothing (final)

Goal

Wire gemory to the token auth: hold a short-lived access token in memory, attach it as a bearer header, silently refresh, log in/out, and gate routes. No dev proxy — call mammon cross-origin with CORS.

Cross-origin (no proxy)

  • gemory (:3000) calls mammon (:8080) directly; CORS is configured in Phase 4 (bearer API + credentialed /refresh).
  • The OAuth round-trip runs on the mammon origin: button → window.location = {mammon}/oauth2/authorization/esi → EVE → {mammon}/callback (sets the refresh cookie) → 302 back to gemory.
  • EVE redirect-uri points at mammon — dev http://localhost:8080/callback (already configured); prod https://api.eveal.space/callback (register this in the EVE dev portal — the one external step). No more :3000/callback/proxy.

Scope

  1. axios (mammonAxiosInstance): base URL = VITE_MAMMON_URL (mammon origin); withCredentials: true (so /refresh sends the cookie — bearer calls won't carry it since it's Path=/refresh). Request interceptor adds Authorization: Bearer <in-memory access token> when present.
  2. Access token in memory only (module var / Pinia state, not localStorage).
  3. Auth store (Pinia auth/auth.ts): user, characters, isAuthenticated.
    • refresh(): POST /refresh200 store access token + authed; 401 → logged-out (no console error).
    • fetchMe(): GET /meuser + characters.
    • On boot (main.ts): refresh() then fetchMe().
    • logout(): POST /logout, clear in-memory token + state, route home.
  4. Silent refresh: response interceptor — on 401 from an API call, call POST /refresh once and retry the original request with the new token; if /refresh 401 → clear state + trigger SSO login.
  5. Login / add-character button (full-page nav): logged-out → window.location = {mammon}/oauth2/authorization/esi ("Login with EVE Online"); logged-in → "Add character" → the authenticated add-character initiation (Phase 2 mechanic) then nav. Backend returns to a fixed gemory route; that view runs refresh() + fetchMe().
  6. Router guard: protected routes → if !isAuthenticated after boot, redirect to login. Keep public pages open (match Phase 4 permit-list).
  7. Character selection is frontend-only routing — no backend "active character".

Acceptance criteria

  • Login → EVE SSO → back to gemory logged in; /refresh yields an access token; /me populates. Reload re-bootstraps (refresh cookie persists ≤8h).
  • A bearer API call works cross-origin; on 401 → silent /refresh → retry succeeds.
  • Add character from a live session → appears under the same user.
  • Logout → in-memory token + store cleared, /refresh401, protected routes redirect.
  • No Vite proxy; access token lives only in memory (not localStorage).

Notes to record when done

  • The prod redirect-uri/CORS origin; anything that needed a late backend change (link back to the relevant mammon issue).
Part of **Login with EVE Online**. (Planning docs removed — this issue is the source of truth.) **Depends on:** `eveal/mammon#5`, `eveal/mammon#6`, `eveal/mammon#7` (Phases 2–4) · **Blocks:** nothing (final) ## Goal Wire gemory to the token auth: hold a short-lived access token **in memory**, attach it as a bearer header, silently refresh, log in/out, and gate routes. **No dev proxy** — call mammon cross-origin with CORS. ## Cross-origin (no proxy) - gemory (`:3000`) calls mammon (`:8080`) directly; CORS is configured in Phase 4 (bearer API + credentialed `/refresh`). - The OAuth round-trip runs on the **mammon** origin: button → `window.location = {mammon}/oauth2/authorization/esi` → EVE → `{mammon}/callback` (sets the refresh cookie) → `302` back to gemory. - **EVE `redirect-uri` points at mammon** — dev `http://localhost:8080/callback` (already configured); prod `https://api.eveal.space/callback` (**register this in the EVE dev portal** — the one external step). No more `:3000/callback`/proxy. ## Scope 1. **axios** (`mammonAxiosInstance`): base URL = `VITE_MAMMON_URL` (mammon origin); `withCredentials: true` (so `/refresh` sends the cookie — bearer calls won't carry it since it's `Path=/refresh`). Request interceptor adds `Authorization: Bearer <in-memory access token>` when present. 2. **Access token in memory only** (module var / Pinia state, **not** `localStorage`). 3. **Auth store** (Pinia `auth/auth.ts`): `user`, `characters`, `isAuthenticated`. - `refresh()`: `POST /refresh` → `200` store access token + authed; `401` → logged-out (no console error). - `fetchMe()`: `GET /me` → `user` + `characters`. - **On boot** (`main.ts`): `refresh()` then `fetchMe()`. - `logout()`: `POST /logout`, clear in-memory token + state, route home. 4. **Silent refresh:** response interceptor — on `401` from an API call, call `POST /refresh` once and retry the original request with the new token; if `/refresh` `401` → clear state + trigger SSO login. 5. **Login / add-character button** (full-page nav): logged-out → `window.location = {mammon}/oauth2/authorization/esi` ("Login with EVE Online"); logged-in → "Add character" → the authenticated add-character initiation (Phase 2 mechanic) then nav. Backend returns to a fixed gemory route; that view runs `refresh()` + `fetchMe()`. 6. **Router guard:** protected routes → if `!isAuthenticated` after boot, redirect to login. Keep public pages open (match Phase 4 permit-list). 7. **Character selection is frontend-only routing** — no backend "active character". ## Acceptance criteria - [x] Login → EVE SSO → back to gemory **logged in**; `/refresh` yields an access token; `/me` populates. Reload re-bootstraps (refresh cookie persists ≤8h). - [x] A bearer API call works cross-origin; on `401` → silent `/refresh` → retry succeeds. - [x] Add character from a live session → appears under the same user. - [x] Logout → in-memory token + store cleared, `/refresh` → `401`, protected routes redirect. - [x] No Vite proxy; access token lives **only in memory** (not `localStorage`). ## Notes to record when done - The prod `redirect-uri`/CORS origin; anything that needed a late backend change (link back to the relevant mammon issue).
Sirttas added a new dependency 2026-06-25 18:19:43 +02:00
Sirttas added a new dependency 2026-06-25 18:19:48 +02:00
Sirttas added a new dependency 2026-06-25 18:19:52 +02:00
Sirttas changed title from [eve-login] Plan 5 — Frontend + dev proxy to [eve-login] Phase 5 — Frontend + dev proxy 2026-06-25 18:35:40 +02:00
Sirttas changed title from [eve-login] Phase 5 — Frontend + dev proxy to [eve-login] Phase 5 — Frontend (token client) 2026-06-25 22:01:57 +02:00
Sirttas referenced this issue from a commit 2026-06-28 14:18:11 +02:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Depends on
You do not have permission to read 4 dependencies
Reference: eveal/gemory#5