# @idp.global/idpclient A TypeScript client library for integrating with the idp.global Identity Provider. Works in both browser and Node.js environments. ## Overview The IdpClient provides a complete API for authentication, session management, and organization operations. It uses WebSocket connections via TypedSocket for real-time, type-safe communication with the IdP server. ## Installation ```bash npm install @idp.global/idpclient # or pnpm add @idp.global/idpclient ``` ## Quick Start ```typescript import { IdpClient } from '@idp.global/idpclient'; // Initialize the client const idpClient = new IdpClient('https://idp.global'); // Enable WebSocket connection await idpClient.enableTypedSocket(); // Check login status const isLoggedIn = await idpClient.determineLoginStatus(); if (isLoggedIn) { const userInfo = await idpClient.whoIs(); console.log('Logged in as:', userInfo.user.data.name); } ``` ## Core Features ### Authentication #### Password Login ```typescript const response = await idpClient.requests.loginWithUserNameAndPassword.fire({ username: 'user@example.com', password: 'securepassword', }); if (response.refreshToken) { await idpClient.refreshJwt(response.refreshToken); console.log('Login successful!'); } else if (response.twoFaNeeded) { console.log('2FA verification required'); } ``` #### Magic Link Login ```typescript // Request magic link await idpClient.requests.loginWithEmail.fire({ email: 'user@example.com', }); // After clicking the email link const result = await idpClient.requests.loginWithEmailAfterToken.fire({ email: 'user@example.com', token: 'token-from-email-link', }); if (result.refreshToken) { await idpClient.refreshJwt(result.refreshToken); } ``` #### API Token Login ```typescript const result = await idpClient.requests.loginWithApiToken.fire({ apiToken: 'your-api-token', }); if (result.jwt) { await idpClient.setJwt(result.jwt); } ``` ### Session Management ```typescript // Get current JWT const jwt = await idpClient.getJwt(); // Get parsed JWT data const jwtData = await idpClient.getJwtData(); console.log('User ID:', jwtData.id); // Refresh JWT (automatic housekeeping) await idpClient.performJwtHousekeeping(); // Manual refresh await idpClient.refreshJwt(); // Logout await idpClient.logout(); ``` ### User Information ```typescript // Get current user details const whoIsResponse = await idpClient.whoIs(); console.log('Name:', whoIsResponse.user.data.name); console.log('Email:', whoIsResponse.user.data.email); // Get user data const userData = await idpClient.requests.getUserData.fire({ jwt: await idpClient.getJwt(), userId: jwtData.id, }); // Update user data await idpClient.requests.setUserData.fire({ jwt: await idpClient.getJwt(), userId: jwtData.id, name: 'New Name', }); ``` ### Organization Management ```typescript // Get user's organizations and roles const orgsAndRoles = await idpClient.getRolesAndOrganizations(); console.log('Organizations:', orgsAndRoles.organizations); console.log('Roles:', orgsAndRoles.roles); // Create a new organization const result = await idpClient.createOrganization( 'My Company', // name 'my-company', // slug 'manifest' // mode: 'checkAvailability' or 'manifest' ); if (result.resultingOrganization) { console.log('Created:', result.resultingOrganization.id); } // Get organization details const orgDetails = await idpClient.requests.getOrganizationById.fire({ jwt: await idpClient.getJwt(), organizationId: 'org-id', }); ``` ### Member & Invitation Management ```typescript // Get organization members const members = await idpClient.requests.getOrgMembers.fire({ jwt: await idpClient.getJwt(), organizationId: 'org-id', }); // Invite a new member await idpClient.requests.createInvitation.fire({ jwt: await idpClient.getJwt(), organizationId: 'org-id', email: 'newmember@example.com', roles: ['member'], }); // Bulk invite members await idpClient.requests.bulkCreateInvitations.fire({ jwt: await idpClient.getJwt(), organizationId: 'org-id', invitations: [ { email: 'user1@example.com', roles: ['member'] }, { email: 'user2@example.com', roles: ['admin'] }, ], }); // Accept an invitation await idpClient.requests.acceptInvitation.fire({ jwt: await idpClient.getJwt(), invitationToken: 'token-from-invite-email', }); // Remove a member await idpClient.requests.removeMember.fire({ jwt: await idpClient.getJwt(), organizationId: 'org-id', userId: 'user-id', }); // Transfer ownership await idpClient.requests.transferOwnership.fire({ jwt: await idpClient.getJwt(), organizationId: 'org-id', newOwnerId: 'new-owner-user-id', }); ``` ### Password Management ```typescript // Request password reset await idpClient.requests.resetPassword.fire({ email: 'user@example.com', }); // Set new password (with token from email) await idpClient.requests.setNewPassword.fire({ email: 'user@example.com', tokenArg: 'reset-token', newPassword: 'newsecurepassword', }); // Change password (when logged in) await idpClient.requests.setNewPassword.fire({ email: 'user@example.com', oldPassword: 'currentpassword', newPassword: 'newsecurepassword', }); ``` ### Session & Device Management ```typescript // Get active sessions const sessions = await idpClient.requests.getUserSessions.fire({ jwt: await idpClient.getJwt(), userId: jwtData.id, }); // Revoke a session await idpClient.requests.revokeSession.fire({ jwt: await idpClient.getJwt(), sessionId: 'session-id', }); // Get device ID const deviceInfo = await idpClient.requests.obtainDeviceId.fire({}); // Attach device to session await idpClient.requests.attachDeviceId.fire({ jwt: await idpClient.getJwt(), deviceId: deviceInfo.deviceId.id, }); ``` ### Cross-Domain Authentication ```typescript // Get transfer token for SSO between apps const transferToken = await idpClient.getTransferToken(); // Switch to another app with authentication await idpClient.getTransferTokenAndSwitchToLocation('https://app.example.com/'); // Process incoming transfer token (in target app) const success = await idpClient.processTransferToken(); if (success) { console.log('Cross-domain login successful'); } ``` ### Billing Integration ```typescript // Get billing plan for an organization const billingPlan = await idpClient.requests.getBillingPlan.fire({ jwt: await idpClient.getJwt(), organizationId: 'org-id', }); // Get Paddle configuration const paddleConfig = await idpClient.requests.getPaddleConfig.fire({ jwt: await idpClient.getJwt(), }); // Update payment method await idpClient.updatePaddleCheckoutId('org-id', 'checkout-id'); ``` ### Admin Operations (Global Admins Only) ```typescript // Check if user is global admin const isAdmin = await idpClient.requests.checkGlobalAdmin.fire({ jwt: await idpClient.getJwt(), }); // Get platform statistics const stats = await idpClient.requests.getGlobalAppStats.fire({ jwt: await idpClient.getJwt(), }); // Create a global app await idpClient.requests.createGlobalApp.fire({ jwt: await idpClient.getJwt(), name: 'My App', description: 'App description', }); // Suspend a user await idpClient.requests.suspendUser.fire({ jwt: await idpClient.getJwt(), userId: 'user-id', }); ``` ## Reactive Subscriptions The client provides RxJS subjects for reactive updates: ```typescript // Subscribe to login status changes idpClient.statusObservable.subscribe((status) => { console.log('Login status changed:', status); }); // Subscribe to roles updates idpClient.rolesReplaySubject.subscribe((roles) => { console.log('Roles updated:', roles); }); // Subscribe to organizations updates idpClient.organizationsReplaySubject.subscribe((orgs) => { console.log('Organizations updated:', orgs); }); ``` ## API Reference ### IdpClient Class | Method | Description | |--------|-------------| | `enableTypedSocket()` | Initialize WebSocket connection | | `determineLoginStatus(requireLogin?)` | Check if user is logged in | | `getJwt()` | Get stored JWT string | | `getJwtData()` | Get parsed JWT data | | `setJwt(jwt)` | Store JWT | | `deleteJwt()` | Remove stored JWT | | `refreshJwt(refreshToken?)` | Refresh the JWT | | `performJwtHousekeeping()` | Auto-refresh JWT if needed | | `logout()` | End session and redirect | | `whoIs()` | Get current user info | | `getRolesAndOrganizations()` | Get user's orgs and roles | | `createOrganization(name, slug, mode)` | Create new organization | | `getTransferToken(appData?)` | Get SSO transfer token | | `processTransferToken()` | Process incoming transfer token | | `stop()` | Close WebSocket connection | ### IdpRequests Class Access via `idpClient.requests.*`: **Authentication**: `loginWithUserNameAndPassword`, `loginWithEmail`, `loginWithEmailAfterToken`, `loginWithApiToken`, `resetPassword`, `setNewPassword` **User**: `getUserData`, `setUserData`, `getUserSessions`, `revokeSession`, `getUserActivity` **Organization**: `getOrganizationById`, `updateOrganization`, `createInvitation`, `bulkCreateInvitations`, `getOrgMembers`, `getOrgInvitations`, `acceptInvitation`, `cancelInvitation`, `resendInvitation`, `removeMember`, `updateMemberRoles`, `transferOwnership` **Billing**: `getBillingPlan`, `getPaddleConfig` **Admin**: `checkGlobalAdmin`, `getGlobalAppStats`, `createGlobalApp`, `updateGlobalApp`, `deleteGlobalApp`, `suspendUser`, `deleteSuspendedUser` ## License MIT - See the main repository for full license details.