Skip to content

Commit 16aef70

Browse files
committed
Suggested claude.md changes
1 parent be7ad1d commit 16aef70

1 file changed

Lines changed: 248 additions & 0 deletions

File tree

.claude/CLAUDE.md

Lines changed: 248 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,253 @@
11
# Bitwarden Directory Connector
22

3+
## Project Overview
4+
5+
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).
6+
7+
**Supported Directory Services:**
8+
9+
- LDAP (Lightweight Directory Access Protocol) - includes Active Directory and general LDAP servers
10+
- Microsoft Entra ID (formerly Azure Active Directory)
11+
- Google Workspace
12+
- Okta
13+
- OneLogin
14+
15+
**Technologies:**
16+
17+
- TypeScript
18+
- Angular (GUI)
19+
- Electron (Desktop wrapper)
20+
- Node
21+
- Jest for testing
22+
23+
## Code Architecture & Structure
24+
25+
### Directory Organization
26+
27+
```
28+
src/
29+
├── abstractions/ # Interface definitions (e.g., IDirectoryService)
30+
├── services/ # Business logic implementations for directory services, sync, auth
31+
├── models/ # Data models (UserEntry, GroupEntry, etc.)
32+
├── commands/ # CLI command implementations
33+
├── app/ # Angular GUI components
34+
└── utils/ # Test utilities and fixtures
35+
36+
src-cli/ # CLI-specific code (imports common code from src/)
37+
38+
jslib/ # Legacy folder structure (mix of deprecated/unused and current code - new code should not be added here)
39+
```
40+
41+
### Key Architectural Patterns
42+
43+
1. **Abstractions = Interfaces**: All interfaces are defined in `/abstractions`
44+
2. **Services = Business Logic**: Implementations live in `/services`
45+
3. **Directory Service Pattern**: Each directory provider implements `IDirectoryService` interface
46+
4. **Separation of Concerns**: GUI (Angular app) and CLI (commands) share the same service layer
47+
48+
## Testing Conventions
49+
50+
- **Framework**: Jest with jest-preset-angular
51+
- **Mocking**: jest-mock-extended for type-safe mocks with `mock<Type>()`
52+
- **Location**: Tests colocated with source files
53+
- **Naming**: Descriptive, human-readable test names (e.g., `'should return empty array when no users exist in directory'`)
54+
- **Test Helpers**: Located in `utils/` directory
55+
56+
## Directory Integration Patterns
57+
58+
### IDirectoryService Interface
59+
60+
All directory services implement this core interface with methods:
61+
62+
- `getUsers()` - Retrieve users from directory
63+
- `getGroups()` - Retrieve groups from directory
64+
- Connection and authentication handling
65+
66+
### Service-Specific Implementations
67+
68+
Each directory service has unique authentication and query patterns:
69+
70+
- **LDAP**: Direct LDAP queries, bind authentication
71+
- **Microsoft Entra ID**: Microsoft Graph API, OAuth tokens
72+
- **Google Workspace**: Google Admin SDK, service account credentials
73+
- **Okta/OneLogin**: REST APIs with API tokens
74+
75+
## Code Review Guidelines
76+
77+
### Security Considerations
78+
79+
**Critical Security Areas:**
80+
81+
1. **Credential Handling**
82+
- Never log directory service credentials, API keys, or tokens
83+
- Use secure storage mechanisms for sensitive data
84+
- Credentials should never be hardcoded
85+
86+
2. **Sensitive Data**
87+
- User and group data from directories should be handled securely
88+
- Avoid exposing sensitive information in error messages
89+
- Sanitize data before logging
90+
- Be cautious with data persistence
91+
92+
3. **Input Validation**
93+
- Validate and sanitize data from external directory services
94+
- Check for injection vulnerabilities (LDAP injection, etc.)
95+
- Validate configuration inputs from users
96+
97+
4. **API Security**
98+
- Ensure OAuth flows are implemented correctly
99+
- Verify SSL/TLS is used for all external connections
100+
- Check for secure token storage and refresh mechanisms
101+
102+
### TypeScript Conventions
103+
104+
**Import patterns**
105+
106+
- Use path aliases (`@/`) for project imports
107+
- `@/` - project root
108+
- `@/jslib/` - jslib folder
109+
- ESLint enforces alphabetized import ordering with newlines between groups
110+
111+
**Type Safety:**
112+
113+
- Avoid `any` types - use proper typing or `unknown` with type guards
114+
- Prefer interfaces for contracts, types for unions/intersections
115+
- Use strict null checks - handle `null` and `undefined` explicitly
116+
- Leverage TypeScript's type inference where appropriate
117+
118+
**Async Patterns:**
119+
120+
```typescript
121+
// Good - proper async/await with error handling
122+
async function syncUsers(): Promise<UserEntry[]> {
123+
try {
124+
const users = await directoryService.getUsers();
125+
return users.filter((u) => u.enabled);
126+
} catch (error) {
127+
logger.error("Failed to sync users", error);
128+
throw new SyncError("User sync failed", error);
129+
}
130+
}
131+
132+
// Avoid - unhandled promises
133+
function syncUsers() {
134+
directoryService.getUsers().then((users) => processUsers(users));
135+
}
136+
```
137+
138+
### Error Handling Patterns
139+
140+
**Required Practices:**
141+
142+
1. **Try-catch for async operations** - Always wrap external API calls
143+
2. **Meaningful error messages** - Provide context for debugging
144+
3. **Error propagation** - Don't swallow errors silently
145+
4. **User-facing errors** - Separate user messages from developer logs
146+
147+
```typescript
148+
// Good
149+
try {
150+
await directoryService.connect();
151+
} catch (error) {
152+
logger.error("Directory connection failed", { service: "ldap", error });
153+
throw new ConnectionError("Unable to connect to directory service", error);
154+
}
155+
156+
// Avoid - swallowing errors
157+
try {
158+
await directoryService.connect();
159+
} catch (error) {
160+
console.log("error"); // Too vague, no context
161+
}
162+
```
163+
164+
### Performance Considerations
165+
166+
**Large Dataset Handling:**
167+
168+
- Use pagination for large user/group lists
169+
- Avoid loading entire datasets into memory at once
170+
- Consider streaming or batch processing for large operations
171+
172+
**API Rate Limiting:**
173+
174+
- Respect rate limits for Microsoft Graph API, Google Admin SDK, etc.
175+
- Consider batching large API calls where necessary
176+
177+
**Memory Management:**
178+
179+
- Close connections and clean up resources
180+
- Remove event listeners when components are destroyed
181+
- Be cautious with caching large datasets
182+
183+
### Testing Requirements
184+
185+
**Test File Types:**
186+
187+
- `*.spec.ts` - Unit tests for individual components/services
188+
- `*.integration.spec.ts` - Integration tests against live directory services
189+
190+
**When Tests Are Required:**
191+
192+
- New features must include tests
193+
- Bug fixes should include regression tests
194+
- Changes to core sync logic or directory specific logic require integration tests
195+
196+
**Test Expectations:**
197+
198+
- **Unit tests**: Mock external API calls using jest-mock-extended
199+
- **Integration tests**: Use live directory services (Docker containers or configured cloud services)
200+
- **Coverage focus**: Critical paths (authentication, sync, data transformation)
201+
- **Test scenarios**: Error cases and edge cases (empty results, malformed data, connection failures), not just happy paths
202+
203+
### Common Anti-Patterns to Flag
204+
205+
1. **Hardcoded Values**
206+
- No hardcoded credentials, URLs, or configuration
207+
- Use configuration files or environment variables
208+
209+
2. **Synchronous Operations**
210+
- Don't use sync file operations in production code
211+
- Avoid blocking operations in main thread
212+
213+
3. **Missing Error Handling**
214+
- Every external call should have error handling
215+
- API calls, file operations, and network requests must be wrapped
216+
217+
4. **Memory Leaks**
218+
- Unclosed connections to directory services
219+
- Event listeners not removed
220+
- Large objects not released
221+
222+
5. **Insecure Patterns**
223+
- Logging sensitive data
224+
- Storing credentials in plain text
225+
- Missing input validation
226+
227+
6. **Poor Performance Patterns**
228+
- Loading entire directory into memory
229+
- N+1 query patterns
230+
- Inefficient loops with repeated operations
231+
232+
### Code Organization Standards
233+
234+
**File Naming:**
235+
236+
- kebab-case for files: `ldap-directory.service.ts`
237+
- Descriptive names that reflect purpose
238+
239+
**Class/Function Naming:**
240+
241+
- PascalCase for classes and interfaces
242+
- camelCase for functions and variables
243+
- Descriptive names that indicate purpose
244+
245+
**When to Create New Files:**
246+
247+
- Keep files focused on single responsibility
248+
- Create new service files for distinct directory integrations
249+
- Separate models into individual files when complex
250+
3251
## References
4252

5253
- [Architectural Decision Records (ADRs)](https://contributing.bitwarden.com/architecture/adr/)

0 commit comments

Comments
 (0)