Skip to content
Documentation

    How to Implement User Verification

    User verification ensures that only authorized users can access your private roadmaps or widgets. Because this process involves sensitive credentials (your Shared Secret), the authentication token must be generated on your server, never in the browser.

    You can find an examxple implementation of the user verfiication flow in NextJS on Github.

    View on Github

    Before running the example, ensure you have the following:

    1. Node.js installed (v18 or newer recommended).
    2. Your Hub credentials (found in Settings → User Verification):
      • ACCOUNT_ID
      • SHARED_SECRET
    3. The Channel ID for the portal you want to embed finding-the-channel-id.md
      • CHANNEL_ID

    1. Open your terminal and run the following commands to create a folder and install the necessary web server framework (express).

      Terminal window
      mkdir released-auth-demo
      cd released-auth-demo
      npm init -y
      npm install express
    2. Create a file named server.js and paste in the code below.

      const express = require('express');
      const app = express();
      const port = 3000;
      // --- CONFIGURATION ---
      // TODO: Replace with your actual values from Hub Settings
      const CONFIG = {
      SHARED_SECRET: 'YOUR_SHARED_SECRET',
      ACCOUNT_ID: 'YOUR_ACCOUNT_ID',
      CHANNEL_ID: 'YOUR_CHANNEL_ID'
      };
      // --- MOCK USER DATA ---
      // In your real app, this comes from your database or session
      const currentUser = {
      id: "user_12345",
      email: "john.doe@example.com",
      name: "John Doe",
      avatar: "https://ui-avatars.com/api/?name=John+Doe"
      };
      // --- THE ROUTE ---
      app.get('/', async (req, res) => {
      try {
      // 1. Generate the Auth Token server-side
      // We send the current user's details to Hub to get a temporary token
      const response = await fetch("https://accounts.releasedhub.com/auth/api/impersonation/token", {
      method: "POST",
      headers: {
      "Content-Type": "application/json",
      "Authorization": `Bearer ${CONFIG.SHARED_SECRET}`
      },
      body: JSON.stringify({
      account_id: CONFIG.ACCOUNT_ID,
      user_id: currentUser.id,
      user_email: currentUser.email,
      profile: {
      name: currentUser.name,
      avatar_url: currentUser.avatar
      }
      }),
      });
      if (!response.ok) throw new Error(`API Error: ${response.statusText}`);
      const data = await response.json();
      const token = data; // The short-lived JWT
      // 2. Serve the HTML with the token injected
      res.send(`
      <!DOCTYPE html>
      <html>
      <head>
      <title>Hub Verification Example</title>
      <script type="module" src="https://embed.released.so/released-embed.js"></script>
      </head>
      <body style="font-family: sans-serif; padding: 40px;">
      <h1>Hello, ${currentUser.name}</h1>
      <p>This roadmap is authenticated specifically for you.</p>
      <hr />
      <released-page
      channel-id="${CONFIG.CHANNEL_ID}"
      auth-token="${token}">
      </released-page>
      </body>
      </html>
      `);
      } catch (error) {
      console.error(error);
      res.status(500).send("Error generating token. Check server console.");
      }
      });
      app.listen(port, () => {
      console.log(`Server running at http://localhost:${port}`);
      });
    3. Start the application in your terminal:

      Bash

      node server.js
    4. Most browsers restrict embedded widgets or cookies when running on localhost. To test this properly, you need a public https URL. We recommend using a tool like ngrok.

      1. Install ngrok (if you haven’t already).

      2. Run the tunnel in a new terminal window:

        Bash

        ngrok http 3000
      3. Copy the Forwarding URL provided by ngrok (e.g., https://a1b2-c3d4.ngrok-free.dev).

      4. Important: Add this URL to your Allowed Domains in the Hub dashboard if you have domain restrictions enabled.

      5. Open the URL in your browser to see your authenticated roadmap.

    5. Add the ngrok domain to your list of trusted domains for embedded content.

    Widget not loading?

    Check your browser console. If you see CORS errors, ensure your ngrok URL is added to the “Allowed Domains” list in your Hub settings.

    Fetch is not defined?

    If you are on an older version of Node.js (< v18), upgrade Node or install node-fetch.

    401 Unauthorized?
    • Double-check that your SHARED_SECRET was copied correctly and contains no extra spaces.
    • Check the html source and ensure the token property in the embed html element was successfully populated.