Supersedes the previous commit's reverse-proxy approach entirely: instead
of Caddy routing to Easy Asterisk's own separate vendored web admin
process, the dashboard now reimplements that admin's functionality
natively - one process, one page, real tab-switching, no separate app to
proxy, patch, or embed. Reverts asterisk.sh/asterisk-digital-ocean.sh's
WEBADMIN_BASE_PATH vendor patching and Caddy-skip logic back to their
pre-proxy state (confirmed identical via diff) since neither is needed
anymore.
security-dashboard.sh additions:
- ea_* functions covering full device/category/room parity with
vendor/easy-asterisk/easy-asterisk-v0.10.0.sh's own web admin: list/add/
delete/rename/change-category for devices, list/create/delete/rename for
categories, list/create/delete/rename/add-member/remove-member for
rooms, plus live registered/unregistered status. Reads go straight
through the host-side bind-mounted config files (same as the existing
list_extensions() already does for pjsip.conf); writes go through
`docker exec -i <container> tee <path>` instead of a direct host-side
write, since Easy Asterisk's container writes these files as its own
internal user and a host-side write would just be fighting that
ownership again on the next container restart.
- Found and fixed a real bug (inherited from the vendored admin's own
template, not introduced here): a plain non-mobile LAN device leaves
both the keepalive and ice template lines empty, producing two
consecutive blank lines inside the endpoint's pjsip.conf stanza instead
of one - which broke the delete/rename/category-change parsers' "blank
line ends this device's block" boundary detection, leaving an orphaned
tail of config behind on delete. Fixed by building the endpoint block
from a filtered line list instead of positional template blanks.
Confirmed via a full synthetic add/rename/category-change/delete cycle
against realistic pjsip.conf/categories.conf/rooms.conf fixtures (with
docker exec mocked to a local file) - round-trips back to the original
fixture correctly.
- New plumbing: _secdash_grant_asterisk_access grants read-only access to
categories.conf/rooms.conf's directory (separate from pjsip.conf's,
confirmed against the vendored source - /etc/easy-asterisk/*, not
/etc/asterisk/*); _secdash_write_sudoers adds six exact (no wildcards)
docker-exec sudoers entries scoped to the one Asterisk container
actually installed, validated live with visudo -c; _secdash_write_systemd_unit
passes the new ASTERISK_EA_CONFIG_DIR/ASTERISK_EA_CONTAINER env vars and
adds the config dir to ReadOnlyPaths, validated live with
systemd-analyze verify.
- New UI: Asterisk Admin tab with Devices/Categories/Rooms cards, sortable
tables matching the existing style, inline category-reassignment
dropdowns, and per-room member chips with an inline add-member picker.
Nav button visibility now checks live container reachability
(/api/ea-status) instead of just Asterisk-install detection.
Still unverified: the actual `docker exec` calls (module reload, dialplan
rebuild, live status) against a real running Easy Asterisk container -
only the file-parsing/transformation logic itself has been exercised, via
mocked writes, not the real container plumbing.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ho9mZgAkVpdz7S5wJkg8Nf