diff --git a/infrastructure/docker-compose/configs/ocis/csp.yaml b/infrastructure/docker-compose/configs/ocis/csp.yaml new file mode 100644 index 0000000..1017ebb --- /dev/null +++ b/infrastructure/docker-compose/configs/ocis/csp.yaml @@ -0,0 +1,48 @@ +# OCIS Web — Content Security Policy overrides for local development. +# +# Default OCIS CSP only allows connect-src to 'self' + the owncloud awesome-ocis +# repo, which blocks the OIDC metadata fetch from Authentik. We extend connect-src +# (and a few related directives) to include auth.dezky.local. +# +# Values like "blob:" and "data:" MUST be quoted — bare they're parsed as YAML +# mappings and the proxy service crashes with "expected type 'string'". + +directives: + child-src: + - "'self'" + connect-src: + - "'self'" + - "blob:" + - "https://auth.dezky.local" + - "https://raw.githubusercontent.com/owncloud/awesome-ocis/" + default-src: + - "'none'" + font-src: + - "'self'" + frame-ancestors: + - "'self'" + frame-src: + - "'self'" + - "blob:" + - "https://embed.diagrams.net/" + - "https://office.dezky.local" + - "https://collaboration.dezky.local" + img-src: + - "'self'" + - "data:" + - "blob:" + - "https://raw.githubusercontent.com/owncloud/awesome-ocis/" + manifest-src: + - "'self'" + media-src: + - "'self'" + object-src: + - "'self'" + - "blob:" + script-src: + - "'self'" + - "'unsafe-inline'" + - "'unsafe-eval'" + style-src: + - "'self'" + - "'unsafe-inline'" diff --git a/infrastructure/docker-compose/docker-compose.yml b/infrastructure/docker-compose/docker-compose.yml index 207b047..e4a4dab 100644 --- a/infrastructure/docker-compose/docker-compose.yml +++ b/infrastructure/docker-compose/docker-compose.yml @@ -58,6 +58,7 @@ services: - files.dezky.local - mail.dezky.local - office.dezky.local + - collaboration.dezky.local labels: - traefik.enable=true - traefik.http.routers.dashboard.rule=Host(`traefik.dezky.local`) @@ -239,9 +240,19 @@ services: STORAGE_SYSTEM_DRIVER: ocis OCIS_CONFIG_DIR: /etc/ocis OCIS_BASE_DATA_PATH: /var/lib/ocis + # Extend CSP so the OCIS web SPA can reach Authentik for OIDC metadata. + # Enforced by the OCIS proxy service, not web — env var is PROXY_-prefixed. + PROXY_CSP_CONFIG_FILE_LOCATION: /etc/ocis/csp.yaml + # Expose the embedded NATS service registry and gRPC services on the Docker + # network so the collaboration container can talk to OCIS internals. + NATS_NATS_HOST: 0.0.0.0 + NATS_NATS_PORT: 9233 + GATEWAY_GRPC_ADDR: 0.0.0.0:9142 + MICRO_GRPC_CLIENT_DNS_CACHE_TIMEOUT: 10s volumes: - ocis_config:/etc/ocis - ocis_data:/var/lib/ocis + - ./configs/ocis/csp.yaml:/etc/ocis/csp.yaml:ro networks: [dezky] depends_on: - authentik-server @@ -252,18 +263,30 @@ services: - traefik.http.services.ocis.loadbalancer.server.port=9200 # ───────────────────────────────────────────────────────────────── - # Collabora — Office document editor (integrated into OCIS) + # Collabora — Office document editor (loaded inside an iframe by OCIS) # ───────────────────────────────────────────────────────────────── collabora: image: collabora/code:latest container_name: dezky-collabora restart: unless-stopped + cap_add: + - MKNOD environment: - aliasgroup1: https://files\\.dezky\\.local:443 + # Allow the WOPI host (OCIS collaboration service) to talk to Collabora + aliasgroup1: https://collaboration.dezky.local:443 DONT_GEN_SSL_CERT: "true" - extra_params: --o:ssl.enable=false --o:ssl.termination=true --o:welcome.enable=false + # frame_ancestors: which hosts may embed Collabora in an iframe. + # Without this set, browsers block the iframe with a Danish "Indhold blokeret". + # home_mode.enable=true disables the "Explore The New" welcome popup AND the + # feedback prompt; caps at 20 connections / 10 documents (fine for dev). + extra_params: --o:ssl.enable=false --o:ssl.termination=true --o:ssl.ssl_verification=false --o:home_mode.enable=true --o:feedback.show=false --o:net.frame_ancestors=files.dezky.local username: admin password: ${COLLABORA_ADMIN_PASSWORD} + # Generate a fresh WOPI proof key on every start so the public key Collabora + # advertises matches the private key it signs with. Without this, the OCIS + # collaboration service rejects WOPI calls with "ProofKeys verification failed". + entrypoint: ["/bin/bash", "-c"] + command: ["coolconfig generate-proof-key && /start-collabora-online.sh"] networks: [dezky] labels: - traefik.enable=true @@ -271,6 +294,54 @@ services: - traefik.http.routers.collabora.tls=true - traefik.http.services.collabora.loadbalancer.server.port=9980 + # ───────────────────────────────────────────────────────────────── + # OCIS Collaboration — WOPI bridge between OCIS storage and Collabora. + # Shares the ocis_config volume so it picks up the same JWT/transfer secrets + # that ocis init generated. Without this, opening a .docx just downloads. + # ───────────────────────────────────────────────────────────────── + collaboration: + image: owncloud/ocis:7.0 + container_name: dezky-collaboration + restart: unless-stopped + entrypoint: ["/bin/sh", "-c"] + command: ["ocis collaboration server"] + environment: + OCIS_URL: https://files.dezky.local + OCIS_LOG_LEVEL: warn + OCIS_INSECURE: "true" + OCIS_CONFIG_DIR: /etc/ocis + OCIS_BASE_DATA_PATH: /var/lib/ocis + COLLABORATION_HTTP_ADDR: 0.0.0.0:9300 + COLLABORATION_GRPC_ADDR: 0.0.0.0:9301 + COLLABORATION_WOPI_SRC: https://collaboration.dezky.local + COLLABORATION_APP_NAME: Collabora + COLLABORATION_APP_PRODUCT: Collabora + COLLABORATION_APP_DESCRIPTION: Collabora Online + # APP_ADDR is sent to the browser as the iframe src — must be public, not the + # Docker-internal hostname. Collaboration → Collabora traffic goes via Traefik. + COLLABORATION_APP_ADDR: https://office.dezky.local + COLLABORATION_APP_INSECURE: "true" + COLLABORATION_CS3API_DATAGATEWAY_INSECURE: "true" + # Match OCIS JWT/secrets via the shared config volume. + # Service registry: connect to OCIS's embedded NATS (not localhost). + MICRO_REGISTRY: nats-js-kv + MICRO_REGISTRY_ADDRESS: ocis:9233 + # Direct gRPC pointer to OCIS's gateway (collaboration can't rely on registry + # lookups returning the right hostname for cross-container traffic). + REVA_GATEWAY: ocis:9142 + volumes: + - ocis_config:/etc/ocis + - ocis_data:/var/lib/ocis + networks: [dezky] + depends_on: + - ocis + - collabora + labels: + - traefik.enable=true + - traefik.http.routers.collaboration.rule=Host(`collaboration.dezky.local`) + - traefik.http.routers.collaboration.tls=true + - traefik.http.services.collaboration.loadbalancer.server.port=9300 + # ───────────────────────────────────────────────────────────────── # Portal — Nuxt 3 customer portal (development mode with HMR) # ─────────────────────────────────────────────────────────────────