| quick-260729-d3k |
01 |
auth |
| ldap |
| ldapts |
| active-directory |
| multi-tenancy |
| admin-ui |
| next-intl |
|
| phase |
provides |
| quick-260728-lih |
syncUsersForTenant early-return no-op guard + groupFilterDns-based selective sync (the model this plan replaces) |
|
|
| parseBaseDns() helper turning the newline-separated baseDn String into a trimmed DN list |
| Multi-base directory search across collectSearchEntries/listGroups/searchUsers, merged/deduped by entry dn |
| syncUsersForTenant no-op guard re-keyed on an empty parsed base-DN list (was empty groupFilterDns) |
| Multi-line Base-DN admin textarea + reworked de/en scope wording |
|
| ldap |
| admin-ldap-page |
| i18n |
|
| added |
patterns |
|
|
| Map<string, Entry> keyed by entry.dn used to merge/dedupe results across multiple LDAP search-base calls |
|
|
| created |
modified |
|
|
| apps/api/src/ldap/ldap.service.ts |
| apps/api/src/ldap/ldap.service.spec.ts |
| apps/web/src/app/(portal)/admin/ldap/page.tsx |
| apps/web/src/messages/de.json |
| apps/web/src/messages/en.json |
|
|
| The syncUsersForTenant no-op guard is keyed SOLELY on parseBaseDns(config.baseDn).length === 0 — an empty groupFilterDns is no longer a no-op condition, it now performs a normal multi-base search with no memberOf restriction |
| groupFilterDns ou= entries stay ADDITIONAL search bases (plain filter); non-ou= entries become an optional memberOf constraint ANDed onto every base-DN search |
| Base-DN stays a single String column (newline-separated); no schema change or migration — parseBaseDns() is the sole place the list is derived |
|
| parseBaseDns()-then-loop-then-Map-dedupe pattern for turning a single delimited config field into a multi-target directory search, reusable for any future multi-value LDAP config field |
|
|
| id |
description |
requirement |
verification |
human_judgment |
| D1 |
parseBaseDns() splits the Base-DN field into a trimmed, non-empty list; empty/whitespace-only input yields [] |
260729-d3k |
| kind |
ref |
status |
| unit |
apps/api/src/ldap/ldap.service.spec.ts#LdapService.syncUsersForTenant — empty base DN no-op > creates nobody and deactivates nobody when the base DN is empty (whitespace-only) |
pass |
|
|
false |
|
| id |
description |
requirement |
verification |
human_judgment |
| D2 |
syncUsersForTenant is a total no-op (no bind, no search, no create/update, no deactivation, no ldapConfig.update) ONLY when the parsed base-DN list is empty |
260729-d3k |
| kind |
ref |
status |
| unit |
apps/api/src/ldap/ldap.service.spec.ts#LdapService.syncUsersForTenant — empty base DN no-op > creates nobody and deactivates nobody when the base DN is empty (whitespace-only) |
pass |
|
| kind |
ref |
status |
| unit |
apps/api/src/ldap/ldap.service.spec.ts#LdapService.syncUsersForTenant — empty base DN no-op > is NOT a no-op when baseDn is set but groupFilterDns is empty (normal multi-base search) |
pass |
|
|
false |
|
| id |
description |
requirement |
verification |
human_judgment |
| D3 |
collectSearchEntries/listGroups/searchUsers search every configured base DN and merge/dedupe results by entry dn |
260729-d3k |
| kind |
ref |
status |
| unit |
apps/api/src/ldap/ldap.service.spec.ts#LdapService.syncUsersForTenant — multi base DN scope > searches every configured base DN and merges/dedupes results by dn |
pass |
|
| kind |
ref |
status |
| unit |
pnpm --filter @tessera/api exec vitest run src/ldap/ldap.service.spec.ts (full 18-spec file, incl. searchUsers/listGroups paths exercised by existing specs) |
pass |
|
|
false |
|
| id |
description |
requirement |
verification |
human_judgment |
rationale |
| D4 |
Admin Base-DN field is a multi-line textarea persisting one newline-separated string; de/en i18n reworded to describe the group filter as optional and the base DN(s) as the sync scope |
260729-d3k |
| kind |
ref |
status |
| unit |
node -e JSON.parse(...) de.json/en.json + grep Basis-DN(s)/base DN(s)/baseDnHint/textarea |
pass |
|
| kind |
ref |
status |
| other |
pnpm --filter @tessera/web run type-check |
pass |
|
|
true |
Visual rendering of the new textarea and hint text in the actual admin page was not verified via a running browser session in this quick task — automated checks confirm JSON validity, wording, and TypeScript correctness only. |
|
|
3min |
2026-07-29 |
complete |