Add an LDAP Info page: dynamic connection details + a ready-to-run ldap-client setup script

New admin-only page (nav: "LDAP Info") that answers "what do I put in my
app's LDAP settings" without reading a doc: LDAPS URL, base DN, user/group
search bases, user filter, username attribute, and an example bind DN, all
derived from the running conf.ldap + request host rather than hardcoded --
so it's always correct for the actual deployment, copy-button on every
field.

Also generates a copy-pasteable bash snippet that clones
theta42/ldap-client and writes its ldap.vars file with the real host/base
DN/sso_url already filled in (bind password and SSO API token left as
placeholders with inline instructions, since those need to be created,
not derived).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-15 19:34:30 -04:00
parent 8c970fe3fc
commit edd5a26e44
3 changed files with 189 additions and 0 deletions
+28
View File
@@ -82,6 +82,34 @@ router.get('/oauth-clients', function(req, res, next) {
res.render('oauth_clients', {...values, issuer, discoveryUrl: `${issuer}/.well-known/openid-configuration`});
});
// Everything a 3rd-party app or the ldap-client host script needs to bind
// this directory, derived from the running config + request host rather than
// hardcoded in a doc -- so it's always right for *this* deployment.
router.get('/ldap-info', function(req, res, next) {
const issuer = ((conf.oauth && conf.oauth.issuer) || `${req.protocol}://${req.get('host')}`).replace(/\/$/, '');
const ldapHost = issuer.replace(/^https?:\/\//, '').replace(/:\d+$/, '');
const userBase = (conf.ldap && conf.ldap.userBase) || 'ou=people,dc=example,dc=com';
const groupBase = (conf.ldap && conf.ldap.groupBase) || 'ou=groups,dc=example,dc=com';
// The base DN isn't stored as its own config value -- derive it by
// stripping the leading "ou=...," off userBase (ou=people,dc=example,dc=com
// -> dc=example,dc=com).
const baseDn = userBase.replace(/^ou=[^,]+,/i, '');
res.render('ldap_info', {
...values,
ldapHost,
ldapsUrl: `ldaps://${ldapHost}:636`,
baseDn,
userBase,
groupBase,
userFilter: (conf.ldap && conf.ldap.userFilter) || '(objectClass=posixAccount)',
userNameAttribute: (conf.ldap && conf.ldap.userNameAttribute) || 'uid',
exampleBindDn: `cn=ldapclient,${userBase}`,
ssoUrl: issuer,
});
});
// API Tokens is now a section on the Profile page (own profile only).
router.get('/api-tokens', (req, res) => res.redirect(301, '/'));