3e87ad86ab
Replaces the old flag-driven, copy-based installer with an idempotent
git-clone-and-symlink installer matching theta42/proxy's ops/install.sh
pattern, so `wget -O - .../install.sh | sudo bash` works the same way
for both apps:
- Installs to /opt/theta42/sso-manager (was /opt/sso-manager, and the
repo had to already be checked out locally -- now it clones itself).
- First run only: bootstraps OpenLDAP (modules, overlays, schema,
directory tree, SSO groups -- ops/ldap-setup.sh) with a generated
admin password + JWT secret, and seeds /etc/sso-manager/secrets.js
(was /opt/sso-manager/conf/secrets.js, hand-filled from CLI flags).
Later runs never touch LDAP or the secrets file again.
- ops/systemd/sso-manager.service now points at the new install path
and sets CONF_SECRETS=/etc/sso-manager/secrets.js (requires
@simpleworkjs/conf >= 1.2.0, already the pinned version) instead of
the app needing a config file inside the repo checkout.
- Prints the version it's updating from/to (or "Already up to date")
on every run, instead of updating silently.
Two real bugs found and fixed while testing this end-to-end in a clean
container:
- The debconf `slapd/domain` value was computed as
`${LDAP_BASE_DN#dc=}` ("example,dc=com" for "dc=example,dc=com")
instead of a proper dotted domain -- slapd's postinst hangs
indefinitely on a malformed domain instead of failing cleanly.
Fixed to derive it the same way the secrets file already did
("example.com").
- ops/ldap-setup.sh's ppolicy-overlay checks used an LDAP substring
filter, `(olcOverlay=*ppolicy*)`, against an attribute that doesn't
support substring matching -- it silently matched nothing even when
the overlay was correctly configured (stored as "{0}ppolicy"),
so the final verification always reported failure and `set -e`
aborted the installer after LDAP was set up but before the app was.
Fixed to filter on `(objectClass=olcOverlayConfig)` and let the
existing DN-based grep narrow it down, matching the pattern already
used by every other check in that script.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
75 lines
3.6 KiB
Plaintext
75 lines
3.6 KiB
Plaintext
'use strict';
|
|
|
|
// Example secrets configuration file (file-based config).
|
|
//
|
|
// Bare-metal: install.sh seeds a filled-in version of this file at
|
|
// /etc/sso-manager/secrets.js on first run (LDAP + JWT already live; only
|
|
// SMTP is left as a placeholder). Only write this one by hand if you're
|
|
// skipping install.sh's LDAP bootstrap (SKIP_LDAP=true) or setting up
|
|
// manually.
|
|
// Docker / unified stack: place at ./config/sso-secrets.js and bind-mount
|
|
// ./config at /config (see docker-compose.yml); docker-entrypoint.sh points
|
|
// the CONF_SECRETS env var at it so @simpleworkjs/conf reads it.
|
|
//
|
|
// Values here override conf/base.js and win over <environment>.js. `app_*` env
|
|
// vars (if any are set) override this file too — so the Docker stack passes NO
|
|
// app_* env, keeping this file authoritative.
|
|
//
|
|
// The app only reads the keys it knows (port, name, ldap, smtp, voipms, oauth).
|
|
// The extra `stack`, `bootstrap`, and `serviceAccountPass` keys below are read
|
|
// by the orchestrator (docker-entrypoint.sh, the bootstrap script, setup.sh)
|
|
// and ignored by the app — safe to leave them out for bare-metal use.
|
|
|
|
module.exports = {
|
|
port: 3001,
|
|
name: 'SSO Manager', // shown in UI and outbound email
|
|
logo: '/static/img/theta42.svg', // nav/favicon image; point at your own file under public/ to white-label
|
|
ldap: {
|
|
url: 'ldap://localhost', // or ldaps://host:636 for TLS
|
|
bindDN: 'cn=admin,dc=example,dc=com',
|
|
bindPassword: 'your-ldap-password',
|
|
userBase: 'ou=people,dc=example,dc=com',
|
|
groupBase: 'ou=groups,dc=example,dc=com',
|
|
},
|
|
smtp: {
|
|
host: 'smtp.example.com',
|
|
port: 587,
|
|
secure: false, // true for 465, false for other ports
|
|
user: 'noreply@example.com',
|
|
pass: 'your-smtp-password',
|
|
from: 'SSO Manager <noreply@example.com>',
|
|
},
|
|
voipms: {
|
|
username: '', // VoIP.ms username (optional)
|
|
password: '', // VoIP.ms password (optional)
|
|
did: '', // VoIP.ms DID (optional)
|
|
},
|
|
oauth: {
|
|
issuer: '', // falls back to the request host at runtime
|
|
jwtSecret: 'generate-a-secure-random-string-here',
|
|
token_lifetime: {
|
|
access_token: 3600, // 1 hour in seconds
|
|
refresh_token: 2592000 // 30 days in seconds
|
|
}
|
|
},
|
|
|
|
// ── Orchestrator-only keys (ignored by the app) ──────────────────────────
|
|
// Read by docker-entrypoint.sh (server-side slapd config + validation), the
|
|
// superproject bootstrap script, and setup.sh. Omit for bare-metal use.
|
|
stack: {
|
|
ldapBaseDn: 'dc=example,dc=com', // slapd suffix (also drives seed OUs).
|
|
// The base DN also appears in ldap.bindDN/userBase/groupBase above and
|
|
// in oauth.issuer — keep them consistent with this value
|
|
// (cn=admin,<dn>, ou=people,<dn>, ou=groups,<dn>, https://<ssoHost>).
|
|
ldapDomain: 'example.com', // default cert CN + OAuth issuer host
|
|
ldapCertCn: '', // cert CN; empty -> defaults to ldapDomain
|
|
ssoHost: 'sso.example.com', // public SSO hostname (OAuth issuer URL)
|
|
proxyHost: 'proxy.example.com', // public proxy hostname
|
|
},
|
|
bootstrap: {
|
|
adminUid: 'admin', // initial SSO admin username
|
|
adminPass: 'change-me', // initial SSO admin password
|
|
adminEmail: 'admin@example.com', // initial SSO admin email
|
|
},
|
|
serviceAccountPass: 'change-me', // LDAP password the proxy binds with
|
|
}; |