mirror of
https://github.com/opencloud-eu/opencloud-compose.git
synced 2026-10-07 11:28:15 +08:00
Compare commits
55 Commits
4cdb84b7f1
...
radicale-c
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4f21b38d46 | ||
|
|
442017268a | ||
|
|
b31c3943fd | ||
|
|
cb23d6af18 | ||
|
|
8a1193f2d4 | ||
|
|
18dc807be0 | ||
|
|
0fab6e73a0 | ||
|
|
871b6ae4c8 | ||
|
|
f8b24d5200 | ||
|
|
8826153af8 | ||
|
|
6ed456d3df | ||
|
|
c092407fcd | ||
|
|
8f79c17270 | ||
|
|
dc14e7e10a | ||
|
|
323b2c4aa4 | ||
|
|
887e63e8a6 | ||
|
|
a6e883bcf2 | ||
|
|
49f5ce9d52 | ||
|
|
e824bd17db | ||
|
|
1721922f52 | ||
|
|
db3ddbdf32 | ||
|
|
1fbb2380cc | ||
|
|
34129ff018 | ||
|
|
0f89106b89 | ||
|
|
2b51cb53c0 | ||
|
|
eab3b7e584 | ||
|
|
c4023ff553 | ||
|
|
aac9a1e2f5 | ||
|
|
e6a0e8e2e6 | ||
|
|
1ecdd0e32a | ||
|
|
bcf59c86fd | ||
|
|
7cd7c57bd9 | ||
|
|
213dde31c8 | ||
|
|
dabd81377c | ||
|
|
8d2d89f283 | ||
|
|
189f17f6e0 | ||
|
|
27fd367113 | ||
|
|
fffcec12a8 | ||
|
|
42b4343d6e | ||
|
|
5666410706 | ||
|
|
62131f972b | ||
|
|
274195c6ad | ||
|
|
49ba000f6e | ||
|
|
d759e5a332 | ||
|
|
d7fcd3da64 | ||
|
|
325dce2f53 | ||
|
|
0221cfd91b | ||
|
|
c096f66dfd | ||
|
|
e6d987501e | ||
|
|
2f81c5f62c | ||
|
|
670d978c1c | ||
|
|
d952c2849b | ||
|
|
13b9489c52 | ||
|
|
e8b8511477 | ||
|
|
70e7679bc3 |
@@ -215,6 +215,11 @@ This setup includes:
|
||||
- Radicale as a CalDAV (calendars, to-do lists) and CardDAV (contacts) server
|
||||
- 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
|
||||
|
||||
Enable monitoring capabilities with metrics endpoints using either method:
|
||||
|
||||
@@ -4,24 +4,18 @@
|
||||
--pf-v5-global--primary-color--dark-100: #e2baff;
|
||||
--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-family: OpenCloud;
|
||||
src: url('../fonts/OpenCloud500-Regular.woff2') format('woff2');
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: OpenCloud;
|
||||
src: url('../fonts/OpenCloud750-Bold.woff2') format('woff2');
|
||||
font-weight: bold;
|
||||
font-family: Inter;
|
||||
src: url('../fonts/Inter-Variable.woff2') format('woff2');
|
||||
font-weight: 100 900;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: "OpenCloud", "Open Sans", Helvetica, Arial, sans-serif;
|
||||
background: url(../img/background.png) no-repeat center fixed !important;
|
||||
background-size: cover !important;
|
||||
}
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
3
config/opencloud/apps.yaml
Normal file
3
config/opencloud/apps.yaml
Normal file
@@ -0,0 +1,3 @@
|
||||
maps:
|
||||
config:
|
||||
folderViewEnabled: false
|
||||
2
config/opencloud/apps/maps/assets/src-CNZX96BL.css
Normal file
2
config/opencloud/apps/maps/assets/src-CNZX96BL.css
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
1
config/opencloud/apps/maps/js/hostInit-C_d58ZzI.mjs
Normal file
1
config/opencloud/apps/maps/js/hostInit-C_d58ZzI.mjs
Normal file
@@ -0,0 +1 @@
|
||||
import{t as e}from"./preload-helper-DYl5dUZ5.mjs";await(await e(()=>import(`./remoteEntry-BXGAhFe2.mjs`),[],import.meta.url)).init();
|
||||
@@ -1 +0,0 @@
|
||||
import{t as e}from"./preload-helper-DafEc2pQ.mjs";await(await e(()=>import(`./remoteEntry-lxWu31Tr.mjs`),[],import.meta.url)).init();
|
||||
@@ -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};
|
||||
@@ -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};
|
||||
@@ -1 +0,0 @@
|
||||
import{t as e}from"./src-CIfRBuLG.mjs";export{e as default};
|
||||
1
config/opencloud/apps/maps/js/maps-z34tTD6Z.mjs
Normal file
1
config/opencloud/apps/maps/js/maps-z34tTD6Z.mjs
Normal file
@@ -0,0 +1 @@
|
||||
import{t as e}from"./src-Bjkk5jHv.mjs";export{e as default};
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -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};
|
||||
@@ -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};
|
||||
@@ -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]);
|
||||
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};
|
||||
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-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};
|
||||
@@ -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};
|
||||
825
config/opencloud/apps/maps/js/src-Bjkk5jHv.mjs
Normal file
825
config/opencloud/apps/maps/js/src-Bjkk5jHv.mjs
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1 +0,0 @@
|
||||
import{t as e}from"./src-CIfRBuLG.mjs";export{e as default};
|
||||
1
config/opencloud/apps/maps/js/src-z34tTD6Z.mjs
Normal file
1
config/opencloud/apps/maps/js/src-z34tTD6Z.mjs
Normal file
@@ -0,0 +1 @@
|
||||
import{t as e}from"./src-Bjkk5jHv.mjs";export{e as default};
|
||||
@@ -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]);
|
||||
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};
|
||||
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-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};
|
||||
@@ -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"
|
||||
}
|
||||
@@ -49,6 +49,7 @@ directives:
|
||||
style-src:
|
||||
- '''self'''
|
||||
- '''unsafe-inline'''
|
||||
- 'blob:'
|
||||
worker-src:
|
||||
- "'self'"
|
||||
- 'blob:'
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
# This adds four additional routes to the proxy. Forwarding
|
||||
# request on '/carddav/', '/caldav/' and the respective '/.well-knwown'
|
||||
# This adds four additional routes to the proxy, forwarding requests
|
||||
# on '/caldav/', '/carddav/' and the respective '/.well-known'
|
||||
# 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:
|
||||
- name: default
|
||||
routes:
|
||||
@@ -10,10 +14,15 @@ additional_policies:
|
||||
skip_x_access_token: true
|
||||
additional_headers:
|
||||
- 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
|
||||
backend: http://radicale:5232
|
||||
remote_user_header: X-Remote-User
|
||||
skip_x_access_token: true
|
||||
unprotected: true
|
||||
additional_headers:
|
||||
- X-Script-Name: /caldav
|
||||
- endpoint: /carddav/
|
||||
@@ -24,8 +33,8 @@ additional_policies:
|
||||
- X-Script-Name: /carddav
|
||||
- endpoint: /.well-known/carddav
|
||||
backend: http://radicale:5232
|
||||
remote_user_header: X-Remote-User
|
||||
skip_x_access_token: true
|
||||
unprotected: true
|
||||
additional_headers:
|
||||
- X-Script-Name: /carddav
|
||||
# To enable the radicale web UI add this rule.
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
services:
|
||||
opencloud:
|
||||
# renovate: depName=opencloudeu/opencloud-rolling
|
||||
image: ${OC_DOCKER_IMAGE:-opencloudeu/opencloud-rolling}:${OC_DOCKER_TAG:-7.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
|
||||
# release notes: https://docs.opencloud.eu/opencloud_release_notes.html
|
||||
user: ${OC_CONTAINER_UID_GID:-1000:1000}
|
||||
@@ -58,6 +58,7 @@ services:
|
||||
OC_DEFAULT_LANGUAGE: ${DEFAULT_LANGUAGE}
|
||||
volumes:
|
||||
- ./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
|
||||
# configure the .env file to use own paths instead of docker internal volumes
|
||||
- ${OC_CONFIG_DIR:-opencloud-config}:/etc/opencloud
|
||||
|
||||
@@ -64,7 +64,7 @@ services:
|
||||
restart: always
|
||||
|
||||
postgres:
|
||||
image: postgres:17.10-alpine
|
||||
image: postgres:17.11-alpine
|
||||
networks:
|
||||
opencloud-net:
|
||||
volumes:
|
||||
@@ -78,7 +78,7 @@ services:
|
||||
restart: always
|
||||
|
||||
keycloak:
|
||||
image: quay.io/keycloak/keycloak:26.6.4
|
||||
image: quay.io/keycloak/keycloak:26.7.3
|
||||
networks:
|
||||
opencloud-net:
|
||||
command: [ "start", "--spi-connections-http-client-default-disable-trust-manager=${INSECURE:-false}", "--import-realm" ]
|
||||
|
||||
77
radicale/README.md
Normal file
77
radicale/README.md
Normal 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. |
|
||||
@@ -1,8 +1,9 @@
|
||||
{
|
||||
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
|
||||
"dependencyDashboard": true,
|
||||
"platformAutomerge": true,
|
||||
"enabledManagers": ["docker-compose", "custom.regex"],
|
||||
"baseBranchPatterns": ["main", "stable-4.0"],
|
||||
"baseBranchPatterns": ["main", "stable-4.0", "stable-7.2"],
|
||||
"packageRules": [
|
||||
{
|
||||
"matchManagers": ["docker-compose", "custom.regex"],
|
||||
@@ -14,7 +15,7 @@
|
||||
"automerge": true
|
||||
},
|
||||
{
|
||||
"matchBaseBranches": ["stable-4.0"],
|
||||
"matchBaseBranches": ["stable-4.0", "stable-7.2"],
|
||||
"matchUpdateTypes": ["major", "minor"],
|
||||
"enabled": false
|
||||
},
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
---
|
||||
services:
|
||||
postgres:
|
||||
image: postgres:17.10-alpine
|
||||
image: postgres:17.11-alpine
|
||||
networks:
|
||||
opencloud-net:
|
||||
volumes:
|
||||
@@ -15,7 +15,7 @@ services:
|
||||
restart: always
|
||||
|
||||
keycloak:
|
||||
image: quay.io/keycloak/keycloak:26.6.4
|
||||
image: quay.io/keycloak/keycloak:26.7.3
|
||||
networks:
|
||||
opencloud-net:
|
||||
command: [ "start", "--spi-connections-http-client-default-disable-trust-manager=${INSECURE:-false}", "--import-realm" ]
|
||||
|
||||
@@ -16,7 +16,7 @@ services:
|
||||
- "traefik.http.services.opencloud.loadbalancer.server.port=9200"
|
||||
- "traefik.http.routers.opencloud.${TRAEFIK_SERVICES_TLS_CONFIG}"
|
||||
traefik:
|
||||
image: traefik:v3.6.14
|
||||
image: traefik:v3.7.12
|
||||
# release notes: https://github.com/traefik/traefik/releases
|
||||
user: ${TRAEFIK_CONTAINER_UID_GID:-0:0}
|
||||
networks:
|
||||
|
||||
@@ -23,22 +23,50 @@ services:
|
||||
COLLABORATION_APP_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:
|
||||
image: collabora/code:26.04.1.4.1
|
||||
image: collabora/code:26.04.3.1.1
|
||||
# release notes: https://www.collaboraonline.com/release-notes/
|
||||
networks:
|
||||
opencloud-net:
|
||||
depends_on:
|
||||
collabora-proof-key:
|
||||
condition: service_completed_successfully
|
||||
environment:
|
||||
# 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:-}
|
||||
DONT_GEN_SSL_CERT: "YES"
|
||||
extra_params: |
|
||||
--o:ssl.enable=${COLLABORA_SSL_ENABLE:-true} \
|
||||
--o:ssl.ssl_verification=${COLLABORA_SSL_VERIFICATION:-true} \
|
||||
--o:ssl.termination=true \
|
||||
--o:welcome.enable=false \
|
||||
--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:-} \
|
||||
extra_params: >
|
||||
--o:ssl.enable=${COLLABORA_SSL_ENABLE:-true}
|
||||
--o:ssl.ssl_verification=${COLLABORA_SSL_VERIFICATION:-true}
|
||||
--o:ssl.termination=true
|
||||
--o:welcome.enable=false
|
||||
--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:home_mode.enable=${COLLABORA_HOME_MODE:-false}
|
||||
username: ${COLLABORA_ADMIN_USER:-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).
|
||||
- /usr/share/fonts/truetype:/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:
|
||||
driver: ${LOG_DRIVER:-local}
|
||||
restart: always
|
||||
entrypoint: [ '/bin/bash', '-c' ]
|
||||
command: [ 'coolconfig generate-proof-key && /start-collabora-online.sh' ]
|
||||
healthcheck:
|
||||
test:
|
||||
[
|
||||
"CMD",
|
||||
"bash",
|
||||
"-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'"
|
||||
]
|
||||
# --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
|
||||
# the probe falls back to coolwsd.xml where ssl.enable defaults to true
|
||||
test: ["CMD", "/usr/bin/coolwsd", "--probe", "--use-env-vars"]
|
||||
interval: 15s
|
||||
timeout: 10s
|
||||
retries: 5
|
||||
|
||||
volumes:
|
||||
collabora-proof-key:
|
||||
|
||||
@@ -32,6 +32,7 @@ services:
|
||||
WOPI_ENABLED: "true"
|
||||
# self-signed certificates
|
||||
USE_UNAUTHORIZED_STORAGE: "${INSECURE:-false}"
|
||||
JWT_SECRET: "${EURO_OFFICE_JWT_SECRET}"
|
||||
volumes:
|
||||
# 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).
|
||||
|
||||
Reference in New Issue
Block a user