Files
app/ts_idpclient/readme.md
T

11 KiB

@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

npm install @idp.global/idpclient
# or
pnpm add @idp.global/idpclient

Quick Start

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

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');
}
// 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

const result = await idpClient.requests.loginWithApiToken.fire({
  apiToken: 'your-api-token',
});

if (result.jwt) {
  await idpClient.setJwt(result.jwt);
}

Session Management

// 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

// 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

// 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

// 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

// 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

// 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

// 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

// 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)

// 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:

// 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

This repository contains open-source code licensed under the MIT License. A copy of the license can be found in the LICENSE file.

Please note: The MIT License does not grant permission to use the trade names, trademarks, service marks, or product names of the project, except as required for reasonable and customary use in describing the origin of the work and reproducing the content of the NOTICE file.

Trademarks

This project is owned and maintained by Task Venture Capital GmbH. The names and logos associated with Task Venture Capital GmbH and any related products or services are trademarks of Task Venture Capital GmbH or third parties, and are not included within the scope of the MIT license granted herein.

Use of these trademarks must comply with Task Venture Capital GmbH's Trademark Guidelines or the guidelines of the respective third-party owners, and any usage must be approved in writing. Third-party trademarks used herein are the property of their respective owners and used only in a descriptive manner, e.g. for an implementation of an API or similar.

Company Information

Task Venture Capital GmbH Registered at District Court Bremen HRB 35230 HB, Germany

For any legal inquiries or further information, please contact us via email at hello@task.vc.

By using this repository, you acknowledge that you have read this section, agree to comply with its terms, and understand that the licensing of the code does not imply endorsement by Task Venture Capital GmbH of any derivative works.