Feature/scale - #2
Conversation
|
| GitGuardian id | GitGuardian status | Secret | Commit | Filename | |
|---|---|---|---|---|---|
| 36049876 | Triggered | Generic Password | 4b2033c | .github/workflows/ci.yml | 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 secret safely. Learn here the best practices.
- Revoke and rotate this secret.
- 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.
There was a problem hiding this comment.
Pull request overview
This PR advances the FDX “V2” scalability/security contract end-to-end: rotating refresh sessions + in-memory access tokens, preview/confirm participant imports with idempotency, presigned/direct uploads (including multipart), async “download all” gallery exports, and supporting infra/CI/model layout updates.
Changes:
- Add V2 auth/session lifecycle (refresh rotation, logout revocation) plus public invite/forgot/reset password flows in the webapp.
- Migrate public enrollment/gallery and org workflows (participant import preview/confirm, photo uploads) to V2 endpoints and direct uploads.
- Update deployment/tooling: new face-processing model layout + containers, pgvector image, nginx headers/CSP, CI workflow, and documentation refresh.
Reviewed changes
Copilot reviewed 70 out of 77 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| webapp/vite.config.js | Prettier-style formatting and consistent quoting. |
| webapp/src/pages/superadmin/Overview.jsx | Formatting; retains platform overview UI structure. |
| webapp/src/pages/superadmin/OrganizationUsers.jsx | Formatting; keeps org-admin invitation UI. |
| webapp/src/pages/superadmin/Organizations.jsx | Formatting/refactor for readability; policy editor remains functionally similar. |
| webapp/src/pages/superadmin/Logs.jsx | Formatting; clearer logs page component. |
| webapp/src/pages/public/ResetPassword.jsx | New public reset-password page calling V2 reset endpoint. |
| webapp/src/pages/public/Gallery.jsx | Switch public gallery to V2 contract with async ZIP export + per-photo download URLs. |
| webapp/src/pages/public/ForgotPassword.jsx | New public forgot-password page calling V2 forgot-password endpoint. |
| webapp/src/pages/public/Enrollment.jsx | Switch enrollment to V2 (consent + upload-url + direct upload + complete). |
| webapp/src/pages/public/AcceptInvite.jsx | Switch invite acceptance to V2 endpoint and cookie-based session. |
| webapp/src/pages/organization/Processing.jsx | Formatting-only refactor for readability. |
| webapp/src/pages/organization/Participants.jsx | Replace one-step import with validate/preview then confirm import flow. |
| webapp/src/pages/organization/Overview.jsx | Formatting-only refactor for readability. |
| webapp/src/pages/organization/Logs.jsx | Formatting-only refactor for readability. |
| webapp/src/pages/Login.jsx | Add forgot-password link; gate rendering on auth initialization loading state. |
| webapp/src/lib/api.js | New session model: in-memory access token + refresh-cookie rotation + request retry on 401; adds direct upload helpers. |
| webapp/src/context/PlatformContext.jsx | Add V2 participant-import preview/confirm; add V2 upload batches with checksums + multipart support. |
| webapp/src/context/AuthContext.jsx | Initialize session via refresh; add loading state; switch logout to V2 logout request. |
| webapp/src/components/ProtectedRoute.jsx | Block route decisions until auth initialization completes. |
| webapp/src/components/PageState.jsx | Formatting-only refactor for readability. |
| webapp/src/components/Modal.jsx | Formatting-only refactor for readability. |
| webapp/src/components/Modal.css | Formatting-only refactor for readability. |
| webapp/src/components/LogsTable.jsx | Formatting-only refactor for readability. |
| webapp/src/components/Icon.jsx | Formatting-only refactor for readability. |
| webapp/src/components/Gauge.jsx | Formatting-only refactor for readability. |
| webapp/src/components/Dropzone.css | Formatting-only refactor for readability. |
| webapp/src/components/DashboardShell.jsx | Make logout async before navigating. |
| webapp/src/components/DashboardShell.css | Formatting-only refactor for readability. |
| webapp/src/App.jsx | Register new public routes for forgot/reset password. |
| webapp/package.json | Add Prettier + format scripts for frontend/tooling. |
| webapp/package-lock.json | Lockfile updates for Prettier addition. |
| tools/verify_v2.mjs | New V2 acceptance/verification script covering refresh rotation, tenant isolation, idempotency, uploads, gallery export, etc. |
| tools/verify_models.sh | Update model manifest verification to new face-processing model paths. |
| tools/native_accurate_backend.py | Update model path layout + naming (recognition vs calculator) and warmup asset location. |
| run-platform.sh | Update startup checks to new model locations. |
| ruff.toml | Add Ruff configuration baseline. |
| README.md | Update docs links and explain V2 scope + new model locations + verification commands. |
| face-processing/service/requirements.txt | New shared requirements for containerized ML service. |
| face-processing/service/Dockerfile.gpu | Add CUDA runtime container build for GPU inference. |
| face-processing/service/Dockerfile | Update CPU ML container to new service requirements/assets. |
| face-processing/models/recognition/README.md | Add placement guidance for AdaFace model. |
| face-processing/models/MANIFEST.sha256 | Add checksums for required ONNX models in new layout. |
| face-processing/models/detection/README.md | Add placement guidance for RetinaFace model. |
| docs/workflow.txt | Remove legacy workflow text (superseded). |
| docs/workflow.md | Add structured workflow/architecture doc with diagrams. |
| docs/spec-implementation.md | Add V2 spec-to-implementation mapping + acceptance evidence notes. |
| docker-compose.yml | Switch to pgvector image; point ML service to new Dockerfile/volumes; add V2 env defaults; update healthcheck path. |
| docker-compose.aws.yml | Update model volume path + make FDX_DEVICE configurable. |
| deploy/nginx/default.conf | Add login rate limiting location; add metrics route; add security headers/CSP; forward request IDs. |
| deploy/aws/README.md | Update model placement instructions for AWS deploy. |
| deploy/aws/publish.sh | Update model checks and S3 upload paths; fix CDPATH handling; point ML build to new Dockerfile. |
| deploy/aws/platform.yml | Add S3 CORS + bucket policy for TLS-only; update userdata to new model paths. |
| backend/tests/test_security.py | Add tests for password hashing, opaque tokens, cosine bounds, and cross-tenant endpoint isolation. |
| backend/requirements.txt | Update backend deps (FastAPI, pgvector, argon2, multipart, etc.). |
| backend/app/serializers.py | Formatting/refactor of serializers; no behavioral changes evident in diff. |
| backend/app/models.py | Add V2 durable tables/fields (refresh sessions, tokens, consents, imports, upload batches, exports, vectors, etc.). |
| backend/app/integrations.py | Add presign PUT/GET + multipart helpers; general formatting. |
| backend/app/config.py | Add V2 policy/security/matching/upload settings; set JWT audience + shorter access token default. |
| backend/app/auth.py | Switch to Argon2id; add refresh session rotation + rate limiting helper; validate JWT aud + session revocation. |
| backend/alembic/versions/20260813_05_spec_verification.py | Forward-only migration to add pending enrollment upload fields. |
| backend/alembic/versions/20260813_04_gallery_exports.py | Forward-only migration to add gallery export table. |
| backend/alembic/versions/20260813_03_v2_foundation.py | Core V2 schema migration (vector extension, new columns/tables, backfill). |
| backend/alembic/versions/20260812_02_email_delivery_link.py | Migration formatting for delivery_id link/index. |
| backend/alembic/versions/20260812_01_complete_workflow.py | Migration formatting for thumbnail/enrollment/email outbox fields. |
| backend/alembic/env.py | Formatting-only refactor for readability. |
| backend/alembic.ini | Make Alembic paths relative to repo for portability. |
| .gitignore | Stop ignoring entire models dir; ignore only ONNX model binaries in new locations. |
| .github/workflows/ci.yml | Add CI: frontend formatting/lint/build/audit; backend ruff/pytest/pip-audit + migrations; infra lint; image builds. |
| .env.example | Document new V2 auth/upload/matching policy env vars. |
| .dockerignore | Exclude face-processing/models from Docker build context. |
Files not reviewed (1)
- webapp/package-lock.json: Generated file
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| (blob) => { | ||
| setImage(new File([blob], "selfie.jpg", { type: "image/jpeg" })); | ||
| setPreview(URL.createObjectURL(blob)); | ||
| streamRef.current?.getTracks().forEach((track) => track.stop()); | ||
| setCameraReady(false); | ||
| }, |
| async function submit(event) { | ||
| event.preventDefault(); | ||
| if (password !== confirm) { | ||
| setError("Passwords do not match."); | ||
| return; | ||
| } | ||
| const response = await fetch("/api/v2/auth/reset-password", { | ||
| method: "POST", | ||
| headers: { "Content-Type": "application/json" }, | ||
| body: JSON.stringify({ token, password }), | ||
| }); | ||
| const payload = await response.json(); | ||
| if (!response.ok) { | ||
| setError(payload?.error?.message ?? "Password reset failed."); | ||
| return; | ||
| } | ||
| navigate("/login", { replace: true }); | ||
| } |
| async function submit(event) { | ||
| event.preventDefault(); | ||
| setError(""); | ||
| const response = await fetch("/api/v2/auth/forgot-password", { | ||
| method: "POST", | ||
| headers: { "Content-Type": "application/json" }, | ||
| body: JSON.stringify({ email }), | ||
| }); | ||
| const payload = await response.json(); | ||
| if (!response.ok) { | ||
| setError( | ||
| payload?.error?.message ?? "Password reset could not be requested.", | ||
| ); | ||
| return; | ||
| } | ||
| setMessage(payload.data.message); | ||
| } |
No description provided.