Professional multi-factor authentication system supporting TOTP, HOTP, and Challenge-Response OTP protocols. Built with Next.js 15, TypeScript, and Tailwind CSS.
This project is a full authentication demo and learning platform for OTP-based security. It includes user registration, login, JWT-based sessions, QR code generation, OTP verification, and a challenge-response flow for higher-security use cases.
- π JWT authentication with HTTP-only cookies
- π§βπ» User registration and login flows
- β±οΈ TOTP generation and verification
- π’ HOTP generation and verification
- π§ͺ Challenge-response OTP workflows
- π· QR code generation for authenticator apps
- ποΈ Supabase Postgres user and challenge data management
- π¨ Tailwind-based UI pages and layouts
- π§± Reusable UI components for visual polish
- π‘οΈ Secret encryption and password hashing utilities
/- Home / landing page/login- Login screen/register- Registration screen/dashboard- User dashboard after authentication/verify- OTP verification page/challenge- Challenge-response authentication page/about- Project and OTP comparison page/qrcode- QR code display page/dashboard/settings- User settings page
- JWT token creation and verification
- Secure cookie-based session handling
- Login flow for password-based access
- Auth checks for protected pages and API routes
- TOTP for time-based one-time passwords
- HOTP for counter-based one-time passwords
- Challenge-response OTP for transaction-level validation
- Secret generation and verification helpers
- Password hashing with bcrypt
- Secret storage encryption helpers
- Token validation helpers
- Challenge lifecycle management
- QR code generation for authenticator apps
- Animated and reusable UI components
- Responsive layout built with Tailwind CSS
- Dedicated pages for learning and testing OTP flows
# Install dependencies (use --legacy-peer-deps for React 19 compatibility)
npm install --legacy-peer-deps
powershell -ExecutionPolicy Bypass -Command "npm install --legacy-peer-deps"
# Or use the npm script
npm run install-deps
# Run development server
npm run dev
powershell -ExecutionPolicy Bypass -Command "npm run dev"
Open http://localhost:3000 in your browser.
npm run build
npm startβββ app/
β βββ api/ # API routes
β β βββ auth/ # Authentication endpoints
β β βββ otp/ # OTP generation/verification
β β βββ challenge/ # Challenge-Response endpoints
β β βββ user/ # User information endpoints
β βββ dashboard/ # Dashboard page
β βββ login/ # Login page
β βββ register/ # Registration page
β βββ verify/ # OTP verification page
β βββ challenge/ # Challenge-Response page
β βββ about/ # About page with OTP comparisons
β βββ qrcode/ # QR code display
βββ lib/
β βββ otp/ # TOTP/HOTP/Challenge-Response implementations
β βββ security.ts # Security utilities
β βββ user-manager.ts # User management
β βββ challenge-manager.ts # Challenge lifecycle management
β βββ supabase-admin.ts # Supabase server client
βββ components/
β βββ ui/ # Reusable visual components
βββ package.json
- RFC 6238 compliant
- 30-second time windows
- Automatic expiration and refresh
- Mobile app compatible (Google Authenticator, Authy)
- Best for: Daily user authentication, 2FA
- RFC 4226 compliant
- Counter-based generation
- Manual code generation
- No automatic expiration
- Best for: API authentication, event-driven auth
- Server-generated unique challenges
- Transaction-specific authentication
- 5-minute expiration window
- Single-use challenges
- Maximum security for high-value operations
- Best for: Financial transactions, administrative actions
- Visit
/register - Select "Challenge-Response (Enterprise Security)"
- Complete registration with username, email, password
- Login with username/password
- Redirected to
/challengepage - Generate Challenge - Server creates unique challenge
- Get Challenge Code - Via display or QR code
- Generate Response - Use authenticator with challenge + secret
- Verify Response - Enter 6-digit response code
- Access Granted - Redirect to dashboard
POST /api/challenge/generate
{
"context": "Wire Transfer $10,000 to Account 12345"
}
Response:
{
"success": true,
"challenge": {
"id": "uuid",
"challenge": "8-char-hex-string",
"context": "transaction-details",
"expiresAt": 1234567890
}
}POST /api/challenge/verify
{
"challengeId": "challenge-uuid",
"response": "123456"
}
Response:
{
"success": true,
"message": "Challenge verified successfully"
}GET /api/challenge/qrcode?challengeId=uuid
Response:
{
"success": true,
"qrCode": "data:image/png;base64,..."
}- Unique per request: Each challenge is cryptographically random
- Time-limited: 5-minute expiration window
- Single-use: Cannot be reused after verification
- Context-aware: Can include transaction-specific data
- No replay attacks: Each challenge is unique
- Transaction binding: Challenge includes transaction details
- Server control: Server initiates each authentication
- High-value transactions: Wire transfers, large purchases
- Administrative actions: User management, system configuration
- API authentication: Critical operations, data exports
- Enterprise security: Maximum protection for sensitive operations
- β TOTP (Time-based One-Time Password) - RFC 6238
- β HOTP (HMAC-based One-Time Password) - RFC 4226
- β Secure Authentication with JWT tokens
- β AES-256 Encryption for secret storage
- β bcrypt Password Hashing
- β QR Code Generation for mobile authenticators
- β Modern UI with Tailwind CSS
- β TypeScript for type safety
- Next.js 15 - React framework with App Router
- TypeScript - Type safety
- Tailwind CSS - Modern styling
- speakeasy - OTP generation (RFC compliant)
- bcryptjs - Password hashing
- jsonwebtoken - JWT authentication
- qrcode - QR code generation
- framer-motion - Motion and animations
- lucide-react - Icons
- zod - Schema validation
Create a .env.local file:
JWT_SECRET=your-secret-key-here
NODE_ENV=development- Replace
JWT_SECRETwith a long, random value before using the app in production. - Keep the same secret across restarts if you want existing login tokens to remain valid.
- Do not commit
.env.localto source control.
POST /api/auth/register- Register new userPOST /api/auth/login- User login
GET /api/otp/generate- Generate OTP codeGET /api/otp/generate-next- Generate the next OTP codePOST /api/otp/verify- Verify OTP code
GET /api/qrcode- Get QR code for mobile app
GET /api/challenge/active- View active challenge dataPOST /api/challenge/generate- Create a new challengePOST /api/challenge/generate-response- Generate a challenge responsePOST /api/challenge/verify- Verify a challenge responsePOST /api/challenge/verify-fixed- Verify using a fixed challenge flowGET /api/challenge/qrcode- Get a QR code for a challengePOST /api/challenge/quick-solve- Quick challenge solving helperPOST /api/challenge/clear-all- Clear stored challenges
GET /api/user/info- Get authenticated user informationGET /api/user/secret- Access user secret dataPOST /api/user/convert-to-totp- Convert a user to TOTP flow
- JWT-based authentication
- HTTP-only cookies
- Password strength validation
- Encrypted secret storage
- Session-based OTP access flow
- Challenge replay prevention
- Rate limiting (to be implemented)
Compatible with:
- Google Authenticator
- Microsoft Authenticator
- Authy
- LastPass Authenticator
- Any TOTP/HOTP compatible app
npm run dev- Start the development servernpm run build- Build the production appnpm start- Run the production buildnpm run install-deps- Install dependencies with legacy peer dependency support