Skip to main content

Domains Controller

Path: internal/api/v1/funnels/controllers/domains.controller.js
Service: domainsService
Module: Funnels


Overview

The Domains controller manages custom domain configuration for funnels. It handles domain routing, SSL settings, and domain-to-funnel mappings to enable funnels to be served on custom domains.

Key Capabilities

  • Domain Routes: View all funnels using a specific domain
  • Domain Updates: Configure domain settings and SSL
  • Route Mapping: Manage which funnels are accessible via domain
  • SSL Configuration: Enable/disable SSL for custom domains

Methods

getDomainRoutesById()

Retrieves all funnel routes configured for a specific domain.

Route: GET /v1/funnels/domains/:domain_id/routes
Auth: Required (account-scoped)

Request Parameters

{
domain_id: string; // Domain ID (MongoDB ObjectId)
}

Response

{
"success": true,
"message": "SUCCESS",
"data": {
"domain": {
"_id": "60d5ec49f1b2c72e8c8e4b1b",
"name": "example.com",
"ssl_enabled": true,
"ssl_status": "active",
"verified": true,
"account_id": "60d5ec49f1b2c72e8c8e4b19"
},
"routes": [
{
"funnel_id": "60d5ec49f1b2c72e8c8e4b1a",
"funnel_name": "Lead Generation Funnel",
"base_path": "/landing",
"full_url": "https://example.com/landing",
"status": "active",
"steps": [
{
"step_id": "60d5ec49f1b2c72e8c8e4b1d",
"step_name": "Home Page",
"path": "/",
"full_url": "https://example.com/landing/"
},
{
"step_id": "60d5ec49f1b2c72e8c8e4b1e",
"step_name": "Thank You",
"path": "/thank-you",
"full_url": "https://example.com/landing/thank-you"
}
]
},
{
"funnel_id": "60d5ec49f1b2c72e8c8e4b20",
"funnel_name": "Product Launch",
"base_path": "/launch",
"full_url": "https://example.com/launch",
"status": "active",
"steps": [
{
"step_id": "60d5ec49f1b2c72e8c8e4b21",
"step_name": "Launch Page",
"path": "/",
"full_url": "https://example.com/launch/"
}
]
}
],
"total_funnels": 2,
"total_routes": 3
}
}

MongoDB Collections

CollectionOperationPurpose
funnel_domainsfindOneRetrieve domain details
funnelsfindFind funnels using this domain
funnel_stepslookupJoin step details for each funnel

Business Logic

  • Filters funnels by domain_id and account_id
  • Constructs full URLs from domain + base_path + step_path
  • Includes SSL protocol (https) if ssl_enabled: true
  • Excludes deleted or inactive funnels

updateDomain()

Updates domain configuration and settings.

Route: PUT /v1/funnels/domains/:domain_id
Auth: Required (account-scoped)

Request Parameters

{
domain_id: string; // Domain ID (MongoDB ObjectId)
}

Request Body

{
"domainInfo": {
"name": "example.com",
"ssl_enabled": true,
"ssl_certificate": {
"provider": "letsencrypt",
"issued_at": "2024-01-01T00:00:00Z",
"expires_at": "2024-04-01T00:00:00Z"
},
"dns_records": [
{
"type": "A",
"name": "@",
"value": "192.0.2.1",
"status": "active"
},
{
"type": "CNAME",
"name": "www",
"value": "example.com",
"status": "active"
}
],
"cloudflare_zone_id": "abc123def456",
"default_funnel_id": "60d5ec49f1b2c72e8c8e4b1a",
"redirect_www": true,
"force_https": true
}
}

Response

{
"success": true,
"message": "SUCCESS",
"data": {
"_id": "60d5ec49f1b2c72e8c8e4b1b",
"account_id": "60d5ec49f1b2c72e8c8e4b19",
"name": "example.com",
"ssl_enabled": true,
"ssl_status": "active",
"ssl_certificate": {
"provider": "letsencrypt",
"issued_at": "2024-01-01T00:00:00Z",
"expires_at": "2024-04-01T00:00:00Z"
},
"verified": true,
"verification_code": "dc-verify-abc123",
"dns_records": [
{
"type": "A",
"name": "@",
"value": "192.0.2.1",
"status": "active"
},
{
"type": "CNAME",
"name": "www",
"value": "example.com",
"status": "active"
}
],
"cloudflare_zone_id": "abc123def456",
"default_funnel_id": "60d5ec49f1b2c72e8c8e4b1a",
"redirect_www": true,
"force_https": true,
"updated_at": "2024-01-22T17:00:00Z"
}
}

MongoDB Collections

CollectionOperationPurpose
funnel_domainsfindOneAndUpdateUpdate domain document
cloudflare_zonesupdate (if applicable)Sync Cloudflare settings

Validations

  • Domain name: Valid FQDN format
  • SSL certificate: Valid date range
  • DNS records: Valid record types (A, AAAA, CNAME, TXT)
  • Cloudflare zone: Valid zone ID format

Data Models

Domain Document

{
_id: ObjectId;
account_id: ObjectId; // Owner account
name: string; // Domain name (e.g., "example.com")

// SSL Configuration
ssl_enabled: boolean;
ssl_status?: 'active' | 'pending' | 'failed' | 'expired';
ssl_certificate?: {
provider: 'letsencrypt' | 'custom' | 'cloudflare';
issued_at: Date;
expires_at: Date;
auto_renew?: boolean;
};

// Verification
verified: boolean;
verification_code?: string; // Code for domain ownership verification
verification_method?: 'dns' | 'file';
verified_at?: Date;

// DNS Configuration
dns_records?: Array<{
type: 'A' | 'AAAA' | 'CNAME' | 'TXT';
name: string; // Record name (@ for root, www, etc.)
value: string; // Record value (IP, domain, text)
status: 'active' | 'pending' | 'failed';
ttl?: number; // Time to live (seconds)
}>;

// Cloudflare Integration
cloudflare_zone_id?: string; // Cloudflare zone identifier
cloudflare_enabled?: boolean; // Use Cloudflare CDN

// Routing
default_funnel_id?: ObjectId; // Default funnel for root path
redirect_www: boolean; // Redirect www to non-www (or vice versa)
force_https: boolean; // Redirect HTTP to HTTPS

// Status
status: 'active' | 'inactive' | 'pending_verification';

created_at: Date;
updated_at: Date;
}

Business Logic & Workflows

Domain Setup Flow

sequenceDiagram
participant User
participant Domains
participant DNS
participant SSL
participant Cloudflare

User->>Domains: POST /domains (create domain)
Domains->>Domains: Generate verification code
Domains-->>User: Domain created (pending verification)

User->>DNS: Add DNS records
DNS-->>Domains: DNS propagation

User->>Domains: POST /domains/:id/verify
Domains->>DNS: Check DNS records

alt DNS Verified
DNS-->>Domains: Records found
Domains->>SSL: Request SSL certificate
SSL->>Cloudflare: Provision certificate
Cloudflare-->>SSL: Certificate issued
SSL-->>Domains: SSL active
Domains-->>User: Domain verified + SSL active
else DNS Not Found
DNS-->>Domains: Records missing
Domains-->>User: Verification failed
end

Funnel-Domain Mapping Flow

sequenceDiagram
participant User
participant Funnels
participant Domains
participant Cache

User->>Funnels: PUT /funnels/:id (set domain_id)
Funnels->>Domains: Check domain ownership

alt Domain Owned by Account
Domains-->>Funnels: Domain verified
Funnels->>Funnels: Update funnel.domain_id
Funnels->>Domains: Add route mapping
Funnels->>Cache: Purge domain cache
Funnels-->>User: Funnel updated
else Domain Not Owned
Domains-->>Funnels: Unauthorized
Funnels-->>User: 403 Forbidden
end

SSL Certificate Renewal Flow

sequenceDiagram
participant Cron
participant Domains
participant SSL
participant Cloudflare
participant Notification

Cron->>Domains: Check expiring certificates
Domains->>Domains: Find certs expiring in 30 days

loop For each expiring cert
Domains->>SSL: Request renewal
SSL->>Cloudflare: Renew certificate

alt Renewal Successful
Cloudflare-->>SSL: New certificate
SSL-->>Domains: Update certificate
Domains->>Notification: Success notification
else Renewal Failed
Cloudflare-->>SSL: Error
SSL-->>Domains: Mark as failed
Domains->>Notification: Alert admin
end
end

Integration Points

Cloudflare

  • Purpose: CDN, SSL provisioning, DNS management
  • Integration: cloudflare_zone_id links to Cloudflare account
  • Features: Auto SSL, caching, DDoS protection

DNS Providers

  • Purpose: Domain name resolution
  • Supported: Cloudflare, AWS Route53, custom
  • Verification: TXT record or file-based verification

SSL Certificate Providers

  • Let's Encrypt: Free auto-renewing certificates
  • Cloudflare SSL: Managed by Cloudflare
  • Custom: User-uploaded certificates

Performance Considerations

Route Caching

  • Domain routes cached for 5 minutes
  • Cache invalidated on domain/funnel updates
  • Cloudflare edge caching for maximum performance

DNS Propagation

  • Verification checks use DNS resolver with 5-second timeout
  • Retry logic for transient DNS failures
  • TTL honored for cached DNS results

Query Optimization

  • Indexed fields: account_id, name, verified, status
  • Compound indexes: (account_id, verified), (name, verified)

Security

Multi-Tenant Isolation

  • All domain queries filtered by account_id
  • Domain ownership verified before any updates
  • Route listings only show account's funnels

Domain Verification

  • DNS verification: TXT record with unique code
  • File verification: Place file at /.well-known/dashclicks-verify.txt
  • Prevents takeover: Must verify ownership before SSL/routing

SSL Security

  • Force HTTPS: Redirects all HTTP to HTTPS
  • Auto-renewal: Prevents certificate expiration
  • Certificate validation: Verifies certificate chain

Error Handling

Common Errors

// Domain not found
{
"success": false,
"message": "Domain not found",
"statusCode": 404
}

// Domain not verified
{
"success": false,
"message": "Domain must be verified before use",
"statusCode": 403
}

// SSL provisioning failed
{
"success": false,
"message": "SSL certificate provisioning failed",
"data": {
"reason": "DNS records not configured correctly"
},
"statusCode": 500
}

// Domain already in use
{
"success": false,
"message": "Domain already connected to another account",
"statusCode": 409
}

// Invalid DNS record
{
"success": false,
"message": "Invalid DNS record format",
"data": {
"field": "dns_records[0].value",
"error": "Invalid IP address"
},
"statusCode": 400
}

Best Practices

When to Use This Controller

  • ✅ Setting up custom domains for funnels
  • ✅ Managing SSL certificates
  • ✅ Configuring DNS records
  • ✅ Viewing domain route mappings

Common Patterns

  1. Verify before use: Always verify domain ownership before allowing funnel connections
  2. Auto-renew SSL: Enable auto-renewal for all Let's Encrypt certificates
  3. Force HTTPS: Enable for all production domains
  4. Cache routes: Cache domain routes to reduce database queries

Edge Cases

  • Subdomain conflicts: Multiple funnels cannot share exact same path on subdomain
  • Wildcard domains: Not supported (each subdomain must be configured separately)
  • Certificate limits: Let's Encrypt rate limits (50 certs per domain per week)
  • DNS propagation delays: Verification may take up to 48 hours

Domain Verification Methods

DNS TXT Record Verification

Steps:

  1. Generate verification code: dc-verify-{random}
  2. User adds TXT record: _dashclicks-verify.example.comdc-verify-abc123
  3. System checks DNS for TXT record
  4. Domain verified if code matches

Advantages:

  • Most secure method
  • Industry standard
  • Works for all domain types

File-Based Verification

Steps:

  1. Generate verification code: dc-verify-{random}
  2. User places file at: https://example.com/.well-known/dashclicks-verify.txt
  3. System fetches file via HTTP
  4. Domain verified if code matches

Advantages:

  • No DNS access required
  • Instant verification
  • Works for existing websites

SSL Configuration

Auto SSL (Let's Encrypt)

{
"ssl_enabled": true,
"ssl_certificate": {
"provider": "letsencrypt",
"auto_renew": true
}
}

Features:

  • Free certificates
  • Auto-renewal 30 days before expiry
  • Supports wildcard certificates (*.example.com)

Cloudflare SSL

{
"ssl_enabled": true,
"ssl_certificate": {
"provider": "cloudflare"
},
"cloudflare_enabled": true
}

Features:

  • Managed by Cloudflare
  • Universal SSL (automatic)
  • No renewal management needed

Custom SSL

{
"ssl_enabled": true,
"ssl_certificate": {
"provider": "custom",
"certificate": "-----BEGIN CERTIFICATE-----...",
"private_key": "-----BEGIN PRIVATE KEY-----...",
"chain": "-----BEGIN CERTIFICATE-----..."
}
}

Features:

  • User-provided certificates
  • Manual renewal required
  • Supports EV/OV certificates

DNS Record Configuration

Required A Records

{
"dns_records": [
{
"type": "A",
"name": "@",
"value": "192.0.2.1",
"ttl": 3600
}
]
}

Purpose: Point domain to DashClicks server

WWW Redirect

{
"dns_records": [
{
"type": "CNAME",
"name": "www",
"value": "example.com",
"ttl": 3600
}
],
"redirect_www": true
}

Purpose: Redirect www.example.com to example.com (or vice versa)

Cloudflare Proxied

{
"dns_records": [
{
"type": "A",
"name": "@",
"value": "192.0.2.1",
"ttl": 1,
"proxied": true
}
],
"cloudflare_enabled": true
}

Purpose: Route traffic through Cloudflare CDN


  • Funnels Controller: Connecting funnels to domains
  • Cloudflare Integration: CDN and SSL management
  • DNS Configuration: Domain setup guide
  • SSL Certificates: Certificate provisioning and renewal

Last Updated: January 2025
API Version: v1
Maintained By: DashClicks Engineering

💬

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