build-container / build (push) Successful in 2m20s
- Accounts: the setup code (or an existing single-user install, migrated automatically) creates the admin; the admin adds people in Settings -> People and gives each a one-time invite code to enrol their own passkey - Each person's tasks, NE Hub events and subscribe link, settings, calendar links, iCloud connection and Plex sign-in are private, stored in their own folder (/data/users/<id>/); Plex sign-in moved from browser cookies into that folder (encrypted), so it also follows them across devices - Tab access is enforced by the server (403) and reflected in the app (nav, Home, Settings, search, /api/config hides addresses of tabs a person cannot use); browser storage is namespaced per person - Admin tools: change tabs, invite a device, sign out everywhere (session epoch), turn off, make/remove admin, delete a person and their data; the last admin cannot be removed - Sessions carry the person (uid.epoch.expiry.signature); old single-user cookies still work as the admin - tools/users-test.js (83 checks: isolation, access limits, invites, sign-out/disable/delete, Plex and iCloud per person, migration) now runs in the Gitea workflow before the image is built Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
71 lines
5.6 KiB
Markdown
71 lines
5.6 KiB
Markdown
# NE Hub
|
|
|
|
One installable web app (PWA) for Seafile, OnlyOffice and your four webmail accounts.
|
|
Mobile-first; bottom tabs on phones, side rail on iPad and desktop (tuned for 12.9" at 1024 and 1366 wide).
|
|
|
|
## Configure
|
|
|
|
cp .env.example .env # set ONLYOFFICE_JWT_SECRET (same value as the Document Server) and PUBLIC_URL
|
|
|
|
`PUBLIC_URL` must be an address the OnlyOffice server can reach (not localhost): it posts saved edits back there.
|
|
|
|
## Run
|
|
|
|
docker compose up -d --build # http://localhost:8080
|
|
# or: node server.js
|
|
|
|
Put it behind your reverse proxy with HTTPS (needed for "Add to Home Screen" and the service worker),
|
|
e.g. hub.necloud.us. Settings: `SEAFILE_URL`, `ONLYOFFICE_URL` env vars in docker-compose.yml.
|
|
|
|
## What each part does
|
|
|
|
- **Files**: signs in with your Seafile account, browses libraries, uploads, creates folders, downloads, deletes.
|
|
The server proxies `/sf/*` to Seafile because Seafile sends no CORS headers. Token lives in the browser only.
|
|
Office files open in Seafile's own OnlyOffice integration.
|
|
- **Edit here**: opens docs inside the app via OnlyOffice. The server signs each editor config with the JWT secret and saves edits back to Seafile.
|
|
- **Sign-in**: the whole app sits behind a passkey (WebAuthn). First run: open the site and enter the setup code (`HUB_SETUP_CODE`, or the one printed in the server log) to create a passkey; add more devices from Settings. Passkeys and the session secret live in `/data` (a Docker volume).
|
|
- **People**: you (the admin) add people in Settings -> People, choose which tabs each may use (Files, Office, Music, Audio, Podcast, Podcast Admin, Mail,
|
|
Calendar, Tasks, Search; Home and Settings are always on), and give them a one-time invite code to create their own passkey. Everyone's tasks, NE Hub events,
|
|
settings, iCloud connection, calendar links and Plex sign-in are private to them (`/data/users/<id>/`). Limits are enforced by the server, not just hidden.
|
|
You can change a person's tabs, sign them out everywhere, turn them off, or delete them and their data. An existing single-user install becomes the admin
|
|
automatically on first start (the original files are left in place as a backup).
|
|
- **Files**: also rename, move, share links, image/PDF/video/audio preview, and New document/spreadsheet/presentation.
|
|
- **Calendar**: month grid and agenda. Add, edit and delete events:
|
|
- **NE Hub calendar**: events you create are stored in `/data/events.json` and published as a private subscribe link
|
|
(Manage calendars -> copy link) so Outlook, Google or Apple Calendar can show them (read-only there).
|
|
- **iCloud (two-way)**: connect with an Apple ID and an *app-specific password* (appleid.apple.com). Credentials are
|
|
encrypted in `/data/icloud.json`; only `*.icloud.com` is contacted. Edits keep alarms and attendees intact.
|
|
- **ICS links** (Google secret address, Outlook/M365 published calendar) are read-only.
|
|
- **Tasks**: to-do lists stored in NE Hub (`/data/tasks.json`), with due dates, notes and completion. If the connected iCloud
|
|
account exposes reminder lists over CalDAV they appear too and sync both ways. Apple hides Reminders lists that were upgraded
|
|
for iOS 13+, so for most accounts only NE Hub lists are available.
|
|
- **Settings sync**: your preferences (mail addresses, audiobooks sign-in (encrypted), Plex library, Office save location, calendar/task views, recent files) are saved on the server in `/data/settings.json` and shared by every device. Per-device items (Seafile sign-in token, music queue) stay in the browser.
|
|
- **Search**: libraries, file names (scans libraries if Seafile has no search index) and Plex artists/albums/tracks.
|
|
- **Music**: Plex player. Sign in goes through plex.tv (no password handled), the server proxies your Plex server and adds the token itself, and a mini player keeps playing as you move between tabs; the queue (play next / add to queue) and position are remembered.
|
|
- **Audio**: embeds audiobooks.necloud.us; sign-in details saved in Settings can be copied with one tap.
|
|
- **Podcast** and **Podcast Admin**: launchers that open `PODCAST_URL` (a home-network address) and `VERSE_URL` in their own tabs.
|
|
- **Office**: embeds onlyoffice.necloud.us in a frame, with an "open in new tab" fallback if it blocks framing.
|
|
- **Mail**: deep links to Gmail, Outlook.com, Microsoft 365 and iCloud webmail (inbox + compose).
|
|
Providers forbid framing, and a real unified inbox would need Google/Azure app registrations.
|
|
|
|
## Install on iPhone / iPad (PWA)
|
|
|
|
Open the site in **Safari** (it must be the `https://` address), tap **Share -> Add to Home Screen**. The home-screen app has proper
|
|
icons (iPhone, iPad), a splash screen for each iPhone and iPad size (including iPad Pro 12.9"), and opens full screen without Safari's bars.
|
|
iOS keeps a separate sign-in for the home-screen app, so sign in once inside it with your passkey; it then stays signed in
|
|
(`SESSION_DAYS`, default 180, renewed whenever you use it). Regenerate the artwork with `python3 tools/make-icons.py` (needs Pillow).
|
|
|
|
## Build and deploy with Gitea
|
|
|
|
`.gitea/workflows/build.yml` builds the container on every push to `main` (and `v*` tags) and pushes it to
|
|
`git.necloud.us/nate/hub` (tags: `latest`, short commit sha, git tag). amd64 (x86) only.
|
|
|
|
One-time setup in Gitea: create an access token with the **write:package** scope, then add it to the repo under
|
|
Settings -> Actions -> Secrets as `REGISTRY_TOKEN` (optionally `REGISTRY_USER`). The runner needs Docker.
|
|
|
|
On the server:
|
|
|
|
cp .env.example .env # fill in secrets, PUBLIC_URL, etc.
|
|
docker compose pull && docker compose up -d
|
|
docker compose logs hub | grep "Setup code" # first sign-in: create your passkey
|