71 lines
3.7 KiB
Markdown
71 lines
3.7 KiB
Markdown
# Wiring Threema relay into the portal
|
|
|
|
Drop-in files in this archive:
|
|
|
|
```
|
|
src/lib/packages.ts # add 'threema' to catalog + customProvisioning flag
|
|
src/lib/threema-relay.ts # new — admin API client
|
|
src/app/api/tenants/[name]/threema/route.ts # new — POST provision / DELETE deprovision
|
|
src/app/api/tenants/[name]/threema/routes/route.ts # new — atomic add/remove of a single Threema ID
|
|
src/components/channel-users/channel-users.tsx # branch threema through relay-managed endpoint
|
|
src/components/packages/package-card.tsx # handle customProvisioning enable/disable
|
|
deploy/patch-i18n-threema.mjs # idempotent i18n key injection
|
|
```
|
|
|
|
## Manual steps after dropping in
|
|
|
|
1. `.env` (and `.env.example`) — add:
|
|
```
|
|
THREEMA_RELAY_URL=http://pieced-threema-gateway.threema-gateway.svc:8080
|
|
THREEMA_RELAY_ADMIN_TOKEN=__from_openbao__
|
|
```
|
|
The portal pod's OpenBao client should also read `secret/data/threema-gateway/admin` and surface `token` as this env var (existing ESO pattern in the portal's Helm chart).
|
|
|
|
2. Patch the message files (one-time):
|
|
```bash
|
|
node deploy/patch-i18n-threema.mjs
|
|
```
|
|
|
|
3. Re-export `CHANNEL_PACKAGE_IDS` is unchanged in source; verify
|
|
`tenants/[name]/page.tsx` still derives the enabled-channels list
|
|
from it — it should now include `threema` automatically once a
|
|
tenant has it in `spec.packages`.
|
|
|
|
4. Type-check:
|
|
```bash
|
|
npx tsc --noEmit
|
|
```
|
|
|
|
## Flow summary
|
|
|
|
### Enabling Threema for a tenant
|
|
1. Customer toggles the threema package card.
|
|
2. PackageCard sees `customProvisioning: true` → POSTs `/api/tenants/<name>/threema`.
|
|
3. Handler calls relay `POST /admin/tokens` → gets `{token, hmacSecret}`.
|
|
4. Handler writes them to OpenBao at `secret/data/tenants/tenant-<name>/threema-relay`.
|
|
5. PackageCard then PATCHes `tenant.spec.packages` to include `threema`.
|
|
6. Operator reconciles: ExternalSecret syncs OpenBao → Secret; OpenClaw pod restarts with `THREEMA_RELAY_*` env vars; plugin registers `threema` channel.
|
|
|
|
### Customer adds a Threema ID
|
|
1. UI calls `POST /api/tenants/<name>/threema/routes` with `{threemaId}`.
|
|
2. Handler calls relay `POST /admin/routes` (uniqueness enforced at PK).
|
|
3. On 201 or 409-from-same-tenant: handler patches K8s `spec.channelUsers.threema`.
|
|
4. On 409-from-other-tenant: 409 to client with explanation.
|
|
5. On K8s patch failure after relay success: handler compensates by `DELETE /admin/routes/...` at the relay.
|
|
|
|
### Customer removes a Threema ID
|
|
1. UI calls `DELETE /api/tenants/<name>/threema/routes?threemaId=...`.
|
|
2. Handler patches K8s `spec.channelUsers.threema` to drop the ID.
|
|
3. Handler calls relay `DELETE /admin/routes/...` (404 = idempotent OK).
|
|
4. If relay drop fails: K8s already updated, surface warning but treat as success — relay deletes are idempotent on retry.
|
|
|
|
### Disabling Threema for a tenant
|
|
1. Customer disables the threema card.
|
|
2. PackageCard DELETEs `/api/tenants/<name>/threema`.
|
|
3. Handler calls relay `DELETE /admin/tokens/<name>` (cascades to all routes for this tenant).
|
|
4. Handler deletes OpenBao secret at `secret/data/tenants/tenant-<name>/threema-relay`.
|
|
5. PackageCard then PATCHes `tenant.spec.packages` to drop `threema`.
|
|
6. Operator reconciles: ExternalSecret targets a missing OpenBao path → Secret deleted → OpenClaw pod restarts without `threema` channel.
|
|
|
|
There's a small window (between step 4 and the operator's reconcile) where the pod still thinks it has a relay token but the relay has revoked it. Outbound during that window returns 401 from the relay; inbound is blackholed at the relay because routes are gone. Both are graceful failures.
|