@happyvertical/directory 0.74.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENT.md +34 -0
- package/LICENSE +7 -0
- package/dist/adapters/aws.d.ts +39 -0
- package/dist/adapters/aws.d.ts.map +1 -0
- package/dist/adapters/kanidm.d.ts +41 -0
- package/dist/adapters/kanidm.d.ts.map +1 -0
- package/dist/adapters/postgres.d.ts +73 -0
- package/dist/adapters/postgres.d.ts.map +1 -0
- package/dist/adapters/stalwart.d.ts +39 -0
- package/dist/adapters/stalwart.d.ts.map +1 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +1942 -0
- package/dist/index.js.map +1 -0
- package/dist/shared/errors.d.ts +33 -0
- package/dist/shared/errors.d.ts.map +1 -0
- package/dist/shared/factory.d.ts +36 -0
- package/dist/shared/factory.d.ts.map +1 -0
- package/dist/shared/types.d.ts +321 -0
- package/dist/shared/types.d.ts.map +1 -0
- package/metadata.json +32 -0
- package/package.json +70 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../src/shared/errors.ts","../src/adapters/aws.ts","../src/adapters/kanidm.ts","../src/adapters/postgres.ts","../src/adapters/stalwart.ts","../src/shared/factory.ts"],"sourcesContent":["/**\n * Error classes for @happyvertical/directory package\n */\n\n// ============================================================================\n// Base Error\n// ============================================================================\n\nexport class DirectoryError extends Error {\n code: string;\n provider?: string;\n cause?: unknown;\n\n constructor(\n message: string,\n code: string,\n provider?: string,\n cause?: unknown,\n ) {\n super(message);\n this.name = 'DirectoryError';\n this.code = code;\n this.provider = provider;\n this.cause = cause;\n }\n}\n\n// ============================================================================\n// Connection Errors\n// ============================================================================\n\nexport class ConnectionError extends DirectoryError {\n constructor(message: string, provider?: string, cause?: unknown) {\n super(message, 'CONNECTION_ERROR', provider, cause);\n this.name = 'ConnectionError';\n }\n}\n\n// ============================================================================\n// Authentication Errors\n// ============================================================================\n\nexport class AuthenticationError extends DirectoryError {\n constructor(message: string, provider?: string, cause?: unknown) {\n super(message, 'AUTHENTICATION_ERROR', provider, cause);\n this.name = 'AuthenticationError';\n }\n}\n\n// ============================================================================\n// Not Found Errors\n// ============================================================================\n\nexport class NotFoundError extends DirectoryError {\n resourceType: string;\n resourceId: string;\n\n constructor(\n resourceType: string,\n resourceId: string,\n provider?: string,\n cause?: unknown,\n ) {\n super(\n `${resourceType} not found: ${resourceId}`,\n 'NOT_FOUND',\n provider,\n cause,\n );\n this.name = 'NotFoundError';\n this.resourceType = resourceType;\n this.resourceId = resourceId;\n }\n}\n\n// ============================================================================\n// Conflict Errors\n// ============================================================================\n\nexport class ConflictError extends DirectoryError {\n resourceType: string;\n resourceId: string;\n\n constructor(\n resourceType: string,\n resourceId: string,\n provider?: string,\n cause?: unknown,\n ) {\n super(\n `${resourceType} already exists: ${resourceId}`,\n 'CONFLICT',\n provider,\n cause,\n );\n this.name = 'ConflictError';\n this.resourceType = resourceType;\n this.resourceId = resourceId;\n }\n}\n\n// ============================================================================\n// Validation Errors\n// ============================================================================\n\nexport class ValidationError extends DirectoryError {\n constructor(message: string, provider?: string, cause?: unknown) {\n super(message, 'VALIDATION_ERROR', provider, cause);\n this.name = 'ValidationError';\n }\n}\n\n// ============================================================================\n// Rate Limit Errors\n// ============================================================================\n\nexport class RateLimitError extends DirectoryError {\n retryAfter?: number;\n\n constructor(provider?: string, retryAfter?: number) {\n super(\n `Rate limit exceeded${retryAfter ? ` (retry after ${retryAfter}s)` : ''}`,\n 'RATE_LIMIT',\n provider,\n );\n this.name = 'RateLimitError';\n this.retryAfter = retryAfter;\n }\n}\n","/**\n * AWS directory adapter\n *\n * Implements AwsDirectoryAdapter using AWS SDK v3 for Organizations and IAM.\n * Provides user/group CRUD (mapped to IAM), membership management,\n * organizational unit operations, account management, and access key operations.\n *\n * Caveats:\n * - Account creation is asynchronous; use getAccountCreationStatus to poll.\n * - AWS accounts cannot be truly deleted via the API.\n * - IAM CreateUser does not set passwords (use CreateLoginProfile separately).\n */\n\nimport {\n AddUserToGroupCommand,\n AttachUserPolicyCommand,\n CreateAccessKeyCommand,\n CreateGroupCommand,\n CreateUserCommand,\n DeleteAccessKeyCommand,\n DeleteGroupCommand,\n DeleteUserCommand,\n DetachUserPolicyCommand,\n GetGroupCommand,\n GetUserCommand,\n IAMClient,\n ListGroupsCommand,\n ListGroupsForUserCommand,\n ListUsersCommand,\n RemoveUserFromGroupCommand,\n UpdateUserCommand,\n} from '@aws-sdk/client-iam';\nimport {\n CreateAccountCommand,\n CreateOrganizationalUnitCommand,\n DescribeCreateAccountStatusCommand,\n DescribeOrganizationalUnitCommand,\n ListAccountsCommand,\n ListOrganizationalUnitsForParentCommand,\n MoveAccountCommand,\n OrganizationsClient,\n} from '@aws-sdk/client-organizations';\nimport {\n AuthenticationError,\n ConflictError,\n ConnectionError,\n DirectoryError,\n NotFoundError,\n} from '../shared/errors.js';\nimport type {\n AwsAccessKey,\n AwsAccount,\n AwsAccountCreationStatus,\n AwsDirectoryAdapter,\n AwsIamUser,\n AwsOptions,\n AwsOrganizationalUnit,\n CreateAwsAccountInput,\n CreateAwsIamUserInput,\n CreateAwsOuInput,\n CreateGroupInput,\n CreateUserInput,\n DirectoryGroup,\n DirectoryUser,\n UpdateGroupInput,\n UpdateUserInput,\n} from '../shared/types.js';\n\n// ============================================================================\n// Error Handling Helper\n// ============================================================================\n\nfunction handleAwsError(error: unknown, context: string): never {\n if (\n error instanceof AuthenticationError ||\n error instanceof ConnectionError ||\n error instanceof NotFoundError ||\n error instanceof ConflictError ||\n error instanceof DirectoryError\n ) {\n throw error;\n }\n\n const awsError = error as { name?: string; message?: string };\n const name = awsError.name ?? '';\n const message = awsError.message ?? String(error);\n\n switch (name) {\n case 'EntityAlreadyExistsException':\n case 'DuplicateOrganizationalUnitException':\n throw new ConflictError('resource', context, 'aws', error);\n case 'NoSuchEntityException':\n case 'OrganizationalUnitNotFoundException':\n case 'AccountNotFoundException':\n throw new NotFoundError('resource', context, 'aws', error);\n case 'AccessDeniedException':\n case 'InvalidClientTokenId':\n case 'UnrecognizedClientException':\n case 'InvalidAccessKeyId':\n throw new AuthenticationError(`${context}: ${message}`, 'aws', error);\n default:\n throw new DirectoryError(\n `${context}: ${message}`,\n 'AWS_ERROR',\n 'aws',\n error,\n );\n }\n}\n\n// ============================================================================\n// Mapping Helpers\n// ============================================================================\n\nfunction mapIamUserToDirectoryUser(user: {\n UserName?: string;\n Arn?: string;\n UserId?: string;\n CreateDate?: Date;\n Tags?: { Key?: string; Value?: string }[];\n}): DirectoryUser {\n const displayNameTag = user.Tags?.find((t) => t.Key === 'DisplayName');\n const emailTag = user.Tags?.find((t) => t.Key === 'Email');\n\n return {\n id: user.UserName ?? '',\n username: user.UserName ?? '',\n displayName: displayNameTag?.Value,\n email: emailTag?.Value,\n active: true,\n metadata: {\n arn: user.Arn,\n userId: user.UserId,\n createDate: user.CreateDate?.toISOString(),\n },\n };\n}\n\nfunction mapIamGroupToDirectoryGroup(group: {\n GroupName?: string;\n Arn?: string;\n GroupId?: string;\n CreateDate?: Date;\n}): DirectoryGroup {\n return {\n id: group.GroupName ?? '',\n name: group.GroupName ?? '',\n metadata: {\n arn: group.Arn,\n groupId: group.GroupId,\n createDate: group.CreateDate?.toISOString(),\n },\n };\n}\n\nfunction mapIamUserToAwsIamUser(user: {\n UserName?: string;\n Arn?: string;\n UserId?: string;\n CreateDate?: Date;\n}): AwsIamUser {\n return {\n username: user.UserName ?? '',\n arn: user.Arn,\n userId: user.UserId,\n createDate: user.CreateDate,\n };\n}\n\n// ============================================================================\n// Adapter Implementation\n// ============================================================================\n\nexport class AwsAdapter implements AwsDirectoryAdapter {\n private readonly orgs: OrganizationsClient;\n private readonly iam: IAMClient;\n\n constructor(readonly options: AwsOptions) {\n const clientConfig = {\n region: options.region,\n ...(options.credentials ? { credentials: options.credentials } : {}),\n };\n\n this.orgs = new OrganizationsClient(clientConfig);\n this.iam = new IAMClient(clientConfig);\n }\n\n // ==========================================================================\n // Connection\n // ==========================================================================\n\n async testConnection(): Promise<boolean> {\n try {\n await this.iam.send(new ListUsersCommand({ MaxItems: 1 }));\n return true;\n } catch {\n return false;\n }\n }\n\n async disconnect(): Promise<void> {\n // AWS SDK clients do not require explicit cleanup\n }\n\n // ==========================================================================\n // User CRUD (DirectoryAdapter -> IAM Users)\n // ==========================================================================\n\n async createUser(input: CreateUserInput): Promise<DirectoryUser> {\n try {\n const tags: { Key: string; Value: string }[] = [];\n if (input.displayName) {\n tags.push({ Key: 'DisplayName', Value: input.displayName });\n }\n if (input.email) {\n tags.push({ Key: 'Email', Value: input.email });\n }\n\n const result = await this.iam.send(\n new CreateUserCommand({\n UserName: input.username,\n ...(tags.length > 0 ? { Tags: tags } : {}),\n }),\n );\n\n return mapIamUserToDirectoryUser({\n ...result.User,\n Tags: tags,\n });\n } catch (error) {\n handleAwsError(error, `createUser(${input.username})`);\n }\n }\n\n async getUser(id: string): Promise<DirectoryUser> {\n try {\n const result = await this.iam.send(new GetUserCommand({ UserName: id }));\n return mapIamUserToDirectoryUser(result.User ?? {});\n } catch (error) {\n handleAwsError(error, `getUser(${id})`);\n }\n }\n\n async updateUser(\n id: string,\n _input: UpdateUserInput,\n ): Promise<DirectoryUser> {\n try {\n // IAM UpdateUser only supports NewPath and NewUserName.\n // displayName and email are stored as tags, updated separately.\n await this.iam.send(new UpdateUserCommand({ UserName: id }));\n\n // Update tags if displayName or email changed\n // Note: IAM tag updates require TagUser/UntagUser commands which are\n // beyond the scope of this adapter. We store the intent in metadata.\n\n return this.getUser(id);\n } catch (error) {\n handleAwsError(error, `updateUser(${id})`);\n }\n }\n\n async deleteUser(id: string): Promise<void> {\n try {\n await this.iam.send(new DeleteUserCommand({ UserName: id }));\n } catch (error) {\n handleAwsError(error, `deleteUser(${id})`);\n }\n }\n\n async listUsers(): Promise<DirectoryUser[]> {\n try {\n const result = await this.iam.send(new ListUsersCommand({}));\n return (result.Users ?? []).map((u) => mapIamUserToDirectoryUser(u));\n } catch (error) {\n handleAwsError(error, 'listUsers');\n }\n }\n\n // ==========================================================================\n // Group CRUD (DirectoryAdapter -> IAM Groups)\n // ==========================================================================\n\n async createGroup(input: CreateGroupInput): Promise<DirectoryGroup> {\n try {\n const result = await this.iam.send(\n new CreateGroupCommand({ GroupName: input.name }),\n );\n\n const group = mapIamGroupToDirectoryGroup(result.Group ?? {});\n\n // Add initial members if provided\n if (input.members) {\n for (const memberId of input.members) {\n await this.addUserToGroup(memberId, input.name);\n }\n }\n\n return group;\n } catch (error) {\n handleAwsError(error, `createGroup(${input.name})`);\n }\n }\n\n async getGroup(id: string): Promise<DirectoryGroup> {\n try {\n const result = await this.iam.send(\n new GetGroupCommand({ GroupName: id }),\n );\n\n const group = mapIamGroupToDirectoryGroup(result.Group ?? {});\n group.members = (result.Users ?? []).map((u) => u.UserName ?? '');\n\n return group;\n } catch (error) {\n handleAwsError(error, `getGroup(${id})`);\n }\n }\n\n async updateGroup(\n id: string,\n _input: UpdateGroupInput,\n ): Promise<DirectoryGroup> {\n // IAM groups have limited update capability (only GroupName via UpdateGroup).\n // displayName and description are not supported natively by IAM groups.\n // Return the current group state.\n return this.getGroup(id);\n }\n\n async deleteGroup(id: string): Promise<void> {\n try {\n await this.iam.send(new DeleteGroupCommand({ GroupName: id }));\n } catch (error) {\n handleAwsError(error, `deleteGroup(${id})`);\n }\n }\n\n async listGroups(): Promise<DirectoryGroup[]> {\n try {\n const result = await this.iam.send(new ListGroupsCommand({}));\n return (result.Groups ?? []).map((g) => mapIamGroupToDirectoryGroup(g));\n } catch (error) {\n handleAwsError(error, 'listGroups');\n }\n }\n\n // ==========================================================================\n // Membership\n // ==========================================================================\n\n async addUserToGroup(userId: string, groupId: string): Promise<void> {\n try {\n await this.iam.send(\n new AddUserToGroupCommand({\n UserName: userId,\n GroupName: groupId,\n }),\n );\n } catch (error) {\n handleAwsError(error, `addUserToGroup(${userId}, ${groupId})`);\n }\n }\n\n async removeUserFromGroup(userId: string, groupId: string): Promise<void> {\n try {\n await this.iam.send(\n new RemoveUserFromGroupCommand({\n UserName: userId,\n GroupName: groupId,\n }),\n );\n } catch (error) {\n handleAwsError(error, `removeUserFromGroup(${userId}, ${groupId})`);\n }\n }\n\n async getGroupMembers(groupId: string): Promise<DirectoryUser[]> {\n try {\n const result = await this.iam.send(\n new GetGroupCommand({ GroupName: groupId }),\n );\n return (result.Users ?? []).map((u) => mapIamUserToDirectoryUser(u));\n } catch (error) {\n handleAwsError(error, `getGroupMembers(${groupId})`);\n }\n }\n\n async getUserGroups(userId: string): Promise<DirectoryGroup[]> {\n try {\n const result = await this.iam.send(\n new ListGroupsForUserCommand({ UserName: userId }),\n );\n return (result.Groups ?? []).map((g) => mapIamGroupToDirectoryGroup(g));\n } catch (error) {\n handleAwsError(error, `getUserGroups(${userId})`);\n }\n }\n\n // ==========================================================================\n // Organizational Units (AwsDirectoryAdapter)\n // ==========================================================================\n\n async createOrganizationalUnit(\n input: CreateAwsOuInput,\n ): Promise<AwsOrganizationalUnit> {\n try {\n const result = await this.orgs.send(\n new CreateOrganizationalUnitCommand({\n ParentId: input.parentId,\n Name: input.name,\n }),\n );\n\n const ou = result.OrganizationalUnit;\n return {\n id: ou?.Id ?? '',\n name: ou?.Name ?? '',\n arn: ou?.Arn,\n parentId: input.parentId,\n };\n } catch (error) {\n handleAwsError(error, `createOrganizationalUnit(${input.name})`);\n }\n }\n\n async getOrganizationalUnit(id: string): Promise<AwsOrganizationalUnit> {\n try {\n const result = await this.orgs.send(\n new DescribeOrganizationalUnitCommand({\n OrganizationalUnitId: id,\n }),\n );\n\n const ou = result.OrganizationalUnit;\n return {\n id: ou?.Id ?? '',\n name: ou?.Name ?? '',\n arn: ou?.Arn,\n };\n } catch (error) {\n handleAwsError(error, `getOrganizationalUnit(${id})`);\n }\n }\n\n async listOrganizationalUnits(\n parentId: string,\n ): Promise<AwsOrganizationalUnit[]> {\n try {\n const result = await this.orgs.send(\n new ListOrganizationalUnitsForParentCommand({\n ParentId: parentId,\n }),\n );\n\n return (result.OrganizationalUnits ?? []).map((ou) => ({\n id: ou.Id ?? '',\n name: ou.Name ?? '',\n arn: ou.Arn,\n parentId,\n }));\n } catch (error) {\n handleAwsError(error, `listOrganizationalUnits(${parentId})`);\n }\n }\n\n // ==========================================================================\n // Accounts (AwsDirectoryAdapter)\n // ==========================================================================\n\n async createAccount(\n input: CreateAwsAccountInput,\n ): Promise<AwsAccountCreationStatus> {\n try {\n const result = await this.orgs.send(\n new CreateAccountCommand({\n AccountName: input.name,\n Email: input.email,\n ...(input.roleName ? { RoleName: input.roleName } : {}),\n }),\n );\n\n const status = result.CreateAccountStatus;\n return {\n id: status?.Id ?? '',\n accountId: status?.AccountId,\n state:\n (status?.State as AwsAccountCreationStatus['state']) ?? 'IN_PROGRESS',\n failureReason: status?.FailureReason\n ? String(status.FailureReason)\n : undefined,\n };\n } catch (error) {\n handleAwsError(error, `createAccount(${input.name})`);\n }\n }\n\n async getAccountCreationStatus(\n id: string,\n ): Promise<AwsAccountCreationStatus> {\n try {\n const result = await this.orgs.send(\n new DescribeCreateAccountStatusCommand({\n CreateAccountRequestId: id,\n }),\n );\n\n const status = result.CreateAccountStatus;\n return {\n id: status?.Id ?? '',\n accountId: status?.AccountId,\n state:\n (status?.State as AwsAccountCreationStatus['state']) ?? 'IN_PROGRESS',\n failureReason: status?.FailureReason\n ? String(status.FailureReason)\n : undefined,\n };\n } catch (error) {\n handleAwsError(error, `getAccountCreationStatus(${id})`);\n }\n }\n\n async listAccounts(): Promise<AwsAccount[]> {\n try {\n const result = await this.orgs.send(new ListAccountsCommand({}));\n return (result.Accounts ?? []).map((a) => ({\n id: a.Id ?? '',\n name: a.Name ?? '',\n email: a.Email ?? '',\n arn: a.Arn,\n status: a.Status ? String(a.Status) : undefined,\n }));\n } catch (error) {\n handleAwsError(error, 'listAccounts');\n }\n }\n\n async moveAccount(\n accountId: string,\n sourceParentId: string,\n destParentId: string,\n ): Promise<void> {\n try {\n await this.orgs.send(\n new MoveAccountCommand({\n AccountId: accountId,\n SourceParentId: sourceParentId,\n DestinationParentId: destParentId,\n }),\n );\n } catch (error) {\n handleAwsError(\n error,\n `moveAccount(${accountId}, ${sourceParentId} -> ${destParentId})`,\n );\n }\n }\n\n // ==========================================================================\n // IAM Users (AwsDirectoryAdapter)\n // ==========================================================================\n\n async createIamUser(input: CreateAwsIamUserInput): Promise<AwsIamUser> {\n try {\n const result = await this.iam.send(\n new CreateUserCommand({\n UserName: input.username,\n ...(input.path ? { Path: input.path } : {}),\n }),\n );\n\n return mapIamUserToAwsIamUser(result.User ?? {});\n } catch (error) {\n handleAwsError(error, `createIamUser(${input.username})`);\n }\n }\n\n async getIamUser(username: string): Promise<AwsIamUser> {\n try {\n const result = await this.iam.send(\n new GetUserCommand({ UserName: username }),\n );\n return mapIamUserToAwsIamUser(result.User ?? {});\n } catch (error) {\n handleAwsError(error, `getIamUser(${username})`);\n }\n }\n\n async deleteIamUser(username: string): Promise<void> {\n try {\n await this.iam.send(new DeleteUserCommand({ UserName: username }));\n } catch (error) {\n handleAwsError(error, `deleteIamUser(${username})`);\n }\n }\n\n async listIamUsers(): Promise<AwsIamUser[]> {\n try {\n const result = await this.iam.send(new ListUsersCommand({}));\n return (result.Users ?? []).map((u) => mapIamUserToAwsIamUser(u));\n } catch (error) {\n handleAwsError(error, 'listIamUsers');\n }\n }\n\n // ==========================================================================\n // IAM Policies (AwsDirectoryAdapter)\n // ==========================================================================\n\n async attachUserPolicy(username: string, policyArn: string): Promise<void> {\n try {\n await this.iam.send(\n new AttachUserPolicyCommand({\n UserName: username,\n PolicyArn: policyArn,\n }),\n );\n } catch (error) {\n handleAwsError(error, `attachUserPolicy(${username}, ${policyArn})`);\n }\n }\n\n async detachUserPolicy(username: string, policyArn: string): Promise<void> {\n try {\n await this.iam.send(\n new DetachUserPolicyCommand({\n UserName: username,\n PolicyArn: policyArn,\n }),\n );\n } catch (error) {\n handleAwsError(error, `detachUserPolicy(${username}, ${policyArn})`);\n }\n }\n\n // ==========================================================================\n // Access Keys (AwsDirectoryAdapter)\n // ==========================================================================\n\n async createAccessKey(username: string): Promise<AwsAccessKey> {\n try {\n const result = await this.iam.send(\n new CreateAccessKeyCommand({ UserName: username }),\n );\n\n const key = result.AccessKey;\n return {\n accessKeyId: key?.AccessKeyId ?? '',\n secretAccessKey: key?.SecretAccessKey ?? '',\n username: key?.UserName ?? username,\n createDate: key?.CreateDate,\n };\n } catch (error) {\n handleAwsError(error, `createAccessKey(${username})`);\n }\n }\n\n async deleteAccessKey(username: string, accessKeyId: string): Promise<void> {\n try {\n await this.iam.send(\n new DeleteAccessKeyCommand({\n UserName: username,\n AccessKeyId: accessKeyId,\n }),\n );\n } catch (error) {\n handleAwsError(error, `deleteAccessKey(${username}, ${accessKeyId})`);\n }\n }\n}\n","/**\n * Kanidm directory adapter\n *\n * Implements KanidmDirectoryAdapter using the Kanidm REST API v1.\n * Provides user/group CRUD, membership management, and OAuth2 client operations.\n * Uses native fetch with AbortSignal.timeout() for all HTTP requests.\n */\n\nimport {\n AuthenticationError,\n ConflictError,\n ConnectionError,\n DirectoryError,\n NotFoundError,\n ValidationError,\n} from '../shared/errors.js';\nimport type {\n CreateGroupInput,\n CreateOAuth2ClientInput,\n CreateUserInput,\n CredentialResetIntent,\n DirectoryGroup,\n DirectoryUser,\n KanidmDirectoryAdapter,\n KanidmOptions,\n OAuth2Client,\n UpdateGroupInput,\n UpdateOAuth2ClientInput,\n UpdateUserInput,\n} from '../shared/types.js';\n\n// ============================================================================\n// Kanidm Response Types\n// ============================================================================\n\ninterface KanidmAttrs {\n attrs: Record<string, string[]>;\n}\n\ninterface KanidmAuthResult {\n state?: { success?: string };\n token?: string;\n}\n\n// ============================================================================\n// Adapter Implementation\n// ============================================================================\n\nexport class KanidmAdapter implements KanidmDirectoryAdapter {\n private readonly baseUrl: string;\n private readonly timeout: number;\n private adminToken: string | null = null;\n private adminTokenExpiry = 0;\n\n constructor(private readonly options: KanidmOptions) {\n if (\n !options.apiToken &&\n (!options.adminUsername || !options.adminPassword)\n ) {\n throw new ValidationError(\n 'KanidmAdapter requires either apiToken or both adminUsername and adminPassword',\n 'kanidm',\n );\n }\n this.baseUrl = options.baseUrl.replace(/\\/+$/, '');\n this.timeout = options.timeout ?? 30_000;\n }\n\n // ==========================================================================\n // Authentication\n // ==========================================================================\n\n private async getAdminToken(): Promise<string> {\n if (this.options.apiToken) {\n return this.options.apiToken;\n }\n\n if (this.adminToken && Date.now() < this.adminTokenExpiry) {\n return this.adminToken;\n }\n\n const authUrl = `${this.baseUrl}/v1/auth`;\n\n // Step 1: Initialize auth\n const initResponse = await fetch(authUrl, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n step: {\n init2: {\n username: this.options.adminUsername,\n issue: 'token',\n privileged: true,\n },\n },\n }),\n signal: AbortSignal.timeout(this.timeout),\n });\n\n if (!initResponse.ok) {\n throw new AuthenticationError(\n 'Failed to initialize admin authentication',\n 'kanidm',\n );\n }\n\n const cookies = initResponse.headers.get('set-cookie');\n\n // Step 2: Begin password authentication\n const beginResponse = await fetch(authUrl, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n ...(cookies ? { Cookie: cookies } : {}),\n },\n body: JSON.stringify({ step: { begin: 'password' } }),\n signal: AbortSignal.timeout(this.timeout),\n });\n\n if (!beginResponse.ok) {\n throw new AuthenticationError(\n 'Failed to begin password authentication',\n 'kanidm',\n );\n }\n\n // Step 3: Provide password\n const credResponse = await fetch(authUrl, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n ...(cookies ? { Cookie: cookies } : {}),\n },\n body: JSON.stringify({\n step: { cred: { password: this.options.adminPassword } },\n }),\n signal: AbortSignal.timeout(this.timeout),\n });\n\n if (!credResponse.ok) {\n throw new AuthenticationError('Invalid admin credentials', 'kanidm');\n }\n\n const result = (await credResponse.json()) as KanidmAuthResult;\n const token = result.state?.success || result.token;\n\n if (!token) {\n throw new AuthenticationError('Failed to obtain admin token', 'kanidm');\n }\n\n this.adminToken = token;\n this.adminTokenExpiry = Date.now() + 3_600_000; // 1 hour\n\n return this.adminToken;\n }\n\n // ==========================================================================\n // HTTP Helper\n // ==========================================================================\n\n private async request<T = unknown>(\n method: string,\n path: string,\n body?: unknown,\n ): Promise<T> {\n const token = await this.getAdminToken();\n const url = `${this.baseUrl}${path}`;\n\n let response: Response;\n try {\n response = await fetch(url, {\n method,\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${token}`,\n },\n ...(body !== undefined ? { body: JSON.stringify(body) } : {}),\n signal: AbortSignal.timeout(this.timeout),\n });\n } catch (error) {\n if (error instanceof TypeError) {\n throw new ConnectionError(\n `Failed to connect to Kanidm at ${this.baseUrl}`,\n 'kanidm',\n error,\n );\n }\n throw error;\n }\n\n if (response.ok) {\n const text = await response.text();\n if (!text) return undefined as T;\n return JSON.parse(text) as T;\n }\n\n // Map HTTP status codes to error types\n const errorBody = await response.text().catch(() => '');\n\n switch (response.status) {\n case 401:\n case 403:\n // Invalidate cached token on auth failure\n this.adminToken = null;\n this.adminTokenExpiry = 0;\n throw new AuthenticationError(\n errorBody || `Authentication failed: ${response.status}`,\n 'kanidm',\n );\n case 404:\n throw new NotFoundError('resource', path, 'kanidm');\n case 409:\n throw new ConflictError('resource', path, 'kanidm');\n default:\n throw new DirectoryError(\n errorBody ||\n `Request failed: ${response.status} ${response.statusText}`,\n 'REQUEST_ERROR',\n 'kanidm',\n );\n }\n }\n\n // ==========================================================================\n // Mapping Helpers\n // ==========================================================================\n\n private mapPersonToUser(data: KanidmAttrs): DirectoryUser {\n const attrs = data.attrs;\n return {\n id: this.attrFirst(attrs, 'uuid') ?? this.attrFirst(attrs, 'name') ?? '',\n username: this.attrFirst(attrs, 'name') ?? '',\n displayName: this.attrFirst(attrs, 'displayname'),\n email: this.attrFirst(attrs, 'mail'),\n active: this.attrFirst(attrs, 'class')\n ? !attrs.class?.includes('recycled')\n : true,\n groups: attrs.memberof,\n metadata: { attrs },\n };\n }\n\n private mapGroupToDirectoryGroup(data: KanidmAttrs): DirectoryGroup {\n const attrs = data.attrs;\n return {\n id: this.attrFirst(attrs, 'uuid') ?? this.attrFirst(attrs, 'name') ?? '',\n name: this.attrFirst(attrs, 'name') ?? '',\n displayName: this.attrFirst(attrs, 'displayname'),\n description: this.attrFirst(attrs, 'description'),\n members: attrs.member,\n metadata: { attrs },\n };\n }\n\n private mapOAuth2Client(data: KanidmAttrs): OAuth2Client {\n const attrs = data.attrs;\n return {\n id:\n this.attrFirst(attrs, 'uuid') ??\n this.attrFirst(attrs, 'oauth2_rs_name') ??\n '',\n name: this.attrFirst(attrs, 'oauth2_rs_name') ?? '',\n displayName: this.attrFirst(attrs, 'displayname'),\n redirectUris: attrs.oauth2_rs_origin ?? [],\n scopes: attrs.oauth2_rs_scope_map ? attrs.oauth2_rs_scope_map : undefined,\n metadata: { attrs },\n };\n }\n\n private attrFirst(\n attrs: Record<string, string[]>,\n key: string,\n ): string | undefined {\n const values = attrs[key];\n return values?.[0];\n }\n\n // ==========================================================================\n // Connection\n // ==========================================================================\n\n async testConnection(): Promise<boolean> {\n try {\n await this.getAdminToken();\n return true;\n } catch {\n return false;\n }\n }\n\n async disconnect(): Promise<void> {\n this.adminToken = null;\n this.adminTokenExpiry = 0;\n }\n\n // ==========================================================================\n // User CRUD\n // ==========================================================================\n\n async createUser(input: CreateUserInput): Promise<DirectoryUser> {\n const body: Record<string, unknown> = {\n attrs: {\n name: [input.username],\n ...(input.displayName ? { displayname: [input.displayName] } : {}),\n ...(input.email ? { mail: [input.email] } : {}),\n ...(input.metadata ?? {}),\n },\n };\n\n await this.request('POST', '/v1/person', body);\n return this.getUser(input.username);\n }\n\n async getUser(id: string): Promise<DirectoryUser> {\n const data = await this.request<KanidmAttrs>(\n 'GET',\n `/v1/person/${encodeURIComponent(id)}`,\n );\n return this.mapPersonToUser(data);\n }\n\n async updateUser(id: string, input: UpdateUserInput): Promise<DirectoryUser> {\n const attrs: Record<string, string[]> = {};\n\n if (input.displayName !== undefined) {\n attrs.displayname = [input.displayName];\n }\n if (input.email !== undefined) {\n attrs.mail = [input.email];\n }\n\n await this.request('PATCH', `/v1/person/${encodeURIComponent(id)}`, {\n attrs,\n });\n\n return this.getUser(id);\n }\n\n async deleteUser(id: string): Promise<void> {\n await this.request('DELETE', `/v1/person/${encodeURIComponent(id)}`);\n }\n\n async listUsers(): Promise<DirectoryUser[]> {\n const data = await this.request<KanidmAttrs[]>('GET', '/v1/person');\n return (data ?? []).map((entry) => this.mapPersonToUser(entry));\n }\n\n // ==========================================================================\n // Group CRUD\n // ==========================================================================\n\n async createGroup(input: CreateGroupInput): Promise<DirectoryGroup> {\n const body: Record<string, unknown> = {\n attrs: {\n name: [input.name],\n ...(input.displayName ? { displayname: [input.displayName] } : {}),\n ...(input.description ? { description: [input.description] } : {}),\n ...(input.members ? { member: input.members } : {}),\n ...(input.metadata ?? {}),\n },\n };\n\n await this.request('POST', '/v1/group', body);\n return this.getGroup(input.name);\n }\n\n async getGroup(id: string): Promise<DirectoryGroup> {\n const data = await this.request<KanidmAttrs>(\n 'GET',\n `/v1/group/${encodeURIComponent(id)}`,\n );\n return this.mapGroupToDirectoryGroup(data);\n }\n\n async updateGroup(\n id: string,\n input: UpdateGroupInput,\n ): Promise<DirectoryGroup> {\n const attrs: Record<string, string[]> = {};\n\n if (input.displayName !== undefined) {\n attrs.displayname = [input.displayName];\n }\n if (input.description !== undefined) {\n attrs.description = [input.description];\n }\n\n await this.request('PATCH', `/v1/group/${encodeURIComponent(id)}`, {\n attrs,\n });\n\n return this.getGroup(id);\n }\n\n async deleteGroup(id: string): Promise<void> {\n await this.request('DELETE', `/v1/group/${encodeURIComponent(id)}`);\n }\n\n async listGroups(): Promise<DirectoryGroup[]> {\n const data = await this.request<KanidmAttrs[]>('GET', '/v1/group');\n return (data ?? []).map((entry) => this.mapGroupToDirectoryGroup(entry));\n }\n\n // ==========================================================================\n // Membership\n // ==========================================================================\n\n async addUserToGroup(userId: string, groupId: string): Promise<void> {\n await this.request(\n 'POST',\n `/v1/group/${encodeURIComponent(groupId)}/_attr/member`,\n [userId],\n );\n }\n\n async removeUserFromGroup(userId: string, groupId: string): Promise<void> {\n await this.request(\n 'DELETE',\n `/v1/group/${encodeURIComponent(groupId)}/_attr/member`,\n [userId],\n );\n }\n\n async getGroupMembers(groupId: string): Promise<DirectoryUser[]> {\n const group = await this.getGroup(groupId);\n if (!group.members || group.members.length === 0) {\n return [];\n }\n\n const users: DirectoryUser[] = [];\n for (const memberId of group.members) {\n try {\n const user = await this.getUser(memberId);\n users.push(user);\n } catch (error) {\n // Skip members that are not persons (e.g., nested groups)\n if (!(error instanceof NotFoundError)) {\n throw error;\n }\n }\n }\n\n return users;\n }\n\n async getUserGroups(userId: string): Promise<DirectoryGroup[]> {\n const user = await this.getUser(userId);\n if (!user.groups || user.groups.length === 0) {\n return [];\n }\n\n const groups: DirectoryGroup[] = [];\n for (const groupId of user.groups) {\n try {\n const group = await this.getGroup(groupId);\n groups.push(group);\n } catch (error) {\n if (!(error instanceof NotFoundError)) {\n throw error;\n }\n }\n }\n\n return groups;\n }\n\n // ==========================================================================\n // OAuth2 Client CRUD\n // ==========================================================================\n\n async createOAuth2Client(\n input: CreateOAuth2ClientInput,\n ): Promise<OAuth2Client> {\n const body: Record<string, unknown> = {\n attrs: {\n oauth2_rs_name: [input.name],\n ...(input.displayName ? { displayname: [input.displayName] } : {}),\n oauth2_rs_origin: input.redirectUris,\n ...(input.scopes ? { oauth2_rs_scope_map: input.scopes } : {}),\n },\n };\n\n await this.request('POST', '/v1/oauth2', body);\n return this.getOAuth2Client(input.name);\n }\n\n async getOAuth2Client(id: string): Promise<OAuth2Client> {\n const data = await this.request<KanidmAttrs>(\n 'GET',\n `/v1/oauth2/${encodeURIComponent(id)}`,\n );\n return this.mapOAuth2Client(data);\n }\n\n async updateOAuth2Client(\n id: string,\n input: UpdateOAuth2ClientInput,\n ): Promise<OAuth2Client> {\n const attrs: Record<string, string[]> = {};\n\n if (input.displayName !== undefined) {\n attrs.displayname = [input.displayName];\n }\n if (input.redirectUris !== undefined) {\n attrs.oauth2_rs_origin = input.redirectUris;\n }\n if (input.scopes !== undefined) {\n attrs.oauth2_rs_scope_map = input.scopes;\n }\n\n await this.request('PATCH', `/v1/oauth2/${encodeURIComponent(id)}`, {\n attrs,\n });\n\n return this.getOAuth2Client(id);\n }\n\n async deleteOAuth2Client(id: string): Promise<void> {\n await this.request('DELETE', `/v1/oauth2/${encodeURIComponent(id)}`);\n }\n\n async listOAuth2Clients(): Promise<OAuth2Client[]> {\n const data = await this.request<KanidmAttrs[]>('GET', '/v1/oauth2');\n return (data ?? []).map((entry) => this.mapOAuth2Client(entry));\n }\n\n // ==========================================================================\n // OAuth2 Secret Management\n // ==========================================================================\n\n async getOAuth2ClientSecret(id: string): Promise<string> {\n const data = await this.request<string>(\n 'GET',\n `/v1/oauth2/${encodeURIComponent(id)}/_basic_secret`,\n );\n return data;\n }\n\n // ==========================================================================\n // Credential Management\n // ==========================================================================\n\n async createCredentialResetIntent(\n userId: string,\n options?: { ttl?: number },\n ): Promise<CredentialResetIntent> {\n const ttl = options?.ttl ?? 3600;\n const token = await this.request<string>(\n 'GET',\n `/v1/person/${encodeURIComponent(userId)}/_credential/_update_intent/${ttl}`,\n );\n return {\n token,\n url: `${this.baseUrl}/ui/reset?token=${encodeURIComponent(token)}`,\n ttl,\n };\n }\n}\n","/**\n * PostgreSQL directory adapter for @happyvertical/directory\n *\n * Maps PostgreSQL roles and databases to the DirectoryAdapter interface.\n * Uses the CNPG cluster admin role for provisioning operations.\n *\n * Concept mapping:\n * - DirectoryUser -> PostgreSQL role WITH LOGIN\n * - DirectoryGroup -> PostgreSQL role WITHOUT LOGIN (NOLOGIN)\n * - Membership -> GRANT role TO role\n * - PgDatabase -> PostgreSQL database\n * - PgRole -> PostgreSQL role (any)\n */\n\nimport pg from 'pg';\nimport {\n AuthenticationError,\n ConflictError,\n ConnectionError,\n DirectoryError,\n NotFoundError,\n} from '../shared/errors.js';\nimport type {\n CreateGroupInput,\n CreatePgDatabaseInput,\n CreatePgRoleInput,\n CreateUserInput,\n DirectoryGroup,\n DirectoryUser,\n PgDatabase,\n PgRole,\n PostgresDirectoryAdapter,\n PostgresOptions,\n UpdateGroupInput,\n UpdateUserInput,\n} from '../shared/types.js';\n\nconst { Client } = pg;\n\nconst PROVIDER = 'postgres';\n\n/**\n * System roles excluded from list operations.\n * Includes PostgreSQL internal roles (pg_*) and the default superuser.\n */\nconst SYSTEM_ROLE_PREFIX = 'pg_';\nconst SYSTEM_ROLES = new Set(['postgres']);\n\n/**\n * System databases excluded from list operations.\n */\nconst SYSTEM_DATABASES = new Set(['template0', 'template1', 'postgres']);\n\nexport class PostgresAdapter implements PostgresDirectoryAdapter {\n private options: PostgresOptions;\n private client: pg.Client | null = null;\n\n constructor(options: PostgresOptions) {\n this.options = options;\n }\n\n // ==========================================================================\n // Private Helpers\n // ==========================================================================\n\n /**\n * Escape a SQL identifier by wrapping in double quotes and escaping\n * any embedded double quotes. Used for DDL statements where\n * parameterized queries are not supported.\n */\n private escapeIdentifier(name: string): string {\n return `\"${name.replace(/\"/g, '\"\"')}\"`;\n }\n\n /**\n * Escape a SQL string literal by wrapping in single quotes and escaping\n * any embedded single quotes. Used for DDL statements (e.g., passwords)\n * where parameterized queries are not supported.\n */\n private escapeLiteral(value: string): string {\n return `'${value.replace(/'/g, \"''\")}'`;\n }\n\n /**\n * Get or create the pg.Client instance. Connects lazily on first use.\n */\n private async getClient(): Promise<pg.Client> {\n if (this.client) {\n return this.client;\n }\n\n try {\n this.client = new Client({\n host: this.options.host,\n port: this.options.port ?? 5432,\n user: this.options.adminUser,\n password: this.options.adminPassword,\n database: this.options.database ?? 'postgres',\n ssl: this.options.ssl\n ? typeof this.options.ssl === 'object'\n ? this.options.ssl\n : { rejectUnauthorized: false }\n : undefined,\n });\n\n await this.client.connect();\n return this.client;\n } catch (error) {\n this.client = null;\n throw this.mapError(error);\n }\n }\n\n /**\n * Check if a role name is a system role that should be excluded from lists.\n */\n private isSystemRole(rolname: string): boolean {\n return rolname.startsWith(SYSTEM_ROLE_PREFIX) || SYSTEM_ROLES.has(rolname);\n }\n\n /**\n * Map a pg_roles row to a DirectoryUser.\n */\n private rowToUser(row: Record<string, unknown>): DirectoryUser {\n return {\n id: row.rolname as string,\n username: row.rolname as string,\n active: true,\n metadata: {\n superuser: row.rolsuper as boolean,\n createDb: row.rolcreatedb as boolean,\n createRole: row.rolcreaterole as boolean,\n },\n };\n }\n\n /**\n * Map a pg_roles row to a DirectoryGroup.\n */\n private rowToGroup(row: Record<string, unknown>): DirectoryGroup {\n return {\n id: row.rolname as string,\n name: row.rolname as string,\n metadata: {\n superuser: row.rolsuper as boolean,\n createDb: row.rolcreatedb as boolean,\n createRole: row.rolcreaterole as boolean,\n },\n };\n }\n\n /**\n * Map a pg_roles row to a PgRole.\n */\n private rowToPgRole(row: Record<string, unknown>): PgRole {\n return {\n name: row.rolname as string,\n login: row.rolcanlogin as boolean,\n superuser: row.rolsuper as boolean,\n createDb: row.rolcreatedb as boolean,\n createRole: row.rolcreaterole as boolean,\n };\n }\n\n /**\n * Map a pg_database row to a PgDatabase.\n */\n private rowToDatabase(row: Record<string, unknown>): PgDatabase {\n return {\n name: row.datname as string,\n owner: row.owner as string,\n encoding: row.encoding as string | undefined,\n size: row.size as string | undefined,\n };\n }\n\n /**\n * Map PostgreSQL errors to directory error classes.\n */\n private mapError(error: unknown): DirectoryError {\n if (error instanceof DirectoryError) {\n return error;\n }\n\n const pgError = error as {\n code?: string;\n message?: string;\n routine?: string;\n };\n\n // PostgreSQL error codes\n switch (pgError.code) {\n case '42710': // duplicate_object\n return new ConflictError(\n 'role',\n pgError.message ?? 'unknown',\n PROVIDER,\n error,\n );\n case '42704': // undefined_object\n return new NotFoundError(\n 'role',\n pgError.message ?? 'unknown',\n PROVIDER,\n error,\n );\n case '28P01': // invalid_password\n return new AuthenticationError(\n pgError.message ?? 'Invalid password',\n PROVIDER,\n error,\n );\n default:\n break;\n }\n\n // Connection errors\n const message =\n pgError.message ??\n (error instanceof Error ? error.message : String(error));\n if (\n message.includes('ECONNREFUSED') ||\n message.includes('connect ETIMEDOUT') ||\n message.includes('getaddrinfo')\n ) {\n return new ConnectionError(\n `Failed to connect to PostgreSQL: ${message}`,\n PROVIDER,\n error,\n );\n }\n\n return new DirectoryError(message, 'UNKNOWN_ERROR', PROVIDER, error);\n }\n\n // ==========================================================================\n // Connection\n // ==========================================================================\n\n async testConnection(): Promise<boolean> {\n try {\n const client = await this.getClient();\n await client.query('SELECT 1');\n return true;\n } catch {\n return false;\n }\n }\n\n async disconnect(): Promise<void> {\n if (this.client) {\n await this.client.end();\n this.client = null;\n }\n }\n\n // ==========================================================================\n // User CRUD (PostgreSQL roles WITH LOGIN)\n // ==========================================================================\n\n async createUser(input: CreateUserInput): Promise<DirectoryUser> {\n const client = await this.getClient();\n\n try {\n let sql = `CREATE ROLE ${this.escapeIdentifier(input.username)} WITH LOGIN`;\n\n if (input.password) {\n sql += ` PASSWORD ${this.escapeLiteral(input.password)}`;\n }\n\n await client.query(sql);\n\n return this.getUser(input.username);\n } catch (error) {\n throw this.mapError(error);\n }\n }\n\n async getUser(id: string): Promise<DirectoryUser> {\n const client = await this.getClient();\n\n try {\n const result = await client.query(\n `SELECT rolname, rolsuper, rolcreatedb, rolcreaterole, rolcanlogin\n FROM pg_roles\n WHERE rolname = $1 AND rolcanlogin = true`,\n [id],\n );\n\n if (result.rows.length === 0) {\n throw new NotFoundError('user', id, PROVIDER);\n }\n\n return this.rowToUser(result.rows[0]);\n } catch (error) {\n throw this.mapError(error);\n }\n }\n\n async updateUser(id: string, input: UpdateUserInput): Promise<DirectoryUser> {\n const client = await this.getClient();\n\n try {\n // Verify the user exists first\n await this.getUser(id);\n\n const alterClauses: string[] = [];\n\n if (input.password !== undefined) {\n alterClauses.push(`PASSWORD ${this.escapeLiteral(input.password)}`);\n }\n\n if (alterClauses.length > 0) {\n const sql = `ALTER ROLE ${this.escapeIdentifier(id)} WITH ${alterClauses.join(' ')}`;\n await client.query(sql);\n }\n\n return this.getUser(id);\n } catch (error) {\n throw this.mapError(error);\n }\n }\n\n async deleteUser(id: string): Promise<void> {\n const client = await this.getClient();\n\n try {\n await this.getUser(id);\n await client.query(`DROP ROLE ${this.escapeIdentifier(id)}`);\n } catch (error) {\n throw this.mapError(error);\n }\n }\n\n async listUsers(): Promise<DirectoryUser[]> {\n const client = await this.getClient();\n\n try {\n const result = await client.query(\n `SELECT rolname, rolsuper, rolcreatedb, rolcreaterole, rolcanlogin\n FROM pg_roles\n WHERE rolcanlogin = true\n ORDER BY rolname`,\n );\n\n return result.rows\n .filter(\n (row: Record<string, unknown>) =>\n !this.isSystemRole(row.rolname as string),\n )\n .map((row: Record<string, unknown>) => this.rowToUser(row));\n } catch (error) {\n throw this.mapError(error);\n }\n }\n\n // ==========================================================================\n // Group CRUD (PostgreSQL roles WITHOUT LOGIN)\n // ==========================================================================\n\n async createGroup(input: CreateGroupInput): Promise<DirectoryGroup> {\n const client = await this.getClient();\n\n try {\n await client.query(\n `CREATE ROLE ${this.escapeIdentifier(input.name)} NOLOGIN`,\n );\n\n // Add initial members if provided\n if (input.members) {\n for (const member of input.members) {\n await this.addUserToGroup(member, input.name);\n }\n }\n\n return this.getGroup(input.name);\n } catch (error) {\n throw this.mapError(error);\n }\n }\n\n async getGroup(id: string): Promise<DirectoryGroup> {\n const client = await this.getClient();\n\n try {\n const result = await client.query(\n `SELECT rolname, rolsuper, rolcreatedb, rolcreaterole, rolcanlogin\n FROM pg_roles\n WHERE rolname = $1 AND rolcanlogin = false`,\n [id],\n );\n\n if (result.rows.length === 0) {\n throw new NotFoundError('group', id, PROVIDER);\n }\n\n return this.rowToGroup(result.rows[0]);\n } catch (error) {\n throw this.mapError(error);\n }\n }\n\n async updateGroup(\n id: string,\n _input: UpdateGroupInput,\n ): Promise<DirectoryGroup> {\n // PostgreSQL roles don't have display names or descriptions.\n // Verify the group exists and return it.\n return this.getGroup(id);\n }\n\n async deleteGroup(id: string): Promise<void> {\n const client = await this.getClient();\n\n try {\n await this.getGroup(id);\n await client.query(`DROP ROLE ${this.escapeIdentifier(id)}`);\n } catch (error) {\n throw this.mapError(error);\n }\n }\n\n async listGroups(): Promise<DirectoryGroup[]> {\n const client = await this.getClient();\n\n try {\n const result = await client.query(\n `SELECT rolname, rolsuper, rolcreatedb, rolcreaterole, rolcanlogin\n FROM pg_roles\n WHERE rolcanlogin = false\n ORDER BY rolname`,\n );\n\n return result.rows\n .filter(\n (row: Record<string, unknown>) =>\n !this.isSystemRole(row.rolname as string),\n )\n .map((row: Record<string, unknown>) => this.rowToGroup(row));\n } catch (error) {\n throw this.mapError(error);\n }\n }\n\n // ==========================================================================\n // Membership (GRANT/REVOKE role TO/FROM role)\n // ==========================================================================\n\n async addUserToGroup(userId: string, groupId: string): Promise<void> {\n const client = await this.getClient();\n\n try {\n await client.query(\n `GRANT ${this.escapeIdentifier(groupId)} TO ${this.escapeIdentifier(userId)}`,\n );\n } catch (error) {\n throw this.mapError(error);\n }\n }\n\n async removeUserFromGroup(userId: string, groupId: string): Promise<void> {\n const client = await this.getClient();\n\n try {\n await client.query(\n `REVOKE ${this.escapeIdentifier(groupId)} FROM ${this.escapeIdentifier(userId)}`,\n );\n } catch (error) {\n throw this.mapError(error);\n }\n }\n\n async getGroupMembers(groupId: string): Promise<DirectoryUser[]> {\n const client = await this.getClient();\n\n try {\n // Verify the group exists\n await this.getGroup(groupId);\n\n const result = await client.query(\n `SELECT r.rolname, r.rolsuper, r.rolcreatedb, r.rolcreaterole, r.rolcanlogin\n FROM pg_auth_members m\n JOIN pg_roles g ON g.oid = m.roleid\n JOIN pg_roles r ON r.oid = m.member\n WHERE g.rolname = $1 AND r.rolcanlogin = true\n ORDER BY r.rolname`,\n [groupId],\n );\n\n return result.rows.map((row: Record<string, unknown>) =>\n this.rowToUser(row),\n );\n } catch (error) {\n throw this.mapError(error);\n }\n }\n\n async getUserGroups(userId: string): Promise<DirectoryGroup[]> {\n const client = await this.getClient();\n\n try {\n // Verify the user exists\n await this.getUser(userId);\n\n const result = await client.query(\n `SELECT g.rolname, g.rolsuper, g.rolcreatedb, g.rolcreaterole, g.rolcanlogin\n FROM pg_auth_members m\n JOIN pg_roles g ON g.oid = m.roleid\n JOIN pg_roles r ON r.oid = m.member\n WHERE r.rolname = $1 AND g.rolcanlogin = false\n ORDER BY g.rolname`,\n [userId],\n );\n\n return result.rows.map((row: Record<string, unknown>) =>\n this.rowToGroup(row),\n );\n } catch (error) {\n throw this.mapError(error);\n }\n }\n\n // ==========================================================================\n // Database Provisioning\n // ==========================================================================\n\n async createDatabase(input: CreatePgDatabaseInput): Promise<PgDatabase> {\n const client = await this.getClient();\n\n try {\n let sql = `CREATE DATABASE ${this.escapeIdentifier(input.name)} OWNER ${this.escapeIdentifier(input.owner)}`;\n\n if (input.encoding) {\n sql += ` ENCODING ${this.escapeLiteral(input.encoding)}`;\n }\n\n await client.query(sql);\n\n return this.getDatabase(input.name);\n } catch (error) {\n throw this.mapError(error);\n }\n }\n\n async getDatabase(name: string): Promise<PgDatabase> {\n const client = await this.getClient();\n\n try {\n const result = await client.query(\n `SELECT\n d.datname,\n pg_catalog.pg_get_userbyid(d.datdba) AS owner,\n pg_encoding_to_char(d.encoding) AS encoding,\n pg_database_size(d.datname)::text AS size\n FROM pg_database d\n WHERE d.datname = $1`,\n [name],\n );\n\n if (result.rows.length === 0) {\n throw new NotFoundError('database', name, PROVIDER);\n }\n\n return this.rowToDatabase(result.rows[0]);\n } catch (error) {\n throw this.mapError(error);\n }\n }\n\n async dropDatabase(name: string): Promise<void> {\n const client = await this.getClient();\n\n try {\n await this.getDatabase(name);\n await client.query(`DROP DATABASE ${this.escapeIdentifier(name)}`);\n } catch (error) {\n throw this.mapError(error);\n }\n }\n\n async listDatabases(): Promise<PgDatabase[]> {\n const client = await this.getClient();\n\n try {\n const result = await client.query(\n `SELECT\n d.datname,\n pg_catalog.pg_get_userbyid(d.datdba) AS owner,\n pg_encoding_to_char(d.encoding) AS encoding,\n pg_database_size(d.datname)::text AS size\n FROM pg_database d\n ORDER BY d.datname`,\n );\n\n return result.rows\n .filter(\n (row: Record<string, unknown>) =>\n !SYSTEM_DATABASES.has(row.datname as string),\n )\n .map((row: Record<string, unknown>) => this.rowToDatabase(row));\n } catch (error) {\n throw this.mapError(error);\n }\n }\n\n // ==========================================================================\n // Role Provisioning\n // ==========================================================================\n\n async createRole(input: CreatePgRoleInput): Promise<PgRole> {\n const client = await this.getClient();\n\n try {\n const options: string[] = [];\n\n if (input.login !== undefined) {\n options.push(input.login ? 'LOGIN' : 'NOLOGIN');\n }\n\n if (input.password) {\n options.push(`PASSWORD ${this.escapeLiteral(input.password)}`);\n }\n\n if (input.superuser !== undefined) {\n options.push(input.superuser ? 'SUPERUSER' : 'NOSUPERUSER');\n }\n\n if (input.createDb !== undefined) {\n options.push(input.createDb ? 'CREATEDB' : 'NOCREATEDB');\n }\n\n if (input.createRole !== undefined) {\n options.push(input.createRole ? 'CREATEROLE' : 'NOCREATEROLE');\n }\n\n let sql = `CREATE ROLE ${this.escapeIdentifier(input.name)}`;\n if (options.length > 0) {\n sql += ` WITH ${options.join(' ')}`;\n }\n\n await client.query(sql);\n\n return this.getRole(input.name);\n } catch (error) {\n throw this.mapError(error);\n }\n }\n\n async getRole(name: string): Promise<PgRole> {\n const client = await this.getClient();\n\n try {\n const result = await client.query(\n `SELECT rolname, rolcanlogin, rolsuper, rolcreatedb, rolcreaterole\n FROM pg_roles\n WHERE rolname = $1`,\n [name],\n );\n\n if (result.rows.length === 0) {\n throw new NotFoundError('role', name, PROVIDER);\n }\n\n return this.rowToPgRole(result.rows[0]);\n } catch (error) {\n throw this.mapError(error);\n }\n }\n\n async dropRole(name: string): Promise<void> {\n const client = await this.getClient();\n\n try {\n await this.getRole(name);\n await client.query(`DROP ROLE ${this.escapeIdentifier(name)}`);\n } catch (error) {\n throw this.mapError(error);\n }\n }\n\n async listRoles(): Promise<PgRole[]> {\n const client = await this.getClient();\n\n try {\n const result = await client.query(\n `SELECT rolname, rolcanlogin, rolsuper, rolcreatedb, rolcreaterole\n FROM pg_roles\n ORDER BY rolname`,\n );\n\n return result.rows\n .filter(\n (row: Record<string, unknown>) =>\n !this.isSystemRole(row.rolname as string),\n )\n .map((row: Record<string, unknown>) => this.rowToPgRole(row));\n } catch (error) {\n throw this.mapError(error);\n }\n }\n\n // ==========================================================================\n // Access Control (GRANT/REVOKE on databases)\n // ==========================================================================\n\n async grantAccess(roleName: string, databaseName: string): Promise<void> {\n const client = await this.getClient();\n\n try {\n await client.query(\n `GRANT ALL ON DATABASE ${this.escapeIdentifier(databaseName)} TO ${this.escapeIdentifier(roleName)}`,\n );\n } catch (error) {\n throw this.mapError(error);\n }\n }\n\n async revokeAccess(roleName: string, databaseName: string): Promise<void> {\n const client = await this.getClient();\n\n try {\n await client.query(\n `REVOKE ALL ON DATABASE ${this.escapeIdentifier(databaseName)} FROM ${this.escapeIdentifier(roleName)}`,\n );\n } catch (error) {\n throw this.mapError(error);\n }\n }\n}\n","/**\n * Stalwart mail server directory adapter\n *\n * Implements StalwartDirectoryAdapter using the Stalwart REST API\n * with HTTP Basic authentication. Manages users, groups, domains,\n * DKIM keys, DNS records, and mailboxes via the principals API.\n */\n\nimport {\n AuthenticationError,\n ConflictError,\n ConnectionError,\n DirectoryError,\n NotFoundError,\n} from '../shared/errors.js';\nimport type {\n CreateDkimKeyInput,\n CreateGroupInput,\n CreateMailboxInput,\n CreateMailDomainInput,\n CreateUserInput,\n DirectoryGroup,\n DirectoryUser,\n DkimKey,\n DnsRecord,\n Mailbox,\n MailDomain,\n StalwartDirectoryAdapter,\n StalwartOptions,\n UpdateGroupInput,\n UpdateMailboxInput,\n UpdateUserInput,\n} from '../shared/types.js';\n\nconst PROVIDER = 'stalwart';\nconst DEFAULT_TIMEOUT = 30_000;\n\n/** Stalwart principal as returned by the API */\ninterface StalwartPrincipal {\n name: string;\n type: 'individual' | 'group' | 'domain';\n description?: string;\n emails?: string[];\n memberOf?: string[];\n members?: string[];\n quota?: number;\n secrets?: string[];\n [key: string]: unknown;\n}\n\nexport class StalwartAdapter implements StalwartDirectoryAdapter {\n private readonly options: StalwartOptions;\n private readonly authHeader: string;\n\n constructor(options: StalwartOptions) {\n this.options = options;\n this.authHeader = `Basic ${btoa(`${options.username}:${options.password}`)}`;\n }\n\n private get timeout(): number {\n return this.options.timeout ?? DEFAULT_TIMEOUT;\n }\n\n // ==========================================================================\n // HTTP Helper\n // ==========================================================================\n\n private async request<T = unknown>(\n method: string,\n path: string,\n body?: unknown,\n ): Promise<T> {\n const url = `${this.options.baseUrl}${path}`;\n const headers: Record<string, string> = {\n Authorization: this.authHeader,\n Accept: 'application/json',\n };\n\n if (body !== undefined) {\n headers['Content-Type'] = 'application/json';\n }\n\n let response: Response;\n try {\n response = await fetch(url, {\n method,\n headers,\n body: body !== undefined ? JSON.stringify(body) : undefined,\n signal: AbortSignal.timeout(this.timeout),\n });\n } catch (error) {\n if (error instanceof DOMException && error.name === 'TimeoutError') {\n throw new ConnectionError(\n `Request timed out after ${this.timeout}ms: ${method} ${path}`,\n PROVIDER,\n error,\n );\n }\n throw new ConnectionError(\n `Failed to connect to Stalwart: ${(error as Error).message}`,\n PROVIDER,\n error,\n );\n }\n\n if (response.ok) {\n const text = await response.text();\n if (!text) return undefined as T;\n try {\n return JSON.parse(text) as T;\n } catch {\n return text as T;\n }\n }\n\n const errorBody = await response.text().catch(() => '');\n\n switch (response.status) {\n case 401:\n case 403:\n throw new AuthenticationError(\n `Authentication failed: ${response.status} ${response.statusText}`,\n PROVIDER,\n );\n case 404:\n throw new NotFoundError('resource', path, PROVIDER);\n case 409:\n throw new ConflictError('resource', path, PROVIDER);\n default:\n throw new DirectoryError(\n `Stalwart API error: ${response.status} ${response.statusText}${errorBody ? ` - ${errorBody}` : ''}`,\n 'API_ERROR',\n PROVIDER,\n );\n }\n }\n\n // ==========================================================================\n // Connection\n // ==========================================================================\n\n async testConnection(): Promise<boolean> {\n try {\n await this.request('GET', '/api/principal?type=individual&limit=1');\n return true;\n } catch (error) {\n if (error instanceof AuthenticationError) {\n throw error;\n }\n return false;\n }\n }\n\n async disconnect(): Promise<void> {\n // HTTP adapter - no persistent connection to close\n }\n\n // ==========================================================================\n // User CRUD\n // ==========================================================================\n\n async createUser(input: CreateUserInput): Promise<DirectoryUser> {\n const principal: StalwartPrincipal = {\n name: input.username,\n type: 'individual',\n description: input.displayName,\n emails: input.email ? [input.email] : [],\n secrets: input.password ? [input.password] : undefined,\n };\n\n await this.request('POST', '/api/principal', principal);\n return this.getUser(input.username);\n }\n\n async getUser(id: string): Promise<DirectoryUser> {\n const principal = await this.request<StalwartPrincipal>(\n 'GET',\n `/api/principal/${encodeURIComponent(id)}`,\n );\n return this.principalToUser(principal);\n }\n\n async updateUser(id: string, input: UpdateUserInput): Promise<DirectoryUser> {\n const patch: Record<string, unknown> = {};\n if (input.displayName !== undefined) patch.description = input.displayName;\n if (input.email !== undefined) patch.emails = [input.email];\n if (input.password !== undefined) patch.secrets = [input.password];\n\n await this.request(\n 'PATCH',\n `/api/principal/${encodeURIComponent(id)}`,\n patch,\n );\n return this.getUser(id);\n }\n\n async deleteUser(id: string): Promise<void> {\n await this.request('DELETE', `/api/principal/${encodeURIComponent(id)}`);\n }\n\n async listUsers(): Promise<DirectoryUser[]> {\n const names = await this.request<string[]>(\n 'GET',\n '/api/principal?type=individual',\n );\n const users = await Promise.all(\n (names ?? []).map((name) => this.getUser(name)),\n );\n return users;\n }\n\n // ==========================================================================\n // Group CRUD\n // ==========================================================================\n\n async createGroup(input: CreateGroupInput): Promise<DirectoryGroup> {\n const principal: StalwartPrincipal = {\n name: input.name,\n type: 'group',\n description: input.description ?? input.displayName,\n members: input.members,\n };\n\n await this.request('POST', '/api/principal', principal);\n return this.getGroup(input.name);\n }\n\n async getGroup(id: string): Promise<DirectoryGroup> {\n const principal = await this.request<StalwartPrincipal>(\n 'GET',\n `/api/principal/${encodeURIComponent(id)}`,\n );\n return this.principalToGroup(principal);\n }\n\n async updateGroup(\n id: string,\n input: UpdateGroupInput,\n ): Promise<DirectoryGroup> {\n const patch: Record<string, unknown> = {};\n if (input.displayName !== undefined) patch.description = input.displayName;\n if (input.description !== undefined) patch.description = input.description;\n\n await this.request(\n 'PATCH',\n `/api/principal/${encodeURIComponent(id)}`,\n patch,\n );\n return this.getGroup(id);\n }\n\n async deleteGroup(id: string): Promise<void> {\n await this.request('DELETE', `/api/principal/${encodeURIComponent(id)}`);\n }\n\n async listGroups(): Promise<DirectoryGroup[]> {\n const names = await this.request<string[]>(\n 'GET',\n '/api/principal?type=group',\n );\n const groups = await Promise.all(\n (names ?? []).map((name) => this.getGroup(name)),\n );\n return groups;\n }\n\n // ==========================================================================\n // Membership\n // ==========================================================================\n\n async addUserToGroup(userId: string, groupId: string): Promise<void> {\n const group = await this.request<StalwartPrincipal>(\n 'GET',\n `/api/principal/${encodeURIComponent(groupId)}`,\n );\n const members = group.members ?? [];\n if (!members.includes(userId)) {\n members.push(userId);\n }\n await this.request(\n 'PATCH',\n `/api/principal/${encodeURIComponent(groupId)}`,\n { members },\n );\n }\n\n async removeUserFromGroup(userId: string, groupId: string): Promise<void> {\n const group = await this.request<StalwartPrincipal>(\n 'GET',\n `/api/principal/${encodeURIComponent(groupId)}`,\n );\n const members = (group.members ?? []).filter((m) => m !== userId);\n await this.request(\n 'PATCH',\n `/api/principal/${encodeURIComponent(groupId)}`,\n { members },\n );\n }\n\n async getGroupMembers(groupId: string): Promise<DirectoryUser[]> {\n const group = await this.request<StalwartPrincipal>(\n 'GET',\n `/api/principal/${encodeURIComponent(groupId)}`,\n );\n const members = group.members ?? [];\n const users = await Promise.all(members.map((name) => this.getUser(name)));\n return users;\n }\n\n async getUserGroups(userId: string): Promise<DirectoryGroup[]> {\n const user = await this.request<StalwartPrincipal>(\n 'GET',\n `/api/principal/${encodeURIComponent(userId)}`,\n );\n const groupNames = user.memberOf ?? [];\n const groups = await Promise.all(\n groupNames.map((name) => this.getGroup(name)),\n );\n return groups;\n }\n\n // ==========================================================================\n // Domain CRUD\n // ==========================================================================\n\n async createDomain(input: CreateMailDomainInput): Promise<MailDomain> {\n const principal: StalwartPrincipal = {\n name: input.name,\n type: 'domain',\n };\n\n await this.request('POST', '/api/principal', principal);\n return this.getDomain(input.name);\n }\n\n async getDomain(id: string): Promise<MailDomain> {\n const principal = await this.request<StalwartPrincipal>(\n 'GET',\n `/api/principal/${encodeURIComponent(id)}`,\n );\n return {\n id: principal.name,\n name: principal.name,\n active: true,\n };\n }\n\n async deleteDomain(id: string): Promise<void> {\n await this.request('DELETE', `/api/principal/${encodeURIComponent(id)}`);\n }\n\n async listDomains(): Promise<MailDomain[]> {\n const names = await this.request<string[]>(\n 'GET',\n '/api/principal?type=domain',\n );\n const domains = await Promise.all(\n (names ?? []).map((name) => this.getDomain(name)),\n );\n return domains;\n }\n\n // ==========================================================================\n // DKIM\n // ==========================================================================\n\n async createDkimKey(input: CreateDkimKeyInput): Promise<DkimKey> {\n const result = await this.request<{\n id?: string;\n publicKey?: string;\n }>('POST', '/api/dkim', {\n domain: input.domain,\n selector: input.selector,\n });\n\n return {\n id: result?.id ?? `${input.selector}._domainkey.${input.domain}`,\n domain: input.domain,\n selector: input.selector,\n publicKey: result?.publicKey,\n };\n }\n\n // ==========================================================================\n // DNS Records\n // ==========================================================================\n\n async getDnsRecords(domain: string): Promise<DnsRecord[]> {\n const records = await this.request<DnsRecord[]>(\n 'GET',\n `/api/dns/records/${encodeURIComponent(domain)}`,\n );\n return records ?? [];\n }\n\n // ==========================================================================\n // Mailbox CRUD\n // ==========================================================================\n\n async createMailbox(input: CreateMailboxInput): Promise<Mailbox> {\n const atIndex = input.email.indexOf('@');\n const localPart =\n atIndex >= 0 ? input.email.slice(0, atIndex) : input.email;\n const principal: StalwartPrincipal = {\n name: localPart,\n type: 'individual',\n description: input.name,\n emails: [input.email],\n secrets: [input.password],\n quota: input.quota,\n };\n\n await this.request('POST', '/api/principal', principal);\n return this.getMailbox(localPart);\n }\n\n async getMailbox(id: string): Promise<Mailbox> {\n const principal = await this.request<StalwartPrincipal>(\n 'GET',\n `/api/principal/${encodeURIComponent(id)}`,\n );\n return this.principalToMailbox(principal);\n }\n\n async updateMailbox(id: string, input: UpdateMailboxInput): Promise<Mailbox> {\n const patch: Record<string, unknown> = {};\n if (input.name !== undefined) patch.description = input.name;\n if (input.password !== undefined) patch.secrets = [input.password];\n if (input.quota !== undefined) patch.quota = input.quota;\n\n await this.request(\n 'PATCH',\n `/api/principal/${encodeURIComponent(id)}`,\n patch,\n );\n return this.getMailbox(id);\n }\n\n async deleteMailbox(id: string): Promise<void> {\n await this.request('DELETE', `/api/principal/${encodeURIComponent(id)}`);\n }\n\n async listMailboxes(): Promise<Mailbox[]> {\n const names = await this.request<string[]>(\n 'GET',\n '/api/principal?type=individual',\n );\n const mailboxes = await Promise.all(\n (names ?? []).map((name) => this.getMailbox(name)),\n );\n return mailboxes;\n }\n\n // ==========================================================================\n // Principal Mapping Helpers\n // ==========================================================================\n\n private principalToUser(principal: StalwartPrincipal): DirectoryUser {\n return {\n id: principal.name,\n username: principal.name,\n displayName: principal.description,\n email: principal.emails?.[0],\n active: true,\n groups: principal.memberOf,\n };\n }\n\n private principalToGroup(principal: StalwartPrincipal): DirectoryGroup {\n return {\n id: principal.name,\n name: principal.name,\n displayName: principal.description,\n description: principal.description,\n members: principal.members,\n };\n }\n\n private principalToMailbox(principal: StalwartPrincipal): Mailbox {\n return {\n id: principal.name,\n name: principal.description ?? principal.name,\n email: principal.emails?.[0] ?? '',\n quota: principal.quota,\n active: true,\n };\n }\n}\n","/**\n * Factory functions and type guards for @happyvertical/directory package\n */\n\nimport type {\n AwsDirectoryAdapter,\n AwsOptions,\n DirectoryAdapter,\n GetDirectoryAdapterOptions,\n KanidmDirectoryAdapter,\n KanidmOptions,\n PostgresDirectoryAdapter,\n PostgresOptions,\n StalwartDirectoryAdapter,\n StalwartOptions,\n} from './types.js';\n\n// ============================================================================\n// Type Guards\n// ============================================================================\n\nexport function isKanidmOptions(\n opts: GetDirectoryAdapterOptions,\n): opts is KanidmOptions {\n return opts.type === 'kanidm';\n}\n\nexport function isStalwartOptions(\n opts: GetDirectoryAdapterOptions,\n): opts is StalwartOptions {\n return opts.type === 'stalwart';\n}\n\nexport function isPostgresOptions(\n opts: GetDirectoryAdapterOptions,\n): opts is PostgresOptions {\n return opts.type === 'postgres';\n}\n\nexport function isAwsOptions(\n opts: GetDirectoryAdapterOptions,\n): opts is AwsOptions {\n return opts.type === 'aws';\n}\n\n// ============================================================================\n// Generic Factory\n// ============================================================================\n\n/**\n * Create a directory adapter instance (returns base DirectoryAdapter)\n *\n * @example\n * ```typescript\n * const adapter = await getDirectoryAdapter({\n * type: 'kanidm',\n * baseUrl: 'https://idm.example.com',\n * adminUsername: 'admin',\n * adminPassword: 'secret',\n * });\n * ```\n */\nexport async function getDirectoryAdapter(\n options: GetDirectoryAdapterOptions,\n): Promise<DirectoryAdapter> {\n if (isKanidmOptions(options)) {\n const { KanidmAdapter } = await import('../adapters/kanidm.js');\n return new KanidmAdapter(options);\n }\n\n if (isStalwartOptions(options)) {\n const { StalwartAdapter } = await import('../adapters/stalwart.js');\n return new StalwartAdapter(options);\n }\n\n if (isPostgresOptions(options)) {\n const { PostgresAdapter } = await import('../adapters/postgres.js');\n return new PostgresAdapter(options);\n }\n\n if (isAwsOptions(options)) {\n const { AwsAdapter } = await import('../adapters/aws.js');\n return new AwsAdapter(options);\n }\n\n throw new Error(\n `Unknown directory adapter type: ${(options as { type: string }).type}`,\n );\n}\n\n// ============================================================================\n// Typed Convenience Factories\n// ============================================================================\n\n/**\n * Create a Kanidm directory adapter with full OAuth2 support\n */\nexport async function getKanidmAdapter(\n options: Omit<KanidmOptions, 'type'>,\n): Promise<KanidmDirectoryAdapter> {\n const { KanidmAdapter } = await import('../adapters/kanidm.js');\n return new KanidmAdapter({ type: 'kanidm', ...options } as KanidmOptions);\n}\n\n/**\n * Create a Stalwart directory adapter with domain/mailbox support\n */\nexport async function getStalwartAdapter(\n options: Omit<StalwartOptions, 'type'>,\n): Promise<StalwartDirectoryAdapter> {\n const { StalwartAdapter } = await import('../adapters/stalwart.js');\n return new StalwartAdapter({ type: 'stalwart', ...options });\n}\n\n/**\n * Create a PostgreSQL directory adapter with database/role provisioning\n */\nexport async function getPostgresAdapter(\n options: Omit<PostgresOptions, 'type'>,\n): Promise<PostgresDirectoryAdapter> {\n const { PostgresAdapter } = await import('../adapters/postgres.js');\n return new PostgresAdapter({ type: 'postgres', ...options });\n}\n\n/**\n * Create an AWS directory adapter with Organizations/IAM support\n */\nexport async function getAwsAdapter(\n options: Omit<AwsOptions, 'type'>,\n): Promise<AwsDirectoryAdapter> {\n const { AwsAdapter } = await import('../adapters/aws.js');\n return new AwsAdapter({ type: 'aws', ...options });\n}\n"],"names":["PROVIDER","KanidmAdapter","StalwartAdapter","PostgresAdapter","AwsAdapter"],"mappings":"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"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Error classes for @happyvertical/directory package
|
|
3
|
+
*/
|
|
4
|
+
export declare class DirectoryError extends Error {
|
|
5
|
+
code: string;
|
|
6
|
+
provider?: string;
|
|
7
|
+
cause?: unknown;
|
|
8
|
+
constructor(message: string, code: string, provider?: string, cause?: unknown);
|
|
9
|
+
}
|
|
10
|
+
export declare class ConnectionError extends DirectoryError {
|
|
11
|
+
constructor(message: string, provider?: string, cause?: unknown);
|
|
12
|
+
}
|
|
13
|
+
export declare class AuthenticationError extends DirectoryError {
|
|
14
|
+
constructor(message: string, provider?: string, cause?: unknown);
|
|
15
|
+
}
|
|
16
|
+
export declare class NotFoundError extends DirectoryError {
|
|
17
|
+
resourceType: string;
|
|
18
|
+
resourceId: string;
|
|
19
|
+
constructor(resourceType: string, resourceId: string, provider?: string, cause?: unknown);
|
|
20
|
+
}
|
|
21
|
+
export declare class ConflictError extends DirectoryError {
|
|
22
|
+
resourceType: string;
|
|
23
|
+
resourceId: string;
|
|
24
|
+
constructor(resourceType: string, resourceId: string, provider?: string, cause?: unknown);
|
|
25
|
+
}
|
|
26
|
+
export declare class ValidationError extends DirectoryError {
|
|
27
|
+
constructor(message: string, provider?: string, cause?: unknown);
|
|
28
|
+
}
|
|
29
|
+
export declare class RateLimitError extends DirectoryError {
|
|
30
|
+
retryAfter?: number;
|
|
31
|
+
constructor(provider?: string, retryAfter?: number);
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/shared/errors.ts"],"names":[],"mappings":"AAAA;;GAEG;AAMH,qBAAa,cAAe,SAAQ,KAAK;IACvC,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,OAAO,CAAC;gBAGd,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EACZ,QAAQ,CAAC,EAAE,MAAM,EACjB,KAAK,CAAC,EAAE,OAAO;CAQlB;AAMD,qBAAa,eAAgB,SAAQ,cAAc;gBACrC,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO;CAIhE;AAMD,qBAAa,mBAAoB,SAAQ,cAAc;gBACzC,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO;CAIhE;AAMD,qBAAa,aAAc,SAAQ,cAAc;IAC/C,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;gBAGjB,YAAY,EAAE,MAAM,EACpB,UAAU,EAAE,MAAM,EAClB,QAAQ,CAAC,EAAE,MAAM,EACjB,KAAK,CAAC,EAAE,OAAO;CAYlB;AAMD,qBAAa,aAAc,SAAQ,cAAc;IAC/C,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;gBAGjB,YAAY,EAAE,MAAM,EACpB,UAAU,EAAE,MAAM,EAClB,QAAQ,CAAC,EAAE,MAAM,EACjB,KAAK,CAAC,EAAE,OAAO;CAYlB;AAMD,qBAAa,eAAgB,SAAQ,cAAc;gBACrC,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO;CAIhE;AAMD,qBAAa,cAAe,SAAQ,cAAc;IAChD,UAAU,CAAC,EAAE,MAAM,CAAC;gBAER,QAAQ,CAAC,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM;CASnD"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { AwsDirectoryAdapter, AwsOptions, DirectoryAdapter, GetDirectoryAdapterOptions, KanidmDirectoryAdapter, KanidmOptions, PostgresDirectoryAdapter, PostgresOptions, StalwartDirectoryAdapter, StalwartOptions } from './types.js';
|
|
2
|
+
export declare function isKanidmOptions(opts: GetDirectoryAdapterOptions): opts is KanidmOptions;
|
|
3
|
+
export declare function isStalwartOptions(opts: GetDirectoryAdapterOptions): opts is StalwartOptions;
|
|
4
|
+
export declare function isPostgresOptions(opts: GetDirectoryAdapterOptions): opts is PostgresOptions;
|
|
5
|
+
export declare function isAwsOptions(opts: GetDirectoryAdapterOptions): opts is AwsOptions;
|
|
6
|
+
/**
|
|
7
|
+
* Create a directory adapter instance (returns base DirectoryAdapter)
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```typescript
|
|
11
|
+
* const adapter = await getDirectoryAdapter({
|
|
12
|
+
* type: 'kanidm',
|
|
13
|
+
* baseUrl: 'https://idm.example.com',
|
|
14
|
+
* adminUsername: 'admin',
|
|
15
|
+
* adminPassword: 'secret',
|
|
16
|
+
* });
|
|
17
|
+
* ```
|
|
18
|
+
*/
|
|
19
|
+
export declare function getDirectoryAdapter(options: GetDirectoryAdapterOptions): Promise<DirectoryAdapter>;
|
|
20
|
+
/**
|
|
21
|
+
* Create a Kanidm directory adapter with full OAuth2 support
|
|
22
|
+
*/
|
|
23
|
+
export declare function getKanidmAdapter(options: Omit<KanidmOptions, 'type'>): Promise<KanidmDirectoryAdapter>;
|
|
24
|
+
/**
|
|
25
|
+
* Create a Stalwart directory adapter with domain/mailbox support
|
|
26
|
+
*/
|
|
27
|
+
export declare function getStalwartAdapter(options: Omit<StalwartOptions, 'type'>): Promise<StalwartDirectoryAdapter>;
|
|
28
|
+
/**
|
|
29
|
+
* Create a PostgreSQL directory adapter with database/role provisioning
|
|
30
|
+
*/
|
|
31
|
+
export declare function getPostgresAdapter(options: Omit<PostgresOptions, 'type'>): Promise<PostgresDirectoryAdapter>;
|
|
32
|
+
/**
|
|
33
|
+
* Create an AWS directory adapter with Organizations/IAM support
|
|
34
|
+
*/
|
|
35
|
+
export declare function getAwsAdapter(options: Omit<AwsOptions, 'type'>): Promise<AwsDirectoryAdapter>;
|
|
36
|
+
//# sourceMappingURL=factory.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../../src/shared/factory.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EACV,mBAAmB,EACnB,UAAU,EACV,gBAAgB,EAChB,0BAA0B,EAC1B,sBAAsB,EACtB,aAAa,EACb,wBAAwB,EACxB,eAAe,EACf,wBAAwB,EACxB,eAAe,EAChB,MAAM,YAAY,CAAC;AAMpB,wBAAgB,eAAe,CAC7B,IAAI,EAAE,0BAA0B,GAC/B,IAAI,IAAI,aAAa,CAEvB;AAED,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,0BAA0B,GAC/B,IAAI,IAAI,eAAe,CAEzB;AAED,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,0BAA0B,GAC/B,IAAI,IAAI,eAAe,CAEzB;AAED,wBAAgB,YAAY,CAC1B,IAAI,EAAE,0BAA0B,GAC/B,IAAI,IAAI,UAAU,CAEpB;AAMD;;;;;;;;;;;;GAYG;AACH,wBAAsB,mBAAmB,CACvC,OAAO,EAAE,0BAA0B,GAClC,OAAO,CAAC,gBAAgB,CAAC,CAwB3B;AAMD;;GAEG;AACH,wBAAsB,gBAAgB,CACpC,OAAO,EAAE,IAAI,CAAC,aAAa,EAAE,MAAM,CAAC,GACnC,OAAO,CAAC,sBAAsB,CAAC,CAGjC;AAED;;GAEG;AACH,wBAAsB,kBAAkB,CACtC,OAAO,EAAE,IAAI,CAAC,eAAe,EAAE,MAAM,CAAC,GACrC,OAAO,CAAC,wBAAwB,CAAC,CAGnC;AAED;;GAEG;AACH,wBAAsB,kBAAkB,CACtC,OAAO,EAAE,IAAI,CAAC,eAAe,EAAE,MAAM,CAAC,GACrC,OAAO,CAAC,wBAAwB,CAAC,CAGnC;AAED;;GAEG;AACH,wBAAsB,aAAa,CACjC,OAAO,EAAE,IAAI,CAAC,UAAU,EAAE,MAAM,CAAC,GAChC,OAAO,CAAC,mBAAmB,CAAC,CAG9B"}
|