npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

kenzosso

v1.0.1

Published

SSO authentication package for Kenzo Portal integration with Clerk

Downloads

9

Readme

kenzosso

SSO authentication package for Kenzo Portal integration with Clerk.

This package allows target applications to authenticate users seamlessly when they click on an app link from the Kenzo Portal profile menu. The user is automatically signed in without needing to enter credentials.

Prerequisites

Before using this package, you must:

  1. Register your app in Kenzo Portal Admin → App Store
  2. Get your App Secret from the SSO Configuration tab
  3. Store the secret securely (environment variable recommended)

Installation

npm install kenzosso
# or
yarn add kenzosso

Peer Dependencies

This package requires the following peer dependencies:

{
  "react": ">=17.0.0",
  "@clerk/clerk-react": ">=4.0.0"
}

Quick Start

Option 1: Using the Provider (Recommended)

Wrap your app with KenzoSSOProvider to automatically handle SSO authentication:

// App.jsx or layout.jsx
import { ClerkProvider } from '@clerk/clerk-react';
import { KenzoSSOProvider } from 'kenzosso';

function App() {
  return (
    <ClerkProvider publishableKey={process.env.REACT_APP_CLERK_PUBLISHABLE_KEY}>
      <KenzoSSOProvider
        appSecret={process.env.REACT_APP_KENZO_SSO_SECRET}
        onSuccess={({ userData, session }) => {
          console.log('SSO Success:', userData);
        }}
        onError={({ error }) => {
          console.error('SSO Error:', error);
        }}
      >
        <YourApp />
      </KenzoSSOProvider>
    </ClerkProvider>
  );
}

Option 2: Using the Handler Component

For simpler cases, use the KenzoSSOHandler component:

import { ClerkProvider } from '@clerk/clerk-react';
import { KenzoSSOHandler } from 'kenzosso';

function App() {
  return (
    <ClerkProvider publishableKey={process.env.REACT_APP_CLERK_PUBLISHABLE_KEY}>
      <KenzoSSOHandler
        appSecret={process.env.REACT_APP_KENZO_SSO_SECRET}
        onSuccess={({ userData }) => console.log('Logged in:', userData)}
        onError={(error) => console.error('SSO failed:', error)}
      />
      <YourApp />
    </ClerkProvider>
  );
}

Option 3: Using Hooks

For more control, use the hooks directly:

import { useClerk } from '@clerk/clerk-react';
import { useKenzoSSOWithClerk } from 'kenzosso';

function App() {
  const clerk = useClerk();

  const { isProcessing, isAuthenticated, userData, error } = useKenzoSSOWithClerk(clerk, {
    appSecret: process.env.REACT_APP_KENZO_SSO_SECRET,
    onSuccess: ({ userData, session }) => {
      console.log('SSO Success:', userData);
    },
    onError: ({ error }) => {
      console.error('SSO Error:', error);
    },
  });

  if (isProcessing) {
    return <div>Authenticating...</div>;
  }

  return <YourApp />;
}

Option 4: Manual Implementation

For complete control over the SSO flow:

import { useEffect } from 'react';
import { useClerk } from '@clerk/clerk-react';
import { handleKenzoSSO, signInWithClerk } from 'kenzosso';

const APP_SECRET = process.env.REACT_APP_KENZO_SSO_SECRET;

function App() {
  const clerk = useClerk();

  useEffect(() => {
    async function processSSO() {
      // 1. Handle SSO token validation
      const userData = await handleKenzoSSO(APP_SECRET);

      if (!userData) return; // No SSO token in URL

      // 2. Sign in with Clerk
      const result = await signInWithClerk(clerk, userData, {
        createUserIfNotExists: true,
        onSuccess: (session) => console.log('Signed in:', session),
        onError: (error) => console.error('Sign-in failed:', error),
      });
    }

    processSSO();
  }, [clerk]);

  return <YourApp />;
}

Next.js Integration

For Next.js apps, wrap your layout with the provider:

// app/layout.jsx (App Router)
import { ClerkProvider } from '@clerk/nextjs';
import { KenzoSSOProvider } from 'kenzosso';

export default function RootLayout({ children }) {
  return (
    <html>
      <body>
        <ClerkProvider>
          <KenzoSSOProvider appSecret={process.env.NEXT_PUBLIC_KENZO_SSO_SECRET}>
            {children}
          </KenzoSSOProvider>
        </ClerkProvider>
      </body>
    </html>
  );
}
// pages/_app.jsx (Pages Router)
import { ClerkProvider } from '@clerk/nextjs';
import { KenzoSSOProvider } from 'kenzosso';

export default function App({ Component, pageProps }) {
  return (
    <ClerkProvider {...pageProps}>
      <KenzoSSOProvider appSecret={process.env.NEXT_PUBLIC_KENZO_SSO_SECRET}>
        <Component {...pageProps} />
      </KenzoSSOProvider>
    </ClerkProvider>
  );
}

API Reference

Components

KenzoSSOProvider

| Prop | Type | Default | Description | |------|------|---------|-------------| | appSecret | string | REQUIRED | App secret from Kenzo App Store | | clerk | object | - | Clerk instance (optional) | | onSuccess | function | - | Callback on successful SSO | | onError | function | - | Callback on SSO error | | autoProcess | boolean | true | Auto-process SSO token on mount | | createUserIfNotExists | boolean | true | Create Clerk user if not exists |

KenzoSSOHandler

Same props as KenzoSSOProvider, but renders nothing and doesn't provide context.

Hooks

useKenzoSSO(options)

Basic hook for SSO token handling without Clerk integration.

Options:

  • appSecret: App secret from Kenzo App Store (REQUIRED)
  • autoProcess: Whether to auto-process on mount

Returns:

  • userData: Validated user data
  • isLoading: Processing state
  • error: Error message if any
  • hasToken: Whether SSO token is present
  • processSSO: Manual trigger function

useKenzoSSOWithClerk(clerk, options)

Complete hook for SSO with Clerk sign-in.

Options:

  • appSecret: App secret from Kenzo App Store (REQUIRED)
  • autoProcess: Whether to auto-process on mount
  • createUserIfNotExists: Create user if not in Clerk
  • onSuccess: Success callback
  • onError: Error callback

Returns:

  • isProcessing: Processing state
  • isAuthenticated: Whether user is signed in
  • userData: Validated user data
  • error: Error message if any
  • processSSO: Manual trigger function

useKenzoSSOToken()

Simple hook to check for SSO token presence.

Returns:

  • hasToken: Whether token is present
  • token: The token value

useKenzoTokenValidation(appSecret)

Manual token validation hook.

Returns:

  • validate: Function to validate a token
  • isValidating: Validation state
  • result: Validation result
  • error: Error message if any

Utility Functions

handleKenzoSSO(appSecret)

Complete SSO flow - extracts token, validates, and cleans URL.

const userData = await handleKenzoSSO('your-app-secret');
// Returns: { email, name, employee_id, app_id } or null

validateSSOToken(token, appSecret)

Validates an SSO token with the Kenzo API.

const result = await validateSSOToken('abc123...', 'your-app-secret');
// Returns: { valid: boolean, data: {...}, message: string }

signInWithClerk(clerk, userData, options)

Signs in a user with Clerk using SSO user data.

const result = await signInWithClerk(clerk, userData, {
  createUserIfNotExists: true,
  onSuccess: (session) => console.log('Success'),
  onError: (error) => console.error('Error'),
});
// Returns: { success: boolean, session?, error? }

getSSOTokenFromURL()

Extracts SSO token from URL query parameters.

removeSSOTokenFromURL()

Removes SSO token from URL without page reload.

How It Works

  1. User clicks app in Kenzo Portal → Kenzo generates a secure SSO token
  2. User is redirected to target app → URL contains ?sso_token=xxx
  3. Package detects token → Validates with Kenzo API
  4. Kenzo validates and returns user data → Email, name, employee_id
  5. Package signs in with Clerk → Creates user if needed
  6. Token is removed from URL → Clean browser history

Security

  • Tokens expire in 5 minutes
  • Tokens are single-use (marked as used after validation)
  • Tokens are app-specific
  • All communication over HTTPS
  • App secret required for validation

Troubleshooting

SSO token not detected

  • Check if URL contains ?sso_token= parameter
  • Ensure autoProcess is true or call processSSO() manually

Token validation fails

  • Token may have expired (5 minute limit)
  • Token may have already been used
  • Verify your app secret is correct

Clerk sign-in fails

  • Verify Clerk publishable key is correct
  • Check if email-based authentication is enabled in Clerk
  • Check Clerk dashboard for sign-in errors

CORS errors

  • Ensure target app domain is allowed in Kenzo CORS configuration

License

MIT