Commit Graph
100 Commits
Author SHA1 Message Date
Claude f01781de41 Add live HDMI/display hotplug handling via udev + systemd
Adds a udev rule (DRM 'change' events) that triggers a new kiosk-hotplug.service, which re-runs the same xrandr mirroring logic as the Openbox autostart script. External displays plugged in after boot now get mirrored without requiring a login or lightdm restart. Named kiosk-hotplug (not kiosk-display-*) to avoid collision with the existing kiosk-display-* wildcard cleanup in remove_all_schedules(). Also removes the udev rule during Complete Uninstall and documents the behavior in the README.
2026-08-02 22:37:39 +00:00
Claude 68a7345f5b Mirror external HDMI/monitor output onto primary display automatically
Openbox autostart now detects any connected output beyond the primary and mirrors the kiosk content onto it via xrandr, instead of leaving detected-but-unused external displays dark. Also documents the behavior, its limitation (applies at session start, not live hotplug), and adds an HDMI troubleshooting section to the README.
2026-08-02 22:34:19 +00:00
Claude b5d37fa646 Install net-tools and ncdu; curl/git already covered
apt install already includes curl and git; adds net-tools and ncdu to the same idempotent apt install so they're present on fresh installs without duplicating already-installed packages.
2026-08-02 22:15:15 +00:00
Claude ca00674e4c Add offline/air-gapped download instructions to README
Clarifies that the installer script can be downloaded on another machine and transferred via USB, while noting the kiosk machine still needs internet access during install for apt/npm packages.
2026-08-02 22:06:48 +00:00
Claude 29b5783052 Fix LightDM autologin on fresh server installs (nopasswdlogin group + missing config)
Two bugs caused the login screen to appear on new Ubuntu 24.04 server hardware:

1. Ubuntu 24.04's PAM config checks 'user ingroup nopasswdlogin', not 'autologin'.
   Add kiosk user to nopasswdlogin group (and autologin for older versions).

2. The upgrade path never wrote /etc/lightdm/lightdm.conf.d/10-kiosk.conf,
   so on new hardware running through upgrade the file simply didn't exist.

Refactor: extract configure_lightdm_autologin() shared helper called from
both fresh install (step 19/27) and upgrade, so both paths are consistent.
Also use [Seat:*] instead of [SeatDefaults] for forward compatibility.

https://claude.ai/code/session_01VQ13Fwq4MXxwThLfCXBeGr
2026-06-16 18:15:05 +00:00
Claude 91d905f45a Fix LightDM autologin on Ubuntu 22.04+ (new hardware)
[SeatDefaults] is silently ignored by LightDM on newer Ubuntu versions.
Replace with [Seat:*] which is the correct section name for Ubuntu 22.04+.

Also add the kiosk user to the autologin group, which newer Ubuntu
requires for passwordless autologin to work.

Without these fixes, LightDM shows the login screen instead of
auto-logging in and launching the kiosk app.

https://claude.ai/code/session_01VQ13Fwq4MXxwThLfCXBeGr
2026-06-16 18:04:36 +00:00
Claude 879e2ecd14 Fix all file existence checks to run as kiosk user
/home/kiosk is mode 700 so root cannot traverse it. Every [[ -f ]] or
[[ ! -f ]] check on paths inside /home/kiosk was silently returning
'not found' even after the kiosk user had successfully written the file.

Replace all three [[ ! -f "$electron_bin" ]] checks and the
[[ -f "$sandbox" ]] check in install_electron_binary with
sudo -u "$KIOSK_USER" test -f so they run in the kiosk user's
security context and can actually see the files.

https://claude.ai/code/session_01VQ13Fwq4MXxwThLfCXBeGr
2026-06-16 17:32:32 +00:00
Claude 56e3d17459 Restore chmod 644 on tmp zip so kiosk user can read it for unzip
Accidentally dropped this line when rewriting the extraction block.
mktemp creates the file as root:root 600, so sudo -u kiosk unzip
gets 'Permission denied' trying to open the zipfile.

https://claude.ai/code/session_01VQ13Fwq4MXxwThLfCXBeGr
2026-06-16 17:25:36 +00:00
Claude 43266a4cf0 Fix Electron binary extraction: chown dist/ before extracting as kiosk user
The previous fix incorrectly ran unzip as root, which fails because
/home/kiosk is not accessible to root. The kiosk user is the right
actor for the extraction, but two things blocked it:

1. node_modules/electron/dist/ can be owned by root when npm's electron
   postinstall runs with --unsafe-perm, so the kiosk user gets
   'Permission denied' trying to write there. Fix: sudo chown -R the
   electron directory to the kiosk user before extracting.

2. With set -euo pipefail active (upgrade call had no || guard), a
   failed unzip or chmod would abort the script silently before the
   diagnostic error messages could print. Fix: add || true to both
   commands so the function always reaches the explicit -f check which
   prints the real error and returns 1. The upgrade call already has
   || { log_error ...; return 1; } from the previous commit.

https://claude.ai/code/session_01VQ13Fwq4MXxwThLfCXBeGr
2026-06-16 17:17:37 +00:00
Claude 670b32f53c Fix Electron binary extraction failing silently during upgrade
Two bugs combined to cause the 'Electron binary download failed' error
even though the zip downloaded and unzip reported inflating all files:

1. The upgrade path called install_electron_binary bare (no ||), so
   set -euo pipefail was active inside the function. Any failing command
   (e.g. chmod on a file that wasn't written) killed the script before
   the error messages printed. Fresh install used || exit 1, which
   disables set -e inside the function body. Upgrade now uses
   || { log_error ...; return 1; } to match.

2. The unzip ran as the kiosk user, but node_modules/electron/dist/ can
   be owned by root when npm's electron postinstall script runs with
   --unsafe-perm. The kiosk user can't write there, so unzip's write
   errors go to stderr (not visible in the log) while inflating: lines
   still appear on stdout. The binary is never actually written.
   Fix: run mkdir/unzip/chmod as root, then chown -R to kiosk.

https://claude.ai/code/session_01VQ13Fwq4MXxwThLfCXBeGr
2026-06-16 17:11:56 +00:00
Claude 174bbe46ae Fix permission denied on Electron zip: chmod 644 before kiosk-user unzip
mktemp creates the tmp zip owned by root with mode 600.
sudo -u kiosk unzip then fails with "Permission denied".
Add chmod 644 immediately after download so the kiosk user can read it.

https://claude.ai/code/session_01EyjEQLWbTXcZgbMDarf7NU
2026-06-16 16:54:51 +00:00
Claude b7e35c84c9 Detect pipe execution; show clear upgrade error instead of cryptic path failure
When the script is run via curl|bash or wget|bash, BASH_SOURCE[0] is a
pipe descriptor, not a real file. The upgrade function grep-extracts
heredocs from the script file, so it fails with a confusing path error.

Fixes:
- Set SCRIPT_FILE global at startup (empty string when piped)
- upgrade_kiosk() checks SCRIPT_FILE before asking "Continue?" and shows
  a clear message explaining how to download the script to a file first
- Removes the silent failure path (no more cryptic "Cannot find script at
  /proc/.../pipe:[...]" error)

https://claude.ai/code/session_01EyjEQLWbTXcZgbMDarf7NU
2026-06-16 16:45:58 +00:00
Claude 440b074245 Add unzip to apt packages; guard install_electron_binary against missing unzip
Fresh Ubuntu 24.04 minimal installs don't include unzip. The wget fallback
in install_electron_binary() downloaded the 120MB Electron zip successfully
but then failed on the unzip call. Two fixes:
1. Add unzip to the main apt install step so it's always present.
2. Auto-install unzip inside install_electron_binary() as a safety net for
   upgrades on existing systems that may not have it.

https://claude.ai/code/session_01EyjEQLWbTXcZgbMDarf7NU
2026-06-16 16:39:36 +00:00
Claude 27aaf5a15c feat: match any touch screen for libinput, not just Wacom "Finger" devices
Drop the MatchProduct "Finger" restriction from the xorg libinput rule,
leaving only MatchIsTouchscreen "on". MatchIsTouchscreen is set by udev
from hardware capabilities, so it matches finger touch screens of any
brand (ELAN, Goodix, eGalax, Wacom, etc.) while never matching keyboards,
mice, or pen/stylus digitizers (which are tagged as tablets, not
touchscreens). This makes the script work on any touch hardware without
hardcoding device names. Behavior on existing Wacom machines is unchanged
since their finger device matched either way.

https://claude.ai/code/session_01EyjEQLWbTXcZgbMDarf7NU
2026-06-16 15:05:28 +00:00
Claude 66a633b22c fix: resolve touch input with keyring flag + libinput driver
Two genuinely separate root causes were behind the dead touchscreen:

1. GNOME keyring grab — under LightDM autologin the keyring stays locked.
   When Chromium accessed it, the gcr-prompter unlock dialog grabbed all
   keyboard and touch input at the X level. The app rendered (timers ran)
   but ignored every tap and keypress. Fix: --password-store=basic stops
   Electron from using the keyring, so the dialog never appears.

2. Wacom driver single-touch emulation — the wacom X driver only does
   single-touch pointer emulation and never passes real multitouch to
   Chromium, so 1-finger and 2-finger swipe gestures could not fire.
   Fix: force the finger touch device to the libinput driver via
   /etc/X11/xorg.conf.d/99-finger-libinput.conf. libinput delivers proper
   XI2 multitouch which Chromium turns into real JS touch events. The
   pen/stylus stays on the wacom driver.

Removed the earlier dead-end attempts (xsetwacom MapToOutput / CTM reset,
Wacom Enable Touch Gesture, 99-wacom-touch.conf) which were all chasing the
wrong cause while the keyring grab masked any real testing. The upgrade path
removes the stale 99-wacom-touch.conf so it can't override libinput.

https://claude.ai/code/session_01EyjEQLWbTXcZgbMDarf7NU
2026-06-16 14:52:31 +00:00
Claude 4e7fbe497c fix: use xsetwacom MapToOutput instead of xinput set-prop for CTM
The Wacom driver owns the Coordinate Transformation Matrix and silently
overrides any xinput set-prop changes. xsetwacom MapToOutput tells the
driver to recalculate the CTM for the primary connected output, which is
the correct API and persists across driver resets.

Dynamically detects the primary output (eDP1, HDMI1, DP1, etc.) so the
fix works on any machine without hardcoding a display name.

https://claude.ai/code/session_01EyjEQLWbTXcZgbMDarf7NU
2026-06-16 13:55:09 +00:00
Claude 3315ccc44a fix: reset Coordinate Transformation Matrix to identity in start.sh
The Wacom driver can initialise the CTM to all-zeros, which maps every
touch event to screen coordinate (0,0). The touchscreen appears completely
dead even though the hardware and kernel are working correctly.

Reset the CTM to the identity matrix for every touch/finger device at
startup, before launching Electron, so coordinates are always correct.

https://claude.ai/code/session_01EyjEQLWbTXcZgbMDarf7NU
2026-06-16 13:44:50 +00:00
Claude 14172782c9 fix: correct xorg MatchProduct glob — Wacom*Finger* not Wacom.*Finger
xorg uses fnmatch (shell glob) for MatchProduct, where . is a literal
dot. Wacom.*Finger never matched "Wacom HID 48E3 Finger touch" because
there is no literal dot in that string. Wacom*Finger* matches correctly.

https://claude.ai/code/session_01EyjEQLWbTXcZgbMDarf7NU
2026-06-16 13:13:41 +00:00
Claude 5cbade03d7 fix: add xorg.conf.d Wacom touch config so driver starts in touch event mode
Without /etc/X11/xorg.conf.d/99-wacom-touch.conf the Wacom driver initialises
the finger touch device in pointer emulation mode (generating RawButtonPress/
RawButtonRelease/RawMotion). Electron never sees TouchBegin/TouchEnd events so
touchstart/pointerdown(touch) never fire in the renderer.

Setting Option "Gesture" "on" and Option "Touch" "on" at the driver level means
the device initialises in XI2 touch mode on every X server start, regardless of
any post-init xinput set-prop calls.

Added to both fresh install (step 18) and upgrade function.

https://claude.ai/code/session_01EyjEQLWbTXcZgbMDarf7NU
2026-06-16 13:08:38 +00:00
Claude 95027fe6fe fix: export XAUTHORITY in start.sh so xinput touch init never hits auth error
Without XAUTHORITY set, xinput can fail with "Authorization required"
if the display manager doesn't propagate it through the session environment.
Hardcode the kiosk user's .Xauthority path to guarantee xinput works.

https://claude.ai/code/session_01EyjEQLWbTXcZgbMDarf7NU
2026-06-16 12:57:21 +00:00
Claude 55039c510b chore: restore original ubuntu-based-kiosk-v1.0.2.sh alongside v1.0.3
Keep v1.0.2 in the repo as a stable fallback while v1.0.3 touch screen
support is being validated on different hardware.

https://claude.ai/code/session_01EyjEQLWbTXcZgbMDarf7NU
2026-06-16 02:27:13 +00:00
Claude 00dd806e9c chore: bump version to v1.0.3 and rename script file
Update all version strings (header, SCRIPT_VERSION, JS VERSION constant)
and rename ubuntu-based-kiosk-v1.0.2.sh → ubuntu-based-kiosk-v1.0.3.sh.
Update README with v1.0.3 change log and archive v1.0.2 as previous.

https://claude.ai/code/session_01EyjEQLWbTXcZgbMDarf7NU
2026-06-16 02:23:43 +00:00
Claude 6f18a2f897 fix: detect touch screens dynamically instead of hardcoding Wacom device name
The xinput loop now scans all input devices at startup, matches anything
with "touch" or "finger" in the name (excluding touchpads/trackpads), and
attempts to enable Wacom touch gestures on each match. Non-Wacom devices
silently ignore the set-prop call, so the loop is safe on any hardware.

https://claude.ai/code/session_01EyjEQLWbTXcZgbMDarf7NU
2026-06-16 02:21:09 +00:00
Claude c18615a78e fix: enable Wacom touch gestures on startup and update start.sh on upgrade
Add xinput call to start.sh so Wacom HID 48E3 touch gesture support is
initialized every time the kiosk starts, not just after lightdm restarts.
Also add start.sh to the upgrade extraction list so it is updated in place
instead of keeping the stale version from the original install.

https://claude.ai/code/session_01EyjEQLWbTXcZgbMDarf7NU
2026-06-16 02:19:03 +00:00
Claude 37663be91b fix: add PointerEvent fallback for swipe detection
touchstart/touchend never fire on this device (confirmed by zero [TOUCH]
log entries). The activity tracker already uses pointerdown/pointerup and
works fine, proving PointerEvents reach the preload. Added pointer event
handlers that mirror the touch handlers for all gestures (2-finger swipe,
3-finger toggle, 1-finger arrow keys). A 500ms debounce on the IPC send
prevents double-firing on devices where both event types fire.

https://claude.ai/code/session_01EyjEQLWbTXcZgbMDarf7NU
2026-06-16 01:59:25 +00:00
Claude 8f886854f2 revert: restore v1.0.0 touch handler approach for two-finger swipe
capture:true and --touch-events=enabled were added to handle Authelia's
login page blocking touch events. Authelia now auto-logs in on startup
so the login page never shows. Reverting to the v1.0.0 approach (passive:true
only, no --touch-events flag) which had working two-finger swipe.

https://claude.ai/code/session_01EyjEQLWbTXcZgbMDarf7NU
2026-06-16 01:52:46 +00:00
Claude f40d8e337c fix: add --touch-events=enabled to Electron launch flags
With --ozone-platform=x11, Chromium defaults touch event detection to
'auto' and may not identify the hardware as a touchscreen, so touchstart/
touchend never fire in the renderer. --touch-events=enabled forces W3C
touch events on unconditionally, restoring two-finger swipe navigation.

https://claude.ai/code/session_01EyjEQLWbTXcZgbMDarf7NU
2026-06-16 01:16:58 +00:00
Claude d595464400 fix: preserve node_modules during upgrade to avoid re-downloading Electron
The upgrade was wiping node_modules then relying on npm to re-download the
~120MB Electron binary. npm returns exit 0 even when the download times out,
leaving the kiosk with no Electron binary and a blank screen on next boot.

node_modules only needs to be deleted on a fresh install or when explicitly
changing Electron version. For a JS-file-only upgrade, npm install without
a wipe is either a no-op (no changes) or applies dependency updates cleanly.
The install_electron_binary fallback remains as a safety net.

https://claude.ai/code/session_01EyjEQLWbTXcZgbMDarf7NU
2026-06-16 00:52:22 +00:00
Claude 543a442775 fix: use sudo to remove root-owned config backup after upgrade
Backup is created with sudo cp (owned by root), so the cleanup rm -f
fails with "Operation not permitted" when run without sudo.

https://claude.ai/code/session_01EyjEQLWbTXcZgbMDarf7NU
2026-06-16 00:39:53 +00:00
Claude 3d5a5839b3 fix: use capture:true on touch event listeners to prevent page JS interference
Touch handlers used bubble phase (no capture:true), so any page script that
called stopPropagation() on touchstart/touchend — e.g. Authelia's login form
or scroll containers — silently blocked the preload's swipe detection.

Using capture:true fires the preload's listeners in the capture phase (before
any element-level handlers), so swipe works even on pages with their own
touch handling. Applied to both preloads (standard and auto-show keyboard).

Also adds missing [TOUCH] 2-finger HORIZONTAL console.log to the standard
preload so swipe events are visible in electron.log for debugging.

https://claude.ai/code/session_01EyjEQLWbTXcZgbMDarf7NU
2026-06-16 00:31:14 +00:00
Claude 31eb750514 docs: clarify Authelia access_control merge with before/after example
The duplicate-block pitfall (YAML silently ignores duplicate keys, causing
a white screen) is now called out explicitly in both the script's printed
output and the README. Added a before/after example showing the correct
merged result with the kiosk one_factor rule above the two_factor wildcard.
Also explains why one_factor is required (TOTP/WebAuthn need interactive
second step, impossible via API).

https://claude.ai/code/session_01EyjEQLWbTXcZgbMDarf7NU
2026-06-16 00:25:11 +00:00
Claude effb726979 fix: add 10-second timeout to Authelia fetch to prevent white screen
Without a timeout, session.defaultSession.fetch() hangs for 1-2 minutes
on TCP timeout when Authelia is unreachable (wrong URL, server down,
firewall). Since createWindow() awaits autheliaAuthenticate(), the main
window is visible but no BrowserView is attached during that wait —
causing a persistent white screen with ibeam cursor.

https://claude.ai/code/session_01EyjEQLWbTXcZgbMDarf7NU
2026-06-16 00:15:18 +00:00
Claude 0eef318e78 docs: update Authelia setup instructions to use MERGE workflow
- Step 3 now says MERGE (not replace/append) with clear warning to keep existing config
- access_control: kiosk one_factor rule must go ABOVE any existing two_factor rule,
  with explanation that Authelia applies rules top-down (first match wins)
- session block: keep existing values; only add the block if none exists yet
- Kiosk can only do one_factor — TOTP/WebAuthn via API is not possible
- Updated in both configure_authelia() printed output and README Authentication section

https://claude.ai/code/session_01EyjEQLWbTXcZgbMDarf7NU
2026-06-15 23:55:53 +00:00
Claude 0b52ec27fb fix: shared install_electron_binary() covers both fresh install and upgrade
The upgrade_kiosk() path deleted node_modules then ran npm install but
never checked the binary or set chrome-sandbox permissions — so every
upgrade produced a blank screen.

Changes:
- Extract electron binary verification, fallback downloads, and
  chrome-sandbox chmod 4755 into a shared install_electron_binary()
  function called by both step 17/27 (fresh install) and step 5/6
  (upgrade_kiosk) so neither path can silently skip the permission fix
- Add repair_electron() function: stops display, re-runs
  install_electron_binary, restarts lightdm — no SSH needed
- Wire repair_electron as Advanced menu option 12 "Fix Blank Screen"

https://claude.ai/code/session_01EyjEQLWbTXcZgbMDarf7NU
2026-06-15 23:38:37 +00:00
Claude bd4d4cadc8 fix: robust Electron binary download with timeouts, retry, and wget fallback
The ~120MB Electron binary download was silently failing because npm's
default 60s fetch timeout is too short on slower connections.

Changes to step 17/27:
- Set npm fetch-timeout to 600s and retries to 5 before running npm install
- If binary still missing after npm install, retry via install.js with
  ELECTRON_FORCE_DOWNLOAD=true
- If still missing, fall back to direct wget download of the exact
  versioned zip from GitHub releases (300s timeout, 3 tries, shows progress)
- Exit 1 with clear message if all three attempts fail
- Log chrome-sandbox permission step for visibility

https://claude.ai/code/session_01EyjEQLWbTXcZgbMDarf7NU
2026-06-15 23:34:00 +00:00
Claude 2556863129 fix: use sudo for all config.json access in configure_authelia
/home/kiosk/ has 750 permissions so the install user can't read inside
it. The -f check and both jq reads were running as the current user and
failing silently, causing the false "config.json not found" error.

Changed:
  [[ ! -f "$config_file" ]]  →  sudo test -f "$config_file"
  jq -r ... "$config_file"   →  sudo -u kiosk jq -r ... "$config_file"
  jq ... > "$tmp"            →  sudo -u kiosk jq ... > "$tmp" && sudo mv

https://claude.ai/code/session_01EyjEQLWbTXcZgbMDarf7NU
2026-06-15 23:20:14 +00:00
Claude 4c3f5576b9 fix: detect and retry Electron binary download when npm install silently fails
npm install returns 0 even when Electron's postinstall binary download
fails, leaving node_modules/electron/dist/electron missing and causing
a blank screen with no useful error.

After npm install, explicitly check for the binary. If absent, retry
via ELECTRON_FORCE_DOWNLOAD=true node install.js. If still missing,
print a clear error and exit 1 instead of silently continuing to a
broken install.

https://claude.ai/code/session_01EyjEQLWbTXcZgbMDarf7NU
2026-06-15 22:52:49 +00:00
Claude f1febbd914 release: v1.0.2 - Authelia auto-login, pipewire fix, dynamic README
New file ubuntu-based-kiosk-v1.0.2.sh containing all changes made
since v1.0.1:
- Authelia auto-login addon (Addons → 5): AES-256 encrypted credentials,
  startup API auth, full Dockerized server-side setup printed on save
- Fix: PipeWire .config dirs created as root caused Permission denied
  at step [5.5/27] on fresh Ubuntu 24.04 minimal installs
- README install commands now pull latest script dynamically via
  GitHub contents API (no more hardcoded version numbers)

SCRIPT_VERSION and VERSION constants updated to 1.0.2.
README changelog and current version updated to 1.0.2.

https://claude.ai/code/session_01EyjEQLWbTXcZgbMDarf7NU
2026-06-15 14:57:51 +00:00
Claude 05538611cf docs: add Authelia server-side setup guide to script output and README
After configure_authelia() saves credentials, it now prints the full
Dockerized Authelia server-side checklist: argon2 hash generation
command, users.yml kiosk user template, configuration.yml session
duration and access_control rules, and a docker compose restart step.

README gains a new Authentication section under Optional Add-ons
covering the same steps in Markdown with a table comparing Authelia
SSO vs HTTP Basic Auth (both can coexist).

Also clarifies that the Authelia password is encrypted at rest and
not stored in plain text.

https://claude.ai/code/session_01EyjEQLWbTXcZgbMDarf7NU
2026-06-15 14:49:32 +00:00
Claude 2a5fb6188b feat: Authelia auto-login with machine-ID-bound AES-256 encryption
Adds an Authelia Auto-Login addon (Addons menu → 5) that:
- Prompts for Authelia URL, username, and password
- Encrypts the password with AES-256-CBC keyed from /etc/machine-id
  via scrypt (the encrypted blob is machine-specific and useless elsewhere)
- Stores autheliaURL, autheliaUsername, autheliaEncryptedPassword in config.json

On every kiosk startup, main.js decrypts the password and calls
Authelia's /api/firstfactor with keepMeLoggedIn:true before any
BrowserViews are created. Electron's session.defaultSession handles
the Set-Cookie response automatically, so all sites load already
authenticated.

To set up credentials via SSH:
  ssh user@kiosk
  ./ubuntu-based-kiosk-v*.sh  →  Addons → 5. Authelia Auto-Login

https://claude.ai/code/session_01EyjEQLWbTXcZgbMDarf7NU
2026-06-15 14:35:41 +00:00
Claude 42aafff219 fix: create pipewire config dirs as kiosk user to avoid permission denied
sudo mkdir -p created the .config/pipewire/pipewire.conf.d directories
owned by root, causing the subsequent sudo -u kiosk tee to fail with
"Permission denied" at step [5.5/27] on a fresh install.

Switching to sudo -u kiosk mkdir -p ensures the directories are owned
by the kiosk user before the tee writes into them.

https://claude.ai/code/session_01EyjEQLWbTXcZgbMDarf7NU
2026-06-15 14:11:56 +00:00
Claude c2d9b34d53 docs: remove hardcoded version numbers from install instructions
Quick Install section now queries the GitHub contents API to find and
download the latest ubuntu-based-kiosk-v*.sh script dynamically, so the
README never needs a manual version bump when a new release is pushed.

Post-install "run again" references use `ls ubuntu-based-kiosk-v*.sh | sort -V | tail -1`
for the same reason.

Also bumps version references from 1.0.0 → 1.0.1, Electron 41 → 42,
Node.js 20 → 22, and adds the v1.0.1 changelog entry.

https://claude.ai/code/session_01EyjEQLWbTXcZgbMDarf7NU
2026-06-15 13:45:26 +00:00
Claude dc8f2b3a9c Add v1.0.1: update Node.js 20→22 LTS and Electron 39→42
Node.js 20 reached EOL April 2026; bumps nodesource setup to 22.x.
Electron pin updated from ^39.2.4 to ^42.0.0 (current stable).

https://claude.ai/code/session_0143uHgfTvF3Pv1oDinkhJRX
2026-06-03 01:16:43 +00:00
Claude 11173bbcda Add --allow-server-ssh --disable-ssh-auth to netbird up commands
NetBird v0.60 changed SSH to JWT/IdP-based auth by default.
Using --disable-ssh-auth keeps access controlled purely by NetBird
ACL policies (machine-level, like pre-v0.60 behaviour) without
requiring an identity provider or OIDC flow.

https://claude.ai/code/session_01M3tiofbGfmTddeMcXr8nXr
2026-04-21 02:55:48 +00:00
Claude a7894ede51 v1.0.1-beta: replace nodeIntegration/contextIsolation:false with contextBridge preload
All 6 popup BrowserWindows (lockout, prompt, pause, pin, keyboard ×2)
now use contextIsolation:true + popup-preload.js instead of the
deprecated nodeIntegration:true pattern. A new popup-preload.js file
exposes crypto.hashPassword, fs.readPin, ipcRenderer.send/on/once to
the renderer via contextBridge. All affected HTML files updated to use
window.electronAPI.* instead of direct require('electron') calls.
The popup-preload.js heredoc is also added to the upgrade extract_file
list so upgrades re-extract it correctly.

https://claude.ai/code/session_01M3tiofbGfmTddeMcXr8nXr
2026-04-21 01:29:27 +00:00
Claude 589a65bc55 feat: add v1.0.1-beta with BrowserView → WebContentsView migration
BrowserView has been deprecated since Electron 29 and will be removed
in a future major release. This beta migrates all usage to the
WebContentsView API introduced in Electron 28.

Changes in main.js:
- Import WebContentsView instead of BrowserView
- Add bringViewToTop() helper (remove+re-add as last child = on top)
- createWindow: new WebContentsView / contentView.addChildView
- attachView: contentView.removeChildView + bringViewToTop
- showLockoutScreen: contentView.removeChildView for all views
- unlockScreen: bringViewToTop to restore hidden view
- returnToTabs: bringViewToTop instead of setTopBrowserView
- showHiddenTab: bringViewToTop instead of setTopBrowserView

v1.0.0 is kept unchanged. The legacy update_mainjs_keyboard() patch
function is guarded by a grep check that prevents it running against
the new WebContentsView-based main.js.

https://claude.ai/code/session_01M3tiofbGfmTddeMcXr8nXr
2026-04-21 01:12:22 +00:00
Claude 5085a19805 chore: upgrade Electron from v39.2.4 to v41.2.1
No breaking changes affecting the kiosk app between these versions:
- BrowserView still present (deprecated but not removed until future release)
- WebContentsView destroyed-event change does not apply (app uses BrowserView)
- Session.clearStorageData quotas removal not used
- PDF OOPIF change not relevant

https://claude.ai/code/session_01M3tiofbGfmTddeMcXr8nXr
2026-04-21 01:04:54 +00:00
Claude ae65853f5a docs: update README for v1.0.0
- Bump version references from 0.9.9.1/0.9.8 to 1.0.0
- Update script filename to ubuntu-based-kiosk-v1.0.0.sh throughout
- Add v1.0.0 changelog entries (upgrade fix, sudo/timezone fixes)
- Preserve prior version history (v0.9.9.1, v0.9.8) as changelog
- Update Claude model reference to Sonnet 4.6
- Update last-updated date

https://claude.ai/code/session_01M3tiofbGfmTddeMcXr8nXr
2026-04-21 01:02:08 +00:00
Claude 145320998e chore: bump version to 1.0.0 and rename script file
https://claude.ai/code/session_01M3tiofbGfmTddeMcXr8nXr
2026-04-21 00:59:09 +00:00
Claude 4b7ab7c0be fix: prevent sudo cache expiry during install and add timezone fallback
Two issues caused the timezone step to fail on first run:

1. Sudo credential cache (default 15 min) can expire during the long
   apt install step before configure_timezone runs. Added `sudo -v`
   immediately after the install confirmation prompt to prime the cache
   as late as possible, just before the first long-running step.

2. `sudo timedatectl set-timezone` can fail with "Access denied" if
   polkit/D-Bus is not yet fully ready in the install environment.
   Added a direct fallback (ln -sf localtime + tee /etc/timezone)
   that bypasses D-Bus entirely.

https://claude.ai/code/session_01M3tiofbGfmTddeMcXr8nXr
2026-04-21 00:16:55 +00:00
Claude 07823423e5 fix: use sudo test -s to verify extracted files in upgrade_kiosk
On Ubuntu 22.04+, useradd creates home directories with 750 permissions,
so the non-root user running the script cannot traverse /home/kiosk to
check file existence with [[ -s ]]. sudo tee (running as root) writes the
files successfully, but the bash test always returned false, falsely
reporting all extractions as failed.

Switch to `sudo test -s` to match the pattern already used elsewhere in
the script (line ~10320) when checking files under /home/kiosk.

https://claude.ai/code/session_01M3tiofbGfmTddeMcXr8nXr
2026-04-20 23:10:47 +00:00
Claude 96747fa411 Rename UBK to Ubuntu Based Kiosk and rename main install script
- Rename install_kiosk_v0.9.9.1.sh to ubuntu-based-kiosk.sh
- Update all repository URLs from ubk to ubuntu-based-kiosk
- Remove UBK abbreviation from documentation and script headers
- Update installation instructions in Readme.md
2025-12-30 05:28:48 +00:00
Claude eb2f31f818 Fix power menu IPC and export/import permissions
- Power menu: Send IPC to views[] instead of mainWindow.webContents
  (preload.js runs in BrowserViews, not mainWindow)
- Export: Add chmod 777 to temp dir, use sudo for all file operations,
  use sudo tar and fix archive ownership
- Import: Use sudo tar, add proper permissions to temp directory
2025-12-28 21:35:37 +00:00
Claude 79d112794b Add 30-second auto-dismiss timeout to secondary screens
- PIN entry window: auto-closes after 30 seconds of inactivity
- Pause dialog: auto-closes after 30 seconds of inactivity
- Power menu: converted from native dialog to custom overlay with
  30-second timeout (lockout mode still uses native dialog)
- Nav menu already had 30-second timeout

All modal windows and overlays now automatically dismiss after
30 seconds to prevent screens being left open indefinitely.
2025-12-28 18:05:21 +00:00
Claude 4ac9676ef5 Power button follows same show/hide logic as nav button
- Power button now starts hidden and appears on user interaction
- Auto-hides after 5 seconds of inactivity (matching nav button)
- Increased size to 60px with 3px border for consistency
- Removed hover transitions for simpler, consistent behavior
2025-12-28 17:29:27 +00:00
Claude c4f93571a9 Add power button, fix EPIPE errors, fix display schedule
- Add red power icon button in top-right corner of UI
- Click power button triggers showPowerMenu via IPC
- Add EPIPE error suppression for stdout/stderr (no more error dialogs)
- Fix display on/off scripts: add XAUTHORITY, hardcode kiosk user
- Add logging to display scripts for debugging
2025-12-28 16:41:36 +00:00
Claude 27de108579 Add error handling to SIGUSR1 power button handler 2025-12-28 15:58:13 +00:00
Claude 7ed5faa2dc Simplify power button: direct SIGUSR1 from root ACPI handler
- Simplified power button script runs as root from acpid
- No longer needs DISPLAY/XAUTHORITY (just sends signal)
- Finds all Electron processes and sends SIGUSR1 to each
- Updated ACPI event handlers to call /usr/local/bin/kiosk-power-button.sh
- Updated test-power-button to actually trigger and test
- Upgrade function now installs simplified handler
2025-12-27 14:23:40 +00:00
Claude e04fc42a85 Fix on-screen keyboard: ignore Ctrl/Alt modifier keys
When pressing Ctrl or Alt on the virtual keyboard, the literal text
"Control" or "Alt" was being inserted into text fields. Now these
modifier keys are properly ignored since they don't function as
standalone keys in input fields.
2025-12-27 03:24:43 +00:00
Claude 966709547f Fix upgrade: ensure dir exists, use sudo tee directly
- Create kiosk directory if it doesn't exist before extraction
- Use 'sudo tee' instead of 'sudo -u kiosk tee' for reliable writes
- Add line numbers to output for debugging
- chown at end fixes permissions
2025-12-24 18:48:38 +00:00
Claude bb82108809 Fix upgrade extraction using grep+sed line numbers
The awk-based extraction had variable scoping issues when run
as a nested function. Switch to grep for finding line numbers
and sed for extraction - more reliable approach.
2025-12-24 18:42:53 +00:00
Claude b17adbde2b Fix upgrade: use awk extraction, restart lightdm not kiosk
- Replace sed with awk for more reliable heredoc extraction
- Add debug output showing script path
- Fix restart to use lightdm instead of non-existent kiosk.service
- Kill electron process before upgrade, check electron after
- Add script path validation before extraction
2025-12-24 18:36:20 +00:00
Claude ec0d3ee633 Fix sed patterns in upgrade - remove strict anchors
The sed patterns were too strict with ^ and $ anchors, causing
extraction to fail on lines with leading whitespace.
2025-12-24 18:27:17 +00:00
Claude 703339c5e9 v0.9.9.1: Silent upgrade, import number selection, power button fix
- Silent upgrade: extracts app files from script without user input
- Import now shows numbered list, user can select by number
- Improved power button handler with better Electron process detection
- SIGUSR1 now primary method for power menu (more reliable)
- Upgrade automatically regenerates power button handler
- Added XAUTHORITY export for X11 authentication
2025-12-24 18:17:11 +00:00
Claude 2ba980ce94 Add upgrade feature that preserves all settings
- New upgrade_kiosk() function in Core Settings menu (option 10)
- Auto-exports config, timers, and addon configs before reinstall
- Auto-imports everything after reinstall completes
- User just needs to press Enter through installer prompts
- Also fixed SUDO_USER unbound variable issues
2025-12-24 13:36:52 +00:00
Claude da99774c44 Fix SUDO_USER unbound variable in export/import
- Use ${SUDO_USER:-} to avoid unbound variable error with set -u
- Fall back to USER, then /tmp if neither is set
- Validate home_dir exists and is writable
- Use whoami instead of $USER in scp hint
2025-12-24 02:34:52 +00:00
Claude 113adeb119 Fix export/import exit on counter increment with set -e
The script uses 'set -euo pipefail' which causes ((var++)) to exit
when var is 0, since the expression evaluates to 0 (falsey).
Changed to var=$((var + 1)) which always succeeds.
2025-12-24 02:31:13 +00:00
Claude f2f645b7b8 Add VPN configs to settings export/import
Export now includes:
- WireGuard: /etc/wireguard/*.conf files
- Netbird: config.json, state directory (machine keys), user config
- OpenVPN: /etc/openvpn/ directory
- Tailscale: notes installation status (requires re-auth)

Import restores all VPN configs and auto-enables services.
Warns if VPN software not installed after restore.
2025-12-24 02:22:02 +00:00
Claude 2acc8aaa1d Add settings export/import feature for easy backup/restore
- Added export_settings: backs up all config to timestamped .tar.gz
  - Core config (sites, touch controls, passwords)
  - Schedule timers (power, display, quiet hours)
  - Addon configs (Squeezelite, VNC, Easy Asterisk)
- Added import_settings: restores from backup file
  - Lists available backups in home directory
  - Enables timers and sets permissions automatically
- Added to Advanced menu (options 8 and 9)
- Bump version to 0.9.9
2025-12-24 02:16:30 +00:00
Claude 5ec37d8457 Fix kiosk power button, pause dialog timeout, and mic static
- Add SIGUSR1 signal handler for power button trigger script fallback
- Add 30-second auto-close timeout to pause dialog popup
- Configure PipeWire noise cancellation/echo suppression for microphone
- Bump version to 0.9.8.1
2025-12-24 01:43:11 +00:00
Claude 20cb5d0a5e Add Easy Asterisk client-only installation option
- Add sub-menu to Easy Asterisk addon with Server/Client/Both options
- Implement Baresip SIP client installation for client-only mode
- Add configuration prompts for server connection details (IP, port, extension, password)
- Create systemd user service for automatic Baresip startup
- Support TLS encryption and auto-answer mode options
- Update status display to show both server and client installation status
2025-12-17 06:19:58 +00:00
Claude 2048ac7bc8 Fix version regex to support 4-part version numbers (e.g., 0.9.8.7) 2025-12-11 00:53:11 +00:00
Claude 234dd900f6 Integrate Easy Asterisk Intercom into v0.9.8 installer
Added to install_kiosk_v0.9.8.sh:
- SECTION 14.5: Easy Asterisk Intercom addon functions
- get_latest_easy_asterisk_version() - Fetches latest version from GitHub API
- get_installed_easy_asterisk_version() - Checks installed version
- backup_easy_asterisk_configs() - Backs up configs before updates
- restore_easy_asterisk_configs() - Restores configs after install
- download_and_install_easy_asterisk() - Downloads and runs installer
- addon_easy_asterisk_intercom() - Main menu function with update logic

- Added option 4 "Easy Asterisk Intercom" to Addons menu
- Updated show_addon_status() to display Intercom installation status
- Integration uses stable v0.9.8 as base (v0.9.9 was broken)

README updates:
- Fixed all references from v0.9.9 to v0.9.8
- Updated menu paths (2) Addons → (4) Easy Asterisk Intercom
- Corrected version number throughout
- Updated Quick Install section

Features:
- Downloads latest easy-asterisk-v*.sh from GitHub repo
- Automatic version detection and update checking
- Configuration preservation during updates/reruns
- Safe to run multiple times
- User prompts for install/update/rerun decisions
2025-12-10 22:32:22 +00:00
Claude 38e732b976 Remove broken Copilot code that would install wrong Asterisk version
Removed:
- install_easy_asterisk() function that installed Ubuntu Asterisk packages
- configure_easy_asterisk() function for non-existent addon
- Menu option 1 "Install Easy Asterisk" (broken implementation)
- Menu option 5 "Configure Easy Asterisk" (broken implementation)

The removed code would have:
- Installed default Ubuntu Asterisk (apt-get install asterisk)
- Created fake local config files
- Conflicted with actual Easy Asterisk from GitHub repo

Updated:
- Menu renumbered: Intercom is now option 1 (was option 2)
- Configure Intercom is now option 4 (was option 6)
- Updated README to reflect new menu numbers
- Updated error messages with correct option references

Result: Clean implementation with only the working GitHub-based
Easy Asterisk Intercom installer that properly manages versions
and preserves configurations.
2025-12-10 12:52:26 +00:00
Claude 62e4a906b9 Add Easy Asterisk Intercom addon with automatic update management
Features:
- Download and install latest Easy Asterisk from GitHub repository
- Automatic version detection using GitHub API
- Smart update checking with user confirmation
- Configuration preservation during updates and reruns
- Backup and restore functionality for configs
- Safe re-run capability without breaking existing setup

Menu changes:
- Added "Install/Update Intercom (Easy Asterisk)" option
- Updated configure_intercom to work with Easy Asterisk installation
- Enhanced configuration interface with file editing support

README updates:
- Added Communication section with Easy Asterisk Intercom
- Documented installation, update, and configuration workflows
- Updated version to 0.9.9
- Added installation locations and management commands

The intercom addon integrates with outis1one/easy-asterisk repository
and follows the pattern of easy-asterisk-v*.sh version files.
2025-12-10 12:21:18 +00:00
Claude 160c39a47d Fix power menu VPN display and navigation rendering issues
- Fixed power menu showing VPN address twice by excluding VPN interfaces
  (tailscale, wg, netbird, tun, wt) when detecting local IP
- Fixed site bleeding through during navigation by removing all other
  BrowserViews before attaching new one
- Fixed dim navigation popup by forcing reflow and adding fade-in effect
- Added webContents.invalidate() to ensure proper view rendering after switch

These changes improve the visual clarity and reliability of the navigation
system and power menu display.
2025-12-04 18:06:10 +00:00
Claude 08638045d5 Improve navigation menu UX and button behavior
Fixed three navigation menu issues:
1. Nav button timeout - now auto-hides after 5 seconds like pause/keyboard buttons
2. Better site selection visual feedback - bolder text, white border, lift effect on hover
3. Independent column scrolling - only sites list scrolls, cheat sheet stays fixed

Navigation button changes:
- Added navButtonHideTimer and NAV_BUTTON_HIDE_DELAY (5 seconds)
- Updated showNavButton() to set auto-hide timer
- Updated hideNavButton() to clear timer
- Matches pause button behavior for consistent UX

Site button styling improvements:
- Hover: bold text, bright white border, lifts up 2px, brighter background
- Click: even darker background, pressed down effect
- Default: subtle border and shadow
- Smooth 0.3s transitions for modern feel
- Much more obvious visual feedback when hovering/selecting

Column scroll changes:
- Content overflow changed from auto to hidden
- Sites column: overflow-y auto, padding for scrollbar
- Cheat sheet column: overflow-y hidden (stays fixed)
- Columns container: max-height 70vh
- Only URL list scrolls, gestures/shortcuts remain visible
2025-12-03 01:55:30 +00:00
Claude 27c8adf040 Remove auto-rotation stop from navigation menu
Navigation menu now jumps to selected site but allows rotation to continue.
The pause button remains the only control for stopping rotation.

Changes:
- Removed manualNavigationMode=true from navigate-to-tab handler
- Removed inactivityExtensionUntil=0 (related to manual mode)
- Updated logging to reflect that rotation continues

Users can now use the navigation menu to quickly jump to any site while
keeping rotation active, or use the pause button if they want to stop on
a specific site.
2025-12-02 21:45:59 +00:00
Claude 31f8d2f973 Fix navigation menu tab switching function name
Resolved ReferenceError: showView is not defined when clicking sites in nav menu.

Changes:
- Changed showView() to attachView() - the correct function name
- Added manualNavigationMode=true to stop auto-rotation on manual navigation
- Added markActivity() to reset inactivity timer
- Added inactivityExtensionUntil=0 to clear extensions
- Added additional logging for debugging
- Added error logging for invalid view indices

This makes navigation menu behavior consistent with nextTab() and
previousTab() functions throughout the codebase.
2025-12-02 21:39:08 +00:00
Claude 5db15802a0 Fix navigation menu config IPC handler error
Resolved ReferenceError: config is not defined in the 'get-config' IPC handler.

Changes:
- Modified IPC handler to read config.json directly using fs.readFileSync
- Added proper error handling with try/catch block
- Added fallback to send empty config if file doesn't exist or can't be read
- Added console logging for debugging config transmission

This fixes the JavaScript error that was displaying on screen and prevents
the navigation menu from loading sites properly.
2025-12-02 20:19:25 +00:00
Claude 08594601ec Fix navigation menu bugs in 0.9.8
Fixed Issues:
1. Icon rendering - Replaced emoji 🔑 with SVG key icon for better compatibility
2. JavaScript errors - Added try/catch blocks throughout navigation menu code
3. Sites not loading - Fixed IPC communication with extensive error logging
4. Menu becoming part of rotation - Ensured proper overlay with z-index and pointer-events
5. Missing auto-dismiss - Added 30-second timeout that auto-closes menu
6. Improved close button positioning - Moved to top-right with better visibility

Technical Changes:
- Changed navButton.innerHTML from emoji to SVG path for key icon
- Added NAV_MENU_TIMEOUT constant (30000ms)
- Added navMenuTimer variable for timeout management
- Enhanced createNavMenu() with console logging and error handling
- Fixed content positioning with 'position:relative'
- Added pointer-events:auto to ensure menu captures events
- Enhanced showNavMenu() with try/catch and 30-second auto-dismiss timer
- Enhanced hideNavMenu() with timer cleanup and error handling
- Enhanced toggleNavMenu() with logging
- Fixed loadSitesIntoNav() with error handling
- Enhanced config-data IPC handler with extensive logging and validation
- Changed siteBtn.innerHTML to siteBtn.textContent to prevent XSS
- Added user-select:none to prevent text selection on buttons
- Added stopPropagation to content to prevent background clicks from closing
- Fixed close button event handler with proper logging

Console Output:
- All navigation menu actions now log to console with [NAV] prefix
- Helps diagnose issues: button clicks, menu show/hide, config requests, site loading
- Error messages clearly identify failure points

This should resolve all reported issues with the navigation menu.
2025-12-02 19:00:30 +00:00
Claude a6994601c4 Complete version 0.9.8: Named Sites & Navigation Menu
Bug Fixes:
- Fixed virtual console menu display (now checks both getty and X11 DontVTSwitch)
- Fixed complete_uninstall to properly remove LMS/Squeezelite services
- Fixed full_reinstall to clean all addons and settings (except saved VPN/VNC)

Named Websites Feature:
- Added 'name' field to config.json schema for all sites
- Added NAMES array throughout codebase for site name management
- Added update_site_names() function with menu option (Sites → option 3)
- Names prompted during site addition (both new installs and adding sites)
- Site listings now display as "Name" - URL when name is provided
- All management functions (add, update, delete, reorder) handle names properly
- Names fully integrated with save/load config operations

Navigation Menu Feature:
- Added enableNavButton config option (defaults to true)
- Added navigation button at top-left (purple key icon 🔑)
- Button shows on user interaction (same logic as pause/keyboard buttons)
- Navigation menu overlay with 2-column layout:
  * Column 1: Clickable list of all non-hidden sites (uses names if available)
  * Column 2: Touch gesture cheat sheet and keyboard shortcuts reference
- Menu accessible via key icon click
- IPC handlers added: get-config and navigate-to-tab
- Menu excludes hidden sites (duration === -1) as requested
- Optional feature configurable via Optional Buttons menu

README Updates:
- Updated all version references to 0.9.8
- Updated installation commands to use install_kiosk_0.9.8.sh
- Added comprehensive "Why Use Named Sites?" section with use cases:
  * Home/Family kiosks examples
  * Business kiosks examples
  * Digital signage examples
  * Multi-location setups examples
- Updated Multi-Site Management section to include named sites and navigation menu
- Updated Touch Controls section to reflect correct gesture (3-finger DOWN toggle)
- Updated Project Status to version 0.9.8
- Updated menu access commands throughout document

Technical Implementation:
- preload.js: Added nav button/menu variables, create/show/hide functions
- preload.js: Added IPC listener for 'nav-button-enabled'
- preload.js: Integration with user interaction handlers
- main.js: Added enableNavButton variable and config loading
- main.js: Added 'get-config' and 'navigate-to-tab' IPC handlers
- main.js: Send nav-button-enabled state on page load
- Bash script: Added site name prompts in add_new_sites() and add_new_sites_simple()
- Bash script: Added update_site_names() function for updating existing site names
- Bash script: Updated configure_optional_buttons() to include navigation button
- Bash script: Updated all save/load config operations to handle NAMES array

Script now at 9607 lines (242 lines added for navigation menu feature)
All syntax validated with bash -n
2025-12-02 18:16:25 +00:00
Claude 06f0208c0b WIP: Version 0.9.8 - Named Sites & Navigation Menu (partial)
Bug fixes completed:
- Fixed virtual console menu display bug (checks both getty and X11)
- Fixed complete_uninstall to properly remove LMS/Squeezelite
- Fixed full_reinstall to clean all addons and settings

Named websites feature completed:
- Added 'name' field to config.json schema
- Added site name management throughout (add, update, delete, reorder)
- Added update_site_names() menu option
- Names display in site listings

Navigation button configuration completed:
- Added enableNavButton config option
- Added to optional buttons menu
- Integrated with save/load config

TODO: Navigation menu UI implementation in preload.js still needed
2025-12-02 18:09:36 +00:00
Claude 2f31a730f6 Release version 0.9.7-5: Maintenance & Polish Update
- Removed PTT (Push-to-Talk) functionality (moved to separate project)
- Fixed power menu to display both local and VPN IP addresses
- Updated Electron to v39.2.4 with enhanced rollback instructions
- Updated README dates to 2025 and version references to 0.9.7-5
- Removed stray text from README printer section
2025-12-02 16:55:09 +00:00
Claude 95c7af9ac6 Fix core menu option 10 (Full reinstall) not working
Issue: Option 10 was immediately returning to main menu instead of
performing the reinstall.

Root Cause: The menu case statement had 'return' after full_reinstall,
which caused it to exit the core_settings_menu even when the user
cancelled the reinstall (by not typing 'YES').

Fix: Removed the 'return' statement from line 8994.
Now when users cancel, they stay in the core settings menu.
When reinstall completes, the pause() at the end lets them press enter
and naturally return to the menu for additional configuration.

Note: Option 11 (complete_uninstall) correctly keeps 'return' since
uninstalling should exit the entire menu system.
2025-12-02 15:11:21 +00:00
Claude 5d63740c05 Release version 0.9.7-4: Gesture & Console Improvements
Major Changes:
1. FIXED: Virtual console Ctrl+Alt+F1-F8 key combinations now work properly
   - Updated configure_virtual_consoles() to modify X11 serverflags
   - Enable/disable now updates both systemd getty AND X11 VT switching
   - Added restart lightdm notification for changes to take effect
   - Fixed initial installation to set X11 VT switching based on user choice
   - Users who previously enabled consoles must re-enable for keys to work

2. IMPROVED: Simplified hidden tab gesture to single toggle
   - 3-finger DOWN now toggles hidden tabs (both show AND hide)
   - Removed separate 3-finger UP gesture (simpler UX)
   - Updated all gesture handlers in both standard and Jitsi modes
   - Updated all console.log messages and documentation

README Updates:
- Updated all version references to 0.9.7-4
- Updated Touch Gesture Quick Reference table
- Simplified gesture: 3-finger DOWN = Toggle hidden tabs
- Updated hidden tabs documentation to reflect toggle behavior
- Added important notes about virtual console fix in 0.9.7-4
- Added instructions to re-enable consoles for existing users
- Updated menu system access examples
- Updated project status to "Gesture & Console Improvements"

This release focuses on fixing the console key combo issue and improving
the hidden tab gesture for easier one-handed use.
2025-12-02 12:48:14 +00:00
Claude 5ceccbb420 Work in progress: Version 0.9.7-4 improvements
Completed Changes:
- Updated version header to 0.9.7-4 with release notes
- FIXED: Virtual console Ctrl+Alt+F1-F8 key combinations now work
  - Updated configure_virtual_consoles() to modify X11 serverflags
  - Enable/disable now updates both systemd getty AND X11 VT switching
  - Added restart lightdm notification for changes to take effect  - Fixed initial installation to set X11 VT switching based on user choice
- FIXED: Swapped hidden tab gestures for easier use
  - 3-finger DOWN now shows hidden tabs (easier than UP)
  - 3-finger UP now returns to normal tabs
  - Updated all gesture handlers and documentation
  - Changed in both standard and Jitsi preload modes

In Progress:
- URL naming feature (requires config schema changes)
- Navigation hot corner menu (substantial new feature)

These changes fix the immediate issues and improve usability.
The navigation menu feature requires extensive additional development.
2025-12-02 12:34:34 +00:00
Claude 5ff748b875 Bump version to 0.9.7-3
Version Changes:
- Created install_kiosk_0.9.7-3.sh with updated version number
- Updated script header with release notes for 0.9.7-3
- Updated SCRIPT_VERSION constant to "0.9.7-3"

README Updates:
- Updated all references from 0.9.7-2 to 0.9.7-3
- Updated Quick Install wget command
- Updated Menu System Access examples
- Updated Complete Uninstall examples
- Updated Project Status section
- Updated footer version

Release Notes for 0.9.7-3:
- Fixed missing complete_uninstall function (line 8704 error)
- Added virtual console configuration (Ctrl+Alt+F1-F8)
- Added emergency hotspot to initial installation
- Enhanced security options and documentation
2025-12-02 01:10:13 +00:00
Claude ed87ff257c Update README with new features and hidden tab use cases
Documentation updates:
- Update Quick Install script name to install_kiosk_0.9.7-2.sh
- Document virtual console configuration feature
- Document emergency hotspot configuration during install
- Document complete uninstall functionality
- Add comprehensive "Why Use Hidden Tabs?" section with:
  - Private communication use cases
  - Administrative access scenarios
  - Content management applications
  - Secure entertainment options
  - Business use cases
  - Real-world example scenarios
- Add new "Installation & Management Features" section with:
  - Virtual Console Configuration details
  - Emergency WiFi Hotspot documentation
  - Complete Uninstall process and safety features
- Update menu system documentation
- Update system behavior security notes
- Update version and date to 0.9.7-2, December 2, 2024
2025-12-02 01:00:23 +00:00
Claude 1cd1565239 Fix install script issues and add new features
- Fix line 8704: Add missing complete_uninstall() function
  - Provides full system cleanup and uninstallation
  - Removes kiosk user, services, and all configurations
  - Offers reboot option after uninstall

- Add virtual console configuration feature
  - New configure_virtual_consoles() function
  - Allows enabling/disabling Ctrl+Alt+F1-F8 console access
  - Added to Advanced menu (option 7)
  - Integrated into initial installation with security prompt

- Add emergency hotspot to initial installation
  - Prompts user at end of installation
  - Can be configured immediately or deferred
  - Provides automatic WiFi hotspot when internet is down
2025-12-02 00:42:39 +00:00
Claude bac48cd183 Fix jq command error in save_config and bump to v0.9.6-3
Fixed critical bug where jq command was incomplete in save_config function,
causing configuration save to fail with jq usage error when configuring
rotation sites.

Issue: The jq -n command on lines 3476-3493 had all arguments but was
missing the JSON template/filter, causing jq to output its help text
instead of creating the config file.

Fix: Added complete JSON object template to jq command with all required
fields (unit, autoswitch, enableTouch, etc.) and empty tabs array.

Version bumped from 0.9.6-2 to 0.9.6-3.
2025-11-23 19:30:59 +00:00
Claude b1a007778a Add talkiepi-based intercom setup as simpler alternative to talkkonnect
Created setup_intercom_simple.sh using talkiepi (barnard fork) instead of
talkkonnect for a more stable and lightweight intercom solution.

Advantages over talkkonnect:
- Simpler build process (no Opus patching required)
- Fewer dependencies (just Go, libopenal, libopus)
- Full CLI support for server, username, password, and channel
- More stable and less fragile
- Better suited for headless/kiosk automation

Also added INTERCOM_COMPARISON.md documenting all evaluated options
(talkkonnect, talkiepi, barnard, mumbler) with recommendations.
2025-11-23 19:05:30 +00:00
Claude 5efc4a6e91 Fix talkkonnect uninstall in setup_intercom.sh
The uninstall function was only removing old installation paths, causing
talkkonnect to appear as "still installed" after uninstalling.

Fixed both check_talkkonnect_status() and uninstall_talkkonnect():

check_talkkonnect_status():
- Now checks for both old and new installation locations
- Old: ~/go/bin/talkkonnect and ~/talkkonnect.xml
- New: /usr/local/bin/talkkonnect and ~/.config/talkkonnect/
- Checks all locations to accurately determine if installed

uninstall_talkkonnect():
- Removes binaries from BOTH /usr/local/bin and ~/go/bin
- Removes config from BOTH ~/.config/talkkonnect and ~/talkkonnect.xml
- Properly stops and disables service before removing
- Shows progress with descriptive messages
- Optionally removes source directory ~/talkkonnect
- Only performs actions if files/directories actually exist

Now uninstall properly removes everything and status correctly shows
"Not installed" after uninstalling.
2025-11-23 18:28:56 +00:00
Claude c07ec69eaf Integrate proven talkkonnect installation into setup_intercom
Completely replaced the install_talkkonnect_with_config() function in
setup_intercom.sh with the proven method from talkkonnect_complete_install.sh.

Key improvements:
- Uses working Opus patch for x86_64 architecture
- Installs to /usr/local/bin/talkkonnect (not ~/go/bin)
- Config in ~/.config/talkkonnect/ (proper XDG location)
- Sets <insecure>true</insecure> by default (handles self-signed certs)
- Proper XDG_RUNTIME_DIR in systemd service for PipeWire/audio
- Automatically enables service (starts on boot)
- Better progress feedback and error handling
- Uses Go 1.24.1 (latest stable)

The function now:
1. Installs all dependencies correctly
2. Builds with proper Opus library integration
3. Creates config with user's server/credentials from prompts
4. Sets up systemd service properly
5. Enables and starts service automatically

This makes setup_intercom.sh a complete, reliable one-stop solution
that uses the same proven method as talkkonnect_complete_install.sh
while maintaining the interactive prompt workflow.

Included files:
- setup_intercom.sh - Updated with new function
- setup_intercom.sh.backup - Backup of original
- setup_intercom_talkkonnect_function.txt - Reference for the new function
- update_setup_intercom.sh - Script used to perform the replacement
2025-11-23 16:50:04 +00:00
Claude be26312ca9 Add quick fix script for talkkonnect issues
Created fix_talkkonnect_now.sh to resolve immediate issues:
- Sets <insecure>true</insecure> for self-signed certificates
- Warns about SuperUser account (admin-only, not for clients)
- Fixes file ownership and permissions
- Creates/updates systemd service
- Enables and starts talkkonnect service automatically

This fixes:
- Certificate errors ("wrong certificate")
- SuperUser connection issues (can't connect as SuperUser)
- Service not starting automatically

The script detects existing installations and fixes them in-place.

Minor update to setup_intercom.sh to indicate improved method.
2025-11-23 13:01:19 +00:00
Claude 10a73fc6d4 Add audio troubleshooting tools and documentation
Added fix_talkkonnect_audio.sh diagnostic script:
- Checks PipeWire/PulseAudio session availability
- Lists all audio devices (ALSA, PulseAudio/PipeWire)
- Shows current talkkonnect audio configuration
- Provides specific recommendations for audio issues
- Includes test commands for verifying audio

Updated TALKKONNECT_SETUP.md:
- Added "Common Warnings (Usually Non-Fatal)" section
- Explains "Unable to Unmute" error (cosmetic, audio usually works)
- Explains "Unable to Find Channel Name" warning
- Explains "Failed to connect PipeWire event context" error
- Added reference to audio diagnostic script
- Included quick audio test commands

These help users understand that common errors like "Unable to Unmute"
are non-fatal and audio typically works despite the warnings.
2025-11-23 12:45:17 +00:00
Claude f56f0be57a Fix permission issues when creating config in different user's home
The installation script was failing with "Permission denied" when trying
to create the config directory in another user's home directory.

Fixes:
1. Added home directory existence check before creating config
2. Use sudo -u to create directory as target user when needed
3. Use sudo tee to write config file (handles all permission scenarios)
4. Use sudo for sed command to modify the created config file
5. Always set proper ownership and permissions after creation

This fixes the "mkdir: cannot create directory '/home/kiosk': Permission denied" error.

Now the script will:
- Verify target user's home directory exists (fail gracefully if not)
- Create config directory as the target user
- Write config file with sudo to avoid permission issues
- Set proper ownership (user:user) and permissions (755 dir, 644 file)
2025-11-23 12:36:09 +00:00
Claude e47251991e Add diagnostic script and improve permission fix for talkkonnect
Added diagnose_talkkonnect.sh to help troubleshoot installation issues:
- Checks binary installation
- Finds all config files and shows ownership
- Analyzes systemd service configuration
- Detects audio/PipeWire sessions for each user
- Identifies permission mismatches
- Provides specific recommendations

Improved fix_talkkonnect_permissions.sh:
- Now automatically updates systemd service file if needed
- Changes service user to match target user
- Updates config path in service file
- Reloads systemd after changes
- Stops service before making changes

These tools help resolve the "permission denied" error when talkkonnect
is configured to run as one user but config is owned by another.
2025-11-23 04:43:18 +00:00
Claude 28a3e394d8 Fix talkkonnect permission issues and add setup documentation
The installation script had a critical bug where it created the config
directory in the script runner's home directory instead of the target
user's home directory. This caused "permission denied" errors when the
systemd service tried to run as the target user.

Changes:
- Fixed CONFIG_DIR to use $TARGET_HOME instead of $HOME
- Updated config path replacements to use $TARGET_HOME
- Added ownership change after config creation when running as different user
- Created fix_talkkonnect_permissions.sh script to repair existing installations
- Added comprehensive TALKKONNECT_SETUP.md with troubleshooting guide

This fixes the "open /home/user/.config/talkkonnect/talkkonnect.xml: permission denied" error.
2025-11-23 04:25:56 +00:00
Claude a2136226b4 Fix Bluetooth scanning bailing after device discovery
The script was exiting immediately after showing "Devices found: 14" because
the timeout command returns exit code 124, which caused the script to bail
due to 'set -euo pipefail'. Added '|| true' to wait and bluetoothctl scan off
commands to allow the script to continue executing and display the device list.

install_kiosk_0.9.6-2.sh:7185-7186
2025-11-23 04:11:56 +00:00