Migrate Authelia addon; fix real config-clobbering bug in save_config; bump to v2.6.0
Second Addon migrated: menus/addon_authelia.sh (encrypted SSO
credentials, AES-256-CBC with a key derived from /etc/machine-id via
scrypt - same algorithm main.js decrypts with - plus the full
Dockerized server-side setup instructions, now viewable again later
without reconfiguring).
Investigating how to wire its three config.json fields (autheliaURL/
autheliaUsername/autheliaEncryptedPassword) into lib/config.sh surfaced
a real, currently-shipping bug that has nothing to do with Authelia
specifically: save_config() did a full `jq -n` rebuild of config.json
from a fixed list of known fields - identical to what the legacy
script's own save_config still does. The legacy configure_authelia()
writes its three fields via a careful `. + {...}` merge that preserves
everything else already in the file, but neither save_config knew those
fields existed - so the next time a user visited Sites, Touch Controls,
Navigation, or Password Protection (all of which call save_config),
their Authelia credentials were silently deleted. This bug already
existed in the shipped single-file installer; it was ported faithfully
into lib/config.sh's first version because no test happened to set an
untracked field before calling save_config.
Fixed in lib/config.sh: save_config now merges its known fields onto
whatever's already in config.json (jq `. + {...}`) instead of rebuilding
the file from nothing, with a `jq empty` validity check falling back to
`{}` if the existing file is missing or corrupt. Any field this tool
doesn't track - Authelia's three today, anything else a future addon
adds tomorrow - now survives automatically. autheliaURL/
autheliaUsername/autheliaEncryptedPassword are also tracked fields in
their own right now (load_existing_config/save_config), consistent with
every other config.json field this tool manages, giving Authelia both a
direct fix and the general safety net.
The equivalent bug still exists, unfixed, in ubuntu-based-kiosk.sh's own
save_config - noted in both that script's changelog and the Readme's
"Modular Management" section as an open question: whether to backport
just that one fix into the legacy script now, independent of the wider
migration, given it's a real credential-loss bug affecting the
currently-shipping installer today.
Verified:
- New dedicated test (test_save_merge.sh) proving the save_config fix
itself: seeded config.json with a simulated untracked field via the
same `. + {...}` merge Authelia's own code uses, called save_config
from an unrelated context (Sites deleting a tab), and confirmed the
untracked field survived while the tab deletion still correctly took
effect (not undone by the merge) - plus corrupt-JSON and
missing-file edge cases both handled without crashing.
- New scratch-config test for addon_authelia.sh using REAL encryption
(this sandbox has both Node and /etc/machine-id): configured with a
real password, then decrypted the stored ciphertext using main.js's
exact algorithm (independently reproduced in the test) and confirmed
it recovers the original password exactly - true interoperability,
not just "some ciphertext was produced." Also covered cancel paths,
clearing the configuration, the encryption-unavailable failure path,
and confirmed Authelia's config survives an unrelated Sites save.
- Full regression: re-ran all 9 prior scratch/stub test suites after
both the lib/config.sh changes - all still clean.
- End-to-end: ran the real install.sh as a genuine non-root, non-
"kiosk" user with a seeded minimal config.json, through Addons ->
Authelia -> Configure with a real URL/username/password -> confirmed
the resulting config.json on disk, and independently decrypted the
stored password for real using main.js's algorithm to confirm it
matches exactly. Clean exit code 0 throughout.
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
# Ubuntu Based Kiosk
|
||||
|
||||
**Current Version:** 2.5.0 (check script header for latest version)
|
||||
**Current Version:** 2.6.0 (check script header for latest version)
|
||||
**Built with Claude Sonnet 4.6 AI assistance**
|
||||
**License:** GPL v3 - Keep derivatives open source
|
||||
**Repository:** https://github.com/outis1one/ubuntu-based-kiosk/
|
||||
@@ -1209,6 +1209,9 @@ terminal menu and the web UI, so they can't drift apart).
|
||||
reconfigure for network access, complete uninstall (purge). The first
|
||||
Addon migrated — genuinely mutates real system state (apt packages,
|
||||
`/etc/cups`, ufw) rather than this project's own files.
|
||||
- `menus/addon_authelia.sh` — **Authelia Auto-Login** (Addons):
|
||||
encrypted SSO credentials plus the server-side setup instructions.
|
||||
Prompted the `save_config` merge fix above.
|
||||
- `install.sh` — entry point for the modular tool, now grouped **Core
|
||||
Settings / Addons / Advanced** like the legacy menu. Run it against an
|
||||
*already-installed* kiosk:
|
||||
@@ -1221,7 +1224,7 @@ terminal menu and the web UI, so they can't drift apart).
|
||||
**Honest status:** this does not yet replace first-time installation, or
|
||||
most of the old installer. `ubuntu-based-kiosk.sh` is still ~12,000
|
||||
lines and still contains its own unremoved, unmodified copies of every
|
||||
menu above (plus Upgrade, Reinstall, Uninstall, 4 more Addons, and the
|
||||
menu above (plus Upgrade, Reinstall, Uninstall, 3 more Addons, and the
|
||||
other 8 Advanced items — none of that has moved yet). Both copies
|
||||
coexist deliberately: the old ones stay until enough
|
||||
of Core Settings/Addons/Advanced is migrated to
|
||||
@@ -1230,13 +1233,26 @@ Migration continues one `menus/*.sh` file at a time; first-time
|
||||
installation itself is the last and largest piece to move, if it moves
|
||||
at all.
|
||||
|
||||
**Open question:** the config-clobbering bug fixed in `lib/config.sh`
|
||||
(v2.6.0 — `save_config` silently deleting fields it doesn't know about,
|
||||
like Authelia's credentials, on the next unrelated save) has the exact
|
||||
same shape in `ubuntu-based-kiosk.sh`'s own `save_config`, unfixed. It's
|
||||
a real bug in the currently-shipping single-file installer, independent
|
||||
of whether the rest of that menu ever gets migrated. Worth deciding
|
||||
separately whether to backport just that fix into the legacy script now
|
||||
rather than waiting for a full migration pass.
|
||||
|
||||
---
|
||||
|
||||
## Project Status & Future Plans
|
||||
|
||||
**Current Version:** 2.5.0
|
||||
**Current Version:** 2.6.0
|
||||
|
||||
**Recent Updates (v2.5.0):**
|
||||
**Recent Updates (v2.6.0):**
|
||||
- **Authelia Auto-Login migrated** — encrypted SSO credentials (same AES-256-CBC/scrypt algorithm `main.js` decrypts with, verified by a real encrypt→decrypt round trip in testing) plus the full server-side Docker setup instructions, viewable again later without reconfiguring.
|
||||
- **Important bug found and fixed, not specific to Authelia:** `save_config()` did a full rebuild of `config.json` from known fields — exactly like the legacy script's `save_config` still does. Authelia's own write is a careful merge that preserves everything else, but the *next* save from Sites, Touch Controls, Navigation, or Password Protection would silently delete the Authelia credentials, since none of those knew the three Authelia fields existed. **This is a real bug in the currently-shipping single-file installer**, not introduced by this migration. Fixed in `lib/config.sh` by changing `save_config` to merge its known fields onto whatever's already on disk instead of rebuilding from nothing, so any untracked field — Authelia's three today, anything else tomorrow — survives automatically. The equivalent bug still exists, unfixed, in `ubuntu-based-kiosk.sh`'s own `save_config` — see "Modular Management" below.
|
||||
|
||||
**Previous (v2.5.0):**
|
||||
- **First Addon migrated:** CUPS Printing — install/reconfigure/complete uninstall, in `./install.sh`. Genuinely mutates real system state (`apt install`/`remove --purge`, `/etc/cups`, `ufw`) at fixed paths CUPS itself doesn't let us relocate, so every test uses full command-level `sudo` stubbing rather than the scratch-directory approach used for this project's own files.
|
||||
- **Menu restructured:** `install.sh`'s top level is now grouped Core Settings / Addons / Advanced, matching the legacy tool, instead of one flat list — done now while it's cheap, ahead of the list getting unwieldy.
|
||||
- **Bug fix:** a "wait for service to start" retry loop used a bare `cmd1 && cmd2 && break` as its body — that's not made safe by being inside a loop; a bare `&&`/`||` list used as a standalone statement is fully subject to `set -e`, and the first command failing on an early iteration (near-certain right after a fresh install) would have killed the whole session. Restored the `if cmd1 && cmd2; then break; fi` form.
|
||||
|
||||
+6
-3
@@ -16,7 +16,8 @@
|
||||
# Core Settings: Sites & Page Timing, Display & Interaction, Timezone,
|
||||
# Hidden Site PIN, Password Protection & Lockout, WiFi,
|
||||
# Power/Display/Quiet Hours.
|
||||
# Addons: CUPS Printing (menus/addon_cups.sh).
|
||||
# Addons: CUPS Printing (menus/addon_cups.sh), Authelia Auto-Login
|
||||
# (menus/addon_authelia.sh).
|
||||
# Advanced: Diagnostics (menus/diagnostics.sh - system status/logs/
|
||||
# audio/network).
|
||||
#
|
||||
@@ -52,6 +53,8 @@ source "$SCRIPT_DIR/menus/power_schedule.sh"
|
||||
source "$SCRIPT_DIR/menus/diagnostics.sh"
|
||||
# shellcheck source=menus/addon_cups.sh
|
||||
source "$SCRIPT_DIR/menus/addon_cups.sh"
|
||||
# shellcheck source=menus/addon_authelia.sh
|
||||
source "$SCRIPT_DIR/menus/addon_authelia.sh"
|
||||
|
||||
################################################################################
|
||||
# Preflight
|
||||
@@ -115,8 +118,8 @@ core_settings_menu() {
|
||||
}
|
||||
|
||||
addons_menu_builder() {
|
||||
MENU_LABELS=("CUPS Printing")
|
||||
MENU_HANDLERS=(addon_cups_menu)
|
||||
MENU_LABELS=("CUPS Printing" "Authelia Auto-Login")
|
||||
MENU_HANDLERS=(addon_cups_menu addon_authelia_menu)
|
||||
}
|
||||
|
||||
addons_menu() {
|
||||
|
||||
+33
-2
@@ -60,6 +60,9 @@ LOCKOUT_AT_TIME=""
|
||||
LOCKOUT_ACTIVE_START=""
|
||||
LOCKOUT_ACTIVE_END=""
|
||||
REQUIRE_PASSWORD_ON_BOOT="false"
|
||||
AUTHELIA_URL=""
|
||||
AUTHELIA_USERNAME=""
|
||||
AUTHELIA_ENCRYPTED_PASSWORD=""
|
||||
|
||||
kiosk_user_exists() {
|
||||
id "$KIOSK_USER" &>/dev/null
|
||||
@@ -125,6 +128,10 @@ load_existing_config() {
|
||||
|
||||
boot_password=$(sudo -u "$KIOSK_USER" jq -r '.requirePasswordOnBoot // false' "$CONFIG_PATH" 2>/dev/null)
|
||||
[[ "$boot_password" == "true" ]] && REQUIRE_PASSWORD_ON_BOOT="true" || REQUIRE_PASSWORD_ON_BOOT="false"
|
||||
|
||||
AUTHELIA_URL=$(sudo -u "$KIOSK_USER" jq -r '.autheliaURL // ""' "$CONFIG_PATH" 2>/dev/null || echo "")
|
||||
AUTHELIA_USERNAME=$(sudo -u "$KIOSK_USER" jq -r '.autheliaUsername // ""' "$CONFIG_PATH" 2>/dev/null || echo "")
|
||||
AUTHELIA_ENCRYPTED_PASSWORD=$(sudo -u "$KIOSK_USER" jq -r '.autheliaEncryptedPassword // ""' "$CONFIG_PATH" 2>/dev/null || echo "")
|
||||
}
|
||||
|
||||
# Write every bash global back out to config.json, then offer to reload the
|
||||
@@ -159,7 +166,28 @@ save_config() {
|
||||
local boot_password_json="false"
|
||||
[[ "$REQUIRE_PASSWORD_ON_BOOT" == "true" ]] && boot_password_json="true"
|
||||
|
||||
jq -n \
|
||||
# Merge onto whatever's already in config.json rather than rebuilding
|
||||
# the file from nothing. The legacy save_config did a full `jq -n`
|
||||
# rebuild listing every known field - any field it doesn't know about
|
||||
# (e.g. Authelia's autheliaURL/autheliaUsername/
|
||||
# autheliaEncryptedPassword, written by its own careful `. + {...}`
|
||||
# merge) gets silently DELETED the next time any other menu that
|
||||
# calls save_config runs. Real, currently-shipping bug in the legacy
|
||||
# script, not unique to this migration - ported faithfully into this
|
||||
# file's first version because no test happened to set an untracked
|
||||
# field first. `. + {known fields...}` below preserves anything this
|
||||
# tool doesn't track while still fully replacing every field it does
|
||||
# (including tabs, via the same array-rebuild loop as before) - jq's
|
||||
# `+` on objects takes the right-hand value for any key present on
|
||||
# both sides, so a fully-specified `tabs` here still discards a
|
||||
# deleted tab rather than merging old and new.
|
||||
local existing="{}"
|
||||
if sudo -u "$KIOSK_USER" test -f "$CONFIG_PATH" 2>/dev/null; then
|
||||
existing=$(sudo -u "$KIOSK_USER" cat "$CONFIG_PATH" 2>/dev/null)
|
||||
echo "$existing" | jq empty 2>/dev/null || existing="{}"
|
||||
fi
|
||||
|
||||
echo "$existing" | jq \
|
||||
--argjson autoswitch true \
|
||||
--argjson enableTouch true \
|
||||
--argjson dualSwipe "$dual_json" \
|
||||
@@ -177,7 +205,10 @@ save_config() {
|
||||
--arg lockoutActiveStart "${LOCKOUT_ACTIVE_START:-}" \
|
||||
--arg lockoutActiveEnd "${LOCKOUT_ACTIVE_END:-}" \
|
||||
--argjson requirePasswordOnBoot "$boot_password_json" \
|
||||
'{autoswitch:$autoswitch,enableTouch:$enableTouch,dualSwipe:$dualSwipe,swipeMode:$swipeMode,allowNavigation:$allowNavigation,homeTabIndex:$homeTabIndex,inactivityTimeout:$inactivityTimeout,enablePauseButton:$enablePauseButton,enableKeyboardButton:$enableKeyboardButton,enableNavButton:$enableNavButton,enablePasswordProtection:$enablePasswordProtection,lockoutPassword:$lockoutPassword,lockoutTimeout:$lockoutTimeout,lockoutAtTime:$lockoutAtTime,lockoutActiveStart:$lockoutActiveStart,lockoutActiveEnd:$lockoutActiveEnd,requirePasswordOnBoot:$requirePasswordOnBoot,tabs:[]}' > "$tmp"
|
||||
--arg autheliaURL "${AUTHELIA_URL:-}" \
|
||||
--arg autheliaUsername "${AUTHELIA_USERNAME:-}" \
|
||||
--arg autheliaEncryptedPassword "${AUTHELIA_ENCRYPTED_PASSWORD:-}" \
|
||||
'. + {autoswitch:$autoswitch,enableTouch:$enableTouch,dualSwipe:$dualSwipe,swipeMode:$swipeMode,allowNavigation:$allowNavigation,homeTabIndex:$homeTabIndex,inactivityTimeout:$inactivityTimeout,enablePauseButton:$enablePauseButton,enableKeyboardButton:$enableKeyboardButton,enableNavButton:$enableNavButton,enablePasswordProtection:$enablePasswordProtection,lockoutPassword:$lockoutPassword,lockoutTimeout:$lockoutTimeout,lockoutAtTime:$lockoutAtTime,lockoutActiveStart:$lockoutActiveStart,lockoutActiveEnd:$lockoutActiveEnd,requirePasswordOnBoot:$requirePasswordOnBoot,autheliaURL:$autheliaURL,autheliaUsername:$autheliaUsername,autheliaEncryptedPassword:$autheliaEncryptedPassword,tabs:[]}' > "$tmp"
|
||||
|
||||
if [[ ${#URLS[@]} -gt 0 ]]; then
|
||||
for idx in "${!URLS[@]}"; do
|
||||
|
||||
@@ -0,0 +1,232 @@
|
||||
#!/bin/bash
|
||||
################################################################################
|
||||
# menus/addon_authelia.sh - "Authelia Auto-Login" addon.
|
||||
#
|
||||
# Stores encrypted Authelia SSO credentials so the kiosk authenticates
|
||||
# automatically on every startup. The password is AES-256-CBC encrypted
|
||||
# with a key derived from this machine's /etc/machine-id via scrypt -
|
||||
# the encrypted blob is useless on any other machine - and is NEVER
|
||||
# stored in plain text, matching the legacy addon exactly (same
|
||||
# algorithm, same salt, same node crypto calls).
|
||||
#
|
||||
# autheliaURL/autheliaUsername/autheliaEncryptedPassword are tracked
|
||||
# fields in lib/config.sh now (load_existing_config/save_config), same
|
||||
# as every other config.json field this tool manages - this is also
|
||||
# what motivated fixing save_config to merge onto the existing file
|
||||
# instead of rebuilding it from scratch (see lib/config.sh): the legacy
|
||||
# save_config had no idea these three fields existed, so configuring
|
||||
# Authelia and then visiting Sites/Touch/Navigation/Password Protection
|
||||
# in the legacy menu would silently wipe the credentials on the next
|
||||
# save. Real bug in the shipped script, not unique to this migration.
|
||||
#
|
||||
# Depends on: lib/menu.sh, lib/config.sh being sourced first.
|
||||
################################################################################
|
||||
|
||||
addon_authelia_status() {
|
||||
if [[ -n "$AUTHELIA_URL" ]]; then
|
||||
echo "Authelia: configured"
|
||||
echo " URL: $AUTHELIA_URL"
|
||||
echo " Username: $AUTHELIA_USERNAME"
|
||||
else
|
||||
echo "Authelia: not configured"
|
||||
fi
|
||||
}
|
||||
|
||||
addon_authelia_menu_builder() {
|
||||
if [[ -n "$AUTHELIA_URL" ]]; then
|
||||
MENU_LABELS=("Reconfigure (overwrite)" "Show server-side setup instructions again" "Clear Authelia configuration")
|
||||
MENU_HANDLERS=(action_configure_authelia action_show_authelia_server_setup action_clear_authelia)
|
||||
else
|
||||
MENU_LABELS=("Configure Authelia auto-login")
|
||||
MENU_HANDLERS=(action_configure_authelia)
|
||||
fi
|
||||
}
|
||||
|
||||
addon_authelia_menu() {
|
||||
load_existing_config
|
||||
|
||||
if ! sudo -u "$KIOSK_USER" test -f "$CONFIG_PATH" 2>/dev/null; then
|
||||
log_error "config.json not found at $CONFIG_PATH - run a full install first"
|
||||
pause
|
||||
return
|
||||
fi
|
||||
|
||||
run_menu "AUTHELIA AUTO-LOGIN" addon_authelia_menu_builder addon_authelia_status
|
||||
}
|
||||
|
||||
################################################################################
|
||||
# Encryption
|
||||
################################################################################
|
||||
|
||||
# Same algorithm as the legacy addon: AES-256-CBC, key derived from
|
||||
# /etc/machine-id via scrypt with a fixed salt, random IV prepended to
|
||||
# the ciphertext, everything base64-encoded. main.js decrypts with the
|
||||
# same derivation - do not change this without updating main.js too.
|
||||
encrypt_authelia_password() {
|
||||
local password="$1"
|
||||
command -v node &>/dev/null || return 1
|
||||
|
||||
node -e "
|
||||
const crypto=require('crypto'),fs=require('fs');
|
||||
const id=fs.readFileSync('/etc/machine-id','utf8').trim();
|
||||
const key=crypto.scryptSync(id,'kiosk-authelia-v1',32);
|
||||
const iv=crypto.randomBytes(16);
|
||||
const c=crypto.createCipheriv('aes-256-cbc',key,iv);
|
||||
const enc=Buffer.concat([c.update(process.argv[1],'utf8'),c.final()]);
|
||||
process.stdout.write(Buffer.concat([iv,enc]).toString('base64'));
|
||||
" "$password" 2>/dev/null
|
||||
}
|
||||
|
||||
################################################################################
|
||||
# Actions
|
||||
################################################################################
|
||||
|
||||
action_configure_authelia() {
|
||||
echo
|
||||
echo "Stores encrypted Authelia credentials so the kiosk"
|
||||
echo "authenticates automatically on every startup."
|
||||
echo "Password is encrypted with this machine's unique ID -"
|
||||
echo "the encrypted blob is useless on any other machine."
|
||||
echo
|
||||
|
||||
if [[ -n "$AUTHELIA_URL" ]]; then
|
||||
echo "Current config:"
|
||||
echo " URL: $AUTHELIA_URL"
|
||||
echo " Username: $AUTHELIA_USERNAME"
|
||||
echo
|
||||
ask_yes_no "Overwrite existing Authelia config?" "n" || { echo "Cancelled"; return; }
|
||||
echo
|
||||
fi
|
||||
|
||||
local url user pass
|
||||
read -r -p "Authelia URL (e.g. https://auth.yourdomain.com): " url
|
||||
[[ -z "$url" ]] && { echo "Cancelled"; return; }
|
||||
read -r -p "Authelia username: " user
|
||||
[[ -z "$user" ]] && { echo "Cancelled"; return; }
|
||||
read -r -s -p "Authelia password: " pass
|
||||
echo
|
||||
[[ -z "$pass" ]] && { echo "Cancelled"; return; }
|
||||
|
||||
echo "Encrypting with machine ID..."
|
||||
local encrypted
|
||||
encrypted=$(encrypt_authelia_password "$pass")
|
||||
if [[ -z "$encrypted" ]]; then
|
||||
log_error "Encryption failed - is Node.js installed?"
|
||||
return 1
|
||||
fi
|
||||
|
||||
AUTHELIA_URL="$url"
|
||||
AUTHELIA_USERNAME="$user"
|
||||
AUTHELIA_ENCRYPTED_PASSWORD="$encrypted"
|
||||
save_config
|
||||
|
||||
log_success "Authelia config saved (password encrypted, NOT stored in plain text)"
|
||||
action_show_authelia_server_setup
|
||||
|
||||
echo
|
||||
if is_service_active lightdm && ask_yes_no "Restart kiosk display now?" "n"; then
|
||||
sudo systemctl restart lightdm
|
||||
fi
|
||||
}
|
||||
|
||||
action_clear_authelia() {
|
||||
echo
|
||||
ask_yes_no "Clear Authelia configuration?" "n" || { echo "Cancelled"; return; }
|
||||
|
||||
AUTHELIA_URL=""
|
||||
AUTHELIA_USERNAME=""
|
||||
AUTHELIA_ENCRYPTED_PASSWORD=""
|
||||
save_config
|
||||
log_success "Authelia configuration cleared"
|
||||
}
|
||||
|
||||
action_show_authelia_server_setup() {
|
||||
echo
|
||||
echo "════════════════════════════════════════════════════════════"
|
||||
echo " AUTHELIA SERVER-SIDE SETUP (Dockerized)"
|
||||
echo "════════════════════════════════════════════════════════════"
|
||||
echo
|
||||
echo "1. Generate the argon2 password hash on your Docker host:"
|
||||
echo
|
||||
echo " docker run --rm authelia/authelia:latest \\"
|
||||
echo " authelia crypto hash generate argon2 \\"
|
||||
echo " --password 'yourpassword'"
|
||||
echo
|
||||
echo " Copy the \$argon2id\$... output — that is your hash."
|
||||
echo
|
||||
echo "2. ADD a kiosk user to ~/docker/authelia/config/users.yml"
|
||||
echo " (append — do not replace existing users):"
|
||||
echo
|
||||
echo " kiosk:"
|
||||
echo " displayname: \"Kiosk Display\""
|
||||
echo " password: '\$argon2id\$v=19\$m=65536,t=3,p=4\$<paste hash here>'"
|
||||
echo " email: kiosk@local.com"
|
||||
echo " groups:"
|
||||
echo " - kiosk"
|
||||
echo
|
||||
echo "3. MERGE into ~/docker/authelia/config/configuration.yml:"
|
||||
echo
|
||||
echo " ── access_control ─────────────────────────────────────"
|
||||
echo " Find your EXISTING access_control block and add the"
|
||||
echo " kiosk rule as the FIRST rule inside it."
|
||||
echo
|
||||
echo " !! DO NOT create a second access_control: block !!"
|
||||
echo " YAML silently ignores duplicate keys — the kiosk rule"
|
||||
echo " will be invisible to Authelia and you will get a white"
|
||||
echo " screen on the kiosk."
|
||||
echo
|
||||
echo " Authelia reads rules top-down, first match wins."
|
||||
echo " The kiosk rule MUST be above any two_factor rule or"
|
||||
echo " the two_factor wildcard will match first."
|
||||
echo
|
||||
echo " ── EXAMPLE — before (your existing config): ──────────"
|
||||
echo " access_control:"
|
||||
echo " default_policy: deny"
|
||||
echo " rules:"
|
||||
echo " - domain: '*.yourdomain.com'"
|
||||
echo " policy: two_factor"
|
||||
echo
|
||||
echo " ── EXAMPLE — after (add kiosk rule above two_factor): ─"
|
||||
echo " access_control:"
|
||||
echo " default_policy: deny"
|
||||
echo " rules:"
|
||||
echo " - domain: '*.yourdomain.com' # <-- kiosk first"
|
||||
echo " subject: 'group:kiosk'"
|
||||
echo " policy: one_factor"
|
||||
echo " - domain: '*.yourdomain.com' # <-- existing"
|
||||
echo " policy: two_factor"
|
||||
echo
|
||||
echo " Why one_factor? The kiosk authenticates via the API"
|
||||
echo " (/api/firstfactor — password only). TOTP and WebAuthn"
|
||||
echo " require a second interactive step that is impossible"
|
||||
echo " from a script, so the kiosk group must use one_factor."
|
||||
echo
|
||||
echo " ── session ─────────────────────────────────────────────"
|
||||
echo " Keep your existing session block — no changes needed."
|
||||
echo " The kiosk re-authenticates via API on every startup so"
|
||||
echo " session expiry barely matters for it."
|
||||
echo
|
||||
echo " If you do NOT yet have a session block, add:"
|
||||
echo
|
||||
echo " session:"
|
||||
echo " expiration: 8h"
|
||||
echo " inactivity: 1h"
|
||||
echo " remember_me: 7d"
|
||||
echo " cookies:"
|
||||
echo " - domain: yourdomain.com"
|
||||
echo " authelia_url: https://auth.yourdomain.com"
|
||||
echo
|
||||
echo "4. Restart Authelia on your Docker host:"
|
||||
echo " docker compose restart authelia"
|
||||
echo
|
||||
echo "────────────────────────────────────────────────────────────"
|
||||
echo " NOTE: HTTP Basic Auth (per-site username/password) still"
|
||||
echo " works alongside Authelia for sites that use browser-popup"
|
||||
echo " authentication rather than Authelia SSO."
|
||||
echo "────────────────────────────────────────────────────────────"
|
||||
echo
|
||||
echo " To clear Authelia config later, use this menu's"
|
||||
echo " 'Clear Authelia configuration' option."
|
||||
echo
|
||||
pause
|
||||
}
|
||||
+37
-2
@@ -1,8 +1,43 @@
|
||||
#!/bin/bash
|
||||
################################################################################
|
||||
### Ubuntu Based Kiosk v2.5.0 ###
|
||||
### Ubuntu Based Kiosk v2.6.0 ###
|
||||
################################################################################
|
||||
#
|
||||
# RELEASE v2.6.0 - Authelia Migrated; Real Config-Clobbering Bug Fixed
|
||||
# - New in ./install.sh: Authelia Auto-Login (menus/addon_authelia.sh) -
|
||||
# encrypted SSO credentials (AES-256-CBC, key derived from this
|
||||
# machine's /etc/machine-id via scrypt - same algorithm main.js
|
||||
# decrypts with, verified by test with a real round-trip encrypt/
|
||||
# decrypt, not just "some string came out"), plus the full Dockerized
|
||||
# server-side setup instructions, viewable again later without
|
||||
# reconfiguring.
|
||||
# - IMPORTANT bug found and fixed in lib/config.sh, NOT specific to
|
||||
# Authelia or to this migration: save_config() did a full `jq -n`
|
||||
# rebuild of config.json from known fields, exactly like the legacy
|
||||
# script's save_config still does. Authelia's own write is a careful
|
||||
# `. + {...}` merge that preserves everything - but the legacy
|
||||
# configure_authelia() writes autheliaURL/autheliaUsername/
|
||||
# autheliaEncryptedPassword into config.json via that merge, and
|
||||
# *neither* the legacy save_config nor this project's own (before this
|
||||
# fix) had any idea those three fields existed. The next time a user
|
||||
# visited Sites, Touch Controls, Navigation, or Password Protection -
|
||||
# all of which call save_config - their Authelia credentials were
|
||||
# silently deleted. This is a real bug in the currently-shipping
|
||||
# single-file installer, not introduced by this migration; ported
|
||||
# faithfully into lib/config.sh's first version because no test
|
||||
# happened to set an untracked field before calling save_config.
|
||||
# Fixed here by changing save_config to merge its known fields onto
|
||||
# whatever's already in config.json (jq `. + {...}`) instead of
|
||||
# rebuilding the file from nothing, so any field this tool doesn't
|
||||
# track - Authelia's three today, anything else tomorrow - survives
|
||||
# automatically. autheliaURL/autheliaUsername/autheliaEncryptedPassword
|
||||
# are also now tracked fields in their own right, same as every other
|
||||
# config.json field this tool manages. NOTE: the equivalent bug still
|
||||
# exists in this script's own save_config below, unfixed - see
|
||||
# Readme.md ("Modular Management") for the open question of whether to
|
||||
# backport this specific fix here independent of the wider migration,
|
||||
# given it's a real, currently-shipping credential-loss bug.
|
||||
#
|
||||
# RELEASE v2.5.0 - First Addon Migrated (CUPS), Menu Restructured
|
||||
# - New in ./install.sh: CUPS Printing (menus/addon_cups.sh) - the first
|
||||
# Addon migrated. Install/reconfigure/complete uninstall (purge),
|
||||
@@ -226,7 +261,7 @@ set -euo pipefail
|
||||
### SECTION 1: CONSTANTS & GLOBALS
|
||||
################################################################################
|
||||
|
||||
SCRIPT_VERSION="2.5.0"
|
||||
SCRIPT_VERSION="2.6.0"
|
||||
|
||||
# Resolve the real path to this script file.
|
||||
# When piped (curl|bash or wget|bash), BASH_SOURCE[0] is a pipe descriptor,
|
||||
|
||||
Reference in New Issue
Block a user