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

@nettie/franklin-id

v0.1.2

Published

React component library for easily integrating Franklin/Genoox authentication (using Auth0) into your application.

Readme

Franklin ID Auth Component (@nettie/franklin-id)

React component library for easily integrating Franklin/Genoox authentication (using Auth0) into your application.

Installation

npm install @nettie/franklin-id # or yarn add @nettie/franklin-id, or bun install @nettie/franklin-id
# Make sure you have react and react-dom installed as peer dependencies
npm install react react-dom

Prerequisites

Before using this component, ensure you have:

  1. Configured an Auth0 Application: Set up an application in your Auth0 dashboard (likely a Single Page Application type).
  2. Configured an Auth0 API: Set up an API in Auth0 that your application will interact with (e.g., https://genoox.eu.auth0.com/api/v2/). Note its API Audience identifier.
  3. Registered Callback URL: You need a backend endpoint (like the provided Supabase function example) that handles the OAuth code exchange. Add the URL of this backend endpoint (e.g., https://<your-project-ref>.supabase.co/functions/v1/auth-callback) to the "Allowed Callback URLs" in your Auth0 Application settings.
  4. Obtained Credentials: Note down your Auth0 Domain, Client ID, and the API Audience identifier.

Usage

Import the FranklinAuth component using a default import and provide the necessary configuration props.

import React, { useState } from 'react';
// Correct: Use a default import
import FranklinAuth from '@nettie/franklin-id';

// Configuration - Load sensitive values from environment variables or a config service
const AUTH0_DOMAIN = process.env.REACT_APP_AUTH0_DOMAIN || 'your-auth0-domain.auth0.com';
const AUTH0_CLIENT_ID = process.env.REACT_APP_AUTH0_CLIENT_ID || 'your_auth0_client_id';
// This MUST be the URL of your backend handler (e.g., Supabase function) registered in Auth0
const AUTH0_CALLBACK_URL = process.env.REACT_APP_AUTH0_CALLBACK_URL || 'https://<your-project-ref>.supabase.co/functions/v1/auth-callback';
const API_AUDIENCE = process.env.REACT_APP_API_AUDIENCE || 'https://your-api-audience.com/'; // Your Auth0 API Audience

function YourApplication() {
  const [isAuthenticated, setIsAuthenticated] = useState(false);
  const [userProfile, setUserProfile] = useState<any>(null); // Store decoded ID token claims
  const [accessToken, setAccessToken] = useState<string | null>(null);
  const [authError, setAuthError] = useState<any>(null);

  // Function to parse ID token (basic example, use a library like jwt-decode for robustness)
  const parseJwt = (token: string) => {
    try {
      // Basic validation: check for 3 parts separated by dots
      if (token.split('.').length !== 3) return null;
      return JSON.parse(atob(token.split('.')[1]));
    } catch (e) {
      console.error("Error parsing JWT:", e);
      return null;
    }
  };

  const handleLoginSuccess = (tokens: { idToken: string, accessToken: string }) => {
    console.log("Authentication successful!");
    setIsAuthenticated(true);
    setAccessToken(tokens.accessToken); // Store access token in state (IMPORTANT: See token handling section)
    setUserProfile(parseJwt(tokens.idToken)); // Decode ID token for user info
    setAuthError(null);

    // Now you can use the accessToken to call your protected API
    // fetch('https://your.api.com/data', {
    //   headers: { Authorization: `Bearer ${tokens.accessToken}` }
    // }).then(...)
  };

  const handleLoginFailure = (error: any) => {
    console.error("Authentication failed:", error);
    setIsAuthenticated(false);
    setAccessToken(null);
    setUserProfile(null);
    setAuthError(error);
  };

  const handleLogout = () => {
    // Basic logout: clear local state
    setIsAuthenticated(false);
    setAccessToken(null);
    setUserProfile(null);
    setAuthError(null);
    // TODO: Implement full logout by redirecting to Auth0 logout endpoint
    // const logoutUrl = `https://${AUTH0_DOMAIN}/v2/logout?client_id=${AUTH0_CLIENT_ID}&returnTo=${window.location.origin}`;
    // window.location.href = logoutUrl;
  };

  return (
    <div>
      <h1>My Application</h1>
      {!isAuthenticated ? (
        <div>
          <p>Please log in.</p>
          <FranklinAuth
            auth0Domain={AUTH0_DOMAIN}
            clientId={AUTH0_CLIENT_ID}
            redirectUri={AUTH0_CALLBACK_URL} // Your backend callback handler URL
            audience={API_AUDIENCE}          // Your Auth0 API Audience
            onAuthSuccess={handleLoginSuccess}
            onAuthFailure={handleLoginFailure}
            // Optionally provide custom scopes or state:
            // scope="openid profile email read:custom_scope"
            // state="your_secure_random_state_value"
          />
          {authError && <p style={{ color: 'red' }}>Error: {authError.error_description || authError.error || 'Login failed'}</p>}
        </div>
      ) : (
        <div>
          <h2>Welcome, {userProfile?.name || 'User'}!</h2>
          {userProfile?.picture && (
            <img src={userProfile.picture} alt="Profile" width="50" style={{ borderRadius: '50%' }} />
          )}
          <p>You are logged in.</p>
          <button onClick={handleLogout}>Logout</button>
          {/* Display Access Token for debugging (REMOVE in production) */}
          {accessToken && (
            <div style={{ marginTop: '10px', wordBreak: 'break-all' }}>
              <strong>Access Token:</strong> <small>{accessToken}</small>
            </div>
          )}
          {/* Add components that need the access token here */}
          {/* Example: <UserProfileEditor accessToken={accessToken} /> */}
        </div>
      )}
    </div>
  );
}

export default YourApplication;

Component Props

| Prop | Type | Required | Description | |------------------|---------------------------------------------------------|----------|-------------------------------------------------------------------------------------------------------------------------------------------| | auth0Domain | string | Yes | Your Auth0 tenant domain (e.g., your-tenant.auth0.com). | | clientId | string | Yes | The Client ID of your Auth0 Application. | | redirectUri | string | Yes | The URL of your backend callback handler (e.g., Supabase function) that Auth0 should redirect to after login. This URL must be registered in your Auth0 Application's "Allowed Callback URLs". | | audience | string | Yes | The unique identifier (API Audience) of the API registered in Auth0 that you want to get an Access Token for. | | onAuthSuccess | (tokens: { idToken: string, accessToken: string }) => void | Yes | Callback function executed on successful authentication. Receives an object containing the idToken and accessToken. | | onAuthFailure | (error: any) => void | Yes | Callback function executed on authentication failure. Receives the error object from Auth0. | | scope | string | No | Optional. Space-separated list of OAuth scopes to request. Defaults to extensive Franklin/Genoox scopes. Override if specific permissions are needed. | | state | string | No | Optional. A random string used for CSRF protection. If provided, your backend callback handler should generate and verify it. Defaults to a placeholder (implement proper state handling for production). |

Handling Tokens

  • idToken (ID Token):
    • A JSON Web Token (JWT) containing claims about the authenticated user (e.g., name, email, picture).
    • Intended for the client application (your React app) to understand who the user is.
    • Can be decoded client-side to display user profile information.
    • Auth0 validates this token during the code exchange in your backend callback handler.
  • accessToken (Access Token):
    • A token (often a JWT, but can be opaque) that proves the user has authorized your application to access specific resources on their behalf (defined by the scope requested).
    • Intended for the Resource Server (your target API, e.g., https://franklin.genoox.com/api/v2/...).
    • Crucially, include this token in the Authorization: Bearer <accessToken> header when making requests from your application (or your backend) to your protected API.
    • Security: Do NOT store Access Tokens in localStorage or sessionStorage due to vulnerability to XSS attacks. Store them securely in application memory (React state, Context API, Redux, etc.) for the duration needed. Fetch new tokens when the application loads or the previous token expires (Auth0 handles session management to facilitate this).

Development (of this package)

This package contains only the library code. For testing and development:

  1. Clone this repository.
  2. Install dependencies: bun install
  3. Build the package: bun run build
  4. Link the package locally: npm link (or bun link)
  5. In a separate test application (like the test-auth-app example), link the package: npm link @nettie/franklin-id (or bun link @nettie/franklin-id).
  6. Run the test application's development server (e.g., bun run dev). Changes in the franklin-id package will require rebuilding (bun run build) to be reflected in the test app.
# Example workflow:
# In ./franklin-id directory:
 bun install
 bun run build
 npm link # Or bun link

# In ../test-auth-app directory:
 bun install
 npm link @nettie/franklin-id # Or bun link @nettie/franklin-id
 bun run dev