Commit graph

32 commits

Author SHA1 Message Date
1b58768738 fix(video): logo overlays must belong to the workspace; drop debug stderr
- produceVideo checks every logo overlay key against the workspace's
  media_assets, group_assets or branding logo before queueing; a
  well-formed content address alone no longer suffices.
- Remove MEDIA_DEBUG_STDERR=1 from the production compose: it wrote raw
  ffmpeg stderr to an unrotated file, bypassing redaction.
2026-10-15 15:09:07 +02:00
77b32ef70f feat: enable oCIS public link sharing (folders can be shared publicly) 2026-10-15 09:56:25 +00:00
1ddaf32edf fix: raise upload limits — api 2 GiB, nginx 2g (was 100 MiB api / 20m-512m nginx)
Cloudflare free caps at 100 MB on the proxied route regardless; larger
files need the domain set to DNS-only or a chunked upload path.
2026-10-15 08:46:50 +00:00
3c1bce1cd2 chore: produce-worker debug — MEDIA_DEBUG_STDERR=1 routes ffmpeg stderr to /tmp/ffmpeg-debug.log 2026-10-14 23:19:45 +00:00
87ddc1a206 fix: api image installs ffmpeg (ffprobe was missing — every upload probe failed ENOENT) 2026-10-14 22:55:02 +00:00
d9e8cdf789 feat: produce worker deployment + web producer/collective/branding UI + mobile CSS (wave-2c)
Deployment (t4g2): media-worker gains font-dejavu (drawtext lower-thirds)
and a dedicated produce-worker compose service running src/produce.ts —
claims video_processing_jobs compose|mix by lane, renders assembled/
overlaid/voiced cuts, registers derived library assets. Deliberately its
own process so a remote-lane box needs only Postgres + S3 + ffmpeg.

Web: compose media attachments UI (t2), Producer panel in the video
drawer (t5), collective creation + branding settings + shell branding
(brandweb), mobile CSS (mcss: touch targets, icon sizing, safe areas).
2026-10-14 20:40:49 +00:00
1069f20c54 brand: de-ownCloud the files load flash — title, theme-color, splash at the edge
oCIS web's index.html carries ownCloud branding before the app mounts
(title 'ownCloud', blue theme-color, white/blue splash spinner). The
files vhosts (tunnel + TLS) now rewrite those at the edge: Hub title,
dark theme-color, dark splash with warm text and the red spinner.
2026-10-14 13:32:00 +00:00
b89dea5c93 feat: per-connection publish governance — auto, 1-admin, majority, consensus
Per the owner's spec: each social connection gets publishGovernance in its
fields — unset = manual publish (today), auto = dispatch on approval,
admin1/admin_majority/admin_consensus = a publish-phase chatgov poll
(subject draft_publish, its own open-poll slot, no collision with review
gates). Dispatch holds until the publish poll passes (E3 pre-dispatch
check); auto dispatches on approval. Includes migration 033, the PATCH
/connections/:id/publish-governance route (chatgov.manage), and 19+31 new
tests. Implementation by the branding-panel process (claude/opus), lint
and integration fixes here.
2026-10-14 08:04:56 +00:00
7aa99681dd files: allow api.occupymedia.cc in the oCIS CSP connect-src
The oCIS web fetches the OIDC discovery document from the Hub issuer in the
browser — connect-src only allowed same-origin + blob, so the fetch was
blocked and the web fell back to its own login. With the CSP fix + the
external issuer flip, the full SSO chain works: Hub login -> authorize ->
consent SPA -> code -> autoprovisioned personal drive.
2026-10-13 19:07:32 +00:00
3117e1c18e ops: OIDC issuer deployment wiring — key volume, CORS for files, Drive authMode flip 2026-10-13 18:46:28 +00:00
c01d121748 mobile: gateway handoff for Chat and Drive below 1024px; pin Hub theme in the SSO bootstrap
Panel consensus (the branding panel): don't mount full-app iframes on
mobile — nested scrolling, keyboard collapse and double chrome break both
Element and oCIS under the bottom tab bar. Chat and Drive render a gateway
card (same-tab handoff, matrix: deep link, signed-in-as) below 1024px; the
iframe stays on desktop. hub-sso.html pins mx_local_settings.theme to
custom-OccupyHub Dark once (version-flagged) — a device's earlier picker
choice would otherwise beat config.json's default_theme.
2026-10-13 17:41:05 +00:00
3463b0a4f4 edge: strip Accept-Encoding on the oCIS signin restyle location
oCIS compresses the idp sign-in HTML, and sub_filter cannot rewrite
compressed bodies. Works on the grey/failover path where the edge serves
files; in tunnel mode files bypasses the edge entirely (tunnel ingress
points straight at oCIS), so the permanent brand fix remains the Hub OIDC
issuer (docs/design/2026-10-13-files-oidc-sso.md).
2026-10-13 17:07:50 +00:00
9d42d61f6b edge: restyle the oCIS idp sign-in wall into the Hub palette
The sign-in page is served by oCIS's idp service, which the web theme.json
cannot touch. Inject hub-signin.css via sub_filter on /signin/ until oCIS
sits behind the Hub OIDC issuer (see docs/design/2026-10-13-files-oidc-sso.md).
2026-10-13 16:57:38 +00:00
af93176bbe ops: tuwunel loads appservice registrations via TUWUNEL_APPSERVICE_DIR
Inline [appservice.*] tables drop the namespaces field (registration then
fails M_EXCLUSIVE for every AS user). The env var points tuwunel at the
/appservices mount (telegram + hub YAMLs, both with namespaces).
2026-10-13 16:05:48 +00:00
189cb41a09 ops: pin shared Temporal publishing queue; pass MATRIX_SSO_AS_TOKEN/HS_TOKEN to api
W1's governance sim found approved publishes never executing: the api starts
workflows on tmbh-publishing while the 3-day-old scheduler image consumed the
old superposter-publishing default. Pin TEMPORAL_TASK_QUEUE on both services.
2026-10-13 15:35:49 +00:00
fe5f2403d6 feat: in-app Chat (Matrix JWT SSO) + Drive (embedded oCIS)
- api: matrix-sso module (tuwunel jwt -> login/get_token), POST /matrix/session, GET /matrix/identity, drive controller
- web: /chat full-height Element view, /files Library+Drive tabs, embedded-app frame component
- edge: /hub-sso.html handshake route (origin-pinned CSP), X-Frame-Options strip on files
- oCIS: csp.yaml frame-ancestors app.occupymedia.cc
- server config still required: tuwunel [global.jwt], MATRIX_SSO_JWT_SECRET, oCIS restart
2026-10-13 14:57:07 +00:00
a2aa70c961 edge: social.occupymedia.cc vhost — Mastodon web :3030 + streaming :4040 (CT-host LAN bind, websocket upgrade, 80m uploads) 2026-10-13 14:34:06 +00:00
27fd68c8df Landing: Enter -> login door, /login deep-link (signin mode), /signup register; onboarding scroll fix 2026-10-13 08:13:33 +00:00
e3a6e9da97 Share with collective: fix union narrowing in open-room result handling 2026-10-12 22:35:32 +00:00
6ea605c87e Edge: hub-branded oCIS theme + assets for files.occupymedia.cc, both ingress paths; brand assets mount 2026-10-12 18:22:05 +00:00
6161ac4740 Manual: full participation guide (media/accounts/decisions/safety) + Enter-to-door + provisioner env passthrough 2026-10-12 15:49:25 +00:00
ac969f05c9 Chat client hosted at chat.occupymedia.cc: Element + API on one host, hub welcome page 2026-10-12 13:16:45 +00:00
39dcf7a8b8 Edge: chat root redirects to branded client, serve matrix well-known; onboarding hero full-bleed on black 2026-10-12 12:55:05 +00:00
7cea73dc0d Edge: tailscale0 relay exemption, CT320 transit hop, files/office/intake host parity 2026-10-11 21:36:20 +00:00
83e34aa343 Switch chat CT to tuwunel 1.9.4 with R2 media provider 2026-10-11 21:09:51 +00:00
b1b2a07b3d Pass FILES_OCID_* WebDAV credentials into the api container 2026-10-11 16:25:48 +00:00
2cb77ae6b4 Harden archive bot for production; exempt container egress in edge firewall
- archive_sync_state keyed by room per migration 029 (drop synthetic id cursor)
- putStaging buffers the stream and sends content-length (oCIS rejects chunked)
- mimeClass passthrough from sniffed payload
- edge-firewall: RETURN docker-bridge ingress before the CF-range catch-all so
  container egress (Matrix/R2/platform) survives the 80/443 source filter
- files scaffold: keep the ocdav data-gateway hop on-loopback
2026-10-11 16:12:43 +00:00
688a2ce996 Enable basic-auth WebDAV on the oCIS proxy (machine access for api/bot)
The group-files api and the archive bot authenticate to oCIS WebDAV with
basic credentials (admin until a dedicated service user exists). The proxy
is LAN-published only; no WAN forward exists.
2026-10-11 08:49:27 +00:00
6cdffa60b2 Track the files scaffold; sync deployed oCIS compose requirements
infra/occupymedia/files/ was gitignored in phase one ('nothing deployed');
the oCIS deployment is now live, and the storage doc + DEPLOY.md link to its
runbook. Track the secret-free scaffold (compose.yml, csp.yaml, README,
tuwunel example, .env.example); keep only .env + secrets/ ignored.

compose.yml carries the deployment-proven fixes: ocis runs as user 1000 with
OCIS_CONFIG_DIR=/etc/ocis and HOME=/var/lib/ocis (source-built images do not
inherit the official image's conventions), and 9200/9980 publish on the LAN
for the CT150 tunnel connector.
2026-10-11 07:51:59 +00:00
161f06f1e9 Ship edge-activate.sh: workstation-side activation + pool verification
One-shot watcher for the workstation: probes ping.occupymedia.cc through a
reachable edge IP, flips the four hostnames after the port-forward verifies,
checks the public path for 6 minutes and auto-reverts to TUNNEL if the new
pool assignment is broken too. Retires itself if the tunnel heals first.
README updated to match.
2026-10-10 21:26:54 +00:00
9365b561b2 Add edge stack: second ingress path + dual-path DNS failover
Cloudflare's tunnel edge-pool assignment can blackhole the site for whole
regions (2026-10-10: tunnel hostnames served from an unreachable anycast
range for hours). This adds an independent path and the automation that
keeps occupymedia.cc reachable when either path is sick:

- nginx edge mirroring the tunnel ingress (app/api/tube/chat/ping), LE
  wildcard via dns-01, twice-daily renewal
- DOCKER-USER firewall: 80/443 restricted to Cloudflare ranges (CF mode)
  or OPEN for grey-cloud mode via firewall.mode
- edge-watcher (60s systemd timer): dynamic public-IP sync, dual-path
  health checks, DNS failover TUNNEL<->ORIGIN/GREY with hysteresis,
  gated by EDGE_ENABLED
- ping.occupymedia.cc sacrificial probe host for activation
- deployment runbook in README.md; credential files shipped as .example
2026-10-10 21:22:15 +00:00
aa5e262f3a Tactical Media Broadcast Hub — initial release
Self-hosted multi-platform broadcast newsroom for activist collectives:
publishing pipeline with group approval and DST-proof scheduling, TweetDeck-style
column wall with hostile-content-safe rendering, live control room with Auto
Director, bridged chat governance with polls and quorum, distributed sandboxed
transcode workers, encrypted content-addressed archive, monthly analytics.

MIT licensed. See README.md and docs/.
2026-10-10 11:56:42 +00:00