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
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
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
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
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
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
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
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
- 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
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
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
- 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
- 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
- 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.
- 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
- 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
- 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
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.
- 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
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.
- 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
- 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
- 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
- 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
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.
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.
- 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
- 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
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
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.
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.
- 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.
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
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.
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.
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.
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.
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
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
- 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
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.
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.
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.
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
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
- 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
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.
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.
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.
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
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.
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.
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)
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.
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.
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
Fixes:
1. Addons menu: Remove duplicate menu items (1,2 appeared twice)
- Fixed numbering: Remote Access is now option 5 instead of 6
2. Bluetooth scanning improvements:
- Make controller pairable/discoverable before scanning
- Capture scan output to show DISCOVERED devices (not just paired)
- Real-time progress indicator during 30-second scan
- Separate display of discovered vs already-paired devices
- Better error handling for pairing failures
- Proper cleanup of scan process with 'scan off'
- Helpful hints when pairing fails (e.g., AuthenticationFailed)
The bluetooth scan previously only showed paired devices after scanning,
which made it appear that no devices were found even when they were
broadcasting. Now it properly captures and displays discovered devices.
Created check_talkkonnect_fix.sh to verify if the terminal initialization
fix has been applied to the talkkonnect systemd service. This script checks
for the presence of:
- Environment="TERM=dumb"
- StandardInput=null
These settings are required to prevent the "Cannot Initialize Terminal" error
when talkkonnect runs as a systemd service without a TTY.
PROBLEM:
- talkkonnect fails with "Cannot Initialize Terminal" error
- Service shows "Talkkonnect Terminated Abnormally" in logs
- Root cause: talkkonnect uses termbox-go which requires a TTY
- Systemd services don't provide TTY by default
SOLUTION:
- Added Environment="TERM=dumb" to systemd service
- Added StandardInput=null to prevent terminal initialization
- Both changes allow talkkonnect to run headless as a service
CHANGES:
- Updated install_kiosk_0.9.6-1.sh with the fix
- Created install_kiosk_0.9.6-2.sh (new version with fix)
- Added fix_talkkonnect_terminal.sh for quick patching of existing installations
Created new version 0.9.6-1 that removes all WebRTC and Jitsi intercom
functionality and adds comprehensive Bluetooth support instead.
Changes:
- REMOVED: WebRTC intercom system (all auto-discovery, mesh networking, PWA client)
- REMOVED: Jitsi web intercom (all configuration, PTT service, PIN dialog)
- ADDED: Bluetooth addon with device management
* Scan and pair bluetooth devices
* Connect/disconnect bluetooth audio devices
* Auto-reconnect to trusted devices
* Battery status display for supported devices
- UPDATED: Addon menu now shows "Bluetooth Audio & Devices" instead of Jitsi
- UPDATED: Logs menu now includes Bluetooth logs
- UPDATED: Installation overview lists bluetooth instead of Jitsi
- UPDATED: Version header documents this as "Bluetooth Edition"
Recommended: Users should use talkkonnect addon for native PTT intercom
instead of web-based solutions for better audio quality and lower latency.
File size reduced from 338KB to 322KB (removed ~400 lines of code)
All bash syntax validated successfully
The status check was showing "Not installed" even after successful
installation because it relied on PATH and file checks that weren't
working reliably.
Changes:
- Check for /etc/systemd/system/talkkonnect.service first
- This is the most reliable indicator of installation
- Systemd service file is created during install and requires root
- Falls back to command/file checks if service file doesn't exist
This ensures status shows correctly immediately after installation.
Fixes "Text file busy" error and "Not installed" status:
1. **Stop service before install** (lines 535-547)
- Check if talkkonnect service is running
- Stop systemd service if active
- Kill any stray processes
- Sleep 1 second to ensure file is released
- Then copy the new binary
2. **Fix status check** (line 72)
- Changed from $HOME/go/bin/talkkonnect
- To /home/$KIOSK_USER/go/bin/talkkonnect
- Now correctly detects installed binary
3. **Separate build and install steps**
- Build completes inside first sudo block
- Installation happens in second sudo block after stopping service
- Clean error handling for each step
This matches the working talkkonnect_complete_install.sh approach.
The build was succeeding but the post-build verification was failing
because it tried to check /home/kiosk/talkkonnect-binary from outside
the sudo -u kiosk block.
Changes:
- Move binary verification and installation inside the sudo -u block
- Use ~ instead of /home/$KIOSK_USER (more reliable inside sudo)
- Remove redundant chmod/chown after sudo block
- Binary now installed while running as kiosk user
This matches the approach from talkkonnect_complete_install.sh where
all file operations happen inside the user context.
Implements comprehensive Bluetooth speaker/headphone support:
- Interactive pairing wizard using expect/bluetoothctl
- Device management (add, remove, disconnect, reconnect)
- Auto-reconnect on boot via systemd service
- Audio routing with PipeWire/PulseAudio integration
- Built-in diagnostics for troubleshooting
- Status display in addons menu
- Avoids CLI complexity with automated pairing workflow
Features:
- Section 14.5: Complete Bluetooth addon module
- Menu integration: New option 7 in Addons menu
- Status tracking: Shows paired/connected device counts
- Compatible with existing Squeezelite/Jitsi audio stack
Changed from /tmp to ~/talkkonnect to match working script approach:
- Clone to /home/$KIOSK_USER/talkkonnect instead of /tmp/talkkonnect-src
- Build to ~/talkkonnect-binary then copy to ~/go/bin/talkkonnect
- Run all operations as kiosk user from the start
- No chown needed - user owns their own home directory
This eliminates all "Permission denied" errors when:
- Creating vendor directory
- Removing old source files
- Building the binary
Matches the proven approach from talkkonnect_complete_install.sh
Added chown after git clone to give kiosk user ownership of the
/tmp/talkkonnect-src directory. This allows 'go mod vendor' to
successfully create the vendor directory when running as kiosk user.
Without this fix, the build would fail with:
"go: mkdir /tmp/talkkonnect-src/vendor: permission denied"
"Warning: gopus not found in vendor directory"
"[ERROR] Binary not executable after build"
Critical fixes to resolve "[ERROR] Binary not executable after build":
1. **Opus x86_64 Compatibility Patch**
- Added gopus library patch to use system libopus for x86_64
- The embedded Opus source in gopus is ARM-optimized and incomplete for x86_64
- Now uses pkg-config to link against system libopus library
2. **Vendored Dependencies**
- Added `go mod vendor` to create vendored dependencies
- Build now uses `-mod=vendor` flag to ensure patched gopus is used
3. **Enhanced Build Process**
- Set CGO_CFLAGS and CGO_LDFLAGS for proper Opus compilation
- Build in cmd/talkkonnect directory (correct location)
- Added build-essential and pkg-config to dependencies
4. **Improved XML Configuration**
- Updated to modern talkkonnect/xml document type
- Added critical voicetargets section to prevent crashes
- Added proper global settings structure
- Created .config/talkkonnect directory for logs
5. **Additional Dependencies**
- Added libopus0, libopusfile-dev for complete Opus support
- Added build-essential and pkg-config for compilation
This integrates the working approach from talkkonnect_complete_install.sh
into the setup_intercom.sh script.
Changes:
- Add SCRIPT_DIR variable for locating companion scripts
- Update addon_talkkonnect_intercom() to launch setup_intercom.sh
- Replace 134 lines of duplicate code with 30-line integration
- Update INTERCOM_README.md with clear usage instructions
Benefits:
- Single source of truth for intercom functionality
- Easier maintenance (update only setup_intercom.sh)
- Cleaner separation: install_kiosk handles UBK, setup_intercom handles intercom
- Both scripts work standalone or together automatically
Usage:
- Option 1: Run install_kiosk_0.9.6.sh → Addons → Intercom (option 4)
- Option 2: Run setup_intercom.sh directly
- Both scripts must be in same directory (automatic when cloning repo)
Created modular, standalone intercom system to avoid bloating the
10,000+ line main install script.
New Files:
- setup_intercom.sh: Complete standalone installation and management
* Install Murmur server (one kiosk becomes the server)
* Install talkkonnect client (connect to existing server)
* Install both (all-in-one setup)
* Full service management (start/stop/restart)
* Configuration tools
* Log viewing
* Uninstall options
- INTERCOM_README.md: Comprehensive documentation
* Quick start guide
* Use cases and scenarios
* Multi-kiosk setup instructions
* Troubleshooting guide
* Integration instructions
* Technical details
- integrate_intercom.sh: Integration helper
* Shows how to wire into main install script
* Example menu integration code
* Alternative sourcing method
Features:
✓ Menu-driven interface with dynamic options
✓ Status display (installed/running state)
✓ Server configuration (password, port, welcome text)
✓ Client configuration (server, credentials, channel)
✓ Service management (enable/disable/start/stop)
✓ Log viewing for diagnostics
✓ Clean uninstallation
Use Cases:
1. Single kiosk (server + client)
2. Multi-kiosk (one server, multiple clients)
3. Connect to external Mumble server
4. Other devices can connect (desktop/mobile Mumble apps)
Technical:
- Murmur server on port 64738
- talkkonnect built from source with Go
- Systemd service management
- Audio through ALSA/PipeWire
- PTT via keyboard (default: spacebar)
Next Steps:
- Test installation on clean system
- Wire into main install script addon menu
- Consider auto-discovery for multi-kiosk setups
The installation prompt was only accepting lowercase 'y', causing the
script to exit when users entered uppercase 'Y'. This fix aligns the
prompt behavior with all other y/n prompts in the script by using
case-insensitive pattern matching (=~ ^[Yy]$).
Fixes issue where installation would bail after selecting Y to proceed.
Fixes JavaScript error "given browserview is not attached to the window"
that occurred when unlocking the screen after boot with password protection.
Changes to unlockScreen() function:
- Add try-catch around hidden view restoration to prevent crashes
- Ensure view is attached with addBrowserView() before setTopBrowserView()
- Add fallback to regular views if hidden view restoration fails
- Validate currentIndex is within bounds before using it
- Check views.length>0 before attempting to attach views
This ensures safe view restoration in all unlock scenarios, particularly
when unlocking immediately after boot with password protection enabled.
Key changes:
- Remove time-based lockout prompt ("Only enforce lockout during specific hours?")
- Detach all browser views when locked to prevent content visibility
- Show power menu on solid black screen (lockoutWindow) when locked
- Password protection now always active when enabled (more reliable)
Fixes:
- Users can no longer see URLs or content when password screen is active
- Pressing Ctrl+Alt+Delete shows power menu on solid screen, not over content
- All browser views completely hidden until password is entered
CRITICAL FIX: Removed lockoutActivityTime reset from markActivity()
- markActivity() was resetting lockoutActivityTime on EVERY activity
- This prevented inactivity lockout from EVER triggering
- Now lockout timer only resets when user unlocks or selects extension
ROOT CAUSE:
The markActivity() function was resetting lockoutActivityTime (line 3904):
if(enablePasswordProtection && lockoutTimeout > 0){
lockoutActivityTime = now; // ← PROBLEM
}
markActivity() is called on EVERY:
- Mouse move
- Mouse click
- Keyboard press
- Page load
- Focus change
Result: lockoutActivityTime was CONSTANTLY being reset, so lockout could
NEVER reach the configured timeout (user reported 17 minutes wasn't working).
FIX:
Removed the lockoutActivityTime reset from markActivity() entirely (line 3908).
Now lockoutActivityTime only resets when:
1. User unlocks screen (unlockScreen() function)
2. User selects time extension (showPauseDialog/showInactivityPrompt)
This is the correct, simple behavior: lockout should trigger after X minutes
of inactivity, period. If user wants to extend, they can select an extension.
USER REPORT:
- Scheduled lockout works ✓ (lock at 15:00)
- Inactivity lockout doesn't work ✗ (lock after 17 min idle)
- This fix addresses the inactivity lockout issue
SIMPLIFIED: Removed unnecessary complexity added in v0.9.5-7 and v0.9.5-8.
The simple fix was just to stop resetting the timer on every activity.
CRITICAL FIX: Extensions now properly reset lockout activity timer
- Pause button extensions now reset lockoutActivityTime when selected
- Manual site timeout extensions now reset lockoutActivityTime when selected
- Prevents lockout from counting idle time accumulated BEFORE extension
- Lockout timer now truly starts fresh when user selects an extension
ROOT CAUSE (v0.9.5-7 was incomplete):
In v0.9.5-7, I added code to checkLockoutTimer() to SKIP lockout checks during
active extensions. This prevented lockout from triggering during the extension
period. However, the extension handlers themselves didn't reset lockoutActivityTime.
TWO PLACES WERE MISSING lockoutActivityTime reset:
1. showInactivityPrompt() - Manual site timeout extensions (line 4632)
When user selects "15 minutes" on manual site inactivity prompt:
✓ Set inactivityExtensionUntil = now + 15min
✓ Set lastUserInteraction = now
✓ Set siteStartTime = now
✗ Did NOT set lockoutActivityTime = now
2. showPauseDialog() - Pause button extensions (line 4680)
When user clicks pause button and selects "15 minutes":
✓ Set inactivityExtensionUntil = now + 15min
✓ Set lastUserInteraction = now
✓ Set siteStartTime = now
✗ Did NOT set lockoutActivityTime = now
BROKEN SCENARIO IN v0.9.5-7:
- Lockout configured for 30 minutes of inactivity
- User is idle for 10 minutes
- User clicks "15 minutes" extension
- lockoutActivityTime still shows 10 minutes ago (NOT reset)
- Extension blocks lockout for 15 minutes (v0.9.5-7 fix working)
- After 15 minutes, extension expires
- v0.9.5-7 code resets lockoutActivityTime to now
- Lockout would happen 30 minutes later
The problem: This means lockout NEVER enforced the configured timeout if
users kept selecting extensions, because each extension expiration reset
the lockout timer.
FIX IN v0.9.5-8:
Added lockoutActivityTime = now to BOTH extension handlers:
- Lines 4637-4641: Manual site inactivity prompt extension handler
- Lines 4684-4688: Pause button extension handler
NEW BEHAVIOR:
- User idle for 10 minutes
- User clicks "15 minutes" extension
- lockoutActivityTime = now (RESET on extension selection)
- User is now considered "active" (selected extension = user interaction)
- Extension blocks lockout for 15 minutes
- After 15 minutes, lockoutActivityTime shows 15 minutes ago
- Lockout happens 30 minutes after extension selected (at 15 + 30 = 45 min total)
This is more intuitive: selecting an extension is a user interaction that
proves the user is present, so lockout timer should start fresh.
Includes all fixes from v0.9.5-7 (checkLockoutTimer respects extensions)
CRITICAL FIX: Inactivity lockout now respects time extensions
- Lockout timer was completely ignoring pause button extensions
- Lockout timer was ignoring manual site timeout extensions
- Added inactivityExtensionUntil check to checkLockoutTimer() function
- Time extensions now properly prevent BOTH site timeout AND lockout
- When extension expires, lockout timer resets (doesn't trigger immediately)
FIXED: Manual sites (duration: 0) now fully support time extensions
- Pause button extensions now work on manual sites
- Manual site timeout extensions now prevent lockout
- Extensions apply to both rotation blocking AND lockout prevention
ROOT CAUSE:
The checkLockoutTimer() function (line 4061) only checked:
- lockoutActivityTime vs lockoutTimeout
- Did NOT check inactivityExtensionUntil
This meant when a user clicked "15 minutes" on pause button:
✓ Site rotation/timeout was blocked (lines 4317, 4375 checked extension)
✗ Inactivity lockout still triggered after configured time
EXAMPLE SCENARIO THAT WAS BROKEN:
- Manual site with 2 min inactivity timeout to return home
- Lockout after 5 minutes of inactivity
- User idle for 1m 50s, clicks "15 minutes" extension
- Expected: Can stay for 15 more minutes
- Actual v0.9.5-6:
* Home return prompt blocked ✓
* Lockout happens at 5 min idle ✗
- Fixed v0.9.5-7:
* Home return prompt blocked ✓
* Lockout also blocked for 15 min ✓
FIX (lines 4083-4100):
Now checkLockoutTimer() checks inactivityExtensionUntil FIRST:
1. If within extension period: return early (skip lockout check)
2. If extension just expired: reset lockoutActivityTime (prevent immediate trigger)
3. Then check normal lockout timeout
This matches the pattern used in rotation (line 4317) and home return (line 4375).
Includes all fixes from v0.9.5-6 (boot password sequence, limited power menu)
CRITICAL SECURITY FIX#1: Boot password now required BEFORE showing websites
- Password screen now appears IMMEDIATELY on boot (no website flash)
- Websites and rotation timer only start AFTER successful password entry
- Root cause: attachView() was called before checking boot flag
- Fix: Reordered code to check boot flag FIRST, only call attachView() if no boot
- unlockScreen() now starts master timer when unlocking from boot password
CRITICAL SECURITY FIX#2: Limited power menu when locked out
- Ctrl+Alt+Del when locked now shows LIMITED menu: Shutdown/Restart/Cancel
- NO Reload option available when locked (prevents bypass)
- Full menu (with Reload) only available when unlocked
- Still allows emergency shutdown/restart without password
- Message clearly indicates "System is locked. Limited options available."
ROOT CAUSE OF BOOT PASSWORD BYPASS:
In v0.9.5-5, the code sequence was:
1. attachView(startIndex) - shows website
2. Check boot flag - if exists, show password screen
This meant users saw the website for ~1 second, then password screen appeared.
Pressing Ctrl+Alt+Del at that moment would reload and bypass the password.
NEW SEQUENCE in v0.9.5-6:
1. Check boot flag FIRST
2. If boot flag exists: show password screen, DON'T load websites
3. If no boot flag: load websites normally
4. When password entered: attachView() and startMasterTimer()
Includes all fixes from v0.9.5-5 and v0.9.5-4
CRITICAL SECURITY FIX:
- Fixed Ctrl+Alt+Del bypassing boot password requirement
* Added isLockedOut check to showPowerMenu() function
* Power menu (Shutdown/Restart/Reload) now blocked when system is locked out
* Prevents bypassing boot password via Reload option
* Also prevents bypassing inactivity lockout and time-based lockout
ROOT CAUSE:
The showPowerMenu() function was missing the isLockedOut check that other
navigation functions (nextTab, prevTab) already had. This allowed users to
press Ctrl+Alt+Del during boot password screen, select "Reload", and bypass
the password requirement entirely.
NAVIGATION TROUBLESHOOTING:
Added troubleshooting notes for users experiencing navigation issues:
- Check config.json for hidden sites (duration: -1)
- Hidden sites don't count toward navigation
- Need at least 2 visible sites for Ctrl+Tab/swipe to work
Includes all fixes from v0.9.5-4 (polkit restrictions, X server hardening,
autostart compatibility, xbindkeys fixes)
This was the root cause of extensions not working. When user clicked
extension buttons (15 min, 30 min, etc.), that click triggered markActivity()
which immediately cleared the extension that was just set.
Now extensions work correctly - they only expire when:
- Time runs out naturally
- User explicitly goes home
- User cancels the extension
This fixes:
- Pause button extensions not working (rotating after 1 min)
- Manual site timeout extensions not working (prompt after 1 min)
- Both rotation and inactivity timer extensions
This release fixes multiple critical bugs reported in v0.9.5-1:
## Configuration Persistence Fixes
- **CRITICAL**: Fixed sites being wiped when editing password/pause/OSK settings
- Added load_existing_config() function to load all settings before any menu
- Now called before configure_optional_features and configure_password_protection
- Prevents empty URLS/DURS arrays from overwriting existing sites in save_config
- **Fixed password protection not being saved on reboot**
- Settings now properly persist through load_existing_config function
- All password protection variables properly loaded from config.json
- **Fixed sites not being saved on reboot**
- Configuration persistence issue resolved with load_existing_config
## Timing & Extension Fixes (main.js)
- **Fixed time extension rotating to wrong site**
- Added checks to prevent rotation while pause dialog is open
- Added checks to prevent rotation while inactivity prompt is open
- Extension is now applied to the current site, not the next one
- **Fixed pause not working correctly**
- Pause dialog no longer allows rotation during user selection
- Extension properly blocks rotation until time expires
- **Fixed manual site timeout popup appearing after 1 minute**
- Fixed extension expiration to reset lastUserInteraction
- Prevents prompt from showing immediately after extension expires
- Added proper checks to prevent duplicate prompts
## User Experience Improvements
- **Added cancel/exit option to menus**
- configure_optional_features now asks "Save these changes?"
- configure_password_protection now asks "Save these changes?"
- Users can discard changes by answering "no"
- **Added comprehensive settings display**
- show_current_config now displays all sites with [HOME] marker
- Shows home URL and inactivity timeout
- Shows optional features status (pause/keyboard buttons)
- Shows complete password protection configuration
- Shows lockout timeout, lock time, active hours, and boot password
## Version Updates
- Bumped SCRIPT_VERSION to 0.9.5-2
- Bumped main.js VERSION to 0.9.5-2
All reported issues from 0.9.5-1 have been addressed.
New Features:
- Time-based session lockout: Automatically lock at a specific time daily
- Active hours for lockout: Only enforce timeout during configured hours
- Password on boot: Require password when system powers on/reboots
- Enhanced lockout timeout: Now respects active hours configuration
Configuration Options:
- lockoutAtTime: Time to auto-lock (e.g., "17:00")
- lockoutActiveStart/End: Time range for lockout enforcement
- requirePasswordOnBoot: Boolean to require password on system boot
Technical Changes:
- Updated configure_password_protection() with new prompts
- Added lockout time validation (HH:MM format)
- Enhanced main.js with isWithinActiveHours() and checkScheduledLockTime()
- Added boot flag creation in openbox autostart
- Updated config.json schema with new fields
The session timeout (inactivityTimeout) continues to work as before,
returning to home page after inactivity. The lockout timeout provides
an additional security layer with password protection.
- Fixed missing closing brace in keyboard auto-close section
- Removed duplicate line in showKeyboardIcon function
- Corrects SyntaxError: missing ) after argument list at line 441
Based on v0.9.2-6 (includes enhanced Electron update tool)
Version 0.9.4 introduces configurable optional features and security:
New Features:
- Optional pause button: Can be disabled during install/rerun
* Disables functionality entirely, not just hides the UI
* Configured in Core Settings menu (option 7)
- Optional keyboard button: Can be disabled during install/rerun
* Disables on-screen keyboard functionality completely
* Configured in Core Settings menu (option 7)
- Password protection with session lockout:
* Customizable lockout timeout (in minutes of inactivity)
* Blank screen during lockout with no interaction allowed
* Password required to unlock after timeout
* Password required after display schedule wake-up
* SHA-256 password hashing for security
* Option to only require password after display wake (0 minute timeout)
Configuration:
- New configure_optional_features() function for pause/keyboard buttons
- New configure_password_protection() function for security setup
- Added to Core Settings menu (options 7 & 8)
- All settings saved to config.json and loaded on startup
Implementation:
- Main.js: Password lockout window with blank screen
- Main.js: Lockout timer check in master timer loop
- Main.js: Display wake flag detection (.display-wake file)
- Main.js: Conditional pause button visibility based on config
- Preload.js: Conditional keyboard button based on config
- Display-on script: Creates flag file to trigger password requirement
All features are configurable on first install or by rerunning the script.
Fixed two critical issues preventing Electron update from completing:
1. cd permission denied error
Problem: Script tried to `cd /home/kiosk/kiosk-app` which failed with
"Permission denied" because the directory has restricted permissions (drwxr-x---)
and the regular user can't enter it.
Fix: Use `sudo -u kiosk bash -c "cd '/home/kiosk/kiosk-app' && npm install ..."`
instead of separate cd + npm commands. This runs both commands as the kiosk
user in a single bash session, avoiding the permission issue.
2. Wrong service name (kiosk vs lightdm)
Problem: Scripts tried to stop/start "kiosk" service which doesn't exist on
the user's system. Their kiosk runs under lightdm service.
Fix: Changed all references from:
- `systemctl stop/start kiosk` → `systemctl stop/start lightdm`
- "Restart kiosk service" → "Restart kiosk display"
- `journalctl -u kiosk` → `journalctl -u lightdm`
Additional fixes:
- Updated file checks: `[ -d ]` → `sudo test -d` for restricted directories
- Applied fixes to both update paths: successful install and failure/restore
- Updated both update_electron.sh and install_kiosk_0.9.2-6.sh
Changes in both scripts:
- update_electron() function: removed cd, added bash -c wrapper, changed service name
- Backup restore paths: same fixes applied
- Success path: updated restart prompts and service checks
- Failure path: fixed restore process with proper directory access
The update should now complete successfully without permission errors.
Fixed two issues preventing the Electron update from working properly:
1. Log messages appearing in version output
- get_latest_electron_version() was outputting log messages to stdout
- These messages were being captured along with the version number
- Result: "Target version: [INFO] Fetching...39.2.3" in output
- Fix: Redirect log_info and log_error to stderr with >&2
- Now only the version number is captured in the variable
2. Backup function permission errors
- stat command needed sudo to read owner of restricted directories
- File checks [ -f ] couldn't access files in drwxr-x--- directories
- mkdir failed with "cannot create directory '/home/kiosk': Permission denied"
- Fix: Use sudo for all file operations in create_backup():
* sudo stat -c '%U' to get directory owner
* sudo test -f/d for file/directory checks
* sudo -u owner for mkdir, cp, and file writes
Changes in both update_electron.sh and install_kiosk_0.9.2-6.sh:
- get_latest_electron_version functions: Added >&2 to log statements
- create_backup functions: Added sudo to stat and all file checks
- Ensures backup works with restricted /home/kiosk permissions
The update process should now complete successfully without permission errors
or garbled version output.
The scripts were failing to find the kiosk installation at /home/kiosk/kiosk-app
because the /home/kiosk directory has restricted permissions (drwxr-x---),
preventing regular users from reading it.
Changes in both update_electron.sh and install_kiosk_0.9.2-6.sh:
1. Updated find_kiosk_dir() to use sudo for all file checks
- sudo test -f for checking if main.js exists
- Prevents "permission denied" errors on restricted directories
2. Added Method 4: Detect from running electron process
- Parses ps output to find electron executable path
- Extracts app directory from the path
- Provides fallback when directory searches fail
3. Updated get_current_electron_version functions
- Use sudo test -f to check if package.json exists
- Use sudo grep to read package.json and get version
- Ensures version detection works with restricted permissions
4. Fixed directory existence checks
- Use sudo test -d for checking kiosk directory
These changes allow the scripts to:
- Find kiosk installations in directories with restricted permissions
- Detect installations even when run as a regular user
- Work correctly with the standard /home/kiosk setup (drwxr-x---)
- Provide better fallback detection using running processes
The scripts will now prompt for sudo password when needed to check
for files in restricted directories, then continue normally.
Changed the script to run as a regular user instead of requiring sudo.
The script now:
- Checks that it's NOT being run as root (prevents sudo usage)
- Uses sudo for individual commands that need elevated privileges
- Prompts for sudo password only when needed
Changes:
- Removed EUID check that required running with sudo
- Added check to prevent running as root
- Added sudo to backup operations (mkdir, cp, file writes)
- All systemctl and npm install commands already use sudo appropriately
This matches the behavior of install_kiosk scripts which should be run
as a regular user, not with sudo.
Usage: ./update_electron.sh (not sudo ./update_electron.sh)
This new version of the install script includes a completely rewritten
manual Electron update tool that fixes all the issues with the previous version:
NEW FEATURES:
- Smart installation detection across multiple locations
- Verifies Electron is actually running (not just installed)
- Gets current version from both package.json and node_modules
- Fetches latest stable version from npm with multiple fallback methods
- Clear version comparison display (current vs latest)
- Breaking changes warning with direct links to Electron documentation
- Automatic backup creation before any changes
- Provides clear restore instructions
- Multiple user confirmation prompts before making changes
- Automatic rollback if update fails
- Fixes chrome-sandbox permissions after installation
- Manages kiosk service stop/start automatically
FIXES:
- No more "no electron app found" errors
- No more "script just bails" - proper error handling throughout
- Proper detection of running Electron instances
- Network failure handling with multiple fallback methods
- Clear feedback at every step of the process
The enhanced update tool is accessible from:
Advanced Menu → Manual Electron Update
Version updated from 0.9.2 to 0.9.2-6 to reflect the enhancement.
This script addresses issues with the manual Electron update process by:
- Detecting kiosk installation across multiple methods (user home, systemd service)
- Checking if Electron is actually running (not just installed)
- Getting current Electron version from both package.json and node_modules
- Fetching latest stable Electron version from npm registry with fallbacks
- Displaying clear version comparison (current vs latest)
- Warning users to check for breaking changes with links to documentation
- Creating automatic backups of package.json, package-lock.json, and version info
- Providing clear restore instructions if something goes wrong
- Requiring user confirmation at multiple steps before making changes
- Automatically attempting rollback if the update fails
- Fixing chrome-sandbox permissions after installation
- Managing kiosk service stop/start around the update
The script handles edge cases like:
- Missing or moved installations
- Network failures when fetching versions
- Failed npm installations with automatic recovery
- Permission issues with proper sudo user handling
Users can now safely update Electron with confidence that they can restore
if needed, and with clear visibility into what versions are being used.
The pause button wasn't appearing because preload.js variables were being
reset when pages reloaded/navigated, but the visibility message was only
sent once in attachView().
Now sends pause-button-visibility on EVERY page load (did-finish-load event)
to ensure the button state persists across page reloads and navigation.