{"_id":"@archie/auth0-user-security","_rev":"2-4b0076eee9f28661dbf9e8c66f7c869d","name":"@archie/auth0-user-security","dist-tags":{"latest":"0.1.7"},"versions":{"0.1.7":{"name":"@archie/auth0-user-security","version":"0.1.7","keywords":["auth0","authentication","user-security","session-management","identity","oauth","typescript","enterprise"],"author":{"name":"Archie Team"},"license":"UNLICENSED","_id":"@archie/auth0-user-security@0.1.7","maintainers":[{"name":"jorge.osorio","email":"jorge.osorio@8base.com"}],"homepage":"https://github.com/archie/archie-lib-auth0#readme","bugs":{"url":"https://github.com/archie/archie-lib-auth0/issues"},"dist":{"shasum":"051af8b72a94b1d850de31ca82df641429ff3c23","tarball":"https://registry.npmjs.org/@archie/auth0-user-security/-/auth0-user-security-0.1.7.tgz","fileCount":20,"integrity":"sha512-wVATwvan8sFoBAv5EnKSOhzBL5q0/HPppGBDT33wJLlqn0HcU8rYfHNJxgH/D7JUUW2vcrE4sLouBbq7wmnE2A==","signatures":[{"sig":"MEUCIDR5OwS1GwxCp3kyGe9pqZemL3VykAu+IfaXjf+ykBghAiEAl244VqVRCP8RxKFexIg1Xx4LRH88Zb5XeN6c9euWteQ=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":132912},"main":"dist/index.js","type":"module","_from":"file:archie-auth0-user-security-0.1.7.tgz","types":"dist/index.d.ts","module":"dist/index.esm.js","engines":{"node":">=18.0.0","pnpm":">=8.0.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.esm.js","require":"./dist/index.js"}},"scripts":{"dev":"tsx watch src/index.ts","docs":"typedoc src/index.ts","lint":"eslint src --ext .ts","test":"vitest","build":"rollup -c","format":"prettier --write \"src/**/*.ts\" \"./*.{js,ts,json,md}\"","lint:fix":"eslint src --ext .ts --fix","test:watch":"vitest --watch","type-check":"tsc --noEmit","build:watch":"rollup -c --watch","format:check":"prettier --check \"src/**/*.ts\" \"./*.{js,ts,json,md}\"","test:coverage":"vitest --coverage"},"_npmUser":{"name":"jorge.osorio","actor":{"name":"jorge.osorio","type":"user","email":"jorge.osorio@8base.com"},"email":"jorge.osorio@8base.com"},"_resolved":"/tmp/34b4a361293a5c46f3f151cdfeaa096e/archie-auth0-user-security-0.1.7.tgz","_integrity":"sha512-wVATwvan8sFoBAv5EnKSOhzBL5q0/HPppGBDT33wJLlqn0HcU8rYfHNJxgH/D7JUUW2vcrE4sLouBbq7wmnE2A==","repository":{"url":"git+https://github.com/archie/archie-lib-auth0.git","type":"git"},"_npmVersion":"10.8.2","description":"Enterprise-grade Auth0 user security library for Node.js applications","directories":{},"_nodeVersion":"20.19.2","dependencies":{"tslib":"^2.6.3","ua-parser-js":"^1.0.37"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.6.0","auth0":"^4.0.0","eslint":"^8.54.0","rollup":"^4.6.1","vitest":"^1.0.4","typedoc":"^0.25.4","prettier":"^3.1.0","typescript":"^5.3.2","@types/node":"^20.10.0","rollup-plugin-dts":"^6.1.0","@types/ua-parser-js":"^0.7.39","@vitest/coverage-v8":"^1.0.4","eslint-config-prettier":"^9.0.0","eslint-plugin-prettier":"^5.0.1","@rollup/plugin-commonjs":"^25.0.7","@rollup/plugin-typescript":"^11.1.5","@typescript-eslint/parser":"^8.35.0","@rollup/plugin-node-resolve":"^15.2.3","@typescript-eslint/eslint-plugin":"^8.35.0"},"peerDependencies":{"auth0":"^4.0.0"},"_npmOperationalInternal":{"tmp":"tmp/auth0-user-security_0.1.7_1751483950449_0.04962018755360087","host":"s3://npm-registry-packages-npm-production"}}},"time":{"created":"2025-07-02T19:19:10.368Z","modified":"2026-04-01T20:53:11.587Z","0.1.7":"2025-07-02T19:19:10.621Z"},"bugs":{"url":"https://github.com/archie/archie-lib-auth0/issues"},"author":{"name":"Archie Team"},"license":"UNLICENSED","homepage":"https://github.com/archie/archie-lib-auth0#readme","keywords":["auth0","authentication","user-security","session-management","identity","oauth","typescript","enterprise"],"repository":{"url":"git+https://github.com/archie/archie-lib-auth0.git","type":"git"},"description":"Enterprise-grade Auth0 user security library for Node.js applications","maintainers":[{"email":"anderson.losada@archie.com","name":"anderson-losada"},{"email":"jorge.osorio@8base.com","name":"jorge.osorio"}],"readme":"# @archie/auth0-user-security\n\nA framework-agnostic TypeScript library for managing Auth0 user security operations including session management, authentication methods, and account linking.\n\n## Features\n\n- **Session Management**: List, revoke, and manage user sessions\n- **Authentication Methods**: List and manage connected authentication providers\n- **Account Linking**: Connect and disconnect secondary authentication methods\n- **Password Management**: Generate secure password change tickets\n- **Framework Agnostic**: Core service works with any Node.js framework\n- **TypeScript Support**: Fully typed with comprehensive type definitions\n- **Enterprise Ready**: Built with enterprise-grade patterns and error handling\n\n## Installation\n\n```bash\nnpm install @archie/auth0-user-security\n# or\nyarn add @archie/auth0-user-security\n# or\npnpm add @archie/auth0-user-security\n```\n\n## Prerequisites\n\n### Auth0 Configuration\n\nBefore using this library, you need to configure your Auth0 tenant with the following:\n\n1. **Create a Machine to Machine Application**:\n   - Go to Auth0 Dashboard > Applications > Create Application\n   - Choose \"Machine to Machine Applications\"\n   - Select your API and grant the following scopes:\n     - `read:users`\n     - `update:users`\n     - `delete:users`\n     - `read:user_idp_tokens`\n     - `create:user_tickets`\n\n2. **Configure Social Connections** (optional):\n   - Go to Auth0 Dashboard > Authentication > Social\n   - Enable the providers you want to support (Google, GitHub, Microsoft, Apple)\n\n## Basic Usage\n\n```typescript\nimport { Auth0UserSecurityService } from \"@archie/auth0-user-security\";\n\n// Initialize the service\nconst userSecurityService = new Auth0UserSecurityService({\n  domain: \"your-tenant.auth0.com\",\n  clientId: \"your-client-id\",\n  clientSecret: \"your-client-secret\",\n  audience: \"your-api-audience\",\n});\n\n// List user sessions\nconst sessions = await userSecurityService.findUserSessions(\"user123\");\n\n// Revoke a specific session\nawait userSecurityService.revokeUserSession(\"user123\", \"sessionId\");\n\n// Generate password change ticket\nconst ticket =\n  await userSecurityService.generatePasswordChangeTicket(\"user123\");\n```\n\n## Usage Examples\n\n### Complete Session Management\n\n```typescript\nimport {\n  Auth0UserSecurityService,\n  UserAuthenticationMethodProvider,\n  SessionNotFoundError,\n  UserNotFoundError,\n  Auth0ApiError,\n  type IUser,\n  type UserSession,\n  type UserSessionRevokeInput,\n} from \"@archie/auth0-user-security\";\n\nconst userSecurityService = new Auth0UserSecurityService({\n  domain: process.env.AUTH0_DOMAIN!,\n  clientId: process.env.AUTH0_CLIENT_ID!,\n  clientSecret: process.env.AUTH0_CLIENT_SECRET!,\n});\n\n// 1. Find User Sessions - Get all active sessions for a user\nasync function getUserSessionsWithDetails(userEmail: string) {\n  try {\n    const user: IUser = { email: userEmail };\n    const sessions = await userSecurityService.findUserSessions(user);\n\n    console.log(`User ${userEmail} has ${sessions.length} active sessions:`);\n    sessions.forEach((session, index) => {\n      console.log(`Session ${index + 1}:`);\n      console.log(`  - ID: ${session.id}`);\n      console.log(`  - Platform: ${session.platform}`);\n      console.log(`  - Name: ${session.name}`);\n      console.log(`  - Address: ${session.address}`);\n      console.log(`  - Last Activity: ${session.lastActivityAt || \"Unknown\"}`);\n    });\n\n    return sessions;\n  } catch (error) {\n    if (error instanceof UserNotFoundError) {\n      console.error(`User not found: ${userEmail}`);\n    } else if (error instanceof Auth0ApiError) {\n      console.error(`Auth0 API error: ${error.message}`);\n    } else {\n      console.error(\"Error fetching user sessions:\", error.message);\n    }\n    throw error;\n  }\n}\n\n// 2. Revoke User Session - Revoke a specific session\nasync function revokeSpecificSession(userEmail: string, sessionId: string) {\n  try {\n    const user: IUser = { email: userEmail };\n    const sessionInput: UserSessionRevokeInput = { id: sessionId };\n\n    const success = await userSecurityService.revokeUserSession(\n      user,\n      sessionInput,\n    );\n\n    if (success) {\n      console.log(`✅ Session ${sessionId} revoked successfully`);\n    } else {\n      console.log(`❌ Failed to revoke session ${sessionId}`);\n    }\n\n    return success;\n  } catch (error) {\n    if (error instanceof SessionNotFoundError) {\n      console.log(\"Session not found or does not belong to user\");\n    } else if (error instanceof UserNotFoundError) {\n      console.log(\"User not found\");\n    } else {\n      console.error(\"Error revoking session:\", error.message);\n    }\n    throw error;\n  }\n}\n\n// 3. Revoke All User Sessions - Revoke all sessions for a user\nasync function revokeAllUserSessions(userEmail: string) {\n  try {\n    const user: IUser = { email: userEmail };\n    const success = await userSecurityService.revokeAllUserSessions(user);\n\n    if (success) {\n      console.log(`✅ All sessions revoked for user: ${userEmail}`);\n    } else {\n      console.log(`❌ Failed to revoke all sessions for user: ${userEmail}`);\n    }\n\n    return success;\n  } catch (error) {\n    if (error instanceof UserNotFoundError) {\n      console.error(`User not found: ${userEmail}`);\n    } else {\n      console.error(\"Error revoking all sessions:\", error.message);\n    }\n    throw error;\n  }\n}\n\n// 4. Smart Session Management - Revoke all sessions except current\nasync function revokeAllOtherSessions(\n  userEmail: string,\n  currentSessionId?: string,\n) {\n  try {\n    const user: IUser = { email: userEmail };\n    const sessions = await userSecurityService.findUserSessions(user);\n\n    // If no current session specified, revoke all\n    const sessionsToRevoke = currentSessionId\n      ? sessions.filter((session) => session.id !== currentSessionId)\n      : sessions;\n\n    let revokedCount = 0;\n    for (const session of sessionsToRevoke) {\n      try {\n        const sessionInput: UserSessionRevokeInput = { id: session.id };\n        const success = await userSecurityService.revokeUserSession(\n          user,\n          sessionInput,\n        );\n        if (success) {\n          console.log(\n            `Revoked session: ${session.name} on ${session.platform}`,\n          );\n          revokedCount++;\n        }\n      } catch (error) {\n        console.warn(`Failed to revoke session ${session.id}:`, error.message);\n      }\n    }\n\n    console.log(\n      `✅ Revoked ${revokedCount} out of ${sessionsToRevoke.length} sessions`,\n    );\n    return revokedCount;\n  } catch (error) {\n    console.error(\"Error revoking sessions:\", error.message);\n    throw error;\n  }\n}\n```\n\n### Authentication Methods Management\n\n```typescript\nimport {\n  type UserAuthenticationMethod,\n  type UserAuthenticationMethodDisconnectInput,\n} from \"@archie/auth0-user-security\";\n\n// 5. Find User Authentication Methods - Get all connected auth methods\nasync function displayUserAuthMethods(userEmail: string) {\n  try {\n    const user: IUser = { email: userEmail };\n    const methods =\n      await userSecurityService.findUserAuthenticationMethods(user);\n\n    console.log(\n      `User ${userEmail} has ${methods.length} authentication methods:`,\n    );\n    methods.forEach((method, index) => {\n      console.log(`Method ${index + 1}:`);\n      console.log(`  - ID: ${method.id}`);\n      console.log(`  - Provider: ${method.provider}`);\n      console.log(`  - Username: ${method.username}`);\n    });\n\n    return methods;\n  } catch (error) {\n    if (error instanceof UserNotFoundError) {\n      console.error(`User not found: ${userEmail}`);\n    } else {\n      console.error(\"Error fetching authentication methods:\", error.message);\n    }\n    throw error;\n  }\n}\n\n// 6. Connect Secondary Account - Link additional auth method\nasync function connectSecondaryAccount(\n  userEmail: string,\n  redirectUri: string,\n  authorizationCode: string,\n) {\n  try {\n    const user: IUser = { email: userEmail };\n\n    console.log(`Connecting secondary account for user: ${userEmail}`);\n    const updatedMethods = await userSecurityService.connectSecondaryAccount(\n      user,\n      redirectUri,\n      authorizationCode,\n    );\n\n    console.log(\"✅ Secondary account connected successfully!\");\n    console.log(\n      `User now has ${updatedMethods.length} authentication methods:`,\n    );\n    updatedMethods.forEach((method, i) => {\n      console.log(`  ${i + 1}. ${method.provider} (${method.username})`);\n    });\n\n    return updatedMethods;\n  } catch (error) {\n    if (error instanceof UserNotFoundError) {\n      console.error(`User not found: ${userEmail}`);\n    } else {\n      console.error(\"Error connecting secondary account:\", error.message);\n    }\n    throw error;\n  }\n}\n\n// 7. Disconnect Secondary Account - Remove linked auth method\nasync function disconnectSecondaryAccount(\n  userEmail: string,\n  methodId: string,\n  provider: UserAuthenticationMethodProvider,\n) {\n  try {\n    const user: IUser = { email: userEmail };\n    const methodInput: UserAuthenticationMethodDisconnectInput = {\n      id: methodId,\n      provider: provider,\n    };\n\n    console.log(`Disconnecting ${provider} account (${methodId})...`);\n    const updatedMethods = await userSecurityService.disconnectSecondaryAccount(\n      user,\n      methodInput,\n    );\n\n    console.log(`✅ ${provider} account disconnected successfully!`);\n    console.log(`User now has ${updatedMethods.length} authentication methods`);\n\n    return updatedMethods;\n  } catch (error) {\n    if (error instanceof UserNotFoundError) {\n      console.error(`User not found: ${userEmail}`);\n    } else {\n      console.error(`Error disconnecting ${provider} account:`, error.message);\n    }\n    throw error;\n  }\n}\n\n// Helper: Check if user has specific auth method\nasync function hasAuthenticationMethod(\n  userEmail: string,\n  provider: UserAuthenticationMethodProvider,\n): Promise<boolean> {\n  try {\n    const user: IUser = { email: userEmail };\n    const methods =\n      await userSecurityService.findUserAuthenticationMethods(user);\n    return methods.some((method) => method.provider === provider);\n  } catch (error) {\n    console.error(\"Error checking authentication method:\", error.message);\n    return false;\n  }\n}\n```\n\n### Password Management\n\n```typescript\nimport {\n  type UserAccountChangePasswordTicket,\n  type UserAccountConnectionTicket,\n  ConfigurationError,\n} from \"@archie/auth0-user-security\";\n\n// 8. Generate Password Change Ticket - Create secure password reset URL\nasync function initiatePasswordChange(userEmail: string, redirectUrl: string) {\n  try {\n    const user: IUser = { email: userEmail };\n\n    console.log(`Generating password change ticket for user: ${userEmail}`);\n    const ticket: UserAccountChangePasswordTicket =\n      await userSecurityService.generatePasswordChangeTicket(user, redirectUrl);\n\n    // Send email to user (pseudo-code)\n    await sendPasswordChangeEmail(userEmail, ticket.redirect);\n\n    console.log(\"✅ Password change ticket generated and sent to user\");\n    console.log(`Ticket URL: ${ticket.redirect}`);\n\n    return ticket;\n  } catch (error) {\n    if (error instanceof UserNotFoundError) {\n      console.error(`User not found: ${userEmail}`);\n    } else if (error instanceof ConfigurationError) {\n      console.error(`Configuration error: ${error.message}`);\n    } else {\n      console.error(\"Error generating password change ticket:\", error.message);\n    }\n    throw error;\n  }\n}\n\n// Helper function to send email (implement with your email service)\nasync function sendPasswordChangeEmail(email: string, ticketUrl: string) {\n  // Implementation depends on your email service (SendGrid, AWS SES, etc.)\n  console.log(`📧 Sending password change email to: ${email}`);\n  console.log(`🔗 Ticket URL: ${ticketUrl}`);\n\n  // Example with a generic email service\n  // await emailService.send({\n  //   to: email,\n  //   subject: 'Password Reset Request',\n  //   html: `\n  //     <h2>Password Reset</h2>\n  //     <p>Click the link below to reset your password:</p>\n  //     <a href=\"${ticketUrl}\">Reset Password</a>\n  //     <p>This link will expire in 24 hours.</p>\n  //   `\n  // });\n}\n```\n\n### Account Connection URL Generation\n\n```typescript\n// 9. Generate Account Connection URL - Create OAuth connection URL\nfunction generateAccountConnectionUrl(\n  provider: UserAuthenticationMethodProvider,\n  redirectUrl: string,\n) {\n  try {\n    console.log(`Generating connection URL for ${provider}...`);\n    const ticket: UserAccountConnectionTicket =\n      userSecurityService.generateAccountConnectionUrl(provider, redirectUrl);\n\n    console.log(`✅ Connection URL generated for ${provider}`);\n    console.log(`🔗 Redirect URL: ${ticket.redirect}`);\n    console.log(`📱 Provider: ${ticket.provider}`);\n\n    return ticket;\n  } catch (error) {\n    if (error instanceof ConfigurationError) {\n      console.error(`Configuration error: ${error.message}`);\n    } else {\n      console.error(\n        `Error generating connection URL for ${provider}:`,\n        error.message,\n      );\n    }\n    throw error;\n  }\n}\n\n// Complete OAuth flow example\nasync function completeOAuthFlow(\n  userEmail: string,\n  provider: UserAuthenticationMethodProvider,\n  callbackUrl: string,\n) {\n  try {\n    // Step 1: Generate connection URL\n    const ticket = generateAccountConnectionUrl(provider, callbackUrl);\n    console.log(`\\n🚀 Step 1: Visit this URL to connect ${provider}:`);\n    console.log(ticket.redirect);\n\n    // Step 2: After user completes OAuth, you'll receive authorization code in your callback\n    // This would typically be handled by your web server callback endpoint\n    console.log(`\\n⏳ Step 2: Waiting for OAuth callback...`);\n    console.log(\n      `Your callback endpoint should receive: ${callbackUrl}?code=AUTHORIZATION_CODE`,\n    );\n\n    // Step 3: Use the authorization code to link accounts (this would be in your callback handler)\n    // const authCode = 'received-from-callback';\n    // const methods = await connectSecondaryAccount(userEmail, callbackUrl, authCode);\n\n    return ticket;\n  } catch (error) {\n    console.error(\"Error in OAuth flow:\", error.message);\n    throw error;\n  }\n}\n```\n\n### Complete User Security Dashboard\n\n```typescript\n// 10. Complete Security Dashboard - Get all user security info\nasync function getUserSecurityDashboard(userEmail: string) {\n  try {\n    const user: IUser = { email: userEmail };\n\n    console.log(\"=== User Security Dashboard ===\");\n    console.log(`👤 User: ${userEmail}`);\n\n    // Get sessions\n    const sessions = await userSecurityService.findUserSessions(user);\n    console.log(`\\n📱 Active Sessions: ${sessions.length}`);\n    if (sessions.length > 0) {\n      sessions.forEach((session, i) => {\n        console.log(`  ${i + 1}. ${session.name} on ${session.platform}`);\n        console.log(`     IP: ${session.address}`);\n        console.log(\n          `     Last Activity: ${session.lastActivityAt || \"Unknown\"}`,\n        );\n      });\n    } else {\n      console.log(\"  No active sessions found\");\n    }\n\n    // Get authentication methods\n    const methods =\n      await userSecurityService.findUserAuthenticationMethods(user);\n    console.log(`\\n🔐 Authentication Methods: ${methods.length}`);\n    if (methods.length > 0) {\n      methods.forEach((method, i) => {\n        console.log(`  ${i + 1}. ${method.provider} (${method.username})`);\n      });\n    } else {\n      console.log(\"  No authentication methods found\");\n    }\n\n    // Security summary\n    console.log(`\\n📊 Security Summary:`);\n    console.log(`  - Total Sessions: ${sessions.length}`);\n    console.log(`  - Total Auth Methods: ${methods.length}`);\n    console.log(\n      `  - Has Social Auth: ${methods.some((m) => m.provider !== \"email-password\") ? \"Yes\" : \"No\"}`,\n    );\n    console.log(\n      `  - Primary Auth: ${methods.find((m) => m.provider === \"email-password\") ? \"Email/Password\" : \"Social Only\"}`,\n    );\n\n    return {\n      user: userEmail,\n      sessions,\n      methods,\n      summary: {\n        totalSessions: sessions.length,\n        totalAuthMethods: methods.length,\n        hasSocialAuth: methods.some((m) => m.provider !== \"email-password\"),\n        hasPrimaryAuth: methods.some((m) => m.provider === \"email-password\"),\n      },\n    };\n  } catch (error) {\n    if (error instanceof UserNotFoundError) {\n      console.error(`User not found: ${userEmail}`);\n    } else {\n      console.error(\"Error fetching user security dashboard:\", error.message);\n    }\n    throw error;\n  }\n}\n```\n\n### Bulk Operations and Advanced Examples\n\n```typescript\n// Bulk session management for multiple users\nasync function bulkRevokeUserSessions(userEmails: string[]) {\n  const results = [];\n\n  console.log(\n    `🔄 Processing ${userEmails.length} users for session revocation...`,\n  );\n\n  for (const userEmail of userEmails) {\n    try {\n      const user: IUser = { email: userEmail };\n      const success = await userSecurityService.revokeAllUserSessions(user);\n\n      results.push({\n        userEmail,\n        status: success ? \"success\" : \"failed\",\n        timestamp: new Date().toISOString(),\n      });\n\n      console.log(`✅ Revoked all sessions for user: ${userEmail}`);\n    } catch (error) {\n      results.push({\n        userEmail,\n        status: \"error\",\n        error: error.message,\n        timestamp: new Date().toISOString(),\n      });\n      console.log(\n        `❌ Failed to revoke sessions for user: ${userEmail} - ${error.message}`,\n      );\n    }\n  }\n\n  const successCount = results.filter((r) => r.status === \"success\").length;\n  console.log(`\\n📊 Bulk Operation Summary:`);\n  console.log(`  - Total Users: ${userEmails.length}`);\n  console.log(`  - Successful: ${successCount}`);\n  console.log(`  - Failed: ${userEmails.length - successCount}`);\n\n  return results;\n}\n\n// Security audit report with detailed analysis\nasync function generateSecurityAuditReport(userEmails: string[]) {\n  const report = {\n    generatedAt: new Date().toISOString(),\n    totalUsers: userEmails.length,\n    totalSessions: 0,\n    totalAuthMethods: 0,\n    userDetails: [],\n    statistics: {\n      usersWithMultipleSessions: 0,\n      usersWithSocialAuth: 0,\n      usersWithEmailPasswordOnly: 0,\n      averageSessionsPerUser: 0,\n      averageAuthMethodsPerUser: 0,\n      mostCommonProviders: {},\n    },\n  };\n\n  console.log(`🔍 Generating security audit for ${userEmails.length} users...`);\n\n  for (const userEmail of userEmails) {\n    try {\n      const user: IUser = { email: userEmail };\n      const [sessions, methods] = await Promise.all([\n        userSecurityService.findUserSessions(user),\n        userSecurityService.findUserAuthenticationMethods(user),\n      ]);\n\n      report.totalSessions += sessions.length;\n      report.totalAuthMethods += methods.length;\n\n      // Update statistics\n      if (sessions.length > 1) report.statistics.usersWithMultipleSessions++;\n      if (methods.some((m) => m.provider !== \"email-password\"))\n        report.statistics.usersWithSocialAuth++;\n      if (methods.every((m) => m.provider === \"email-password\"))\n        report.statistics.usersWithEmailPasswordOnly++;\n\n      // Count providers\n      methods.forEach((method) => {\n        report.statistics.mostCommonProviders[method.provider] =\n          (report.statistics.mostCommonProviders[method.provider] || 0) + 1;\n      });\n\n      report.userDetails.push({\n        userEmail,\n        sessionsCount: sessions.length,\n        authMethodsCount: methods.length,\n        providers: methods.map((m) => m.provider),\n        hasSocialAuth: methods.some((m) => m.provider !== \"email-password\"),\n        lastActivity: sessions.length > 0 ? sessions[0].lastActivityAt : null,\n        riskLevel: calculateRiskLevel(sessions, methods),\n      });\n\n      console.log(`✅ Processed user: ${userEmail}`);\n    } catch (error) {\n      console.error(`❌ Error processing user ${userEmail}:`, error.message);\n      report.userDetails.push({\n        userEmail,\n        error: error.message,\n        riskLevel: \"unknown\",\n      });\n    }\n  }\n\n  // Calculate averages\n  report.statistics.averageSessionsPerUser =\n    report.totalSessions / report.totalUsers;\n  report.statistics.averageAuthMethodsPerUser =\n    report.totalAuthMethods / report.totalUsers;\n\n  // Print report\n  console.log(\"\\n=== 🔒 SECURITY AUDIT REPORT ===\");\n  console.log(`📅 Generated: ${report.generatedAt}`);\n  console.log(`👥 Total Users Analyzed: ${report.totalUsers}`);\n  console.log(`📱 Total Active Sessions: ${report.totalSessions}`);\n  console.log(`🔐 Total Auth Methods: ${report.totalAuthMethods}`);\n  console.log(`\\n📊 Statistics:`);\n  console.log(\n    `  - Users with Multiple Sessions: ${report.statistics.usersWithMultipleSessions}`,\n  );\n  console.log(\n    `  - Users with Social Auth: ${report.statistics.usersWithSocialAuth}`,\n  );\n  console.log(\n    `  - Users with Email/Password Only: ${report.statistics.usersWithEmailPasswordOnly}`,\n  );\n  console.log(\n    `  - Average Sessions per User: ${report.statistics.averageSessionsPerUser.toFixed(2)}`,\n  );\n  console.log(\n    `  - Average Auth Methods per User: ${report.statistics.averageAuthMethodsPerUser.toFixed(2)}`,\n  );\n  console.log(`\\n🔝 Most Common Providers:`);\n  Object.entries(report.statistics.mostCommonProviders)\n    .sort(([, a], [, b]) => b - a)\n    .forEach(([provider, count]) => {\n      console.log(`  - ${provider}: ${count} users`);\n    });\n\n  return report;\n}\n\n// Helper function to calculate risk level\nfunction calculateRiskLevel(\n  sessions: UserSession[],\n  methods: UserAuthenticationMethod[],\n): \"low\" | \"medium\" | \"high\" {\n  let riskScore = 0;\n\n  // Multiple sessions increase risk\n  if (sessions.length > 3) riskScore += 2;\n  else if (sessions.length > 1) riskScore += 1;\n\n  // Only social auth (no email/password) increases risk\n  if (!methods.some((m) => m.provider === \"email-password\")) riskScore += 2;\n\n  // Many auth methods might indicate account compromise\n  if (methods.length > 3) riskScore += 1;\n\n  if (riskScore >= 4) return \"high\";\n  if (riskScore >= 2) return \"medium\";\n  return \"low\";\n}\n\n// Emergency security response - revoke all sessions for high-risk users\nasync function emergencySecurityResponse(userEmails: string[]) {\n  console.log(\"🚨 EMERGENCY SECURITY RESPONSE INITIATED\");\n\n  const results = [];\n\n  for (const userEmail of userEmails) {\n    try {\n      const user: IUser = { email: userEmail };\n\n      // Get current security status\n      const [sessions, methods] = await Promise.all([\n        userSecurityService.findUserSessions(user),\n        userSecurityService.findUserAuthenticationMethods(user),\n      ]);\n\n      const riskLevel = calculateRiskLevel(sessions, methods);\n\n      if (riskLevel === \"high\") {\n        // Revoke all sessions for high-risk users\n        const success = await userSecurityService.revokeAllUserSessions(user);\n\n        // Generate password reset ticket\n        const ticket = await userSecurityService.generatePasswordChangeTicket(\n          user,\n          \"https://yourapp.com/password-reset-complete\",\n        );\n\n        results.push({\n          userEmail,\n          action: \"sessions_revoked_password_reset_sent\",\n          riskLevel,\n          sessionsRevoked: success,\n          passwordResetUrl: ticket.redirect,\n          timestamp: new Date().toISOString(),\n        });\n\n        console.log(\n          `🔒 HIGH RISK - Revoked sessions and sent password reset for: ${userEmail}`,\n        );\n      } else {\n        results.push({\n          userEmail,\n          action: \"no_action_required\",\n          riskLevel,\n          timestamp: new Date().toISOString(),\n        });\n\n        console.log(\n          `✅ LOW/MEDIUM RISK - No action required for: ${userEmail}`,\n        );\n      }\n    } catch (error) {\n      results.push({\n        userEmail,\n        action: \"error\",\n        error: error.message,\n        timestamp: new Date().toISOString(),\n      });\n      console.log(`❌ Error processing ${userEmail}:`, error.message);\n    }\n  }\n\n  const actionsCount = results.filter(\n    (r) => r.action === \"sessions_revoked_password_reset_sent\",\n  ).length;\n  console.log(`\\n🚨 Emergency Response Summary:`);\n  console.log(`  - Users Processed: ${userEmails.length}`);\n  console.log(`  - High-Risk Actions Taken: ${actionsCount}`);\n  console.log(`  - Users Requiring Immediate Attention: ${actionsCount}`);\n\n  return results;\n}\n```\n\n## API Reference\n\n### Auth0UserSecurityService\n\nThe main service class providing all user security operations.\n\n#### Constructor\n\n```typescript\nconstructor(config: Auth0Config, logger?: ILogger)\n```\n\n**Parameters:**\n\n- `config`: Auth0 configuration object\n- `logger`: Optional logger instance (defaults to console)\n\n#### Methods\n\n##### `findUserSessions(userId: string): Promise<UserSession[]>`\n\nRetrieves all active sessions for a user.\n\n**Parameters:**\n\n- `userId`: The Auth0 user ID\n\n**Returns:** Array of user sessions with device and browser information\n\n**Example:**\n\n```typescript\nconst sessions = await userSecurityService.findUserSessions(\"auth0|user123\");\nconsole.log(sessions[0].device); // \"Desktop\"\nconsole.log(sessions[0].browser); // \"Chrome 120.0.0\"\n```\n\n##### `findUserAuthenticationMethods(userId: string): Promise<UserAuthenticationMethod[]>`\n\nRetrieves all authentication methods connected to a user account.\n\n**Parameters:**\n\n- `userId`: The Auth0 user ID\n\n**Returns:** Array of authentication methods\n\n**Example:**\n\n```typescript\nconst methods =\n  await userSecurityService.findUserAuthenticationMethods(\"auth0|user123\");\nconsole.log(methods[0].provider); // \"google-oauth2\"\nconsole.log(methods[0].connection); // \"google-oauth2\"\n```\n\n##### `revokeUserSession(userId: string, sessionId: string): Promise<void>`\n\nRevokes a specific user session.\n\n**Parameters:**\n\n- `userId`: The Auth0 user ID\n- `sessionId`: The session ID to revoke\n\n**Throws:**\n\n- `SessionNotFoundError`: If session doesn't exist or doesn't belong to user\n\n##### `revokeAllUserSessions(userId: string): Promise<void>`\n\nRevokes all sessions for a user.\n\n**Parameters:**\n\n- `userId`: The Auth0 user ID\n\n##### `generatePasswordChangeTicket(userId: string): Promise<string>`\n\nGenerates a secure password change ticket URL.\n\n**Parameters:**\n\n- `userId`: The Auth0 user ID\n\n**Returns:** Password change ticket URL\n\n##### `generateAccountConnectionUrl(userId: string, provider: UserAuthenticationMethodProvider): Promise<string>`\n\nGenerates a URL for connecting a new authentication method.\n\n**Parameters:**\n\n- `userId`: The Auth0 user ID\n- `provider`: The authentication provider to connect\n\n**Returns:** Connection URL\n\n##### `connectSecondaryAccount(userId: string, provider: UserAuthenticationMethodProvider, accessToken: string): Promise<UserAuthenticationMethod[]>`\n\nConnects a secondary authentication method to a user account.\n\n**Parameters:**\n\n- `userId`: The Auth0 user ID\n- `provider`: The authentication provider\n- `accessToken`: The access token from the provider\n\n**Returns:** Updated list of authentication methods\n\n##### `disconnectSecondaryAccount(userId: string, provider: UserAuthenticationMethodProvider, secondaryUserId: string): Promise<UserAuthenticationMethod[]>`\n\nDisconnects a secondary authentication method from a user account.\n\n**Parameters:**\n\n- `userId`: The Auth0 user ID\n- `provider`: The authentication provider\n- `secondaryUserId`: The secondary user ID to disconnect\n\n**Returns:** Updated list of authentication methods\n\n## Types\n\n### UserSession\n\n```typescript\ninterface UserSession {\n  id: string;\n  userId: string;\n  clientId: string;\n  createdAt: Date;\n  updatedAt: Date;\n  device: string;\n  browser: string;\n  os: string;\n  country?: string;\n  city?: string;\n  current: boolean;\n}\n```\n\n### UserAuthenticationMethod\n\n```typescript\ninterface UserAuthenticationMethod {\n  userId: string;\n  provider: UserAuthenticationMethodProvider;\n  connection: string;\n  isSocial: boolean;\n  profileData: Record<string, any>;\n}\n```\n\n### UserAuthenticationMethodProvider\n\n```typescript\nenum UserAuthenticationMethodProvider {\n  GOOGLE = \"google-oauth2\",\n  GITHUB = \"github\",\n  MICROSOFT = \"windowslive\",\n  APPLE = \"apple\",\n  EMAIL_PASSWORD = \"email-password\",\n}\n```\n\n## Framework Integration\n\n### NestJS Example\n\n```typescript\nimport { Injectable } from \"@nestjs/common\";\nimport { Auth0UserSecurityService } from \"@archie/auth0-user-security\";\n\n@Injectable()\nexport class UserSecurityService {\n  private readonly auth0Service: Auth0UserSecurityService;\n\n  constructor() {\n    this.auth0Service = new Auth0UserSecurityService({\n      domain: process.env.AUTH0_DOMAIN!,\n      clientId: process.env.AUTH0_CLIENT_ID!,\n      clientSecret: process.env.AUTH0_CLIENT_SECRET!,\n      audience: process.env.AUTH0_AUDIENCE!,\n    });\n  }\n\n  async getUserSessions(userId: string) {\n    return this.auth0Service.findUserSessions(userId);\n  }\n\n  async revokeSession(userId: string, sessionId: string) {\n    return this.auth0Service.revokeUserSession(userId, sessionId);\n  }\n}\n```\n\n### Express Example\n\n```typescript\nimport express from \"express\";\nimport { Auth0UserSecurityService } from \"@archie/auth0-user-security\";\n\nconst app = express();\nconst userSecurityService = new Auth0UserSecurityService({\n  domain: process.env.AUTH0_DOMAIN!,\n  clientId: process.env.AUTH0_CLIENT_ID!,\n  clientSecret: process.env.AUTH0_CLIENT_SECRET!,\n  audience: process.env.AUTH0_AUDIENCE!,\n});\n\napp.get(\"/users/:userId/sessions\", async (req, res) => {\n  try {\n    const sessions = await userSecurityService.findUserSessions(\n      req.params.userId,\n    );\n    res.json(sessions);\n  } catch (error) {\n    res.status(500).json({ error: error.message });\n  }\n});\n\napp.delete(\"/users/:userId/sessions/:sessionId\", async (req, res) => {\n  try {\n    await userSecurityService.revokeUserSession(\n      req.params.userId,\n      req.params.sessionId,\n    );\n    res.status(204).send();\n  } catch (error) {\n    res.status(500).json({ error: error.message });\n  }\n});\n```\n\n## Error Handling\n\nThe library provides specific error classes for different scenarios:\n\n```typescript\nimport {\n  UserNotFoundError,\n  SessionNotFoundError,\n  Auth0ApiError,\n  ConfigurationError,\n} from \"@archie/auth0-user-security\";\n\ntry {\n  await userSecurityService.revokeUserSession(\"user123\", \"session123\");\n} catch (error) {\n  if (error instanceof UserNotFoundError) {\n    console.log(\"User not found in Auth0\");\n  } else if (error instanceof SessionNotFoundError) {\n    console.log(\"Session not found or does not belong to user\");\n  } else if (error instanceof Auth0ApiError) {\n    console.log(\"Auth0 API error:\", error.message);\n  } else if (error instanceof ConfigurationError) {\n    console.log(\"Configuration error:\", error.message);\n  }\n}\n```\n\n## Environment Variables\n\nSet these environment variables for your application:\n\n```env\nAUTH0_DOMAIN=your-tenant.auth0.com\nAUTH0_CLIENT_ID=your-client-id\nAUTH0_CLIENT_SECRET=your-client-secret\nAUTH0_AUDIENCE=your-api-audience\n```\n\n## Security Considerations\n\n1. **Store credentials securely**: Never commit Auth0 credentials to version control\n2. **Use environment variables**: Store sensitive configuration in environment variables\n3. **Validate user ownership**: Always verify that the user making the request owns the resource\n4. **Rate limiting**: Implement rate limiting to prevent abuse\n5. **Audit logging**: Log security-related operations for compliance\n\n## Contributing\n\n1. Fork the repository\n2. Create a feature branch\n3. Make your changes\n4. Add tests for new functionality\n5. Run the test suite\n6. Submit a pull request\n\n## License\n\nMIT License - see LICENSE file for details\n\n## Support\n\nFor support, please open an issue on the GitHub repository or contact the maintainers.\n\n## Changelog\n\nSee [CHANGELOG.md](CHANGELOG.md) for version history and changes.\n","readmeFilename":"README.md"}