Authentication & Billing
CyberDoc uses a custom authentication system with email/password, magic links, and TOTP two-factor authentication. Billing is powered by Stripe with three subscription tiers.
Authentication Methods
Email & Password
- Registration at
/login.htmlwith email, password, and optional name - Password requirements: 8+ characters, at least one letter and one number
- Passwords hashed with PBKDF2-SHA256 (100,000 iterations)
- Rate limited: 5 attempts per 60 seconds per IP
- Pre-fills from scan lead data if user previously completed a CyberDoc scan
Magic Links
- Passwordless login via email link
- 15-minute token expiry, one-time use
- Rate limited: 1 request per 60 seconds per email
- Creates account automatically on first use
TOTP Two-Factor Authentication
- Compatible with Google Authenticator, Authy, and other TOTP apps
- Setup: generate secret, scan/copy to authenticator app, verify with 6-digit code
- 30-second time step with ±1 step window
- Disable requires current 6-digit code verification
- Managed from the Profile page (
/profile.html)
Password Management
- Change Password — Requires current password + new password (authenticated)
- Set Password — For magic-link users who don't have a password yet
- Forgot Password — Sends reset link via email (15-minute expiry)
- Reset Password — Token-based reset from email link
Sessions
- Cookie-based sessions (
cyberdoc_session) - HttpOnly, Secure, SameSite=None in production
- 24-hour default TTL (configurable via
SESSION_TTL_HOURS) - Cookie domain:
.cintelis.aiin production - Session touch on each request (updates
last_seen_at) - Revocable via logout
Access Control
- Administrative functions are restricted to authorised personnel
- Paid features are gated by subscription plan (Pro, Business, Enterprise)
- Not authenticated users redirect to login with return URL
Billing
Subscription Tiers
| Plan | Monthly | Annual | Key Features |
|---|---|---|---|
| Free | $0 | $0 | Email breach check, social profile sweep, browser privacy test, AI diagnosis, PDF report |
| Pro | $29 AUD | $290 AUD | Dashboard + threat map, 10 Lab scans/mo (5 basic tools), branded PDF reports, scan history + export |
| Business | $99 AUD | $990 AUD | Pro + 30 Lab scans/mo (all 17 tools), 3 Red Team scans/mo, tickets, API |
| Enterprise | $499 AUD | $4,990 AUD | Business + unlimited Lab, 15 Red Team/mo (all modes incl. crew), white-label, admin Red Team dashboard, SLA |
Stripe Integration
- Checkout creates Stripe customer (or reuses existing by email)
- Subscription metadata links to workspace ID
- Webhook handles:
checkout.session.completed,customer.subscription.created/updated/deleted,invoice.paid/payment_failed - Billing portal for self-service plan management
- Subscription status stored in D1 + KV (backwards compatibility)
Profile Page
The profile page (/profile.html) provides:
- Account info (email, name, plan badge)
- Subscription status with Stripe portal link
- Password management (change or set)
- TOTP 2FA setup and management
- Verified domains list
- Admin link (visible to admins only)
- Logout
Auth API Endpoints
| Method | Endpoint | Description |
|---|---|---|
| POST | /api/auth/email/register | Create account (email, password, name) |
| POST | /api/auth/email/login | Login with email + password |
| POST | /api/auth/magic-link/send | Send magic link email |
| GET | /api/auth/magic-link/verify | Verify magic link token |
| POST | /api/auth/password/change | Change password (authenticated) |
| POST | /api/auth/password/set | Set password for first time |
| POST | /api/auth/password/forgot | Send password reset email |
| POST | /api/auth/password/reset | Reset password with token |
| POST | /api/auth/totp/setup | Generate TOTP secret |
| POST | /api/auth/totp/verify | Verify and enable TOTP |
| POST | /api/auth/totp/disable | Disable TOTP (requires code) |
| GET | /api/auth/totp/status | Check if TOTP enabled |
| GET | /api/auth/me | Current user info |
| POST | /api/auth/logout | Logout (revoke session) |
Billing API Endpoints
| Method | Endpoint | Description |
|---|---|---|
| POST | /api/billing/webhook | Stripe webhook (no auth, signature verified) |
| GET | /api/billing/subscription | Current plan status (authenticated) |
| POST | /api/billing/checkout | Create Stripe checkout session (authenticated) |
| POST | /api/billing/portal | Open Stripe billing portal (authenticated) |
Database Schema
Authentication and billing data is stored in Cloudflare D1:
users— Primary identity (id, email, workspace_id, display_name, provider)user_emails— Multi-email support with primary flaguser_credentials— Password hashes (PBKDF2-SHA256)magic_links— Login/reset tokens with expiryuser_totp— TOTP secrets and enabled statusapp_sessions— Session records with TTL and admin flagsubscriptions— Stripe customer/subscription mapping per workspace