chore(merge): reconcile master into main (session 2026-05-11)#51
Merged
Conversation
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Update CLAUDE.md with CI/CD info, shared infrastructure, Vite 8 - Update README.md status to Production - Update submodule pointers for docs, web-app, biometric-processor Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- identity-core-api: 3 domain ports + 3 adapters, services use ports not JPA - biometric-processor: FP endpoints → 501, voice async thread pool, HNSW script - client-apps: iOS TokenStorage, Desktop storage, tenantId + X-Tenant-Id header - web-app: widget SDK fixes (URL params, sandbox, postMessage origin) - scripts: test-health.sh, test-crud.sh, test-rbac.sh (1,311 lines) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Update tenant: remove `slug` field from PUT body (not in UpdateTenantRequest DTO)
- Update role: replace `tenantId` with `active` field (match UpdateRoleRequest DTO)
- Create auth flow: use tenant-scoped endpoint /api/v1/tenants/{id}/auth-flows
with authMethodType string instead of authMethodId UUID (match CreateAuthFlowCommand)
- Fix all auth-flow read/update/delete paths to use tenant-scoped URLs
- Add 1s sleep between login calls in RBAC script to avoid rate limiting
- Fix RBAC privilege escalation test to use correct UpdateRoleRequest fields
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Mark Phase 7 (Client Integration Story) as complete in ROADMAP_V2.md. Update docs submodule with INTEGRATION_GUIDE.md and demo/third-party-demo.html. Old Phase 7 (iOS + Desktop) renumbered to Phase 8. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Phase 6: pure domain models (User/Tenant/Role/Permission), mappers, V25 RLS - Phase 7: integration guide, Acme Bank demo, roadmap updated - Fix: Unicode name validation, CSP frame-ancestors, CORS biometric-api - Fix: liveness frame count, redux-persist CJS interop Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- NFC: browser-specific message + role-based buttons - Widget demo + Developer portal: mobile responsive - i18n: WidgetDemoPage (44 keys) + DeveloperPortalPage (8 keys) translated - Settings: avatar upload + weekly reports disabled as "Coming soon" - CORS: fixed env var name (CORS_ALLOWED_ORIGINS → CORS_ORIGINS) - CSP: frame-ancestors 'self' for widget iframe Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Widget Demo + Developer Portal restricted to admin roles - Hardware key enrollment: FIDO2 requirement info alert - Login page: biometric methods behind "More options" toggle - Card detection: display class_name from YOLO model - Theme tokens for password icon (no hardcoded colors) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
FIVUCSAS evolves from authentication-only to full Identity Verification Platform (IVP). Phase 8 adds 5 sub-phases (8A-8E) covering verification schema, document processing (YOLO + Tesseract OCR), face-to-document matching (DeepFace), admin UI with flow builder, and advanced integrations. Includes 7 Turkish industry templates (BDDK Banking KYC, SGK Healthcare, YOK Education, e-Devlet Government, TCMB Fintech, BTK Telecom, Gig Economy). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
V26 migration applied, 6 API endpoints live, 5 industry templates. 22 files, 941 lines of new code. identity-core-api healthy. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
13-section architecture document covering unified flow engine, verification step types, industry templates, database schema, API contracts, security, compliance, and implementation roadmap. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…eployed - biometric-processor: 5 verification endpoints (document-scan, data-extract, face-match, liveness-check, pipeline/test) + MRZ parser - identity-core-api: 9 step handlers, handler registry, biometric client, orchestrated pipeline execution Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- VerificationFlowBuilderPage, VerificationDashboardPage - VerificationSessionDetailPage, TemplateSelector - VerificationRepository + useVerification hook - Sidebar items + routes (admin-only) - i18n keys for EN/TR Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- RLS: SET LOCAL app.current_tenant_id wired via AOP - Liveness: explicit multipart/form-data header (415 fix) - Phase 6: User/Role/Permission domain repos + 3 services migrated - E2E: 28 Playwright tests for verification pages Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Comprehensive test script for the verification pipeline covering: - Identity API: templates, sessions, step submission, user status - Biometric Processor: document-scan, data-extract, face-match, liveness - MRZ parsing: TD3 passport and TD1 ID card ICAO test cases - Auto-detects Docker container IPs for direct access on Hetzner Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
… test script - BiometricProcessorClient: removed double /api/v1 prefix (was 404) - V27 migration: 3 VERIFICATION flows seeded (Simple, Healthcare, Fintech) - scripts/test-verification.sh: 13/13 tests pass - All verification endpoints confirmed working in production Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…s fixed - client-apps: GitHub Actions APK build workflow (debug + release) - biometric-processor: Tesseract OCR for TC Kimlik + video interview upload - identity-core-api: VideoInterviewHandler + admin review endpoint + V28 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
All phases 0-8 are now complete. Updated status markers, test counts, migration versions (V1-V28), and completion dates across all docs. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- All screens wired to real backend (Face, Voice, TOTP, Dashboard, Profile)
- Dashboard API path fix + StatisticsDto alignment
- Profile editing wired to PUT /users/{id}
- Debug APK (54MB) + Release APK (33MB) built and released
- ProGuard fix for SLF4J
- GitHub Release: v1.0.0-debug
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Parent CLAUDE.md: APK v1.0.0 released, mobile apps 90% - identity-core-api: verification pipeline details, Flyway V1-V28 summary - biometric-processor: Phase 8B/8C verification endpoints documented - client-apps: submodule pointer updated - All phases 0-8 complete, 103 API + 28 Playwright + 304 unit tests Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- docs: Step-up auth guide for mobile integration (3 endpoints, Android Keystore examples) - scripts: cloudflare-tunnel.sh for routing biometric-processor through local GPU Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Fixed 7 test files for API drift, all 90 shared unit tests pass - Desktop kiosk mode: --kiosk flag, fullscreen, password-protected exit - Desktop compilation verified - SLF4J ProGuard rule for release APK builds Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Audit Tools Installed: Semgrep, Trivy, Hadolint, ShellCheck Custom Review Commands: /security-audit, /arch-review, /test-gaps, /docker-review, /perf-review Critical (8/9 fixed): - Spring Boot 3.4.5→3.4.7, Security→6.4.13, Tomcat→10.1.53, Netty→4.1.132 - PostgreSQL JDBC→42.7.7, Commons-IO→2.21.0 - JWT tokens removed from settings, shell injection fixed - 1 remaining: CVE-2026-22732 awaits upstream Spring Security 6.5.x High (34/34 fixed): - All dependency CVEs resolved via Spring Boot upgrade - Docker: no-new-privileges on all services, read_only where safe - Nginx: security headers fixed in location blocks Medium (19/19 fixed): - SRI integrity hashes on CDN scripts - Dockerfile consolidation and --no-install-recommends - Python 3.13: imghdr→magic byte detection - Template literals in auth-test Full report: docs/audit/AUDIT-2026-03-31.md Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Updates identity-core-api and web-app submodule pointers for enrollment page fixes: status auto-complete, face mobile UX, WebAuthn delete, floating Snackbar, human-readable messages, TOTP/WebAuthn records. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
fix(landing): docs CTA → docs.fivucsas.com; bump web-app submodule
Submodule bump a4c0053 → 70a4c06 to pull in Rollingcat-Software/web-app#25 (Scope B UI refresh for verify-app). - HostedLoginApp / VerifyApp / LoginMfaFlow visuals only; every OAuth handler, postMessage event, frame-bust effect, step component, SDK byte, CSP header preserved. - verify-widget/html/index.html regenerated by sync-assets.sh so the Docker image picks up the new bundle hashes. - fivucsas-auth.js SDK untouched — sha384 on live matches staged copy, bys-demo + every external integrator's SRI hash stays valid. Deploy: 3-step sync ran (build:verify → sync-assets.sh → docker compose up -d --build verify-widget). verify.fivucsas.com/ and /login → 200. 56/56 verify-app tests green; 608/608 full suite green. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
chore(web-app): bump submodule to Scope B — verify.fivucsas.com refresh
- Heading for 2026-04-22 Scope B entry was tagged "[2026-04-22b]", which
is not ISO 8601 and contradicts this file's opening convention. Tag
changed to plain "[2026-04-22]" — the Scope B scope is already in the
title after the em-dash, and the Scope A section on the same date
keeps its own distinct title ("landing, web-app shell, BYS demo").
Both are valid ISO dates under distinct titles.
- Step-component count: the LoginMfaFlow bullet said "every one of the
10 step components" then parenthetically listed 11 entries. Prose now
matches the list (11).
Pure doc cleanup; no submodule or code change.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
docs(changelog): address PR #31 Copilot nits (ISO date + step count)
Parent-repo bundle for SEO round 3 (landing + demo + web-app): - landing-website/index.html: expand robots meta + hreflang alternates. - bys-demo/index.html: flip noindex → index, follow (per user review — it's a public integration showcase). Title reframed to lead with FIVUCSAS (not Marmara). New WebPage JSON-LD positions it as a demo of the FIVUCSAS SoftwareApplication, reducing Google-confusion risk. - bys-demo/robots.txt: sitemap pointer. - bys-demo/sitemap.xml: new, single URL for demo home. - web-app submodule 70a4c06 → 12c5cbc: pulls in PR #26 (verify-app Copilot nits) + PR #27 (app.fivucsas.com indexable with per-route X-Robots-Tag defense-in-depth). Zero code change in the landing SPA bundle — only HTML meta + JSON-LD additions. bys-demo auth JS untouched (SDK SRI hash stays valid). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
All six Copilot comments resolved: 1. bys-demo/test-elements.html: added <meta name="robots" content="noindex, nofollow"> in addition to the robots.txt Disallow — Disallow only blocks crawling; without a noindex directive the URL can still appear in search results if discovered elsewhere. 2. CHANGELOG: [2026-04-22c] → [2026-04-22] (ISO 8601 compliant); scope marker "(round 3)" moved into the title text, matching this file's "dates are in ISO 8601" opening convention. 3. landing-website/index.html googlebot meta: was only "index, follow" while the general robots tag had "max-image-preview:large, max-snippet:-1, max-video-preview:-1". Google's behaviour is to narrow to the googlebot-specific tag when present, so the max-* directives weren't applying for Google. Mirrored them in the googlebot meta. 4. bys-demo/index.html googlebot meta: same fix — mirror the robots directives. 5. landing-website/index.html canonical + og:url inconsistency: canonical uses trailing slash but og:url and the four JSON-LD `url` fields were bare. Normalised all to trailing slash so shared/indexed URLs match. 6. bys-demo/index.html JSON-LD comment: said "TechArticle-style" but the actual @type is WebPage. Comment reworded to match. All doc / meta / comment hygiene; no code path touched. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
feat(seo): landing hreflang + bys-demo indexable + web-app SEO bump
Audit of actual endpoint counts against the landing's "180+ API endpoints" claim: identity-core-api @*Mapping methods: 174 biometric-processor FastAPI routes: 111 total: 285 "180+" was defensibly truthful but undersells the platform by a wide margin. "250+" is still conservative (actual is 285) while more accurately signalling the real API surface area. No other stat needed adjustment — "10 auth methods" ✓, "1,800+ tests" ✓ (793 identity-core + 608 web-app + ~425 client-apps + 27 Playwright + ML ≈ 1,850+), "3 microservices" ✓ (matches the three service cards). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
fix(content): landing endpoint stat 180+ → 250+ (audit)
The crest SVG (mu-crest in the BYS demo hero) rendered the sub-wordmark as plain ASCII "UNIVERSITESI". The correct Turkish form carries diacritics on every vowel: "ÜNİVERSİTESİ". Discovered during a full Turkish-char sweep across every live surface. This was the only remaining ASCII-only Turkish string. All other surfaces (rollingcatsoftware.com, fivucsas.com, app.fivucsas.com, demo.* other pages, verify.fivucsas.com, geleceginadanasi.com.tr) are clean. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
fix(bys-demo): crest UNIVERSITESI → ÜNİVERSİTESİ
Google currently autocorrects "FIVUCSAS" to "fivics" (archery brand).
Goal: rank for the literal brand token by surfacing the acronym + its
expansion in every signal Google uses for query understanding.
- index.html: <title> + og/twitter title & description now include the
full acronym expansion "Face and Identity Verification Using
Cloud-based SaaS". Organization + WebSite JSON-LD gain alternateName
pointing at the same expansion (schema.org/alternateName is the
canonical mechanism for acronym-vs-expansion disambiguation).
- App.tsx hero: H1 now leads with the literal token FIVUCSAS as a
gradient first line, subtitle moved underneath ("Face & Identity
Verification Platform" + Turkish equivalent). A visible plain-text
acronym subline is added directly under the lede paragraph so
on-page text explicitly defines what FIVUCSAS expands to (in both
EN and TR via i18n).
- sitemap.xml: expanded from one URL to seven public surfaces (root,
app root + login + register + developer-portal + widget-demo, and
demo.fivucsas.com) with 2026-05-11 lastmod and weekly changefreq.
Notes (vs. task spec):
- og:url, canonical, hreflang en/tr, robots meta, and robots.txt were
already correct on master — no diff needed for those.
- The "Try Admin Dashboard" stale rollingcatsoftware.com URL has
already been removed from App.tsx in an earlier refactor.
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds workflow_dispatch so the landing-site deploy can be retried manually without making a no-op landing-website change. Self-hosted broker has stalled job dispatch before; a manual re-trigger path is operationally useful. Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Self-hosted runner had a stuck broker session conflict that blocked PR #43's deploy from dispatching. web-app's deploy-hostinger.yml already runs on ubuntu-latest with the same HOSTINGER_SSH_KEY secret and works reliably; aligning landing deploy to the same pattern. Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
docs.fivucsas.com serves the FIVUCSAS API Documentation (Spring Boot springdoc-generated, brand-positive — 12 mentions of FIVUCSAS on the page). It's reachable, indexable (X-Robots-Tag header was removed earlier today when we split noindex out of secure-headers), and worth crawling for brand discoverability. Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…47) Bing Webmaster Tools' URL Inspection on https://fivucsas.com/ flagged two SEO issues on the static HTML payload (Bingbot doesn't fully execute the Vite SPA's JS): 1. "H1 tag missing" — no <h1> in initial HTML (React renders it into #root post-hydration, but crawlers don't see it). 2. "Meta Description too long or too short" — 184 chars vs Bing's 150-160 sweet spot. This commit: - landing-website/index.html: trims description / og:description / twitter:description from 184 → 155 chars with the full acronym expansion at the front; adds a static visually-hidden <h1> in <body> outside #root carrying the full brand+expansion so crawlers see it in the initial HTML response. - landing-website/README.md: H1 brand-anchor refresh + "SEO" section documenting why the static H1 + JSON-LD + trimmed description live in index.html (Vite SPA crawler-visibility constraint). - CHANGELOG.md: SEO round 4 entry covering this session's full sweep — landing static-H1, Traefik noindex split, IN-H2 router-precedence fix, Uptime Kuma monitor #3 repoint, sitemap +docs.fivucsas.com, identity-core-api gitleaks placeholders, submodule README + repo- description brand anchors, portfolio card, profile README, deploy- landing.yml runner switch. 16 PRs merged this round. - CLAUDE.md: Production URLs table — Swagger annotated as admin-IP-gated (IN-H2 router-precedence fix made it correctly enforce for the first time since 2026-04-19). - Submodule pointers: bump biometric-processor / client-apps / docs / identity-core-api / practice-and-test / web-app / spoof-detector to current origin/<default> so the parent records the merged READMEs, brand-anchor commits, and the identity-core-api Traefik label change (noindex@file middleware attachment). Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* docs(roadmap): refresh — supersede 2026-04-20 phase-A/B-centric version Replace the 3-week-stale roadmap with current state. Phase A (lint), Phase B (Dependabot security), Phase C wave-0 ops hardening, Phase I Android 13/13, and 2026-04-30 senior-review remediation are all closed. Active waves now framed against: - INVESTIGATION 2026-05-07 6-lens audit (10 P0 + ~25 P1 + ~50 P2/P3) with 10 P0 closed same-day and ~12 P1 closed by 7ee52de batch 2026-05-08 - Ops + DB hygiene from SENIOR_DB Appendix C + CICD_AUDIT_2026-05-04 - Documentation / DX backlog per DOC_AUDIT_2026-05-04 T4.12 - spoof-detector paper push (BIOSIG / IJCB 2026 target) Branch state documented (master vs main divergence + submodule HEADs). Operator-only queue separated from agent-actionable work. Legacy Phase 1-7 content archived. Cross-links to canonical source-of-truth docs (INVESTIGATION_MASTER, ROADMAP_OPTIMIZED_2026-05-04, CICD_AUDIT, SENIOR_DB_REVIEW Appendix C, spoof-detector/ROADMAP.md). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * chore(submodules): bump api+bio+docs+spoof-detector — 2026-05-11 session batch Bumps following today's parallel-agent session merging 9 PRs across the submodule mainlines: - api 6b17e0e → 606f1f4 * #96 chore(handlers+purge) — confirm dev-gate annotations on AddressProofHandler + WatchlistCheckHandler; flip APP_PURGE_SOFT_DELETE_ENABLED default-on in application-prod.yml (GDPR Art. 17). +5 tests. * #97 feat(nfc) — wire bio mrz_parser into NfcController via new POST /api/v1/nfc/verify-mrz. Document number masked to last-4 in audit log + response (PII). +7 tests. * #98 feat(db) — V59 audit_logs.tenant_id backfill from users JOIN + sentinel UUID for remaining NULLs; V60 DROP refresh_tokens.token plaintext column (T+7d soak elapsed since PR #71). RefreshToken.token demoted to @transient (preserves 5 wire-token call sites). +7 tests. - bio 6f69a7d → 750492c * #94 feat(quality+liveness) — real occlusion detector (270 LOC): eye-variance 120 / mouth-variance 130 / CIE-Lab ΔE 18 thresholds. Anti-spoof contradiction policy spot-check confirmed 2026-05-08 LIVENESS_VERDICT_POLICY=conservative already vetoes correctly. +15 tests. * #95 feat(nfc) — new POST /api/v1/nfc/mrz route exposing mrz_parser.py with DG1 bytes b64 decoding for future ICAO chip-read. +10 tests. - docs ed4dd25 → 78a9b4a * #13 — tenant onboarding playbook (DX-first, 215 lines) + 8 ADRs (572 lines covering hosted-first OIDC / pgvector / MobileFaceNet removal / Facenet512 server-authoritative / RFC 6749 §10.4 family-revoke / V53 BEFORE-DELETE / Persistable<UUID> refresh tokens / spoof-detector standalone) + hierarchy consolidation (14 git mvs, 4 empty dirs removed, 4 broken links fixed, Runbooks table cross-linking /opt/projects/infra/). - spoof-detector abc7f05 → cc73cf0 * #10 perf(blink) — per-frame FaceLandmarker cache (3.0x at 3 faces, 4.9x at 5; blink-stage FPS 9.8→28.9) + EAR threshold recalibration (0.20→0.18, clean 60s fixture: 17bpm in target band). +13 tests (126→139 green). Adds spoof-detector to .gitmodules — was extracted on `main` (commit a6ac35a) but not yet on `master`. This commit brings the SEO branch in line. Audit-delta-before-rebuild: api was at 5add915 in last image (2026-05-08 20:03 UTC); HEAD now at 606f1f4 (15+ commits including today's 3 PRs). bio was at 31a2667 in last image (2026-05-09 11:15 UTC); HEAD now at 750492c (3+ commits including today's 2 PRs). Operator must rebuild both containers post-merge. Per memory feedback_no_code_loss_during_restructure.md: every PR was opened FIRST, merged with admin bypass (1-review branch protection enabled today via PR #48), no in-flight unique code remains. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(changelog): 2026-05-11 session — 9 PRs across 5 repos + 5 tracks closed Single comprehensive entry summarizing today's parallel-agent session: - INVESTIGATION 2026-05-07 P1 residue (NFC MRZ wiring, occlusion impl, anti-spoof verify, dev-gate confirmations, purge default-on) - Ops + DB hygiene (V59 audit_logs tenant_id backfill, V60 drop refresh_tokens.token plaintext, branch protection, Flyway repair runbook) - Docs DX backlog (tenant onboarding playbook + 8 ADRs + hierarchy consolidation) - spoof-detector paper P0 (blink cache + EAR recalibration) - ROADMAP refresh Operator deliverables and audit-delta-before-rebuild evidence captured. Follow-up queue: bio test-suite rot (79 baseline failures), master/main reconciliation, biometric-processor README broken links. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Merge origin/master into origin/main to converge the two divergent lineages. master has been the active integration branch since the 2026-04-19 audit; main accumulated parallel work from the spoof-detector restructure, branch protection rollout (PR #48), and the 2026-05-04 through 2026-05-09 investigation waves. Reconciliation rules applied: - ROADMAP.md, CHANGELOG.md, .gitmodules: master wins (canonical) - Submodule pointers: master wins (latest HEADs) - identity-core-api -> 606f1f4 - biometric-processor -> 750492c - docs -> 78a9b4a - spoof-detector -> cc73cf0 - web-app -> 096ed05 - client-apps -> 5ab3abb - CICD_AUDIT_2026-05-04.md: preserved from main (PR #48 added 91 lines of branch-protection evidence; master never had this file) - archive/2026-04-pre-roadmap-2028/: master deleted; honor that (rename-to-archive on main + delete-on-master => take delete) - All 2026-05 dated investigation/audit docs on main: preserved (forward historical record) - .env.example, CLAUDE.md, .github/workflows/deploy-landing.yml, .gitignore: take main's content (main carries newer BE-H1 RS256 defaults, MTCNN/Facenet512 architecture notes, ubuntu-latest runner, archive/ tracked instead of ignored) Verifies the directive: both branches will converge to identical content after this merges and a follow-up main->master sync PR ships. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
| GitGuardian id | GitGuardian status | Secret | Commit | Filename | |
|---|---|---|---|---|---|
| 29834700 | Triggered | Generic Password | f48bddf | scripts/test-rbac.sh | View secret |
| 32722355 | Triggered | Generic Password | 6d4cc73 | scripts/test-rbac.sh | View secret |
🛠 Guidelines to remediate hardcoded secrets
- Understand the implications of revoking this secret by investigating where it is used in your code.
- Replace and store your secrets safely. Learn here the best practices.
- Revoke and rotate these secrets.
- If possible, rewrite git history. Rewriting git history is not a trivial act. You might completely break other contributing developers' workflow and you risk accidentally deleting legitimate data.
To avoid such incidents in the future consider
- following these best practices for managing and storing secrets including API keys and other credentials
- install secret detection on pre-commit to catch secret before it leaves your machine and ease remediation.
🦉 GitGuardian detects secrets in your source code to help developers and security teams secure the modern development process. You are seeing this because you or someone else with access to this repository has authorized GitGuardian to scan your pull request.
6 tasks
ahmetabdullahgultekin
added a commit
that referenced
this pull request
May 11, 2026
…52) * chore(deps-dev): bump vite from 6.4.1 to 6.4.2 in /landing-website (#28) Bumps [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) from 6.4.1 to 6.4.2. - [Release notes](https://github.com/vitejs/vite/releases) - [Changelog](https://github.com/vitejs/vite/blob/v6.4.2/packages/vite/CHANGELOG.md) - [Commits](https://github.com/vitejs/vite/commits/v6.4.2/packages/vite) --- updated-dependencies: - dependency-name: vite dependency-version: 6.4.2 dependency-type: direct:development ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * docs(changelog): 2026-04-24 evening — 12 more PRs merged, puzzle-page split, dashboard 403/500/422 remediation * docs(changelog): PR #38 — frontend RBAC gating (Rules 2+3) live on app.fivucsas.com * chore(submodule): bump identity-core-api → 4bee6d7 (4 PRs landed 2026-04-25) Pointer bump for the 4 PRs that landed on identity-core-api/main today: efb8228 feat(rbac): V45 TENANT_ADMIN permission baseline (#27) 4794595 fix(auth): session cancel + dead-end prevention + method switch (#25) 9e2df8e feat(tenants): multi email-domain support (V44 + entity foundation) (#26) 4bee6d7 feat(register): resolve tenant by email-domain via tenant_email_domains (V44 wire-up) (#28) V44 + V45 migrations both ship in this bump. Next prod boot (\`docker compose up -d identity-core-api\`) will apply them. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * chore(submodule): bump web-app → 1689177 (PR #39 biometric-puzzles) Pointer bump for the always-succeed bug fix: 1689177 feat(biometric-puzzles): real per-challenge face + hand detection (#39) 14 face puzzles now run pinned ChallengeType through the BiometricPuzzle engine. 9 hand puzzles use the new HandLandmarker + per-challenge detector module. Regression guard ensures every registry entry references a unique component (prevents the bug-pattern from recurring). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * chore(submodule): bump biometric-processor → 4a9383d (PR #36 anti-spoof core) PR #36 (liveness_score) — rPPG analyzer + temporal consistency + light challenge service. ~1 KLOC of additive anti-spoof analysis, 3 new test files, no rewiring of existing code paths. Note: the broader liveness_capture branch (Aysenur's 6-commit superset with demo-ui artifacts + dev OpenCV tool) was NOT merged — 12 KLOC, 7 real conflicts in central wiring; needs cleanup. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * chore(submodule): bump web-app → 9d7f0c2 (PR #40 lint sweep, 78→17 warnings) * chore(submodule): bump client-apps → acd395d (PRs #27/#28/#29 — Android CI fix, iOS CoreFoundation, APK i18n) * chore(submodule): bump client-apps → 2af501f (PR #30 V16 i18n — 12 login screens) * chore(submodule): bump biometric-processor → ee1e870 (PR #51 anti-spoof pipeline integration, Aysenur) * chore(submodule): bump web-app → 07f34d0 (PR #41 CI fix unblocks #39+#40 deploy) * chore(submodule): bump biometric-processor → bdd8203 (PR #52 config validator) * chore(submodules): bump for today's afternoon-evening wave identity-core-api → 2adfa90 (PR #29 audit_logs.tenant_id fix + V46 backfill) biometric-processor → bdd8203 (PR #52 config validator) client-apps → e840de0 (PR #31 MFA dispatch + PR #32 polish v2) Plus prod deploy of identity-core-api with V46 backfill applied: 829 NULL-tenant audit rows → 0; 104 anonymous failed-login rows correctly stay NULL by design. * chore(submodule): bump identity-core-api → 07b6bcf (PR #30 V47 enrollment scores) * chore(submodules): bump for next wave (4 more PRs landed + 2 deploys) identity-core-api → 12e8010 (PR #30 V47 enrollment scores + PR #31 auth-sessions admin list) biometric-processor → 8c5423f (PR #53 demographics router gating, ~400 MB savings) web-app → b59005c (PR #44 auth-sessions admin page wiring) client-apps → f4bdc40 (PR #33 MFA PR #25 endpoints — DELETE cancel + switch-method + NEEDS_ENROLLMENT) Prod deploys: - identity-core-api rebuilt + restarted with V47 → live, GET /auth/sessions verified - biometric-api rebuilt + restarted with demographics gating → ~400 MB freed * chore(submodules): bump for 3 Dependabot security/patch merges (web #42 postcss XSS, bp #48 dotenv, bp #46 next-demo) * chore(submodule): bump biometric-processor → f6c6fcb (PR #55 gesture Phase 1, supersedes #50) * chore(submodules): bump client-apps + biometric-processor (post-PR-#34 + bp #54) - client-apps → 5e756d8 (PR #34: KMP LoginScreen reads active auth flow + dynamic primary step) - biometric-processor → a29812d (PR #54: dependabot uuid removal + @sentry/webpack-plugin 5.1.1→5.2.0) - docs/practice-and-test pointer refresh (no-op in tree) - .env.example: BE-H1 RS256 JWT signing config (carried over from prior wave) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * chore(submodule): bump web-app → 0c61076 (PR #31 GestureLivenessStep + i18n) PR #31 — gesture Phase 2 web (landmarks-only client-side detection). Closes the deferred-draft items: liveness.gesture.* keys (17 × en/tr) landed; build + lint green. * chore(submodule): bump client-apps → 0104d15 (PR #35 polish: i18n + UX sweep) PR #35 — TR translation refinements (HW_TOKEN_*, MRZ_BACK_OF_ID_OVERLAY), 22 new i18n keys (OTP countdown + a11y + Profile sweep), TOTP auto-submit on 6 digits, Email/SMS OTP 30s resend countdown, ProfileScreen + EditProfileScreen full i18n. 447/447 desktopTest still green. * docs: strip iOS/macOS from forward roadmap (out of scope, no Apple hardware) (#36) * chore(submodule): bump client-apps → 0104d15 (PR #35 polish: i18n + UX sweep) PR #35 — TR translation refinements (HW_TOKEN_*, MRZ_BACK_OF_ID_OVERLAY), 22 new i18n keys (OTP countdown + a11y + Profile sweep), TOTP auto-submit on 6 digits, Email/SMS OTP 30s resend countdown, ProfileScreen + EditProfileScreen full i18n. 447/447 desktopTest still green. * docs: strip iOS/macOS from forward roadmap (out of scope, no Apple hardware) Apple platforms (iOS / iPadOS / macOS) are permanently out of scope as of 2026-04-26 — the product owner has no Apple hardware available for development, signing, or testing. Android APK + Windows + Linux desktop cover the demonstration target. Apple-platform users are served via the hosted login page (verify.fivucsas.com) in their system browser. KMP `iosMain` source directory remains in the codebase as part of the Kotlin Multiplatform compile structure but receives no further engineering work. This is a docs-only PR, no source code is touched. Files touched in this repo: - ROADMAP.md: scope-note banner at top. - ROADMAP_V2.md: scope-note banner; Phase 7 retitled "Desktop" (iOS bullets dropped); Phase summary table row 7 updated; WebAuthn browser-OS support table iOS/macOS rows flagged "n/a — native app out of scope (browser support remains for hosted-login users on Apple devices)"; ASCII core-design diagram updated to remove "NFC on iOS/unsupported" phrasing. - MASTER_PLAN.md: scope-note banner at top; INTEGRATION PATH 4 SDK callout drops Swift Package, keeps Android AAR. - PLATFORM_STATUS.md: scope-note banner at top; KMP source-structure bullet updated to keep `iosMain` listed but flagged as out of scope (in-tree for compile structure only). - MOBILE_APP_COMPREHENSIVE_REDESIGN.md: scope-note banner at top. Architectural diagrams referencing `iosMain`/`iosApp`/`IosTokenStorage` preserved as KMP architectural reference (not engineered against). - CHANGELOG.md: single Unreleased entry under a new ### Docs heading. Submodule bumps (forward to docs-branch tips of each submodule's companion PR): - web-app → a84f9791 (PR #46) - identity-core-api → 2af82343 (PR #34) - biometric-processor → 65d2ea50 (PR #56) - docs → a3c012e9 (PR #11 — substantive rewrite of CLIENT_APPS_PARITY.md and PATH_TO_20_20.md) `client-apps` submodule deliberately NOT bumped — concurrent agent active in that repo and per cleanup plan, that submodule was excluded from this sweep. Its iOS-related docs (ROADMAP_CLIENT_APPS.md, CHANGELOG.md, README) will be cleaned up separately. History preserved: any CHANGELOG entries that mention past iOS work are left as-is. Only forward-looking content is updated. Pre-pivot Appendix A in CLIENT_APPS_PARITY.md is also preserved as historical reference. * chore(submodules): bump pointers to post-merge mains (post doc-strip) Sub-repos' doc-strip branches squash-merged; bump parent pointers to the new main SHAs so this parent PR lands a coherent tree: - web-app → main (PR #46 + PR #47) - identity-core-api → main (PR #33 + PR #34) - biometric-processor → main (PR #56) - docs → main (PR #11) * docs: refresh CLAUDE.md + add login surfaces comparison + close-out scope - CLAUDE.md: stale rollingcatsoftware.com URLs → fivucsas.com domains; CX33 → CX43 (16 GB); add verify.fivucsas.com + demo.fivucsas.com to subdomain table; refresh "Last verified" to 2026-04-26. - docs submodule bump: new LOGIN_SURFACES_COMPARISON_2026-04-26.md (3-way compare of app.fivucsas/login, verify.fivucsas/login, verify.fivucsas/widget) - FIVUCSAS_INCOMPLETE_2026-04-26.md: refreshed with 8 PRs shipped, iOS/macOS DROPPED, V42/V43 audit-finding correction * chore(submodule): bump identity-core-api → 82b3a48 (V48 drop biometric_data) PR #35 — biometric_data table removed (V48 migration applied live on Hetzner; flyway_schema_history rank 48 = success). 9 files of dead code deleted: BiometricData entity + 2 repository declarations + legacy service.BiometricService + 4 application service callers + EnrollmentController references. Net -390 / +97 LOC. Zero data loss (table empty since 2026-04 pivot). * chore(submodule): bump web-app → $(git -C web-app rev-parse --short HEAD) (PR #48 perf: MUI vendor split) PR #48 — Phase E2 MUI vendor chunk split. mui-vendor 555 KB → mui-core 517 KB + mui-icons 37 KB. E1 Recharts lazy was already in place. 678/678 tests still green; lint 0/0; single file change (vite.config.ts). * chore(submodule): bump identity-core-api → 462c062 (PR #36 PKCE D5a/b) PR #36 — Phase D5a/b shipped + DEPLOYED. New AuditAction.PKCE_FAILURE + PkceFailureReason enum + PkceVerificationException + per-clientId Bucket4j (30 failures / 5 min) + Retry-After on exhaustion. Audit row written even when rate-limited (full attack pattern visibility for SOC). +3 net tests (929→932 passing). * chore(biometric): bump submodules + roadmap docs - biometric-processor: Faz 1-3 — centerface/.env.prod, liveness wired into /enroll+/verify, pose quality fields, adaptive threshold config - web-app: FaceLandmarker primary detector, passive liveness pre-filter, enrollment renewal UX, i18n keys added (678/678 tests pass) - BIOMETRIC_PIPELINE_AUDIT_2026-04-28.md: full audit doc - BIOMETRIC_ROADMAP_2026-04-28.md: fix roadmap - CLAUDE.md: biometric pipeline section updated Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * chore(submodule): bump biometric-processor (compose centerface+anti-spoof+liveness) * chore(submodule): bump biometric-processor (mtcnn fix) * chore(submodule): bump web-app (CI env fix + FaceLandmarker + passive liveness) * docs(2026-04-28): refresh CLAUDE.md + add session roadmap and client-apps plan - CLAUDE.md: replace stale "biometric pipeline aging" note with verified post-fix prod state (Facenet512, mtcnn, anti-spoof on, UniFace passive liveness, MediaPipe FaceLandmarker, adaptive threshold). Refresh Last verified line and Next Steps to point at today's branches and the V42/V43 missing-migration P0. - ROADMAP_2026-04-28.md: canonical record of today's findings (8 user- found bugs C1-C11), 6 morning fixes verified live, and a final-state table for the 4 afternoon teams. - CLIENT_APPS_PARITY_PLAN_2026-04-28.md: research-only plan for Team D (Compose UI parity + APK release workflow). Ready for user review; needs keystore + 4 GitHub secrets before action. Companion memory updates (in ~/.claude/projects memory): feedback_no_hard_delete_users.md feedback_readonly_rootfs_cache_dirs.md feedback_liveness_hybrid_vs_passive.md project_session_20260428.md (READ FIRST ON RESUME) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * chore(submodules): bump web-app + identity-core-api + biometric-processor (2026-04-28 wave) web-app 47f7077: - fix(sidebar): exact-route highlight (no prefix collision) - fix(enrollment): TOTP/EMAIL_OTP/SMS_OTP/QR_CODE correctness sweep - fix(web): rescue stashed agent work (biometric tools network error, puzzles polish, MFA double-step defense) identity-core-api 8ba4ee7: - fix(enrollment): drop SMS_OTP/QR_CODE/EMAIL_OTP from AUTO_COMPLETE_TYPES - fix(enrollment): auto-create ENROLLED EMAIL_OTP+QR_CODE rows on first list - fix(mfa): exclude completed methods from next step's available list biometric-processor 9444018: - fix(prod): give UniFace MiniFASNet a writable model cache (HOME=/tmp, UNIFACE_CACHE_DIR=/app/uniface-cache, named volume biometric_uniface) - fix(liveness): use passive UniFace only — hybrid mode vetoed every login Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * chore(submodule): bump identity-core-api → c25b731 (users-list lastLogin fix) Wrong audit action constant ('USER_AUTHENTICATED') made the Users list always show "Never" for Last Login. Switch to 'USER_LOGIN' and fall back to User.lastLoginAt when audit is empty. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * chore(submodule): bump identity-core-api → 5446d57 (V42 + tenant-lock) Two changes: - Restore Flyway V42 (TOTP secret encrypted-at-rest CHECK constraint) from the security/phase-1-auth-hardening branch, applied manually to prod since out-of-order=false. - fix(auth): tenant-lock OAuth-initiated logins to the client's tenant. demo.fivucsas.com (marmara-bys-demo OAuth client) now rejects users from other tenants. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs: multi-email / multi-tenant identity design note Captures the architectural answer to the 2026-04-28 question: "I have ahabgu@gmail.com on Fivucsas and ahmet.abdullah@marun.edu.tr should be on Marmara — same person, two emails, two tenants." Today's reality: - The schema already supports two distinct user rows in two tenants. tenant_email_domains (V44) auto-routes registration by email domain (marmara.edu.tr → Marmara). Today's tenant-lock at OAuth login (commit 5446d57) enforces "right account at right surface." - glsm's 2-row situation explained — soft-delete + new tenant registration. No 500 risk after morning's findByEmail filter; do not hard-delete the soft-deleted row (FK cascade lesson). Three architecture options laid out: - A. Status quo — works for today's use case - B. Identities + memberships — week-long, true human-centric model - C. Email aliases on user row — cheap, partial Recommendation: A now. B if/when concrete business need surfaces. Phone-as-primary-login folded into B at that point. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(archive): move 16 superseded reports into archive/2026-04-pre-roadmap-2028/ Top-level was carrying 22 markdown files, most pre-dating the 2026-04-28 production hardening day. Canonical "current state" docs now sit at root: CHANGELOG.md CLAUDE.md README.md ROADMAP_2026-04-28.md CLIENT_APPS_PARITY_PLAN_2026-04-28.md MULTI_EMAIL_TENANT_DESIGN_2026-04-28.md Archived (preserved with full git history via git mv): API_EDGE_CASE_AUDIT.md ARCHITECTURE_ANALYSIS.md BIOMETRIC_PIPELINE_AUDIT_2026-04-28.md (morning audit, items shipped same day) BIOMETRIC_ROADMAP_2026-04-28.md (morning roadmap, items shipped same day) CLIENT_SIDE_ML_REPORT.md FIVUCSAS_INCOMPLETE_2026-04-26.md FRONTEND_COMPARISON_REPORT.md INFRA_REVIEW.md MASTER_PLAN.md MOBILE_APP_COMPREHENSIVE_REDESIGN.md NFC_READER_REDESIGN.md PERFORMANCE_AUDIT.md PLATFORM_STATUS.md ROADMAP.md ROADMAP_V2.md TODO.md Each of these is referenced from archive/2026-04-pre-roadmap-2028/README.md with a one-line "why archived" rationale. Also unignore /archive/ — it was previously gitignored which would have silently swallowed this commit. Future archive waves can keep this same shape (wave-name folder + README index). README.md updated with version 4.0.0 + pointer to ROADMAP_2026-04-28. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * chore(2026-04-28-evening): 4 audit reports + bump submodules Audit reports captured at root: AUDIT_2026-04-28_BASIC.md — design correctness on happy paths AUDIT_2026-04-28_EDGE.md — race / extreme inputs / FK cascades AUDIT_2026-04-28_SECURITY.md — authn / authz / OAuth / secrets / transport AUDIT_2026-04-28_OPS.md — backups / containers / network / DR Bumps: identity-core-api → 24d3784: - V42 TOTP encrypted-at-rest CHECK (restored from unmerged branch) - users-list lastLoginAt fix (action 'USER_LOGIN', not 'USER_AUTHENTICATED') - OAuth tenant-lock (commit 5446d57 — refuses cross-tenant logins) - MFA double-consume race fix (PESSIMISTIC_WRITE on session lookup) - Cross-tenant by-id user access fix (enforceTenantScope guard) biometric-processor → 9d4481f: - Strip bio.fivucsas.com public Traefik router. Internal-only via backend docker network (per CLAUDE.md design intent). P0 audit findings closed today (5): ops-P0a bio.fivucsas exposed → 9d4481f ops-P0b disk 91% → docker builder prune (-23 GB) edge-P0a MFA double-consume race → 24d3784 edge-P0b cross-tenant user by-id → 24d3784 basic-P0 demo creds in prod bundle → false positive (already DEV-gated) P0 findings deferred (need coordinated rotation / SPA refactor): sec-P0a secrets in git history → TODO Phase C1a-f sec-P0b VITE_BIOMETRIC_API_KEY in → expand today's useFaceSearch SPA bundle for non-search reroute to all biometric callsites Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(audit): 2026-04-29 ops follow-up — closes 2 P0 + 2 P1 from yesterday P0 closed yesterday (verified today): 1. bio.fivucsas.com publicly exposed → router stripped (9d4481f) 2. Disk 91% → 86% via builder prune (-23 GB) P1 documentation shipped today: 3. Observability runbook → infra/observability/RUNBOOK_OBSERVABILITY.md 4. DR runbook → infra/RUNBOOK_DR.md (first drill instructions inside) P1/P2 still open: WAL/PITR, password rotation, image SHA pinning, shared_buffers tuning, PgBouncer, offsite long-term retention. Top 3 next actions for the user: - Run the first DR drill (validates RTO/RPO + the runbook itself) - Bring up observability (~5 min once Grafana password chosen) - Move postgres password out of backup.sh into .env (chmod 600) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * chore(submodule): bump web-app → eef1657 (Sec-P0b — biometric API key out of bundle) Closes the second of yesterday's audit-security P0s. SPA no longer ships VITE_BIOMETRIC_API_KEY; all biometric calls now route through identity-core-api with the user's Bearer JWT. Bundle re-verified post-merge: X-API-Key 0 hits VITE_BIOMETRIC_API 0 hits bio.fivucsas.com 1 hit (cosmetic help-text) Combined with yesterday's biometric-processor public-router strip (commit 9d4481f on the bp side, parent submodule pointer 5199952), bio.fivucsas.com is now fully internal — no public DNS reach, no public credential leaked in any browser bundle. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * chore(submodule): bump identity-core-api → d4c4d43 (5 P1 carryovers + 9 tests) Closes 5 P1s from yesterday's audits: EDGE-P1 #3 startEnrollment race → 500 EDGE-P1 #4 /audit-logs unbounded size param EDGE-P1 #8 V43 migration version gap SEC-P1 #4 /auth/mfa/step missing rate-limit bucket SEC-P1 #3 JWT default-algo locked to RS256 on prod profile V43 row pre-inserted into prod flyway_schema_history before rebuild (out-of-order=false in prod), mirroring yesterday's V42 pattern. 9 new tests across 5 suites (mvn -DskipTests package green): ManageEnrollmentServiceTest +2 (race + winner-vanishes) AuditLogControllerTest +3 (size 0/100/10000000) MigrationChainContiguityTest +2 (V43 reservation + chain) RateLimitInterceptorMfaStepTest +3 (30/min, 31st 429, IP isolation) JwtServiceProdAlgoLockTest +4 (prod+HS512 throws, etc.) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * chore(submodule): bump web-app → c641d4e (basic-audit P1 sweep) Closes 9 P1 + 2 P2 from AUDIT_2026-04-28_BASIC.md: - 23 Turkish translations for biometricPuzzle hints (full tr/en parity) - document.title localized via pageTitles namespace - 6 raw err.message sites routed through formatApiError - TOTP enrollment hardcoded English (3 sites) + QR alt text localized - UserService / AuthService re-throw ZodError; formatApiError extended to map ZodError → t('errors.validation') 63 new keys per language, +5 KB bundle, 678 vitest pass. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * chore(submodules): bump api → 69bfa09 + web-app → c580822 (5-team wave) API (69bfa09) consolidates Teams A + B + C: A — fix/test-mocks-2026-04-29 (dcf50d6) 7 mock failures from yesterday's 24d3784 fixed. 946→966 tests, 0 failures. B — fix/biometric-adapter-tenant-and-embedding-forward (70e3e4d) BiometricServicePort gains 5-arg overloads forwarding tenant_id + D2 client_embedding(s) to bio. Backward-compat via default methods. 6 new adapter tests. C — fix/tenant-soft-delete-and-totp-convert (69bfa09) Tenant @SQLDelete + @SQLRestriction (Edge-P1 #5: tenant hard-delete trap closed). User.two_factor_secret @Convert (Edge-P1 #7: defense-in-depth for V42 CHECK). V49 idempotent reverse index applied to prod. 14 new tests. Full suite: 966 tests, 0 failures, 0 errors. Web-app (c580822): E — fix/loginpage-face-tile-cleanup Removed dead face-tile state from LoginPage (broken pre-auth since SPA reroute; tile was already invisible). +3/-32. Deployed to Hostinger. Production deployed at 04:48 UTC: api rebuilt + restarted, V49 in flyway_schema_history, smoke-tests green (login OK, cross-tenant client_id still rejected at the marmara-bys-demo gate). Team D (ops P2) committed to /opt/projects local repo (no remote); Sec-P0a runbook at /opt/projects/infra/RUNBOOK_SECRET_ROTATION.md captures the operator-coordinated history rewrite + secret rotation. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * chore(deploy): tag :latest images with :sha-<short> after build (Ops-P2 #7) Mirror the rollback-friendly tagging pattern from /opt/projects/infra/deploy.sh (commit e3e9056) into the FIVUCSAS dev-driven deploy scripts. After the remote `docker compose up -d --build`, the script now SSHs back in to walk `docker compose images`, find each repo carrying `:latest`, and re-tag it as `:sha-<short>` derived from the local identity-core-api git HEAD. This lets a broken deploy roll back to the previously-built image without rebuilding. - deploy-identity-core-hetzner.sh: new step 4b - deploy-identity-core-hetzner.ps1: new step 3b (mirrors bash via ssh heredoc) - header comments cite the audit (Ops-P2 #7) and the reference SHA Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * chore(audit): close DRAFT audit PRs api#32 + web#45 as superseded Both audit PRs were authored 2026-04-26 and contained only an .md report file (no code to merge). Today's hardening wave closes the substantive findings; the reports remain in the working tree for history. api#32 closed-via-comment: V42 restored (bad7262), V43 slot reserved (29aa007), test compile fixed (dcf50d6, be30dc7), JWT RS256 lock (65415f3), MFA-step rate limit + Retry-After (3670932). web#45 closed-via-comment: i18n sweep (c641d4e), biometric API key elimination (fc79de6, 5ac4a97, 2a3820b), CI .env.production write (15aab67), face-tile login removal (c580822). Closing comments on each PR list closed vs. deferred items with SHAs. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(changelog): add 2026-04-28 + 2026-04-29 hardening wave entries Single comprehensive entry per day covering: - 2026-04-28: 6 morning fixes (LoginPage 401 i18n, UserRepo soft-delete, optional MFA-step skip, Fivucsas tenant contact_email, UniFace passive liveness, useQualityAssessment bbox fallback); enrollment correctness sweep across TOTP/EMAIL_OTP/SMS_OTP/QR_CODE; fingerprint-twice MFA fix; 4 audit reports; FK-cascade incident note. - 2026-04-29: Sec-P0b biometric API key elimination from SPA bundle (fc79de6, 5ac4a97, 2a3820b); biometric adapter telemetry forwarding (6ad1d91); JWT RS256 lock on prod profile (65415f3); MFA-step rate-limit + Retry-After (3670932); audit-log size cap (8075c11); Tenant @SQLDelete + TOTP @Convert (2e05457); V42 restore (bad7262) + V43 reserve (29aa007); test compile fix (dcf50d6, be30dc7); Ops-P2 image-SHA tagging in scripts/deploy/*; 5 runbooks; audit DRAFT PRs api#32 + web#45 closed. Each line cites the specific commit SHA that landed the fix. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * chore: bump submodules — bio→22563fd (file-size guard), web→5b8f876 (face demo) biometric-processor: MAX_FILE_SIZE guard wired before API-key auth (Z3). web-app: public /face-demo page showcasing 7 face capabilities (Z5). ROADMAP_2026-04-28: add Round 2/3 + doc archive notes. Closes the Z-wave (post-AUDIT_2026-04-28 follow-up). Z1/Z2 still open pending Anthropic rate-limit reset. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * chore(submodules): bump api → 30371e8 (Z1) + web-app → 9e151bf (Z2) api: refresh-token rotation family revocation (Sec-P2 #6) + OAuth2 HostedAuthorizeCompleteRequest @Valid (Sec-P2 #7) + MFA expiresAt boundary alignment (Edge-P2 #6). web-app: VitePWA navigateFallback + cleanupOutdatedCaches (Edge-P2 #9) — kills stale-shell 404s after Hostinger deploys. Closes the post-AUDIT_2026-04-28 Z-wave. Sec-P2 #8 (audit-log HTML escape) deferred — log-file-only today, only relevant if a future UI renders details unescaped. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(claude): refresh status to 2026-04-29 — Z-wave shipped Last-verified line, In Progress section, and Next Steps order all reset to today's reality. The post-AUDIT_2026-04-28 Z-wave (Z1 refresh-token family revocation + OAuth2 @Valid + MFA boundary, Z2 VitePWA navigateFallback, Z3 bio MAX_FILE_SIZE, Z4 ops housekeeping, Z5 /face-demo) is closed. Operator-only items (Sec-P0a rotation, DR drill, observability bring-up, V50 prod apply) remain. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * chore(submodule): bump web-app → 9231f4d (Z2 vitest exclude) Adds .claude/** + archive/** to vitest test.exclude so the baseline reflects real source (678 passing, 0 failing) instead of stale agent-worktree drafts. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * chore: bump docs+bio submodules + ignore verify-widget/html build artifacts - docs: import AUDIT_2026-04-19 + PRECOMMIT_HOOKS reference - biometric-processor: import AUDIT_2026-04-26 read-only verification - .gitignore: verify-widget/html/ is build staging, not source Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * chore(submodules): bump api+web to ship gitleaks CI - identity-core-api da9b7c4: add gitleaks workflow (Sec-P0a §8) - web-app 0256e58: add gitleaks workflow (Sec-P0a §8) Pairs with GitHub-side secret-scanning + push-protection now enabled on both repos via API. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * chore(submodules): bump api+web — gitleaks CLI fix + allowlist - identity-core-api 8b5fdde: switch to gitleaks CLI (no paid license) + allowlist 10 known test/doc false positives — CI green. - web-app 4566b19: switch to gitleaks CLI — CI green. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(claude): mark all reachable Z-wave + ops follow-ups as completed 2026-04-30 V50 applied + api recreated, observability live, DR drill OK, gitleaks CI on both repos, secret scanning + push protection enabled. Sec-P0a actual rotation + DNS A record + Grafana contact point remain operator-only. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(claude): record biometric-API-key rotation + Grafana ops-email + finding that .env.gcp leaked GCP creds, not Hetzner Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * chore(submodule): web-app 7365003 — CI SKIP_MODEL_FETCH Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * chore(submodule): web-app c791923 — fix dashboard/profile mismatches Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * chore(submodule): web-app 91b1b6e — face mesh + hand skeleton overlays on puzzles Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * chore(submodule): web-app 0654b27 — close P3 session-count UX Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(claude): record late-day profile UX polish + puzzle landmark overlays Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * refactor(landing): strip Marmara University from buyer-facing copy (P2.5) (#37) * refactor(landing): strip Marmara University buyer-facing branding — keep in /about + README (P2.5) The hero badge and footer on fivucsas.com lead with "Marmara University - Engineering Project" / "2026 FIVUCSAS. Marmara University.", which signals "student demo" to prospective tenants and undercuts the SaaS positioning. Strip the academic framing from the two buyer-facing surfaces: - Hero badge → "Multi-Tenant Biometric Identity Platform" - Footer → "2026 FIVUCSAS. All rights reserved." Marmara University attribution is preserved verbatim in the Project Team section (lines 423 + 471 — Project Team subtitle and Supervisor row), which is the academic-history equivalent of an /about page. README.md is also untouched. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * chore(landing): strip Marmara from meta keywords for SEO consistency (Copilot review) Refs FIVUCSAS#37 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * chore(submodules): bump api+bio+web — 7 PRs landed (Phase 1+2 + Copilot) api 8b5fdde..20cc504: PR #37 — validate-on-migrate + statement_timeout + MDC + Maven cache + Copilot fixes: CORS expose, X-Request-Id validation, constants PR #38 — Tx/Async correctness (readOnly defaults, REQUIRES_NEW, proxy-bypass, bounded pool), JPA equals/hashCode, audit-log HTML escape + Copilot fixes: TenantContext across @Async (RLS-safe), userAgentV2 escape, AuditEscapeTest + AuditLogAdapterTest escape PR #39 — fingerprint placeholder removed (legacy biometric path deleted; WebAuthn FingerprintAuthHandler retained) bio 6e6ee88..f0d997c: PR #57 — asyncio.to_thread on UniFace + QualityAssessor + cv2.imread (event-loop unblock, P2.11) PR #58 — fingerprint placeholder hash_embedder removed web f649ef3..7dae2c9: PR #49 — central dateFnsLocale helper across 9 list pages (P3.2) + Copilot fix: locale-aware skeletons P/PP/PPP/p/pp instead of literal MMM dd, yyyy / HH:mm:ss patterns Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(triage): USER_BUGS_2026-04-30 — face-no-gate / YOLO wrong class / puzzles broken Three direct user reports surfaced 2026-04-30 16:50 (TR): 1. Face enrollment auto-advances even when no face is in view; failure surfaces only at server save. Front-end has the detection signal but does not gate progression on it. Branch fix/face-enrollment-no-face-gate. 2. YOLO card-type classifier picks the wrong TR ID variant. Likely label-order / preprocessing / no confidence floor. Defensive fix even if model is the root cause: ≥0.6 floor + manual-select fallback. Branch fix/card-type-yolo-classification. 3. Math + shape-drawing biometric puzzles silently broken. Likely string/number validation, missing onSolve wiring, pointer-event / canvas-size races. Branch fix/biometric-puzzles-math-shape. Each has a separate background fix branch + Vitest. This file is the canonical triage doc; supersedes ad-hoc TODO entries. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * chore(submodules): bump api+bio+web — USER-BUG-1 + 3, JVM heap, post-merge Copilot api 20cc504..9973ee2: PR #40 — perf(jvm): drop -Xmx512m silent override, MaxRAMPercentage=75 (PERF #1; ~1.5 GB heap on 2 GiB container; 40-80 ms p99 saving) PR #41 — chore: align FINGERPRINT delete log with PR #39 removal (Copilot post-merge; FACE/VOICE arms keep the info-log, FINGERPRINT explicit no-op with debug-only) bio f0d997c..b1fe294: PR #59 — fix: 4 Copilot post-merge findings on PR #57 / #58 A. _model typed via TYPE_CHECKING uniface.spoofing.MiniFASNet B. _ensure_model_loaded → asyncio.Lock + double-checked locking C. asyncio.to_thread → get_thread_pool().run_blocking() so ML_THREAD_POOL_SIZE is honored D. README Voice line corrected — Resemblyzer GE2E still in prod (numba conflict resolved by librosa==0.9.2 pin, not removal) web 7dae2c9..6ce1f7d: PR #50 — fix(face): hard-stop face enrollment when no face is detected (USER-BUG-1; useFaceChallenge.ts hard-timeout removed, center-crop-fallback removed, early gate on detection.detected, en/tr i18n, 33/33 vitest) PR #51 — fix(puzzles): smooth finger-count + index-extended check (USER-BUG-3; HAND_MATH / HAND_FINGER_COUNT / HAND_SHAPE_TRACE / HAND_TRACE_TEMPLATE were jittered out by strict count===target comparator on noisy MediaPipe output; FingerCountSmoother 500ms dominance ≥60% + isIndexExtended TIP-above-PIP; 21/21 hand-challenge + 27/27 puzzle suite pass) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * chore(submodules): bump api+bio+web — USER-BUG-2 closed (server+client) + USER-BUG-4 SMS OTP api 9973ee2..cc8ed23: PR #42 — fix(sms-otp): branch on VerifiableSmsService for Twilio Verify; prod uses SMS_PROVIDER=twilio-verify but OtpController was unconditionally going through local Redis OtpService. Fix: skip otpService.generate when smsService instanceof VerifiableSmsService; verify via verifiable.verifyCode. Plus normalizeCode (NFKC + ZWSP/LRM/RLM/BOM strip + trim) applied to email + SMS verify input. 5 new test cases including "sendShouldNotGenerateLocalCode" that would have caught the original bug; 13/13 pass. USER-BUG-4. Needs identity-core-api container rebuild. bio b1fe294..de5584e: PR #60 — fix(card-type): server-side defensive tightening on YOLOCardTypeDetector. Confidence threshold 0.5 → 0.65; OCR validation now runs on every detection (not only the two confusable pairs); borderline calls (conf in [0.65, 0.75) AND OCR no_evidence) return detected=False rather than committing to a guess. _ocr_validate returns (chosen_class, evidence) for diagnostic logging. akademisyen_karti added to supported_card_types (model class was present, list was missing it). Companion to web-app PR #52 (client defense-in-depth). USER-BUG-2 server-side, the user-visible path. web 6ce1f7d..8ea8186: PR #52 — fix(card-type): client CardDetector labels.json (canonical training-time class order) + FALLBACK_CLASS_NAMES corrected; CARD_HIGH_CONFIDENCE=0.7 gate; i18n cardDetection.classLabels so CardDetectionPage no longer leaks raw slugs; vitest pinning order against alphabetical regression. USER-BUG-2 client defense-in-depth. USER_BUGS_2026-04-30.md status table updated. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(user-bugs): all four closed; operator rebuild + E.164 phone follow-up noted Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * chore(submodule): identity-core-api → 567ce25 — ShedLock for SoftDeletePurgeJob (P2.9, PR #43) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * chore(submodules): bump api+web — auth-methods-testing real APIs (USER-BUG-5) + V51 renumber api 567ce25..8165311: PR #45 — chore(db): renumber V53__shedlock to V51 to fix MigrationChainContiguityTest after PR #43 left a gap (V51/V52 reserved on feat/v51-forbid-hard-delete-p1-7). web a1f1adb..bb30a4a: PR #53 — fix(auth-methods-testing): server-mediated puzzles call real APIs (USER-BUG-5 part 1). Deleted StubAuthRepository entirely. EmailOtp/Sms/Totp/QrCode now hit real /auth/2fa/* endpoints against the admin's own session, surface real errors. Password puzzle was never a discrete second factor — left excluded from registry by design. PR #54 — fix(auth-methods-testing): biometric/WebAuthn puzzles wrap production step components (USER-BUG-5 part 2). Face/Voice/ Fingerprint/NFC/HardwareKey now hit real biometric + webauthn endpoints, auto-enroll on 404, every onSuccess gated on server-confirmed verdict. setTimeout fakes removed. USER-BUG-5 (auth-methods-testing page mocks) fully closed. Total this session: 18 PRs merged across api/bio/web/root. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * chore(submodules): bump api+bio — Copilot post-merge round 2 fixes (round 2 of 3) api 8165311..2fe3f03: PR #44 — chore: address Copilot findings on PR #42, PR #40 OtpController: PROVIDER_REJECTED label clarified, normalizeCode docs aligned with NFKC, .strip() instead of .trim() to handle U+3000-class whitespace, verifySmsOtp UserNotFound now consistent across both modes. Dockerfile: ENTRYPOINT now uses exec for SIGTERM forwarding. bio de5584e..9b81a39: PR #61 — fix: address Copilot findings on PR #59, PR #60 Combined yolo_card_type + uniface + quality_assessor fixes (borderline-reject + ocr_unavailable, _ocr_validate confidence arg removed, _CONFUSABLE_PAIRS dead code removed, docstring sync, ThreadPool injected via constructor instead of static import to break infra→container coupling, _model type narrowed via local cast, ImportError guidance aligned with uniface>=3.0.0 pin, async-lock concurrency test added). Web-app post-merge fixes round 2 still pending — single agent in flight. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(user-bugs): USER-BUG-5 (auth-methods-testing mocks) closed; status table updated Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * chore(submodule): web-app → f2930ca — Copilot post-merge round 2 (PR #55) PR #55 — fix: address Copilot findings on PR #50, #51, #52 CardDetector: __dirname → import.meta.url for ESM; smoothing-buffer impl/comment alignment; JSDoc shape 5+C → 4+C; UNRECOGNISED_CONFIDENCE_THRESHOLD extracted to remove the 0.6-duplicated-3x smell. useFaceChallenge: cropFace-null path now also resets stageStartRef so the stage-timer race is closed end-to-end (not just hold-timer). handChallenges: HAND_FINGER_COUNT target<0 short-circuit; FingerCountSmoother "immediately" docstring corrected; HAND_FINGER_COUNT-specific jitter regression test added; "4 fingers" comment aligned with twoFingerFrame. Test verification (per agent): vitest 5/5 + 23/23 on touched specs; eslint 0 errors. Closes Copilot post-merge round 2 (web-app). All 22 findings across the 3 repos addressed (api #44 + bio #61 + web #55). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * chore(submodules): bump api+web — Copilot post-merge round 3 api 2fe3f03..04b44bf: PR #46 — chore: address Copilot post-merge findings on PR #43+#44 (round 3) V52__shedlock_timestamps_tz.sql — ALTER lock_until/locked_at to TIMESTAMP WITH TIME ZONE so shedlock matches the rest of the schema's TZ-aware convention (rest of identity_core uses TIMESTAMPTZ). Picked V52 because MigrationChainContiguityTest requires no gap; V54 would have failed. VerifiableSmsService.java — closed unclosed Javadoc <p> tag (doclint). TwilioVerifySmsService.java — log.warn now passes the exception so SLF4J emits the stack trace (was string-only before). OtpController.java — switches on VerifyResult so the summary log says "SMS OTP provider error" on PROVIDER_ERROR vs "SMS OTP mismatch" on INVALID_CODE. OtpControllerTest.java — Logback ListAppender attached, asserts both WARN reason branches plus negative regression guard. web f2930ca..e90aa35: PR #56 — chore: address Copilot post-merge findings on PR #53 (round 3) QrCodePuzzle.tsx — onError moved into useEffect so it no longer fires during render (kills "Cannot update a component while rendering a different component" warning). EmailOtpPuzzle.tsx — header comment fixed (OTP sent on click, not on mount). useTestVerifyApi.ts — JSDoc paths standardised on apiBase-relative form to match AuthSessionRepository.generateQrToken; file header documents the convention. AuthMethodMode.tsx — docblock rewritten to use the actual AuthMethodModeKind values (real | test | stub) instead of the stale "live" reference. Test verification (per agent): api — mvn -Dtest=OtpControllerTest,MigrationChainContiguityTest → 17/17 web — npx vitest run src/features/auth-methods-testing → 47/47 npm run lint → 0 errors / 2 pre-existing warnings (cap 90) 23 PRs merged this session total. Round 3 closes the Copilot review backlog. Operator container rebuild (Task #25) still required for the server-side fixes to land in prod. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * chore(submodule): biometric-processor — Copilot post-merge round 4 (PR #62) I-prefix for IThreadPoolExecutorPort, dead test helpers removed, asyncio.sleep event-loop smell fixed. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * chore(submodule): identity-core-api → V53 forbid hard-delete trigger landed (PR #47) PR #47 — feat(db): V53 BEFORE DELETE trigger on users + tenants RAISE EXCEPTION on hard DELETE; bypass via SET LOCAL app.allow_hard_delete='on' for legitimate GDPR Art. 17 purge. SoftDeletePurgeJob.purgeBatch now sets the GUC inside the TX so the trigger lets the row delete proceed. Trigger is idempotent (CREATE OR REPLACE FUNCTION + DROP TRIGGER IF EXISTS). Closes the residual hard-delete vector flagged in DB review #1 (DB_REVIEW_2026-04-30.md) and codifies feedback_no_hard_delete_users.md at the database layer. Renumbered to V53 because V51 = ShedLock (PR #43) and V52 = ShedLock TIMESTAMPTZ alignment (PR #46) merged first. Ahabgu incident regression (2026-04-28 careless `DELETE FROM users` cascading across 13 FK children) is now engine-level impossible. 3 commits: migration SQL + purge bypass + Testcontainers integration test (RUN_INTEGRATION=true gate, CI exercises). Effective on next container rebuild (Task #25). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * chore(submodule): web-app — wrong-password error fix (USER-BUG-6, PR #57) PR #57 — fix(login): show 'invalid credentials' on wrong password Root cause: AuthService.login() was wrapping the axios 401 in UnauthorizedError, stripping response.status/data, so formatApiError fell through every branch to errors.unknown. Fix: re-throw axios error untouched; formatApiError now reads backend errorCode (INVALID_CREDENTIALS, NEEDS_ENROLLMENT, MFA_REQUIRED) and routes to distinct i18n keys; 401 on /auth/login returns errors.invalidCredentials not the misleading errors.unauthorized (session-expired) message. 720/720 vitest pass. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * chore(submodules): bump web+bio — face login cold-start (USER-BUG-7) web-app PR #58 — perf(face-login): preload MediaPipe + idle-time engine warmup index.html — preconnect to cdn.jsdelivr.net + storage.googleapis.com, prefetch vision_bundle.mjs + vision_wasm_internal.wasm + face_landmarker.task. Browser warms DNS/TLS/cache while React parses. LoginPage.tsx + verify-app/LoginMfaFlow.tsx — BiometricEngine.initialize() fires inside requestIdleCallback while user types email/password. By MFA-dispatch the FaceLandmarker is loaded; "MediaPipe (CDN)" badge shows immediately and detection runs on the first frame. vite.config.ts — mediapipe-vendor manualChunk so the npm fallback path isn't in the main login bundle. Estimated 1.5–2s shaved off "land on login → face badge visible". bio PR #63 — perf(bio): warm UniFace at startup + per-stage timing logs container.py — UniFace MiniFASNet constructed inside initialize_dependencies() (was first-request lazy, costing 1–2s for every end-user after every restart). Failures non-fatal. verify_face.py + check_liveness.py — per-stage timing logs: "face/verify: decode=… detect=… quality=… embed=… fetch=… total=…ms". Future debugging will show which stage dominates. First /verify after deploy: ~3–4s → ~700–900ms. Remaining bottleneck (per agent): DeepFace Facenet512.represent + mtcnn inside _extractor.extract() costs ~250–400ms on CX43 CPU. New timing logs will quantify. Further gains require ONNX export of Facenet512 or a model swap (out of scope for this perf pass). Effective on next container rebuild + Hostinger deploy (web auto via CI). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * chore(submodules): bump api+web — admin-pages bug sweep (USER-BUG-8/9/10) api 8c7f6d2..6bb853f: PR #49 — fix(admin): SUPER_ADMIN cross-tenant + missing default-flow transition + verification stats aggregates Bug A — Guest endpoints route through TenantScopeResolver so SUPER_ADMIN sees platform-wide invitations; cross-tenant repo methods added; IllegalStateException → 409 in GlobalExceptionHandler (was generic 500). Bug B — ManageAuthFlowService.updateFlow now dethrones the prior default flow in the same TX when isDefault=true. Bug C — AuthSessionController + DeviceController accept null tenantId for SUPER_ADMIN as platform-wide. Paged repo methods findAllByStatusIn / findAllByUserId added; listAllDevices() use-case. Bug D — VerificationController /stats now computes completionRate, failureRate, avgTimeMinutes, statusDistribution, last-30-days dailyVerifications, top-10 failureReasons (was returning {total, completed, …} while FE rendered a different shape — every tile = "Veri yok"). Verification flows kept distinct from auth flows (flow_type=VERIFICATION subset, KYC/KYB/AML). web b0c9888: PR #59 — fix(admin): wire Star/StarBorder default-flow toggle, surface SUPER_ADMIN cross-tenant flag, replace hardcoded English in DevicesPage with t() (new devices.* keys EN+TR), pipe Guest toast through formatApiError. AuthSessionsPage + DevicesPage send empty tenantId when current user is SUPER_ADMIN; banner explains the cross-tenant view. AuthFlowsPage gets a Star icon button + confirmation dialog that calls updateFlow({isDefault: true}). GuestsPage error path now humans-readable. useVerification refactored to read the new dashboard shape. 702/702 web vitest pass; 3 backend tests updated to reflect the "null tenantId = platform-wide for SUPER_ADMIN" contract. USER-BUG-8 / 9 / 10 all closed. Effective on next container rebuild (Task #25) for backend; web auto-deploys via Hostinger CI. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * chore(submodule): identity-core-api → V54 E.164 phone validation (PR #48) PR #48 merged: @Pattern E.164 on CreateUserRequest + UpdateUserRequest; V54__users_phone_number_e164.sql backfills existing non-E.164 rows + adds CHECK constraint. Renumbered V53 → V54 after rebase to avoid collision with V53 forbid-hard-delete trigger (PR #47). Web-side auto-prefix +90 + strip-non-digits deferred (Task #46) — agent rate-limited before reaching the FE form work. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * chore(submodule): identity-core-api → AuthController.verifyMfaStep extraction (PR #50, P2.9 second half) PR #50 — refactor(auth): extract verifyMfaStep into VerifyMfaStepService strategy. AuthController.java 1526L → 1162L (-364, -24%); verifyMfaStep itself 380L → 25L pure HTTP shim. New under application/service/mfa/: VerifyMfaStepHandler (interface), MfaStepResult, VerifyMfaStepRequest, VerifyMfaStepResponse, VerifyMfaStepService (orchestrator, 390L). New under .../mfa/handler/: 10 @Component handlers (one per AuthMethodType: PASSWORD, EMAIL_OTP, SMS_OTP, TOTP, FACE, VOICE, FINGERPRINT, HARDWARE_KEY, QR_CODE, NFC_DOCUMENT) + WebAuthnVerifySupport shared by FINGERPRINT/HARDWARE_KEY. Tests: 1050 → 1053 (zero regressions, 18 new VerifyMfaStepServiceTest). Wire contract preserved: request/response shape, status codes, audit keys (MFA_STEP_COMPLETED/FAILED/COMPLETE), RFC 8176 amr ordering, pessimistic-lock (findBySessionTokenForUpdate + @Transactional), WebAuthn challenge two-phase flow. Pure refactor, no production rebuild needed. Closes master-roadmap P2.9 second half. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * chore(submodules): bump api+web+bio — Copilot post-merge round 5 (26 findings) api 19d76ff..cb3ea1a: PR #51 — chore: address Copilot post-merge findings on PR #49 (round 5) 7 findings: - UserController guest-invite: SUPER_ADMIN no longer falls back to currentUser.tenant; missing tenantId now hard-errors 400. - Guest list / device list platform-wide paths capped at MAX_PLATFORM_WIDE_GUESTS / DEVICES = 1000 rows. - AuthSessionQueryService javadoc documents the tenantId=null SUPER_ADMIN platform-wide contract. - GlobalExceptionHandler: new DomainStateConflictException narrows 409 handler; 15 domain throws migrated; 9 test assertions updated. IllegalStateException no longer silently demoted to 409. - ManageVerificationService.getStats: N+1 step-result fetch replaced with findAllBySessionIdInOrderBySessionIdAscStepNumberAsc batched query. bio 16a03b2..41c85db: PR #64 — chore: address Copilot post-merge findings on PR #63 (round 5) 4 findings: - container.py: liveness warm-up now runs UniFaceLivenessDetector.warm_model_sync() on the cached detector instance (was a throw-away MiniFASNet() that didn't actually warm the production code path). - container.py: explicit info-log when liveness backend skips warm-up. - container.py: generic exception handler uses exc_info=True. - check_liveness.py: renamed mid-flow timing to total_until_liveness; added true end-to-end total on completion log. web b0c9888..0bc801f: PR #60 — chore: address Copilot post-merge findings on PR #57+#58+#59 (round 5) 15 findings: - AuthService.ts comment now references real i18n keys (errors.invalidCredentials, errors.mfaRequired). - formatApiError.test.ts test descriptions renamed to match. - index.html: MediaPipe CDN pinned to @0.10.18 (matches package.json). - index.html: prefetches now use as="fetch" + crossorigin. - LoginPage warm-up comment clarified (timing optimization, not chunk split). - BiometricEngine.initialize() single-flight via shared _initPromise (kills duplicate-init race between LoginPage + LoginMfaFlow). - useAuthSessionsList: test exercises crossTenant=true with empty tenantId. - AuthFlowsPage: success auto-clear timer in ref, cleared on unmount + before re-scheduling. - AuthFlowsPage: Star IconButton aria-label toggles between setAsDefault / alreadyDefault. - DeviceRepository / VerificationRepository: signatures require explicit { crossTenant?: boolean } flag for empty tenantId; throws otherwise. - useVerification: derives isSuperAdmin; non-super-admin callers wait for tenantId instead of falling through. - AuthFlowsPage Set-default Dialog onClose ignores backdrop/Escape while request is in flight. - tr.json grammar fix: "...ayarlansın mı?" → "...ayarlamak ister misiniz?". 35 PRs merged this session total. Round 5 closes the Copilot review backlog on the last 5 user-bug PRs. Operator container rebuild (Task #25) still required for server-side fixes to land in prod. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * chore(submodule): identity-core-api → Copilot round 6 on PR #50 (PR #52) PR #52 merged: WebAuthn action=challenge short-circuits substitution guard; completeMfa/advanceToNextStep wrapped (AuthFlow lookup or token-mint failures emit MFA_STEP_FAILED orchestration-error, not 500); VerifyMfaStepHandler javadoc reflects actual wiring (List → EnumMap). 15/15 VerifyMfaStepServiceTest green. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * chore(submodule): web-app — phone E.164 auto-prefix (USER-BUG-4 part 2, PR #61) PR #61 merged. New web-app/src/utils/phoneNumber.ts utility: normalizePhoneInputE164 strips non-digits, auto-prepends +90, preserves typed +CC, dedupes accidental 905... prefixes; isValidE164 matches backend Pattern ^\+[1-9]\d{7,14}$. Wired into SettingsPage profile-form phone field and EnrollmentPage SMS-OTP phone-prompt dialog. Replaces legacy length<10 check. Submit payload uses normalized form. en/tr i18n key phoneNumber.e164Required. 26 new tests; 747/747 vitest pass. USER-BUG-4 fully closed end-to-end: server PR #48 rejects non-E.164 with 422; client PR #61 prevents that 422 from reaching the user by normalizing on input. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * chore(submodule): identity-core-api → Copilot round 7 on PR #52 (PR #53) PR #53 merged: challenge action double-call fixed (contract violation surfaced as 400 instead of re-invoking handler); e.getMessage() removed from user-facing strings + audit reasons (e.getClass().getSimpleName() only — full exception still in server log); RuntimeException catch + containsInterrupted(Throwable) cause-chain walk re-sets Thread.currentThread().interrupt() so cooperative cancellation isn't lost when an HTTP client wraps InterruptedException as RuntimeException. 15/15 VerifyMfaStepServiceTest green. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(session): 2026-05-01 status snapshot + 4 historical 4-lens review docs SESSION_STATUS_2026-05-01.md: canonical session-state doc. 39 PRs merged across 4 repos this session; all 10 user-reported bugs closed end-to-end; 7 rounds of Copilot post-merge cleanup; 9 senior reviewers deployed (5 delivered 2026-04-30, 4 in flight 2026-05-01). Operator container rebuild (Task #25) is the gating step — server-side work is on main but not running in prod. Adds the 4 lens reviews from 2026-04-30 morning that were left untracked: - BACKEND_REVIEW_2026-04-30.md (Senior BE) - ENGINEERING_REVIEW_2026-04-30.md (Chief Engineer) - FRONTEND_REVIEW_2026-04-30.md (Senior FE — static lens; superseded by the in-flight 2026-05-01 redrive that explicitly covers working-feature dimension after user feedback that USER-BUG-6/7/8/9/10 weren't caught) - PRODUCT_REVIEW_2026-04-30.md (Product Owner) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * chore(submodule): identity-core-api → P0 cross-tenant breach fixed (PR #54) PR #54: TenantBindFromAuthFilter binds TenantContext to JWT-derived tenantId after JwtAuthenticationFilter populates SecurityContextHolder. Forged X-Tenant-ID headers from non-SUPER_ADMIN users are now overwritten with the authenticated user's true tenantId + AUDIT-logged for SIEM. SUPER_ADMIN keeps the legitimate cross-tenant override. Closes SECURITY_REVIEW_2026-05-01.md §P0-1 (Task #57). Application-layer half of multi-tenant isolation; DB-layer half is Task #27 (FORCE ROW LEVEL SECURITY + non-superuser app role). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * chore(api-submodule): bump to security wave 2026-05-02 (P0-SEC-2/4 + P1-1) - 7aee607 OAuth2 confidential client_secret + RoleController tenantId ownership (#55) - 8d03566 hash refresh-token secret on write, dual-read legacy plaintext (#56) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(2026-05-02): session status + proctoring/amispoof.com design memo SESSION_STATUS_2026-05-02.md — 8 P0/P1 from senior reviews shipped in 5 PRs across 2 repos. Operator-only residuals (rebuild + env vars + JWT_SECRET decision + GDPR fixture force-push) listed in strict order. RESEARCH_PROCTORING_AMISPOOF_2026-05-02.md — design memo on extracting proctoring work into its own submodule + standing up amispoof.com as public demo + research data flywheel. Recommends option B (extract now, defer demo). User picks A/B/C. No code in that direction yet. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * chore(api-submodule): bump to WebAuthn fix wave (PR #57) cf398b9 — WebAuthn origin allowlist (registration + assertion paths), clientDataJSON required, sign-counter validated. Operator must set WEBAUTHN_ALLOWED_ORIGINS in .env.prod before rebuild. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * chore(2026-05-02): api bump + optimized roadmap api submodule bumped to 9cf4367 — includes #58 backend security batch (JJWT alg/kid bind + iss/aud + HS512 gated + PKCE hard-reject + audit escape + MfaSession Jackson), #59 test coverage backfill (F4 RLS + F5 refresh-token family revoke + F9 ShedLock concurrency), and #60 P0-critical CustomUserDetails wiring fix. ROADMAP_OPTIMIZED_2026-05-02.md replaces stale ROADMAP_2026-04-28.md + sprawling Phase-A–L tracker. Single source of truth for what's open: T1 operator-only urgent, T2 awaiting user decisions, T3 in flight, T4 leverage-ranked open work, T5 long-running scheduled. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(session-status): record CustomUserDetails blast-radius + upgrade rebuild to P0 URGENT PR #60 surfaced that the broken principal-type wiring in CustomUserDetailsService had been silently nullifying — for at least 8 days — not just PR #54's cross-tenant filter, but also 5 methods on AuthorizationService and AuditLoggingAspect's user/tenant attribution. Operator container rebuild is now P0 URGENT. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * chore(submodules): bump web-app + biometric-processor to 2026-05-02 main - web-app: e02c32f — PR #61 phone E.164 + PR #62 VITE_API_BASE_URL + PR #63 ErrorHandler/useVerification i18n + Redux removal + PR #64 round-8 MediaPipe CDN centralization + BiometricEngine dispose race. - biometric-processor: 9f0999f — PR #66 round-8 UniFace warm-up cache + audit-doc import + Traefik public-router strip + MAX_UPLOAD_SIZE guard. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * chore(submodule): web-app → F3 Playwright tags + nightly cron (PR #65) Default Playwright run no longer mutates PROD. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * chore(submodule): web-app → P1-FE error-surfacing batch (PR #66) Mutation hooks now setState({error}) before re-throw across 5 features. DeveloperPortalPage setTimeout leak fixed. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * chore(submodule): identity-core-api → backend quality + YAML hotfix (#61, #62) PR #61 — P1-Q5/Q6/Q9 dead helpers + adapter cleanup + controller @Transactional move. PR #62 — hotfix dup `app:` block in application-prod.yml (boot blocker). Live state post-deploy 2026-05-02 17:58 UTC: api HEAD 27d7423 + hotfix c53ce53 baked locally; main is now d8a4d33. bio HEAD 9f0999f + manual schema/backfill applied (Alembic 0005 not in container yet). Soak window: APP_SECURITY_JWT_ALLOW_HS512=true, iss/aud empty, until ~2026-06-01. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(2026-05-02): rebuild executed + JWT/User analysis + soak plan - SESSION_STATUS: late-session rebuild section, two-retry post-mortem, follow-up Tasks #80/81/82. - ANALYSIS_2026-05-02_USER_DOMAIN_AND_JWT_ROTATION: deep-dive professional recommendations on (a) Hexagonal User-domain bifurcation — gradual migration with ArchUnit guard rather than delete-or-park; (b) JWT_SECRET defence-in-depth via kid-based key registry rather than hard rotation. - ROADMAP_OPTIMIZED: late-session adds line. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * chore(submodules): land PR-#63/#64/#67/#68 — backend/bio quality batch (2026-05-04) - identity-core-api #63: ArchUnit user-domain-boundary guard (P0-Q3) - identity-core-api #64: JWT kid-based key registry (T3.C) - biometric-processor #67: F2 + F10 CI hygiene (drop pytest swallow + remove stale tests) - biometric-processor #68: alembic in runtime image + backfill async-iter fix (Task #81) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * chore(web-submodule): T-FRONTEND-HYGIENE P3 batch Bumps web-app to 319b457 (PR #67): - index.html title brand-neutralized - 9 setTimeout cleanups (TOTP/WebAuthn/NFC/StepUp/FaceVerify/etc.) - NotificationPanel polling pauses on hidden tab - CSP comment drift fixed in vite.config.ts - tfhub.dev / kaggle.com stripped from connect-src (post-MobileFaceNet) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(2026-05-04): roadmap refresh + CHANGELOG entry for Wave 1 - ROADMAP_OPTIMIZED_2026-05-02.md: post-deploy refresh (operator rebuild EXECUTED 2026-05-02 17:50–17:58 UTC; T2.1 proctoring direction = B; T2.2 user-domain decision = ArchUnit guard). - SESSION_STATUS_2026-05-02.md: T3.C kid-registry rollout instructions added to §5 (operator post-merge env steps). - CHANGELOG.md: Wave 1 batch — api PR #63/#64, bio PR #67/#68, web PR #67, CI/CD status, Copilot post-merge nit on NfcStep.tsx:96 queued. T-LOGIN-EDGE and T-SEC-TAIL still in flight; submodule pointer for api deliberately not bumped here. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * chore(api-submodule): T-SEC-TAIL DeviceController boundary + P2 cleanup Bumps identity-core-api 2d958c5 -> 19366c0: * fix(security): route WebAuthn credential writes through service boundary (T-SEC-TAIL §T4.4) (#66) * fix(security): reject ID-token replay against /oauth2/userinfo (SECURITY_REVIEW_2026-05-01) (#67) * feat(db): V57 — hand audit_logs partition lifecycle to pg_partman (concurrent agent's work, included in fast-forward) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(review): senior UI/UX designer review of verify + app — 2026-05-04 Comprehensive design review covering app.fivucsas.com (admin dashboard), verify.fivucsas.com (hosted login + embeddable widget), demo.fivucsas.com (Marmara BYS showcase), and fivucsas.com (brand cohesion). 35 prioritized findings (1 P0, 4 P1, 20 P2, 11 P3) with file paths, effort sizing, and agent-actionable flags. Verified against HEAD 319b457 to avoid restating items already shipped (Profile date-i18n, tenant hardcode, dead Redux, PWA navigateFallback, USER-BUG-1..10). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(review): senior DB engineer deep review — 2026-05-04 Comprehensive storage-tier review covering schema design, indexes, relations, views, functions, performance, backup, security, migration hygiene. 30 findings prioritised P0–P3. Headline P0s: - V57 on disk without V56 will brick Flyway on next deploy - User entity still missin…
This was referenced May 12, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
masterandmainhad diverged since the 2026-03-28 merge base.masterwas the active integration branch where the 2026-04-19 audit remediation, SEO PRs (#42-#47), and the 2026-05-11 session work (ROADMAP refresh + submodule pointer bumps + CHANGELOG entry, PR #50) all landed.mainaccumulated parallel work: the spoof-detector standalone restructure, the 2026-05-04 through 2026-05-09 investigation/audit doc waves, and PR #48 (branch protection across 5 repos with CICD_AUDIT_2026-05-04.md appended).This PR brings master's content into main so both branches can converge.
Reconciliation rules applied
ROADMAP.md(root)CHANGELOG.md.gitmodules606f1f4, bio750492c, docs78a9b4a, spoof-detectorcc73cf0, web-app096ed05, client-apps5ab3abbCICD_AUDIT_2026-05-04.mdarchive/2026-04-pre-roadmap-2028/*(most)INVESTIGATION_*_2026-05-07.md,SENIOR_*_2026-05-04.md, etc..env.example,CLAUDE.md,.github/workflows/deploy-landing.yml,.gitignoreVerification
git diff --cached origin/master -- ROADMAP.md CHANGELOG.md .gitmodulesis emptyCICD_AUDIT_2026-05-04.mdpreserved unmodified from main HEAD.gitmodulesFollow-up
A second PR (
chore(sync): main -> master post-reconciliation) will fast-forwardmasterto this merge commit so the two branches are byte-identical. Branch-protection requires PR even for that sync.Test plan
gh pr merge --squash --admin --delete-branch(admin bypass per CICD T3.1.d policy)main->mastergit log origin/main..origin/masterempty ANDgit log origin/master..origin/mainemptyGenerated with Claude Code.