Compare commits

...

4 Commits

Author SHA1 Message Date
wmantly e249b4e168 Merge pull request #155 from theta42/bump-1.1.6
Bump version to 1.1.6
2026-07-16 19:04:34 -04:00
wmantly 34b1413c96 Bump version to 1.1.6; update CHANGELOG 2026-07-16 19:02:59 -04:00
wmantly eded87b6f9 Merge pull request #154 from theta42/fix-host-auth-mode-radios
hosts.ejs: fix Authentication tab radios not enforcing mutual exclusivity
2026-07-16 19:01:26 -04:00
wmantly a57f3f03f6 hosts.ejs: fix Authentication tab radios not enforcing mutual exclusivity
The three auth_mode radios (Off / Basic / SSO) had no shared [name]
attribute, so per the HTML spec each was its own independent group --
clicking one didn't uncheck the others, letting multiple options
appear selected at once despite the page's own text saying "basic
auth and SSO can't both be enabled."

Added name="auth_mode" to restore native browser radio-group
behavior. The original comment claimed the radios were deliberately
kept nameless to avoid polluting the submitted form data (formAJAX
serializes every [name] field in the form), but that reasoning
doesn't hold: model-redis's processKeys() rebuilds the saved object
strictly from the Host model's own _keyMap, so an unrecognized
auth_mode field is silently stripped before anything is ever
persisted -- confirmed directly with model-redis's own
object_validate.js. Updated the stale comment accordingly.
2026-07-16 18:59:50 -04:00
4 changed files with 20 additions and 11 deletions
+7 -1
View File
@@ -6,6 +6,11 @@ correspond to git tags (`vX.Y.Z`) and `nodejs/package.json`'s `version`.
## [Unreleased] ## [Unreleased]
## [1.1.6] - 2026-07-16
### Fixed
- Hosts admin UI's Authentication tab radios (Off / Basic / SSO) had no shared `name`, so clicking one didn't uncheck the others -- multiple options could appear selected at once. Added `name="auth_mode"` to restore standard exclusive radio-group behavior.
## [1.1.5] - 2026-07-16 ## [1.1.5] - 2026-07-16
### Fixed ### Fixed
@@ -44,7 +49,8 @@ First tagged release. Establishes the `vX.Y.Z` tag convention that the in-app up
- Standalone backup script (`ops/backup.sh`) for deployments not using theta-env's orchestrator — snapshots Redis and `./config`, with retention. - Standalone backup script (`ops/backup.sh`) for deployments not using theta-env's orchestrator — snapshots Redis and `./config`, with retention.
- Admin-only in-app banner that checks GitHub releases every 24h and surfaces available updates. - Admin-only in-app banner that checks GitHub releases every 24h and surfaces available updates.
[Unreleased]: https://github.com/theta42/proxy/compare/v1.1.5...HEAD [Unreleased]: https://github.com/theta42/proxy/compare/v1.1.6...HEAD
[1.1.6]: https://github.com/theta42/proxy/compare/v1.1.5...v1.1.6
[1.1.5]: https://github.com/theta42/proxy/compare/v1.1.4...v1.1.5 [1.1.5]: https://github.com/theta42/proxy/compare/v1.1.4...v1.1.5
[1.1.4]: https://github.com/theta42/proxy/compare/v1.1.3...v1.1.4 [1.1.4]: https://github.com/theta42/proxy/compare/v1.1.3...v1.1.4
[1.1.3]: https://github.com/theta42/proxy/compare/v1.1.2...v1.1.3 [1.1.3]: https://github.com/theta42/proxy/compare/v1.1.2...v1.1.3
+2 -2
View File
@@ -1,12 +1,12 @@
{ {
"name": "proxy-api", "name": "proxy-api",
"version": "1.1.5", "version": "1.1.6",
"lockfileVersion": 3, "lockfileVersion": 3,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "proxy-api", "name": "proxy-api",
"version": "1.1.5", "version": "1.1.6",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@fortawesome/fontawesome-free": "^7.3.0", "@fortawesome/fontawesome-free": "^7.3.0",
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "proxy-api", "name": "proxy-api",
"version": "1.1.5", "version": "1.1.6",
"private": true, "private": true,
"author": [ "author": [
{ {
+10 -7
View File
@@ -115,10 +115,13 @@
// attach users to). // attach users to).
let hostFormCurrentHost = null; let hostFormCurrentHost = null;
// The auth_mode radios aren't real form fields (no [name]); this keeps the // The auth_mode radios share a name so the browser enforces mutual
// two hidden basicauth_enabled/sso_enabled inputs — the ones actually // exclusivity, but auth_mode itself isn't in Host's _keyMap -- the model
// submitted — in sync so only one can ever be true, and shows/hides the // layer strips unrecognized fields on save (see model-redis's
// matching field group. // processKeys), so it's never actually persisted. This keeps the two
// hidden basicauth_enabled/sso_enabled inputs -- the real, submitted
// fields -- in sync with whichever radio is selected, and shows/hides
// the matching field group.
function hostAuthModeChanged(mode){ function hostAuthModeChanged(mode){
$('#basicauth_enabled-hidden').val(mode === 'basic' ? 'true' : 'false'); $('#basicauth_enabled-hidden').val(mode === 'basic' ? 'true' : 'false');
$('#sso_enabled-hidden').val(mode === 'sso' ? 'true' : 'false'); $('#sso_enabled-hidden').val(mode === 'sso' ? 'true' : 'false');
@@ -713,15 +716,15 @@
<div class="form-group"> <div class="form-group">
<div class="radio"><label> <div class="radio"><label>
<input type="radio" id="auth_mode-none" value="none" checked onchange="hostAuthModeChanged('none')"> <input type="radio" name="auth_mode" id="auth_mode-none" value="none" checked onchange="hostAuthModeChanged('none')">
Off (public) Off (public)
</label></div> </label></div>
<div class="radio"><label> <div class="radio"><label>
<input type="radio" id="auth_mode-basic" value="basic" onchange="hostAuthModeChanged('basic')"> <input type="radio" name="auth_mode" id="auth_mode-basic" value="basic" onchange="hostAuthModeChanged('basic')">
Basic authentication Basic authentication
</label></div> </label></div>
<div class="radio"><label> <div class="radio"><label>
<input type="radio" id="auth_mode-sso" value="sso" onchange="hostAuthModeChanged('sso')"> <input type="radio" name="auth_mode" id="auth_mode-sso" value="sso" onchange="hostAuthModeChanged('sso')">
Single sign-on (SSO) Single sign-on (SSO)
</label></div> </label></div>
</div> </div>