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).
89 lines
2.5 KiB
Bash
89 lines
2.5 KiB
Bash
#!/bin/bash
|
|
################################################################################
|
|
# menus/hidden_pin.sh - "Hidden Site PIN" menu.
|
|
#
|
|
# Guards access to hidden pages (duration = -1, see menus/sites.sh) via a
|
|
# flat PIN file rather than config.json - a fourth shape for the framework
|
|
# to prove out (plain file, not JSON at all).
|
|
#
|
|
# Depends on: lib/menu.sh, lib/config.sh being sourced first.
|
|
################################################################################
|
|
|
|
hidden_pin_file() {
|
|
echo "$KIOSK_DIR/.jitsi-pin"
|
|
}
|
|
|
|
hidden_pin_status() {
|
|
local pin_file
|
|
pin_file=$(hidden_pin_file)
|
|
|
|
if sudo -u "$KIOSK_USER" test -f "$pin_file" 2>/dev/null; then
|
|
local current_pin
|
|
current_pin=$(sudo -u "$KIOSK_USER" cat "$pin_file" 2>/dev/null)
|
|
if [[ "$current_pin" == "NOPIN" ]]; then
|
|
echo "Current: no PIN (hidden pages open to anyone)"
|
|
else
|
|
echo "Current: PIN set (${#current_pin} digits)"
|
|
fi
|
|
else
|
|
echo "Current: not configured (default: 1234)"
|
|
fi
|
|
}
|
|
|
|
hidden_pin_menu_builder() {
|
|
MENU_LABELS=("Set new PIN (4-8 digits)" "Disable PIN (open access)" "Reset to default (1234)")
|
|
MENU_HANDLERS=(action_set_pin action_disable_pin action_reset_pin)
|
|
}
|
|
|
|
hidden_pin_menu() {
|
|
run_menu "HIDDEN SITE PIN" hidden_pin_menu_builder hidden_pin_status
|
|
}
|
|
|
|
################################################################################
|
|
# Actions
|
|
################################################################################
|
|
|
|
write_pin() {
|
|
local value="$1"
|
|
local pin_file
|
|
pin_file=$(hidden_pin_file)
|
|
|
|
sudo mkdir -p "$KIOSK_DIR"
|
|
echo "$value" | sudo -u "$KIOSK_USER" tee "$pin_file" > /dev/null
|
|
sudo -u "$KIOSK_USER" chmod 600 "$pin_file"
|
|
log_warning "Restart the kiosk display for this to take effect"
|
|
}
|
|
|
|
action_set_pin() {
|
|
echo
|
|
local new_pin confirm_pin
|
|
while true; do
|
|
read -r -p "Enter new PIN (4-8 digits): " new_pin
|
|
|
|
if [[ ! "$new_pin" =~ ^[0-9]{4,8}$ ]]; then
|
|
echo "❌ PIN must be 4-8 digits"
|
|
continue
|
|
fi
|
|
|
|
read -r -p "Confirm PIN: " confirm_pin
|
|
|
|
if [[ "$new_pin" == "$confirm_pin" ]]; then
|
|
write_pin "$new_pin"
|
|
log_success "PIN updated"
|
|
break
|
|
else
|
|
echo "❌ PINs don't match, try again"
|
|
fi
|
|
done
|
|
}
|
|
|
|
action_disable_pin() {
|
|
write_pin "NOPIN"
|
|
log_success "PIN disabled - hidden pages accessible without a PIN"
|
|
}
|
|
|
|
action_reset_pin() {
|
|
write_pin "1234"
|
|
log_success "PIN reset to default (1234)"
|
|
}
|