Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
Multi-tenant biometric auth platform | Marmara University CSE4297 | Hexagonal Architecture

**Status**: Production deployed. Phases 0-8 complete. ~1,900+ tests. All services healthy.
**Last verified**: 2026-05-29 (2026-05-29: **Card detection client-only + true nano model + launcher/rebrand finish.** Card detection is now **CLIENT-ONLY** — the server `/biometric/card-detect` fallback was removed (web-app #111), so the in-browser ONNX model is the sole path and the bio container needs no card-path rebuild. The shipped card model is **Ayşenur's true 12.3 MB YOLOv8n (opset 12)**, integrated client- and server-side (web-app #109, biometric-processor #116) — replacing the old 51 MB YOLOv8m; user-verified detecting correctly and loading ~4× faster. `amispoof` got an **"Am I Spoof?"** display rebrand (launcher app-switcher tile + amispoof page hero/titles + landing labels; the domain stays lowercase `amispoof.fivucsas.com`). The shared suite-launcher rollout is **finished**, including the verify surface (landing + integrator explainer ONLY — NOT the active auth/login flow) and the authenticated app dashboard. MFA dark-mode "black box" code-input fix + auth-flow editing hardened to create-first (delete→create data-loss + dropped-default bugs) shipped in web-app #108. Marmara's default `APP_LOGIN` flow is now **PASSWORD + pick-one {EMAIL_OTP, TOTP, QR_CODE}** (prod DB; rollback runbook in identity-core-api/docs). Details in `PROJECT_STATUS_2026-05-29.md`. 2026-05-28: **Suite launcher unified + security backlog.** Redesigned shared `<fivucsas-launcher>` web component (web-app #103) — hosted at `app.fivucsas.com/launcher.js` (ships in web-app `public/` → Hostinger deploy), it is the ONE cross-site app switcher + global EN/TR toggle. Rolled out to `demo`, `docs` (+3 subpages: biometric/identity/sdk), `amispoof` (web-app #104 removed the amispoof auto-skip), and `landing`; deleted every site's bespoke "FIVUCSAS suite" cross-site bar + per-site EN/TR switch, incl. the dashboard TopBar toggle (Settings-page language `<select>` kept). One toggle drives `html[data-lang]` (static sites localize via `[data-lang]` CSS) and fires a `fivucsas:languagechange` CustomEvent → `i18n.changeLanguage` for the React surfaces (dashboard + verify share `web-app/src/i18n/index.ts`; landing listens in `App.tsx`). `links.fivucsas.com` keeps its own controls — it IS the hub. **api #111 (S13)**: TOTP used-code replay prevention — bounded ~120s Redis `SET key 1 EX NX` marker per `(userId, timeStep)`, max ~3 in-window markers/user, in-memory fallback capped 50k; NOT an infinite blacklist; enrollment keeps plain verify (legit retries). **web #102 (F13/F9)**: surfaced swallowed voice-enrollment errors via `formatApiError` + the `OTP_ATTEMPTS_EXHAUSTED` state. **F12** voice threshold verified CORRECT (verify = cosine *similarity* `>=` 0.65; search = pgvector `<=>` cosine *distance* `< 0.6`) — no change. **Prod rebuild + full-repo unmerged-work scan (2026-05-28 cont'd):** rebuilt `identity-core-api` (image was 2 weeks old) → deployed 8 merged-but-undeployed security fixes (S1/S2/S9/S11/S13/S14/F14 + the JWT-aud/MFA-fail-open bundle). The rebuild crash-looped ~11 min because `.env.prod` had `APP_SECURITY_JWT_AUDIENCE=` **blank** (an empty value OVERRIDES the `:fivucsas-api` default; #100 fails fast on blank in prod) — fixed to `fivucsas-api`, see api CLAUDE.md operator note. Docker build also needed api #112: `mvn dependency:go-offline` is now best-effort (a purged upstream `jackson-databind:*-SNAPSHOT` in the transitive closure broke it; the real `mvn package` resolves via the jackson-bom pin). Scanned ALL repos (most "unmerged" branches are squash-merge debris). **Merged:** FIVUCSAS #70 (redacted a still-live partial secret on master), web #94 (ws CVE DoS), bio #104/#108/#109, api #101 + #102 (rebased onto main + ArchUnit store re-frozen via Maven container) + #99 (**V61** `audit_logs.tenant_id NOT NULL` — self-gating: pre-checks 0 NULLs & fails loud, metadata-only ALTER; applies on the next api rebuild), bio #106 (mp.solutions→`mp.tasks.vision.FaceLandmarker` port, bakes `face_landmarker.task`). **Closed superseded:** spoof #18, FIVUCSAS #68, **bio #107** (mislabeled — deleted best.pt + repointed to a non-existent best.onnx, added no model). **Held (need work):** bio #105 (`liveness_errors.py` already on main + failing test → rebase), web #90 (server-validate puzzles — its 2 backend routes are unshipped, soft-passes on 404), spoof #54 (paper-section rebase + pilot-table integrity) + #56 (stacked on #54). Flagged NO-merge: spoof `learned-fuser` branch ("100% accuracy / ACER 0.00%" on a 120-video subset — reproducibility review before any paper use). **Card detection → CLIENT-ONLY** (web-app #106, made client-only in web-app #111): `useCardDetection` runs the YOLO model in-browser (onnxruntime-web, no server round-trip). The server fallback to identity-core-api `/biometric/card-detect` was REMOVED in #111 — the in-browser ONNX model is the only path. The deployed `web-app/public/models/yolo-card-nano.onnx` is now Ayşenur's TRUE **12.3 MB YOLOv8n** (opset 12), delivered + integrated via web-app #109 (client manifest/labels + bucket SHA256) and biometric-processor #116 (`best.onnx` in-repo, `best.pt` dropped). The biometric-processor container does NOT need a rebuild for the card model anymore (server card path removed). 2026-05-21: `links.fivucsas.com` hub — API tile → `/swagger-ui.html` with admin-IP "gated" badge (raw API root returned 401), Turkish i18n role-label fixes (English under `lang=tr` was İ-mangling Latin `i` under uppercase), team contact info, Ayşenur LinkedIn URL fix; poster author contact block + **regenerated A0 PDF/PNG** from `landing-website/public/poster/files/fivucsas-poster.html`; attribution — Ayşe Gülsüm Eren GitHub `@aysegulsum` + `marun.edu.tr` academic emails across `spoof-detector` + `practice-and-test` (forensic git-author records left intact); bilingual TR/EN switchers completed on `bys-demo`/`docs-site`/`verify-widget`. Consolidated into PR #69 → `master` (whole `fix/2026-05-12-bake-mini-fasnet-models` branch). NOTE: `api.fivucsas.com/` returns 401 by design (it's an API origin, not a page); Swagger/`/v3/api-docs`/`/actuator` are admin-IP gated (403 public), OIDC discovery is public (200). Carry-forward from 2026-05-12 / 2026-05-11: 11 PRs shipped across 5 repos + Flyway repair on prod, V59/V60 applied, branch protection on 6 branches, master/main reconciled, INVESTIGATION 2026-05-07 P1 residue closed, tenant onboarding playbook + 8 ADRs + docs/ hierarchy consolidated, spoof-detector blink cache + EAR recalibration paper-P0. **Added today**: parent PR #57 (poster suite: A0 default + 4 style variants compliant with CSE4198 §5.1) + parent PR #58 (archived 18 dated 2026-04/2026-05-04 docs into `archive/2026-05/{audits,plans,reviews,roadmaps,sessions}/`, tidied `.gitignore`); bio PR #99 (closed issue #91: 32 stale unit tests + 3 asyncio-fixture leaks fixed, no production code touched, module-scoped TestClient pattern documented for follow-ups); bio Dependabot #97/#98 in flight (rebased post-#99). Submodule pointer for biometric-processor bumped to post-#99 main.)
**Last verified**: 2026-05-30 (2026-05-30: **Auth program — cross-device / authenticator login.** SHIPPED + DEPLOYED: **passkey hybrid web login** (discoverable + usernameless; anonymous `POST /webauthn/passkey/authenticate-options` + `/passkey/authenticate`, **Flyway V72** adds `WebAuthnCredential.discoverable` + `user_handle`; "Sign in with a passkey" → browser-native hybrid QR, no app needed — THE cross-device answer; api #161, web #137); **no-Firebase number-matching approve-login** (Redis-backed `POST /auth/approve-login/session` → poll → authed-approver `/decide`; `matchNumber` is a zero-padded STRING; web initiator + client-apps approver shared KMP stack; api #161, web #137, client-apps #53); **NFC chip-trust** (api consumes bio `POST /nfc/verify-authenticity`, **fail-closed**), **serial canonicalization** (UPPERHEX-no-separators so mobile-enrolled cards match web verify), **guest-invite email EN/TR i18n** (api #159, bio #131); **mobile login fixes v5.2.3** (MFA-handoff flicker fix + the "server-200-flipped-to-failure" regression fix + UX, client-apps #44/#46/#52). Prod: api rebuilt + V72 applied; web → Hostinger (`index-B7OwE7r8.js`) + verify.fivucsas.com Docker (`index-BBN--UaC.js`, /login 200); rollback tag `identity-core-api-…:rollback-pre-passkeys-20260530`. **OPERATOR-BLOCKED at runtime:** ICAO CSCA roots (Turkey) must land in bio `NFC_CSCA_TRUST_DIR` before any SOD-carrying NFC client passes (serial-only unaffected). **OPEN:** a separate on-device mobile login bug (server 200 AUTHENTICATED, app shows "Verification failed") — needs the developer's debug-build adb logcat. **IN-FLIGHT (feature-flagged `app.auth.config-driven-login` default OFF, dark→staging→canary→broad):** config-driven login (password-as-a-factor + usernameless-in-flow + `GET /auth/login-config` + flow-builder) — internals NOT documented here yet, they land with their PRs. Full tracker: `ROADMAP_AUTH_2026-05-30.md`. 2026-05-29: **Card detection client-only + true nano model + launcher/rebrand finish.** Card detection is now **CLIENT-ONLY** — the server `/biometric/card-detect` fallback was removed (web-app #111), so the in-browser ONNX model is the sole path and the bio container needs no card-path rebuild. The shipped card model is **Ayşenur's true 12.3 MB YOLOv8n (opset 12)**, integrated client- and server-side (web-app #109, biometric-processor #116) — replacing the old 51 MB YOLOv8m; user-verified detecting correctly and loading ~4× faster. `amispoof` got an **"Am I Spoof?"** display rebrand (launcher app-switcher tile + amispoof page hero/titles + landing labels; the domain stays lowercase `amispoof.fivucsas.com`). The shared suite-launcher rollout is **finished**, including the verify surface (landing + integrator explainer ONLY — NOT the active auth/login flow) and the authenticated app dashboard. MFA dark-mode "black box" code-input fix + auth-flow editing hardened to create-first (delete→create data-loss + dropped-default bugs) shipped in web-app #108. Marmara's default `APP_LOGIN` flow is now **PASSWORD + pick-one {EMAIL_OTP, TOTP, QR_CODE}** (prod DB; rollback runbook in identity-core-api/docs). Details in `PROJECT_STATUS_2026-05-29.md`. 2026-05-28: **Suite launcher unified + security backlog.** Redesigned shared `<fivucsas-launcher>` web component (web-app #103) — hosted at `app.fivucsas.com/launcher.js` (ships in web-app `public/` → Hostinger deploy), it is the ONE cross-site app switcher + global EN/TR toggle. Rolled out to `demo`, `docs` (+3 subpages: biometric/identity/sdk), `amispoof` (web-app #104 removed the amispoof auto-skip), and `landing`; deleted every site's bespoke "FIVUCSAS suite" cross-site bar + per-site EN/TR switch, incl. the dashboard TopBar toggle (Settings-page language `<select>` kept). One toggle drives `html[data-lang]` (static sites localize via `[data-lang]` CSS) and fires a `fivucsas:languagechange` CustomEvent → `i18n.changeLanguage` for the React surfaces (dashboard + verify share `web-app/src/i18n/index.ts`; landing listens in `App.tsx`). `links.fivucsas.com` keeps its own controls — it IS the hub. **api #111 (S13)**: TOTP used-code replay prevention — bounded ~120s Redis `SET key 1 EX NX` marker per `(userId, timeStep)`, max ~3 in-window markers/user, in-memory fallback capped 50k; NOT an infinite blacklist; enrollment keeps plain verify (legit retries). **web #102 (F13/F9)**: surfaced swallowed voice-enrollment errors via `formatApiError` + the `OTP_ATTEMPTS_EXHAUSTED` state. **F12** voice threshold verified CORRECT (verify = cosine *similarity* `>=` 0.65; search = pgvector `<=>` cosine *distance* `< 0.6`) — no change. **Prod rebuild + full-repo unmerged-work scan (2026-05-28 cont'd):** rebuilt `identity-core-api` (image was 2 weeks old) → deployed 8 merged-but-undeployed security fixes (S1/S2/S9/S11/S13/S14/F14 + the JWT-aud/MFA-fail-open bundle). The rebuild crash-looped ~11 min because `.env.prod` had `APP_SECURITY_JWT_AUDIENCE=` **blank** (an empty value OVERRIDES the `:fivucsas-api` default; #100 fails fast on blank in prod) — fixed to `fivucsas-api`, see api CLAUDE.md operator note. Docker build also needed api #112: `mvn dependency:go-offline` is now best-effort (a purged upstream `jackson-databind:*-SNAPSHOT` in the transitive closure broke it; the real `mvn package` resolves via the jackson-bom pin). Scanned ALL repos (most "unmerged" branches are squash-merge debris). **Merged:** FIVUCSAS #70 (redacted a still-live partial secret on master), web #94 (ws CVE DoS), bio #104/#108/#109, api #101 + #102 (rebased onto main + ArchUnit store re-frozen via Maven container) + #99 (**V61** `audit_logs.tenant_id NOT NULL` — self-gating: pre-checks 0 NULLs & fails loud, metadata-only ALTER; applies on the next api rebuild), bio #106 (mp.solutions→`mp.tasks.vision.FaceLandmarker` port, bakes `face_landmarker.task`). **Closed superseded:** spoof #18, FIVUCSAS #68, **bio #107** (mislabeled — deleted best.pt + repointed to a non-existent best.onnx, added no model). **Held (need work):** bio #105 (`liveness_errors.py` already on main + failing test → rebase), web #90 (server-validate puzzles — its 2 backend routes are unshipped, soft-passes on 404), spoof #54 (paper-section rebase + pilot-table integrity) + #56 (stacked on #54). Flagged NO-merge: spoof `learned-fuser` branch ("100% accuracy / ACER 0.00%" on a 120-video subset — reproducibility review before any paper use). **Card detection → CLIENT-ONLY** (web-app #106, made client-only in web-app #111): `useCardDetection` runs the YOLO model in-browser (onnxruntime-web, no server round-trip). The server fallback to identity-core-api `/biometric/card-detect` was REMOVED in #111 — the in-browser ONNX model is the only path. The deployed `web-app/public/models/yolo-card-nano.onnx` is now Ayşenur's TRUE **12.3 MB YOLOv8n** (opset 12), delivered + integrated via web-app #109 (client manifest/labels + bucket SHA256) and biometric-processor #116 (`best.onnx` in-repo, `best.pt` dropped). The biometric-processor container does NOT need a rebuild for the card model anymore (server card path removed). 2026-05-21: `links.fivucsas.com` hub — API tile → `/swagger-ui.html` with admin-IP "gated" badge (raw API root returned 401), Turkish i18n role-label fixes (English under `lang=tr` was İ-mangling Latin `i` under uppercase), team contact info, Ayşenur LinkedIn URL fix; poster author contact block + **regenerated A0 PDF/PNG** from `landing-website/public/poster/files/fivucsas-poster.html`; attribution — Ayşe Gülsüm Eren GitHub `@aysegulsum` + `marun.edu.tr` academic emails across `spoof-detector` + `practice-and-test` (forensic git-author records left intact); bilingual TR/EN switchers completed on `bys-demo`/`docs-site`/`verify-widget`. Consolidated into PR #69 → `master` (whole `fix/2026-05-12-bake-mini-fasnet-models` branch). NOTE: `api.fivucsas.com/` returns 401 by design (it's an API origin, not a page); Swagger/`/v3/api-docs`/`/actuator` are admin-IP gated (403 public), OIDC discovery is public (200). Carry-forward from 2026-05-12 / 2026-05-11: 11 PRs shipped across 5 repos + Flyway repair on prod, V59/V60 applied, branch protection on 6 branches, master/main reconciled, INVESTIGATION 2026-05-07 P1 residue closed, tenant onboarding playbook + 8 ADRs + docs/ hierarchy consolidated, spoof-detector blink cache + EAR recalibration paper-P0. **Added today**: parent PR #57 (poster suite: A0 default + 4 style variants compliant with CSE4198 §5.1) + parent PR #58 (archived 18 dated 2026-04/2026-05-04 docs into `archive/2026-05/{audits,plans,reviews,roadmaps,sessions}/`, tidied `.gitignore`); bio PR #99 (closed issue #91: 32 stale unit tests + 3 asyncio-fixture leaks fixed, no production code touched, module-scoped TestClient pattern documented for follow-ups); bio Dependabot #97/#98 in flight (rebased post-#99). Submodule pointer for biometric-processor bumped to post-#99 main.)

## Architecture

Expand Down Expand Up @@ -123,6 +123,13 @@ FIVUCSAS/ # Parent repo (submodules)

PASSWORD | EMAIL_OTP | SMS_OTP | TOTP | FACE | VOICE | FINGERPRINT | HARDWARE_KEY | QR_CODE | NFC_DOCUMENT

**Cross-device login surfaces (2026-05-30, shipped):** **passkey hybrid login** (discoverable
WebAuthn mode — browser/OS resolves the user by `userHandle`, no app needed; folds into the
WebAuthn/HARDWARE_KEY method as its discoverable mode) and **approve-login** (no-Firebase,
number-matching, poll-based cross-device approval; companion to QR_CODE). The config-driven
login work (in-flight, feature-flagged) will surface PASSKEY + APPROVE_LOGIN as selectable
Layer-1 methods in the flow builder — see `ROADMAP_AUTH_2026-05-30.md`.

## Architectural direction (2026-04-16)

**Hosted-first auth.** Primary integration mode is redirective OIDC: tenants call `FivucsasAuth.loginRedirect({...})` → user redirected to `verify.fivucsas.com/login` → MFA → browser returns with `?code=…&state=…` → tenant exchanges at `/oauth2/token`. Widget iframe remains for **inline step-up MFA** only. See `web-app/docs/AUDIT_REPORT_2026-04-16.md` and `web-app/docs/plans/HOSTED_LOGIN_INTEGRATION.md` (PR-1).
Expand Down
4 changes: 4 additions & 0 deletions ROADMAP.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# FIVUCSAS — Product Roadmap

> **Auth program (cross-device / authenticator / config-driven login):** see the consolidated
> tracker `ROADMAP_AUTH_2026-05-30.md` (shipped passkey hybrid login + approve-login + NFC
> trust + mobile v5.2.3; in-flight feature-flagged config-driven login; operator + backlog items).

> Last updated / verified: 2026-05-30 — **stabilize-&-harden backlog COMPLETE** (see "Stabilize & harden — COMPLETE 2026-05-30" directly below) **plus** the same-day Identity & account-linking (Phases 1-5) + ROOT role/user_type unification ship (section after it). Prior 2026-05-29 admin-walkthrough wave (9 PRs) + the 2026-05-12 wave (11 PRs) + the phase-A/B/C/I closures remain valid below. Verbose tier breakdown: `archive/2026-05/reviews/INVESTIGATION_MASTER_2026-05-07.md`.

## Stabilize & harden — COMPLETE 2026-05-30
Expand Down
Loading
Loading