Files
jobtrackingapp/docs/redesign/audit/API_AND_IDENTITY.md
T
2026-09-09 19:29:39 +02:00

8.8 KiB
Raw Blame History

API integration and identity boundaries

Transport

api.ts is the shared Axios transport. Production uses /api; local development defaults to port 5202 unless NEXT_PUBLIC_API_BASE_URL overrides it. The value is embedded in the static build. All discovered direct frontend api/axios calls are in API_CALL_SITES; UI wrappers such as cvBuilder, aiWorkspace and applicationWorkspace are included. SDK OAuth/navigation and server-to-server provider calls are separate from that census.

Credentialed requests use the HttpOnly auth cookie and XSRF handling. B02 adds immutable session provenance, cancellation and late-response rejection. Downloads use authorized blob requests where required; B05 CSV bytes must not be decoded/re-encoded through Blob.text(). Error handling uses shared extraction plus screen-specific recovery. A new fetch/cache/form abstraction must preserve all of these behaviors.

Domain contract map

Paths are relative to /api. See the linked census for each method, interpolated ID and exact source line. DTOs are in frontend types, domain wrappers, and API controllers.

Frontend owner API groups Identity / mutation contract
Login/account/security cards /auth/config, /auth/me, login/register/reset/verification, /auth/profile, avatar, email-change, 2FA, sessions, language preferences Public challenge/setup entry versus authenticated self-account actions; client never chooses authoritative owner
Table/Kanban/edit/add /jobapplications, /board, choices, duplicate-check, status, restore; /companies and relationship Owner-scoped job/company lookup and associations; status changes and soft deletion distinct from creation intent
Capture/discovery /jobimport/preview, /job-discovery/search, saved-searches/results, Gmail suggested jobs Review/preview and create separate; B01 connection enforcement; saved searches belong to account
Personal analytics/reminders Dashboard/statistics call sites, reminders/rules, notification-settings Current-account reporting and dates; global/admin reporting separate
Full/overlay job workspace /jobapplications/:id/workspace, timeline, analysis, match, CV, tailoring, cover-letter, drafts, submitted-packages, checklist, interview-prep, follow-up Job owner boundary plus nested artifact IDs; workspace aggregate reads do not authorize child writes
Profile/evidence /career/profile, versions/restore, /career/evidence, /profile-cv/* Principal-owned singleton; extraction proposal review; history/projection distinct from CV overrides
CV library/editor /cv/* through cvBuilderApi, themes, outline, variant save/copy/history/publish/preview/export Private owner + resource ID; job association validates same owner; B03 admission shared with other PDF callers
Public CV Public-CV slug endpoints Anonymous access only through explicitly published variant; not arbitrary private ID download
Contextual AI /ai/usage, /jobapplications/:id/ai/modules, generate/history; profile and CV AI endpoints Server entitlement, context ownership/consent and quotas; UI accept step does not replace backend authorization
Documents /attachments/*, submitted-package attachments, PDF export Authorized upload/download/delete and scoped references; preserve content disposition and blob handling
Correspondence/mail /correspondence/*, /gmail/*, /microsoft-graph/*, /imap/*, /email/providers, message, drafts, send OAuth mailbox distinct from login; owner/job association, draft revision, send attempt/delivery state
Calendar /calendar/status, /calendar/jobs/:id/events, events.ics Owned job dates + provider permission; date-only and UTC timestamp semantics remain distinct
Operations/notifications /operations, cancel/retry, /notifications, read/dismiss Owner-scoped asynchronous work; rerender does not mean enqueue again
Export/lifecycle/billing /export/jobs, /export/account, /backup/encrypted, /account-lifecycle/*, /billing/status, checkout/portal Owner data; recent-auth/destructive/provider constraints; B05 at CSV boundary
Admin /users, /admin/audit, /admin/system and maintenance/email/AI subroutes Server Admin role; sensitive system views kept separate from personal workspace

No backend contract changes are proposed for Phase 1. API endpoint names and old route query values are compatibility surface even if new screen labels differ.

Authentication and authorization

Program.cs configures the smart authentication selector and local/provider validation. Local bearer or cookie JWT validation includes issuer/audience/signature/lifetime and a live local-session validation step. Production account-aware policies resolve authenticated identity before limiting. Relevant middleware order is forwarded headers/security/routing/CORS and CSRF handling, then authentication → authorization → rate limiter → B02 SessionContextMiddleware → controllers. Do not move owner limiting ahead of authentication during shell/API cleanup.

CurrentUserService derives local owner identity from the principal. Its background-owner scope cannot replace an HTTP request identity. JobTrackerContext uses live owner evaluation and fail-closed query filters. These are additional guards; not a license to remove explicit ownership checks from services or to introduce unscoped IgnoreQueryFilters() calls.

The CV service looks up id + owner and validates job associations with jobId + owner. Its explicit public lookup bypasses ordinary filters only for the published-slug path. Career Profile PUT derives the owner from current authentication and updates that singleton, explaining why B02 session provenance is separate from ID-based authorization. The old retained A form replay under B was not simply an IDOR. B02 now rejects retained/missing/forged session provenance server-side; the client also unmounts/aborts private state.

Admin controllers enforce Admin roles; Pro operations have server entitlement checks. The permissive default in AccountPlanContext is for isolated previews, while routed App supplies server-backed values. It is not proof that an ordinary user can obtain Pro server access. The frontend's auth/config and role-based navigation are presentation logic; a stale or crafted frontend must remain constrained by the API.

This is an integration map with targeted service verification, not a fresh claim that every authorization path in the application has been penetration-tested. Keep the permanent B01–B06 tests and original independent audit evidence.

State and storage map

State Current scope Preservation condition
Auth credential HttpOnly cookie; CSRF companion cookie Do not move tokens into browser storage or let client headers select owner
authUserKey, auth persistence preferences Browser identity marker/preferences Not an authoritative server identity; B02 handles account-generation change
authSessionContext storage signal Cross-tab change notification Immutable per page context; stale work aborts/reauthenticates, it does not adopt B's identity
Form/editor state and workspace tab cache React/component memory Dispose on B02 invalidation; preserve unsaved-navigation guard within one identity
Dashboard visibility dashboardPrefs:<owner> localStorage Owner-scoped, five booleans; not cross-device persistence
Saved job views, headline fallback, onboarding dismissal Owner-keyed localStorage Never rehydrate A's private view/draft data into B's page
Theme/language/sidebar collapse/table page size and columns Device/browser preferences (language also server-hydrated) These are presentation preferences, not private document caches
Pro notice dismissal Feature-keyed sessionStorage Presentation-only; no CV/account content, entitlement still server-derived
Mail drafts / application drafts / CV history Server persistence with domain-specific APIs Preserve each existing contract; do not replace with a generic browser draft mechanism

Sources: auth.ts, sessionBoundary.ts, App.tsx, SavedViewsMenu, DashboardView, ProfilePage, ProFeatureNotice. Any future cache must be account-scoped and must not replay mutations after the page's identity generation changes. Record revision conflicts, identity isolation and duplicate-creation idempotency remain three distinct contracts.