Migrate Timezone and Hidden Site PIN menus; harden menu framework against set -e; bump to v2.1.0

Two more menus migrated onto lib/menu.sh + lib/config.sh, chosen
specifically because neither touches config.json - a third and fourth
shape for the framework (a system command via timedatectl, and a flat
PIN file), on top of Sites' list CRUD and Display's JSON toggles.

- menus/timezone.sh: also replaces the legacy script's hand-numbered
  18-entry case statement with a plain data list (TIMEZONE_COMMON_ZONES)
  plus one handler that reads the number run_menu hands it - adding or
  removing a zone never touches numbering anywhere else. Required a
  small run_menu addition: handlers now receive the chosen 1-based
  number as $1, so one handler can serve a whole data-driven list
  instead of needing a wrapper function per entry.
- menus/hidden_pin.sh: set/disable/reset the PIN gating hidden pages.

Testing menus/timezone.sh surfaced a real bug before it ever shipped:
this whole tool runs under `set -e`, and set_timezone() rejecting an
invalid zone via a bare `return 1` as its last statement took down the
*entire* install.sh session, not just that one action - a single typo
would silently drop the user back to their shell. Fixed at the
framework level in lib/menu.sh (run_menu now absorbs a failed handler's
exit code) rather than patching set_timezone alone, since any future
menu could hit the same trap. Verified against the real install.sh as a
genuine non-root user: an invalid timezone now logs an error and
redraws the Timezone menu instead of killing the session (confirmed
exit code 0 at the end of the run). Note this specific hazard was
introduced by this session's own return-1 idiom, not inherited from the
legacy script, which never uses a bare return 1 in these functions.

Also per the user: left the old configure_sites/configure_touch_controls/
configure_navigation_security/configure_optional_features functions in
ubuntu-based-kiosk.sh untouched for now (still carrying the v2.0.0
settings-clobber and reorder bugs) rather than removing them - they'll
be retired in one pass once enough of Core Settings/Addons/Advanced is
migrated. Bumped SCRIPT_VERSION to 2.1.0 with matching changelog entries
in the script header and Readme, and updated the Readme's "Modular
Management" section to state plainly what is and isn't migrated yet.

Verified:
- Full regression: re-ran the Sites and Display scratch-config test
  suites against the updated run_menu signature - both still clean.
- New scratch-config tests for hidden_pin.sh (set/mismatch/reject/
  disable/reset, correct file permissions) and timezone.sh (builder
  entry count, common-zone pick by index, manual entry with legacy
  US/* alias normalization, region search + cancel, invalid-zone
  rejection) - all correct, with timedatectl/sudo stubbed only where
  needed to avoid mutating this sandbox's real system clock/timezone.
- End-to-end: ran the real install.sh as a genuine non-root, non-"kiosk"
  user, navigating Timezone -> manual entry -> invalid zone -> confirmed
  no crash and a normal return to the menu, then Hidden Site PIN -> set
  a PIN -> confirmed the file on disk (mode 600, correct content) ->
  clean exit (code 0).
This commit is contained in:
Claude
2026-08-18 16:33:12 +00:00
parent c1370edc3e
commit 074b2ec2e3
6 changed files with 299 additions and 24 deletions
+26 -2
View File
@@ -1,8 +1,32 @@
#!/bin/bash
################################################################################
### Ubuntu Based Kiosk v2.0.0 ###
### Ubuntu Based Kiosk v2.1.0 ###
################################################################################
#
# RELEASE v2.1.0 - Two More Menus Migrated, Menu Framework Hardened
# - New in ./install.sh: Timezone (menus/timezone.sh) and Hidden Site PIN
# (menus/hidden_pin.sh) menus, alongside Sites & Page Timing and Display
# & Interaction from v2.0.0. Timezone doubles as a demonstration of the
# framework: the old hand-numbered 18-entry case statement is now just
# a data list plus one handler.
# - Hardened lib/menu.sh: since this whole tool runs under `set -e`, a menu
# action that legitimately fails (e.g. rejecting an invalid timezone) and
# returns non-zero as its last statement could take down the *entire*
# session, not just that one action - one typo would silently drop the
# user back to their shell. Caught by testing menus/timezone.sh (its
# set_timezone() does `return 1` on an invalid zone) before this ever
# shipped; run_menu() now absorbs a failed handler's exit code so it
# only redraws the menu, protecting every menu, present and future.
# - The old (unmigrated) configure_sites/configure_touch_controls/
# configure_navigation_security/configure_optional_features functions
# still live in this script, unchanged, and still have both v2.0.0 bugs
# above - left in place deliberately until enough of Core Settings/
# Addons/Advanced is migrated to retire them in one pass. configure_
# timezone/configure_hidden_site_pin don't share the set -e hazard
# (they never use a bare `return 1`), but are otherwise also still
# here unchanged pending the same cleanup. See Readme.md ("Modular
# Management") for current migration status.
#
# RELEASE v2.0.0 - Modular Management & Unversioned Filename
# - New git-clone-based management path: lib/menu.sh (reusable numbered-menu
# framework) + lib/config.sh (single config.json load/save) + menus/*.sh,
@@ -85,7 +109,7 @@ set -euo pipefail
### SECTION 1: CONSTANTS & GLOBALS
################################################################################
SCRIPT_VERSION="2.0.0"
SCRIPT_VERSION="2.1.0"
# Resolve the real path to this script file.
# When piped (curl|bash or wget|bash), BASH_SOURCE[0] is a pipe descriptor,