Compare commits

...

4 Commits

Author SHA1 Message Date
wmantly 96b3aec5eb Merge pull request #73 from theta42/release-1.1.20
Release 1.1.20: bump proxy submodule to v1.1.17
2026-07-20 00:31:55 -04:00
wmantly 5aff5349a8 Release 1.1.20: bump proxy submodule to v1.1.17
Pins the proxy submodule to v1.1.17 (wildcard sibling-parent fix: an
existing single-label subdomain host can now be attached to a wildcard
cert added afterward). Embeds proxy's v1.1.17 changelog in the theta-env
release notes.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-20 00:31:12 -04:00
wmantly 3b0f8f1f9a chore: bump sso-manager-node submodule to v1.1.17 (#72)
Picks up the configurable LDAPS hostname feature and docs.

Co-authored-by: Claude <noreply@anthropic.com>
2026-07-19 01:14:32 -04:00
wmantly 28016376ad feat: propagate CFG_LDAPS_HOST through setup and document LDAPS networking (#71)
Pass optional CFG_LDAPS_HOST from setup.env through setup.sh into the
generated ./config/sso-secrets.js as ldap.ldapsHost. This lets operators
advertise an internal-only LDAPS hostname (e.g. ldap.internal.example.com
or sso-manager) on the SSO /integrations page instead of the public
OAuth issuer, avoiding a public 636 port forward.

- setup.env.example: add CFG_LDAPS_HOST
- setup.sh: read/forward CFG_LDAPS_HOST into sso-secrets.js
- config.example/sso-secrets.js.example: document ldapsHost/ldapsPort
- .env.example: add LDAPS_HOST for legacy .env migrations
- docker-compose.yml: comment warning against public 636 forwarding
- README.md: explain CFG_LDAPS_HOST recommendation
- CHANGELOG.md + bump version to 1.1.19

Co-authored-by: Claude <noreply@anthropic.com>
2026-07-19 01:14:03 -04:00
9 changed files with 66 additions and 4 deletions
+6
View File
@@ -77,3 +77,9 @@ MGMT_BIND=0.0.0.0
# (sso-manager inside the docker net uses the service name, which is in the # (sso-manager inside the docker net uses the service name, which is in the
# cert's SAN, so the default is usually fine). # cert's SAN, so the default is usually fine).
LDAP_CERT_CN= LDAP_CERT_CN=
# ── Optional: LDAPS hostname shown on the SSO /integrations page ────────────────
# Leave blank to derive from the public SSO host (SSO_HOST). Set an internal-only
# name like 'ldap.internal.example.com' or 'sso-manager' so direct-LDAP clients
# don't need a public 636 port forward. See docs/ldap.md for network layouts.
LDAPS_HOST=
+36 -1
View File
@@ -10,6 +10,41 @@ for what changed inside the apps it composes.
## [Unreleased] ## [Unreleased]
## [1.1.20] - 2026-07-20
### Bumped
- proxy -> [v1.1.17](https://github.com/theta42/proxy/releases/tag/v1.1.17)
proxy:
### Fixed
- An existing single-label subdomain host (e.g. `sso.nl.wgnode.com`) could not be attached to a wildcard cert added later (e.g. `*.nl.wgnode.com`): `Host.lookUpWildcardParent()` only checked the wildcard-as-child position (the wildcard's own base domain) and missed the far more common wildcard-as-sibling case, so the edit form's "Parent Wildcard" option stayed permanently greyed out. It now checks both positions, and a regression test covers the sibling case.
## [1.1.19] - 2026-07-18
### Bumped
- sso-manager-node -> [v1.1.17](https://github.com/theta42/sso-manager-node/releases/tag/v1.1.17)
sso-manager-node:
### Added
- `conf.ldap.ldapsHost` and `conf.ldap.ldapsPort` config options for advertising a separate, internal-only LDAPS hostname on the `/integrations` page. Falls back to the public OAuth issuer host when unset.
- Contextual help panel on `/integrations` → LDAP explaining why LDAPS needs a hostname, why port 636 should not be forwarded publicly, and the recommended internal-DNS / Docker-internal alternatives.
- Tests for the `/integrations` route's LDAPS URL derivation and `ldapsHost` override.
### Changed
- `nodejs/package.json` / `package-lock.json` version bumped to `1.1.17`.
- `routes/index.js` now derives the displayed LDAPS URL from `conf.ldap.ldapsHost`/`ldapsPort` with fallback to the OAuth issuer host.
- `docs/configuration.md`, `docs/ldap.md`, `DEPLOYMENT.md`, and `secrets.js.example` document the new `ldapsHost`/`ldapsPort` options and recommended network layouts.
### theta-env own changes
- `setup.env.example` adds optional `CFG_LDAPS_HOST` for the internal LDAPS hostname.
- `setup.sh` passes `CFG_LDAPS_HOST` into the generated `./config/sso-secrets.js` as `ldap.ldapsHost`.
- `config.example/sso-secrets.js.example` documents `ldap.ldapsHost` / `ldap.ldapsPort`.
- `.env.example` adds `LDAPS_HOST` for legacy `.env` migrations.
- `docker-compose.yml` comments warn against forwarding 636 to the public internet.
- `README.md` explains the `CFG_LDAPS_HOST` recommendation in the port-forwarding section.
## [1.1.18] - 2026-07-18 ## [1.1.18] - 2026-07-18
### Bumped ### Bumped
@@ -257,7 +292,7 @@ First tagged release. Establishes the `vX.Y.Z` tag convention going forward.
- proxy -> [v1.1.0](https://github.com/theta42/proxy/releases/tag/v1.1.0) - proxy -> [v1.1.0](https://github.com/theta42/proxy/releases/tag/v1.1.0)
- sso-manager-node -> [v1.1.0](https://github.com/theta42/sso-manager-node/releases/tag/v1.1.0) - sso-manager-node -> [v1.1.0](https://github.com/theta42/sso-manager-node/releases/tag/v1.1.0)
[Unreleased]: https://github.com/theta42/theta-env/compare/v1.1.18...HEAD [Unreleased]: https://github.com/theta42/theta-env/compare/v1.1.20...HEAD
[1.1.17]: https://github.com/theta42/theta-env/compare/v1.1.16...v1.1.17 [1.1.17]: https://github.com/theta42/theta-env/compare/v1.1.16...v1.1.17
[1.1.16]: https://github.com/theta42/theta-env/compare/v1.1.15...v1.1.16 [1.1.16]: https://github.com/theta42/theta-env/compare/v1.1.15...v1.1.16
[1.1.15]: https://github.com/theta42/theta-env/compare/v1.1.14...v1.1.15 [1.1.15]: https://github.com/theta42/theta-env/compare/v1.1.14...v1.1.15
+4
View File
@@ -120,6 +120,10 @@ Optional extra ports (only if you need them):
- **636** (LDAPS) — only if a legacy app on another machine binds to LDAP - **636** (LDAPS) — only if a legacy app on another machine binds to LDAP
directly over the network. The proxy itself reaches LDAP over the internal directly over the network. The proxy itself reaches LDAP over the internal
Docker network, so you do **not** need to expose 636 for the stack to work. Docker network, so you do **not** need to expose 636 for the stack to work.
**Do not forward 636 to the public internet.** If you need LAN clients to bind
LDAP, set `CFG_LDAPS_HOST=ldap.internal.example.com` (or `sso-manager` for
same-host Docker clients) in `setup.env` and use an internal DNS record / cert
SAN. The default shows the public SSO hostname, which implies a public route.
### 4. Docker + Docker Compose ### 4. Docker + Docker Compose
+3
View File
@@ -17,6 +17,9 @@ module.exports = {
bindPassword: 'CHANGE-ME', // slapd root + app bind password bindPassword: 'CHANGE-ME', // slapd root + app bind password
userBase: 'ou=people,dc=example,dc=com', userBase: 'ou=people,dc=example,dc=com',
groupBase: 'ou=groups,dc=example,dc=com', groupBase: 'ou=groups,dc=example,dc=com',
// ldapsHost: 'ldap.internal.example.com', // optional: internal-only hostname
// shown on /integrations for direct LDAPS binds. Empty -> derive from issuer.
// ldapsPort: 636,
}, },
smtp: { // optional; leave host '' to skip smtp: { // optional; leave host '' to skip
host: '', port: 587, secure: false, host: '', port: 587, secure: false,
+2
View File
@@ -46,6 +46,8 @@ services:
- "${SSO_BIND:-0.0.0.0}:${SSO_PORT:-3001}:3001" - "${SSO_BIND:-0.0.0.0}:${SSO_PORT:-3001}:3001"
# LDAPS for EXTERNAL direct-LDAP clients (legacy apps). The proxy itself # LDAPS for EXTERNAL direct-LDAP clients (legacy apps). The proxy itself
# reaches LDAPS over theta-net (sso-manager:636) without this host mapping. # reaches LDAPS over theta-net (sso-manager:636) without this host mapping.
# Prefer an internal-only hostname (set CFG_LDAPS_HOST in setup.env / ldapsHost
# in sso-secrets.js) and do NOT forward 636 to the public internet.
- "${LDAPS_PORT:-636}:636" - "${LDAPS_PORT:-636}:636"
# Plain LDAP (389) is NOT mapped — direct-LDAP clients should use LDAPS. # Plain LDAP (389) is NOT mapped — direct-LDAP clients should use LDAPS.
environment: environment:
+1 -1
Submodule proxy updated: 289a9587d6...21e295615b
+6
View File
@@ -36,6 +36,12 @@ CFG_DOMAIN=example.com
#CFG_ADMIN_UID=admin # initial SSO admin username #CFG_ADMIN_UID=admin # initial SSO admin username
#CFG_ADMIN_EMAIL=admin@proxy.example.com # defaults to admin@<proxyHost> #CFG_ADMIN_EMAIL=admin@proxy.example.com # defaults to admin@<proxyHost>
#CFG_LDAP_CERT_CN= # LDAP TLS cert CN; empty -> defaults to the domain #CFG_LDAP_CERT_CN= # LDAP TLS cert CN; empty -> defaults to the domain
#
# Hostname advertised on the SSO /integrations page for direct LDAPS binds.
# Leave blank to derive it from the public SSO host (same as oauth.issuer).
# Recommended: set an internal-only name like 'ldap.internal.example.com' or
# 'sso-manager' so clients don't need a public 636 port forward. See docs.
#CFG_LDAPS_HOST=
# Optional SMTP (outbound email from the SSO app). Leave blank to disable: # Optional SMTP (outbound email from the SSO app). Leave blank to disable:
#CFG_SMTP_HOST=smtp.example.com #CFG_SMTP_HOST=smtp.example.com
+6
View File
@@ -240,6 +240,8 @@ module.exports = {
bindPassword: $(js_str "$CFG_LDAP_ADMIN_PASS"), bindPassword: $(js_str "$CFG_LDAP_ADMIN_PASS"),
userBase: $(js_str "ou=people,${dn}"), userBase: $(js_str "ou=people,${dn}"),
groupBase: $(js_str "ou=groups,${dn}"), groupBase: $(js_str "ou=groups,${dn}"),
ldapsHost: $(js_str "${CFG_LDAPS_HOST:-}"),
ldapsPort: 636,
}, },
smtp: { smtp: {
host: $(js_str "${CFG_SMTP_HOST:-}"), host: $(js_str "${CFG_SMTP_HOST:-}"),
@@ -355,6 +357,7 @@ ensure_config() {
CFG_ADMIN_UID="${CFG_ADMIN_UID:-}" CFG_ADMIN_UID="${CFG_ADMIN_UID:-}"
CFG_ADMIN_EMAIL="${CFG_ADMIN_EMAIL:-}" CFG_ADMIN_EMAIL="${CFG_ADMIN_EMAIL:-}"
CFG_LDAP_CERT_CN="${CFG_LDAP_CERT_CN:-}" CFG_LDAP_CERT_CN="${CFG_LDAP_CERT_CN:-}"
CFG_LDAPS_HOST="${CFG_LDAPS_HOST:-}"
CFG_CLIENT_ID="${CFG_CLIENT_ID:-}" CFG_CLIENT_ID="${CFG_CLIENT_ID:-}"
CFG_CLIENT_SECRET="${CFG_CLIENT_SECRET:-}" CFG_CLIENT_SECRET="${CFG_CLIENT_SECRET:-}"
CFG_LDAP_ADMIN_PASS="${CFG_LDAP_ADMIN_PASS:-}" CFG_LDAP_ADMIN_PASS="${CFG_LDAP_ADMIN_PASS:-}"
@@ -383,6 +386,8 @@ ensure_config() {
CFG_ADMIN_PASS="${BOOTSTRAP_ADMIN_PASS:-$CFG_ADMIN_PASS}" CFG_ADMIN_PASS="${BOOTSTRAP_ADMIN_PASS:-$CFG_ADMIN_PASS}"
CFG_SVC_PASS="${LDAP_SERVICE_PASS:-$CFG_SVC_PASS}" CFG_SVC_PASS="${LDAP_SERVICE_PASS:-$CFG_SVC_PASS}"
CFG_LDAP_CERT_CN="${LDAP_CERT_CN:-$CFG_LDAP_CERT_CN}" CFG_LDAP_CERT_CN="${LDAP_CERT_CN:-$CFG_LDAP_CERT_CN}"
# .env has no legacy LDAPS_HOST key; this stays as set in setup.env/env.
CFG_LDAPS_HOST="${CFG_LDAPS_HOST:-}"
CFG_SMTP_HOST="${SMTP_HOST:-${CFG_SMTP_HOST:-}}" CFG_SMTP_HOST="${SMTP_HOST:-${CFG_SMTP_HOST:-}}"
CFG_SMTP_PORT="${SMTP_PORT:-${CFG_SMTP_PORT:-}}" CFG_SMTP_PORT="${SMTP_PORT:-${CFG_SMTP_PORT:-}}"
CFG_SMTP_USER="${SMTP_USER:-${CFG_SMTP_USER:-}}" CFG_SMTP_USER="${SMTP_USER:-${CFG_SMTP_USER:-}}"
@@ -416,6 +421,7 @@ ensure_config() {
CFG_ADMIN_UID="${CFG_ADMIN_UID:-admin}" CFG_ADMIN_UID="${CFG_ADMIN_UID:-admin}"
CFG_ADMIN_EMAIL="${CFG_ADMIN_EMAIL:-admin@$CFG_PROXY_HOST}" CFG_ADMIN_EMAIL="${CFG_ADMIN_EMAIL:-admin@$CFG_PROXY_HOST}"
CFG_LDAP_CERT_CN="${CFG_LDAP_CERT_CN:-}" CFG_LDAP_CERT_CN="${CFG_LDAP_CERT_CN:-}"
CFG_LDAPS_HOST="${CFG_LDAPS_HOST:-}"
CFG_CLIENT_ID="${CFG_CLIENT_ID:-}" CFG_CLIENT_ID="${CFG_CLIENT_ID:-}"
CFG_CLIENT_SECRET="${CFG_CLIENT_SECRET:-}" CFG_CLIENT_SECRET="${CFG_CLIENT_SECRET:-}"
# Random secrets (generated fresh unless sourced/migrated above). These do # Random secrets (generated fresh unless sourced/migrated above). These do