@happyvertical/directory 0.99.0 → 0.100.0
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/dist/adapters/stalwart.d.ts +6 -1
- package/dist/adapters/stalwart.d.ts.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +74 -14
- package/dist/index.js.map +1 -1
- package/dist/shared/types.d.ts +27 -0
- package/dist/shared/types.d.ts.map +1 -1
- package/package.json +2 -2
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { CreateDkimKeyInput, CreateGroupInput, CreateMailboxInput, CreateMailDomainInput, CreateUserInput, DirectoryGroup, DirectoryUser, DkimKey, DnsRecord, Mailbox, MailDomain, StalwartDirectoryAdapter, StalwartOptions, UpdateGroupInput, UpdateMailboxInput, UpdateUserInput } from '../shared/types.js';
|
|
1
|
+
import { CreateDkimKeyInput, CreateGroupInput, CreateMailboxInput, CreateMailDomainInput, CreateUserInput, DirectoryGroup, DirectoryUser, DkimKey, DnsRecord, EnsureMailboxInput, EnsureMailboxResult, Mailbox, MailDomain, StalwartDirectoryAdapter, StalwartOptions, UpdateGroupInput, UpdateMailboxInput, UpdateUserInput } from '../shared/types.js';
|
|
2
2
|
export declare class StalwartAdapter implements StalwartDirectoryAdapter {
|
|
3
3
|
private readonly options;
|
|
4
4
|
private readonly authHeader;
|
|
@@ -29,11 +29,16 @@ export declare class StalwartAdapter implements StalwartDirectoryAdapter {
|
|
|
29
29
|
getDnsRecords(domain: string): Promise<DnsRecord[]>;
|
|
30
30
|
createMailbox(input: CreateMailboxInput): Promise<Mailbox>;
|
|
31
31
|
getMailbox(id: string): Promise<Mailbox>;
|
|
32
|
+
findMailboxByEmail(email: string): Promise<Mailbox | null>;
|
|
33
|
+
ensureMailbox(input: EnsureMailboxInput): Promise<EnsureMailboxResult>;
|
|
34
|
+
private createMailboxWithPrincipalId;
|
|
32
35
|
updateMailbox(id: string, input: UpdateMailboxInput): Promise<Mailbox>;
|
|
33
36
|
deleteMailbox(id: string): Promise<void>;
|
|
34
37
|
listMailboxes(): Promise<Mailbox[]>;
|
|
38
|
+
private listPrincipalNames;
|
|
35
39
|
private principalToUser;
|
|
36
40
|
private principalToGroup;
|
|
41
|
+
private assertMailboxEmail;
|
|
37
42
|
private principalToMailbox;
|
|
38
43
|
}
|
|
39
44
|
//# sourceMappingURL=stalwart.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stalwart.d.ts","sourceRoot":"","sources":["../../src/adapters/stalwart.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;
|
|
1
|
+
{"version":3,"file":"stalwart.d.ts","sourceRoot":"","sources":["../../src/adapters/stalwart.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -10,5 +10,5 @@ export { PostgresAdapter } from './adapters/postgres.js';
|
|
|
10
10
|
export { StalwartAdapter } from './adapters/stalwart.js';
|
|
11
11
|
export { AuthenticationError, ConflictError, ConnectionError, DirectoryError, NotFoundError, RateLimitError, ValidationError, } from './shared/errors.js';
|
|
12
12
|
export { getAwsAdapter, getDirectoryAdapter, getKanidmAdapter, getPostgresAdapter, getStalwartAdapter, isAwsOptions, isKanidmOptions, isPostgresOptions, isStalwartOptions, } from './shared/factory.js';
|
|
13
|
-
export type { AwsAccessKey, AwsAccount, AwsAccountCreationStatus, AwsAccountCreationWaitOptions, AwsAccountParent, AwsAssumeRoleInput, AwsDirectoryAdapter, AwsIamRole, AwsIamUser, AwsOptions, AwsOrganizationalUnit, AwsTemporaryCredentials, CreateAwsAccountInput, CreateAwsIamUserInput, CreateAwsOuInput, CreateDkimKeyInput, CreateGroupInput, CreateMailboxInput, CreateMailDomainInput, CreateOAuth2ClientInput, CreatePgDatabaseInput, CreatePgRoleInput, CreateUserInput, CredentialResetIntent, DirectoryAdapter, DirectoryAdapterType, DirectoryGroup, DirectoryOrchestrator, DirectoryUser, DkimKey, DnsRecord, EnsureAwsAccountInput, EnsureAwsIamRoleInput, EnsureAwsOuInput, GetDirectoryAdapterOptions, KanidmDirectoryAdapter, KanidmOptions, Mailbox, MailDomain, OAuth2Client, PgDatabase, PgRole, PostgresDirectoryAdapter, PostgresOptions, PutAwsIamRolePolicyInput, StalwartDirectoryAdapter, StalwartOptions, TenantProvisioningInput, TenantProvisioningResult, UpdateGroupInput, UpdateMailboxInput, UpdateOAuth2ClientInput, UpdateUserInput, } from './shared/types.js';
|
|
13
|
+
export type { AwsAccessKey, AwsAccount, AwsAccountCreationStatus, AwsAccountCreationWaitOptions, AwsAccountParent, AwsAssumeRoleInput, AwsDirectoryAdapter, AwsIamRole, AwsIamUser, AwsOptions, AwsOrganizationalUnit, AwsTemporaryCredentials, CreateAwsAccountInput, CreateAwsIamUserInput, CreateAwsOuInput, CreateDkimKeyInput, CreateGroupInput, CreateMailboxInput, CreateMailDomainInput, CreateOAuth2ClientInput, CreatePgDatabaseInput, CreatePgRoleInput, CreateUserInput, CredentialResetIntent, DirectoryAdapter, DirectoryAdapterType, DirectoryGroup, DirectoryOrchestrator, DirectoryUser, DkimKey, DnsRecord, EnsureAwsAccountInput, EnsureAwsIamRoleInput, EnsureAwsOuInput, EnsureMailboxInput, EnsureMailboxResult, GetDirectoryAdapterOptions, KanidmDirectoryAdapter, KanidmOptions, Mailbox, MailDomain, OAuth2Client, PgDatabase, PgRole, PostgresDirectoryAdapter, PostgresOptions, PutAwsIamRolePolicyInput, StalwartDirectoryAdapter, StalwartOptions, TenantProvisioningInput, TenantProvisioningResult, UpdateGroupInput, UpdateMailboxInput, UpdateOAuth2ClientInput, UpdateUserInput, } from './shared/types.js';
|
|
14
14
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAGzD,OAAO,EACL,mBAAmB,EACnB,aAAa,EACb,eAAe,EACf,cAAc,EACd,aAAa,EACb,cAAc,EACd,eAAe,GAChB,MAAM,oBAAoB,CAAC;AAG5B,OAAO,EACL,aAAa,EACb,mBAAmB,EACnB,gBAAgB,EAChB,kBAAkB,EAClB,kBAAkB,EAClB,YAAY,EACZ,eAAe,EACf,iBAAiB,EACjB,iBAAiB,GAClB,MAAM,qBAAqB,CAAC;AAG7B,YAAY,EACV,YAAY,EACZ,UAAU,EACV,wBAAwB,EACxB,6BAA6B,EAC7B,gBAAgB,EAChB,kBAAkB,EAClB,mBAAmB,EACnB,UAAU,EACV,UAAU,EACV,UAAU,EACV,qBAAqB,EACrB,uBAAuB,EACvB,qBAAqB,EACrB,qBAAqB,EACrB,gBAAgB,EAChB,kBAAkB,EAClB,gBAAgB,EAChB,kBAAkB,EAClB,qBAAqB,EACrB,uBAAuB,EACvB,qBAAqB,EACrB,iBAAiB,EACjB,eAAe,EACf,qBAAqB,EACrB,gBAAgB,EAChB,oBAAoB,EACpB,cAAc,EACd,qBAAqB,EACrB,aAAa,EACb,OAAO,EACP,SAAS,EACT,qBAAqB,EACrB,qBAAqB,EACrB,gBAAgB,EAChB,0BAA0B,EAC1B,sBAAsB,EACtB,aAAa,EACb,OAAO,EACP,UAAU,EACV,YAAY,EACZ,UAAU,EACV,MAAM,EACN,wBAAwB,EACxB,eAAe,EACf,wBAAwB,EACxB,wBAAwB,EACxB,eAAe,EACf,uBAAuB,EACvB,wBAAwB,EACxB,gBAAgB,EAChB,kBAAkB,EAClB,uBAAuB,EACvB,eAAe,GAChB,MAAM,mBAAmB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAGzD,OAAO,EACL,mBAAmB,EACnB,aAAa,EACb,eAAe,EACf,cAAc,EACd,aAAa,EACb,cAAc,EACd,eAAe,GAChB,MAAM,oBAAoB,CAAC;AAG5B,OAAO,EACL,aAAa,EACb,mBAAmB,EACnB,gBAAgB,EAChB,kBAAkB,EAClB,kBAAkB,EAClB,YAAY,EACZ,eAAe,EACf,iBAAiB,EACjB,iBAAiB,GAClB,MAAM,qBAAqB,CAAC;AAG7B,YAAY,EACV,YAAY,EACZ,UAAU,EACV,wBAAwB,EACxB,6BAA6B,EAC7B,gBAAgB,EAChB,kBAAkB,EAClB,mBAAmB,EACnB,UAAU,EACV,UAAU,EACV,UAAU,EACV,qBAAqB,EACrB,uBAAuB,EACvB,qBAAqB,EACrB,qBAAqB,EACrB,gBAAgB,EAChB,kBAAkB,EAClB,gBAAgB,EAChB,kBAAkB,EAClB,qBAAqB,EACrB,uBAAuB,EACvB,qBAAqB,EACrB,iBAAiB,EACjB,eAAe,EACf,qBAAqB,EACrB,gBAAgB,EAChB,oBAAoB,EACpB,cAAc,EACd,qBAAqB,EACrB,aAAa,EACb,OAAO,EACP,SAAS,EACT,qBAAqB,EACrB,qBAAqB,EACrB,gBAAgB,EAChB,kBAAkB,EAClB,mBAAmB,EACnB,0BAA0B,EAC1B,sBAAsB,EACtB,aAAa,EACb,OAAO,EACP,UAAU,EACV,YAAY,EACZ,UAAU,EACV,MAAM,EACN,wBAAwB,EACxB,eAAe,EACf,wBAAwB,EACxB,wBAAwB,EACxB,eAAe,EACf,uBAAuB,EACvB,wBAAwB,EACxB,gBAAgB,EAChB,kBAAkB,EAClB,uBAAuB,EACvB,eAAe,GAChB,MAAM,mBAAmB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1331,7 +1331,9 @@ var StalwartAdapter = class {
|
|
|
1331
1331
|
const text = await response.text();
|
|
1332
1332
|
if (!text) return void 0;
|
|
1333
1333
|
try {
|
|
1334
|
-
|
|
1334
|
+
const parsed = JSON.parse(text);
|
|
1335
|
+
if (parsed && typeof parsed === "object" && !Array.isArray(parsed) && "data" in parsed) return parsed.data;
|
|
1336
|
+
return parsed;
|
|
1335
1337
|
} catch {
|
|
1336
1338
|
return text;
|
|
1337
1339
|
}
|
|
@@ -1347,7 +1349,7 @@ var StalwartAdapter = class {
|
|
|
1347
1349
|
}
|
|
1348
1350
|
async testConnection() {
|
|
1349
1351
|
try {
|
|
1350
|
-
await this.request("GET", "/api/principal?
|
|
1352
|
+
await this.request("GET", "/api/principal?types=individual&limit=1");
|
|
1351
1353
|
return true;
|
|
1352
1354
|
} catch (error) {
|
|
1353
1355
|
if (error instanceof AuthenticationError) throw error;
|
|
@@ -1382,7 +1384,7 @@ var StalwartAdapter = class {
|
|
|
1382
1384
|
await this.request("DELETE", `/api/principal/${encodeURIComponent(id)}`);
|
|
1383
1385
|
}
|
|
1384
1386
|
async listUsers() {
|
|
1385
|
-
const names = await this.
|
|
1387
|
+
const names = await this.listPrincipalNames("individual");
|
|
1386
1388
|
return await Promise.all((names ?? []).map((name) => this.getUser(name)));
|
|
1387
1389
|
}
|
|
1388
1390
|
async createGroup(input) {
|
|
@@ -1410,7 +1412,7 @@ var StalwartAdapter = class {
|
|
|
1410
1412
|
await this.request("DELETE", `/api/principal/${encodeURIComponent(id)}`);
|
|
1411
1413
|
}
|
|
1412
1414
|
async listGroups() {
|
|
1413
|
-
const names = await this.
|
|
1415
|
+
const names = await this.listPrincipalNames("group");
|
|
1414
1416
|
return await Promise.all((names ?? []).map((name) => this.getGroup(name)));
|
|
1415
1417
|
}
|
|
1416
1418
|
async addUserToGroup(userId, groupId) {
|
|
@@ -1450,7 +1452,7 @@ var StalwartAdapter = class {
|
|
|
1450
1452
|
await this.request("DELETE", `/api/principal/${encodeURIComponent(id)}`);
|
|
1451
1453
|
}
|
|
1452
1454
|
async listDomains() {
|
|
1453
|
-
const names = await this.
|
|
1455
|
+
const names = await this.listPrincipalNames("domain");
|
|
1454
1456
|
return await Promise.all((names ?? []).map((name) => this.getDomain(name)));
|
|
1455
1457
|
}
|
|
1456
1458
|
async createDkimKey(input) {
|
|
@@ -1471,8 +1473,44 @@ var StalwartAdapter = class {
|
|
|
1471
1473
|
async createMailbox(input) {
|
|
1472
1474
|
const atIndex = input.email.indexOf("@");
|
|
1473
1475
|
const localPart = atIndex >= 0 ? input.email.slice(0, atIndex) : input.email;
|
|
1476
|
+
return this.createMailboxWithPrincipalId(input, localPart);
|
|
1477
|
+
}
|
|
1478
|
+
async getMailbox(id) {
|
|
1479
|
+
const principal = await this.request("GET", `/api/principal/${encodeURIComponent(id)}`);
|
|
1480
|
+
return this.principalToMailbox(principal);
|
|
1481
|
+
}
|
|
1482
|
+
async findMailboxByEmail(email) {
|
|
1483
|
+
this.assertMailboxEmail(email);
|
|
1484
|
+
const names = await this.listPrincipalNames("individual");
|
|
1485
|
+
const principal = (await Promise.all((names ?? []).map((name) => this.request("GET", `/api/principal/${encodeURIComponent(name)}`)))).find((entry) => entry.emails?.includes(email));
|
|
1486
|
+
return principal ? this.principalToMailbox(principal, email) : null;
|
|
1487
|
+
}
|
|
1488
|
+
async ensureMailbox(input) {
|
|
1489
|
+
this.assertMailboxEmail(input.email);
|
|
1490
|
+
if (!input.principalId.trim()) throw new ValidationError("Mailbox principalId must not be empty", PROVIDER);
|
|
1491
|
+
const existing = await this.findMailboxByEmail(input.email);
|
|
1492
|
+
if (existing) return {
|
|
1493
|
+
mailbox: existing,
|
|
1494
|
+
created: false
|
|
1495
|
+
};
|
|
1496
|
+
try {
|
|
1497
|
+
return {
|
|
1498
|
+
mailbox: await this.createMailboxWithPrincipalId(input, input.principalId),
|
|
1499
|
+
created: true
|
|
1500
|
+
};
|
|
1501
|
+
} catch (error) {
|
|
1502
|
+
if (!(error instanceof ConflictError)) throw error;
|
|
1503
|
+
const concurrentlyCreated = await this.findMailboxByEmail(input.email);
|
|
1504
|
+
if (concurrentlyCreated) return {
|
|
1505
|
+
mailbox: concurrentlyCreated,
|
|
1506
|
+
created: false
|
|
1507
|
+
};
|
|
1508
|
+
throw new ConflictError("mailbox principal", input.principalId, PROVIDER);
|
|
1509
|
+
}
|
|
1510
|
+
}
|
|
1511
|
+
async createMailboxWithPrincipalId(input, principalId) {
|
|
1474
1512
|
const principal = {
|
|
1475
|
-
name:
|
|
1513
|
+
name: principalId,
|
|
1476
1514
|
type: "individual",
|
|
1477
1515
|
description: input.name,
|
|
1478
1516
|
emails: [input.email],
|
|
@@ -1480,11 +1518,7 @@ var StalwartAdapter = class {
|
|
|
1480
1518
|
quota: input.quota
|
|
1481
1519
|
};
|
|
1482
1520
|
await this.request("POST", "/api/principal", principal);
|
|
1483
|
-
return this.getMailbox(
|
|
1484
|
-
}
|
|
1485
|
-
async getMailbox(id) {
|
|
1486
|
-
const principal = await this.request("GET", `/api/principal/${encodeURIComponent(id)}`);
|
|
1487
|
-
return this.principalToMailbox(principal);
|
|
1521
|
+
return this.getMailbox(principalId);
|
|
1488
1522
|
}
|
|
1489
1523
|
async updateMailbox(id, input) {
|
|
1490
1524
|
const patch = {};
|
|
@@ -1498,9 +1532,31 @@ var StalwartAdapter = class {
|
|
|
1498
1532
|
await this.request("DELETE", `/api/principal/${encodeURIComponent(id)}`);
|
|
1499
1533
|
}
|
|
1500
1534
|
async listMailboxes() {
|
|
1501
|
-
const names = await this.
|
|
1535
|
+
const names = await this.listPrincipalNames("individual");
|
|
1502
1536
|
return await Promise.all((names ?? []).map((name) => this.getMailbox(name)));
|
|
1503
1537
|
}
|
|
1538
|
+
async listPrincipalNames(type) {
|
|
1539
|
+
const names = [];
|
|
1540
|
+
let page = 1;
|
|
1541
|
+
let fetched = 0;
|
|
1542
|
+
let total = 0;
|
|
1543
|
+
do {
|
|
1544
|
+
const result = await this.request("GET", `/api/principal?types=${encodeURIComponent(type)}&page=${page}&limit=100`);
|
|
1545
|
+
if (Array.isArray(result)) return result;
|
|
1546
|
+
const items = result?.items;
|
|
1547
|
+
if (!Array.isArray(items)) throw new DirectoryError("Stalwart principal list response did not include an items array", "INVALID_API_RESPONSE", PROVIDER);
|
|
1548
|
+
const declaredTotal = result.total;
|
|
1549
|
+
if (typeof declaredTotal !== "number" || !Number.isSafeInteger(declaredTotal) || declaredTotal < 0) throw new DirectoryError("Stalwart principal list response did not include a valid total", "INVALID_API_RESPONSE", PROVIDER);
|
|
1550
|
+
if (items.some((principal) => principal.type !== type || typeof principal.name !== "string" || !principal.name)) throw new DirectoryError("Stalwart principal list response included an invalid principal", "INVALID_API_RESPONSE", PROVIDER);
|
|
1551
|
+
if (items.length === 0 && fetched < declaredTotal) throw new DirectoryError("Stalwart principal list pagination ended before the reported total", "INVALID_API_RESPONSE", PROVIDER);
|
|
1552
|
+
names.push(...items.map((principal) => principal.name));
|
|
1553
|
+
fetched += items.length;
|
|
1554
|
+
total = declaredTotal;
|
|
1555
|
+
if (fetched > total) throw new DirectoryError("Stalwart principal list response exceeded the reported total", "INVALID_API_RESPONSE", PROVIDER);
|
|
1556
|
+
page += 1;
|
|
1557
|
+
} while (fetched < total);
|
|
1558
|
+
return names;
|
|
1559
|
+
}
|
|
1504
1560
|
principalToUser(principal) {
|
|
1505
1561
|
return {
|
|
1506
1562
|
id: principal.name,
|
|
@@ -1520,11 +1576,15 @@ var StalwartAdapter = class {
|
|
|
1520
1576
|
members: principal.members
|
|
1521
1577
|
};
|
|
1522
1578
|
}
|
|
1523
|
-
|
|
1579
|
+
assertMailboxEmail(email) {
|
|
1580
|
+
const atIndex = email.indexOf("@");
|
|
1581
|
+
if (atIndex <= 0 || atIndex !== email.lastIndexOf("@") || atIndex === email.length - 1 || /\s/.test(email)) throw new ValidationError(`Invalid mailbox email address: ${email}`, PROVIDER);
|
|
1582
|
+
}
|
|
1583
|
+
principalToMailbox(principal, matchedEmail) {
|
|
1524
1584
|
return {
|
|
1525
1585
|
id: principal.name,
|
|
1526
1586
|
name: principal.description ?? principal.name,
|
|
1527
|
-
email: principal.emails?.[0] ?? "",
|
|
1587
|
+
email: matchedEmail ?? principal.emails?.[0] ?? "",
|
|
1528
1588
|
quota: principal.quota,
|
|
1529
1589
|
active: true
|
|
1530
1590
|
};
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../src/adapters/aws.ts","../src/adapters/kanidm.ts","../src/adapters/postgres.ts","../src/adapters/stalwart.ts","../src/shared/factory.ts"],"sourcesContent":["/**\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 CreateRoleCommand,\n CreateUserCommand,\n DeleteAccessKeyCommand,\n DeleteGroupCommand,\n DeleteUserCommand,\n DetachUserPolicyCommand,\n GetGroupCommand,\n GetRoleCommand,\n GetUserCommand,\n IAMClient,\n ListGroupsCommand,\n ListGroupsForUserCommand,\n ListUsersCommand,\n PutRolePolicyCommand,\n RemoveUserFromGroupCommand,\n TagRoleCommand,\n UpdateAssumeRolePolicyCommand,\n UpdateRoleCommand,\n UpdateUserCommand,\n} from '@aws-sdk/client-iam';\nimport {\n CreateAccountCommand,\n CreateOrganizationalUnitCommand,\n DescribeCreateAccountStatusCommand,\n DescribeOrganizationalUnitCommand,\n ListAccountsCommand,\n ListOrganizationalUnitsForParentCommand,\n ListParentsCommand,\n MoveAccountCommand,\n OrganizationsClient,\n TagResourceCommand,\n} from '@aws-sdk/client-organizations';\nimport { AssumeRoleCommand, STSClient } from '@aws-sdk/client-sts';\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 AwsAccountCreationWaitOptions,\n AwsAccountParent,\n AwsAssumeRoleInput,\n AwsDirectoryAdapter,\n AwsIamRole,\n AwsIamUser,\n AwsOptions,\n AwsOrganizationalUnit,\n AwsTemporaryCredentials,\n CreateAwsAccountInput,\n CreateAwsIamUserInput,\n CreateAwsOuInput,\n CreateGroupInput,\n CreateUserInput,\n DirectoryGroup,\n DirectoryUser,\n EnsureAwsAccountInput,\n EnsureAwsIamRoleInput,\n EnsureAwsOuInput,\n PutAwsIamRolePolicyInput,\n UpdateGroupInput,\n UpdateUserInput,\n} from '../shared/types.js';\n\nconst DEFAULT_ACCOUNT_CREATION_TIMEOUT_MS = 10 * 60 * 1000;\nconst DEFAULT_ACCOUNT_CREATION_POLL_INTERVAL_MS = 5 * 1000;\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\nfunction mapAwsAccount(account: {\n Id?: string;\n Name?: string;\n Email?: string;\n Arn?: string;\n Status?: string;\n State?: string;\n}): AwsAccount {\n return {\n id: account.Id ?? '',\n name: account.Name ?? '',\n email: account.Email ?? '',\n arn: account.Arn,\n status: account.Status ? String(account.Status) : undefined,\n };\n}\n\nfunction mapAwsIamRole(role: {\n RoleName?: string;\n Arn?: string;\n RoleId?: string;\n Path?: string;\n CreateDate?: Date;\n AssumeRolePolicyDocument?: string;\n}): AwsIamRole {\n return {\n roleName: role.RoleName ?? '',\n arn: role.Arn,\n roleId: role.RoleId,\n path: role.Path,\n createDate: role.CreateDate,\n assumeRolePolicyDocument: role.AssumeRolePolicyDocument,\n };\n}\n\nfunction toAwsTags(\n tags?: Record<string, string>,\n): { Key: string; Value: string }[] | undefined {\n const entries = Object.entries(tags ?? {}).filter(([key]) => key.length > 0);\n\n if (entries.length === 0) {\n return undefined;\n }\n\n return entries.map(([Key, Value]) => ({ Key, Value }));\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\n// ============================================================================\n// Adapter Implementation\n// ============================================================================\n\nexport class AwsAdapter implements AwsDirectoryAdapter {\n private readonly orgs: OrganizationsClient;\n private readonly iam: IAMClient;\n private readonly sts: STSClient;\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 this.sts = new STSClient(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 Tags: toAwsTags(input.tags),\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 organizationalUnits: AwsOrganizationalUnit[] = [];\n let nextToken: string | undefined;\n\n do {\n const result = await this.orgs.send(\n new ListOrganizationalUnitsForParentCommand({\n ParentId: parentId,\n NextToken: nextToken,\n }),\n );\n\n organizationalUnits.push(\n ...(result.OrganizationalUnits ?? []).map((ou) => ({\n id: ou.Id ?? '',\n name: ou.Name ?? '',\n arn: ou.Arn,\n parentId,\n })),\n );\n nextToken = result.NextToken;\n } while (nextToken);\n\n return organizationalUnits;\n } catch (error) {\n handleAwsError(error, `listOrganizationalUnits(${parentId})`);\n }\n }\n\n async findOrganizationalUnitByName(\n parentId: string,\n name: string,\n ): Promise<AwsOrganizationalUnit | null> {\n const organizationalUnits = await this.listOrganizationalUnits(parentId);\n return organizationalUnits.find((ou) => ou.name === name) ?? null;\n }\n\n async ensureOrganizationalUnit(\n input: EnsureAwsOuInput,\n ): Promise<AwsOrganizationalUnit> {\n const existing = await this.findOrganizationalUnitByName(\n input.parentId,\n input.name,\n );\n\n if (existing) {\n if (input.tags) {\n await this.tagAwsOrganizationsResource(existing.id, input.tags);\n }\n return existing;\n }\n\n return this.createOrganizationalUnit(input);\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 Tags: toAwsTags(input.tags),\n }),\n );\n\n const status = result.CreateAccountStatus;\n if (!status?.Id) {\n throw new DirectoryError(\n `createAccount(${input.name}) did not return a create account request id`,\n 'AWS_ACCOUNT_CREATION_REQUEST_ID_MISSING',\n 'aws',\n );\n }\n\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 accounts: AwsAccount[] = [];\n let nextToken: string | undefined;\n\n do {\n const result = await this.orgs.send(\n new ListAccountsCommand({ NextToken: nextToken }),\n );\n accounts.push(...(result.Accounts ?? []).map((a) => mapAwsAccount(a)));\n nextToken = result.NextToken;\n } while (nextToken);\n\n return accounts;\n } catch (error) {\n handleAwsError(error, 'listAccounts');\n }\n }\n\n async findAccountByEmail(email: string): Promise<AwsAccount | null> {\n const accounts = await this.listAccounts();\n return (\n accounts.find(\n (account) => account.email.toLowerCase() === email.toLowerCase(),\n ) ?? null\n );\n }\n\n async ensureAccount(input: EnsureAwsAccountInput): Promise<AwsAccount> {\n const existing = await this.findAccountByEmail(input.email);\n if (existing) {\n if (input.tags) {\n await this.tagAwsOrganizationsResource(existing.id, input.tags);\n }\n return existing;\n }\n\n const createStatus = await this.createAccount(input);\n const finalStatus = await this.waitForAccountCreation(\n createStatus.id,\n input.wait,\n );\n\n if (finalStatus.state !== 'SUCCEEDED' || !finalStatus.accountId) {\n throw new DirectoryError(\n `ensureAccount(${input.email}) failed: ${finalStatus.failureReason ?? finalStatus.state}`,\n 'AWS_ACCOUNT_CREATION_FAILED',\n 'aws',\n );\n }\n\n const created = await this.findAccountByEmail(input.email);\n if (created) {\n return created;\n }\n\n return {\n id: finalStatus.accountId,\n name: input.name,\n email: input.email,\n status: 'ACTIVE',\n };\n }\n\n async waitForAccountCreation(\n id: string,\n options: AwsAccountCreationWaitOptions = {},\n ): Promise<AwsAccountCreationStatus> {\n const timeoutMs = options.timeoutMs ?? DEFAULT_ACCOUNT_CREATION_TIMEOUT_MS;\n const pollIntervalMs =\n options.pollIntervalMs ?? DEFAULT_ACCOUNT_CREATION_POLL_INTERVAL_MS;\n const startedAt = Date.now();\n\n while (true) {\n const status = await this.getAccountCreationStatus(id);\n if (status.state !== 'IN_PROGRESS') {\n return status;\n }\n\n if (Date.now() - startedAt >= timeoutMs) {\n throw new DirectoryError(\n `waitForAccountCreation(${id}) timed out after ${timeoutMs}ms`,\n 'AWS_ACCOUNT_CREATION_TIMEOUT',\n 'aws',\n );\n }\n\n await sleep(pollIntervalMs);\n }\n }\n\n async getAccountParent(accountId: string): Promise<AwsAccountParent | null> {\n try {\n const result = await this.orgs.send(\n new ListParentsCommand({ ChildId: accountId }),\n );\n const parent = result.Parents?.[0];\n if (!parent?.Id) {\n return null;\n }\n\n return {\n id: parent.Id,\n type: parent.Type ? String(parent.Type) : '',\n };\n } catch (error) {\n handleAwsError(error, `getAccountParent(${accountId})`);\n }\n }\n\n async ensureAccountInOrganizationalUnit(\n accountId: string,\n destinationParentId: string,\n ): Promise<void> {\n const currentParent = await this.getAccountParent(accountId);\n if (currentParent?.id === destinationParentId) {\n return;\n }\n\n if (!currentParent?.id) {\n throw new DirectoryError(\n `ensureAccountInOrganizationalUnit(${accountId}) could not determine the current account parent`,\n 'AWS_ACCOUNT_PARENT_MISSING',\n 'aws',\n );\n }\n\n await this.moveAccount(accountId, currentParent.id, destinationParentId);\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 async tagAwsOrganizationsResource(\n resourceId: string,\n tags: Record<string, string>,\n ): Promise<void> {\n const awsTags = toAwsTags(tags);\n if (!awsTags) {\n return;\n }\n\n try {\n await this.orgs.send(\n new TagResourceCommand({\n ResourceId: resourceId,\n Tags: awsTags,\n }),\n );\n } catch (error) {\n handleAwsError(error, `tagAwsOrganizationsResource(${resourceId})`);\n }\n }\n\n // ==========================================================================\n // STS (AwsDirectoryAdapter)\n // ==========================================================================\n\n async assumeAwsRole(\n input: AwsAssumeRoleInput,\n ): Promise<AwsTemporaryCredentials> {\n try {\n const result = await this.sts.send(\n new AssumeRoleCommand({\n RoleArn: input.roleArn,\n RoleSessionName: input.sessionName,\n ...(input.externalId ? { ExternalId: input.externalId } : {}),\n ...(input.durationSeconds\n ? { DurationSeconds: input.durationSeconds }\n : {}),\n }),\n );\n const credentials = result.Credentials;\n\n if (\n !credentials?.AccessKeyId ||\n !credentials.SecretAccessKey ||\n !credentials.SessionToken\n ) {\n throw new DirectoryError(\n `assumeAwsRole(${input.roleArn}) returned incomplete credentials`,\n 'AWS_ASSUME_ROLE_INCOMPLETE_CREDENTIALS',\n 'aws',\n );\n }\n\n return {\n accessKeyId: credentials.AccessKeyId,\n secretAccessKey: credentials.SecretAccessKey,\n sessionToken: credentials.SessionToken,\n expiration: credentials.Expiration,\n assumedRoleArn: result.AssumedRoleUser?.Arn,\n assumedRoleId: result.AssumedRoleUser?.AssumedRoleId,\n };\n } catch (error) {\n handleAwsError(error, `assumeAwsRole(${input.roleArn})`);\n }\n }\n\n // ==========================================================================\n // IAM Roles (AwsDirectoryAdapter)\n // ==========================================================================\n\n async getIamRole(roleName: string): Promise<AwsIamRole> {\n try {\n const result = await this.iam.send(\n new GetRoleCommand({ RoleName: roleName }),\n );\n return mapAwsIamRole(result.Role ?? {});\n } catch (error) {\n handleAwsError(error, `getIamRole(${roleName})`);\n }\n }\n\n async ensureIamRole(input: EnsureAwsIamRoleInput): Promise<AwsIamRole> {\n try {\n await this.getIamRole(input.roleName);\n await this.iam.send(\n new UpdateAssumeRolePolicyCommand({\n RoleName: input.roleName,\n PolicyDocument: input.assumeRolePolicyDocument,\n }),\n );\n\n if (input.description !== undefined) {\n await this.iam.send(\n new UpdateRoleCommand({\n RoleName: input.roleName,\n Description: input.description,\n }),\n );\n }\n\n const tags = toAwsTags(input.tags);\n if (tags) {\n await this.iam.send(\n new TagRoleCommand({\n RoleName: input.roleName,\n Tags: tags,\n }),\n );\n }\n\n return this.getIamRole(input.roleName);\n } catch (error) {\n if (!(error instanceof NotFoundError)) {\n throw error;\n }\n }\n\n try {\n const result = await this.iam.send(\n new CreateRoleCommand({\n RoleName: input.roleName,\n AssumeRolePolicyDocument: input.assumeRolePolicyDocument,\n ...(input.description ? { Description: input.description } : {}),\n ...(input.path ? { Path: input.path } : {}),\n Tags: toAwsTags(input.tags),\n }),\n );\n return mapAwsIamRole(result.Role ?? {});\n } catch (error) {\n handleAwsError(error, `ensureIamRole(${input.roleName})`);\n }\n }\n\n async putIamRolePolicy(input: PutAwsIamRolePolicyInput): Promise<void> {\n try {\n await this.iam.send(\n new PutRolePolicyCommand({\n RoleName: input.roleName,\n PolicyName: input.policyName,\n PolicyDocument: input.policyDocument,\n }),\n );\n } catch (error) {\n handleAwsError(error, `putIamRolePolicy(${input.roleName})`);\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"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../src/adapters/aws.ts","../src/adapters/kanidm.ts","../src/adapters/postgres.ts","../src/adapters/stalwart.ts","../src/shared/factory.ts"],"sourcesContent":["/**\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 CreateRoleCommand,\n CreateUserCommand,\n DeleteAccessKeyCommand,\n DeleteGroupCommand,\n DeleteUserCommand,\n DetachUserPolicyCommand,\n GetGroupCommand,\n GetRoleCommand,\n GetUserCommand,\n IAMClient,\n ListGroupsCommand,\n ListGroupsForUserCommand,\n ListUsersCommand,\n PutRolePolicyCommand,\n RemoveUserFromGroupCommand,\n TagRoleCommand,\n UpdateAssumeRolePolicyCommand,\n UpdateRoleCommand,\n UpdateUserCommand,\n} from '@aws-sdk/client-iam';\nimport {\n CreateAccountCommand,\n CreateOrganizationalUnitCommand,\n DescribeCreateAccountStatusCommand,\n DescribeOrganizationalUnitCommand,\n ListAccountsCommand,\n ListOrganizationalUnitsForParentCommand,\n ListParentsCommand,\n MoveAccountCommand,\n OrganizationsClient,\n TagResourceCommand,\n} from '@aws-sdk/client-organizations';\nimport { AssumeRoleCommand, STSClient } from '@aws-sdk/client-sts';\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 AwsAccountCreationWaitOptions,\n AwsAccountParent,\n AwsAssumeRoleInput,\n AwsDirectoryAdapter,\n AwsIamRole,\n AwsIamUser,\n AwsOptions,\n AwsOrganizationalUnit,\n AwsTemporaryCredentials,\n CreateAwsAccountInput,\n CreateAwsIamUserInput,\n CreateAwsOuInput,\n CreateGroupInput,\n CreateUserInput,\n DirectoryGroup,\n DirectoryUser,\n EnsureAwsAccountInput,\n EnsureAwsIamRoleInput,\n EnsureAwsOuInput,\n PutAwsIamRolePolicyInput,\n UpdateGroupInput,\n UpdateUserInput,\n} from '../shared/types.js';\n\nconst DEFAULT_ACCOUNT_CREATION_TIMEOUT_MS = 10 * 60 * 1000;\nconst DEFAULT_ACCOUNT_CREATION_POLL_INTERVAL_MS = 5 * 1000;\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\nfunction mapAwsAccount(account: {\n Id?: string;\n Name?: string;\n Email?: string;\n Arn?: string;\n Status?: string;\n State?: string;\n}): AwsAccount {\n return {\n id: account.Id ?? '',\n name: account.Name ?? '',\n email: account.Email ?? '',\n arn: account.Arn,\n status: account.Status ? String(account.Status) : undefined,\n };\n}\n\nfunction mapAwsIamRole(role: {\n RoleName?: string;\n Arn?: string;\n RoleId?: string;\n Path?: string;\n CreateDate?: Date;\n AssumeRolePolicyDocument?: string;\n}): AwsIamRole {\n return {\n roleName: role.RoleName ?? '',\n arn: role.Arn,\n roleId: role.RoleId,\n path: role.Path,\n createDate: role.CreateDate,\n assumeRolePolicyDocument: role.AssumeRolePolicyDocument,\n };\n}\n\nfunction toAwsTags(\n tags?: Record<string, string>,\n): { Key: string; Value: string }[] | undefined {\n const entries = Object.entries(tags ?? {}).filter(([key]) => key.length > 0);\n\n if (entries.length === 0) {\n return undefined;\n }\n\n return entries.map(([Key, Value]) => ({ Key, Value }));\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\n// ============================================================================\n// Adapter Implementation\n// ============================================================================\n\nexport class AwsAdapter implements AwsDirectoryAdapter {\n private readonly orgs: OrganizationsClient;\n private readonly iam: IAMClient;\n private readonly sts: STSClient;\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 this.sts = new STSClient(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 Tags: toAwsTags(input.tags),\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 organizationalUnits: AwsOrganizationalUnit[] = [];\n let nextToken: string | undefined;\n\n do {\n const result = await this.orgs.send(\n new ListOrganizationalUnitsForParentCommand({\n ParentId: parentId,\n NextToken: nextToken,\n }),\n );\n\n organizationalUnits.push(\n ...(result.OrganizationalUnits ?? []).map((ou) => ({\n id: ou.Id ?? '',\n name: ou.Name ?? '',\n arn: ou.Arn,\n parentId,\n })),\n );\n nextToken = result.NextToken;\n } while (nextToken);\n\n return organizationalUnits;\n } catch (error) {\n handleAwsError(error, `listOrganizationalUnits(${parentId})`);\n }\n }\n\n async findOrganizationalUnitByName(\n parentId: string,\n name: string,\n ): Promise<AwsOrganizationalUnit | null> {\n const organizationalUnits = await this.listOrganizationalUnits(parentId);\n return organizationalUnits.find((ou) => ou.name === name) ?? null;\n }\n\n async ensureOrganizationalUnit(\n input: EnsureAwsOuInput,\n ): Promise<AwsOrganizationalUnit> {\n const existing = await this.findOrganizationalUnitByName(\n input.parentId,\n input.name,\n );\n\n if (existing) {\n if (input.tags) {\n await this.tagAwsOrganizationsResource(existing.id, input.tags);\n }\n return existing;\n }\n\n return this.createOrganizationalUnit(input);\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 Tags: toAwsTags(input.tags),\n }),\n );\n\n const status = result.CreateAccountStatus;\n if (!status?.Id) {\n throw new DirectoryError(\n `createAccount(${input.name}) did not return a create account request id`,\n 'AWS_ACCOUNT_CREATION_REQUEST_ID_MISSING',\n 'aws',\n );\n }\n\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 accounts: AwsAccount[] = [];\n let nextToken: string | undefined;\n\n do {\n const result = await this.orgs.send(\n new ListAccountsCommand({ NextToken: nextToken }),\n );\n accounts.push(...(result.Accounts ?? []).map((a) => mapAwsAccount(a)));\n nextToken = result.NextToken;\n } while (nextToken);\n\n return accounts;\n } catch (error) {\n handleAwsError(error, 'listAccounts');\n }\n }\n\n async findAccountByEmail(email: string): Promise<AwsAccount | null> {\n const accounts = await this.listAccounts();\n return (\n accounts.find(\n (account) => account.email.toLowerCase() === email.toLowerCase(),\n ) ?? null\n );\n }\n\n async ensureAccount(input: EnsureAwsAccountInput): Promise<AwsAccount> {\n const existing = await this.findAccountByEmail(input.email);\n if (existing) {\n if (input.tags) {\n await this.tagAwsOrganizationsResource(existing.id, input.tags);\n }\n return existing;\n }\n\n const createStatus = await this.createAccount(input);\n const finalStatus = await this.waitForAccountCreation(\n createStatus.id,\n input.wait,\n );\n\n if (finalStatus.state !== 'SUCCEEDED' || !finalStatus.accountId) {\n throw new DirectoryError(\n `ensureAccount(${input.email}) failed: ${finalStatus.failureReason ?? finalStatus.state}`,\n 'AWS_ACCOUNT_CREATION_FAILED',\n 'aws',\n );\n }\n\n const created = await this.findAccountByEmail(input.email);\n if (created) {\n return created;\n }\n\n return {\n id: finalStatus.accountId,\n name: input.name,\n email: input.email,\n status: 'ACTIVE',\n };\n }\n\n async waitForAccountCreation(\n id: string,\n options: AwsAccountCreationWaitOptions = {},\n ): Promise<AwsAccountCreationStatus> {\n const timeoutMs = options.timeoutMs ?? DEFAULT_ACCOUNT_CREATION_TIMEOUT_MS;\n const pollIntervalMs =\n options.pollIntervalMs ?? DEFAULT_ACCOUNT_CREATION_POLL_INTERVAL_MS;\n const startedAt = Date.now();\n\n while (true) {\n const status = await this.getAccountCreationStatus(id);\n if (status.state !== 'IN_PROGRESS') {\n return status;\n }\n\n if (Date.now() - startedAt >= timeoutMs) {\n throw new DirectoryError(\n `waitForAccountCreation(${id}) timed out after ${timeoutMs}ms`,\n 'AWS_ACCOUNT_CREATION_TIMEOUT',\n 'aws',\n );\n }\n\n await sleep(pollIntervalMs);\n }\n }\n\n async getAccountParent(accountId: string): Promise<AwsAccountParent | null> {\n try {\n const result = await this.orgs.send(\n new ListParentsCommand({ ChildId: accountId }),\n );\n const parent = result.Parents?.[0];\n if (!parent?.Id) {\n return null;\n }\n\n return {\n id: parent.Id,\n type: parent.Type ? String(parent.Type) : '',\n };\n } catch (error) {\n handleAwsError(error, `getAccountParent(${accountId})`);\n }\n }\n\n async ensureAccountInOrganizationalUnit(\n accountId: string,\n destinationParentId: string,\n ): Promise<void> {\n const currentParent = await this.getAccountParent(accountId);\n if (currentParent?.id === destinationParentId) {\n return;\n }\n\n if (!currentParent?.id) {\n throw new DirectoryError(\n `ensureAccountInOrganizationalUnit(${accountId}) could not determine the current account parent`,\n 'AWS_ACCOUNT_PARENT_MISSING',\n 'aws',\n );\n }\n\n await this.moveAccount(accountId, currentParent.id, destinationParentId);\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 async tagAwsOrganizationsResource(\n resourceId: string,\n tags: Record<string, string>,\n ): Promise<void> {\n const awsTags = toAwsTags(tags);\n if (!awsTags) {\n return;\n }\n\n try {\n await this.orgs.send(\n new TagResourceCommand({\n ResourceId: resourceId,\n Tags: awsTags,\n }),\n );\n } catch (error) {\n handleAwsError(error, `tagAwsOrganizationsResource(${resourceId})`);\n }\n }\n\n // ==========================================================================\n // STS (AwsDirectoryAdapter)\n // ==========================================================================\n\n async assumeAwsRole(\n input: AwsAssumeRoleInput,\n ): Promise<AwsTemporaryCredentials> {\n try {\n const result = await this.sts.send(\n new AssumeRoleCommand({\n RoleArn: input.roleArn,\n RoleSessionName: input.sessionName,\n ...(input.externalId ? { ExternalId: input.externalId } : {}),\n ...(input.durationSeconds\n ? { DurationSeconds: input.durationSeconds }\n : {}),\n }),\n );\n const credentials = result.Credentials;\n\n if (\n !credentials?.AccessKeyId ||\n !credentials.SecretAccessKey ||\n !credentials.SessionToken\n ) {\n throw new DirectoryError(\n `assumeAwsRole(${input.roleArn}) returned incomplete credentials`,\n 'AWS_ASSUME_ROLE_INCOMPLETE_CREDENTIALS',\n 'aws',\n );\n }\n\n return {\n accessKeyId: credentials.AccessKeyId,\n secretAccessKey: credentials.SecretAccessKey,\n sessionToken: credentials.SessionToken,\n expiration: credentials.Expiration,\n assumedRoleArn: result.AssumedRoleUser?.Arn,\n assumedRoleId: result.AssumedRoleUser?.AssumedRoleId,\n };\n } catch (error) {\n handleAwsError(error, `assumeAwsRole(${input.roleArn})`);\n }\n }\n\n // ==========================================================================\n // IAM Roles (AwsDirectoryAdapter)\n // ==========================================================================\n\n async getIamRole(roleName: string): Promise<AwsIamRole> {\n try {\n const result = await this.iam.send(\n new GetRoleCommand({ RoleName: roleName }),\n );\n return mapAwsIamRole(result.Role ?? {});\n } catch (error) {\n handleAwsError(error, `getIamRole(${roleName})`);\n }\n }\n\n async ensureIamRole(input: EnsureAwsIamRoleInput): Promise<AwsIamRole> {\n try {\n await this.getIamRole(input.roleName);\n await this.iam.send(\n new UpdateAssumeRolePolicyCommand({\n RoleName: input.roleName,\n PolicyDocument: input.assumeRolePolicyDocument,\n }),\n );\n\n if (input.description !== undefined) {\n await this.iam.send(\n new UpdateRoleCommand({\n RoleName: input.roleName,\n Description: input.description,\n }),\n );\n }\n\n const tags = toAwsTags(input.tags);\n if (tags) {\n await this.iam.send(\n new TagRoleCommand({\n RoleName: input.roleName,\n Tags: tags,\n }),\n );\n }\n\n return this.getIamRole(input.roleName);\n } catch (error) {\n if (!(error instanceof NotFoundError)) {\n throw error;\n }\n }\n\n try {\n const result = await this.iam.send(\n new CreateRoleCommand({\n RoleName: input.roleName,\n AssumeRolePolicyDocument: input.assumeRolePolicyDocument,\n ...(input.description ? { Description: input.description } : {}),\n ...(input.path ? { Path: input.path } : {}),\n Tags: toAwsTags(input.tags),\n }),\n );\n return mapAwsIamRole(result.Role ?? {});\n } catch (error) {\n handleAwsError(error, `ensureIamRole(${input.roleName})`);\n }\n }\n\n async putIamRolePolicy(input: PutAwsIamRolePolicyInput): Promise<void> {\n try {\n await this.iam.send(\n new PutRolePolicyCommand({\n RoleName: input.roleName,\n PolicyName: input.policyName,\n PolicyDocument: input.policyDocument,\n }),\n );\n } catch (error) {\n handleAwsError(error, `putIamRolePolicy(${input.roleName})`);\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 ValidationError,\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 EnsureMailboxInput,\n EnsureMailboxResult,\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\ninterface StalwartPrincipalPage {\n items?: StalwartPrincipal[];\n total?: number;\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 const parsed = JSON.parse(text) as unknown;\n if (\n parsed &&\n typeof parsed === 'object' &&\n !Array.isArray(parsed) &&\n 'data' in parsed\n ) {\n return (parsed as { data: T }).data;\n }\n return parsed 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?types=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.listPrincipalNames('individual');\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.listPrincipalNames('group');\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.listPrincipalNames('domain');\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 return this.createMailboxWithPrincipalId(input, 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 findMailboxByEmail(email: string): Promise<Mailbox | null> {\n this.assertMailboxEmail(email);\n const names = await this.listPrincipalNames('individual');\n const principals = await Promise.all(\n (names ?? []).map((name) =>\n this.request<StalwartPrincipal>(\n 'GET',\n `/api/principal/${encodeURIComponent(name)}`,\n ),\n ),\n );\n const principal = principals.find((entry) => entry.emails?.includes(email));\n return principal ? this.principalToMailbox(principal, email) : null;\n }\n\n async ensureMailbox(input: EnsureMailboxInput): Promise<EnsureMailboxResult> {\n this.assertMailboxEmail(input.email);\n if (!input.principalId.trim()) {\n throw new ValidationError(\n 'Mailbox principalId must not be empty',\n PROVIDER,\n );\n }\n\n const existing = await this.findMailboxByEmail(input.email);\n if (existing) {\n return { mailbox: existing, created: false };\n }\n\n try {\n const mailbox = await this.createMailboxWithPrincipalId(\n input,\n input.principalId,\n );\n return { mailbox, created: true };\n } catch (error) {\n if (!(error instanceof ConflictError)) {\n throw error;\n }\n\n const concurrentlyCreated = await this.findMailboxByEmail(input.email);\n if (concurrentlyCreated) {\n return { mailbox: concurrentlyCreated, created: false };\n }\n throw new ConflictError('mailbox principal', input.principalId, PROVIDER);\n }\n }\n\n private async createMailboxWithPrincipalId(\n input: CreateMailboxInput,\n principalId: string,\n ): Promise<Mailbox> {\n const principal: StalwartPrincipal = {\n name: principalId,\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(principalId);\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.listPrincipalNames('individual');\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 async listPrincipalNames(\n type: StalwartPrincipal['type'],\n ): Promise<string[]> {\n const names: string[] = [];\n let page = 1;\n let fetched = 0;\n let total = 0;\n\n do {\n const result = await this.request<string[] | StalwartPrincipalPage>(\n 'GET',\n `/api/principal?types=${encodeURIComponent(type)}&page=${page}&limit=100`,\n );\n\n if (Array.isArray(result)) {\n return result;\n }\n\n const items = result?.items;\n if (!Array.isArray(items)) {\n throw new DirectoryError(\n 'Stalwart principal list response did not include an items array',\n 'INVALID_API_RESPONSE',\n PROVIDER,\n );\n }\n\n const declaredTotal = result.total;\n if (\n typeof declaredTotal !== 'number' ||\n !Number.isSafeInteger(declaredTotal) ||\n declaredTotal < 0\n ) {\n throw new DirectoryError(\n 'Stalwart principal list response did not include a valid total',\n 'INVALID_API_RESPONSE',\n PROVIDER,\n );\n }\n\n if (\n items.some(\n (principal) =>\n principal.type !== type ||\n typeof principal.name !== 'string' ||\n !principal.name,\n )\n ) {\n throw new DirectoryError(\n 'Stalwart principal list response included an invalid principal',\n 'INVALID_API_RESPONSE',\n PROVIDER,\n );\n }\n\n if (items.length === 0 && fetched < declaredTotal) {\n throw new DirectoryError(\n 'Stalwart principal list pagination ended before the reported total',\n 'INVALID_API_RESPONSE',\n PROVIDER,\n );\n }\n\n names.push(...items.map((principal) => principal.name));\n fetched += items.length;\n total = declaredTotal;\n if (fetched > total) {\n throw new DirectoryError(\n 'Stalwart principal list response exceeded the reported total',\n 'INVALID_API_RESPONSE',\n PROVIDER,\n );\n }\n page += 1;\n } while (fetched < total);\n\n return names;\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 assertMailboxEmail(email: string): void {\n const atIndex = email.indexOf('@');\n if (\n atIndex <= 0 ||\n atIndex !== email.lastIndexOf('@') ||\n atIndex === email.length - 1 ||\n /\\s/.test(email)\n ) {\n throw new ValidationError(\n `Invalid mailbox email address: ${email}`,\n PROVIDER,\n );\n }\n }\n\n private principalToMailbox(\n principal: StalwartPrincipal,\n matchedEmail?: string,\n ): Mailbox {\n return {\n id: principal.name,\n name: principal.description ?? principal.name,\n email: matchedEmail ?? 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"],"mappings":"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"}
|
package/dist/shared/types.d.ts
CHANGED
|
@@ -135,6 +135,25 @@ export interface CreateMailboxInput {
|
|
|
135
135
|
password: string;
|
|
136
136
|
quota?: number;
|
|
137
137
|
}
|
|
138
|
+
/**
|
|
139
|
+
* Desired mailbox state for a caller that owns a stable Stalwart principal id.
|
|
140
|
+
*
|
|
141
|
+
* `ensureMailbox` never changes the credentials of an existing mailbox found
|
|
142
|
+
* by `email`; `password` is used only when the mailbox must be created.
|
|
143
|
+
*/
|
|
144
|
+
export interface EnsureMailboxInput extends CreateMailboxInput {
|
|
145
|
+
principalId: string;
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Result of reconciling a mailbox address.
|
|
149
|
+
*
|
|
150
|
+
* Callers must use `created` to decide whether it is safe to persist the
|
|
151
|
+
* supplied credential: an existing mailbox keeps its original credential.
|
|
152
|
+
*/
|
|
153
|
+
export interface EnsureMailboxResult {
|
|
154
|
+
mailbox: Mailbox;
|
|
155
|
+
created: boolean;
|
|
156
|
+
}
|
|
138
157
|
export interface UpdateMailboxInput {
|
|
139
158
|
name?: string;
|
|
140
159
|
password?: string;
|
|
@@ -150,6 +169,14 @@ export interface StalwartDirectoryAdapter extends DirectoryAdapter {
|
|
|
150
169
|
getDnsRecords(domain: string): Promise<DnsRecord[]>;
|
|
151
170
|
createMailbox(input: CreateMailboxInput): Promise<Mailbox>;
|
|
152
171
|
getMailbox(id: string): Promise<Mailbox>;
|
|
172
|
+
/** Find a mailbox by its complete primary email address. */
|
|
173
|
+
findMailboxByEmail(email: string): Promise<Mailbox | null>;
|
|
174
|
+
/**
|
|
175
|
+
* Return the mailbox for `email`, creating it under `principalId` only when
|
|
176
|
+
* that address does not already exist. Existing credentials are preserved;
|
|
177
|
+
* `created` reports whether this call created the mailbox.
|
|
178
|
+
*/
|
|
179
|
+
ensureMailbox(input: EnsureMailboxInput): Promise<EnsureMailboxResult>;
|
|
153
180
|
updateMailbox(id: string, input: UpdateMailboxInput): Promise<Mailbox>;
|
|
154
181
|
deleteMailbox(id: string): Promise<void>;
|
|
155
182
|
listMailboxes(): Promise<Mailbox[]>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/shared/types.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/shared/types.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@happyvertical/directory",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.100.0",
|
|
4
4
|
"description": "Unified directory services with adapter-based architecture (Kanidm, Stalwart, PostgreSQL, AWS)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
"access": "public"
|
|
25
25
|
},
|
|
26
26
|
"dependencies": {
|
|
27
|
-
"@happyvertical/utils": "0.
|
|
27
|
+
"@happyvertical/utils": "0.100.0",
|
|
28
28
|
"@aws-sdk/client-iam": "^3.1034.0",
|
|
29
29
|
"@aws-sdk/client-organizations": "^3.1034.0",
|
|
30
30
|
"@aws-sdk/client-sts": "^3.1034.0",
|