swiftops-backend / docs /dev /auth /ADMIN_REGISTRATION_OTP_EMAIL.md
kamau1's picture
chore: migrate to useast organize the docs, delete redundant migrations
c4f7e3e

Admin Registration OTP Email Template

Overview

When someone attempts to register as a Platform Admin, the configured admin email receives a detailed notification with the registration request details and an OTP code.

Email Template

Template File: src/app/templates/emails/admin_registration_otp.html

Information Displayed

The admin receives an email containing:

1. Registration Details

  • Name: Full name of the person registering
  • Email: Email address being registered
  • Phone: Phone number provided
  • IP Address: Source IP of the registration request
  • Timestamp: UTC timestamp when registration was initiated
  • Location: (Optional, if available from IP geolocation)

2. OTP Code

  • Large, easy-to-read verification code
  • Expiry time (default: 10 minutes)

3. Security Warnings

  • Action required instructions
  • Platform Admin access level warning
  • Instructions for handling suspicious requests

Sample Email Content

🚨 Platform Admin Registration Request

Someone is attempting to register a Platform Admin account with the following details:

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ πŸ“‹ Registration Details                 β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ Name:       John Doe                    β”‚
β”‚ Email:      john@example.com            β”‚
β”‚ Phone:      +1234567890                 β”‚
β”‚ IP Address: 192.168.1.100               β”‚
β”‚ Timestamp:  2024-01-15 14:30:00 UTC     β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

πŸ” Action Required:
If you recognize this person and approve their registration, share the OTP code below with them. 
Otherwise, ignore this email.

Verification code for Platform Admin Registration:

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚   6 1 3 2 8 1 β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

This code will expire in 10 minutes.

⚠️ Security Warning:
Only share this code if you personally verified and approved this registration request. 
Platform Admin accounts have full system access.

If you don't recognize this registration attempt:
β€’ Do not share the OTP code
β€’ Let it expire (10 minutes)
β€’ Contact your security team if you're concerned

Implementation Details

Trigger Point

Endpoint: POST /auth/send-admin-otp

Request Body:

{
  "email": "admin@example.com",
  "first_name": "John",
  "last_name": "Doe",
  "phone": "+1234567890"
}

Template Selection Logic

File: src/app/services/otp_service.py (line ~430-450)

# Determine template based on registration type
is_admin_registration = additional_metadata and 'admin_registration' in additional_metadata
template_name = 'admin_registration_otp' if is_admin_registration else 'otp'
subject = 'SwiftOps Platform Admin Registration Request' if is_admin_registration else 'Your SwiftOps Verification Code'

Template Variables

The following Jinja2 variables are passed to the template:

From OTP Service:

  • code - The 6-digit OTP code
  • purpose - "Platform Admin Registration"
  • validity_minutes - Expiry time (default: 10)

From Auth Endpoint (additional_metadata):

  • admin_registration - Boolean flag (true)
  • registrant_name - Full name (first + last)
  • registrant_email - Email being registered
  • registrant_phone - Phone number or "Not provided"
  • ip_address - Source IP address
  • timestamp - UTC timestamp

Auto-added by NotificationService:

  • app_domain - Application domain (e.g., "swiftops.atomio.tech")
  • current_year - Current year for copyright footer

IP Address Capture

File: src/app/api/v1/auth.py (line ~85-88)

# Capture request metadata for security audit
from datetime import datetime
ip_address = request.client.host if request.client else "Unknown"
timestamp = datetime.utcnow().strftime("%Y-%m-%d %H:%M:%S UTC")

The IP address is captured from the FastAPI Request object at the time of registration.

Security Benefits

  1. Identity Verification: Admin sees WHO is attempting to register before approving
  2. Audit Trail: IP address and timestamp provide forensic data
  3. Social Engineering Protection: Admin can verify offline before sharing OTP
  4. Suspicious Activity Detection: Unusual names, IPs, or timing patterns are visible
  5. Access Control: Emphasizes that Platform Admin has full system access

Configuration

Required Environment Variables

Admin Email Recipient:

PLATFORM_ADMIN_EMAIL=admin@yourcompany.com

This email receives all Platform Admin registration OTP requests.

Optional Configuration

IP Geolocation (Future Enhancement): If you want to add location data based on IP address, integrate a service like:

  • MaxMind GeoIP2
  • ipapi.co
  • ip-api.com

Add location lookup in auth.py before sending OTP:

# Future enhancement - IP geolocation
try:
    location = await get_location_from_ip(ip_address)
except Exception:
    location = None

Testing

Test the Registration Flow

  1. Send OTP Request:
curl -X POST http://localhost:8000/api/v1/auth/send-admin-otp \
  -H "Content-Type: application/json" \
  -d '{
    "email": "test@example.com",
    "first_name": "Test",
    "last_name": "User",
    "phone": "+1234567890"
  }'
  1. Check Admin Email:

    • Email sent to PLATFORM_ADMIN_EMAIL
    • Should display all registration details
    • Should show OTP code prominently
    • Should include security warnings
  2. Complete Registration:

curl -X POST http://localhost:8000/api/v1/auth/register \
  -H "Content-Type: application/json" \
  -d '{
    "email": "test@example.com",
    "first_name": "Test",
    "last_name": "User",
    "phone": "+1234567890",
    "password": "SecurePassword123!",
    "otp_code": "123456"
  }'

Email Template Customization

Styling Changes

The template uses inline CSS for maximum email client compatibility. Key style sections:

Color Scheme:

  • Red theme (#dc2626) for Platform Admin emphasis
  • Yellow warnings (#f59e0b) for action required
  • Gray text (#6b7280) for labels

Layout:

  • 600px width for optimal viewing
  • Responsive table layout
  • Mobile-friendly sizing

Content Modifications

To customize warnings or messaging:

Edit src/app/templates/emails/admin_registration_otp.html:

<!-- Main warning box -->
<div style="background-color: #fef3c7; ...">
    <p>Your custom message here</p>
</div>

<!-- Security warning -->
<div style="background-color: #fee2e2; ...">
    <p>Your custom security message</p>
</div>

To add additional fields:

  1. Add variable to additional_metadata in auth.py
  2. Add table row in template:
<tr>
    <td style="color: #6b7280; font-size: 14px; vertical-align: top;">
        <strong>Your Field:</strong>
    </td>
    <td style="color: #111827; font-size: 14px;">
        {{ your_variable }}
    </td>
</tr>

Comparison with Generic OTP Template

Generic OTP (otp.html)

  • Used for: Password resets, 2FA, general verifications
  • Recipient: The user requesting the action
  • Context: Minimal - just code and purpose
  • Security: Assumes user initiated the request

Admin Registration OTP (admin_registration_otp.html)

  • Used for: Platform Admin account creation
  • Recipient: Configured admin email (not the registrant)
  • Context: Full details about WHO is registering
  • Security: Admin must verify offline before sharing OTP

Related Documentation

  • Registration Flow: docs/agent/SETUP_COMPLETE.md
  • Auth API: docs/dev/AUTH_API_GUIDE.md
  • OTP Integration: docs/OTP_INTEGRATION_GUIDE.md
  • User Management: docs/USER_MANAGEMENT_IMPLEMENTATION.md

Troubleshooting

Email Not Received

  1. Check PLATFORM_ADMIN_EMAIL:

    echo $PLATFORM_ADMIN_EMAIL
    
  2. Check Resend API Configuration:

    echo $RESEND_API_KEY
    echo $RESEND_FROM_EMAIL
    
  3. Check Logs:

    # Look for OTP send confirmation
    grep "Platform admin registration OTP sent" logs/app.log
    

Template Not Found Error

Ensure template file exists:

ls src/app/templates/emails/admin_registration_otp.html

If missing, the system will fall back to generic otp.html template.

IP Address Shows as "Unknown"

This can happen when:

  • Running behind a proxy without X-Forwarded-For headers
  • Testing locally (may show 127.0.0.1)
  • Request object doesn't have client property

Check FastAPI proxy configuration if behind nginx/load balancer.

Future Enhancements

Planned Features

  1. IP Geolocation: Show city/country from IP address
  2. User Agent Tracking: Display browser/device information
  3. Risk Scoring: Highlight suspicious registration patterns
  4. Multi-Admin Approval: Require multiple admin OTP codes
  5. Time-based Restrictions: Only allow registrations during business hours
  6. Email Verification: Require email verification before sending OTP

Extensibility Points

The template system is designed for easy extension:

  1. Custom Templates per Role:

    if role == 'client_admin':
        template_name = 'client_admin_registration_otp'
    elif role == 'contractor_admin':
        template_name = 'contractor_admin_registration_otp'
    
  2. Webhook Notifications: Send registration events to Slack/Teams/Discord

  3. Approval Workflow: Store pending registrations in database for manual approval

Summary

The admin registration OTP email provides comprehensive security context for high-privilege account creation. By showing WHO is registering, FROM WHERE, and WHEN, it enables admins to make informed decisions about sharing verification codes.

This approach balances user experience (simple registration form) with security (admin verification before account creation).