multi-tenant relay und card-push to user
This commit is contained in:
1 parent
7219bae655
commit
5b18c46ac2
22 files changed
+7453
-519
No files matched your search
@@ -342,30 +342,37 @@ When running multiple hyprcrd instances that share CalDAV credentials, you need
|
||||
|
||||
## Relay
|
||||
|
||||
A minimal web service for mobile note capture and card sharing between hyprcrd instances.
|
||||
A self-hosted **multi-tenant** message relay for hyprcrd. Multiple users
|
||||
share one relay instance — each one has their own login, their own
|
||||
client encryption secret, and their own inbox. Cards (and in the future:
|
||||
encrypted chat messages) can be sent **between tenants** on the same
|
||||
relay.
|
||||
|
||||
**Full documentation:** [`relay/README.md`](relay/README.md)
|
||||
|
||||
### Architecture
|
||||
|
||||
```
|
||||
[Phone/Browser] → https://relay.example.com → [Relay Service]
|
||||
↓ poll
|
||||
[hyprcrd (local)]
|
||||
[hyprcrd alice] ──push──┐ ┌──poll── [hyprcrd alice]
|
||||
├──► [Relay] ◄────────────┤
|
||||
[hyprcrd bob] ──push──┘ tenants: alice, bob └──poll── [hyprcrd bob]
|
||||
|
||||
[hyprcrd A] → push card → [Relay] ← poll ← [hyprcrd B]
|
||||
sender encrypts → relay decrypts with sender's secret →
|
||||
re-encrypts with shared inter-tenant key → stores →
|
||||
on recipient poll: decrypts → re-encrypts with recipient's secret
|
||||
```
|
||||
|
||||
### Deploy to Webspace
|
||||
### Deploy
|
||||
|
||||
**Webspace** (any PHP host with `mod_rewrite` and `pdo_sqlite`):
|
||||
|
||||
```bash
|
||||
cd relay
|
||||
./dist.sh
|
||||
# upload hyprcrd-relay.zip and extract into your webspace
|
||||
```
|
||||
|
||||
Upload the resulting `hyprcrd-relay.zip` to your webspace and extract it. The SQLite database is created automatically on first request. Open the URL and set a password + shared secret.
|
||||
|
||||
Requirements: PHP 8.3+ with `pdo_sqlite`, Apache with `mod_rewrite`.
|
||||
|
||||
### Deploy with Docker
|
||||
**Docker**:
|
||||
|
||||
```bash
|
||||
cd relay
|
||||
@@ -373,42 +380,76 @@ docker build -t hyprcrd-relay .
|
||||
docker run -d -p 8081:80 -v relay-data:/var/www/html/data hyprcrd-relay
|
||||
```
|
||||
|
||||
The `data/` directory is created on first request and contains the
|
||||
SQLite DB plus the master encryption key (chmod 600, blocked from web
|
||||
access via `.htaccess`).
|
||||
|
||||
### Development (both together)
|
||||
|
||||
```bash
|
||||
./dev.sh
|
||||
```
|
||||
|
||||
Starts hyprcrd on `http://localhost:8088` and the relay on `http://localhost:8081` in the same Docker network. Source files are bind-mounted — changes are live without rebuilding.
|
||||
Starts hyprcrd on `http://localhost:8088` and the relay on `http://localhost:8081` in the same Docker network. Source files are bind-mounted — changes are live without rebuilding. From inside the hyprcrd container, the relay is reachable at `http://relay:80`.
|
||||
|
||||
From inside the hyprcrd container, the relay is reachable at `http://relay:80`.
|
||||
### Setup workflow
|
||||
|
||||
### Setup
|
||||
1. Open the relay URL **from a desktop browser** — the setup wizard
|
||||
is desktop-friendly
|
||||
2. Create the first **admin** account: username + password (UI login)
|
||||
+ shared secret (client encryption)
|
||||
3. As admin, click the **users** tab and create accounts for any
|
||||
additional users you want to give relay access to
|
||||
4. Each user enters their credentials in their own hyprcrd:
|
||||
**Settings → Relay** → relay URL + username + shared secret
|
||||
5. To send a card from one tenant to another, use the relay UI's
|
||||
compose form (recipient picker) — or push cards from hyprcrd
|
||||
|
||||
1. Open the relay URL, set a **password** (for UI login) and a **shared secret** (for encryption)
|
||||
2. In hyprcrd: **Settings > Relay** — enter the relay URL and the same shared secret
|
||||
3. Click **save**
|
||||
### How it works (high level)
|
||||
|
||||
### How it works
|
||||
|
||||
- **Mobile inbox**: type a note on the relay UI, it arrives as a card with `#inbox` tag
|
||||
- **Push to relay**: right-click any card → "push to relay" — other instances pick it up on next poll
|
||||
- Messages are encrypted client-side (AES-256-CBC) before sending to the relay
|
||||
- The relay only stores ciphertext — it cannot read your messages
|
||||
- hyprcrd polls the relay every 45 seconds in the background
|
||||
- Messages are kept on the relay for 24 hours, then auto-deleted
|
||||
- Cards pushed from the same instance are not re-imported
|
||||
- Enter to send, Shift+Enter for newline
|
||||
- **Per-tenant inboxes**: each user only sees their own messages
|
||||
- **Cross-tenant routing**: send a card to another tenant on the same
|
||||
relay; the relay decrypts with the sender's secret, re-encrypts with
|
||||
a shared inter-tenant key for storage, then re-encrypts with the
|
||||
recipient's secret on delivery
|
||||
- **At-rest encryption**: every sensitive value in the DB (tenant
|
||||
secrets, the inter-tenant key, message bodies) is encrypted. The
|
||||
master key lives outside the DB in a chmod-600 file
|
||||
- **24-hour ephemeral**: messages and attachments auto-delete after a
|
||||
day. Cards extracted in hyprcrd are the long-term store
|
||||
- **Future: end-to-end encrypted chat** between tenants is planned and
|
||||
will require per-pair key exchange — see `relay/README.md` for the
|
||||
roadmap
|
||||
|
||||
### Relay Security
|
||||
|
||||
- Separate password (UI login) and shared secret (API + encryption)
|
||||
- Bcrypt hashing for both credentials
|
||||
- Rate-limited login (5 attempts/minute)
|
||||
- AES-256-CBC client-side encryption — relay never sees plaintext
|
||||
- Per-tenant bcrypt-hashed passwords + secrets
|
||||
- Master key encryption for tenant secrets and the inter-tenant key
|
||||
at rest
|
||||
- HttpOnly + SameSite=Strict session cookies
|
||||
- Rate-limited login (5 attempts/minute per IP)
|
||||
- AES-256-CBC for all message encryption
|
||||
- Security headers (X-Frame-Options, HSTS, X-Content-Type-Options)
|
||||
- SQLite database blocked from direct download via `.htaccess`
|
||||
- Request size limited to 256KB
|
||||
- `data/` directory blocked from direct download via `.htaccess`
|
||||
- Request size limited to 256KB (15MB for attachments)
|
||||
- Last-admin protection prevents accidental lockout
|
||||
|
||||
For the full security model (including what's NOT protected and the
|
||||
roadmap to strict E2E for chat), see [`relay/README.md`](relay/README.md).
|
||||
|
||||
### Migrating from the old single-tenant relay
|
||||
|
||||
When you upgrade an existing relay installation, the new code automatically
|
||||
detects the legacy schema and drops the old `messages` and `attachments`
|
||||
tables (the data is 24h-ephemeral anyway). The setup wizard appears on
|
||||
your next visit. You'll need to:
|
||||
1. Run through the desktop setup wizard to create the first admin
|
||||
2. Recreate any other tenant accounts that need access
|
||||
3. On every connected hyprcrd, update **Settings → Relay** to add the
|
||||
new **username** field and the new shared secret
|
||||
|
||||
The old `relay_key` was bcrypt-hashed and cannot be recovered, so all
|
||||
client secrets need to be reissued.
|
||||
|
||||
## Rebuilding Tailwind CSS
|
||||
|
||||
|
||||
Reference in new issue
Block a user