@shamar/adonis 0.1.2 → 0.1.4

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.
Files changed (83) hide show
  1. package/README.md +94 -2
  2. package/assets/admin.css +1 -1
  3. package/assets/shamar-ui.js +290 -5
  4. package/dist/auth/ldap.d.ts +115 -0
  5. package/dist/auth/ldap.d.ts.map +1 -0
  6. package/dist/auth/ldap.js +275 -0
  7. package/dist/auth/ldap.js.map +1 -0
  8. package/dist/auth/masquerade.d.ts +31 -0
  9. package/dist/auth/masquerade.d.ts.map +1 -0
  10. package/dist/auth/masquerade.js +36 -0
  11. package/dist/auth/masquerade.js.map +1 -0
  12. package/dist/auth_login_view.d.ts +56 -0
  13. package/dist/auth_login_view.d.ts.map +1 -0
  14. package/dist/auth_login_view.js +56 -0
  15. package/dist/auth_login_view.js.map +1 -0
  16. package/dist/commands/commands.json +1 -0
  17. package/dist/commands/main.d.ts +4 -0
  18. package/dist/commands/main.js +36 -0
  19. package/dist/commands/publish_auth.d.ts +13 -0
  20. package/dist/commands/publish_auth.d.ts.map +1 -0
  21. package/dist/commands/publish_auth.js +26 -0
  22. package/dist/commands/publish_auth.js.map +1 -0
  23. package/dist/config.d.ts +59 -1
  24. package/dist/config.d.ts.map +1 -1
  25. package/dist/config.js.map +1 -1
  26. package/dist/configure.d.ts +16 -1
  27. package/dist/configure.d.ts.map +1 -1
  28. package/dist/configure.js +6 -0
  29. package/dist/configure.js.map +1 -1
  30. package/dist/context.d.ts +3 -0
  31. package/dist/context.d.ts.map +1 -1
  32. package/dist/controllers/admin_controller.d.ts +1 -0
  33. package/dist/controllers/admin_controller.d.ts.map +1 -1
  34. package/dist/controllers/admin_controller.js +91 -9
  35. package/dist/controllers/admin_controller.js.map +1 -1
  36. package/dist/index.d.ts +6 -1
  37. package/dist/index.d.ts.map +1 -1
  38. package/dist/index.js +6 -1
  39. package/dist/index.js.map +1 -1
  40. package/dist/provider.d.ts.map +1 -1
  41. package/dist/provider.js +2 -1
  42. package/dist/provider.js.map +1 -1
  43. package/dist/publish_auth.d.ts +45 -0
  44. package/dist/publish_auth.d.ts.map +1 -0
  45. package/dist/publish_auth.js +69 -0
  46. package/dist/publish_auth.js.map +1 -0
  47. package/dist/resources/api_key_resource.d.ts +4 -6
  48. package/dist/resources/api_key_resource.d.ts.map +1 -1
  49. package/dist/resources/api_key_resource.js +4 -16
  50. package/dist/resources/api_key_resource.js.map +1 -1
  51. package/dist/routes.d.ts.map +1 -1
  52. package/dist/routes.js +27 -5
  53. package/dist/routes.js.map +1 -1
  54. package/dist/shamar/auth.d.ts +13 -1
  55. package/dist/shamar/auth.d.ts.map +1 -1
  56. package/dist/shamar/auth.js +42 -5
  57. package/dist/shamar/auth.js.map +1 -1
  58. package/dist/shamar/list-query.d.ts +9 -0
  59. package/dist/shamar/list-query.d.ts.map +1 -1
  60. package/dist/shamar/list-query.js +29 -1
  61. package/dist/shamar/list-query.js.map +1 -1
  62. package/dist/shamar/relation-fields.d.ts +15 -0
  63. package/dist/shamar/relation-fields.d.ts.map +1 -1
  64. package/dist/shamar/relation-fields.js +25 -4
  65. package/dist/shamar/relation-fields.js.map +1 -1
  66. package/dist/shamar/relation-table.d.ts +37 -0
  67. package/dist/shamar/relation-table.d.ts.map +1 -0
  68. package/dist/shamar/relation-table.js +61 -0
  69. package/dist/shamar/relation-table.js.map +1 -0
  70. package/dist/shamar/view-context.d.ts +8 -0
  71. package/dist/shamar/view-context.d.ts.map +1 -1
  72. package/dist/shamar/view-context.js +1 -0
  73. package/dist/shamar/view-context.js.map +1 -1
  74. package/package.json +15 -6
  75. package/resources/views/shamar/partials/detail-entry.edge +7 -0
  76. package/resources/views/shamar/partials/field-relation-table.edge +309 -105
  77. package/resources/views/shamar/partials/list-row.edge +17 -4
  78. package/resources/views/shamar/partials/nav.edge +6 -1
  79. package/resources/views/shamar/partials/shell-open.edge +14 -0
  80. package/resources/views/shamar/partials/topbar.edge +3 -0
  81. package/resources/views/shamar/show.edge +59 -20
  82. package/stubs/views/auth/layout.edge +244 -0
  83. package/stubs/views/auth/login.edge +65 -0
@@ -818,9 +818,12 @@
818
818
 
819
819
  openRecord() {
820
820
  if (!this.value || !this.detailUrlBase) return;
821
+ const url = this.readonly
822
+ ? `${this.detailUrlBase}/${this.value}`
823
+ : `${this.detailUrlBase}/${this.value}/edit`;
821
824
  window.ShamarUI.openDialog({
822
- url: `${this.detailUrlBase}/${this.value}/edit`,
823
- title: this.label || 'Edit record',
825
+ url,
826
+ title: this.label || (this.readonly ? 'View record' : 'Edit record'),
824
827
  slug: this.relatedResource,
825
828
  });
826
829
  },
@@ -1119,9 +1122,12 @@
1119
1122
 
1120
1123
  openRecord(item) {
1121
1124
  if (!item?.id || !this.detailUrlBase) return;
1125
+ const url = this.readonly
1126
+ ? `${this.detailUrlBase}/${item.id}`
1127
+ : `${this.detailUrlBase}/${item.id}/edit`;
1122
1128
  window.ShamarUI.openDialog({
1123
- url: `${this.detailUrlBase}/${item.id}/edit`,
1124
- title: item.label || 'Edit record',
1129
+ url,
1130
+ title: item.label || (this.readonly ? 'View record' : 'Edit record'),
1125
1131
  slug: this.relatedResource,
1126
1132
  });
1127
1133
  },
@@ -1453,10 +1459,30 @@
1453
1459
  function createShamarM2mTable(cfg) {
1454
1460
  const self = createShamarM2m(cfg);
1455
1461
  self.addOpen = false;
1462
+ self.listUrl = cfg.listUrl || null;
1463
+ self.columns = Array.isArray(cfg.columns) ? cfg.columns : [];
1464
+ self.listHeaders = Array.isArray(cfg.listHeaders) ? cfg.listHeaders : [];
1465
+ self.rows = [];
1466
+ self.total = 0;
1467
+ self.page = 1;
1468
+ self.pageCount = 1;
1469
+ self.perPage = String(cfg.perPage || 10);
1470
+ self.listSearch = '';
1471
+ self.listFilters = [];
1472
+ self.listSort = cfg.defaultSort || '';
1473
+ self.listDirection = cfg.defaultDirection || 'asc';
1474
+ self.listLoading = false;
1475
+ self.filterPanelOpen = false;
1476
+ self._listAbort = null;
1477
+
1456
1478
  const prevInit = self.init;
1457
1479
  const prevDestroy = self.destroy;
1458
1480
  const prevPick = self.pick;
1459
1481
  const prevCreateAndEdit = self.createAndEdit;
1482
+ const prevAttach = self.attachHasMany;
1483
+ const prevDetach = self.detachHasMany;
1484
+ const prevOpenRecord = self.openRecord;
1485
+
1460
1486
  self.init = function initTable() {
1461
1487
  prevInit.call(this);
1462
1488
  this._tablePickHandler = (event) => {
@@ -1467,13 +1493,190 @@
1467
1493
  }
1468
1494
  };
1469
1495
  window.addEventListener('shamar-m2m-pick', this._tablePickHandler);
1496
+ if (this.listUrl) {
1497
+ this.loadList();
1498
+ }
1470
1499
  };
1500
+
1471
1501
  self.destroy = function destroyTable() {
1472
1502
  prevDestroy.call(this);
1473
1503
  if (this._tablePickHandler) {
1474
1504
  window.removeEventListener('shamar-m2m-pick', this._tablePickHandler);
1475
1505
  }
1506
+ if (this._listAbort) this._listAbort.abort();
1507
+ };
1508
+
1509
+ Object.defineProperty(self, 'filterableHeaders', {
1510
+ get() {
1511
+ return (this.listHeaders || []).filter(
1512
+ (header) =>
1513
+ header.filter_kind === 'boolean' ||
1514
+ (header.filter_kind === 'select' && Array.isArray(header.options)),
1515
+ );
1516
+ },
1517
+ });
1518
+
1519
+ Object.defineProperty(self, 'availableResults', {
1520
+ get() {
1521
+ const linked = new Set([
1522
+ ...(this.selected || []).map((item) => String(item.id)),
1523
+ ...(this.rows || []).map((row) => String(row.id)),
1524
+ ]);
1525
+ return (this.results || []).filter((item) => !linked.has(String(item.id)));
1526
+ },
1527
+ });
1528
+
1529
+ self.cellAlignment = function cellAlignment(columnName) {
1530
+ const column = (this.columns || []).find((entry) => entry.name === columnName);
1531
+ return column?.alignmentClass || '';
1532
+ };
1533
+
1534
+ self.buildListUrl = function buildListUrl() {
1535
+ const url = new URL(this.listUrl, window.location.origin);
1536
+ if (this.listSearch) url.searchParams.set('search', this.listSearch);
1537
+ if (this.listSort) {
1538
+ url.searchParams.set('sort', this.listSort);
1539
+ if (this.listDirection === 'asc' || this.listDirection === 'desc') {
1540
+ url.searchParams.set('direction', this.listDirection);
1541
+ }
1542
+ }
1543
+ url.searchParams.set('page', String(this.page || 1));
1544
+ url.searchParams.set('perPage', String(this.perPage || 10));
1545
+ if (this.listFilters?.length) {
1546
+ url.searchParams.set('filters', JSON.stringify(this.listFilters));
1547
+ }
1548
+ return `${url.pathname}${url.search}`;
1549
+ };
1550
+
1551
+ self.loadList = async function loadList() {
1552
+ if (!this.listUrl) return;
1553
+ if (this._listAbort) this._listAbort.abort();
1554
+ const ctl = new AbortController();
1555
+ this._listAbort = ctl;
1556
+ this.listLoading = true;
1557
+ try {
1558
+ const response = await fetch(this.buildListUrl(), {
1559
+ signal: ctl.signal,
1560
+ credentials: 'same-origin',
1561
+ headers: { Accept: 'application/json' },
1562
+ });
1563
+ if (!response.ok) throw new Error('list failed');
1564
+ const data = await response.json();
1565
+ this.rows = Array.isArray(data.rows) ? data.rows : [];
1566
+ this.total = Number(data.total) || 0;
1567
+ this.page = Number(data.page) || 1;
1568
+ this.pageCount = Math.max(1, Number(data.pageCount) || 1);
1569
+ this.perPage = String(data.perPage || this.perPage || 10);
1570
+ if (Array.isArray(data.columns) && data.columns.length) {
1571
+ this.columns = data.columns;
1572
+ }
1573
+ if (Array.isArray(data.listHeaders)) {
1574
+ this.listHeaders = data.listHeaders;
1575
+ }
1576
+ if (data.sort) this.listSort = data.sort;
1577
+ if (data.direction) this.listDirection = data.direction;
1578
+ } catch (error) {
1579
+ if (error.name !== 'AbortError') {
1580
+ this.rows = [];
1581
+ this.total = 0;
1582
+ showToast('error', {
1583
+ title: 'Error',
1584
+ message: 'Unable to load related records.',
1585
+ });
1586
+ }
1587
+ } finally {
1588
+ this.listLoading = false;
1589
+ }
1476
1590
  };
1591
+
1592
+ self.applyListSearch = function applyListSearch() {
1593
+ this.page = 1;
1594
+ this.loadList();
1595
+ };
1596
+
1597
+ self.setListPage = function setListPage(page) {
1598
+ const next = Math.max(1, Number(page) || 1);
1599
+ this.page = next;
1600
+ this.loadList();
1601
+ };
1602
+
1603
+ self.toggleListSort = function toggleListSort(field) {
1604
+ if (!field) return;
1605
+ if (this.listSort === field) {
1606
+ this.listDirection = this.listDirection === 'asc' ? 'desc' : 'asc';
1607
+ } else {
1608
+ this.listSort = field;
1609
+ this.listDirection = 'asc';
1610
+ }
1611
+ this.page = 1;
1612
+ this.loadList();
1613
+ };
1614
+
1615
+ self.hasFilter = function hasFilter(header, value) {
1616
+ const field = header.filterField || header.name;
1617
+ return this.listFilters.some(
1618
+ (chip) => chip.field === field && String(chip.value) === String(value),
1619
+ );
1620
+ };
1621
+
1622
+ self.toggleBooleanFilter = function toggleBooleanFilter(header, value) {
1623
+ const field = header.filterField || header.name;
1624
+ const existing = this.listFilters.find((chip) => chip.field === field);
1625
+ if (existing && String(existing.value) === String(value)) {
1626
+ this.listFilters = this.listFilters.filter((chip) => chip.field !== field);
1627
+ } else {
1628
+ this.listFilters = [
1629
+ ...this.listFilters.filter((chip) => chip.field !== field),
1630
+ {
1631
+ field,
1632
+ op: '=',
1633
+ value,
1634
+ label: `${header.label}: ${value ? 'Yes' : 'No'}`,
1635
+ },
1636
+ ];
1637
+ }
1638
+ this.page = 1;
1639
+ this.loadList();
1640
+ };
1641
+
1642
+ self.toggleSelectFilter = function toggleSelectFilter(header, opt) {
1643
+ const field = header.filterField || header.name;
1644
+ const value = opt.value;
1645
+ if (this.hasFilter(header, value)) {
1646
+ this.listFilters = this.listFilters.filter(
1647
+ (chip) => !(chip.field === field && String(chip.value) === String(value)),
1648
+ );
1649
+ } else {
1650
+ this.listFilters = [
1651
+ ...this.listFilters.filter((chip) => chip.field !== field),
1652
+ {
1653
+ field,
1654
+ op: '=',
1655
+ value,
1656
+ label: `${header.label}: ${opt.label}`,
1657
+ },
1658
+ ];
1659
+ }
1660
+ this.page = 1;
1661
+ this.loadList();
1662
+ };
1663
+
1664
+ self.removeListFilter = function removeListFilter(chip) {
1665
+ this.listFilters = this.listFilters.filter(
1666
+ (entry) =>
1667
+ !(entry.field === chip.field && String(entry.value) === String(chip.value)),
1668
+ );
1669
+ this.page = 1;
1670
+ this.loadList();
1671
+ };
1672
+
1673
+ self.clearListFilters = function clearListFilters() {
1674
+ this.listFilters = [];
1675
+ this.filterPanelOpen = false;
1676
+ this.page = 1;
1677
+ this.loadList();
1678
+ };
1679
+
1477
1680
  self.toggleAdd = function toggleAdd() {
1478
1681
  this.addOpen = !this.addOpen;
1479
1682
  if (this.addOpen) {
@@ -1482,18 +1685,76 @@
1482
1685
  this.$nextTick?.(() => this.$refs.addInput?.focus());
1483
1686
  }
1484
1687
  };
1688
+
1485
1689
  self.closeAdd = function closeAdd() {
1486
1690
  this.addOpen = false;
1487
1691
  this.query = '';
1488
1692
  };
1693
+
1489
1694
  self.pick = function pickTable(item) {
1695
+ if (
1696
+ this.listUrl &&
1697
+ item?.id != null &&
1698
+ this.rows.some((row) => String(row.id) === String(item.id))
1699
+ ) {
1700
+ this.closeAdd();
1701
+ return;
1702
+ }
1490
1703
  prevPick.call(this, item);
1491
1704
  this.closeAdd();
1492
1705
  };
1706
+
1707
+ self.attachHasMany = async function attachHasManyTable(item) {
1708
+ await prevAttach.call(this, item);
1709
+ if (this.listUrl) {
1710
+ this.page = 1;
1711
+ await this.loadList();
1712
+ }
1713
+ };
1714
+
1715
+ self.detachHasMany = async function detachHasManyTable(relatedId) {
1716
+ await prevDetach.call(this, relatedId);
1717
+ if (this.listUrl) {
1718
+ await this.loadList();
1719
+ }
1720
+ };
1721
+
1722
+ self.openRecord = function openRecordTable(item) {
1723
+ if (!item?.id || !this.detailUrlBase) return;
1724
+ const url = this.readonly
1725
+ ? `${this.detailUrlBase}/${item.id}`
1726
+ : `${this.detailUrlBase}/${item.id}/edit`;
1727
+ window.ShamarUI.openDialog({
1728
+ url,
1729
+ title: item.label || (this.readonly ? 'View record' : 'Edit record'),
1730
+ slug: this.relatedResource,
1731
+ onResult: () => {
1732
+ if (this.listUrl) this.loadList();
1733
+ },
1734
+ });
1735
+ };
1736
+
1493
1737
  self.createAndEdit = function createAndEditTable() {
1494
1738
  this.closeAdd();
1495
- prevCreateAndEdit.call(this);
1739
+ if (!this.createUrl) return;
1740
+ const q = (this.query || '').trim();
1741
+ const url = q
1742
+ ? `${this.createUrl}${this.createUrl.includes('?') ? '&' : '?'}name=${encodeURIComponent(q)}`
1743
+ : this.createUrl;
1744
+ const title = q ? `New ${this.singularLabel}` : `Create ${this.singularLabel}`;
1745
+ window.ShamarUI.openDialog({
1746
+ url,
1747
+ title,
1748
+ slug: this.relatedResource,
1749
+ onResult: (detail) => {
1750
+ if (detail?.id) {
1751
+ prevPick.call(this, { id: detail.id, label: detail.label });
1752
+ }
1753
+ if (this.listUrl) this.loadList();
1754
+ },
1755
+ });
1496
1756
  };
1757
+
1497
1758
  return self;
1498
1759
  }
1499
1760
 
@@ -3134,12 +3395,36 @@
3134
3395
  applyListHrefs();
3135
3396
  bindListViewSwitcher();
3136
3397
  bindListRefresh();
3398
+ bindListRowNavigation();
3137
3399
  bindMediaUploads();
3138
3400
  bindFormSaveShortcut();
3139
3401
  bindFormAutosave();
3140
3402
  bindRecordPagerNav();
3141
3403
  });
3142
3404
 
3405
+ function bindListRowNavigation() {
3406
+ document.addEventListener('click', (event) => {
3407
+ if (!(event instanceof MouseEvent) || event.button !== 0) return;
3408
+ if (event.defaultPrevented) return;
3409
+ if (event.metaKey || event.ctrlKey || event.shiftKey || event.altKey) return;
3410
+ const target = event.target;
3411
+ if (!(target instanceof Element)) return;
3412
+ if (
3413
+ target.closest(
3414
+ 'a, button, input, select, textarea, label, [data-shamar-stop-row-nav]',
3415
+ )
3416
+ ) {
3417
+ return;
3418
+ }
3419
+ const row = target.closest('tr[data-shamar-row-href]');
3420
+ if (!row) return;
3421
+ const href = row.getAttribute('data-shamar-row-href');
3422
+ if (!href) return;
3423
+ event.preventDefault();
3424
+ window.location.assign(href);
3425
+ });
3426
+ }
3427
+
3143
3428
  function relationConfigsFromForm(form) {
3144
3429
  const configs = [];
3145
3430
  if (!(form instanceof HTMLFormElement)) return configs;
@@ -0,0 +1,115 @@
1
+ import { type AuthLoginMode, type ExternalIdentity } from '@shamar/cherubim';
2
+ export interface LdapDomainConfig {
3
+ /** Stable key, e.g. corp. */
4
+ id: string;
5
+ /** Human label for logs / UI. */
6
+ label?: string;
7
+ /** LDAP(S) URL. */
8
+ url: string;
9
+ /** Optional service-account bind for search. */
10
+ bindDn?: string;
11
+ bindPassword?: string;
12
+ searchBase: string;
13
+ /** Filter with {{username}} placeholder. */
14
+ searchFilter: string;
15
+ emailAttribute?: string;
16
+ nameAttribute?: string;
17
+ /** Default memberOf. */
18
+ groupsAttribute?: string;
19
+ groupRoleMap?: Record<string, string>;
20
+ /** Prefer this domain when login uses an email domain suffix. */
21
+ emailDomains?: string[];
22
+ /** Prefer this domain for NetBIOS-prefixed logins. */
23
+ netbios?: string;
24
+ tls?: {
25
+ rejectUnauthorized?: boolean;
26
+ };
27
+ /** Operation timeout in milliseconds (ldapts `timeout`). Default 10_000. */
28
+ timeoutMs?: number;
29
+ /** TCP connect timeout in milliseconds (ldapts `connectTimeout`). Defaults to `timeoutMs`. */
30
+ connectTimeoutMs?: number;
31
+ }
32
+ export interface LdapAuthSettings {
33
+ domains: LdapDomainConfig[];
34
+ /**
35
+ * How to link a successful LDAP bind to a local user:
36
+ * - `existing` (default) — only log in if a local row already has the sync `externalId`
37
+ * - `create` — upsert a local user when missing (auto-provision)
38
+ */
39
+ provisioning?: LdapProvisioningMode;
40
+ }
41
+ /** Local user must pre-exist (`existing`) or may be auto-created (`create`). */
42
+ export type LdapProvisioningMode = 'existing' | 'create';
43
+ /** Pluggable directory client — production uses ldapts; tests inject a mock. */
44
+ export interface LdapDirectoryClient {
45
+ authenticate(username: string, password: string, domain: LdapDomainConfig): Promise<ExternalIdentity | null>;
46
+ }
47
+ export type LocalCredentialVerifier<TUser> = (username: string, password: string) => Promise<TUser | null>;
48
+ export type LdapUserLinker<TUser> = (identity: ExternalIdentity) => Promise<TUser | null>;
49
+ export type PasswordLoginSuccess<TUser> = {
50
+ ok: true;
51
+ user: TUser;
52
+ method: 'ldap' | 'local';
53
+ };
54
+ export type PasswordLoginFailure = {
55
+ ok: false;
56
+ message: string;
57
+ /** Set when directory contact timed out. */
58
+ code?: 'ldap_timeout';
59
+ };
60
+ export type PasswordLoginResult<TUser> = PasswordLoginSuccess<TUser> | PasswordLoginFailure;
61
+ export declare const LDAP_TIMEOUT_MESSAGE = "Directory server timed out. Please try again.";
62
+ /** Thrown / rethrown when ldapts (or the network) times out contacting a domain. */
63
+ export declare class LdapTimeoutError extends Error {
64
+ readonly domainId: string;
65
+ constructor(domainId: string, cause?: unknown);
66
+ }
67
+ export declare function isLdapTimeoutError(error: unknown): boolean;
68
+ export type AuthenticateLdapResult = {
69
+ identity: ExternalIdentity | null;
70
+ /** True when at least one domain attempt failed due to a timeout. */
71
+ timedOut: boolean;
72
+ };
73
+ export declare function resolveLdapProvisioning(mode: LdapProvisioningMode | undefined): LdapProvisioningMode;
74
+ export declare function resolveAuthLoginMode(mode: AuthLoginMode | undefined, domains: LdapDomainConfig[] | undefined): AuthLoginMode;
75
+ /**
76
+ * Order domains: hinted matches first, then remaining config order.
77
+ */
78
+ export declare function orderLdapDomains(usernameInput: string, domains: LdapDomainConfig[]): LdapDomainConfig[];
79
+ export declare function searchUsernameForDomain(usernameInput: string, _domain: LdapDomainConfig): string;
80
+ /**
81
+ * Try domains in order until one authenticates.
82
+ * Returns `{ identity: null }` when none succeed (caller decides local fallback).
83
+ * Sets `timedOut` when any domain attempt hit a connect/operation timeout.
84
+ */
85
+ export declare function authenticateLdap(usernameInput: string, password: string, domains: LdapDomainConfig[], client: LdapDirectoryClient): Promise<AuthenticateLdapResult>;
86
+ /**
87
+ * Orchestrate local / LDAP / both login modes.
88
+ *
89
+ * After a successful directory bind, {@link linkFromLdap} must resolve a local
90
+ * user (matched by sync UID / externalId). When `provisioning` is `existing`
91
+ * and no local row exists, LDAP login fails (or falls through to local when
92
+ * `loginMode` is `both`).
93
+ */
94
+ export declare function resolvePasswordLogin<TUser>(options: {
95
+ username: string;
96
+ password: string;
97
+ loginMode?: AuthLoginMode;
98
+ domains?: LdapDomainConfig[];
99
+ /** Default `existing` — AD users must already exist locally with a sync UID. */
100
+ provisioning?: LdapProvisioningMode;
101
+ client: LdapDirectoryClient;
102
+ verifyLocal: LocalCredentialVerifier<TUser>;
103
+ /**
104
+ * Link LDAP identity → local user.
105
+ * Return `null` when no local user exists (and auto-create is not desired).
106
+ */
107
+ linkFromLdap: LdapUserLinker<TUser>;
108
+ }): Promise<PasswordLoginResult<TUser>>;
109
+ /** Apply domain groupRoleMap to an identity's groups. */
110
+ export declare function roleIdsFromLdapIdentity(identity: ExternalIdentity, domain: LdapDomainConfig): string[];
111
+ /**
112
+ * Default ldapts-backed client. Requires the optional `ldapts` peer dependency.
113
+ */
114
+ export declare function createLdaptsDirectoryClient(): LdapDirectoryClient;
115
+ //# sourceMappingURL=ldap.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ldap.d.ts","sourceRoot":"","sources":["../../src/auth/ldap.ts"],"names":[],"mappings":"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"}