Morningstar Credentials is a full-stack academic credentialing platform that combines W3C Verifiable Credentials, DID lifecycle management, governance workflows, and blockchain-backed issuance/verification flows.
Validated in this workspace:
npm run typecheck: passnpm test: pass (352/352)npm run test:coverage:strict: pass (352/352, coverage provider enforced)npm run build:check-warnings: passnpm run audit:all(network-enabled): pass (0moderate+ vulnerabilities in frontend and backend)
CI workflow jobs in .github/workflows/ci.yml:
- TypeScript Check
- Unit Tests
- Test Coverage
- Security Audit
- Production Build
- Deploy to GitHub Pages (main branch only)
- Docker Build (main branch only)
- Frontend: React + Vite (
src/) - Backend API: Express (
backend/server.js) - Persistence: JSON files in
backend/data/ - Auth model: user session tokens + role checks (
guest,student,verifier,issuer,governance) - External providers (optional by endpoint): Gemini, Pinata, SMTP, Turnstile
Protected write endpoints now require user access tokens and role authorization.
Flow:
POST /api/auth/session/startPOST /api/auth/session/bind-walletPOST /api/auth/session/refresh(when needed)POST /api/auth/role/request- Governance approval via
POST /api/auth/role/approveor bootstrap allowlist viaGOVERNANCE_BOOTSTRAP_WALLETS
Legacy static API bearer token model is no longer the active write-route authorization pattern.
npm run setup && npm run dev:allWhat this does:
- Creates
.env.localfrom.env.exampleif missing - Creates
backend/.envfrombackend/.env.exampleif missing - Adds safe local defaults (including
VITE_API_PROXY_URLandALLOWED_ORIGINS) - Installs root and backend dependencies
- Starts backend (
:3001) and frontend (:3000by default)
npm run setup:docker && npm run docker:upStop containers:
npm run docker:down- Node.js 20+
- npm 10+
- Docker Desktop (only for Docker workflow)
Source of truth: .env.example.
Minimum recommended:
VITE_API_PROXY_URL=http://localhost:3001VITE_APP_URL=http://localhost:3000VITE_REOWN_PROJECT_ID=<walletconnect/reown project id>
Production frontend should avoid direct API keys and use backend proxy endpoints.
Source of truth: backend/.env.example.
Minimum recommended for local:
AUTH_TOKEN_SECRET=<strong-random-secret>EMAIL_TRANSPORT_MODE=mockALLOWED_ORIGINS=http://localhost:3000,http://127.0.0.1:3000
For governance bootstrap in local/admin setup:
GOVERNANCE_BOOTSTRAP_WALLETS=0x...
For production external API features:
GEMINI_API_KEYPINATA_API_KEYPINATA_SECRET_KEY- SMTP values when
EMAIL_TRANSPORT_MODE=smtp
npm run dev # frontend only
npm run dev:all # backend + frontend
npm run build
npm run preview
npm run typecheck
npm test
npm run test:coverage
npm run test:coverage:strict
npm run build:check-warnings
npm run audit:allcd backend
npm start
npm run devGET /api/healthGET /healthGET /api/email/health
POST /api/auth/session/startPOST /api/auth/session/bind-walletPOST /api/auth/session/refreshPOST /api/auth/session/logoutGET /api/auth/session/mePOST /api/auth/student/email/startPOST /api/auth/student/email/verifyPOST /api/auth/role/requestGET /api/auth/role/requests(governance)POST /api/auth/role/approve(governance)
GET/POST/PATCH /api/governance/institutions*(POST/PATCHrequire governance role)GET /api/didGET /api/did/:didPOST/PUT/DELETE /api/did*(issuer or governance)POST /api/blockchain/transaction(issuer or governance)POST /api/blockchain/block(governance)POST /api/blockchain/private/store(issuer or governance)POST /api/email/notify(issuer or governance)POST /api/mfa/send-otp(issuer or governance)
POST /api/gemini/schemaPOST /api/gemini/trustPOST /api/ipfs/uploadPOST /api/ipfs/pin
node scripts/verify-base58.js
API_AUTH_TOKEN=<user-access-token> node scripts/verify-blockchain.js
API_AUTH_TOKEN=<user-access-token> node scripts/verify-did.js- Dependency audit is enforced at
moderate+severity in CI. package-lock.jsonpins patched dependency resolutions for known advisories (bn.js,rollup).- CORS, rate limiting, role guards, OTP, and optional Turnstile are enforced server-side.
- In local offline environments,
npm run audit:allmay report connectivity-tolerated skips; CI treats connectivity failures as blocking.
- Backend persistence is file-based (
backend/data/*.json), so multi-instance production needs shared persistent storage. test:coverage:strictcurrently enforces coverage provider availability, not minimum percentage thresholds.- Large client chunks still exist for wallet/veramo/reown bundles; functional but optimization headroom remains.
.
|- src/ # frontend app and services
|- backend/ # express API proxy/server
|- scripts/ # setup, audit, validation utilities
|- tests/ # vitest suites
|- docker-compose.yml # frontend + backend containers
`- .github/workflows/ # CI/CD
See repository license metadata and package.json for dependency licensing context.