Compare commits

...

65 Commits

Author SHA1 Message Date
micbar
4f21b38d46 Radicale: document client setup, allow anonymous well-known discovery
Clients were left guessing the CalDAV/CardDAV URLs (issue #192): the
README documented how to deploy Radicale but not how to connect to it.

- Add radicale/README.md with client URLs (trailing slash required),
  the App-Token requirement (account passwords are rejected with the
  default PROXY_ENABLE_BASIC_AUTH=false), GNOME Online Accounts and
  Thunderbird walkthroughs, and troubleshooting.
- Mark the two '/.well-known/*' proxy routes as unprotected so DAV
  clients can run RFC 6764 service discovery before authenticating.
  Previously the proxy answered 401 where clients expect the 301
  redirect to /caldav/ or /carddav/. Radicale serves no data on these
  paths (deeper paths return 404, path traversal is normalized onto
  the protected routes), verified against opencloud 7.5.0.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-09-01 10:32:42 +02:00
renovate[bot]
442017268a chore(deps): update quay.io/keycloak/keycloak docker tag to v26.7.3 (#374)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-08-31 16:22:03 +02:00
Madipodo
b31c3943fd Fix: EURO_OFFICE_JWT_SECRET was not passed to the container (#360)
* Fix: EURO_OFFICE_JWT_SECRET was not passed to the container

This issue has been open for a while and I ran into the same
problem, so I tried to fix it.

Fixes #340

* removed , what was added by auto formating

* Addes Line again, which was removed by auto formating
2026-08-31 16:21:30 +02:00
Michael Barz
cb23d6af18 Merge pull request #372 from opencloud-eu/renovate/main-alpine-openssl-3.x
chore(deps): update alpine/openssl docker tag to v3.5.8 (main)
2026-08-31 16:19:10 +02:00
renovate[bot]
8a1193f2d4 chore(deps): update alpine/openssl docker tag to v3.5.8 2026-08-31 14:18:57 +00:00
Michael Barz
18dc807be0 Merge pull request #363 from opencloud-eu/renovate/main-quay.io-keycloak-keycloak-26.x
chore(deps): update quay.io/keycloak/keycloak docker tag to v26.7.2 (main)
2026-08-31 16:18:35 +02:00
Michael Barz
0fab6e73a0 Merge pull request #364 from opencloud-eu/renovate/main-traefik-3.x
chore(deps): update traefik docker tag to v3.7.12 (main)
2026-08-31 16:18:06 +02:00
renovate[bot]
871b6ae4c8 chore(deps): update traefik docker tag to v3.7.12 2026-08-28 06:08:18 +00:00
renovate[bot]
f8b24d5200 chore(deps): update quay.io/keycloak/keycloak docker tag to v26.7.2 2026-08-28 06:08:14 +00:00
Benedikt Kulmann
8826153af8 Merge pull request #370 from opencloud-eu/extend-csp-yaml-epub-reader
feat: extend csp yaml for epub reader iframe sytle loading
2026-08-28 08:07:30 +02:00
Alexander Ackermann
6ed456d3df feat: extend csp yaml for epub reader iframe sytle loading 2026-08-27 17:54:03 +02:00
Michael Flemming
c092407fcd Merge pull request #369 from opencloud-eu/renovate/main-opencloudeu-opencloud-rolling-7.x
chore(deps): update opencloudeu/opencloud-rolling docker tag to v7.5.0 (main)
2026-08-25 17:00:56 +02:00
renovate[bot]
8f79c17270 chore(deps): update opencloudeu/opencloud-rolling docker tag to v7.5.0 2026-08-25 14:50:10 +00:00
Viktor Scharf
dc14e7e10a Merge pull request #367 from opencloud-eu/chore/enable-renovate-dependency-dashboard
chore: enable Renovate dependency dashboard
2026-08-21 10:02:40 +02:00
v.scharf
323b2c4aa4 chore: enable Renovate dependency dashboard 2026-08-21 09:51:55 +02:00
Alex
887e63e8a6 chore: bump maps to v3.1.0 (#362) 2026-08-19 08:21:32 +02:00
Michael Barz
a6e883bcf2 Merge pull request #359 from opencloud-eu/renovate/main-postgres-17.x
chore(deps): update postgres docker tag to v17.11 (main)
2026-08-14 16:19:04 +02:00
Michael Barz
49f5ce9d52 Merge pull request #357 from opencloud-eu/renovate/main-collabora-code-26.x
chore(deps): update collabora/code docker tag to v26.04.3.1.1 (main)
2026-08-14 16:18:13 +02:00
renovate[bot]
e824bd17db chore(deps): update postgres docker tag to v17.11 2026-08-13 22:47:53 +00:00
renovate[bot]
1721922f52 chore(deps): update collabora/code docker tag to v26.04.3.1.1 2026-08-11 22:32:41 +00:00
Michael Barz
db3ddbdf32 Merge pull request #355 from opencloud-eu/renovate/main-quay.io-keycloak-keycloak-26.x
chore(deps): update quay.io/keycloak/keycloak docker tag to v26.7.1 (main)
2026-08-05 19:48:18 +02:00
renovate[bot]
1fbb2380cc chore(deps): update quay.io/keycloak/keycloak docker tag to v26.7.1 2026-08-05 17:43:39 +00:00
Michael Barz
34129ff018 Merge pull request #352 from opencloud-eu/renovate/main-traefik-3.x
chore(deps): update traefik docker tag to v3.7.10 (main)
2026-08-05 19:42:49 +02:00
renovate[bot]
0f89106b89 chore(deps): update traefik docker tag to v3.7.10 2026-08-05 07:24:26 +00:00
Viktor Scharf
2b51cb53c0 Merge pull request #353 from opencloud-eu/renovate/main-opencloudeu-opencloud-rolling-7.x
chore(deps): update opencloudeu/opencloud-rolling docker tag to v7.4.0 (main)
2026-08-05 09:23:29 +02:00
renovate[bot]
eab3b7e584 chore(deps): update opencloudeu/opencloud-rolling docker tag to v7.4.0 2026-08-03 20:51:17 +00:00
Jannik Stehle
c4023ff553 Merge pull request #351 from opencloud-eu/feat/add-app-yaml-config-file
feat: add apps.yaml config
2026-07-31 16:16:25 +02:00
Jannik Stehle
aac9a1e2f5 feat: add apps.yaml config
Add a config for the maps map. Its purpose is not to change anything
but to guide and show users how to configure web apps. Now that the
apps.yaml file is mounted, it can easily be extended by more config
options
2026-07-31 11:20:17 +02:00
Tobias Baader
e6a0e8e2e6 Merge pull request #350 from opencloud-eu/feat(keycloak)-use-Inter-variable-font-in-login-theme
feat(keycloak): use Inter variable font in login theme
2026-07-31 09:33:05 +02:00
Alexander Ackermann
1ecdd0e32a use patternfly best practice 2026-07-30 19:16:30 +02:00
Alexander Ackermann
bcf59c86fd use patternfly best practice 2026-07-30 19:09:27 +02:00
Tobias Baader
7cd7c57bd9 feat(keycloak): use Inter variable font in login theme
Replace the bundled OpenCloud font with Inter in the Keycloak login
theme. Use the variable woff2 (weights 100-900) so a single self-hosted
file covers all weights, and drop the two static OpenCloud files.
follow up for
https://github.com/opencloud-eu/web/pull/2988
2026-07-30 18:27:52 +02:00
Jörn Friedrich Dreyer
213dde31c8 Merge pull request #347 from kellergoech/patch-1
Adjust collabora to new distroless container
2026-07-29 11:30:26 +02:00
Thomas Schweiger
dabd81377c chore: bump version to 6.04.2.4.1 2026-07-29 10:48:57 +02:00
Michael Barz
8d2d89f283 Merge pull request #348 from opencloud-eu/renovate/main-traefik-3.x
chore(deps): update traefik docker tag to v3.7.9 (main)
2026-07-25 10:14:26 +02:00
renovate[bot]
189f17f6e0 chore(deps): update traefik docker tag to v3.7.9 2026-07-24 21:51:13 +00:00
micbar
27fd367113 feat: add proof key side car 2026-07-24 12:42:49 +02:00
kellergoech
fffcec12a8 Adjust collavora to new distroless container 2026-07-24 07:06:50 +02:00
Michael Barz
42b4343d6e Merge pull request #341 from opencloud-eu/renovate/main-collabora-code-26.x
chore(deps): update collabora/code docker tag to v26.04.2.2.1 (main)
2026-07-19 18:29:41 +02:00
renovate[bot]
5666410706 chore(deps): update collabora/code docker tag to v26.04.2.2.1 2026-07-18 21:09:00 +00:00
Michael Barz
62131f972b Merge pull request #339 from opencloud-eu/renovate/main-traefik-3.x
chore(deps): update traefik docker tag to v3.7.8 (main)
2026-07-16 20:25:53 +02:00
renovate[bot]
274195c6ad chore(deps): update traefik docker tag to v3.7.8 2026-07-15 21:33:24 +00:00
Michael Barz
49ba000f6e Merge pull request #332 from opencloud-eu/renovate/main-quay.io-keycloak-keycloak-26.x
chore(deps): update quay.io/keycloak/keycloak docker tag to v26.7.0 (main)
2026-07-15 14:41:16 +02:00
Michael Barz
d759e5a332 Merge pull request #331 from opencloud-eu/renovate/main-traefik-3.x
chore(deps): update traefik docker tag to v3.7.7 (main)
2026-07-15 14:36:55 +02:00
renovate[bot]
d7fcd3da64 chore(deps): update traefik docker tag to v3.7.7 2026-07-15 04:55:36 +00:00
Michael Barz
325dce2f53 Merge pull request #338 from opencloud-eu/renovate/main-opencloudeu-opencloud-rolling-7.x
chore(deps): update opencloudeu/opencloud-rolling docker tag to v7.3.0 (main)
2026-07-15 06:55:06 +02:00
renovate[bot]
0221cfd91b chore(deps): update opencloudeu/opencloud-rolling docker tag to v7.3.0 2026-07-14 21:44:03 +00:00
renovate[bot]
c096f66dfd chore(deps): update quay.io/keycloak/keycloak docker tag to v26.7.0 2026-07-09 09:53:11 +00:00
Michael Barz
e6d987501e Merge pull request #328 from opencloud-eu/renovate/main-collabora-code-26.x
chore(deps): update collabora/code docker tag to v26.04.2.1.1 (main)
2026-07-01 13:09:05 +02:00
renovate[bot]
2f81c5f62c chore(deps): update collabora/code docker tag to v26.04.2.1.1 2026-07-01 11:08:45 +00:00
Michael Barz
670d978c1c Merge pull request #322 from opencloud-eu/renovate/main-quay.io-keycloak-keycloak-26.x
chore(deps): update quay.io/keycloak/keycloak docker tag to v26.6.4 (main)
2026-07-01 13:08:22 +02:00
renovate[bot]
d952c2849b chore(deps): update quay.io/keycloak/keycloak docker tag to v26.6.4 2026-07-01 10:59:19 +00:00
Michael Barz
13b9489c52 chore: enable renovate for stable-7.2 2026-07-01 12:58:43 +02:00
Michael Barz
e8b8511477 Merge pull request #327 from opencloud-eu/renovate/main-traefik-3.x
chore(deps): update traefik docker tag to v3.7.5 (main)
2026-07-01 09:08:57 +02:00
renovate[bot]
70e7679bc3 chore(deps): update traefik docker tag to v3.7.6 2026-07-01 00:54:25 +00:00
Michael Barz
0d62d41894 Merge pull request #325 from lbausch/rename-euroffice
Rename euroffice to euro-office
2026-06-28 08:24:33 +02:00
Lorenz Bausch
16bd598d4d Rename euroffice to euro-office 2026-06-27 22:20:15 +02:00
Michael Barz
bc0a74dd5a Merge pull request #323 from opencloud-eu/keycloak-theme-v2-followup
fix (keycloak): adjust opencloud theme background not using full heig…
2026-06-27 09:08:12 +02:00
Alexander Ackermann
b8a0a98a51 fix (keycloak): adjust opencloud theme background not using full height when scrollable 2026-06-27 00:28:27 +02:00
Jörn Friedrich Dreyer
b914288032 Merge pull request #321 from opencloud-eu/keycloak-theme-v2
chore (keycloak): migrate login theme to keycloak.v2
2026-06-26 15:03:21 +02:00
Alexander Ackermann
09e0d8f32a chore (keycloak): migrate login theme to keycloak.v2 2026-06-25 22:13:32 +02:00
Michael Barz
aab87f13a7 Merge pull request #294 from opencloud-eu/renovate/main-opencloudeu-opencloud-rolling-7.x
chore(deps): update opencloudeu/opencloud-rolling docker tag to v7 (main)
2026-06-25 18:34:36 +02:00
Michael Barz
aebf5882f4 Merge pull request #319 from ralfbergs/patch-2
Update opencloud.yml: wrong indentation.
2026-06-25 18:25:59 +02:00
Ralf G. R. Bergs
f292460d32 Update opencloud.yml: wrong indentation. 2026-06-25 15:01:07 +02:00
renovate[bot]
46ad111b94 chore(deps): update opencloudeu/opencloud-rolling docker tag to v7 2026-06-25 08:40:48 +00:00
46 changed files with 1057 additions and 893 deletions

View File

@@ -25,9 +25,9 @@ INSECURE=true
# External IDP # External IDP
#COMPOSE_FILE=docker-compose.yml:weboffice/collabora.yml:traefik/opencloud.yml:traefik/collabora.yml:idm/external-idp.yml #COMPOSE_FILE=docker-compose.yml:weboffice/collabora.yml:traefik/opencloud.yml:traefik/collabora.yml:idm/external-idp.yml
# Euro Office with traefik and letsencrypt # Euro Office with traefik and letsencrypt
#COMPOSE_FILE=docker-compose.yml:weboffice/euroffice.yml:traefik/opencloud.yml:traefik/euroffice.yml #COMPOSE_FILE=docker-compose.yml:weboffice/euro-office.yml:traefik/opencloud.yml:traefik/euro-office.yml
# Euro Office with external proxy (Nginx, Caddy, etc.) # Euro Office with external proxy (Nginx, Caddy, etc.)
#COMPOSE_FILE=docker-compose.yml:weboffice/euroffice.yml:external-proxy/opencloud.yml:external-proxy/euroffice.yml #COMPOSE_FILE=docker-compose.yml:weboffice/euro-office.yml:external-proxy/opencloud.yml:external-proxy/euro-office.yml
## Traefik Settings ## ## Traefik Settings ##
# Note: Traefik is always enabled and can't be disabled. # Note: Traefik is always enabled and can't be disabled.

View File

@@ -147,12 +147,12 @@ Include Euro Office for document editing using either method:
Using `-f` flags: Using `-f` flags:
```bash ```bash
docker compose -f docker-compose.yml -f weboffice/euroffice.yml -f traefik/opencloud.yml -f traefik/euroffice.yml up -d docker compose -f docker-compose.yml -f weboffice/euro-office.yml -f traefik/opencloud.yml -f traefik/euro-office.yml up -d
``` ```
Or by setting in `.env`: Or by setting in `.env`:
``` ```
COMPOSE_FILE=docker-compose.yml:weboffice/euroffice.yml:traefik/opencloud.yml:traefik/euroffice.yml COMPOSE_FILE=docker-compose.yml:weboffice/euro-office.yml:traefik/opencloud.yml:traefik/euro-office.yml
``` ```
> **For local development only**: Add to `/etc/hosts`: > **For local development only**: Add to `/etc/hosts`:
@@ -215,6 +215,11 @@ This setup includes:
- Radicale as a CalDAV (calendars, to-do lists) and CardDAV (contacts) server - Radicale as a CalDAV (calendars, to-do lists) and CardDAV (contacts) server
- Users access to a Personal Calendar and Addressbook - Users access to a Personal Calendar and Addressbook
Clients connect to `https://<your-domain>/caldav/` (calendar) and
`https://<your-domain>/carddav/` (contacts) — note the required trailing
slash — using an App Token as password. See [radicale/README.md](radicale/README.md)
for client setup (GNOME Online Accounts, Thunderbird) and troubleshooting.
### With Monitoring ### With Monitoring
Enable monitoring capabilities with metrics endpoints using either method: Enable monitoring capabilities with metrics endpoints using either method:
@@ -271,12 +276,12 @@ The WOPI server runs inside the OpenCloud process and is served on the OpenCloud
To use Euro Office instead of Collabora behind an external proxy, swap the web office compose files: To use Euro Office instead of Collabora behind an external proxy, swap the web office compose files:
```bash ```bash
docker compose -f docker-compose.yml -f weboffice/euroffice.yml -f external-proxy/opencloud.yml -f external-proxy/euroffice.yml up -d docker compose -f docker-compose.yml -f weboffice/euro-office.yml -f external-proxy/opencloud.yml -f external-proxy/euro-office.yml up -d
``` ```
Or by setting in `.env`: Or by setting in `.env`:
``` ```
COMPOSE_FILE=docker-compose.yml:weboffice/euroffice.yml:external-proxy/opencloud.yml:external-proxy/euroffice.yml COMPOSE_FILE=docker-compose.yml:weboffice/euro-office.yml:external-proxy/opencloud.yml:external-proxy/euro-office.yml
``` ```
This exposes the necessary ports: This exposes the necessary ports:
@@ -286,7 +291,7 @@ This exposes the necessary ports:
As with Collabora, the WOPI server is served on the OpenCloud port (9200) under the `/wopi` and `/collaboration` paths and needs no separate port. As with Collabora, the WOPI server is served on the OpenCloud port (9200) under the `/wopi` and `/collaboration` paths and needs no separate port.
> [!WARNING] > [!WARNING]
> `external-proxy/euroffice.yml` binds the exposed ports to `127.0.0.1` only. If your external proxy runs on a different host, use `external-proxy/euroffice-exposed.yml`, which binds to all interfaces (`0.0.0.0`). Only expose these ports when you know what you are doing. > `external-proxy/euro-office.yml` binds the exposed ports to `127.0.0.1` only. If your external proxy runs on a different host, use `external-proxy/euro-office-exposed.yml`, which binds to all interfaces (`0.0.0.0`). Only expose these ports when you know what you are doing.
**Please note:** **Please note:**
If you're using **Nginx Proxy Manager (NPM)**, you **should NOT** activate **"Block Common Exploits"** for the Proxy Host. If you're using **Nginx Proxy Manager (NPM)**, you **should NOT** activate **"Block Common Exploits"** for the Proxy Host.

View File

@@ -1,38 +1,51 @@
:root { :root {
--pf-global--primary-color--100: #e2baff; --pf-v5-global--primary-color--100: #e2baff;
--pf-global--primary-color--200: #e2baff; --pf-v5-global--primary-color--200: #e2baff;
--pf-global--primary-color--dark-100: #e2baff; --pf-v5-global--primary-color--dark-100: #e2baff;
--pf-global--Color--light-100: #20434f; --pf-v5-c-button--m-secondary--Color: #e2baff;
--pf-v5-global--Color--light-100: #20434f;
--pf-v5-global--FontFamily--text: "Inter", "RedHatText", helvetica, arial, sans-serif;
--pf-v5-global--FontFamily--heading: "Inter", "RedHatDisplay", helvetica, arial, sans-serif;
} }
@font-face { @font-face {
font-family: OpenCloud; font-family: Inter;
src: url('../fonts/OpenCloud500-Regular.woff2') format('woff2'); src: url('../fonts/Inter-Variable.woff2') format('woff2');
font-weight: normal; font-weight: 100 900;
font-style: normal;
}
@font-face {
font-family: OpenCloud;
src: url('../fonts/OpenCloud750-Bold.woff2') format('woff2');
font-weight: bold;
font-style: normal; font-style: normal;
} }
body { body {
font-family: "OpenCloud", "Open Sans", Helvetica, Arial, sans-serif; background: url(../img/background.png) no-repeat center fixed !important;
background: url(../img/background.png) no-repeat center !important;
background-size: cover !important; background-size: cover !important;
} }
.kc-logo-text { .kc-logo-text {
background-image: url(../img/logo.svg) !important; display: block;
width: 300px;
height: 63px;
background: url('../img/logo.svg') no-repeat center;
background-size: contain; background-size: contain;
width: 400px;
margin: 0 !important;
} }
#kc-header-wrapper{ .kc-logo-text span {
display: none;
}
#kc-header-wrapper {
display: flex; display: flex;
justify-content: center; justify-content: center;
} }
.pf-v5-c-login__main-header {
border-top: 4px solid var(--pf-v5-global--primary-color--100);
}
@media (min-width: 1200px) {
.pf-v5-c-login__container {
grid-template-columns: 34rem;
grid-template-areas:
"header"
"main";
}
}

View File

@@ -16,4 +16,4 @@ document.addEventListener("DOMContentLoaded", function () {
} }
setLogoUrl('https://opencloud.eu') setLogoUrl('https://opencloud.eu')
}); });

View File

@@ -1,5 +1,5 @@
parent=keycloak parent=keycloak.v2
import=common/keycloak import=common/keycloak
styles=css/login.css css/theme.css styles=css/login.css css/theme.css
scripts=js/script.js scripts=js/script.js

View File

@@ -0,0 +1,3 @@
maps:
config:
folderViewEnabled: false

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1 @@
import{t as e}from"./preload-helper-DYl5dUZ5.mjs";await(await e(()=>import(`./remoteEntry-BXGAhFe2.mjs`),[],import.meta.url)).init();

View File

@@ -1 +0,0 @@
import{t as e}from"./preload-helper-DafEc2pQ.mjs";await(await e(()=>import(`./remoteEntry-lxWu31Tr.mjs`),[],import.meta.url)).init();

View File

@@ -0,0 +1 @@
import"./dist-CXnzN4cY.mjs";var e={"@opencloud-eu/web-client":{name:`@opencloud-eu/web-client`,version:void 0,scope:[`default`],loaded:!1,from:`maps`,async get(){throw Error(`[Module Federation] Shared module '@opencloud-eu/web-client' must be provided by host`)},shareConfig:{singleton:!0,requiredVersion:`*`,import:!1}},"@opencloud-eu/web-client/graph":{name:`@opencloud-eu/web-client/graph`,version:void 0,scope:[`default`],loaded:!1,from:`maps`,async get(){throw Error(`[Module Federation] Shared module '@opencloud-eu/web-client/graph' must be provided by host`)},shareConfig:{singleton:!0,requiredVersion:`*`,import:!1}},"@opencloud-eu/web-client/graph/generated":{name:`@opencloud-eu/web-client/graph/generated`,version:void 0,scope:[`default`],loaded:!1,from:`maps`,async get(){throw Error(`[Module Federation] Shared module '@opencloud-eu/web-client/graph/generated' must be provided by host`)},shareConfig:{singleton:!0,requiredVersion:`*`,import:!1}},"@opencloud-eu/web-client/ocs":{name:`@opencloud-eu/web-client/ocs`,version:void 0,scope:[`default`],loaded:!1,from:`maps`,async get(){throw Error(`[Module Federation] Shared module '@opencloud-eu/web-client/ocs' must be provided by host`)},shareConfig:{singleton:!0,requiredVersion:`*`,import:!1}},"@opencloud-eu/web-client/ox":{name:`@opencloud-eu/web-client/ox`,version:void 0,scope:[`default`],loaded:!1,from:`maps`,async get(){throw Error(`[Module Federation] Shared module '@opencloud-eu/web-client/ox' must be provided by host`)},shareConfig:{singleton:!0,requiredVersion:`*`,import:!1}},"@opencloud-eu/web-client/sse":{name:`@opencloud-eu/web-client/sse`,version:void 0,scope:[`default`],loaded:!1,from:`maps`,async get(){throw Error(`[Module Federation] Shared module '@opencloud-eu/web-client/sse' must be provided by host`)},shareConfig:{singleton:!0,requiredVersion:`*`,import:!1}},"@opencloud-eu/web-client/webdav":{name:`@opencloud-eu/web-client/webdav`,version:void 0,scope:[`default`],loaded:!1,from:`maps`,async get(){throw Error(`[Module Federation] Shared module '@opencloud-eu/web-client/webdav' must be provided by host`)},shareConfig:{singleton:!0,requiredVersion:`*`,import:!1}},"@opencloud-eu/web-pkg":{name:`@opencloud-eu/web-pkg`,version:void 0,scope:[`default`],loaded:!1,from:`maps`,async get(){throw Error(`[Module Federation] Shared module '@opencloud-eu/web-pkg' must be provided by host`)},shareConfig:{singleton:!0,requiredVersion:`*`,import:!1}},"@opencloud-eu/web-pkg/editor":{name:`@opencloud-eu/web-pkg/editor`,version:void 0,scope:[`default`],loaded:!1,from:`maps`,async get(){throw Error(`[Module Federation] Shared module '@opencloud-eu/web-pkg/editor' must be provided by host`)},shareConfig:{singleton:!0,requiredVersion:`*`,import:!1}},luxon:{name:`luxon`,version:void 0,scope:[`default`],loaded:!1,from:`maps`,async get(){throw Error(`[Module Federation] Shared module 'luxon' must be provided by host`)},shareConfig:{singleton:!0,requiredVersion:`*`,import:!1}},pinia:{name:`pinia`,version:void 0,scope:[`default`],loaded:!1,from:`maps`,async get(){throw Error(`[Module Federation] Shared module 'pinia' must be provided by host`)},shareConfig:{singleton:!0,requiredVersion:`*`,import:!1}},vue:{name:`vue`,version:void 0,scope:[`default`],loaded:!1,from:`maps`,async get(){throw Error(`[Module Federation] Shared module 'vue' must be provided by host`)},shareConfig:{singleton:!0,requiredVersion:`*`,import:!1}},"vue3-gettext":{name:`vue3-gettext`,version:void 0,scope:[`default`],loaded:!1,from:`maps`,async get(){throw Error(`[Module Federation] Shared module 'vue3-gettext' must be provided by host`)},shareConfig:{singleton:!0,requiredVersion:`*`,import:!1}}},t=[];export{t as usedRemotes,e as usedShared};

View File

@@ -1 +0,0 @@
import"./dist-r7AkbZvS.mjs";var e={"@opencloud-eu/web-client":{name:`@opencloud-eu/web-client`,version:void 0,scope:[`default`],loaded:!1,from:`maps`,async get(){throw Error(`[Module Federation] Shared module '@opencloud-eu/web-client' must be provided by host`)},shareConfig:{singleton:!0,requiredVersion:`*`,import:!1}},"@opencloud-eu/web-client/graph":{name:`@opencloud-eu/web-client/graph`,version:void 0,scope:[`default`],loaded:!1,from:`maps`,async get(){throw Error(`[Module Federation] Shared module '@opencloud-eu/web-client/graph' must be provided by host`)},shareConfig:{singleton:!0,requiredVersion:`*`,import:!1}},"@opencloud-eu/web-client/graph/generated":{name:`@opencloud-eu/web-client/graph/generated`,version:void 0,scope:[`default`],loaded:!1,from:`maps`,async get(){throw Error(`[Module Federation] Shared module '@opencloud-eu/web-client/graph/generated' must be provided by host`)},shareConfig:{singleton:!0,requiredVersion:`*`,import:!1}},"@opencloud-eu/web-client/ocs":{name:`@opencloud-eu/web-client/ocs`,version:void 0,scope:[`default`],loaded:!1,from:`maps`,async get(){throw Error(`[Module Federation] Shared module '@opencloud-eu/web-client/ocs' must be provided by host`)},shareConfig:{singleton:!0,requiredVersion:`*`,import:!1}},"@opencloud-eu/web-client/sse":{name:`@opencloud-eu/web-client/sse`,version:void 0,scope:[`default`],loaded:!1,from:`maps`,async get(){throw Error(`[Module Federation] Shared module '@opencloud-eu/web-client/sse' must be provided by host`)},shareConfig:{singleton:!0,requiredVersion:`*`,import:!1}},"@opencloud-eu/web-client/webdav":{name:`@opencloud-eu/web-client/webdav`,version:void 0,scope:[`default`],loaded:!1,from:`maps`,async get(){throw Error(`[Module Federation] Shared module '@opencloud-eu/web-client/webdav' must be provided by host`)},shareConfig:{singleton:!0,requiredVersion:`*`,import:!1}},"@opencloud-eu/web-pkg":{name:`@opencloud-eu/web-pkg`,version:void 0,scope:[`default`],loaded:!1,from:`maps`,async get(){throw Error(`[Module Federation] Shared module '@opencloud-eu/web-pkg' must be provided by host`)},shareConfig:{singleton:!0,requiredVersion:`*`,import:!1}},luxon:{name:`luxon`,version:void 0,scope:[`default`],loaded:!1,from:`maps`,async get(){throw Error(`[Module Federation] Shared module 'luxon' must be provided by host`)},shareConfig:{singleton:!0,requiredVersion:`*`,import:!1}},pinia:{name:`pinia`,version:void 0,scope:[`default`],loaded:!1,from:`maps`,async get(){throw Error(`[Module Federation] Shared module 'pinia' must be provided by host`)},shareConfig:{singleton:!0,requiredVersion:`*`,import:!1}},vue:{name:`vue`,version:void 0,scope:[`default`],loaded:!1,from:`maps`,async get(){throw Error(`[Module Federation] Shared module 'vue' must be provided by host`)},shareConfig:{singleton:!0,requiredVersion:`*`,import:!1}},"vue3-gettext":{name:`vue3-gettext`,version:void 0,scope:[`default`],loaded:!1,from:`maps`,async get(){throw Error(`[Module Federation] Shared module 'vue3-gettext' must be provided by host`)},shareConfig:{singleton:!0,requiredVersion:`*`,import:!1}}},t=[];export{t as usedRemotes,e as usedShared};

View File

@@ -1 +0,0 @@
import{t as e}from"./src-CIfRBuLG.mjs";export{e as default};

View File

@@ -0,0 +1 @@
import{t as e}from"./src-Bjkk5jHv.mjs";export{e as default};

View File

@@ -0,0 +1 @@
var e=function(e,t){return new URL(e,t).href},t={},n=function(n,r,i){let a=Promise.resolve();if(r&&r.length>0){let n=document.getElementsByTagName(`link`),o=document.querySelector(`meta[property=csp-nonce]`),s=o?.nonce||o?.getAttribute(`nonce`);function c(e){return Promise.all(e.map(e=>Promise.resolve(e).then(e=>({status:`fulfilled`,value:e}),e=>({status:`rejected`,reason:e}))))}function l(e){return import.meta.resolve?import.meta.resolve(e):new URL(e,new URL(`../../../src/node/plugins/importAnalysisBuild.ts`,import.meta.url)).href}a=c(r.map(r=>{if(r=e(r,i),r=l(r),r in t)return;t[r]=!0;let a=r.endsWith(`.css`);for(let e=n.length-1;e>=0;e--){let t=n[e];if(t.href===r&&(!a||t.rel===`stylesheet`))return}let o=document.createElement(`link`);if(o.rel=a?`stylesheet`:`modulepreload`,a||(o.as=`script`),o.crossOrigin=``,o.href=r,s&&o.setAttribute(`nonce`,s),document.head.appendChild(o),a)return new Promise((e,t)=>{o.addEventListener(`load`,e),o.addEventListener(`error`,()=>t(Error(`Unable to preload CSS for ${r}`)))})}))}function o(e){let t=new Event(`vite:preloadError`,{cancelable:!0});if(t.payload=e,window.dispatchEvent(t),!t.defaultPrevented)throw e}return a.then(e=>{for(let t of e||[])t.status===`rejected`&&o(t.reason);return n().catch(o)})};export{n as t};

View File

@@ -1 +0,0 @@
var e=`modulepreload`,t=function(e,t){return new URL(e,t).href},n={},r=function(r,i,a){let o=Promise.resolve();if(i&&i.length>0){let r=document.getElementsByTagName(`link`),s=document.querySelector(`meta[property=csp-nonce]`),c=s?.nonce||s?.getAttribute(`nonce`);function l(e){return Promise.all(e.map(e=>Promise.resolve(e).then(e=>({status:`fulfilled`,value:e}),e=>({status:`rejected`,reason:e}))))}o=l(i.map(i=>{if(i=t(i,a),i in n)return;n[i]=!0;let o=i.endsWith(`.css`),s=o?`[rel="stylesheet"]`:``;if(a)for(let e=r.length-1;e>=0;e--){let t=r[e];if(t.href===i&&(!o||t.rel===`stylesheet`))return}else if(document.querySelector(`link[href="${i}"]${s}`))return;let l=document.createElement(`link`);if(l.rel=o?`stylesheet`:e,o||(l.as=`script`),l.crossOrigin=``,l.href=i,c&&l.setAttribute(`nonce`,c),document.head.appendChild(l),o)return new Promise((e,t)=>{l.addEventListener(`load`,e),l.addEventListener(`error`,()=>t(Error(`Unable to preload CSS for ${i}`)))})}))}function s(e){let t=new Event(`vite:preloadError`,{cancelable:!0});if(t.payload=e,window.dispatchEvent(t),!t.defaultPrevented)throw e}return o.then(e=>{for(let t of e||[])t.status===`rejected`&&s(t.reason);return r().catch(s)})};export{r as t};

View File

@@ -1,2 +1,2 @@
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["./localSharedImportMap-CALnqYrs.mjs","./dist-r7AkbZvS.mjs","./preload-helper-DafEc2pQ.mjs","./virtualExposes-CZMUMkHF.mjs"])))=>i.map(i=>d[i]); const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["./localSharedImportMap-BrxIqYlq.mjs","./dist-CXnzN4cY.mjs","./preload-helper-DYl5dUZ5.mjs","./virtualExposes-BsjVAkf0.mjs"])))=>i.map(i=>d[i]);
import{t as e}from"./dist-r7AkbZvS.mjs";import{t}from"./preload-helper-DafEc2pQ.mjs";typeof __VUE_HMR_RUNTIME__>`u`&&(globalThis.__VUE_HMR_RUNTIME__={createRecord(){},rerender(){},reload(){}});var n=`__mf_init____mf__virtual/maps__mf_v__runtimeInit__mf_v__.js__`,r=globalThis[n];if(!r){let e,t,i=new Promise((n,r)=>{e=n,t=r});r=globalThis[n]={initPromise:i,initResolve:e,initReject:t},typeof window>`u`&&e({loadRemote:function(){return Promise.resolve(void 0)},loadShare:function(){return Promise.resolve(void 0)}})}var i=r.initResolve,a={},o=`default`,s=`maps`,c,l;async function u(){return c??=t(()=>import(`./localSharedImportMap-CALnqYrs.mjs`),__vite__mapDeps([0,1,2]),import.meta.url),c}async function d(){return l??=t(()=>import(`./virtualExposes-CZMUMkHF.mjs`).then(e=>e.default??e),__vite__mapDeps([3,2]),import.meta.url),l}async function f(t={},n=[]){let{usedShared:r,usedRemotes:c}=await u(),l=e({name:s,remotes:c,shared:r,plugins:[],shareStrategy:`version-first`});var d=a[o];if(d||=a[o]={from:s},!(n.indexOf(d)>=0)){n.push(d),l.initShareScopeMap(`default`,t),i(l);try{await Promise.all(await l.initializeSharing(`default`,{strategy:`version-first`,from:`build`,initScope:n}))}catch(e){console.error(`[Module Federation]`,e)}return l}}async function p(e){let t=await d();if(!(e in t))throw Error(`[Module Federation] Module ${e} does not exist in container.`);return t[e]().then(e=>()=>e)}export{p as get,f as init}; import{t as e}from"./dist-CXnzN4cY.mjs";import{t}from"./preload-helper-DYl5dUZ5.mjs";typeof __VUE_HMR_RUNTIME__>`u`&&(globalThis.__VUE_HMR_RUNTIME__={createRecord(){},rerender(){},reload(){}});var n=`__mf_init____mf__virtual/maps__mf_v__runtimeInit__mf_v__.js__`,r=globalThis[n];if(!r){let e,t,i=new Promise((n,r)=>{e=n,t=r});r=globalThis[n]={initPromise:i,initResolve:e,initReject:t},typeof window>`u`&&e({loadRemote:function(){return Promise.resolve(void 0)},loadShare:function(){return Promise.resolve(void 0)}})}var i=r.initResolve,a={},o=`default`,s=`maps`,c,l;async function u(){return c??=t(()=>import(`./localSharedImportMap-BrxIqYlq.mjs`),__vite__mapDeps([0,1,2]),import.meta.url),c}async function d(){return l??=t(()=>import(`./virtualExposes-BsjVAkf0.mjs`).then(e=>e.default??e),__vite__mapDeps([3,2]),import.meta.url),l}async function f(t={},n=[]){let{usedShared:r,usedRemotes:c}=await u(),l=e({name:s,remotes:c,shared:r,plugins:[],shareStrategy:`version-first`});var d=a[o];if(d||=a[o]={from:s},!(n.indexOf(d)>=0)){n.push(d),l.initShareScopeMap(`default`,t),i(l);try{await Promise.all(await l.initializeSharing(`default`,{strategy:`version-first`,from:`build`,initScope:n}))}catch(e){console.error(`[Module Federation]`,e)}return l}}async function p(e){let t=await d();if(!(e in t))throw Error(`[Module Federation] Module ${e} does not exist in container.`);return t[e]().then(e=>()=>e)}export{p as get,f as init};

View File

@@ -1 +0,0 @@
var e=Object.create,t=Object.defineProperty,n=Object.getOwnPropertyDescriptor,r=Object.getOwnPropertyNames,i=Object.getPrototypeOf,a=Object.prototype.hasOwnProperty,o=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports),s=(e,i,o,s)=>{if(i&&typeof i==`object`||typeof i==`function`)for(var c=r(i),l=0,u=c.length,d;l<u;l++)d=c[l],!a.call(e,d)&&d!==o&&t(e,d,{get:(e=>i[e]).bind(null,d),enumerable:!(s=n(i,d))||s.enumerable});return e},c=(n,r,a)=>(a=n==null?{}:e(i(n)),s(r||!n||!n.__esModule?t(a,`default`,{value:n,enumerable:!0}):a,n));export{c as n,o as t};

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1 +0,0 @@
import{t as e}from"./src-CIfRBuLG.mjs";export{e as default};

View File

@@ -0,0 +1 @@
import{t as e}from"./src-Bjkk5jHv.mjs";export{e as default};

View File

@@ -1,2 +1,2 @@
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["../assets/src-D755RU42.css"])))=>i.map(i=>d[i]); const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["../assets/src-CNZX96BL.css"])))=>i.map(i=>d[i]);
import{t as e}from"./preload-helper-DafEc2pQ.mjs";var t={},n=new Set;async function r(e){if(typeof document>`u`)return;let r=t[e]||[];await Promise.all(r.map(e=>{let t=new URL(e,import.meta.url).href;return n.has(t)||(n.add(t),document.querySelector(`link[rel="stylesheet"][data-mf-href="${t}"]`))?Promise.resolve():new Promise((e,n)=>{let r=document.createElement(`link`);r.rel=`stylesheet`,r.href=t,r.setAttribute(`data-mf-href`,t),r.onload=()=>e(),r.onerror=()=>n(Error(`[Module Federation] Failed to load CSS asset: ${t}`)),document.head.appendChild(r)})}))}var i={".":async()=>{await r(`.`);let t=await e(()=>import(`./maps-BAf8IhJ5.mjs`),__vite__mapDeps([0]),import.meta.url),n={};return Object.assign(n,t),Object.defineProperty(n,`__esModule`,{value:!0,enumerable:!1}),n}};export{i as default}; import{t as e}from"./preload-helper-DYl5dUZ5.mjs";var t={},n=new Set;async function r(e){if(typeof document>`u`)return;let r=t[e]||[];await Promise.all(r.map(e=>{let t=new URL(e,import.meta.url).href;return n.has(t)||(n.add(t),document.querySelector(`link[rel="stylesheet"][data-mf-href="${t}"]`))?Promise.resolve():new Promise((e,n)=>{let r=document.createElement(`link`);r.rel=`stylesheet`,r.href=t,r.setAttribute(`data-mf-href`,t),r.onload=()=>e(),r.onerror=()=>n(Error(`[Module Federation] Failed to load CSS asset: ${t}`)),document.head.appendChild(r)})}))}var i={".":async()=>{await r(`.`);let t=await e(()=>import(`./maps-z34tTD6Z.mjs`),__vite__mapDeps([0]),import.meta.url),n={};return Object.assign(n,t),Object.defineProperty(n,"__esModule",{value:!0,enumerable:!1}),n}};export{i as default};

View File

@@ -1,3 +1,7 @@
{ {
"entrypoint": "js/remoteEntry-lxWu31Tr.mjs" "name": "web-app-maps",
} "version": "3.1.0",
"description": "OpenCloud Web Maps",
"license": "AGPL-3.0",
"entrypoint": "js/remoteEntry-BXGAhFe2.mjs"
}

View File

@@ -49,6 +49,7 @@ directives:
style-src: style-src:
- '''self''' - '''self'''
- '''unsafe-inline''' - '''unsafe-inline'''
- 'blob:'
worker-src: worker-src:
- "'self'" - "'self'"
- 'blob:' - 'blob:'

View File

@@ -1,6 +1,10 @@
# This adds four additional routes to the proxy. Forwarding # This adds four additional routes to the proxy, forwarding requests
# request on '/carddav/', '/caldav/' and the respective '/.well-knwown' # on '/caldav/', '/carddav/' and the respective '/.well-known'
# endpoints to the radicale container and setting the required headers. # endpoints to the radicale container and setting the required headers.
#
# Client URLs (trailing slash required, see radicale/README.md):
# CalDAV: https://<your-domain>/caldav/
# CardDAV: https://<your-domain>/carddav/
additional_policies: additional_policies:
- name: default - name: default
routes: routes:
@@ -10,10 +14,15 @@ additional_policies:
skip_x_access_token: true skip_x_access_token: true
additional_headers: additional_headers:
- X-Script-Name: /caldav - X-Script-Name: /caldav
# The '.well-known' endpoints are 'unprotected' so that DAV clients
# can discover the CalDAV/CardDAV URLs (RFC 6764) before they
# authenticate. Radicale only ever answers these paths with a 301
# redirect to '/caldav/' or '/carddav/' and serves no data here
# (deeper paths return 404), so no authentication is required.
- endpoint: /.well-known/caldav - endpoint: /.well-known/caldav
backend: http://radicale:5232 backend: http://radicale:5232
remote_user_header: X-Remote-User
skip_x_access_token: true skip_x_access_token: true
unprotected: true
additional_headers: additional_headers:
- X-Script-Name: /caldav - X-Script-Name: /caldav
- endpoint: /carddav/ - endpoint: /carddav/
@@ -24,8 +33,8 @@ additional_policies:
- X-Script-Name: /carddav - X-Script-Name: /carddav
- endpoint: /.well-known/carddav - endpoint: /.well-known/carddav
backend: http://radicale:5232 backend: http://radicale:5232
remote_user_header: X-Remote-User
skip_x_access_token: true skip_x_access_token: true
unprotected: true
additional_headers: additional_headers:
- X-Script-Name: /carddav - X-Script-Name: /carddav
# To enable the radicale web UI add this rule. # To enable the radicale web UI add this rule.

View File

@@ -2,7 +2,7 @@
services: services:
opencloud: opencloud:
# renovate: depName=opencloudeu/opencloud-rolling # renovate: depName=opencloudeu/opencloud-rolling
image: ${OC_DOCKER_IMAGE:-opencloudeu/opencloud-rolling}:${OC_DOCKER_TAG:-6.2.0} image: ${OC_DOCKER_IMAGE:-opencloudeu/opencloud-rolling}:${OC_DOCKER_TAG:-7.5.0}
# changelog: https://github.com/opencloud-eu/opencloud/tree/main/changelog # changelog: https://github.com/opencloud-eu/opencloud/tree/main/changelog
# release notes: https://docs.opencloud.eu/opencloud_release_notes.html # release notes: https://docs.opencloud.eu/opencloud_release_notes.html
user: ${OC_CONTAINER_UID_GID:-1000:1000} user: ${OC_CONTAINER_UID_GID:-1000:1000}
@@ -58,6 +58,7 @@ services:
OC_DEFAULT_LANGUAGE: ${DEFAULT_LANGUAGE} OC_DEFAULT_LANGUAGE: ${DEFAULT_LANGUAGE}
volumes: volumes:
- ./config/opencloud/csp.yaml:/etc/opencloud/csp.yaml - ./config/opencloud/csp.yaml:/etc/opencloud/csp.yaml
- ./config/opencloud/apps.yaml:/etc/opencloud/apps.yaml
- ./config/opencloud/banned-password-list.txt:/etc/opencloud/banned-password-list.txt - ./config/opencloud/banned-password-list.txt:/etc/opencloud/banned-password-list.txt
# configure the .env file to use own paths instead of docker internal volumes # configure the .env file to use own paths instead of docker internal volumes
- ${OC_CONFIG_DIR:-opencloud-config}:/etc/opencloud - ${OC_CONFIG_DIR:-opencloud-config}:/etc/opencloud

View File

@@ -1,9 +1,9 @@
--- ---
services: services:
opencloud: opencloud:
environment: environment:
# bind to all interfaces # bind to all interfaces
PROXY_HTTP_ADDR: "0.0.0.0:9200" PROXY_HTTP_ADDR: "0.0.0.0:9200"
ports: ports:
# expose the opencloud server on localhost # expose the opencloud server on localhost
- "127.0.0.1:9200:9200" - "127.0.0.1:9200:9200"

View File

@@ -64,7 +64,7 @@ services:
restart: always restart: always
postgres: postgres:
image: postgres:17.10-alpine image: postgres:17.11-alpine
networks: networks:
opencloud-net: opencloud-net:
volumes: volumes:
@@ -78,7 +78,7 @@ services:
restart: always restart: always
keycloak: keycloak:
image: quay.io/keycloak/keycloak:26.6.3 image: quay.io/keycloak/keycloak:26.7.3
networks: networks:
opencloud-net: opencloud-net:
command: [ "start", "--spi-connections-http-client-default-disable-trust-manager=${INSECURE:-false}", "--import-realm" ] command: [ "start", "--spi-connections-http-client-default-disable-trust-manager=${INSECURE:-false}", "--import-realm" ]

77
radicale/README.md Normal file
View File

@@ -0,0 +1,77 @@
# Radicale — CalDAV / CardDAV
This module adds [Radicale](https://radicale.org/) as a CalDAV (calendars,
to-do lists) and CardDAV (contacts) server behind the OpenCloud proxy. Every
user gets a personal calendar and address book on first access.
## Enabling
Add `radicale/radicale.yml` to your `COMPOSE_FILE`:
```
COMPOSE_FILE=docker-compose.yml:radicale/radicale.yml:traefik/opencloud.yml
```
The routes are defined in [`config/opencloud/proxy.yaml`](../config/opencloud/proxy.yaml),
which `radicale.yml` mounts into the opencloud container.
## Connecting clients
### URLs
| Service | URL |
|---|---|
| CalDAV (calendar) | `https://<your-domain>/caldav/` |
| CardDAV (contacts) | `https://<your-domain>/carddav/` |
**The trailing slash is required.** `https://<your-domain>/caldav` (without
the slash) is not routed to Radicale and returns the OpenCloud web UI instead.
Clients that implement DAV service discovery (RFC 6764) can also be pointed
at the bare domain `https://<your-domain>/` — the `/.well-known/caldav` and
`/.well-known/carddav` endpoints redirect them to the URLs above. Clients
that don't (or that get confused by the web UI at the base URL) need the full
URL including the suffix.
### Authentication: use an App Token
DAV clients authenticate with **username + App Token** — not your account
password. With the default configuration (`PROXY_ENABLE_BASIC_AUTH=false`)
the account password is rejected with `401 Unauthorized`; App Tokens work out
of the box.
Create a token either
- in the web UI under **Settings → App Tokens**, or
- on the CLI:
```bash
docker compose exec opencloud opencloud auth-app create --user-name=<user> --expiration=72h
```
### GNOME Online Accounts
GNOME expects a directly answering DAV endpoint per account, so calendars and
contacts are added as two separate accounts:
1. **Settings → Online Accounts → Add Account → Calendar (CalDAV)**
— URL `https://<your-domain>/caldav/`, your username, an App Token as
password.
2. **Settings → Online Accounts → Add Account → Contacts (CardDAV)**
— URL `https://<your-domain>/carddav/`, same credentials.
### Thunderbird
- Calendar: *New Calendar → On the Network*, URL `https://<your-domain>/caldav/`
- Address book: *New Address Book → Add CardDAV Address Book*, URL
`https://<your-domain>/carddav/`
Use an App Token as the password in both dialogs.
## Troubleshooting
| Symptom | Cause |
|---|---|
| `401 Unauthorized` | Account password used instead of an App Token (or the token expired). |
| `405 Method Not Allowed` / HTML response | Trailing slash missing — the request landed on the web UI, not Radicale. |
| Client says "not a (Cal)DAV server" at the base URL | The client doesn't do RFC 6764 discovery. Use the full `/caldav/` / `/carddav/` URL. |

View File

@@ -1,8 +1,9 @@
{ {
"$schema": "https://docs.renovatebot.com/renovate-schema.json", "$schema": "https://docs.renovatebot.com/renovate-schema.json",
"dependencyDashboard": true,
"platformAutomerge": true, "platformAutomerge": true,
"enabledManagers": ["docker-compose", "custom.regex"], "enabledManagers": ["docker-compose", "custom.regex"],
"baseBranchPatterns": ["main", "stable-4.0"], "baseBranchPatterns": ["main", "stable-4.0", "stable-7.2"],
"packageRules": [ "packageRules": [
{ {
"matchManagers": ["docker-compose", "custom.regex"], "matchManagers": ["docker-compose", "custom.regex"],
@@ -14,7 +15,7 @@
"automerge": true "automerge": true
}, },
{ {
"matchBaseBranches": ["stable-4.0"], "matchBaseBranches": ["stable-4.0", "stable-7.2"],
"matchUpdateTypes": ["major", "minor"], "matchUpdateTypes": ["major", "minor"],
"enabled": false "enabled": false
}, },

View File

@@ -1,7 +1,7 @@
--- ---
services: services:
postgres: postgres:
image: postgres:17.10-alpine image: postgres:17.11-alpine
networks: networks:
opencloud-net: opencloud-net:
volumes: volumes:
@@ -15,7 +15,7 @@ services:
restart: always restart: always
keycloak: keycloak:
image: quay.io/keycloak/keycloak:26.6.3 image: quay.io/keycloak/keycloak:26.7.3
networks: networks:
opencloud-net: opencloud-net:
command: [ "start", "--spi-connections-http-client-default-disable-trust-manager=${INSECURE:-false}", "--import-realm" ] command: [ "start", "--spi-connections-http-client-default-disable-trust-manager=${INSECURE:-false}", "--import-realm" ]

View File

@@ -16,7 +16,7 @@ services:
- "traefik.http.services.opencloud.loadbalancer.server.port=9200" - "traefik.http.services.opencloud.loadbalancer.server.port=9200"
- "traefik.http.routers.opencloud.${TRAEFIK_SERVICES_TLS_CONFIG}" - "traefik.http.routers.opencloud.${TRAEFIK_SERVICES_TLS_CONFIG}"
traefik: traefik:
image: traefik:v3.6.14 image: traefik:v3.7.12
# release notes: https://github.com/traefik/traefik/releases # release notes: https://github.com/traefik/traefik/releases
user: ${TRAEFIK_CONTAINER_UID_GID:-0:0} user: ${TRAEFIK_CONTAINER_UID_GID:-0:0}
networks: networks:

View File

@@ -23,22 +23,50 @@ services:
COLLABORATION_APP_INSECURE: "${INSECURE:-true}" COLLABORATION_APP_INSECURE: "${INSECURE:-true}"
COLLABORATION_CS3API_DATAGATEWAY_INSECURE: "${INSECURE:-true}" COLLABORATION_CS3API_DATAGATEWAY_INSECURE: "${INSECURE:-true}"
# One-shot service that generates the WOPI proof key on first start and
# keeps it in a named volume, like the proofKeyGeneration feature of the
# collabora-online helm chart.
# To rotate the key, remove the volume and start again:
# docker compose down collabora && docker volume rm <project>_collabora-proof-key
collabora-proof-key:
image: alpine/openssl:3.5.8
entrypoint: ["/bin/sh"]
command:
- -ec
- |
if [ ! -s /proof/proof_key ]; then
openssl genrsa -traditional -out /proof/proof_key.tmp 4096
chown 1001:1001 /proof/proof_key.tmp
chmod 400 /proof/proof_key.tmp
mv /proof/proof_key.tmp /proof/proof_key
echo "WOPI proof key generated"
else
echo "WOPI proof key already exists"
fi
volumes:
- collabora-proof-key:/proof
logging:
driver: ${LOG_DRIVER:-local}
restart: "no"
collabora: collabora:
image: collabora/code:26.04.1.4.1 image: collabora/code:26.04.3.1.1
# release notes: https://www.collaboraonline.com/release-notes/ # release notes: https://www.collaboraonline.com/release-notes/
networks: networks:
opencloud-net: opencloud-net:
depends_on:
collabora-proof-key:
condition: service_completed_successfully
environment: environment:
# WOPI host allowlist; the WOPI endpoint is served by the opencloud proxy on the opencloud domain # WOPI host allowlist; the WOPI endpoint is served by the opencloud proxy on the opencloud domain
aliasgroup1: https://${OC_DOMAIN:-cloud.opencloud.test}${TRAEFIK_PORT_HTTPS:+:}${TRAEFIK_PORT_HTTPS:-} aliasgroup1: https://${OC_DOMAIN:-cloud.opencloud.test}${TRAEFIK_PORT_HTTPS:+:}${TRAEFIK_PORT_HTTPS:-}
DONT_GEN_SSL_CERT: "YES" extra_params: >
extra_params: | --o:ssl.enable=${COLLABORA_SSL_ENABLE:-true}
--o:ssl.enable=${COLLABORA_SSL_ENABLE:-true} \ --o:ssl.ssl_verification=${COLLABORA_SSL_VERIFICATION:-true}
--o:ssl.ssl_verification=${COLLABORA_SSL_VERIFICATION:-true} \ --o:ssl.termination=true
--o:ssl.termination=true \ --o:welcome.enable=false
--o:welcome.enable=false \ --o:net.frame_ancestors=${OC_DOMAIN:-cloud.opencloud.test}${TRAEFIK_PORT_HTTPS:+:}${TRAEFIK_PORT_HTTPS:-}
--o:net.frame_ancestors=${OC_DOMAIN:-cloud.opencloud.test}${TRAEFIK_PORT_HTTPS:+:}${TRAEFIK_PORT_HTTPS:-} \ --o:net.lok_allow.host[14]=${OC_DOMAIN:-cloud.opencloud.test}${TRAEFIK_PORT_HTTPS:+:}${TRAEFIK_PORT_HTTPS:-}
--o:net.lok_allow.host[14]=${OC_DOMAIN:-cloud.opencloud.test}${TRAEFIK_PORT_HTTPS:+:}${TRAEFIK_PORT_HTTPS:-} \
--o:home_mode.enable=${COLLABORA_HOME_MODE:-false} --o:home_mode.enable=${COLLABORA_HOME_MODE:-false}
username: ${COLLABORA_ADMIN_USER:-admin} username: ${COLLABORA_ADMIN_USER:-admin}
password: ${COLLABORA_ADMIN_PASSWORD:-admin} password: ${COLLABORA_ADMIN_PASSWORD:-admin}
@@ -52,19 +80,24 @@ services:
# (e.g. Microsoft fonts like Arial, Calibri, Cambria by installing the `ttf-mscorefonts-installer` package). # (e.g. Microsoft fonts like Arial, Calibri, Cambria by installing the `ttf-mscorefonts-installer` package).
- /usr/share/fonts/truetype:/usr/share/fonts/truetype/more:ro - /usr/share/fonts/truetype:/usr/share/fonts/truetype/more:ro
- /usr/share/fonts/truetype:/opt/cool/systemplate/usr/share/fonts/truetype/more:ro - /usr/share/fonts/truetype:/opt/cool/systemplate/usr/share/fonts/truetype/more:ro
# WOPI proof key generated by the collabora-proof-key service.
- type: volume
source: collabora-proof-key
target: /etc/coolwsd/proof_key
read_only: true
volume:
subpath: proof_key
logging: logging:
driver: ${LOG_DRIVER:-local} driver: ${LOG_DRIVER:-local}
restart: always restart: always
entrypoint: [ '/bin/bash', '-c' ]
command: [ 'coolconfig generate-proof-key && /start-collabora-online.sh' ]
healthcheck: healthcheck:
test: # --use-env-vars makes the probe read extra_params, so it probes with
[ # the same http/https scheme the server actually runs with; without it
"CMD", # the probe falls back to coolwsd.xml where ssl.enable defaults to true
"bash", test: ["CMD", "/usr/bin/coolwsd", "--probe", "--use-env-vars"]
"-c",
"exec 3<>/dev/tcp/127.0.0.1/9980 && printf 'GET /hosting/discovery HTTP/1.1\r\nHost: localhost\r\nConnection: close\r\n\r\n' >&3 && cat <&3 | head -1 | grep -q '200 OK'"
]
interval: 15s interval: 15s
timeout: 10s timeout: 10s
retries: 5 retries: 5
volumes:
collabora-proof-key:

View File

@@ -32,6 +32,7 @@ services:
WOPI_ENABLED: "true" WOPI_ENABLED: "true"
# self-signed certificates # self-signed certificates
USE_UNAUTHORIZED_STORAGE: "${INSECURE:-false}" USE_UNAUTHORIZED_STORAGE: "${INSECURE:-false}"
JWT_SECRET: "${EURO_OFFICE_JWT_SECRET}"
volumes: volumes:
# Mount local TrueType fonts so the container can use system fonts # Mount local TrueType fonts so the container can use system fonts
# (e.g. Microsoft fonts like Arial, Calibri, Cambria by installing the `ttf-mscorefonts-installer` package). # (e.g. Microsoft fonts like Arial, Calibri, Cambria by installing the `ttf-mscorefonts-installer` package).