Implements the Auth Layer section of spec 002 (22 tasks). Adds `auth.go` with API key validation, root login, OTP claim, and bearer token extraction. All functions are testable independently of HTTP. Co-authored-by: exe.dev user <exedev@kiosk.exe.xyz> Reviewed-on: kwila/kiosk#28 Co-authored-by: exe-dev-bot <dev-bot@kwila.cloud> Co-committed-by: exe-dev-bot <dev-bot@kwila.cloud> |
||
|---|---|---|
| .agents/skills | ||
| .forgejo/workflows | ||
| cmd/kiosk-deploy | ||
| deploy | ||
| specs | ||
| static | ||
| testdata | ||
| .gitignore | ||
| AGENTS.md | ||
| auth.go | ||
| auth_test.go | ||
| calendar.go | ||
| calendar_test.go | ||
| db.go | ||
| go.mod | ||
| go.sum | ||
| handlers.go | ||
| handlers_test.go | ||
| justfile | ||
| main.go | ||
| migrations.go | ||
| migrations_test.go | ||
| README.md | ||
| scheduler.go | ||
| scheduler_test.go | ||
| seed_test.go | ||
| updater.go | ||
| updater_test.go | ||
Kiosk
A Go web server that aggregates ICS calendar feeds and displays them on a full-screen monthly calendar. Designed for wall-mounted Raspberry Pi displays running in Chromium kiosk mode.
Features
- Aggregates multiple ICS calendar feeds (Google Calendar, FamCal, Proton Calendar, etc.)
- Dark-themed monthly calendar grid optimized for 1920x1080 displays
- Auto-rotates between current and next month every 30 seconds
- Background feed refresh every 15 minutes
- Web-based admin UI for managing feeds - no SSH or config files needed
- Single binary with embedded static assets and SQLite storage
- One-command SD card setup for Raspberry Pi via interactive TUI
Quick Start
Build and run locally:
just dev
# or
go build -o kiosk . && ./kiosk -port 8000
- Admin UI: http://localhost:8000/ - add and manage calendar feeds
- Kiosk display: http://localhost:8000/kiosk - the full-screen calendar view
Deploy to Raspberry Pi
Prerequisites
- Raspberry Pi 3 or 4 (ARM64)
- MicroSD card (8 GB+)
- WiFi network
- Linux host with Go installed (ext4 mounting required - macOS is not supported)
Deploy
The deploy command flashes a ready-to-boot kiosk image onto an SD card:
just deploy
The TUI walks you through four steps:
- SD Card - select from auto-detected removable drives
- WiFi SSID - your network name
- WiFi Password - your network password
- Timezone - searchable list (e.g.
America/New_York)
Review the summary, press Enter, and the tool downloads the DietPi image, flashes it, downloads the latest ARM64 kiosk binary from Forgejo releases, and writes all config files and the binary to the card.
Save your password!
The deploy generates a random root password and displays it once on the success screen. This is the only way to SSH into the Pi. Copy it to your password manager immediately. If you lose it, you'll need to re-flash the SD card.
What Gets Configured
The deploy writes a DietPi image with:
- Automated first-boot setup (no monitor/keyboard needed)
- WiFi credentials and timezone
- Chromium installed in kiosk mode (fullscreen, no cursor, no screensaver)
- Kiosk binary installed at
/opt/kiosk/kioskwith a systemd service - Chromium auto-starts pointing to
http://localhost/kiosk
After deployment:
| Access | Address |
|---|---|
| SSH | ssh root@<pi-ip> with the generated password |
| Admin UI | http://<pi-ip>/ from any device on the network |
| Kiosk display | Auto-starts on the Pi's connected monitor |
After First Boot
- Insert the SD card and power on the Pi.
- Wait 10–15 minutes — DietPi runs automated setup and installs software.
- The Pi reboots into the kiosk display.
- From another device on the network, open the admin UI (
http://<pi-ip>/) and add your calendar feeds.
Feeds refresh automatically every 15 minutes. The kiosk display auto-rotates between the current and next month every 30 seconds.
Configuration Details
Systemd service — The kiosk runs as a systemd service at /etc/systemd/system/kiosk.service. It starts after networking, listens on port 80, and restarts automatically on crash (5-second delay). Working directory is /opt/kiosk/.
Database — Feed configuration is stored in SQLite at /opt/kiosk/kiosk.db, created on first run. Re-flashing the card erases it — you'll need to re-add feeds.
WiFi — The deploy writes WPA2-PSK credentials to dietpi-wifi.txt. Enterprise WiFi (EAP/802.1X) is not supported by the TUI. For enterprise networks, flash normally then edit /boot/dietpi-wifi.txt before first boot.
Image cache — The DietPi image is cached at ~/.cache/dietpi/ on the deploy host. Delete this directory to force a fresh download.
Updating Without Re-flashing
CGO_ENABLED=0 GOOS=linux GOARCH=arm64 go build -o kiosk-arm64 .
scp kiosk-arm64 root@<pi-ip>:/opt/kiosk/kiosk
ssh root@<pi-ip> systemctl restart kiosk
This preserves your database and feed configuration.
Troubleshooting
Pi Won't Boot
- No activity lights: Check power supply. Pi 4 requires USB-C delivering at least 3A.
- Rainbow screen / repeated reboots: SD card image may be corrupted. Re-flash with
sudo ./kiosk-deploy. - Red light only, no green flashing: Pi can't read the SD card. Try a different card or re-seat it.
WiFi Not Connecting
- SSID is case-sensitive —
MyNetwork≠mynetwork. Re-flash if wrong. - WiFi country code defaults to
US. For other countries, SSH in via Ethernet and edit/boot/dietpi-wifi.txt. - Pi 3 only supports 2.4 GHz. Pi 4 supports both bands.
- Hidden networks are not supported.
- Diagnose: Connect Ethernet, SSH in, check
journalctl -u networkingoriwconfig.
Black Screen After Boot
- Wait the full 10–15 minutes. First boot installs packages before Chromium starts.
- If still black after 20+ minutes, SSH in and check:
systemctl status kiosk cat /boot/dietpi.txt | grep AUTOSTART # Should show: AUTO_SETUP_AUTOSTART_TARGET_INDEX=11
Kiosk Service Not Running
systemctl status kiosk # Check status
journalctl -u kiosk -f # View logs (live)
systemctl restart kiosk # Restart
ls -la /opt/kiosk/kiosk # Verify binary exists
- "exec format error": Wrong architecture. Re-flash — the deploy tool downloads the correct ARM64 binary.
- Feeds not loading: Check
journalctl -u kioskfor HTTP errors. The Pi needs internet access to fetch ICS feeds.
No Releases Found / Download Fails
- Check internet connectivity on the deploy host.
- Ensure a Forgejo release exists with a
kiosk-arm64asset attached. - If behind a proxy, ensure
https://git.kwila.cloudis reachable.
Screen Blanking / Display Turns Off
DietPi kiosk mode disables screen blanking by default. If it still turns off:
DISPLAY=:0 xset s off && DISPLAY=:0 xset -dpms && DISPLAY=:0 xset s noblank
To persist, add those commands to /var/lib/dietpi/dietpi-autostart/custom.sh.
SSH Access
ssh root@<pi-ip> # or ssh root@DietPi-Kiosk if mDNS works
Uses Dropbear (DietPi default). Password is the one shown during deploy.
Useful Logs
journalctl -u kiosk -n 50 # Kiosk server
cat /var/tmp/dietpi/logs/dietpi-firstrun-setup.log # First-boot setup
journalctl -b # System boot
Lost Root Password
The password cannot be recovered. Re-flash the SD card with sudo ./kiosk-deploy.
Build
just build # Build web server for current platform
just deploy # Build and run the deploy TUI (requires sudo)
just test # Run tests
just clean # Remove build artifacts
To Do
- Add items here