Host modal: Authentication tab, wildcard-child default, allow-list autocomplete

- Default the "Parent Wildcard" challenge type when a wildcard parent exists.
- Split Authentication (basic auth + SSO) into its own tab; Access keeps IP
  allow/deny.
- Add GET /api/host/auth-suggestions (authenticated host editors, not just
  admins) and datalist-backed "type to search + Add" pickers for the SSO
  allowed-users/groups lists.

Verified in a browser (tab present, datalist populated, picker appends deduped).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-07-11 12:24:29 -04:00
parent 774d8e815e
commit c98214cc76
2 changed files with 85 additions and 11 deletions
+29 -1
View File
@@ -1,7 +1,10 @@
'use strict';
const router = require('express').Router();
const {Host, Domain} = require('../models').models;
const conf = require('@simpleworkjs/conf');
const {Host, Domain, User} = require('../models').models;
const {LocalGroup} = require('../models/local_group');
const {Permission} = require('../models/permission');
const authz = require('../middleware/authz');
const {normalizeHostFeatures} = require('../utils/host_features');
const {collectHostFieldErrors} = require('../utils/hostname_validate');
@@ -25,6 +28,31 @@ function hashHostSecrets(body){
}
}
// Autocomplete source for the per-host auth allow-lists (SSO users/groups).
// Available to any authenticated host editor (not just global admins). Groups
// are derived from local groups, existing permission group-subjects, and the
// conf.auth admin/role-map groups.
router.get('/auth-suggestions', async function(req, res, next){
try{
let users = [];
try{ users = (await User.list()) || []; }catch(error){ /* none */ }
let groups = new Set();
try{ for(let g of await LocalGroup.list()) groups.add(g); }catch(error){ /* none */ }
try{
for(let p of await Permission.listDetail()){
if(p.subjectType === 'group' && p.subject) groups.add(p.subject);
}
}catch(error){ /* none */ }
for(let g of (conf.auth && conf.auth.adminGroups) || []) groups.add(g);
for(let g of Object.keys((conf.auth && conf.auth.groupRoleMap) || {})) groups.add(g);
return res.json({users, groups: [...groups].sort()});
}catch(error){
return next(error);
}
});
router.get('/', async function(req, res, next){
try{
let results = await Model[req.query.detail ? "listDetail" : "list"]();