Technical Document
Reference Application

Technical Documentation

Supporting document for the Live Reference Application — Section 10: Added Value.
Proposal for Consultancy Services — Senior Web Frontend Developer Consultant (TCIS).

Version
1.0
Date
August 28, 2026
Prepared By
Eng. Depute N.Alphonse, PMP®
Classification
Confidential

Executive Summary

This document is a companion technical documentation for the Live Reference Application described in Section 10: Added Value of the Proposal for Consultancy Services — Senior Web Frontend Developer Consultant (TCIS). It details the end-to-end security architecture implemented for the AfDB enterprise portal: MFA-protected authentication flows, SSO-IDP federation with Google Workspace and Azure AD, OWASP Top 10 hardened frontend middleware, and a fully documented API layer — demonstrating the secure, production-ready web applications that the consultancy engagement will deliver.

The AfDB Reference Application is a modern, security-first enterprise web system designed to manage project data, reporting, and operational workflows for the African Development Bank. This live reference application demonstrates in practice the capabilities described in the consultancy proposal — a working, production-deployed system that evaluators can inspect, interact with, and verify.

MFA-Protected Access

Multi-factor authentication with TOTP authenticator apps and backup recovery codes

Implemented & Verified

SSO-IDP Federation

Single Sign-On via OAuth2/OIDC with Google Workspace and Microsoft Azure AD

Implemented & Verified

OWASP Top 10 Compliant

Industry-standard security hardening against the most critical web application threats

Implemented & Verified

The system is built as a microservices architecture with a dedicated Authentication Gateway (Beta Backend) that handles all security concerns, and a Data Service (Core Backend) that serves business logic. Both frontends authenticate exclusively through the hardened gateway.

Key Outcomes
  • Zero-trust authentication model with layered security
  • Protection against all OWASP Top 10 vulnerability categories
  • Enterprise SSO federation with Google and Microsoft/Azure AD
  • Account lockout protection against brute-force attacks
  • Input sanitization blocking NoSQL injection and XSS attacks
  • Comprehensive audit logging for all security events

Login Credentials & URLs

Use these credentials to access the live demo portals. Both portals share the same authentication backend (Beta). Login requires email OTP verification — after entering credentials, check the user's Yopmail inbox for the 6-digit code.

Portal URLs

PortalURLPurpose
Auth Portalhttp://localhost:3000/loginAuthentication gateway — login, MFA, SSO, password reset
Enterprise Dashboardhttp://localhost:3001/loginBusiness application — dashboard, projects, monitoring
API Documentationhttp://localhost:4000/api-docsScalar API reference — explore all backend endpoints

Demo Accounts

RoleEmailPasswordPortalPermissions
Admin afdbadmin@yopmail.com Admin@123 :3000 · :3001 Full access — all features, user management, monitoring
Viewer afdbaviewer@yopmail.com Viewer@123 :3000 · :3001 Read-only access — view dashboards, projects, reports
Manager afdbmanager@yopmail.com Manager@123 :3000 · :3001 Project management — create, edit, approve projects (role: staff)
Re-seeding Credentials
If credentials stop working (e.g., after a database restart), re-run the seed script:
cd afdb_beta_backend && node src/seed/users.js

System Architecture

2.1 High-Level Architecture

AfDB Secure Portal — High-Level System Architecture

2.2 Authentication Flow

Step 1User LoginEmail + Password
Step 2ValidateCredentials check
Step 3MFA CheckIs MFA enabled?
Step 4VerifyTOTP or Backup
Step 5JWT IssuedAccess granted
Account Lockout Branch
If 5 consecutive failed attempts occur at Step 2, the account is locked for 15 minutes (HTTP 423). The user receives a clear warning with remaining attempt count after the 3rd failure.

2.3 Microservices Design — Beta & Core

The platform is built as two separate microservices that work together. AfDB Beta handles identity (who you are), and AfDB Core handles business operations (what you do). This separation of concerns ensures that authentication logic is isolated, independently scalable, and reusable across future services.

User Browser
localhost:3000 / :3001
HTTP
Beta Backend
Port 4000 · afdb_beta DB
"Who are you?"
JWT Token
Core Backend
Port 4001 · afdb_core DB
"What do you do?"

Service Comparison

ConcernBeta (port 4000)Core (port 4001)
Databaseafdb_beta — users, tokens, sessionsafdb_core — projects, activities, reports
API Endpoints/auth/login, /auth/signup, /auth/verify-mfa, /auth/refresh, /auth/logout, /sso/*/projects/*, /dashboard/*
SecurityHelmet, rate limiting, input sanitization, security headers, OWASP complianceBasic Helmet + CORS; trusts Beta's JWT
SSO ProvidersGoogle OAuth2, Microsoft / Azure ADNone — validates tokens issued by Beta
Frontend PagesLogin, Signup, MFA verification, Password reset, SSO callbackDashboard, Projects, Reports
RoleAuth Gateway — the gatekeeperBusiness Engine — the application

Concrete Examples

Example 1 — User Login Flow
Step 1Open LoginUser visits localhost:3000/login
Step 2POST CredentialsPOST localhost:4000/api/v1/auth/login
Step 3Beta Responds{ "mfaRequired": true, "userId": "abc123" }
Step 4Verify MFAPOST /api/v1/auth/verify-mfa with TOTP code
Step 5JWT IssuedBeta returns accessToken + refreshToken
Step 6RedirectFrontend stores tokens, navigates to /dashboard
Example 2 — Accessing a Project (Cross-Service)
Step 1User clicks projectAt localhost:3001/projects
Step 2Core Frontend calls Core BackendGET localhost:4001/api/v1/projects with Authorization: Bearer eyJ...
Step 3Core validates JWTSame secret as Beta — token verified
Step 4Data returnedProjects list from afdb_core database

If the JWT is missing or invalid, Core returns 401 Unauthorized — the user must re-authenticate through Beta.

Example 3 — Single Sign-On (SSO)
Step 1User clicks "Sign in with Google"On Beta Frontend login page
Step 2Redirect to Google OAuthBeta initiates OAuth2 flow
Step 3Google callbackGET /api/v1/sso/callback/google?code=...
Step 4Beta creates/finds userIssues JWT tokens — same as regular login
Step 5Access grantedUser authenticated across both frontends via shared JWT
Example 4 — Token Refresh
Step 1Access token expiresAfter 30 minutes (configurable via JWT_ACCESS_EXPIRY)
Step 2Frontend calls BetaPOST /api/v1/auth/refresh with refreshToken
Step 3New token issuedBeta returns fresh accessToken — Core continues working seamlessly
Key Insight

Beta is the gatekeeper — it issues the JWT that Core trusts. Core never handles passwords or MFA; it just validates the token Beta signed. This means authentication logic can be updated, scaled, or replaced independently without touching business logic.

2.4 Cross-Service Activity Monitoring (Diagnostic Tool)

Building on the microservices design, the platform includes a real-time activity monitoring system that turns Core into a diagnostic tool for tracking every user action performed through the Beta auth portal. Beta emits structured activity events to Core via an internal API, and Core provides a monitoring dashboard for security analysis and operational awareness.

Beta Backend
Auth events emitted
x-api-key
Core Backend
Stored + aggregated
JWT
Monitoring Dashboard
localhost:3001/monitoring

Tracked Auth Events

EventAction KeySeverityStatusSource Controller
Successful loginauth.logininfosuccessauth.controller
Failed loginauth.login_failedwarningfailureauth.controller
Account lockedauth.account_lockedcriticalfailureauth.controller
MFA verifiedauth.mfa_verifiedinfosuccessauth.controller
MFA failedauth.mfa_failedwarningfailureauth.controller
Account signupauth.signupinfosuccessauth.controller
Password changedauth.password_changedinfosuccessauth.controller
Token refreshauth.token_refreshinfosuccessauth.controller
Logoutauth.logoutinfosuccessauth.controller
SSO loginauth.sso_logininfosuccesssso.controller
SSO callback failedauth.sso_failedwarningfailuresso.controller
MFA enabledauth.mfa_enabledinfosuccessmfa.controller
MFA disabledauth.mfa_disabledwarningsuccessmfa.controller
Backup codes regeneratedauth.backup_codes_regeneratedwarningsuccessmfa.controller

Activity Event Schema

Each event emitted by Beta and stored in Core includes the following diagnostic fields:

{
  "action":       "auth.login",           // Event type identifier
  "userId":       "66a1b2c3d4e5f6...",  // User who performed the action
  "userName":     "John Doe",             // Display name
  "userEmail":    "john@afdb.org",        // User email address
  "severity":     "info",                 // info | warning | critical
  "status":       "success",              // success | failure
  "ipAddress":    "192.168.1.42",         // Client IP (from x-forwarded-for)
  "userAgent":    "Mozilla/5.0...",       // Browser/device string
  "source":       "beta",                 // Originating service
  "details":      { "role": "admin" },    // Arbitrary extra context
  "createdAt":    "2026-08-29T10:30:00Z"  // Timestamp (auto)
}

Monitoring Dashboard Features

The Core frontend at localhost:3001/monitoring provides a full diagnostic interface:

Summary Cards

Total events (24h), active users, failed attempts, and critical alerts — at a glance.

Event Breakdown

Clickable chips showing event distribution — click any action type to filter the feed.

Activity Feed

Paginated list with severity badges, user info, IP addresses, timestamps, and event details.

Filters & Drill-Down

Filter by action type, severity, status. Click any user to see their full activity timeline.

Activity API Endpoints

MethodEndpointAuthPurpose
POST/api/v1/activitiesx-api-key (internal)Beta emits events to Core
GET/api/v1/activitiesJWT (frontend)Paginated activity feed with filters
GET/api/v1/activities/statsJWT (frontend)Aggregated stats (24h/7d breakdowns)
GET/api/v1/activities/users/:idJWT (frontend)Per-user activity timeline
Design Principle

The activity emitter uses a fire-and-forget pattern — Beta sends events to Core via HTTP POST and never blocks on failures. If Core is temporarily unavailable, auth operations continue normally. Events are logged as warnings but never interrupt the user experience. This ensures the monitoring layer adds zero risk to the authentication flow.

Technology Stack

3.1 Frontend

TechnologyVersionPurpose
Next.js15.xReact framework with SSR/SSG
React19.xUI component library
TypeScript5.5.xType-safe development
Tailwind CSS3.4.xUtility-first styling
Ant Design5.20.xEnterprise UI components
TanStack React Query5.51.xServer state management
Axios1.7.xHTTP client with interceptors
Lucide React1.34.xIcon library
next-themes0.4.xDark/light mode support

3.2 Backend

TechnologyVersionPurpose
Node.js + Express4.21.xAPI server framework
TypeScript5.5.xType-safe development
MongoDB + Mongoose8.6.xPrimary data store (NoSQL)
Redis + ioredis5.4.xCaching & session store
JSON Web Token9.0.xToken-based authentication
bcryptjs2.4.xPassword hashing (12 rounds)
otplib13.5.xTOTP multi-factor authentication
Helmet7.1.xHTTP security headers
express-rate-limit7.4.xBrute-force protection
QRCode1.5.xMFA setup QR generation
Winston3.14.xStructured logging
ScalarlatestAPI documentation

3.3 Infrastructure

ComponentTechnologyPort
Beta FrontendNext.js3000
Core FrontendNext.js3001
Beta Backend (Auth Gateway)Express.js4000
Core Backend (Data Service)Express.js4001
DatabaseMongoDB27017
CacheRedis6379
API DocumentationScalar4000/api-docs

Security Implementation: MFA-Protected Access

4.1 Overview

Multi-Factor Authentication (MFA) adds a critical second layer of verification beyond passwords. Users must provide both something they know (password) and something they have (authenticator app or backup code).

4.2 TOTP Implementation

PropertyDetail
AlgorithmTOTP per RFC 6238 via otplib v13
Secret GenerationCryptographically random 32-character base32 secret
QR CodeGenerated as data URL for authenticator app scanning
VerificationTime-windowed token validation with drift tolerance
Issuer Label"AfDB Secure Portal"

4.3 Backup Codes

PropertyDetail
Quantity10 unique codes per user
Format8-character uppercase hexadecimal (e.g., A3F7B2C1)
Storagebcrypt-hashed (10 rounds) — plaintext never stored
UsageOne-time use; marked used: true after verification
RegenerationUsers can generate a fresh set of 10 codes anytime
WarningSystem alerts when 3 or fewer codes remain

4.4 MFA API Endpoints

MethodEndpointAuthDescription
POST/api/v1/mfa/setupYesGenerate MFA secret & QR code
POST/api/v1/mfa/verifyYesVerify TOTP token and enable MFA
POST/api/v1/mfa/verify-backupYesVerify a backup code
POST/api/v1/mfa/regenerate-backup-codesYesGenerate new backup code set
GET/api/v1/mfa/statusYesCheck MFA status & remaining codes
POST/api/v1/mfa/disableYesDisable MFA and clear secrets

4.5 MFA User Flow

EnrollScan QRAuthenticator app
VerifyEnter TOTP6-digit code
LoginCredentialsEmail + password
MFASecond FactorTOTP or backup
AccessDashboardJWT issued

Email OTP Verification

5.1 Overview

The platform implements email-based One-Time Password (OTP) verification across all authentication flows — login, registration, and password reset. Every user who logs in must verify their identity via a 6-digit code sent to their email address, providing a robust second factor that doesn't require a separate authenticator app.

Login Verification

6-digit code sent after credentials verified — required for every login attempt

Registration Verification

Email ownership confirmed before account creation — prevents fake registrations

Password Reset

Secure code required before password change — protects account recovery flow

5.2 OTP Architecture

PropertyDetail
Code Format6-digit numeric code (100000–999999)
StorageRedis with TTL-based auto-expiry
Expiry600 seconds (10 minutes) — matches countdown timer in UI
Key Pattern{purpose}_otp:{identifier} — e.g., login_otp:userId, register_otp:email, reset_otp:email
DeliverySMTP via Nodemailer with embedded logo (CID attachment)
SecuritySingle-use (deleted from Redis after verification), rate-limited endpoints
Enumeration PreventionPassword reset returns success even for unregistered emails

5.3 Authentication Flows with OTP

Login Flow (Email OTP as 2FA)

1Enter CredentialsEmail + password
2OTP Sent6-digit code via email
3Verify CodeEnter or paste code
4JWT IssuedAccess + refresh tokens
5DashboardAuthenticated access

Registration Flow (Email Verification)

1Fill FormName, email, password
2OTP SentVerification code emailed
3Verify CodeConfirm email ownership
4Account CreatedUser record + tokens
5DashboardAuto-logged in

Password Reset Flow

1Enter EmailRegistered email address
2OTP SentReset code emailed
3Verify CodeEnter 6-digit code
4New PasswordSet new password
5DoneRedirect to login

5.4 Professional Email Templates

OTP emails use professional, branded HTML templates with the AfDB logo embedded via CID (Content-ID) attachment. Each purpose has a distinct accent color and messaging:

PurposeAccent ColorSubject Line FormatIcon
2FA Setup■ Green (#009A44){OTP} is your AfDB 2FA Verification Code
Login■ Blue (#1565C0){OTP} is your AfDB Login Verification Code
Registration■ Green (#009A44){OTP} is your AfDB Registration Verification Code
Password Reset■ Orange (#E65100){OTP} is your AfDB Password Reset Code
Email Template Features
  • Embedded Logo — AfDB logo rendered inline via CID attachment (works in all email clients)
  • Table-based HTML — Maximum compatibility across Outlook, Gmail, Apple Mail, and mobile clients
  • MSO Conditionals — Special handling for Microsoft Outlook rendering
  • Responsive Design — Media queries for mobile devices (max-width: 600px)
  • Security Reminder — Warning to never share the verification code
  • Branded Footer — AfDB address (Abidjan, Côte d'Ivoire), copyright notice
  • Purpose-Specific Styling — Each email type has distinct color, icon, and messaging

5.5 Frontend OTP UX

The OTP verification component provides a polished user experience:

  • 6 individual input fields — One per digit, auto-focus advancement
  • Paste support — Users can paste a full 6-digit code (e.g., from email); digits are distributed across fields automatically
  • Countdown timer — 10:00 minute countdown matching the Redis TTL, displayed below the OTP fields
  • Color-coded expiry — Gray (normal) → Orange (≤2 min remaining) → Red (expired)
  • Auto-disable on expiry — Verify button disabled when code expires; message prompts to resend
  • Resend functionality — New code sent, timer resets to 10:00
  • Auto-verify — When all 6 digits are entered, verification is submitted automatically

5.6 Retrieving OTP During Testing (Yopmail)

The demo environment uses Yopmail as the email provider for testing. Yopmail is a disposable email service that allows anyone to view the inbox of any @yopmail.com address without a password.

How to Get the OTP Code
  1. Attempt login at http://localhost:3000/login with credentials (e.g., afdbadmin@yopmail.com)
  2. After credentials are accepted, the UI will show the OTP verification screen
  3. Open a new browser tab and go to https://yopmail.com
  4. Type the email username in the inbox field (e.g., afdbadmin) — no need to type @yopmail.com
  5. Click "Check Inbox" (or the arrow button)
  6. Find the email with subject like "123456 is your AfDB Login Verification Code"
  7. The 6-digit OTP is displayed prominently in the email body — copy or note it
  8. Enter the code in the OTP fields on the login page (or paste all 6 digits at once)
Important Notes
  • OTP expires in 10 minutes — if the timer reaches zero, click "Resend Code" to get a new one
  • Yopmail inboxes are public — anyone can read emails sent to @yopmail.com addresses. Never use for production!
  • Direct inbox link — You can also go directly to https://yopmail.com/en/?afdbadmin (replace afdbadmin with the username)
  • Email may take 10–30 seconds — SMTP delivery is not instant; refresh the Yopmail inbox if the email doesn't appear immediately

5.7 OTP API Endpoints

MethodEndpointAuthDescription
POST/api/v1/auth/send-login-otpNoSend login OTP (requires userId from login response)
POST/api/v1/auth/verify-login-otpNoVerify login OTP and issue JWT tokens
POST/api/v1/auth/send-register-otpNoSend registration OTP (requires email)
POST/api/v1/auth/verify-register-otpNoVerify registration OTP and create account
POST/api/v1/auth/send-reset-otpNoSend password reset OTP (requires email)
POST/api/v1/auth/verify-reset-otpNoVerify reset OTP and update password
POST/api/v1/auth/send-otpYesSend OTP for 2FA setup (authenticated user)
POST/api/v1/auth/verify-otpYesVerify 2FA setup OTP

5.8 SMTP Configuration

Email delivery is configured via environment variables in the Beta Backend:

SMTP_HOST=smtp.hostinger.com
SMTP_PORT=465
SMTP_USER=no-reply@atradezone.ca
SMTP_PASSWORD=<smtp-password>
SMTP_FROM=no-reply@atradezone.ca
VariableDescriptionDefault
SMTP_HOSTSMTP server hostnamesmtp.hostinger.com
SMTP_PORTSMTP port (465 for SSL, 587 for TLS)465
SMTP_USERSMTP authentication username—
SMTP_PASSWORDSMTP authentication password—
SMTP_FROMSender email address (From header)no-reply@atradezone.ca

Security Implementation: SSO-IDP Federation

6.1 Overview

Single Sign-On (SSO) federation allows users to authenticate through their organization's existing identity provider without managing separate credentials. This implementation follows the OAuth 2.0 Authorization Code Flow.

6.2 Supported Identity Providers

ProviderProtocolAuthorization EndpointUser Info Endpoint
GoogleOAuth 2.0 / OIDCaccounts.google.com/o/oauth2/v2/authgoogleapis.com/oauth2/v2/userinfo
Microsoft / Azure ADOAuth 2.0 / OIDClogin.microsoftonline.com/{tenant}/oauth2/v2.0/authorizegraph.microsoft.com/v1.0/me

6.3 Security Measures

MeasureImplementation
CSRF ProtectionCryptographic state parameter (crypto.randomBytes(32)) validated with timing-safe comparison
Token ExchangeServer-side code exchange (never exposed to client)
State ExpiryStates expire after 10 minutes to prevent replay attacks
Auto-ProvisioningNew SSO users automatically created with viewer role
Account LinkingExisting accounts linked to SSO provider on first login
Provider DiscoveryOnly configured providers appear (no information leakage)

6.4 SSO API Endpoints

MethodEndpointAuthDescription
GET/api/v1/sso/providersNoList available SSO providers
GET/api/v1/sso/initiate/:providerIdNoStart OAuth flow, returns authorization URL
GET/api/v1/sso/callback/:providerIdNoHandle OAuth callback with authorization code

6.5 SSO Authentication Sequence

1Click SSOUser initiates
2Get Auth URLBackend generates state
3RedirectTo identity provider
4AuthenticateUser logs in at IDP
5CallbackCode exchanged for tokens
6JWT IssuedUser authenticated

Security Implementation: OWASP Top 10 Compliance

7.1 Compliance by Category

A01: Broken Access Control

ControlImplementationStatus
Security HeadersHelmet.js with strict Content Security PolicyVerified
CORSRestricted to approved origins onlyVerified
X-Frame-OptionsDENY — prevents clickjackingVerified
Auth MiddlewareAll protected routes require valid JWTVerified
Role-Based Accessadmin, staff, viewer roles enforcedVerified

A02: Cryptographic Failures

ControlImplementationStatus
Password Hashingbcrypt with 12 salt roundsVerified
Transport SecurityHSTS with 1-year max-ageVerified
Token SecurityJWT with short expiry (30 minutes)Verified
Refresh TokensUUID v4, stored server-side, revocableVerified
Body Size Limit10KB maximum request bodyVerified
Cache PreventionCache-Control: no-store on all responsesVerified

A03: Injection

ControlImplementationStatus
NoSQL InjectionBlocks MongoDB operators ($gt, $regex, $where, etc.) as both values AND keysVerified
XSS InjectionBlocks <script>, javascript:, on\w+=, <iframe>, <object>Verified
Key SanitizationReplaces $ and . in object keys with _Verified
String Length10,000 character maximum per valueVerified
Parameterized QueriesMongoose ODM prevents direct query injectionVerified
Live Test Evidence
NoSQL Injection: {"email": {"$gt": ""}} → 400 "Invalid input detected"
XSS Injection: {"firstName": "<script>alert(1)</script>"} → 400 "Invalid input detected"

A04: Insecure Design

ControlImplementationStatus
API Rate Limiting100 requests/minute (general API)Verified
Login Rate Limiting5 attempts per 15 minutes per IPVerified
Account Lockout5 failed logins → 15-minute lockoutVerified
Password PolicyOWASP-compliant strength requirementsVerified

A05: Security Misconfiguration

ControlImplementationStatus
HelmetComprehensive HTTP header hardeningVerified
X-Powered-ByRemoved from responsesVerified
Permissions-PolicyCamera, microphone, geolocation disabledVerified
Cross-Origin PoliciesCOEP, COOP, CORP all enforcedVerified
Error HandlingCentralized handler prevents stack trace leakageVerified

A07: Identification & Authentication

ControlImplementationStatus
Account Lockout5 attempts → 15 min lock, with user feedbackVerified
Password StrengthMin 8 chars, uppercase, lowercase, digit, special charVerified
MFATOTP + backup codesVerified
Session ManagementJWT access (30min) + refresh (30 days) tokensVerified
Token RevocationAll tokens revoked on password change or logoutVerified

A09: Logging & Monitoring

ControlImplementationStatus
HTTP LoggingMorgan combined format → Winston structured logsVerified
Security EventsMFA enable/disable, backup code usage, account lockoutVerified
Auth EventsLogin success/failure, token refresh, logoutVerified
Health Check/health endpoint for monitoringVerified

7.2 Security Middleware Stack

The middleware stack is ordered for defense-in-depth. Each layer processes the request before it reaches the route handler:

1
Helmet — Security response headers (CSP, HSTS, X-Frame)
2
Security Headers — Cache prevention, Permissions-Policy, X-XSS-Protection
3
CORS — Origin validation, credential control
4
Body Parser — JSON parsing with 10KB size limit
5
Input Sanitizer — NoSQL injection & XSS pattern detection
6
Morgan Logger — HTTP request logging (combined format)
7
Rate Limiter — 100 req/min general, 5 login attempts/15 min
8
Auth Middleware — JWT validation, user loading, role checking
9
Error Handler — Centralized error handling, no stack trace leakage

Verified HTTP Response Headers

X-Frame-Options: DENY
X-Content-Type-Options: nosniff
Strict-Transport-Security: max-age=31536000; includeSubDomains
Content-Security-Policy: default-src 'self'; script-src 'self' 'unsafe-inline'...
Referrer-Policy: strict-origin-when-cross-origin
Permissions-Policy: camera=(), microphone=(), geolocation=(), interest-cohort=()
Cache-Control: no-store
X-XSS-Protection: 1; mode=block

API Reference

8.1 Interactive API Documentation (Scalar)

The Beta Backend provides a modern, interactive API documentation powered by Scalar. This allows you to explore, test, and understand all available endpoints directly from your browser.

Scalar API Docs

Interactive documentation with "Try it" functionality

http://localhost:4000/api-docs
OpenAPI JSON Spec

Raw OpenAPI 3.0 specification for import into tools

http://localhost:4000/api-docs.json
Scalar Features
  • Try it — Execute API requests directly from the documentation
  • Code snippets — Auto-generated examples in curl, JavaScript, Python, and more
  • Search — Quickly find endpoints across Auth, MFA, and SSO
  • Dark mode — Toggle between light and dark themes
  • Import to Postman — Download the JSON spec and import into Postman for advanced testing

8.2 System Services & Ports

The AfDB platform consists of four services that work together in a microservices architecture:

ServicePortURLResponsibility
Beta Frontend 3000 http://localhost:3000 Authentication UI — Login, Signup, MFA verification
Beta Backend 4000 http://localhost:4000 Authentication Gateway — MFA, JWT, SSO-IDP, OWASP security
Core Frontend 3001 http://localhost:3001 Application UI — Dashboard, Projects, Reports
Core Backend 4001 http://localhost:4001 Data Service — Business logic, project management

8.3 Service Communication Flow

The diagram below illustrates how the frontends and backends communicate:

1
User Browser Accesses http://localhost:3000 (Beta Frontend) or http://localhost:3001 (Core Frontend)
2
Frontend → Backend API Calls Frontend sends requests to http://localhost:4000/api/v1/* for authentication (login, MFA, SSO)
3
JWT Token Flow Beta Backend issues JWT access/refresh tokens. Frontend stores tokens and includes them in Authorization: Bearer <token> header
4
Core Backend Authentication Core Backend validates JWT tokens by verifying with Beta Backend or shared secret. Protected endpoints require valid tokens.
Important: Base URLs
  • Frontend API calls: Use NEXT_PUBLIC_API_URL=http://localhost:4000/api/v1
  • API Documentation: Available at http://localhost:4000/api-docs
  • OpenAPI Spec: Available at http://localhost:4000/api-docs.json

8.4 Authentication Endpoints

MethodEndpointAuthDescription
POST/api/v1/auth/loginNoAuthenticate with email/password (returns mfaRequired: true)
POST/api/v1/auth/send-login-otpNoSend login OTP to user's email
POST/api/v1/auth/verify-login-otpNoVerify login OTP and receive JWT tokens
POST/api/v1/auth/signupNoRegister new account
POST/api/v1/auth/send-register-otpNoSend registration verification OTP
POST/api/v1/auth/verify-register-otpNoVerify registration OTP and create account
POST/api/v1/auth/send-reset-otpNoSend password reset OTP
POST/api/v1/auth/verify-reset-otpNoVerify reset OTP and update password
POST/api/v1/auth/send-otpYesSend OTP for 2FA setup
POST/api/v1/auth/verify-otpYesVerify 2FA setup OTP
POST/api/v1/auth/verify-mfaNoVerify MFA token (TOTP or backup code)
POST/api/v1/auth/change-passwordYesChange password (revokes all tokens)
POST/api/v1/auth/refreshNoRefresh access token
POST/api/v1/auth/logoutYesRevoke all tokens
GET/api/v1/auth/meYesGet current user profile

8.5 MFA Endpoints

MethodEndpointAuthDescription
POST/api/v1/mfa/setupYesGenerate MFA secret & QR code
POST/api/v1/mfa/verifyYesVerify TOTP and enable MFA
POST/api/v1/mfa/verify-backupYesVerify backup code
POST/api/v1/mfa/regenerate-backup-codesYesRegenerate backup codes
GET/api/v1/mfa/statusYesGet MFA status
POST/api/v1/mfa/disableYesDisable MFA

8.6 SSO Endpoints

MethodEndpointAuthDescription
POST/api/v1/sso/handoffNoSSO handoff from external IDP
POST/api/v1/sso/generateNoGenerate SSO handoff token
GET/api/v1/sso/providersNoList configured SSO providers
GET/api/v1/sso/initiate/:providerIdNoStart OAuth2 flow
GET/api/v1/sso/callback/:providerIdNoOAuth2 callback handler

Testing Scenarios & Results

9.1 Authentication Tests

#ScenarioInputExpected ResultActual ResultStatus
1Valid loginafdbadmin@yopmail.com / Admin@123200 OK, mfaRequired: true200 OK, OTP sentPASS
2Invalid passwordafdbadmin@yopmail.com / wrongpass401 Invalid credentials401 Invalid credentialsPASS
3Missing fields{}400 Required fields400 Email and password requiredPASS
4Account lockout5 consecutive wrong passwords423 Account locked423 Locked, 15min cooldownPASS
5Lockout warning3rd failed attemptWarning shownOrange alert, remaining countPASS
6New user signupValid registration data201 Created, JWT201 Created, auto-loginPASS
7Weak passwordpassword400 Too weak400 with requirementsPASS
8Duplicate emailExisting email409 Already registered409 Already registeredPASS
9Password changeValid current + new200, tokens revoked200 Password changedPASS

9.2 MFA Tests

#ScenarioInputExpected ResultActual ResultStatus
1MFA setupAuthenticated userSecret + QR returnedQR data URL generatedPASS
2TOTP verifyValid 6-digit code200, JWT issuedTokens returnedPASS
3TOTP invalidWrong code401 Invalid401 Invalid MFA tokenPASS
4Backup codeValid backup code200, code consumedTokens, code marked usedPASS
5Backup reuseSame backup code401 Already used401 InvalidPASS
6RegenerateAuthenticated user10 new codesNew set generatedPASS
7Remaining countAfter using 3 codes7 remainingAccurate count returnedPASS
8MFA login flowMFA-enabled userRedirect to MFAmfaRequired: truePASS

9.3 SSO Tests

#ScenarioInputExpected ResultActual ResultStatus
1Provider discoveryGET /sso/providersList of providersEmpty (no env vars)PASS
2Provider configuredGoogle client ID setGoogle in listProvider with auth URLPASS
3OAuth initiateGET /sso/initiate/googleAuth URL + stateURL generated, state storedPASS
4State validationValid stateState acceptedTiming-safe comparisonPASS
5Invalid stateWrong/expired state403 Invalid403 ForbiddenPASS
6Auto-provisionNew SSO emailUser createdCreated with viewer rolePASS
7Account linkingExisting email + SSOProvider linkedProvider linkedPASS

9.4 Security Tests

#ScenarioInputExpectedActualStatus
1NoSQL injection (value){"email": "$gt:''"}400 Blocked400 "Invalid input detected"PASS
2NoSQL injection (key){"email": {"$gt":""}}400 Blocked400 "Invalid input detected"PASS
3XSS injection{"name": "<script>..."}400 Blocked400 "Invalid input detected"PASS
4iframe injection{"bio": "<iframe>..."}400 Blocked400 "Invalid input detected"PASS
5Security headersAny requestAll headers presentHSTS, X-Frame, CSP, etc.PASS
6Rate limiting100+ req/min429 Throttled429 returnedPASS
7Login rate limit5+ logins/15min429 Throttled429 returnedPASS
8Body size limitRequest > 10KB413 RejectedRequest rejectedPASS
9Cache preventionAny API responseno-store headerHeader presentPASS
10ClickjackingEmbed in iframeX-Frame: DENYHeader presentPASS

9.5 Frontend UX Tests

#ScenarioExpected ResultStatus
1Login page rendersEmail/password form, SSO buttons if configuredPASS
2SSO buttons appearOnly when providers are configuredPASS
3MFA pageTOTP input + backup code togglePASS
4Signup password strengthReal-time strength bar with 5 rulesPASS
5Account lockout warningOrange alert with remaining attemptsPASS
6SSO callback processingLoading spinner → success/error statePASS
7Dark modeFull dark/light theme supportPASS
8Responsive designMobile, tablet, desktop layoutsPASS
9OTP verification screen6-digit input with paste support, countdown timerPASS
10OTP pastePaste 6-digit code fills all fields automaticallyPASS
11OTP expiry timer10:00 countdown, color changes at 2min and expiredPASS
12OTP resendNew code sent, timer resets to 10:00PASS
13Forgot password flowEmail → OTP → new password → successPASS
14Registration OTP flowForm → OTP → verify → account createdPASS
Test Summary

48 test cases executed across 5 categories — Authentication (9), MFA (8), SSO (7), Security (10), Frontend UX (14). All tests passed.


Deployment Architecture

10.1 Required Environment Variables

# Server
PORT=4000
NODE_ENV=production
MONGODB_URI=mongodb://host:27018/afdb_beta
REDIS_HOST=localhost
REDIS_PORT=6379

# JWT Secrets (use strong 256-bit random values)
JWT_ACCESS_SECRET=<256-bit-random-secret>
JWT_REFRESH_SECRET=<256-bit-random-secret>
JWT_ACCESS_EXPIRY=30m
JWT_REFRESH_EXPIRY=30d

# CORS
CORS_ORIGINS=https://portal.afdb.org,https://core.afdb.org

# SSO — Google OAuth2
GOOGLE_CLIENT_ID=<google-oauth-client-id>
GOOGLE_CLIENT_SECRET=<google-oauth-client-secret>
GOOGLE_REDIRECT_URI=https://api.afdb.org/api/v1/sso/callback/google

# SSO — Microsoft / Azure AD
MICROSOFT_CLIENT_ID=<azure-ad-client-id>
MICROSOFT_CLIENT_SECRET=<azure-ad-client-secret>
MICROSOFT_TENANT_ID=<azure-tenant-id>
MICROSOFT_REDIRECT_URI=https://api.afdb.org/api/v1/sso/callback/microsoft

# Frontend
FRONTEND_URL=https://portal.afdb.org

# SMTP (Email OTP Delivery)
SMTP_HOST=smtp.afdb.org
SMTP_PORT=465
SMTP_USER=noreply@afdb.org
SMTP_PASSWORD=<smtp-password>
SMTP_FROM=noreply@afdb.org

10.2 Production Readiness Checklist

  • Set strong JWT_ACCESS_SECRET and JWT_REFRESH_SECRET (min 256-bit)
  • Configure MongoDB with authentication and TLS/SSL
  • Enable Redis persistence and authentication
  • Set NODE_ENV=production
  • Configure TLS/SSL certificates for all endpoints
  • Set up Google and/or Microsoft OAuth2 credentials
  • Configure CORS_ORIGINS with production domains
  • Enable MongoDB audit logging
  • Set up log aggregation (Winston → centralized logging platform)
  • Configure health check monitoring on /health
  • Configure SMTP credentials for email OTP delivery
  • Set up alerting for account lockout events
  • Run security penetration testing before go-live

Compliance Matrix

11.1 OWASP Top 10 (2021) — Full Coverage

CategoryRiskControls ImplementedTests
A01: Broken Access ControlHighHelmet, CORS, X-Frame-Options, Auth Middleware, RBAC5
A02: Cryptographic FailuresHighbcrypt, HSTS, JWT, body limits, cache prevention7
A03: InjectionHighInput sanitizer (NoSQL + XSS), key sanitization, string limits4
A04: Insecure DesignHighRate limiting, account lockout, password policy3
A05: Security MisconfigurationMediumHelmet, Permissions-Policy, header hardening6
A06: Vulnerable ComponentsMediumDependency pinning, regular audits (recommended)N/A
A07: Identification & AuthenticationHighAccount lockout, MFA, password strength, token revocation9
A08: Software & Data IntegrityMediumJWT verification, state validation2
A09: Logging & MonitoringMediumMorgan + Winston, security event loggingVerified
A10: Server-Side Request ForgeryLowNo external URL fetching from user input (except SSO provider URLs)N/A

11.2 Password Policy (OWASP-Compliant)

RequirementRuleExample
Minimum Length8 charactersPassword1!
UppercaseAt least 1Password1!
LowercaseAt least 1Password1!
DigitAt least 1Password1!
Special CharacterAt least 1Password1!

Appendices

Appendix A: User Data Model

{
  email:            String (unique, indexed)
  passwordHash:     String (bcrypt, 12 rounds)
  firstName:        String
  lastName:         String
  role:             Enum ['admin', 'staff', 'viewer']
  mfaEnabled:       Boolean (default: false)
  mfaSecret:        String (TOTP secret)
  mfaBackupCodes:   [{ codeHash: String, used: Boolean }]
  ssoProvider:      String ('google' | 'microsoft')
  ssoId:            String (provider's user ID)
  isActive:         Boolean (default: true)
  loginAttempts:    Number (default: 0)
  lockUntil:        Date
  lastLogin:        Date
  passwordChangedAt: Date
  createdAt:        Date (auto)
  updatedAt:        Date (auto)
}

Appendix B: Token Lifecycle

Login → Access Token (30 min) + Refresh Token (30 days) │ │ ├─ Expired? → Refresh ───┤ │ ├─ Revoked? → Re-authenticate │ └─ Valid → New Access Token issued │ ├─ Password Changed → All tokens revoked ├─ Logout → All tokens revoked └─ MFA Verified → Tokens issued

Appendix C: Security Event Log Examples

INFO  User created: admin@afdb.org
INFO  MFA secret generated for user: 6a91c08b...
INFO  MFA backup codes generated for user: 6a91c08b...
INFO  MFA backup code used for user: 6a91c08b...
WARN  Login attempt on locked account: admin@afdb.org
WARN  Account locked due to 5 failed attempts: admin@afdb.org
INFO  SSO: auto-provisioning user for user@org.com via google
INFO  All tokens revoked for user: 6a91c08b...
INFO  Password changed for user: 6a91c08b...

Appendix D: Demo Credentials

All demo accounts use @yopmail.com email addresses. After logging in with credentials, you will receive a 6-digit OTP via email. Visit https://yopmail.com and enter the username (e.g., afdbadmin) to check the inbox and retrieve the OTP code.

RoleEmailPasswordYopmail InboxPermissions
Adminafdbadmin@yopmail.comAdmin@123yopmail.com/en/?afdbadminFull access — all features, user management, monitoring
Viewerafdbaviewer@yopmail.comViewer@123yopmail.com/en/?afdbaviewerRead-only — view dashboards, projects, reports
Managerafdbmanager@yopmail.comManager@123yopmail.com/en/?afdbmanagerProject management — create, edit, approve projects (role: staff)

End of Document

AfDB Reference Application — Technical Documentation v1.0

Prepared by Eng. Depute N.Alphonse, PMP®

Contact Information
Eng. Depute N.Alphonse
Eng. Depute N.Alphonse, PMP®
Enterprise Software Architect & Digital Transformation Consultant
depute@atradezone.ca
Kigali, Rwanda
Portfolio GitHub LinkedIn
Top