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

@archie/auth0-user-security

v0.1.7

Published

Enterprise-grade Auth0 user security library for Node.js applications

Readme

@archie/auth0-user-security

A framework-agnostic TypeScript library for managing Auth0 user security operations including session management, authentication methods, and account linking.

Features

  • Session Management: List, revoke, and manage user sessions
  • Authentication Methods: List and manage connected authentication providers
  • Account Linking: Connect and disconnect secondary authentication methods
  • Password Management: Generate secure password change tickets
  • Framework Agnostic: Core service works with any Node.js framework
  • TypeScript Support: Fully typed with comprehensive type definitions
  • Enterprise Ready: Built with enterprise-grade patterns and error handling

Installation

npm install @archie/auth0-user-security
# or
yarn add @archie/auth0-user-security
# or
pnpm add @archie/auth0-user-security

Prerequisites

Auth0 Configuration

Before using this library, you need to configure your Auth0 tenant with the following:

  1. Create a Machine to Machine Application:

    • Go to Auth0 Dashboard > Applications > Create Application
    • Choose "Machine to Machine Applications"
    • Select your API and grant the following scopes:
      • read:users
      • update:users
      • delete:users
      • read:user_idp_tokens
      • create:user_tickets
  2. Configure Social Connections (optional):

    • Go to Auth0 Dashboard > Authentication > Social
    • Enable the providers you want to support (Google, GitHub, Microsoft, Apple)

Basic Usage

import { Auth0UserSecurityService } from "@archie/auth0-user-security";

// Initialize the service
const userSecurityService = new Auth0UserSecurityService({
  domain: "your-tenant.auth0.com",
  clientId: "your-client-id",
  clientSecret: "your-client-secret",
  audience: "your-api-audience",
});

// List user sessions
const sessions = await userSecurityService.findUserSessions("user123");

// Revoke a specific session
await userSecurityService.revokeUserSession("user123", "sessionId");

// Generate password change ticket
const ticket =
  await userSecurityService.generatePasswordChangeTicket("user123");

Usage Examples

Complete Session Management

import {
  Auth0UserSecurityService,
  UserAuthenticationMethodProvider,
  SessionNotFoundError,
  UserNotFoundError,
  Auth0ApiError,
  type IUser,
  type UserSession,
  type UserSessionRevokeInput,
} from "@archie/auth0-user-security";

const userSecurityService = new Auth0UserSecurityService({
  domain: process.env.AUTH0_DOMAIN!,
  clientId: process.env.AUTH0_CLIENT_ID!,
  clientSecret: process.env.AUTH0_CLIENT_SECRET!,
});

// 1. Find User Sessions - Get all active sessions for a user
async function getUserSessionsWithDetails(userEmail: string) {
  try {
    const user: IUser = { email: userEmail };
    const sessions = await userSecurityService.findUserSessions(user);

    console.log(`User ${userEmail} has ${sessions.length} active sessions:`);
    sessions.forEach((session, index) => {
      console.log(`Session ${index + 1}:`);
      console.log(`  - ID: ${session.id}`);
      console.log(`  - Platform: ${session.platform}`);
      console.log(`  - Name: ${session.name}`);
      console.log(`  - Address: ${session.address}`);
      console.log(`  - Last Activity: ${session.lastActivityAt || "Unknown"}`);
    });

    return sessions;
  } catch (error) {
    if (error instanceof UserNotFoundError) {
      console.error(`User not found: ${userEmail}`);
    } else if (error instanceof Auth0ApiError) {
      console.error(`Auth0 API error: ${error.message}`);
    } else {
      console.error("Error fetching user sessions:", error.message);
    }
    throw error;
  }
}

// 2. Revoke User Session - Revoke a specific session
async function revokeSpecificSession(userEmail: string, sessionId: string) {
  try {
    const user: IUser = { email: userEmail };
    const sessionInput: UserSessionRevokeInput = { id: sessionId };

    const success = await userSecurityService.revokeUserSession(
      user,
      sessionInput,
    );

    if (success) {
      console.log(`✅ Session ${sessionId} revoked successfully`);
    } else {
      console.log(`❌ Failed to revoke session ${sessionId}`);
    }

    return success;
  } catch (error) {
    if (error instanceof SessionNotFoundError) {
      console.log("Session not found or does not belong to user");
    } else if (error instanceof UserNotFoundError) {
      console.log("User not found");
    } else {
      console.error("Error revoking session:", error.message);
    }
    throw error;
  }
}

// 3. Revoke All User Sessions - Revoke all sessions for a user
async function revokeAllUserSessions(userEmail: string) {
  try {
    const user: IUser = { email: userEmail };
    const success = await userSecurityService.revokeAllUserSessions(user);

    if (success) {
      console.log(`✅ All sessions revoked for user: ${userEmail}`);
    } else {
      console.log(`❌ Failed to revoke all sessions for user: ${userEmail}`);
    }

    return success;
  } catch (error) {
    if (error instanceof UserNotFoundError) {
      console.error(`User not found: ${userEmail}`);
    } else {
      console.error("Error revoking all sessions:", error.message);
    }
    throw error;
  }
}

// 4. Smart Session Management - Revoke all sessions except current
async function revokeAllOtherSessions(
  userEmail: string,
  currentSessionId?: string,
) {
  try {
    const user: IUser = { email: userEmail };
    const sessions = await userSecurityService.findUserSessions(user);

    // If no current session specified, revoke all
    const sessionsToRevoke = currentSessionId
      ? sessions.filter((session) => session.id !== currentSessionId)
      : sessions;

    let revokedCount = 0;
    for (const session of sessionsToRevoke) {
      try {
        const sessionInput: UserSessionRevokeInput = { id: session.id };
        const success = await userSecurityService.revokeUserSession(
          user,
          sessionInput,
        );
        if (success) {
          console.log(
            `Revoked session: ${session.name} on ${session.platform}`,
          );
          revokedCount++;
        }
      } catch (error) {
        console.warn(`Failed to revoke session ${session.id}:`, error.message);
      }
    }

    console.log(
      `✅ Revoked ${revokedCount} out of ${sessionsToRevoke.length} sessions`,
    );
    return revokedCount;
  } catch (error) {
    console.error("Error revoking sessions:", error.message);
    throw error;
  }
}

Authentication Methods Management

import {
  type UserAuthenticationMethod,
  type UserAuthenticationMethodDisconnectInput,
} from "@archie/auth0-user-security";

// 5. Find User Authentication Methods - Get all connected auth methods
async function displayUserAuthMethods(userEmail: string) {
  try {
    const user: IUser = { email: userEmail };
    const methods =
      await userSecurityService.findUserAuthenticationMethods(user);

    console.log(
      `User ${userEmail} has ${methods.length} authentication methods:`,
    );
    methods.forEach((method, index) => {
      console.log(`Method ${index + 1}:`);
      console.log(`  - ID: ${method.id}`);
      console.log(`  - Provider: ${method.provider}`);
      console.log(`  - Username: ${method.username}`);
    });

    return methods;
  } catch (error) {
    if (error instanceof UserNotFoundError) {
      console.error(`User not found: ${userEmail}`);
    } else {
      console.error("Error fetching authentication methods:", error.message);
    }
    throw error;
  }
}

// 6. Connect Secondary Account - Link additional auth method
async function connectSecondaryAccount(
  userEmail: string,
  redirectUri: string,
  authorizationCode: string,
) {
  try {
    const user: IUser = { email: userEmail };

    console.log(`Connecting secondary account for user: ${userEmail}`);
    const updatedMethods = await userSecurityService.connectSecondaryAccount(
      user,
      redirectUri,
      authorizationCode,
    );

    console.log("✅ Secondary account connected successfully!");
    console.log(
      `User now has ${updatedMethods.length} authentication methods:`,
    );
    updatedMethods.forEach((method, i) => {
      console.log(`  ${i + 1}. ${method.provider} (${method.username})`);
    });

    return updatedMethods;
  } catch (error) {
    if (error instanceof UserNotFoundError) {
      console.error(`User not found: ${userEmail}`);
    } else {
      console.error("Error connecting secondary account:", error.message);
    }
    throw error;
  }
}

// 7. Disconnect Secondary Account - Remove linked auth method
async function disconnectSecondaryAccount(
  userEmail: string,
  methodId: string,
  provider: UserAuthenticationMethodProvider,
) {
  try {
    const user: IUser = { email: userEmail };
    const methodInput: UserAuthenticationMethodDisconnectInput = {
      id: methodId,
      provider: provider,
    };

    console.log(`Disconnecting ${provider} account (${methodId})...`);
    const updatedMethods = await userSecurityService.disconnectSecondaryAccount(
      user,
      methodInput,
    );

    console.log(`✅ ${provider} account disconnected successfully!`);
    console.log(`User now has ${updatedMethods.length} authentication methods`);

    return updatedMethods;
  } catch (error) {
    if (error instanceof UserNotFoundError) {
      console.error(`User not found: ${userEmail}`);
    } else {
      console.error(`Error disconnecting ${provider} account:`, error.message);
    }
    throw error;
  }
}

// Helper: Check if user has specific auth method
async function hasAuthenticationMethod(
  userEmail: string,
  provider: UserAuthenticationMethodProvider,
): Promise<boolean> {
  try {
    const user: IUser = { email: userEmail };
    const methods =
      await userSecurityService.findUserAuthenticationMethods(user);
    return methods.some((method) => method.provider === provider);
  } catch (error) {
    console.error("Error checking authentication method:", error.message);
    return false;
  }
}

Password Management

import {
  type UserAccountChangePasswordTicket,
  type UserAccountConnectionTicket,
  ConfigurationError,
} from "@archie/auth0-user-security";

// 8. Generate Password Change Ticket - Create secure password reset URL
async function initiatePasswordChange(userEmail: string, redirectUrl: string) {
  try {
    const user: IUser = { email: userEmail };

    console.log(`Generating password change ticket for user: ${userEmail}`);
    const ticket: UserAccountChangePasswordTicket =
      await userSecurityService.generatePasswordChangeTicket(user, redirectUrl);

    // Send email to user (pseudo-code)
    await sendPasswordChangeEmail(userEmail, ticket.redirect);

    console.log("✅ Password change ticket generated and sent to user");
    console.log(`Ticket URL: ${ticket.redirect}`);

    return ticket;
  } catch (error) {
    if (error instanceof UserNotFoundError) {
      console.error(`User not found: ${userEmail}`);
    } else if (error instanceof ConfigurationError) {
      console.error(`Configuration error: ${error.message}`);
    } else {
      console.error("Error generating password change ticket:", error.message);
    }
    throw error;
  }
}

// Helper function to send email (implement with your email service)
async function sendPasswordChangeEmail(email: string, ticketUrl: string) {
  // Implementation depends on your email service (SendGrid, AWS SES, etc.)
  console.log(`📧 Sending password change email to: ${email}`);
  console.log(`🔗 Ticket URL: ${ticketUrl}`);

  // Example with a generic email service
  // await emailService.send({
  //   to: email,
  //   subject: 'Password Reset Request',
  //   html: `
  //     <h2>Password Reset</h2>
  //     <p>Click the link below to reset your password:</p>
  //     <a href="${ticketUrl}">Reset Password</a>
  //     <p>This link will expire in 24 hours.</p>
  //   `
  // });
}

Account Connection URL Generation

// 9. Generate Account Connection URL - Create OAuth connection URL
function generateAccountConnectionUrl(
  provider: UserAuthenticationMethodProvider,
  redirectUrl: string,
) {
  try {
    console.log(`Generating connection URL for ${provider}...`);
    const ticket: UserAccountConnectionTicket =
      userSecurityService.generateAccountConnectionUrl(provider, redirectUrl);

    console.log(`✅ Connection URL generated for ${provider}`);
    console.log(`🔗 Redirect URL: ${ticket.redirect}`);
    console.log(`📱 Provider: ${ticket.provider}`);

    return ticket;
  } catch (error) {
    if (error instanceof ConfigurationError) {
      console.error(`Configuration error: ${error.message}`);
    } else {
      console.error(
        `Error generating connection URL for ${provider}:`,
        error.message,
      );
    }
    throw error;
  }
}

// Complete OAuth flow example
async function completeOAuthFlow(
  userEmail: string,
  provider: UserAuthenticationMethodProvider,
  callbackUrl: string,
) {
  try {
    // Step 1: Generate connection URL
    const ticket = generateAccountConnectionUrl(provider, callbackUrl);
    console.log(`\n🚀 Step 1: Visit this URL to connect ${provider}:`);
    console.log(ticket.redirect);

    // Step 2: After user completes OAuth, you'll receive authorization code in your callback
    // This would typically be handled by your web server callback endpoint
    console.log(`\n⏳ Step 2: Waiting for OAuth callback...`);
    console.log(
      `Your callback endpoint should receive: ${callbackUrl}?code=AUTHORIZATION_CODE`,
    );

    // Step 3: Use the authorization code to link accounts (this would be in your callback handler)
    // const authCode = 'received-from-callback';
    // const methods = await connectSecondaryAccount(userEmail, callbackUrl, authCode);

    return ticket;
  } catch (error) {
    console.error("Error in OAuth flow:", error.message);
    throw error;
  }
}

Complete User Security Dashboard

// 10. Complete Security Dashboard - Get all user security info
async function getUserSecurityDashboard(userEmail: string) {
  try {
    const user: IUser = { email: userEmail };

    console.log("=== User Security Dashboard ===");
    console.log(`👤 User: ${userEmail}`);

    // Get sessions
    const sessions = await userSecurityService.findUserSessions(user);
    console.log(`\n📱 Active Sessions: ${sessions.length}`);
    if (sessions.length > 0) {
      sessions.forEach((session, i) => {
        console.log(`  ${i + 1}. ${session.name} on ${session.platform}`);
        console.log(`     IP: ${session.address}`);
        console.log(
          `     Last Activity: ${session.lastActivityAt || "Unknown"}`,
        );
      });
    } else {
      console.log("  No active sessions found");
    }

    // Get authentication methods
    const methods =
      await userSecurityService.findUserAuthenticationMethods(user);
    console.log(`\n🔐 Authentication Methods: ${methods.length}`);
    if (methods.length > 0) {
      methods.forEach((method, i) => {
        console.log(`  ${i + 1}. ${method.provider} (${method.username})`);
      });
    } else {
      console.log("  No authentication methods found");
    }

    // Security summary
    console.log(`\n📊 Security Summary:`);
    console.log(`  - Total Sessions: ${sessions.length}`);
    console.log(`  - Total Auth Methods: ${methods.length}`);
    console.log(
      `  - Has Social Auth: ${methods.some((m) => m.provider !== "email-password") ? "Yes" : "No"}`,
    );
    console.log(
      `  - Primary Auth: ${methods.find((m) => m.provider === "email-password") ? "Email/Password" : "Social Only"}`,
    );

    return {
      user: userEmail,
      sessions,
      methods,
      summary: {
        totalSessions: sessions.length,
        totalAuthMethods: methods.length,
        hasSocialAuth: methods.some((m) => m.provider !== "email-password"),
        hasPrimaryAuth: methods.some((m) => m.provider === "email-password"),
      },
    };
  } catch (error) {
    if (error instanceof UserNotFoundError) {
      console.error(`User not found: ${userEmail}`);
    } else {
      console.error("Error fetching user security dashboard:", error.message);
    }
    throw error;
  }
}

Bulk Operations and Advanced Examples

// Bulk session management for multiple users
async function bulkRevokeUserSessions(userEmails: string[]) {
  const results = [];

  console.log(
    `🔄 Processing ${userEmails.length} users for session revocation...`,
  );

  for (const userEmail of userEmails) {
    try {
      const user: IUser = { email: userEmail };
      const success = await userSecurityService.revokeAllUserSessions(user);

      results.push({
        userEmail,
        status: success ? "success" : "failed",
        timestamp: new Date().toISOString(),
      });

      console.log(`✅ Revoked all sessions for user: ${userEmail}`);
    } catch (error) {
      results.push({
        userEmail,
        status: "error",
        error: error.message,
        timestamp: new Date().toISOString(),
      });
      console.log(
        `❌ Failed to revoke sessions for user: ${userEmail} - ${error.message}`,
      );
    }
  }

  const successCount = results.filter((r) => r.status === "success").length;
  console.log(`\n📊 Bulk Operation Summary:`);
  console.log(`  - Total Users: ${userEmails.length}`);
  console.log(`  - Successful: ${successCount}`);
  console.log(`  - Failed: ${userEmails.length - successCount}`);

  return results;
}

// Security audit report with detailed analysis
async function generateSecurityAuditReport(userEmails: string[]) {
  const report = {
    generatedAt: new Date().toISOString(),
    totalUsers: userEmails.length,
    totalSessions: 0,
    totalAuthMethods: 0,
    userDetails: [],
    statistics: {
      usersWithMultipleSessions: 0,
      usersWithSocialAuth: 0,
      usersWithEmailPasswordOnly: 0,
      averageSessionsPerUser: 0,
      averageAuthMethodsPerUser: 0,
      mostCommonProviders: {},
    },
  };

  console.log(`🔍 Generating security audit for ${userEmails.length} users...`);

  for (const userEmail of userEmails) {
    try {
      const user: IUser = { email: userEmail };
      const [sessions, methods] = await Promise.all([
        userSecurityService.findUserSessions(user),
        userSecurityService.findUserAuthenticationMethods(user),
      ]);

      report.totalSessions += sessions.length;
      report.totalAuthMethods += methods.length;

      // Update statistics
      if (sessions.length > 1) report.statistics.usersWithMultipleSessions++;
      if (methods.some((m) => m.provider !== "email-password"))
        report.statistics.usersWithSocialAuth++;
      if (methods.every((m) => m.provider === "email-password"))
        report.statistics.usersWithEmailPasswordOnly++;

      // Count providers
      methods.forEach((method) => {
        report.statistics.mostCommonProviders[method.provider] =
          (report.statistics.mostCommonProviders[method.provider] || 0) + 1;
      });

      report.userDetails.push({
        userEmail,
        sessionsCount: sessions.length,
        authMethodsCount: methods.length,
        providers: methods.map((m) => m.provider),
        hasSocialAuth: methods.some((m) => m.provider !== "email-password"),
        lastActivity: sessions.length > 0 ? sessions[0].lastActivityAt : null,
        riskLevel: calculateRiskLevel(sessions, methods),
      });

      console.log(`✅ Processed user: ${userEmail}`);
    } catch (error) {
      console.error(`❌ Error processing user ${userEmail}:`, error.message);
      report.userDetails.push({
        userEmail,
        error: error.message,
        riskLevel: "unknown",
      });
    }
  }

  // Calculate averages
  report.statistics.averageSessionsPerUser =
    report.totalSessions / report.totalUsers;
  report.statistics.averageAuthMethodsPerUser =
    report.totalAuthMethods / report.totalUsers;

  // Print report
  console.log("\n=== 🔒 SECURITY AUDIT REPORT ===");
  console.log(`📅 Generated: ${report.generatedAt}`);
  console.log(`👥 Total Users Analyzed: ${report.totalUsers}`);
  console.log(`📱 Total Active Sessions: ${report.totalSessions}`);
  console.log(`🔐 Total Auth Methods: ${report.totalAuthMethods}`);
  console.log(`\n📊 Statistics:`);
  console.log(
    `  - Users with Multiple Sessions: ${report.statistics.usersWithMultipleSessions}`,
  );
  console.log(
    `  - Users with Social Auth: ${report.statistics.usersWithSocialAuth}`,
  );
  console.log(
    `  - Users with Email/Password Only: ${report.statistics.usersWithEmailPasswordOnly}`,
  );
  console.log(
    `  - Average Sessions per User: ${report.statistics.averageSessionsPerUser.toFixed(2)}`,
  );
  console.log(
    `  - Average Auth Methods per User: ${report.statistics.averageAuthMethodsPerUser.toFixed(2)}`,
  );
  console.log(`\n🔝 Most Common Providers:`);
  Object.entries(report.statistics.mostCommonProviders)
    .sort(([, a], [, b]) => b - a)
    .forEach(([provider, count]) => {
      console.log(`  - ${provider}: ${count} users`);
    });

  return report;
}

// Helper function to calculate risk level
function calculateRiskLevel(
  sessions: UserSession[],
  methods: UserAuthenticationMethod[],
): "low" | "medium" | "high" {
  let riskScore = 0;

  // Multiple sessions increase risk
  if (sessions.length > 3) riskScore += 2;
  else if (sessions.length > 1) riskScore += 1;

  // Only social auth (no email/password) increases risk
  if (!methods.some((m) => m.provider === "email-password")) riskScore += 2;

  // Many auth methods might indicate account compromise
  if (methods.length > 3) riskScore += 1;

  if (riskScore >= 4) return "high";
  if (riskScore >= 2) return "medium";
  return "low";
}

// Emergency security response - revoke all sessions for high-risk users
async function emergencySecurityResponse(userEmails: string[]) {
  console.log("🚨 EMERGENCY SECURITY RESPONSE INITIATED");

  const results = [];

  for (const userEmail of userEmails) {
    try {
      const user: IUser = { email: userEmail };

      // Get current security status
      const [sessions, methods] = await Promise.all([
        userSecurityService.findUserSessions(user),
        userSecurityService.findUserAuthenticationMethods(user),
      ]);

      const riskLevel = calculateRiskLevel(sessions, methods);

      if (riskLevel === "high") {
        // Revoke all sessions for high-risk users
        const success = await userSecurityService.revokeAllUserSessions(user);

        // Generate password reset ticket
        const ticket = await userSecurityService.generatePasswordChangeTicket(
          user,
          "https://yourapp.com/password-reset-complete",
        );

        results.push({
          userEmail,
          action: "sessions_revoked_password_reset_sent",
          riskLevel,
          sessionsRevoked: success,
          passwordResetUrl: ticket.redirect,
          timestamp: new Date().toISOString(),
        });

        console.log(
          `🔒 HIGH RISK - Revoked sessions and sent password reset for: ${userEmail}`,
        );
      } else {
        results.push({
          userEmail,
          action: "no_action_required",
          riskLevel,
          timestamp: new Date().toISOString(),
        });

        console.log(
          `✅ LOW/MEDIUM RISK - No action required for: ${userEmail}`,
        );
      }
    } catch (error) {
      results.push({
        userEmail,
        action: "error",
        error: error.message,
        timestamp: new Date().toISOString(),
      });
      console.log(`❌ Error processing ${userEmail}:`, error.message);
    }
  }

  const actionsCount = results.filter(
    (r) => r.action === "sessions_revoked_password_reset_sent",
  ).length;
  console.log(`\n🚨 Emergency Response Summary:`);
  console.log(`  - Users Processed: ${userEmails.length}`);
  console.log(`  - High-Risk Actions Taken: ${actionsCount}`);
  console.log(`  - Users Requiring Immediate Attention: ${actionsCount}`);

  return results;
}

API Reference

Auth0UserSecurityService

The main service class providing all user security operations.

Constructor

constructor(config: Auth0Config, logger?: ILogger)

Parameters:

  • config: Auth0 configuration object
  • logger: Optional logger instance (defaults to console)

Methods

findUserSessions(userId: string): Promise<UserSession[]>

Retrieves all active sessions for a user.

Parameters:

  • userId: The Auth0 user ID

Returns: Array of user sessions with device and browser information

Example:

const sessions = await userSecurityService.findUserSessions("auth0|user123");
console.log(sessions[0].device); // "Desktop"
console.log(sessions[0].browser); // "Chrome 120.0.0"
findUserAuthenticationMethods(userId: string): Promise<UserAuthenticationMethod[]>

Retrieves all authentication methods connected to a user account.

Parameters:

  • userId: The Auth0 user ID

Returns: Array of authentication methods

Example:

const methods =
  await userSecurityService.findUserAuthenticationMethods("auth0|user123");
console.log(methods[0].provider); // "google-oauth2"
console.log(methods[0].connection); // "google-oauth2"
revokeUserSession(userId: string, sessionId: string): Promise<void>

Revokes a specific user session.

Parameters:

  • userId: The Auth0 user ID
  • sessionId: The session ID to revoke

Throws:

  • SessionNotFoundError: If session doesn't exist or doesn't belong to user
revokeAllUserSessions(userId: string): Promise<void>

Revokes all sessions for a user.

Parameters:

  • userId: The Auth0 user ID
generatePasswordChangeTicket(userId: string): Promise<string>

Generates a secure password change ticket URL.

Parameters:

  • userId: The Auth0 user ID

Returns: Password change ticket URL

generateAccountConnectionUrl(userId: string, provider: UserAuthenticationMethodProvider): Promise<string>

Generates a URL for connecting a new authentication method.

Parameters:

  • userId: The Auth0 user ID
  • provider: The authentication provider to connect

Returns: Connection URL

connectSecondaryAccount(userId: string, provider: UserAuthenticationMethodProvider, accessToken: string): Promise<UserAuthenticationMethod[]>

Connects a secondary authentication method to a user account.

Parameters:

  • userId: The Auth0 user ID
  • provider: The authentication provider
  • accessToken: The access token from the provider

Returns: Updated list of authentication methods

disconnectSecondaryAccount(userId: string, provider: UserAuthenticationMethodProvider, secondaryUserId: string): Promise<UserAuthenticationMethod[]>

Disconnects a secondary authentication method from a user account.

Parameters:

  • userId: The Auth0 user ID
  • provider: The authentication provider
  • secondaryUserId: The secondary user ID to disconnect

Returns: Updated list of authentication methods

Types

UserSession

interface UserSession {
  id: string;
  userId: string;
  clientId: string;
  createdAt: Date;
  updatedAt: Date;
  device: string;
  browser: string;
  os: string;
  country?: string;
  city?: string;
  current: boolean;
}

UserAuthenticationMethod

interface UserAuthenticationMethod {
  userId: string;
  provider: UserAuthenticationMethodProvider;
  connection: string;
  isSocial: boolean;
  profileData: Record<string, any>;
}

UserAuthenticationMethodProvider

enum UserAuthenticationMethodProvider {
  GOOGLE = "google-oauth2",
  GITHUB = "github",
  MICROSOFT = "windowslive",
  APPLE = "apple",
  EMAIL_PASSWORD = "email-password",
}

Framework Integration

NestJS Example

import { Injectable } from "@nestjs/common";
import { Auth0UserSecurityService } from "@archie/auth0-user-security";

@Injectable()
export class UserSecurityService {
  private readonly auth0Service: Auth0UserSecurityService;

  constructor() {
    this.auth0Service = new Auth0UserSecurityService({
      domain: process.env.AUTH0_DOMAIN!,
      clientId: process.env.AUTH0_CLIENT_ID!,
      clientSecret: process.env.AUTH0_CLIENT_SECRET!,
      audience: process.env.AUTH0_AUDIENCE!,
    });
  }

  async getUserSessions(userId: string) {
    return this.auth0Service.findUserSessions(userId);
  }

  async revokeSession(userId: string, sessionId: string) {
    return this.auth0Service.revokeUserSession(userId, sessionId);
  }
}

Express Example

import express from "express";
import { Auth0UserSecurityService } from "@archie/auth0-user-security";

const app = express();
const userSecurityService = new Auth0UserSecurityService({
  domain: process.env.AUTH0_DOMAIN!,
  clientId: process.env.AUTH0_CLIENT_ID!,
  clientSecret: process.env.AUTH0_CLIENT_SECRET!,
  audience: process.env.AUTH0_AUDIENCE!,
});

app.get("/users/:userId/sessions", async (req, res) => {
  try {
    const sessions = await userSecurityService.findUserSessions(
      req.params.userId,
    );
    res.json(sessions);
  } catch (error) {
    res.status(500).json({ error: error.message });
  }
});

app.delete("/users/:userId/sessions/:sessionId", async (req, res) => {
  try {
    await userSecurityService.revokeUserSession(
      req.params.userId,
      req.params.sessionId,
    );
    res.status(204).send();
  } catch (error) {
    res.status(500).json({ error: error.message });
  }
});

Error Handling

The library provides specific error classes for different scenarios:

import {
  UserNotFoundError,
  SessionNotFoundError,
  Auth0ApiError,
  ConfigurationError,
} from "@archie/auth0-user-security";

try {
  await userSecurityService.revokeUserSession("user123", "session123");
} catch (error) {
  if (error instanceof UserNotFoundError) {
    console.log("User not found in Auth0");
  } else if (error instanceof SessionNotFoundError) {
    console.log("Session not found or does not belong to user");
  } else if (error instanceof Auth0ApiError) {
    console.log("Auth0 API error:", error.message);
  } else if (error instanceof ConfigurationError) {
    console.log("Configuration error:", error.message);
  }
}

Environment Variables

Set these environment variables for your application:

AUTH0_DOMAIN=your-tenant.auth0.com
AUTH0_CLIENT_ID=your-client-id
AUTH0_CLIENT_SECRET=your-client-secret
AUTH0_AUDIENCE=your-api-audience

Security Considerations

  1. Store credentials securely: Never commit Auth0 credentials to version control
  2. Use environment variables: Store sensitive configuration in environment variables
  3. Validate user ownership: Always verify that the user making the request owns the resource
  4. Rate limiting: Implement rate limiting to prevent abuse
  5. Audit logging: Log security-related operations for compliance

Contributing

  1. Fork the repository
  2. Create a feature branch
  3. Make your changes
  4. Add tests for new functionality
  5. Run the test suite
  6. Submit a pull request

License

MIT License - see LICENSE file for details

Support

For support, please open an issue on the GitHub repository or contact the maintainers.

Changelog

See CHANGELOG.md for version history and changes.