feat(hobbs-organizer): v1.1.0 password-protected LAN-only admin for calendar links
- /admin: first-visit password setup (scrypt), signed 30-day session cookie, calendars add/remove/reorder/rename/color/hide, masked URLs, per-feed test, history (20) with restore; /photo-admin -> /admin#photos placeholder - settings in local /data (settings.json + auth.json + history/), seeded once from the calendar secret; dashboard + health read from settings - start.mjs drops privileges after reading secrets and runs a front proxy that stamps the real client IP; admin refuses non-LAN and proxied requests - deploy: HOBBS_DATA_DIR=/var/lib/hobbs-organizer/data, image 1.1.0 (1.0.0 kept) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01E9NnVEico3WvFxLyjy1iW3
This commit is contained in:
@@ -103,6 +103,30 @@ Authorization: Bearer TOKEN
|
||||
|
||||
The Shield wrapper injects this header into every same-origin request. An ordinary browser address bar cannot add it, so browser access in bearer mode should go through an authenticated reverse proxy that injects the header. The configuration scripts intentionally do not print the token.
|
||||
|
||||
## Admin screen (v1.1.0)
|
||||
|
||||
Open `http://SERVER-IP:8080/admin` from a phone or laptop on the home network.
|
||||
|
||||
- **First visit:** choose the admin password. This works only while no password exists, and only from an allowed network.
|
||||
- **Calendars tab:** add, remove, reorder, rename, recolor or hide calendars.
|
||||
- Saved addresses are masked and never shown again.
|
||||
- **Test** fetches a feed and reports its name and how many events are upcoming.
|
||||
- Every save keeps the previous version. **History → Restore** brings any of the last 20 back.
|
||||
- **Account tab:** change the password (this signs out other devices) or sign out.
|
||||
- **Forgot the password:** `docker exec -u 10001 <container> node container/reset-admin.mjs`, then visit `/admin` again.
|
||||
|
||||
Settings live in the `/data` volume (`HOBBS_DATA_DIR`, default `./data`). It must be writable by uid 10001 and should be on local disk.
|
||||
|
||||
| File | Contents |
|
||||
| --- | --- |
|
||||
| `settings.json` | Calendars, including their private URLs. Treat it like a secret. |
|
||||
| `auth.json` | The scrypt password hash and the session key. |
|
||||
| `history/` | The last 20 saved versions. |
|
||||
|
||||
The `calendar_ical_urls` secret is now optional. It is used only to seed `settings.json` on first start.
|
||||
|
||||
Admin is refused unless the TCP client address is inside `ADMIN_ALLOWED_CIDRS`. It is also refused, with a 404, for any request carrying `X-Forwarded-For`, `Forwarded` or `X-Real-IP`, so it cannot be reached through a reverse proxy. The container's own front proxy (port 3000, with Next.js on 127.0.0.1:3001) records the real client address, and forged copies of that header are discarded.
|
||||
|
||||
## Configuration
|
||||
|
||||
Edit `.env` for nonsecret settings:
|
||||
|
||||
Reference in New Issue
Block a user