JSPM

  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 182
  • Score
    100M100P100Q82754F
  • License MIT

Authentication block for 23blocks SDK - users, roles, API keys, subscriptions

Package Exports

  • @23blocks/block-authentication
  • @23blocks/block-authentication/package.json

Readme

@23blocks/block-authentication

Authentication block for the 23blocks SDK - users, roles, API keys, and identity management.

npm version License: MIT

Installation

npm install @23blocks/block-authentication @23blocks/transport-http

Overview

This package provides comprehensive authentication and identity management including:

  • Authentication - Sign in, sign up, sign out, password reset
  • Users - User management, profiles, avatars
  • Roles & Permissions - Role-based access control
  • API Keys - Create and manage API keys
  • MFA - Multi-factor authentication
  • OAuth - Social login and token management
  • Tenants - Multi-tenant user management

Quick Start

import { createHttpTransport } from '@23blocks/transport-http';
import { createAuthenticationBlock } from '@23blocks/block-authentication';

// Create transport with your authentication service URL
const transport = createHttpTransport({
  baseUrl: 'https://auth.yourapp.com', // Your authentication service URL
  headers: () => {
    const token = localStorage.getItem('access_token');
    return {
      'x-api-key': 'your-api-key',
      ...(token ? { Authorization: `Bearer ${token}` } : {}),
    };
  },
});

// Create block
const auth = createAuthenticationBlock(transport, {
  apiKey: 'your-api-key',
});

// Sign in
const { user, accessToken, refreshToken } = await auth.auth.signIn({
  email: 'user@example.com',
  password: 'password',
});

localStorage.setItem('access_token', accessToken);
console.log('Welcome', user.email);

// Get current user
const currentUser = await auth.auth.getCurrentUser();

// Sign out
await auth.auth.signOut();
localStorage.removeItem('access_token');

Services

auth - Authentication

Sign In

// Required fields: email, password
const { user, accessToken, refreshToken, expiresIn } = await auth.auth.signIn({
  email: 'user@example.com',    // Required
  password: 'password',          // Required
});

SignInRequest:

Field Type Required Description
email string Yes User's email address
password string Yes User's password

SignInResponse:

Field Type Description
user User The authenticated user object
accessToken string JWT access token
refreshToken string? Refresh token (if enabled)
tokenType string Always "Bearer"
expiresIn number? Token expiration in seconds

Sign Up (Registration)

// Sign up with required fields only
const { user, accessToken, message } = await auth.auth.signUp({
  email: 'newuser@example.com',       // Required
  password: 'securePassword123',       // Required
  passwordConfirmation: 'securePassword123', // Required - must match password
});

// Sign up with all optional fields
const { user, accessToken, message } = await auth.auth.signUp({
  // Required fields
  email: 'newuser@example.com',
  password: 'securePassword123',
  passwordConfirmation: 'securePassword123',

  // Optional fields
  name: 'John Doe',                    // Display name
  username: 'johndoe',                 // Unique username
  roleId: 'role-uuid',                 // Assign specific role
  confirmSuccessUrl: 'https://yourapp.com/email-confirmed', // Redirect after email confirmation
  timeZone: 'America/New_York',        // User's timezone
  preferredLanguage: 'en',             // Language preference
  payload: { customField: 'value' },   // Custom JSON data
  uniqueId: 'custom-id-123',           // Custom unique identifier
  subscription: 'premium-plan',        // Subscription model unique_id

  // OAuth registration (when registering via social login)
  provider: 'google',                  // OAuth provider
  uid: 'google-user-id',               // OAuth user ID
});

SignUpRequest:

Field Type Required Description
email string Yes User's email address
password string Yes Password (min length depends on server config)
passwordConfirmation string Yes Must match password exactly
name string No User's display name
username string No Unique username
roleId string No Role ID to assign
confirmSuccessUrl string No URL to redirect after email confirmation
timeZone string No IANA timezone (e.g., 'America/New_York')
preferredLanguage string No Language code (e.g., 'en', 'es')
payload object No Custom JSON data stored with user
uniqueId string No Custom unique identifier
subscription string No Subscription model unique_id
provider string No OAuth provider name
uid string No OAuth user ID

SignUpResponse:

Field Type Description
user User The created user object
accessToken string? JWT token (only if email confirmation is disabled)
message string? Server message (e.g., "Confirmation email sent")

Note: If email confirmation is enabled on the server, accessToken will be undefined and the user must confirm their email before signing in.

Sign Out

await auth.auth.signOut();

Get Current User

// Returns user with role, avatar, and profile included
const user = await auth.auth.getCurrentUser();
console.log(user.email, user.role?.name, user.avatar?.url);

Validate Token

const { user, valid } = await auth.auth.validateToken();
if (valid) {
  console.log('Token is valid for', user.email);
}

Password Reset

// Request password reset email
await auth.auth.requestPasswordReset({
  email: 'user@example.com',           // Required
  redirectUrl: 'https://yourapp.com/reset-password', // Optional
});

// Update password with reset token (from email link)
await auth.auth.updatePassword({
  password: 'newSecurePassword',              // Required
  passwordConfirmation: 'newSecurePassword',  // Required
  resetPasswordToken: 'token-from-email',     // Required for reset
});

// Update password with current password (logged in user)
await auth.auth.updatePassword({
  password: 'newSecurePassword',              // Required
  passwordConfirmation: 'newSecurePassword',  // Required
  currentPassword: 'oldPassword',             // Required for change
});

PasswordResetRequest:

Field Type Required Description
email string Yes User's email address
redirectUrl string No URL for password reset page

PasswordUpdateRequest:

Field Type Required Description
password string Yes New password
passwordConfirmation string Yes Must match password
resetPasswordToken string Conditional Required when using reset link
currentPassword string Conditional Required when changing password

Refresh Token

const { accessToken, refreshToken, expiresIn } = await auth.auth.refreshToken({
  refreshToken: 'current-refresh-token', // Required
});
// Request magic link email
await auth.auth.requestMagicLink({
  email: 'user@example.com',                    // Required
  redirectUrl: 'https://yourapp.com/magic-link', // Optional
});

// Verify magic link token (from email)
const { user, accessToken, refreshToken } = await auth.auth.verifyMagicLink({
  token: 'magic-link-token', // Required
});

Invitations

// Send invitation to new user
await auth.auth.sendInvitation({
  email: 'newuser@example.com',                     // Required
  roleId: 'role-id',                                // Optional
  redirectUrl: 'https://yourapp.com/accept-invite', // Optional
});

// Accept invitation
const { user, accessToken } = await auth.auth.acceptInvitation({
  invitationToken: 'invitation-token',    // Required
  password: 'password',                    // Required
  passwordConfirmation: 'password',        // Required - must match password
  name: 'John Doe',                        // Optional
});

// Resend invitation
const user = await auth.auth.resendInvitation({
  email: 'user@example.com',                        // Required
  appid: 'app-id',                                  // Optional
  acceptInvitationUrl: 'https://yourapp.com/accept', // Optional
});

AcceptInvitationRequest:

Field Type Required Description
invitationToken string Yes Token from invitation email
password string Yes New password
passwordConfirmation string Yes Must match password
name string No User's display name

Email Confirmation

// Confirm email with token (from confirmation email link)
const user = await auth.auth.confirmEmail('confirmation-token');

// Resend confirmation email
await auth.auth.resendConfirmation({
  email: 'user@example.com',                        // Required
  confirmSuccessUrl: 'https://yourapp.com/confirmed', // Optional - redirect URL
});

ResendConfirmationRequest:

Field Type Required Description
email string Yes User's email address
confirmSuccessUrl string No URL to redirect after confirmation

Email & Document Validation

// Validate email before registration
const { exists, wellFormed, canRecover, accountStatus, maskedEmail } =
  await auth.auth.validateEmail({
    email: 'user@example.com',
  });

if (exists) {
  console.log('Email already registered');
}

// Validate document before registration
const { exists, canRecover, maskedEmail, maskedDocument, accountStatus } =
  await auth.auth.validateDocument({
    documentType: 'national_id',
    documentNumber: '12345678',
  });

Account Recovery (Deleted Accounts)

// Request account recovery for a deleted account
const { success, message } = await auth.auth.requestAccountRecovery({
  email: 'user@example.com',                    // Required
  recoveryUrl: 'https://yourapp.com/recover',   // Optional
});

// Complete account recovery with new password
const user = await auth.auth.completeAccountRecovery({
  recoveryToken: 'recovery-token',        // Required
  password: 'newPassword',                 // Required
  passwordConfirmation: 'newPassword',     // Required
});

users - User Management

// List users (admin)
const { data: users, meta } = await auth.users.list({
  limit: 20,
  offset: 0,
});

// Get user by ID
const user = await auth.users.get('user-id');

// Update user
const updated = await auth.users.update('user-id', {
  name: 'New Name',
  roleId: 'new-role-id',
});

// Delete user (soft delete)
await auth.users.delete('user-id');

// Get/update current user's profile
const profile = await auth.users.getProfile();
const updatedProfile = await auth.users.updateProfile({
  firstName: 'John',
  lastName: 'Doe',
  phoneNumber: '+1234567890',
});

// User devices
const devices = await auth.users.getDevices();
const device = await auth.users.addDevice({
  deviceType: 'mobile',
  pushId: 'push-token',
  osType: 'ios',
});
await auth.users.removeDevice('device-id');

// Search users
const results = await auth.users.search({
  query: 'john',
  limit: 10,
});

// User subscriptions
const subscription = await auth.users.addSubscription({
  subscriptionModelId: 'model-id',
  code: 'PREMIUM',
});

roles - Role Management

// List roles
const { data: roles } = await auth.roles.list();

// Get role by ID
const role = await auth.roles.get('role-id');

// Create role (admin)
const newRole = await auth.roles.create({
  name: 'Editor',
  code: 'editor',
  permissionIds: ['perm-1', 'perm-2'],
});

// Update role
const updated = await auth.roles.update('role-id', {
  name: 'Senior Editor',
});

// Delete role
await auth.roles.delete('role-id');

// List permissions
const { data: permissions } = await auth.roles.listPermissions();

apiKeys - API Key Management

// List API keys
const { data: keys } = await auth.apiKeys.list();

// Get API key by ID
const key = await auth.apiKeys.get('key-id');

// Create API key
const { apiKey, secret } = await auth.apiKeys.create({
  name: 'My API Key',
  scopes: ['read', 'write'],
  expiresAt: '2025-12-31',
});

// Update API key
const updated = await auth.apiKeys.update('key-id', {
  name: 'Updated Name',
  scopes: ['read'],
});

// Revoke API key
await auth.apiKeys.revoke('key-id');

// Delete API key
await auth.apiKeys.delete('key-id');

// Get usage statistics
const stats = await auth.apiKeys.getUsageStats('key-id');

mfa - Multi-Factor Authentication

// Check MFA status
const { enabled, methods } = await auth.mfa.getStatus();

// Setup MFA (get QR code)
const { qrCodeUrl, secret, backupCodes } = await auth.mfa.setup();

// Enable MFA
await auth.mfa.enable({
  code: '123456',
  secret: 'secret-from-setup',
});

// Verify MFA code
const { valid } = await auth.mfa.verify({
  code: '123456',
});

// Disable MFA
await auth.mfa.disable({
  code: '123456',
});

oauth - OAuth & Token Management

// Social login
const { user, accessToken } = await auth.oauth.socialLogin({
  provider: 'google',
  accessToken: 'google-access-token',
});

// Introspect token
const { active, userId, scopes } = await auth.oauth.introspectToken('token');

// Revoke token
await auth.oauth.revokeToken({
  token: 'token-to-revoke',
});

// Revoke all tokens
await auth.oauth.revokeAllTokens();

tenants - Multi-Tenant Users

// List tenant users
const { data: tenantUsers } = await auth.tenants.listUsers({
  limit: 20,
});

// Get tenant user
const tenantUser = await auth.tenants.getUser('tenant-user-id');

// Create tenant user
const newUser = await auth.tenants.createUser({
  email: 'user@tenant.com',
  name: 'Tenant User',
  roleId: 'role-id',
});

// Update tenant user
const updated = await auth.tenants.updateUser('tenant-user-id', {
  name: 'Updated Name',
});

// Delete tenant user
await auth.tenants.deleteUser('tenant-user-id');

// Validate tenant code
const { valid, tenant } = await auth.tenants.validateCode({
  code: 'TENANT123',
});

avatars - User Avatars

// Get user avatar
const avatar = await auth.avatars.get('user-id');

// Create/upload avatar
const avatar = await auth.avatars.create({
  userId: 'user-id',
  file: fileBlob,
});

// Get presigned URL for upload
const { url, fields } = await auth.avatars.getPresignedUrl({
  filename: 'avatar.jpg',
  contentType: 'image/jpeg',
});

// Delete avatar
await auth.avatars.delete('avatar-id');

Types

import type {
  // User types
  User,
  Role,
  Permission,
  UserAvatar,
  UserProfile,

  // Auth types
  SignInRequest,
  SignInResponse,
  SignUpRequest,
  SignUpResponse,
  PasswordResetRequest,
  PasswordUpdateRequest,
  RefreshTokenRequest,
  RefreshTokenResponse,
  MagicLinkRequest,
  MagicLinkVerifyRequest,
  InvitationRequest,
  AcceptInvitationRequest,
  ResendConfirmationRequest,
  ValidateEmailRequest,
  ValidateEmailResponse,
  ValidateDocumentRequest,
  ValidateDocumentResponse,
  AccountRecoveryRequest,
  AccountRecoveryResponse,
  CompleteRecoveryRequest,

  // API Key types
  ApiKey,
  ApiKeyWithSecret,
  CreateApiKeyRequest,

  // MFA types
  MfaSetupResponse,
  MfaVerifyRequest,
  MfaStatusResponse,

  // Company types
  Company,
  Tenant,
} from '@23blocks/block-authentication';

Error Handling

import { isBlockErrorException, ErrorCodes } from '@23blocks/contracts';

try {
  await auth.auth.signIn({ email, password });
} catch (error) {
  if (isBlockErrorException(error)) {
    switch (error.code) {
      case ErrorCodes.INVALID_CREDENTIALS:
        console.log('Invalid email or password');
        break;
      case ErrorCodes.UNAUTHORIZED:
        console.log('Session expired');
        break;
      case ErrorCodes.VALIDATION_ERROR:
        console.log('Validation error:', error.message);
        break;
      default:
        console.log('Error:', error.message);
    }
  }
}

License

MIT - Copyright (c) 2024 23blocks