Skip to content

phi-beta/SCIM

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

SCIM Client Library

A comprehensive TypeScript library for interacting with SCIM 2.0 (System for Cross-domain Identity Management) servers. This library provides full support for user and group management, advanced filtering, pagination, and bulk operations according to RFC 7643 and RFC 7644 specifications.

Features

  • Full SCIM 2.0 Compliance - Implements RFC 7643 (Core Schema) and RFC 7644 (Protocol)
  • 🔐 Multiple Authentication Methods - Bearer token, API key, Basic auth
  • 👥 User Management - Create, read, update, delete, and list users
  • 👨‍👩‍👧‍👦 Group Management - Complete group lifecycle management
  • 🔍 Advanced Filtering - Fluent filter builder with SCIM query syntax
  • 📄 Pagination Support - Handle large datasets efficiently
  • 🔄 Patch Operations - Partial updates using SCIM patch semantics
  • 📦 Bulk Operations - Perform multiple operations in a single request
  • 🛠 TypeScript First - Full type safety and IntelliSense support
  • 🚀 Easy to Use - Intuitive API with sensible defaults

Installation

npm install scim-client

Quick Start

import { SCIMClient, filter } from 'scim-client';

// Initialize the client
const client = new SCIMClient({
  baseUrl: 'https://your-scim-server.com/scim/v2',
  authToken: 'your-bearer-token'
});

// Create a user
const user = await client.createUser({
  userName: 'john.doe@example.com',
  name: {
    givenName: 'John',
    familyName: 'Doe'
  },
  emails: [{
    value: 'john.doe@example.com',
    primary: true
  }],
  active: true
});

// List users with filtering
const users = await client.listUsers({
  filter: filter().eq('active', true).build(),
  count: 50
});

Configuration

Authentication Options

// Bearer Token
const client = new SCIMClient({
  baseUrl: 'https://api.example.com/scim/v2',
  authToken: 'your-bearer-token'
});

// API Key
const client = new SCIMClient({
  baseUrl: 'https://api.example.com/scim/v2',
  apiKey: 'your-api-key'
});

// Basic Authentication
const client = new SCIMClient({
  baseUrl: 'https://api.example.com/scim/v2',
  username: 'your-username',
  password: 'your-password'
});

// Custom Headers
const client = new SCIMClient({
  baseUrl: 'https://api.example.com/scim/v2',
  authToken: 'token',
  customHeaders: {
    'X-Custom-Header': 'value'
  }
});

User Management

Create User

const user = await client.createUser({
  userName: 'john.doe@example.com',
  name: {
    formatted: 'John Doe',
    familyName: 'Doe',
    givenName: 'John'
  },
  displayName: 'John Doe',
  active: true,
  emails: [{
    value: 'john.doe@example.com',
    type: 'work',
    primary: true
  }],
  phoneNumbers: [{
    value: '+1-555-0123',
    type: 'work'
  }]
});

Update User

// Full update (PUT)
const updatedUser = await client.updateUser(userId, {
  userName: 'john.smith@example.com',
  displayName: 'John Smith',
  active: true
});

// Partial update (PATCH)
import { createPatchRequest, replaceOperation } from 'scim-client';

const patchRequest = createPatchRequest([
  replaceOperation('displayName', 'John Smith'),
  replaceOperation('active', false)
]);

const patchedUser = await client.patchUser(userId, patchRequest);

List Users with Filtering

import { filter } from 'scim-client';

// Simple filter
const activeUsers = await client.listUsers({
  filter: filter().eq('active', true).build()
});

// Complex filter
const complexFilter = filter()
  .eq('active', true)
  .and()
  .co('emails.value', '@example.com')
  .and()
  .gt('meta.created', '2023-01-01T00:00:00Z')
  .build();

const users = await client.listUsers({
  filter: complexFilter,
  sortBy: 'meta.created',
  sortOrder: 'descending',
  startIndex: 1,
  count: 50
});

Group Management

Create Group

const group = await client.createGroup({
  displayName: 'Engineering Team',
  members: [{
    value: 'user-id-1',
    display: 'John Doe'
  }]
});

Add Members to Group

import { createPatchRequest, addOperation } from 'scim-client';

const addMembersPatch = createPatchRequest([
  addOperation('members', [{
    value: 'user-id-2',
    display: 'Jane Smith'
  }])
]);

await client.patchGroup(groupId, addMembersPatch);

Filtering

The library provides a fluent filter builder that supports all SCIM filter operations:

import { filter } from 'scim-client';

// Comparison operators
filter().eq('userName', 'john.doe@example.com').build()
filter().ne('active', false).build()
filter().co('displayName', 'John').build()  // contains
filter().sw('userName', 'admin').build()     // starts with
filter().ew('emails.value', '@example.com').build()  // ends with
filter().gt('meta.created', '2023-01-01').build()
filter().ge('meta.lastModified', '2023-01-01').build()
filter().lt('meta.created', '2023-12-31').build()
filter().le('meta.lastModified', '2023-12-31').build()
filter().pr('phoneNumbers').build()          // present

// Logical operators
filter()
  .eq('active', true)
  .and()
  .co('emails.value', '@example.com')
  .build()

filter()
  .eq('userType', 'Employee')
  .or()
  .eq('userType', 'Contractor')
  .build()

filter()
  .not()
  .eq('active', false)
  .build()

Bulk Operations

Perform multiple operations in a single request:

import { createBulkRequest } from 'scim-client';

const bulkRequest = createBulkRequest([
  {
    method: 'POST',
    bulkId: 'create-user-1',
    path: '/Users',
    data: {
      userName: 'user1@example.com',
      name: { givenName: 'User', familyName: 'One' }
    }
  },
  {
    method: 'POST',
    bulkId: 'create-user-2',
    path: '/Users',
    data: {
      userName: 'user2@example.com',
      name: { givenName: 'User', familyName: 'Two' }
    }
  },
  {
    method: 'DELETE',
    bulkId: 'delete-user',
    path: '/Users/old-user-id'
  }
]);

const bulkResponse = await client.bulkOperations(bulkRequest);

Error Handling

The library provides comprehensive error handling:

import { SCIMError } from 'scim-client';

try {
  const user = await client.getUser('non-existent-id');
} catch (error) {
  if (error instanceof SCIMError) {
    console.log('SCIM Error:', error.status, error.message, error.scimType);
  } else {
    console.log('Network or other error:', error);
  }
}

Server Information

Query server capabilities and configuration:

// Test connection
const isConnected = await client.testConnection();

// Get service provider configuration
const config = await client.getServiceProviderConfig();

// Get supported resource types
const resourceTypes = await client.getResourceTypes();

// Get available schemas
const schemas = await client.getSchemas();

API Reference

SCIMClient

Main client class for all SCIM operations.

Constructor Options

Option Type Required Description
baseUrl string Yes Base URL of the SCIM server
authToken string No Bearer token for authentication
apiKey string No API key for authentication
username string No Username for basic auth
password string No Password for basic auth
timeout number No Request timeout in milliseconds (default: 30000)
customHeaders object No Additional HTTP headers

User Methods

  • createUser(user) - Create a new user
  • getUser(id, attributes?, excludedAttributes?) - Get user by ID
  • updateUser(id, user) - Update user (full replace)
  • patchUser(id, patchRequest) - Update user (partial)
  • deleteUser(id) - Delete user
  • listUsers(options?) - List users with filtering/pagination

Group Methods

  • createGroup(group) - Create a new group
  • getGroup(id, attributes?, excludedAttributes?) - Get group by ID
  • updateGroup(id, group) - Update group (full replace)
  • patchGroup(id, patchRequest) - Update group (partial)
  • deleteGroup(id) - Delete group
  • listGroups(options?) - List groups with filtering/pagination

Utility Methods

  • bulkOperations(bulkRequest) - Perform bulk operations
  • getServiceProviderConfig() - Get server configuration
  • getResourceTypes() - Get supported resource types
  • getSchemas() - Get available schemas
  • testConnection() - Test server connectivity

Development

# Install dependencies
npm install

# Build the project
npm run build

# Run in development mode
npm run dev

# Watch for changes
npm run watch

Contributing

  1. Fork the repository
  2. Create a feature branch
  3. Make your changes
  4. Add tests if applicable
  5. Submit a pull request

License

MIT

Related Standards

Support

For issues and questions, please use the GitHub issue tracker.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published