Commit Graph
10 Commits
Author SHA1 Message Date
ort aa21709f3d Add PWA meta tags to login/signup/join pages
iOS decides whether "Add to Home Screen" creates a true standalone app
(no browser chrome) or a plain bookmark-style Web Clip (full Safari UI --
URL bar, share/reload/compass row, X to close) based on whatever page you
were on when you tapped it. Those tags only existed on dashboard.html and
calendar.html, so anyone adding the icon while logged out -- the normal
first-time flow, since you land on /login.html before signing in -- got
the bookmark-style icon instead of a real standalone app, exactly as
reported. Existing home-screen icons need to be deleted and re-added
after this deploys; iOS bakes in standalone-capability at creation time
and won't retroactively upgrade an icon that already exists.
2026-08-15 16:43:08 -04:00
ort 722a98c249 Trust the reverse proxy so secure cookies actually get set
With COOKIE_SECURE=true behind a TLS-terminating reverse proxy, Express
only ever sees the proxy's plain-HTTP connection to the container, so
req.secure was always false from its perspective. express-session
silently refused to set a `secure` cookie on a connection it believed was
insecure -- login would succeed (200, parent data returned) but no
Set-Cookie ever reached the browser, so the very next request came back
401 and bounced to the login screen. Looked like "logs in, then
immediately signs back out" -- reproduced on both Mac Chrome and iPhone
once COOKIE_SECURE was turned on for push notifications.

app.set('trust proxy', 1) when COOKIE_SECURE is true makes Express read
X-Forwarded-Proto from the proxy, so it correctly sees the connection as
secure. Tied to COOKIE_SECURE rather than a new flag since it's the same
"yes, I'm behind an HTTPS-terminating proxy" fact either way. Verified: no
Set-Cookie without the header (correct -- a request that didn't actually
come through the proxy shouldn't get one), Set-Cookie with Secure/SameSite
correctly present given X-Forwarded-Proto: https, and a full
login-then-auth-check cycle staying authenticated.
2026-08-15 16:35:56 -04:00
ort fdba8c0d1f Don't let a malformed VAPID_SUBJECT crash the whole app
setVapidDetails() throws synchronously on an invalid subject (e.g. missing
the mailto:/https: prefix — an easy mistake). It ran unguarded at module
load, so a bad value took down the entire server, not just push. Wrapped
in try/catch; push now degrades the same way as when it's unconfigured,
and /api/push/vapid-public-key reflects actual readiness (post-validation)
instead of just whether the env vars were present.
2026-08-15 16:18:07 -04:00
ort 2826a3819c Add Web Push notifications, PWA support, and full-screen tablet kiosk
Parents get a real push notification when a kid checks off a task
(false->true transitions only, fire-and-forget, degrades gracefully with
no VAPID keys configured). Dashboard is a fully installable iOS/Android
PWA; each child's kiosk link gets its own dynamic per-token manifest so
"Add to Home Screen" opens straight into their board in standalone mode.

Kiosk view is reworked for tablets: safe-area-aware full-bleed layout,
the whole task row is now tappable (previously only the 24px checkbox
was, well under Apple's touch-target minimum), and app icons are
generated by a small dependency-free PNG encoder (no image tooling
available in this environment).

Push requires real HTTPS (iOS Safari won't allow it otherwise) - README
and UNRAID.md cover VAPID setup and the HTTPS prerequisite.
2026-08-15 16:14:56 -04:00
ort 56d8c4616c Redirect / to /dashboard.html
Visiting the bare root path returned Express's default "Cannot GET /"
since there was no route or index.html for it. dashboard.js already
bounces to /login.html when the session check fails, so this one
redirect covers both logged-in and logged-out visitors.
2026-08-15 14:55:06 -04:00
ort 9021a7839d Build Unraid image directly from the Gitea repo
docker-compose.unraid.yml now uses a Git URL as the build context
(https://git.oservr.com/ort/KCal.git#main) instead of requiring a manual
clone onto the array — Docker/BuildKit fetches the source itself at build
time. Requires the repo to allow anonymous HTTP read access in Gitea
(Settings -> Visibility -> Public); this is a read-only clone, nothing
more. Verified with a real docker build/compose run against the public
repo, not just syntax-checked.

UNRAID.md rewritten to match: no deploy key, no NerdTools/git, no source
checkout needed. Kept a token-auth alternative documented for anyone who'd
rather keep the repo private.
2026-08-15 14:50:00 -04:00
ort 5c2fde0c86 Add Unraid deployment setup
docker-compose.unraid.yml bind-mounts data to /mnt/user/appdata/kids-calendar
instead of a named volume, matching Unraid's appdata convention so backup
plugins pick it up. UNRAID.md covers getting the code onto the array,
running via Compose Manager or terminal, reverse-proxy/HTTPS notes, and
updating. Linked from README.
2026-08-15 13:54:28 -04:00
ort 73a1d58838 Add takeover.md
Project overview, current status, architecture summary, and the
commit/push workflow for the Gitea remote (deploy key location,
GIT_SSH_COMMAND usage).
2026-08-15 13:48:01 -04:00
ort 21baeadeff Ignore GitOServr/ and .DS_Store
GitOServr/ holds the deploy SSH keypair for git.oservr.com — must never
be committed.
2026-08-15 13:48:01 -04:00
ort 66b8fc5d4d Add self-hosted kids calendar app
Express + SQLite (node:sqlite, no native build step) family calendar:
parent accounts with household invites, per-child calendars with
save/duplicate/print, a token-gated read-only kiosk view for tablets,
and polling to keep parent and kiosk views in sync. Defaults to port 3007.
2026-08-15 13:48:01 -04:00