1
0
mirror of https://github.com/bitwarden/directory-connector synced 2025-12-05 23:53:21 +00:00
Files
directory-connector/.claude/CLAUDE.md
Mick Letofsky c7db8376ec Implement reusable Claude code review workflow (#905)
* Implement reusable Claude code review workflow
2025-10-30 07:39:45 +01:00

6.5 KiB

Bitwarden Directory Connector

Project Overview

Directory Connector is a TypeScript application that synchronizes users and groups from directory services to Bitwarden organizations. It provides both a desktop GUI (built with Angular and Electron) and a CLI tool (bwdc).

Supported Directory Services:

  • LDAP (Lightweight Directory Access Protocol) - includes Active Directory and general LDAP servers
  • Microsoft Entra ID (formerly Azure Active Directory)
  • Google Workspace
  • Okta
  • OneLogin

Technologies:

  • TypeScript
  • Angular (GUI)
  • Electron (Desktop wrapper)
  • Node
  • Jest for testing

Code Architecture & Structure

Directory Organization

src/
├── abstractions/       # Interface definitions (e.g., IDirectoryService)
├── services/          # Business logic implementations for directory services, sync, auth
├── models/            # Data models (UserEntry, GroupEntry, etc.)
├── commands/          # CLI command implementations
├── app/               # Angular GUI components
└── utils/             # Test utilities and fixtures

src-cli/               # CLI-specific code (imports common code from src/)

jslib/                 # Legacy folder structure (mix of deprecated/unused and current code - new code should not be added here)

Key Architectural Patterns

  1. Abstractions = Interfaces: All interfaces are defined in /abstractions
  2. Services = Business Logic: Implementations live in /services
  3. Directory Service Pattern: Each directory provider implements IDirectoryService interface
  4. Separation of Concerns: GUI (Angular app) and CLI (commands) share the same service layer

Development Conventions

Code Organization

File Naming:

  • kebab-case for files: ldap-directory.service.ts
  • Descriptive names that reflect purpose

Class/Function Naming:

  • PascalCase for classes and interfaces
  • camelCase for functions and variables
  • Descriptive names that indicate purpose

File Structure:

  • Keep files focused on single responsibility
  • Create new service files for distinct directory integrations
  • Separate models into individual files when complex

TypeScript Conventions

Import Patterns:

  • Use path aliases (@/) for project imports
    • @/ - project root
    • @/jslib/ - jslib folder
  • ESLint enforces alphabetized import ordering with newlines between groups

Type Safety:

  • Avoid any types - use proper typing or unknown with type guards
  • Prefer interfaces for contracts, types for unions/intersections
  • Use strict null checks - handle null and undefined explicitly
  • Leverage TypeScript's type inference where appropriate

Configuration:

  • Use configuration files or environment variables
  • Never hardcode URLs or configuration values

Security Best Practices

Credential Handling:

  • Never log directory service credentials, API keys, or tokens
  • Use secure storage mechanisms for sensitive data
  • Credentials should never be hardcoded
  • Store credentials encrypted, never in plain text

Sensitive Data:

  • User and group data from directories should be handled securely
  • Avoid exposing sensitive information in error messages
  • Sanitize data before logging
  • Be cautious with data persistence

Input Validation:

  • Validate and sanitize data from external directory services
  • Check for injection vulnerabilities (LDAP injection, etc.)
  • Validate configuration inputs from users

API Security:

  • Ensure authentication flows are implemented correctly
  • Verify SSL/TLS is used for all external connections
  • Check for secure token storage and refresh mechanisms

Error Handling

Best Practices:

  1. Try-catch for async operations - Always wrap external API calls
  2. Meaningful error messages - Provide context for debugging
  3. Error propagation - Don't swallow errors silently
  4. User-facing errors - Separate user messages from developer logs

Performance Best Practices

Large Dataset Handling:

  • Use pagination for large user/group lists
  • Avoid loading entire datasets into memory at once
  • Consider streaming or batch processing for large operations

API Rate Limiting:

  • Respect rate limits for Microsoft Graph API, Google Admin SDK, etc.
  • Consider batching large API calls where necessary

Memory Management:

  • Close connections and clean up resources
  • Remove event listeners when components are destroyed
  • Be cautious with caching large datasets

Testing

Framework:

  • Jest with jest-preset-angular
  • jest-mock-extended for type-safe mocks with mock<Type>()

Test Organization:

  • Tests colocated with source files
  • *.spec.ts - Unit tests for individual components/services
  • *.integration.spec.ts - Integration tests against live directory services
  • Test helpers located in utils/ directory

Test Naming:

  • Descriptive, human-readable test names
  • Example: 'should return empty array when no users exist in directory'

Test Coverage:

  • New features must include tests
  • Bug fixes should include regression tests
  • Changes to core sync logic or directory specific logic require integration tests

Testing Approach:

  • Unit tests: Mock external API calls using jest-mock-extended
  • Integration tests: Use live directory services (Docker containers or configured cloud services)
  • Focus on critical paths (authentication, sync, data transformation)
  • Test error scenarios and edge cases (empty results, malformed data, connection failures), not just happy paths

Directory Service Patterns

IDirectoryService Interface

All directory services implement this core interface with methods:

  • getUsers() - Retrieve users from directory and transform them into standard objects
  • getGroups() - Retrieve groups from directory and transform them into standard objects
  • Connection and authentication handling

Service-Specific Implementations

Each directory service has unique authentication and query patterns:

  • LDAP: Direct LDAP queries, bind authentication
  • Microsoft Entra ID: Microsoft Graph API, OAuth tokens
  • Google Workspace: Google Admin SDK, service account credentials
  • Okta/OneLogin: REST APIs with API tokens

References