From dec8de7f50df2dbf5f34b4de420ca834d97884b2 Mon Sep 17 00:00:00 2001
From: Robert Bill <147130488+RobSlgm@users.noreply.github.com>
Date: Fri, 17 Jul 2026 08:36:45 +0200
Subject: [PATCH 1/3] Update dependencies
---
Data/Data.csproj | 28 ++++++++++++++--------------
Data/erm.sql | 4 ++--
Server.Tests/Server.Tests.csproj | 2 +-
openapi.json | 2 +-
4 files changed, 18 insertions(+), 18 deletions(-)
diff --git a/Data/Data.csproj b/Data/Data.csproj
index d3f8889..398b8d3 100644
--- a/Data/Data.csproj
+++ b/Data/Data.csproj
@@ -9,23 +9,23 @@
e9f8dafb-10db-45a2-b53a-f8cdf43eab5e
-
-
+
+
runtime; build; native; contentfiles; analyzers; buildtransitive
all
-
-
+
+
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Data/erm.sql b/Data/erm.sql
index 92ac80c..962f379 100644
--- a/Data/erm.sql
+++ b/Data/erm.sql
@@ -567,7 +567,7 @@ DO $EF$
BEGIN
IF NOT EXISTS(SELECT 1 FROM "__EFMigrationsHistory" WHERE "migration_id" = '20250425070016_CreateInitial') THEN
INSERT INTO "__EFMigrationsHistory" (migration_id, product_version)
- VALUES ('20250425070016_CreateInitial', '10.0.8');
+ VALUES ('20250425070016_CreateInitial', '10.0.10');
END IF;
END $EF$;
COMMIT;
@@ -661,7 +661,7 @@ DO $EF$
BEGIN
IF NOT EXISTS(SELECT 1 FROM "__EFMigrationsHistory" WHERE "migration_id" = '20260622060127_BlobItem') THEN
INSERT INTO "__EFMigrationsHistory" (migration_id, product_version)
- VALUES ('20260622060127_BlobItem', '10.0.8');
+ VALUES ('20260622060127_BlobItem', '10.0.10');
END IF;
END $EF$;
COMMIT;
diff --git a/Server.Tests/Server.Tests.csproj b/Server.Tests/Server.Tests.csproj
index 2391f1f..581137e 100644
--- a/Server.Tests/Server.Tests.csproj
+++ b/Server.Tests/Server.Tests.csproj
@@ -15,7 +15,7 @@
runtime; build; native; contentfiles; analyzers; buildtransitive
all
-
+
runtime; build; native; contentfiles; analyzers; buildtransitive
diff --git a/openapi.json b/openapi.json
index f5d179a..5cf9a96 100644
--- a/openapi.json
+++ b/openapi.json
@@ -10,7 +10,7 @@
"name": "MIT",
"url": "https://mit-license.org/"
},
- "version": "0.0.1"
+ "version": "0.8.0"
},
"paths": {
"/api/version": {
From cc662263833a20bee641327505d9de69be3e4bb4 Mon Sep 17 00:00:00 2001
From: Robert Bill <147130488+RobSlgm@users.noreply.github.com>
Date: Fri, 17 Jul 2026 11:48:33 +0200
Subject: [PATCH 2/3] Add webdav to readme and install instructions
---
Doc/INSTALL.md | 33 +++++++++++++++++++++++++++++++++
README.md | 3 ++-
2 files changed, 35 insertions(+), 1 deletion(-)
diff --git a/Doc/INSTALL.md b/Doc/INSTALL.md
index fd804b8..c4662af 100644
--- a/Doc/INSTALL.md
+++ b/Doc/INSTALL.md
@@ -1,6 +1,10 @@
# Install Calendare Server
- [Infrastructure requirements](#infrastructure-requirements)
+ - [Database](#database)
+ - [File storage](#file-storage)
+ - [S3 Storage Provider](#s3-storage-provider)
+ - [Local storage](#local-storage)
- [DNS](#dns)
- [Domain and subdomain](#domain-and-subdomain)
- [Base Path Configuration](#base-path-configuration)
@@ -18,8 +22,34 @@
The Calendare Server requires specific infrastructure to operate.
+## Database
+
It uses a **PostgreSQL database** for data persistence and relies on an **OIDC provider** for user authentication. These components must be managed independently and are not covered in the following server installation guide.
+The database contains user data and administrative data. The only exception relates to the WebDAV feature (file storage). The file contents are stored externally.
+
+## File storage
+
+File storage is only needed if the WebDAV feature is enabled (**not** for calendar or contact information). The default installation doesn't enable WebDAV.
+
+### S3 Storage Provider
+
+The **preferred** option is to use an external S3 provider (`provider: S3`). A dedicated bucket needs to be configured.
+
+> [!WARNING]
+> The Calendare Server requires a dedicated bucket. It will regulary **delete** all content which is not managed by the server.
+
+### Local storage
+
+The local storage (`provider: Filesystem`) requires a base path to the local file system. Using Kubernetes this means that you need to define `PersistentVolumes` and `VolumeMounts`.
+
+While local storage is supported, it is primarily intended for development and testing. For production deployments, using an **S3-compatible provider** is highly recommended.
+
+> [!NOTE]
+> Furthermore, if you run a multi-instance (highly available) setup, you must ensure your storage backend is distributed (supporting `ReadWriteMany` access).
+>
+> In contrast, the **S3 provider option** is much easier to configure, scales seamlessly across multiple instances out-of-the-box, and eliminates the need to manage complex storage volumes in your cluster.
+
## DNS
### Domain and subdomain
@@ -99,6 +129,7 @@ Similarly, ensure that your environment does not filter or block the specific MI
#### Request Body Size Limits
Ensure that your ingress controller, proxy, or web server is configured to allow larger HTTP request bodies. Providing a universal "one-size-fits-all" limit is difficult, as CalDAV and CardDAV payloads can be quite large.
+The server has for CalDAV and CardDAV requests an internal limit of 30'000'000 bytes (~ 28.6 MB). Currently this limit is fixed and not configurable.
Individual calendar events with long descriptions or attachments or contact cards containing high-resolution profile photos (vCards) can significantly increase the request size. We recommend starting with a limit of at least 10MB to 20MB and adjusting based on your specific use case.
@@ -110,6 +141,8 @@ ingress:
nginx.ingress.kubernetes.io/proxy-body-size: "10m"
```
+If you enable WebDAV take care to revisit the body size limit. The server removes for WebDAV requests any internal body size limit.
+
## Others / Manual
The Calendar Server is built with **.NET 10** and is compatible with various platforms. Although native installation is possible, the only officially supported environment is the provided **Alpine-based OCI container**.
diff --git a/README.md b/README.md
index 53c3acc..4332d01 100644
--- a/README.md
+++ b/README.md
@@ -11,7 +11,8 @@ The **Calendare Server** is built on open standards to ensure seamless compatibi
- **Availability Management**: Includes "Free/Busy" support, helping you manage your schedule and share your availability with others.
- **Efficient Synchronization**: High-performance syncing that only downloads changes since your last update, saving battery life and data.
- **Real-Time Push Notifications**: Support for modern Web Push standards (including encrypted notifications and VAPID keys), so your devices stay updated instantly without constant polling.
-
+- **Basic WebDAV Storage:** Lightweight file hosting support, allowing you to store personal files backed by either local storage or an external S3-compatible provider (preferred).
+-
For the full list of supported RFC's and other specification see the [implemented scope](./Doc/SCOPE.md).
## Designed for Collaboration & Scalability
From 5790704d9520eb1536e26399e6e137335eea1209 Mon Sep 17 00:00:00 2001
From: Robert Bill <147130488+RobSlgm@users.noreply.github.com>
Date: Fri, 17 Jul 2026 12:08:37 +0200
Subject: [PATCH 3/3] Document helm
---
deploy/README.md | 24 ++++++++++++++++++++++++
deploy/README.md.gotmpl | 24 ++++++++++++++++++++++++
2 files changed, 48 insertions(+)
diff --git a/deploy/README.md b/deploy/README.md
index 88725ce..2c896c1 100644
--- a/deploy/README.md
+++ b/deploy/README.md
@@ -105,6 +105,18 @@ Or include the VAPID keys directly in `values.yaml` with:
These defaults are only used if no value is supplied by the user during account creation. The user can change these values later.
+## Calendare User Constraints
+
+| Key | Type | Default | Description |
+| ------------------------------------- | ------ | --------------- | ---------------------------------------- |
+| calendare.userConstraints | object | `{}` | ... |
+| calendare.userConstraints.ApplicationKeySecret | string | undefined | A secret (e.g. 'd9HbXPCSU...Aq5nRk` |
+
+A missing `ApplicationKeySecret` doesn't allow the use of the recommended client application secrets.
+
+Changing the secret invalidates all application keys the users have created.
+
+
## Calendar Clients Feature Configuration
| Key | Type | Default | Description |
@@ -153,6 +165,18 @@ Disabled features have a higher priority than enabled features.
If a client is not configured in `calendare.features` the in-built settings are applied, which are taken from the `appsettings.json` file of the server.
+## WebDAV file storage
+
+| Key | Type | Default | Description |
+| ----------------------------------- | ------ | ---------------------- | ------------------------------ |
+| webdav.enabled | bool | false | Enable/Disable WebDAV storage |
+| webdav.provider | string | `None' | Define S3 or Filestorage |
+
+The `webdav.s3` supports `Bucket`, `Host`, `AccessKey`, `SecretKey`, `Region` and `PathStyle` (true|false).
+
+The `webdav.filestorage` supports `PathBase`.
+
+
## Testing and Debugging Configuration
| Key | Type | Default | Description |
diff --git a/deploy/README.md.gotmpl b/deploy/README.md.gotmpl
index 4e04d24..fd0a55b 100644
--- a/deploy/README.md.gotmpl
+++ b/deploy/README.md.gotmpl
@@ -105,6 +105,18 @@ Or include the VAPID keys directly in `values.yaml` with:
These defaults are only used if no value is supplied by the user during account creation. The user can change these values later.
+## Calendare User Constraints
+
+| Key | Type | Default | Description |
+| ------------------------------------- | ------ | --------------- | ---------------------------------------- |
+| calendare.userConstraints | object | `{}` | ... |
+| calendare.userConstraints.ApplicationKeySecret | string | undefined | A secret (e.g. 'd9HbXPCSU...Aq5nRk` |
+
+A missing `ApplicationKeySecret` doesn't allow the use of the recommended client application secrets.
+
+Changing the secret invalidates all application keys the users have created.
+
+
## Calendar Clients Feature Configuration
| Key | Type | Default | Description |
@@ -153,6 +165,18 @@ Disabled features have a higher priority than enabled features.
If a client is not configured in `calendare.features` the in-built settings are applied, which are taken from the `appsettings.json` file of the server.
+## WebDAV file storage
+
+| Key | Type | Default | Description |
+| ----------------------------------- | ------ | ---------------------- | ------------------------------ |
+| webdav.enabled | bool | false | Enable/Disable WebDAV storage |
+| webdav.provider | string | `None' | Define S3 or Filestorage |
+
+The `webdav.s3` supports `Bucket`, `Host`, `AccessKey`, `SecretKey`, `Region` and `PathStyle` (true|false).
+
+The `webdav.filestorage` supports `PathBase`.
+
+
## Testing and Debugging Configuration
| Key | Type | Default | Description |