Authentication Reference Guide

Multi-Method Authentication System

Table of Contents

  1. Overview
  2. Authentication Modes
  3. Configuration Guide
  4. User Experience
  5. API Reference
  6. Testing
  7. Security Considerations
  8. Troubleshooting

Overview

The Fabrixly-IDS Identity Server supports four distinct authentication modes, providing flexibility for different security requirements and user preferences. Each client application can be configured independently with its preferred authentication method.

Key Features

  • 4 Authentication Modes: Password-only, OTP-only, 2FA, and Flexible
  • Mobile Number Login: Support for mobile number as identifier
  • Configurable OTP Delivery: Email, SMS, or both
  • Dynamic UI: Login form adapts to configured mode
  • Session Management: Secure 2FA flow with session state

Authentication Modes

1. Password Only (auth_mode: "password")

Description: Traditional username/password authentication.

Use Cases:

  • Internal applications with existing password policies
  • Applications where OTP delivery is not feasible
  • Legacy system integration

User Flow:

  1. User enters email/mobile
  2. User enters password
  3. Immediate login upon validation

Security Level: ⭐⭐⭐ (Medium)

Configuration:

{
  auth_mode: "password",
  enable_mobile_login: false,
  otp_delivery_method: "email" // Not used
}

2. OTP Only (auth_mode: "otp")

Description: Passwordless authentication using One-Time Passwords.

Use Cases:

  • Consumer-facing applications
  • Mobile-first applications
  • Reducing password management burden
  • Improved user experience

User Flow:

  1. User enters email/mobile
  2. OTP sent automatically
  3. User enters 6-digit OTP
  4. Login upon OTP verification

Security Level: ⭐⭐⭐⭐ (High)

Configuration:

{
  auth_mode: "otp",
  enable_mobile_login: true,
  otp_delivery_method: "email" // or "sms" or "both"
}

Benefits:

  • No password to remember
  • Reduced credential theft risk
  • Better mobile UX
  • Time-limited codes

3. Password + OTP (2FA) (auth_mode: "password_and_otp")

Description: Two-factor authentication requiring both password and OTP.

Use Cases:

  • High-security applications
  • Financial services
  • Healthcare systems
  • Admin panels
  • Compliance requirements (PCI-DSS, HIPAA)

User Flow:

  1. Step 1: User enters email/mobile + password
  2. Password validated
  3. OTP sent to user
  4. Step 2: User enters 6-digit OTP
  5. Login upon OTP verification

Security Level: ⭐⭐⭐⭐⭐ (Very High)

Configuration:

{
  auth_mode: "password_and_otp",
  enable_mobile_login: false,
  otp_delivery_method: "email" // or "sms" or "both"
}

Benefits:

  • Multi-factor security
  • Protection against password compromise
  • Compliance-ready
  • Audit trail

4. Flexible (auth_mode: "flexible")

Description: User chooses between password or OTP authentication.

Use Cases:

  • Applications with diverse user base
  • Gradual migration to passwordless
  • Power users who prefer passwords
  • Mobile users who prefer OTP

User Flow (Password):

  1. User enters email/mobile
  2. User enters password
  3. Immediate login

User Flow (OTP):

  1. User enters email/mobile
  2. User leaves password field empty
  3. OTP sent automatically
  4. User enters OTP
  5. Login upon verification

Security Level: ⭐⭐⭐⭐ (High - depends on user choice)

Configuration:

{
  auth_mode: "flexible",
  enable_mobile_login: true,
  otp_delivery_method: "email" // or "sms" or "both"
}

Benefits:

  • Maximum flexibility
  • User preference
  • Smooth migration path
  • Best of both worlds

Configuration Guide

  1. Navigate to Clients
    • Open console: https://ids.fabrixly.com
    • Go to "Clients" page
  2. Create/Edit Client
    • Click "Add Client" or edit existing
    • Navigate to "User Authentication" tab
  3. Configure Authentication
    • Authentication Mode: Select from dropdown
      • Password Only
      • OTP Only (Passwordless)
      • Password + OTP (2FA)
      • Flexible (User Choice)
    • Enable Mobile Number Login: Toggle on/off
      • Allows users to login with mobile number instead of email
    • OTP Delivery Method: Select delivery channel
      • Email Only
      • SMS Only
      • Both Email & SMS
  4. Save Configuration

Via API

Create Client:

POST https://ids.fabrixly.com/api/clients
Authorization: Bearer <token>
Content-Type: application/json

{
  "client_name": "My Application",
  "redirect_uris": ["https://ids.fabrixly.com/callback"],
  "auth_mode": "password_and_otp",
  "enable_mobile_login": true,
  "otp_delivery_method": "email",
  "requires_consent": false
}

Update Client:

PUT https://ids.fabrixly.com/api/clients/:client_id
Authorization: Bearer <token>
Content-Type: application/json

{
  "auth_mode": "flexible",
  "enable_mobile_login": true,
  "otp_delivery_method": "both"
}

Via Test Scripts

Quick configuration for testing:

# Password-only mode
npx ts-node src/scripts/test-password-only.ts

# OTP-only mode
npx ts-node src/scripts/test-otp-only.ts

# 2FA mode
npx ts-node src/scripts/test-2fa.ts

# Flexible mode
npx ts-node src/scripts/test-flexible.ts

# Mobile login
npx ts-node src/scripts/test-mobile-login.ts

# View current config
npx ts-node src/scripts/view-auth-config.ts

User Experience

Login Form Behavior

The login form dynamically adapts based on the configured auth_mode:

Password Only

┌─────────────────────────────┐
│ Email or Mobile Number      │
├─────────────────────────────┤
│ Password (required)         │
├─────────────────────────────┤
│      [ SIGN IN ]            │
└─────────────────────────────┘

OTP Only

┌─────────────────────────────┐
│ Email or Mobile Number      │
├─────────────────────────────┤
│      [ SEND OTP ]           │
└─────────────────────────────┘
        ↓
┌─────────────────────────────┐
│ Enter 6-digit OTP           │
├─────────────────────────────┤
│      [ VERIFY OTP ]         │
└─────────────────────────────┘

2FA (Password + OTP)

Step 1 of 2:
┌─────────────────────────────┐
│ Email or Mobile Number      │
├─────────────────────────────┤
│ Password                    │
├─────────────────────────────┤
│      [ CONTINUE ]           │
└─────────────────────────────┘
        ↓
Step 2 of 2:
┌─────────────────────────────┐
│ Enter 6-digit OTP           │
├─────────────────────────────┤
│      [ VERIFY OTP ]         │
└─────────────────────────────┘

Flexible

┌─────────────────────────────┐
│ Email or Mobile Number      │
├─────────────────────────────┤
│ Password (or leave empty)   │
├─────────────────────────────┤
│      [ SIGN IN ]            │
└─────────────────────────────┘

Visual Feedback

Success Messages:

  • "OTP sent to your email"
  • "OTP sent to your mobile"
  • "Password verified. OTP sent to your email"

Error Messages:

  • "User not found"
  • "Password is required"
  • "Invalid password"
  • "Invalid or expired OTP"
  • "Access Denied: You are not a member of any team authorized for this application"

Progress Indicators:

  • "Step 1 of 2: Enter your password"
  • "Step 2 of 2: Two-Factor Authentication"

API Reference

Client Configuration Fields

interface Client {
  // Authentication Configuration
  auth_mode: 'password' | 'otp' | 'password_and_otp' | 'flexible';
  enable_mobile_login: boolean;
  otp_delivery_method: 'email' | 'sms' | 'both';
  
  // Other fields...
  client_id: string;
  client_secret: string;
  client_name: string;
  redirect_uris: string[];
  requires_consent: boolean;
  skip_team_check: boolean;
}

Authentication Endpoints

Login Endpoint:

POST /interaction/:uid/login

Body:
{
  "identifier": "user@example.com" | "+1234567890",
  "password": "password123" | "" | "otp"
}

Response:
- Redirect to callback (password/flexible with password)
- Render OTP form (otp/flexible without password/2FA)
- Error message (invalid credentials)

OTP Verification Endpoint:

POST /interaction/:uid/otp

Body:
{
  "identifier": "user@example.com",
  "otp": "123456"
}

Response:
- Redirect to callback (valid OTP)
- Error message (invalid OTP)

Testing

Test Users

Alice (Example Corp):

  • Email: alice@examplecorp.com
  • Mobile: +1234567890
  • Password: password123

Bob (Example Corp):

  • Email: bob@examplecorp.com
  • Password: password123

Testing Each Mode

1. Test Password-Only

# Configure
npx ts-node src/scripts/test-password-only.ts

# Test
1. Go to https://ids.fabrixly.com
2. Click "Login with SSO"
3. Enter: alice@examplecorp.com
4. Enter: password123
5. Click "SIGN IN"
✓ Should login immediately

2. Test OTP-Only

# Configure
npx ts-node src/scripts/test-otp-only.ts

# Test
1. Go to https://ids.fabrixly.com
2. Click "Login with SSO"
3. Enter: alice@examplecorp.com
4. Click "SEND OTP"
5. Check server console for OTP
6. Enter OTP
7. Click "VERIFY OTP"
✓ Should login after OTP verification

3. Test 2FA

# Configure
npx ts-node src/scripts/test-2fa.ts

# Test
1. Go to https://ids.fabrixly.com
2. Click "Login with SSO"
3. Enter: alice@examplecorp.com
4. Enter: password123
5. Click "CONTINUE"
6. Check server console for OTP
7. Enter OTP
8. Click "VERIFY OTP"
✓ Should login after both factors

4. Test Flexible

# Configure
npx ts-node src/scripts/test-flexible.ts

# Test Option A (Password):
1. Enter: alice@examplecorp.com
2. Enter: password123
3. Click "SIGN IN"
✓ Immediate login

# Test Option B (OTP):
1. Enter: alice@examplecorp.com
2. Leave password empty
3. Click "SIGN IN"
4. Check console for OTP
5. Enter OTP
✓ Login after OTP

Finding OTP Codes

OTP codes are logged to the server console:

[CommunicationService] Generated OTP: 123456 for user: <user-id>
[CommunicationService] OTP: 123456

Note: In production, OTPs would be sent via email/SMS, not logged.


Security Considerations

OTP Security

OTP Characteristics:

  • Length: 6 digits
  • Expiration: 5 minutes (configurable)
  • Storage: Hashed in database
  • One-time use: Invalidated after verification
  • Rate limiting: Recommended for production

Password Security

Requirements:

  • Stored using bcrypt hashing
  • Minimum length enforced (configurable)
  • Team-based access control
  • Session management

2FA Security

Best Practices:

  • Session state stored server-side
  • pendingUserId cleared after verification
  • Time-limited OTP codes
  • Separate verification step

Mobile Login Security

Considerations:

  • Mobile number verification recommended
  • SMS delivery security
  • SIM swap protection
  • Rate limiting on OTP requests

Recommendations

  1. Enable 2FA for high-security applications
  2. Use HTTPS in production
  3. Implement rate limiting on OTP endpoints
  4. Monitor failed attempts
  5. Log authentication events
  6. Regular security audits
  7. User education on phishing

Troubleshooting

Common Issues

OTP Not Received

Problem: User doesn't receive OTP

Solutions:

  1. Check server console for OTP (development)
  2. Verify otp_delivery_method configuration
  3. Check email/SMS service configuration
  4. Verify user has email/mobile number
  5. Check spam folder (email)

Login Form Not Changing

Problem: Form doesn't adapt to auth mode

Solutions:

  1. Clear browser cache
  2. Verify client configuration
  3. Check auth_mode value in database
  4. Restart identity server
  5. Check browser console for errors

2FA Session Lost

Problem: OTP step fails after password

Solutions:

  1. Check session configuration
  2. Verify session middleware
  3. Check pendingUserId in session
  4. Ensure cookies are enabled
  5. Check session timeout

Mobile Login Not Working

Problem: Can't login with mobile number

Solutions:

  1. Verify enable_mobile_login is true
  2. Check user has mobile number in database
  3. Verify mobile number format (+1234567890)
  4. Check identifier field name (should be "identifier")

Debug Mode

Enable detailed logging:

// In src/config/database.ts
export const AppDataSource = new DataSource({
  // ...
  logging: true, // Enable SQL logging
});

Support

For issues or questions:

  1. Check server logs
  2. Review configuration with view-auth-config.ts
  3. Test with provided test scripts
  4. Check database schema
  5. Verify API responses

Migration Guide

From enable_otp_login to auth_mode

If upgrading from older version:

Old Configuration:

{
  enable_otp_login: true
}

New Configuration:

{
  auth_mode: "flexible" // or "otp" for OTP-only
}

Migration Mapping:

  • enable_otp_login: trueauth_mode: "flexible"
  • enable_otp_login: falseauth_mode: "password"

Database Migration:

# Reset database (development only)
npx ts-node src/scripts/reset-db.ts
npm run start:server

Best Practices

Choosing Auth Mode

Scenario Recommended Mode Reason
Internal tools Password Familiar, fast
Consumer app OTP Only Better UX, no passwords
Banking/Finance 2FA Maximum security
Mixed user base Flexible User preference
Mobile-first OTP Only Mobile-optimized
High compliance 2FA Audit requirements

Configuration Tips

  1. Start with Flexible - Allows testing both methods
  2. Enable Mobile Login - For better mobile UX
  3. Use Email for OTP - More reliable than SMS
  4. Monitor Usage - Track which method users prefer
  5. Gradual Migration - Move to passwordless gradually

Performance Optimization

  1. Cache client config - Reduce database queries
  2. Rate limit OTP - Prevent abuse
  3. Async OTP delivery - Don't block login flow
  4. Session optimization - Efficient 2FA state management
  5. Database indexing - On identifier fields

Appendix

Configuration Matrix

Auth Mode Password Required OTP Required User Choice
password ✅ Yes ❌ No ❌ No
otp ❌ No ✅ Yes ❌ No
password_and_otp ✅ Yes ✅ Yes ❌ No
flexible ⚠️ Optional ⚠️ Optional ✅ Yes

File Reference

Backend:

  • src/entities/Client.ts - Client schema
  • src/routes/interaction.ts - Authentication logic
  • src/views/login.ejs - Login UI
  • src/services/CommunicationService.ts - OTP service

Console:

  • console/src/pages/Clients/index.tsx - Client management
  • console/src/api/clients.ts - API types

Scripts:

  • src/scripts/test-*.ts - Test configuration scripts
  • src/scripts/view-auth-config.ts - View configuration
  • src/scripts/README.md - Scripts documentation

Version History

  • v1.0.0 - Initial multi-method authentication release
    • 4 authentication modes
    • Mobile number login
    • Dynamic UI
    • Console configuration

Last Updated: 2025-11-27
Version: 1.0.0
Maintained by: Fabrixly-IDS Team

Subscribe to The Fabrixly Blog

Don’t miss out on the latest issues. Sign up now to get access to the library of members-only issues.
jamie@example.com
Subscribe