feat(admin): implement admin endpoints for issuer management#1
Open
mathewsap45 wants to merge 47 commits into
Open
feat(admin): implement admin endpoints for issuer management#1mathewsap45 wants to merge 47 commits into
mathewsap45 wants to merge 47 commits into
Conversation
- Add require_analytics_auth dependency: accepts X-API-Key or admin Bearer JWT - Protect /analytics/rates, /analytics/issuers, /analytics/anomalies with auth - Keep POST /batch/verify public but rate-limited to 30 req/min per IP via slowapi - Add PyJWT and slowapi to requirements.txt - Add ANALYTICS_API_KEY to .env.example (stored in secrets manager, not hardcoded) Closes dev-fatima-24#114
- Add bruteForce.js middleware tracking failures per IP and per wallet - After 5 failed /auth/verify attempts in 10 min, block for 15 min (429) - Block events logged via audit log and logger.warn for alerting - recordSuccess() clears counters on successful login - Add BRUTE_FORCE_MAX_ATTEMPTS, BRUTE_FORCE_WINDOW_MS, BRUTE_FORCE_BLOCK_MS env vars Closes dev-fatima-24#110
- Add issuer_applications table to SQLite schema - Add POST /v1/onboarding/apply — authenticated providers submit name, license, country, wallet - Add GET /v1/onboarding/applications — admin lists all applications (filterable by status) - Add POST /v1/onboarding/applications/:id/review — admin approves/rejects; approval calls add_issuer on contract - Add addIssuer() helper to soroban.js - Add IssuerOnboarding.jsx page with self-service form - Extend AdminDashboard with pending applications table and approve/reject actions - Add /apply route to App.jsx nav Closes dev-fatima-24#120
- Create docs/roadmap.md with v0.1 (testnet MVP), v0.2 (security hardening), and v1.0 (mainnet launch) milestones, each with target dates and success criteria - Triage issues dev-fatima-24#110, dev-fatima-24#114, dev-fatima-24#116, dev-fatima-24#120 to v0.2 milestone in roadmap table - Add roadmap summary table to README.md linking to docs/roadmap.md Closes dev-fatima-24#116
…14-116-120-combined Feat/issues 110 114 116 120 combined
…r-codes fix: document contract error codes and map backend messages
feat: Implement dependency vulnerability audit across all services
- Add GitHub Actions workflow for CI/CD secret scanning - Add pre-commit hook configuration to block local commits - Add custom gitleaks config for Stellar keys, JWT secrets, API tokens - Add setup scripts for Linux/macOS and Windows - Add comprehensive documentation - Update README with setup instructions Implements multi-layered protection against accidental credential commits. Covers Stellar secret keys, JWT secrets, private keys, and API tokens.
- Add security headers to frontend Nginx configuration - Add security headers middleware to backend Express app - Implement CSP to restrict script sources and prevent XSS - Add X-Frame-Options DENY to prevent clickjacking - Add X-Content-Type-Options nosniff to prevent MIME sniffing - Add Referrer-Policy strict-origin-when-cross-origin - Add Permissions-Policy to disable unnecessary browser features - Create production Nginx config with HSTS enabled - Add automated testing scripts for Linux/macOS and Windows - Add comprehensive documentation with testing procedures - Add backend tests for security headers middleware - Update README with security headers information Protects Freighter wallet interactions from XSS and clickjacking attacks. Target: Grade A on securityheaders.com
- nginx: HTTP→HTTPS 301 redirect on port 80 - nginx: TLS 1.2+ only with hardened cipher suite - nginx: HSTS header max-age=31536000; includeSubDomains; preload - nginx: OCSP stapling enabled - nginx: security headers (X-Content-Type-Options, X-Frame-Options, Referrer-Policy) - docker-compose: expose ports 80+443, mount ./certs volume - docker-compose: add certbot service for Let's Encrypt auto-renewal - docs: add tls-setup.md with setup, verification, and production checklist Closes dev-fatima-24#105
- add jwtKeys.js: current key + up to 5 previous keys, runtime rotateKey() and reloadFromEnv() without service restart - embed kid in JWT header so verification is O(1) — no brute-force key search - auth middleware: tries current key first (by kid), falls back to previous keys so tokens issued before rotation remain valid during transition window - auth route: sign tokens with current key + kid - admin route: POST /admin/jwt/rotate endpoint (admin-only) for runtime rotation or env reload - .env.example: document JWT_KEY_ID and JWT_PREVIOUS_KEYS variables - docs: add jwt-key-rotation.md with procedure, transition window, and security notes Closes dev-fatima-24#107
- POST /admin/issuers — add issuer via add_issuer contract call - DELETE /admin/issuers/:address — revoke issuer via revoke_issuer - GET /admin/issuers — list authorized issuers via list_issuers simulation - Introduce 'admin' JWT role (separate from 'issuer' and 'patient') - Admin public key now receives 'admin' role on SEP-10 login - All three endpoints require admin JWT; 403 for any other role - Audit log entries on add/revoke actions - 13 tests covering auth, validation, and happy paths Closes dev-fatima-24#34
…Badge, Landing (dev-fatima-24#98) - Playwright visual regression tests in e2e/visual.spec.js - Covers: Landing page, NFTCard, VerificationBadge (verified + not-found) - Baseline screenshots committed to e2e/visual.spec.js-snapshots/ - CI visual job in e2e.yml uploads diff images as artifacts on failure - Fix pre-existing duplicate import in App.jsx - Fix pre-existing JSX syntax error in VerificationBadge.jsx Closes dev-fatima-24#98
…ttacks - add sanitize.js middleware: strips HTML/script tags, control chars, rejects null bytes, trims whitespace — applied recursively to all string fields in req.body, req.query, req.params - mount sanitizeInputs globally in app.js at the API boundary (after JSON parsing, before route handlers) - add sanitization.test.js covering XSS tags, control chars, null bytes, nested objects, and arrays Closes dev-fatima-24#108
…ement
- add multiSig.js middleware: M-of-N proposal/approval flow with TTL,
per-proposal audit logging, and configurable key holder allowlist
- wire requireMultiSig('onboarding_review') into POST /onboarding/applications/:id/review
- add POST /admin/multisig/approve endpoint for co-signers
- add GET /admin/multisig/proposals/:id for status checks
- .env.example: document MULTISIG_THRESHOLD, MULTISIG_KEY_HOLDERS, MULTISIG_PROPOSAL_TTL_MS
- docs: add admin-multisig.md with ceremony procedure, key holder guidance,
and emergency procedure
Closes dev-fatima-24#109
…suer-middleware feat: secure issuer middleware with on-chain verification and caching
…rity-issues-105-107-108-109 Fix/security issues 105 107 108 109
…ature/add-security-headers Add comprehensive security headers to prevent XSS and clickjacking
…ature/add-secret-scanning-protection Add secret scanning protection with Gitleaks
…reporting feat: implement comprehensive coverage reporting and threshold enforc…
- Add ContractPaused error variant (code 17) - Add Paused key to DataKey storage enum - Add pause() and unpause() admin-only functions - Add is_paused() read-only query function - Add require_not_paused() guard called by all state-changing functions (add_issuer, revoke_issuer, register_patient, mint_vaccination, revoke_vaccination) - verify_vaccination and other read-only functions remain available when paused - Emit ContractPaused and ContractUnpaused events on state change Closes dev-fatima-24#55
- Add ContractPaused error variant (code 17) - Add Paused key to DataKey storage enum - Add pause() and unpause() admin-only functions - Add is_paused() read-only query function - Add require_not_paused() guard called by all state-changing functions (add_issuer, revoke_issuer, register_patient, mint_vaccination, revoke_vaccination) - verify_vaccination and other read-only functions remain available when paused - Emit ContractPaused and ContractUnpaused events on state change Closes dev-fatima-24#55
…use-mechanism feat(contract): add pause/unpause mechanism for emergency stops
Tests cover all critical security properties (Issue dev-fatima-24#96): - Non-issuer (any address not in allowlist) cannot mint - Revoked issuer cannot mint - Transfer always fails regardless of caller and recipient - Transfer fails even for admin and for real token IDs - Non-admin cannot add issuers - Non-admin cannot revoke issuers - Paused contract rejects mint, add_issuer, revoke_issuer, register_patient - verify_vaccination remains available when paused - Unpause restores minting capability Closes dev-fatima-24#96
auth middleware tests (middleware-auth.test.js): - Valid JWT (patient and issuer roles) calls next() and sets req.user - Key rotation fallback: tries matching kid first, falls back to other keys - Missing Authorization header → 401 - Non-Bearer Authorization header → 401 - Invalid token string → 401 - Expired token → 401 - Token signed with unknown secret → 401 - Missing sub/role/wallet claims → 401 with specific message - Invalid role value → 401 - Empty role value → 401 issuer middleware tests (middleware-issuer.test.js): - Authorized issuer (on-chain) → next() called - Accepts wallet from req.user.publicKey fallback - Revoked/unauthorized issuer → 403 - Patient role → 403 (no on-chain check performed) - Missing req.user → 403 - Missing role → 403 - Missing wallet and publicKey → 401 - isAuthorizedIssuer throws → 500 Also fixes duplicate 'seed' key in package.json causing JSON parse error. Closes dev-fatima-24#97
- New AnalyticsDashboard page at /analytics route (issuer-only) - Bar chart (pure CSS) for vaccination rates by vaccine type - Issuer activity table with volume and last-active timestamp - Anomaly flags table with severity badges (high/medium/low) - Data auto-refreshes every 60 seconds via setInterval - Shows 'no anomalies' success state when list is empty - Graceful error state when analytics service is unreachable - Accessible: ARIA labels on chart, table, sections, live region for refresh time - Unit tests covering all sections, error state, auto-refresh, and anomaly badges Closes dev-fatima-24#19
…dleware-tests test(backend): add middleware unit tests for auth.js and issuer.js
…curity-invariant-tests test(contract): add security invariant tests
…ashboard-page feat(frontend): add analytics dashboard page
…8-visual-regression-tests feat(frontend): add visual regression tests for NFTCard, VerificationBadge, Landing
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
Implements the three admin endpoints required to manage authorized issuers on-chain, resolving EDOHWARES/VacciChain#34.
Changes
Backend
POST /v1/admin/issuers— callsadd_issueron the Soroban contract; requires admin JWTDELETE /v1/admin/issuers/:address— callsrevoke_issueron the Soroban contract; requires admin JWTGET /v1/admin/issuers— simulateslist_issuerscontract call; requires admin JWTadminJWT role (distinct fromissuerandpatient)ADMIN_PUBLIC_KEY) now receivesadminrole on SEP-10 loginTests
backend/tests/admin-issuers.test.jscovering auth enforcement, input validation, and happy paths for all three endpointsTesting
All 13 tests pass.
Closes EDOHWARES/VacciChain#34