- Add standalone.enabled config flag to switch between LDAP+SSO and
ORM-backed backends without changing the production code path
- New ORM models: StandaloneUser (uid, passwordHash, sshPublicKeys,
groups) and StandaloneHost (slug, displayName, kind, metadata)
- user_file.js and hosts_file.js implement the same interfaces as the
LDAP client and accessibleHosts() respectively
- models/user_ldap.js and utils/access.js become conditional facades
that delegate based on conf.standalone.enabled at require time
- Zero changes to ssh_server.js core logic, bridge.js, key_inject.js,
tui_picker.js, or any other consumer
- Fix ssh_server.js: use ?? instead of || for listenPort (0 is falsy)
- Fix ssh_server.js: register session listeners before awaiting
audit.create() so client exec/shell requests aren't rejected
- Patch StringField.toSequelize() and IntegerField.toSequelize() to
pass through primaryKey (the ORM's UUIDField already does this)
- 47 tests pass (24 existing + 15 new unit + 3 existing integration
+ 5 new standalone integration)
- Defaults to SQLite; any Sequelize dialect works via conf.orm
Co-Authored-By: Claude <noreply@anthropic.com>