Skip to main content

Auth Module

🎯 Overview

The internal Auth module wires together authentication flows for the Internal API (/v1/* routes). It accepts login credentials, manages session lifecycles, performs password recovery, and supports account discovery for multi-account users. The module proxies minimal work inside controllers and concentrates business logic inside service layers so the rest of the platform can trust a single source of truth for auth behavior.

The services operate against first-party MongoDB collections and several shared utilities (email delivery, Stripe, Wasabi, Intercom, and Queue Manager hooks). They also enforce complex SSO and impersonation rules that protect main accounts while still allowing support and partner workflows.

📁 Directory Structure

internal/api/v1/auth/
├── 📄 index.js
├── 📄 README.md
├── 📂 controllers/
│ ├── account.controller.js
│ ├── index.js
│ ├── password.controller.js
│ └── session.controller.js
├── 📂 routes/
│ ├── account.routes.js
│ ├── password.routes.js
│ └── session.routes.js
├── 📂 schemas/
│ ├── password.js
│ └── session.js
├── 📂 services/
│ ├── account.service.js
│ ├── index.js
│ ├── password.service.js
│ └── session.service.js
├── 📂 tests/
│ ├── account.test.js
│ ├── fixtures/
│ │ └── session.js
│ ├── password.test.js
│ └── session.test.js
└── 📂 utils/
└── processShared.js

🗄️ MongoDB Collections

Collection: _accounts

  • Purpose: Stores account metadata, affiliate details, branding, and subscription state.
  • Model Reference: shared/models/account.js
  • Key Fields: parent_account, domain, branding.colors, stripe_customer, affiliate
  • Indexes: Compound indexes on _id, parent_account

Collection: _users

  • Purpose: Contains user credentials, roles, and security preferences per account.
  • Model Reference: shared/models/user.js
  • Key Fields: email, password, scope, is_owner, metadata

Collection: _projects.dashboard.preferences

  • Purpose: Stores per-user dashboard access flags used to filter sub-accounts.
  • Model Reference: shared/models/projects-dashboard-preferences.js
  • Key Fields: users, sub_account_id, allow_client_dashboard

Collection: _api.sessions

  • Purpose: Persists API session payloads, token expirations, and metadata.
  • Model Reference: shared/models/api-session.js
  • Key Fields: token.access_token, session_expiration, metadata.platform

Collection: _api.refresh.tokens

  • Purpose: Stores refresh tokens that are removed during logout.
  • Model Reference: shared/models/api-refresh-token.js
  • Key Fields: refresh_token

Collection: _api.grants

  • Purpose: Temporarily caches OAuth grants generated during login/SSO token exchange.
  • Model Reference: shared/models/api-grant.js
  • Key Fields: grant

Collection: _api.scopes

  • Purpose: Lists OAuth scopes used to build session access envelopes.
  • Model Reference: shared/models/api-scope.js
  • Key Fields: scope

Collection: _funnels

  • Purpose: Funnels metadata used when cloning shared funnels after login.
  • Model Reference: shared/models/funnels.js
  • Key Fields: original_funnel_id, account_id, pending

📚 Note: See Database Collections Documentation for schema diagrams and index definitions.

🏗️ Architecture Overview

  • Pattern: Classic MVC with thin controllers → services → shared utilities. Services encapsulate business rules and call Mongo models directly.
  • Key Dependencies:
    • shared/utilities/auth for hashing, session verification, OAuth helper functions.
    • shared/utilities/stripe, stripe SDK, and axios for billing lookups and OAuth exchange.
    • shared/utilities/logger for structured logging and security breadcrumbs.
    • shared/utilities/send-email, Wasabi wrapper, and Queue Manager conventions for transactional email.
  • External Services: Stripe, SendGrid, Twilio, Wasabi Object Storage, Intercom hashing, Axios-based OAuth endpoint on the Router service.

🔗 Submodules

🚀 Quick Start

Authenticate against the Internal API using the login endpoint:

POST /v1/v1/auth/login HTTP/1.1
Content-Type: application/json
X-Client-Id: <public-app-id>

{
"account": "64fa...",
"email": "user@example.com",
"password": "••••••••",
"remember": true,
"platform": "client_dashboard"
}
  • ✅ On success, the controller forwards to sessionService.login, writes a session document, and returns SUCCESS in a subsequent call to GET /v1/v1/auth/status.
  • ❌ On failure (invalid credentials, banned account, unauthorized scope), a 400/403 is raised by the service.

🔐 Required Environment Variables

VariableDescriptionRequired
APP_SECRETJWT secret for password tokens and SSO verification payloads✅ Yes
APP_MISC_SECRETShort-lived OAuth grant signing secret✅ Yes
PORTRouter port used when exchanging OAuth grants✅ Yes
CLIENT_REDIRECT_URIRouter URL used during SSO token exchange✅ Yes
STRIPE_SECRET_KEYStripe API key for account billing lookups✅ Yes
INTRO_COUPON_IDCoupon template ID used when generating promo codes❌ Optional
BOT_BYPASS_KEYOptional header that bypasses bot detection logic❌ Optional

📊 Key Metrics & Performance

  • Session status responses aggregate ~15 Mongo collections and several Stripe/Twilio calls. Cache repeated lookups (scope, Stripe keys) in upstream services when possible.
  • Login requests perform synchronous OAuth grant exchange with the Router service; ensure Router is reachable (PORT) to avoid 502s.
  • Password reset email sends rely on Wasabi public URLs and SendGrid transactional templates; transient failures bubble up as 400 with logged context.
💬

Documentation Assistant

Ask me anything about the docs

Hi! I'm your documentation assistant. Ask me anything about the docs!

I can help you with:
- Code examples
- Configuration details
- Troubleshooting
- Best practices

Try asking: How do I configure the API?
09:31 AM