2FA Security & One-Click SSO Extension Activation | Digital Products Maker | Digital Products Maker
Link copied! 📋
Extension & Account Setup

Two-Factor Authentication (2FA) & One-Click SSO Extension Activation Engine

DPM
Admin
⏱️11 min read
📢Share this article:
Two-Factor Authentication (2FA) & One-Click SSO Extension Activation Engine

Two-Factor Authentication (2FA) & One-Click SSO Extension Activation Engine

As creators, publishers, and e-commerce entrepreneurs scale their businesses with Digital Products Maker (dp-maker), account security and seamless software onboarding become paramount. A compromised portal account can lead to hijacked commercial licenses, stolen asset libraries, or disrupted publishing workflows. Concurrently, manual license key copy-pasting into desktop browser extensions introduces customer friction and configuration errors.

To address these dual challenges with uncompromising engineering rigor, Digital Products Maker implements an RFC 6238 Time-Based One-Time Password (TOTP) 2FA engine alongside a frictionless 60-second Single Sign-On (SSO) token activation protocol and license-gated software update distribution.


1. Architectural Blueprint & Security Subsystems

The 2FA and SSO subsystems integrate three key components across the authentication lifecycle:

  1. TOTP RFC 6238 Engine: Generates 160-bit Base32 secret keys, renders standard otpauth:// QR codes, and verifies 6-digit rolling codes within a strict clock drift window.
  2. One-Click Token SSO Bridge: Ephemeral 60-second cryptographic tokens (extension_auth_tokens) exchanged via secure window.postMessage to bind browser extensions without exposing raw license keys.
  3. Protected Binary Update Stream: Out-of-tree binary storage (protected_uploads) streamed through a verified license entitlement controller.
+---------------------------------------------------------------------------------------------------+
|                                 Customer Portal Dashboard (/portal)                               |
+--------------------------------+----------------------------------+-------------------------------+
                                 |                                  |
               [1. Setup 2FA]    |                [2. One-Click SSO]|
                                 v                                  v
+--------------------------------+------+       +-------------------+-------------------------------+
|      RFC 6238 TOTP Engine             |       |    SSO Token Generation Controller                |
|  - speakeasy.generateSecret()         |       |  - crypto.randomUUID()                            |
|  - Base32 Key in customer_totp_secrets|       |  - 60-second TTL in extension_auth_tokens         |
|  - qrcode.toDataURL() Base64 stream   |       |  - Dispatched via window.postMessage              |
+--------------------------------+------+       +-------------------+-------------------------------+
                                 |                                  |
                                 | [6-digit TOTP]                   | [One-Time Token + device_uuid]
                                 v                                  v
+--------------------------------+------+       +-------------------+-------------------------------+
|    Login Challenge Interceptor        |       |    License Token Activation Controller            |
|  - Intercepts unverified logins       |       |  - POST /api/license/activate-by-token            |
|  - Validates rolling TOTP token       |       |  - Checks customer license & device quota         |
|  - Issues signed 7-day Portal JWT     |       |  - Issues unique 32-byte device_secret            |
+---------------------------------------+       +---------------------------------------------------+

2. RFC 6238 TOTP Two-Factor Authentication Lifecycle

The two-factor authentication subsystem complies fully with RFC 6238 (Time-Based One-Time Password Algorithm) and RFC 4226 (HMAC-Based One-Time Password Algorithm), ensuring plug-and-play compatibility with Google Authenticator, Microsoft Authenticator, Apple Passwords, Authy, and 1Password.

2.1 Schema Definition (customer_totp_secrets)

TOTP secrets are isolated in a dedicated relational schema linked by a strict foreign key to the primary customer record:

CREATE TABLE customer_totp_secrets (
  id INT AUTO_INCREMENT PRIMARY KEY,
  customer_account_id INT NOT NULL UNIQUE,
  secret VARCHAR(255) NOT NULL,
  is_enabled BOOLEAN DEFAULT FALSE,
  created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
  FOREIGN KEY (customer_account_id) REFERENCES customer_accounts(id) ON DELETE CASCADE
);

2.2 Secret Generation & QR Code Provisioning (POST /api/portal/2fa/generate)

When a customer clicks "Enable 2FA" in their security preferences, the server dynamically provisions a cryptographic secret and renders an inline Data URI QR code:

// server/src/features/customer-portal/controller.ts
import speakeasy from "speakeasy";
import qrcode from "qrcode";

export async function generate2FA(req: PortalRequest, res: Response) {
  try {
    const customerId = req.customer?.id;
    if (!customerId) return res.status(401).json({ error: "Unauthorized" });

    // Fetch customer email for branded otpauth URI label
    const [custRows]: any = await pool.query(
      "SELECT email FROM customer_accounts WHERE id = ?",
      [customerId]
    );
    if (custRows.length === 0) return res.status(404).json({ error: "Customer not found" });
    const email = custRows[0].email;

    // Generate Base32 secret with branded issuer
    const secret = speakeasy.generateSecret({
      name: `AI Digital Products (${email})`
    });

    // Store or update secret with unconfirmed status (is_enabled = 0)
    const [existingRows]: any = await pool.query(
      "SELECT id FROM customer_totp_secrets WHERE customer_account_id = ?",
      [customerId]
    );

    if (existingRows.length > 0) {
      await pool.query(
        "UPDATE customer_totp_secrets SET secret = ?, is_enabled = 0 WHERE customer_account_id = ?",
        [secret.base32, customerId]
      );
    } else {
      await pool.query(
        "INSERT INTO customer_totp_secrets (customer_account_id, secret, is_enabled) VALUES (?, ?, 0)",
        [customerId, secret.base32]
      );
    }

    // Render Data URL image string for direct visual display
    const qrDataURL = await qrcode.toDataURL(secret.otpauth_url || "");
    res.json({ secret: secret.base32, qrCode: qrDataURL });
  } catch (err: any) {
    res.status(500).json({ error: "Failed to generate 2FA." });
  }
}

2.3 Verification & Confirmation Handshake (POST /api/portal/2fa/verify)

To prevent lockouts from misconfigured authenticator apps, 2FA is never activated immediately upon secret generation. The customer must prove possession by submitting their first valid 6-digit code:

export async function verify2FA(req: PortalRequest, res: Response) {
  try {
    const customerId = req.customer?.id;
    if (!customerId) return res.status(401).json({ error: "Unauthorized" });
    
    const { token } = req.body;
    if (!token) return res.status(400).json({ error: "Token required" });

    const [rows]: any = await pool.query(
      "SELECT secret FROM customer_totp_secrets WHERE customer_account_id = ?",
      [customerId]
    );
    if (rows.length === 0) return res.status(400).json({ error: "2FA not initialized" });
    
    // Verify 6-digit code using 30-second time window
    const verified = speakeasy.totp.verify({
      secret: rows[0].secret,
      encoding: "base32",
      token
    });

    if (verified) {
      // Mark 2FA as fully armed and enabled
      await pool.query(
        "UPDATE customer_totp_secrets SET is_enabled = 1 WHERE customer_account_id = ?",
        [customerId]
      );
      res.json({ message: "2FA enabled successfully" });
    } else {
      res.status(400).json({ error: "Invalid 2FA token" });
    }
  } catch (err: any) {
    res.status(500).json({ error: "Failed to verify 2FA." });
  }
}

2.4 Login Interception Challenge

When a customer logs in via POST /api/portal/login, the controller checks customer_totp_secrets.is_enabled. If enabled, standard JWT issuance is halted, and the server returns:

{
  "requires2FA": true,
  "message": "Two-factor authentication code required."
}

The user is redirected to a secure 2FA challenge screen to input their 6-digit dynamic authenticator code before obtaining their 7-day session token.


3. One-Click Extension Activation (SSO Token Protocol)

Manually copying a 32-character license key from an email or web dashboard into the Chrome Extension introduces friction, copy-paste truncation errors, and support overhead.

Digital Products Maker replaces this with an automated One-Click Single Sign-On (SSO) Activation Handshake.

+------------------+         +--------------------+         +-------------------+
| Chrome Extension |         |  Customer Portal   |         |   Backend Server  |
+--------+---------+         +---------+----------+         +---------+---------+
         |                             |                              |
         | 1. Opens /portal?auth=1     |                              |
         |---------------------------->|                              |
         |                             | 2. POST /extension-token     |
         |                             |----------------------------->|
         |                             |                              | 3. Creates UUID
         |                             |                              |    (60-sec TTL)
         |                             | 4. Returns { token: UUID }   |
         |                             |<-----------------------------|
         | 5. window.postMessage(token)|                              |
         |<----------------------------|                              |
         |                                                            |
         | 6. POST /api/license/activate-by-token { token, device_uuid }
         |----------------------------------------------------------->|
         |                                                            | 7. Validates token
         |                                                            | 8. Binds hardware
         |                                                            | 9. Generates secret
         | 10. Returns { message, device_secret, plan_id, license_key }|
         |<-----------------------------------------------------------|

3.1 Token Issuance (POST /api/portal/extension-token)

When requested by an authenticated portal session, the server generates a cryptographically secure v4 UUID with a strict 60-second Time-To-Live (TTL):

export async function generateExtensionToken(req: PortalRequest, res: Response) {
  try {
    const token = crypto.randomUUID();
    const customerId = req.customer!.id;
    const expiresAt = new Date(Date.now() + 60000); // 60-second window

    await pool.query(
      "INSERT INTO extension_auth_tokens (token, customer_id, expires_at) VALUES (?, ?, ?)",
      [token, customerId, expiresAt]
    );

    res.json({ token });
  } catch (error) {
    res.status(500).json({ error: 'Server error generating token' });
  }
}

3.2 Single-Use Activation & Device Binding (POST /api/license/activate-by-token)

The Chrome Extension captures the token and immediately calls the activation endpoint alongside its unique device_uuid:

// server/src/features/license/controller.ts
export async function activateByToken(req: Request, res: Response) {
  try {
    const { extension_token, device_uuid } = req.body;

    if (!extension_token || !device_uuid) {
      return res.status(400).json({ error: 'Missing extension_token or device_uuid' });
    }

    // 1. Verify token existence, single-use status, and expiry
    const [tokenRows]: any = await pool.query(
      'SELECT customer_id, expires_at, used FROM extension_auth_tokens WHERE token = ?',
      [extension_token]
    );

    if (tokenRows.length === 0) {
      return res.status(403).json({ error: 'Invalid or expired activation token' });
    }

    const tokenData = tokenRows[0];
    if (tokenData.used) {
      return res.status(403).json({ error: 'Activation token already used' });
    }
    if (new Date(tokenData.expires_at) < new Date()) {
      return res.status(403).json({ error: 'Activation token expired' });
    }

    // 2. Locate active, unbanned license owned by this customer
    const [licRows]: any = await pool.query(
      'SELECT * FROM licenses WHERE customer_account_id = ? AND is_active = 1 AND is_banned = 0',
      [tokenData.customer_id]
    );

    if (licRows.length === 0) {
      return res.status(404).json({ error: 'No active license found linked to your account' });
    }

    const license = licRows[0];
    const license_key = license.license_key;

    // 3. Check hardware slot limit in license_devices
    const [existingDevice]: any = await pool.query(
      'SELECT device_secret FROM license_devices WHERE license_key = ? AND device_uuid = ?',
      [license_key, device_uuid]
    );

    let deviceSecret;
    if (existingDevice.length > 0) {
      deviceSecret = existingDevice[0].device_secret;
    } else {
      const [boundCount]: any = await pool.query(
        'SELECT COUNT(*) as count FROM license_devices WHERE license_key = ?',
        [license_key]
      );
      
      if (boundCount[0].count >= (license.max_devices || 1)) {
        return res.status(403).json({ 
          error: 'Maximum device limit reached for this license.',
          needs_unbind: true,
          license_key
        });
      }

      deviceSecret = generateDeviceSecret();
      await pool.query(
        'INSERT INTO license_devices (license_key, device_uuid, device_secret) VALUES (?, ?, ?)',
        [license_key, device_uuid, deviceSecret]
      );
    }

    // 4. Invalidate token immediately upon successful binding
    await pool.query('UPDATE extension_auth_tokens SET used = 1 WHERE token = ?', [extension_token]);

    return res.status(200).json({
      message: 'Activation successful',
      device_secret: deviceSecret,
      license_key: license_key,
      user_email: license.user_email,
      plan_id: license.plan_id
    });
  } catch (error) {
    res.status(500).json({ error: 'Internal server error during activation' });
  }
}

4. Protected Software Updates Delivery Pipeline

To prevent reverse-engineering and distribution of cracked builds, binary update archives (.zip) are stored in private server storage (protected_uploads) outside the public web root.

4.1 License-Entitlement Streaming (GET /api/portal/downloads/:id/file)

Before streaming any update package, the server executes a live entitlement query to ensure the requesting customer owns an active, unbanned, and unexpired license:

SELECT l.license_key 
FROM licenses l
LEFT JOIN plans p ON l.plan_id = p.id
WHERE l.customer_account_id = ? 
  AND l.is_active = TRUE AND l.is_banned = FALSE
  AND (p.is_lifetime = 1 OR l.expires_at IS NULL OR l.expires_at >= NOW());
  • If the license is expired, the server terminates with HTTP 403 Forbidden:

    "Your license has expired or is inactive. Please renew your plan to download extension files."

  • If verified, the server creates a readable stream (fs.createReadStream), logs the download to update_download_logs, increments app_updates.download_count, and sends headers: Content-Type: application/zip and Content-Disposition: attachment; filename="DPMaker_vX.X.X.zip".

5. Security Troubleshooting & Error Code Guide

Error Scenario Triggering Condition HTTP Code & Response Payload Resolution
2FA Verification Failure User enters out-of-sync or incorrect 6-digit TOTP code. 400 Bad Request
{"error": "Invalid 2FA token"}
Verify device time synchronization or re-enter current rolling code before 30-second rollover.
SSO Token Expired Extension submits token after the 60-second TTL has elapsed. 403 Forbidden
{"error": "Invalid or expired activation token"}
Click "Activate Extension" in Customer Portal again to issue a fresh 60s token.
SSO Token Replay Same token submitted more than once (used = 1). 403 Forbidden
{"error": "Activation token already used"}
Tokens are single-use. Initiate a new activation from the portal.
Update Download Denied Customer account has no active or unexpired license key. 403 Forbidden
{"error": "Your license has expired or is inactive..."}
Renew or upgrade subscription via Customer Portal > Billing tab.
Device Slot Full on SSO Extension activated on machine when boundCount >= max_devices. 403 Forbidden
{"error": "Maximum device limit reached...", "needs_unbind": true}
Unbind an unused machine slot in Customer Portal > My Licenses.

6. Bilingual Terminology Reference (EN & AR)

English Term المصطلح العربي المعتمد Technical Implementation Context
Two-Factor Authentication (2FA) المصادقة الثنائية (2FA) RFC 6238 TOTP security layer managed via customer_totp_secrets.
Authenticator Code / TOTP رمز تطبيق المصادقة 6-digit dynamic rolling passcode generated every 30 seconds.
One-Click Extension Activation التفعيل الفوري للإضافة بضغطة زر Single Sign-On (SSO) workflow using 60-second UUID tokens.
Single Sign-On (SSO) Token رمز المصادقة الموحدة المؤقت Ephemeral token stored in extension_auth_tokens table.
Protected Uploads Stream البث الآمن للملفات المحمية Secure binary streaming of software updates from private storage.
Hardware Fingerprint Binding ربط البصمة التعريفية للجهاز Association of device_uuid and device_secret in license_devices.
License Entitlement Verification التحقق من أهلية وصلاحية الترخيص Real-time database check confirming active, unbanned, unexpired status.

Conclusion & Architectural Summary

The combination of RFC 6238 TOTP Two-Factor Authentication, 60-Second One-Click SSO Extension Activation, and License-Verified Binary Streaming establishes an enterprise-grade security posture for Digital Products Maker. Creators enjoy seamless, error-free extension onboarding while their commercial licenses and valuable digital assets remain guarded by state-of-the-art cryptographic controls.

📢Share this article:

How do you rate this article?

DPM

Digital Products Maker Team

Verified E-E-A-T Author

Digital Commerce & Publishing Lead

Expert tutorials and in-depth guides for building, scaling, and automating digital product businesses.

👋

Enjoyed this article?

Subscribe to our newsletter to get the latest tutorials and blueprints directly in your inbox.