SSO Integration
Thoughtbase
WidgetGuides

SSO Integration

Set up Single Sign-On by passing ssoToken to the widget

Overview

Single Sign-On (SSO) lets the widget know who the current user is. Pass ssoToken in the widget config when you initialize it. This enables you to:

  • Track which users submitted feedback
  • Maintain user context across your app and the widget

Setting Up SSO

Step 1: Generate an SSO Secret

  1. Go to your Thoughtbase dashboard
  2. Navigate to Settings → SSO
  3. Generate or copy your SSO secret

Important: Keep your SSO secret secure! Never expose it in client-side code.

Step 2: Create SSO Tokens in Your Backend

When a user logs into your application, generate a JWT token signed with your SSO secret:

import { SignJWT } from "jose";

const secret = new TextEncoder().encode("your-sso-secret");

const ssoToken = await new SignJWT({
  userId: user.id,
  email: user.email,
  organizationId: "your-org-id",
})
  .setProtectedHeader({ alg: "HS256" })
  .setIssuedAt()
  .setExpirationTime("1h")
  .sign(secret);

Step 3: Pass ssoToken to the Widget

When you initialize the widget, pass the SSO token as ssoToken in the config. Get the token from your backend (e.g. from your session or after the user logs in), then pass it when calling initWidget:

<script>
  // When you have the token (e.g. from session or after login), pass it as ssoToken
  async function initWidgetWithUser() {
    const data = await fetch('/api/generate-sso-token', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ userId: currentUser.id })
    }).then(r => r.json());

    window.thoughtbase.initWidget({
      organizationSlug: 'your-organization-slug',
      convexUrl: 'https://your-project.convex.cloud',
      ssoToken: data.token
    });
  }
  initWidgetWithUser();
</script>

SSO Token Format

Your SSO token should be a JWT with the following payload (use sub for user id with jose):

{
  "sub": "user-id-from-your-system",
  "email": "user@example.com",
  "name": "User Name",
  "image": "https://..."
}

The token should be signed with your SSO secret using HS256 algorithm.

Backend Integration

You’ll need to create an endpoint in your backend to generate SSO tokens. Here’s an example using Node.js:

import { SignJWT } from "jose";
import express from "express";

const app = express();

app.post("/api/generate-sso-token", authenticateUser, async (req, res) => {
  const { user } = req; // Your authenticated user

  const secret = new TextEncoder().encode(
    process.env.THOUGHTBASE_SSO_SECRET // Your SSO secret from Thoughtbase
  );

  const token = await new SignJWT({
    sub: user.id,
    email: user.email,
    name: user.name,
    image: user.avatarUrl,
  })
    .setProtectedHeader({ alg: "HS256" })
    .setIssuedAt()
    .setExpirationTime("1h")
    .sign(secret);

  res.json({ token });
});

Complete Integration Example

Here’s a complete example of integrating the widget with SSO by passing ssoToken when initializing:

<!DOCTYPE html>
<html>
<head>
  <title>My Website</title>
</head>
<body>
  <h1>Welcome to My Site</h1>
  
  <!-- Your custom feedback button -->
  <button id="feedback-btn">Give Feedback</button>
  
  <!-- Load widget script -->
  <script src="https://app.thoughtbase.app/widget.js"></script>
  
  <!-- Initialize widget with ssoToken -->
  <script>
    async function initWidget() {
      try {
        // Get SSO token from your backend (e.g. from session or after login)
        const response = await fetch('/api/generate-sso-token', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({ userId: currentUserId })
        });
        const { token } = await response.json();

        window.thoughtbase.initWidget({
          organizationSlug: 'your-organization-slug',
          convexUrl: 'https://your-project.convex.cloud',
          selector: '#feedback-btn',
          ssoToken: token
        });
      } catch (error) {
        console.error('Failed to init widget with SSO:', error);
      }
    }
    initWidget();
  </script>
</body>
</html>

Security Best Practices

Token Security

  • Never expose your SSO secret in client-side code
  • Generate tokens server-side only
  • Use appropriate token expiration times (recommended: 1 hour)
  • Validate user authentication before generating tokens

Secret Management

  • Store secrets securely: Use environment variables
  • Rotate secrets regularly: Change your SSO secret periodically

Next Steps

  • Learn about Advanced SSO Integration with metadata, avatars, and revenue tracking
  • Review the API Reference for detailed function documentation
  • Test your SSO integration in a development environment
  • Monitor token generation and usage