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

@exyconn/auth

v1.4.0

Published

React authentication hooks, components and server middleware for Exyconn Auth integration

Downloads

1,146

Readme

@exyconn/auth

React authentication hooks, components, and server middleware for Exyconn Auth integration with multi-tenant API key support.

Features

  • 🔐 Client-side hooks - React hooks for authentication state management
  • 🛡️ Guard components - Declarative auth protection for your components
  • 🔒 Protected routes - Easy route protection with automatic redirects
  • Server middleware - Express middleware for API authentication
  • 🏢 Multi-tenant support - API key-based tenant identification

Installation

npm install @exyconn/auth
# or
yarn add @exyconn/auth
# or
pnpm add @exyconn/auth

Subpackages

This package provides two subpackages for different use cases:

| Subpackage | Import | Use Case | |------------|--------|----------| | @exyconn/auth | Main entry | All client-side features | | @exyconn/auth/client | Client-only | React hooks & components | | @exyconn/auth/server | Server-only | Express middleware |


Client Usage (@exyconn/auth or @exyconn/auth/client)

1. Wrap your app with ExyconnAuthProvider

import { ExyconnAuthProvider } from '@exyconn/auth';

function App() {
  return (
    <ExyconnAuthProvider
      apiAuthBaseUrl="https://exyconn-auth-server.exyconn.com"
      uiAuthUrl="https://auth.exyconn.com"
      apiKey="exy_your_api_key"
    >
      <YourApp />
    </ExyconnAuthProvider>
  );
}

2. Use authentication hooks

import { useIsAuthenticated, useUser, useLogout } from '@exyconn/auth';

function ProfilePage() {
  const isAuthenticated = useIsAuthenticated();
  const user = useUser();
  const logout = useLogout();

  if (!isAuthenticated) {
    return <Navigate to="/login" />;
  }

  return (
    <div>
      <img src={user?.profilePicture} alt="Profile" />
      <h1>Hello, {user?.firstName}!</h1>
      <p>Email: {user?.email}</p>
      <button onClick={logout}>Logout</button>
    </div>
  );
}

3. Use guard components

import { RequireAuth, RequireRole, RequirePermission } from '@exyconn/auth';

// Require authentication
<RequireAuth fallback={<LoginPage />}>
  <Dashboard />
</RequireAuth>

// Require specific role
<RequireRole role="admin" fallback={<AccessDenied />}>
  <AdminPanel />
</RequireRole>

// Require specific permission
<RequirePermission permission="posts:edit" fallback={<AccessDenied />}>
  <EditButton />
</RequirePermission>

4. Use ProtectedRoute

import { ProtectedRoute } from '@exyconn/auth';

// Automatically redirects to login if not authenticated
<ProtectedRoute>
  <Dashboard />
</ProtectedRoute>

// With custom loading
<ProtectedRoute loading={<Spinner />}>
  <Dashboard />
</ProtectedRoute>

// With custom fallback (no redirect)
<ProtectedRoute fallback={<LoginPage />} redirectToLogin={false}>
  <Dashboard />
</ProtectedRoute>

Server Usage (@exyconn/auth/server)

1. Use the auth middleware

import express from 'express';
import { authMiddleware } from '@exyconn/auth/server';

const app = express();

// Set environment variables
// API_KEY=your_api_key
// AUTH_API_BASE_URL=https://exyconn-auth-server.exyconn.com

// Protected route
app.get('/api/protected', authMiddleware, (req, res) => {
  res.json({
    message: `Hello ${req.user?.firstName}!`,
    user: req.user,
  });
});

2. Create custom middleware with options

import { createAuthMiddleware } from '@exyconn/auth/server';

const authMiddleware = createAuthMiddleware({
  apiKey: 'your-api-key',
  apiAuthBaseUrl: 'https://your-auth-server.com',
  onError: (error, req, res) => {
    res.status(401).json({ 
      success: false, 
      error 
    });
  },
});

app.get('/api/protected', authMiddleware, (req, res) => {
  res.json({ user: req.user });
});

3. Validate tokens directly

import { validateToken } from '@exyconn/auth/server';

const result = await validateToken({
  token: 'user-token-here',
  apiKey: 'your-api-key',
});

if (result.valid) {
  console.log('User:', result.user);
} else {
  console.error('Invalid:', result.error);
}

Provider Configuration

<ExyconnAuthProvider
  // Base URL for your Exyconn Auth API server (required)
  apiAuthBaseUrl="https://exyconn-auth-server.exyconn.com"
  
  // Base URL for the Auth UI (required)
  uiAuthUrl="https://auth.exyconn.com"
  
  // API key for multi-tenant authentication (required)
  apiKey="exy_your_api_key"
  
  // Whether to auto-fetch user on mount (default: true)
  autoFetch={true}
  
  // Callback when authentication fails
  onAuthError={(error) => console.error(error)}
  
  // Callback when user is successfully authenticated
  onAuthSuccess={(user) => console.log('Logged in:', user)}
  
  // Custom headers for API requests
  headers={{ 'X-Custom-Header': 'value' }}
>
  {children}
</ExyconnAuthProvider>

Available Hooks

| Hook | Return Type | Description | |------|-------------|-------------| | useExyconnAuth() | ExyconnAuthContextValue | Full auth context | | useIsAuthenticated() | boolean | Check if authenticated | | useUser() | AuthUser \| null | Get current user | | useOrganization() | AuthOrganization \| null | Get organization | | useRole() | AuthRole \| null | Get user role | | useRoleSlug() | string \| null | Get role slug | | useHasRole(role) | boolean | Check specific role | | useHasPermission(perm) | boolean | Check permission | | useHasAnyPermission(perms) | boolean | Check any permission | | useHasAllPermissions(perms) | boolean | Check all permissions | | useAuthLoading() | boolean | Loading state | | useAuthError() | string \| null | Error state | | useLogout() | () => void | Logout function | | useAuthToken() | { get, set } | Token management | | useApiKey() | { get, set } | API key management | | useAuthUrls() | { getLoginUrl, ... } | Auth URL builders |


Guard Components

| Component | Props | Description | |-----------|-------|-------------| | <RequireAuth> | fallback, loading | Require authentication | | <RequireRole> | role, fallback, loading | Require specific role | | <RequirePermission> | permission, fallback, loading | Require permission | | <RequireAnyPermission> | permissions[], fallback, loading | Require any permission | | <RequireAllPermissions> | permissions[], fallback, loading | Require all permissions | | <ProtectedRoute> | fallback, loading, redirectToLogin, redirectUrl | Route protection |


Types

AuthUser

interface AuthUser {
  id: string;
  firstName: string;
  lastName: string;
  email: string;
  profilePicture?: string;
  role: string;
  isVerified?: boolean;
  mfaEnabled?: boolean;
  createdAt: string;
  lastLoginAt?: string;
}

Server AuthUser

interface AuthUser {
  id: string;
  email: string;
  firstName?: string;
  lastName?: string;
  profilePicture?: string;
  role?: string;
  isVerified?: boolean;
}

API Endpoints

This package uses the following Exyconn Auth API endpoints:

  • GET /v1/api/auth/me - Get current user
  • GET /v1/api/auth/role - Get current user's role
  • POST /v1/api/auth/logout - Logout user
  • POST /token/validate - Validate token (server-side)

Example: Full Stack Setup

Frontend (React)

import { ExyconnAuthProvider, ProtectedRoute, useUser } from '@exyconn/auth';

function App() {
  return (
    <ExyconnAuthProvider
      apiAuthBaseUrl="https://exyconn-auth-server.exyconn.com"
      uiAuthUrl="https://auth.exyconn.com"
      apiKey="exy_your_api_key"
    >
      <ProtectedRoute>
        <Dashboard />
      </ProtectedRoute>
    </ExyconnAuthProvider>
  );
}

function Dashboard() {
  const user = useUser();
  
  return (
    <div>
      <img src={user?.profilePicture} alt="" />
      <h1>Welcome, {user?.firstName}!</h1>
    </div>
  );
}

Backend (Express)

import express from 'express';
import cors from 'cors';
import { createAuthMiddleware } from '@exyconn/auth/server';

const app = express();
app.use(cors({ origin: 'http://localhost:3000', credentials: true }));
app.use(express.json());

const authMiddleware = createAuthMiddleware({
  apiKey: process.env.API_KEY!,
});

app.get('/api/user', authMiddleware, (req, res) => {
  res.json({ user: req.user });
});

app.listen(4000);

License

MIT © Exyconn