Compare commits

...

6 Commits

Author SHA1 Message Date
Lennart
85f3d89235 version 0.10.4 2025-11-17 01:21:55 +01:00
Lennart
092604694a multiget: percent-decode hrefs 2025-11-17 01:21:20 +01:00
Lennart
8ef24668ba version 0.10.3 2025-11-14 11:02:27 +01:00
Lennart
416658d069 frontend: Fix missing getTimezones import in create-calendar-form
fixes #141
2025-11-14 11:01:59 +01:00
Lennart
80eae5db9e version 0.10.2 2025-11-09 21:39:09 +01:00
Lennart
66f541f1c7 Drop log level for 404 to info
fixes #139
2025-11-09 21:36:17 +01:00
10 changed files with 45 additions and 32 deletions

24
Cargo.lock generated
View File

@@ -2974,7 +2974,7 @@ dependencies = [
[[package]]
name = "rustical"
version = "0.10.1"
version = "0.10.4"
dependencies = [
"anyhow",
"argon2",
@@ -3017,7 +3017,7 @@ dependencies = [
[[package]]
name = "rustical_caldav"
version = "0.10.1"
version = "0.10.4"
dependencies = [
"async-std",
"async-trait",
@@ -3057,7 +3057,7 @@ dependencies = [
[[package]]
name = "rustical_carddav"
version = "0.10.1"
version = "0.10.4"
dependencies = [
"async-trait",
"axum",
@@ -3089,7 +3089,7 @@ dependencies = [
[[package]]
name = "rustical_dav"
version = "0.10.1"
version = "0.10.4"
dependencies = [
"async-trait",
"axum",
@@ -3114,7 +3114,7 @@ dependencies = [
[[package]]
name = "rustical_dav_push"
version = "0.10.1"
version = "0.10.4"
dependencies = [
"async-trait",
"axum",
@@ -3139,7 +3139,7 @@ dependencies = [
[[package]]
name = "rustical_frontend"
version = "0.10.1"
version = "0.10.4"
dependencies = [
"askama",
"askama_web",
@@ -3175,7 +3175,7 @@ dependencies = [
[[package]]
name = "rustical_ical"
version = "0.10.1"
version = "0.10.4"
dependencies = [
"axum",
"chrono",
@@ -3192,7 +3192,7 @@ dependencies = [
[[package]]
name = "rustical_oidc"
version = "0.10.1"
version = "0.10.4"
dependencies = [
"async-trait",
"axum",
@@ -3208,7 +3208,7 @@ dependencies = [
[[package]]
name = "rustical_store"
version = "0.10.1"
version = "0.10.4"
dependencies = [
"anyhow",
"async-trait",
@@ -3241,7 +3241,7 @@ dependencies = [
[[package]]
name = "rustical_store_sqlite"
version = "0.10.1"
version = "0.10.4"
dependencies = [
"async-trait",
"chrono",
@@ -3262,7 +3262,7 @@ dependencies = [
[[package]]
name = "rustical_xml"
version = "0.10.1"
version = "0.10.4"
dependencies = [
"quick-xml",
"thiserror 2.0.17",
@@ -5013,7 +5013,7 @@ checksum = "9edde0db4769d2dc68579893f2306b26c6ecfbe0ef499b013d731b7b9247e0b9"
[[package]]
name = "xml_derive"
version = "0.10.1"
version = "0.10.4"
dependencies = [
"darling",
"heck",

View File

@@ -2,7 +2,7 @@
members = ["crates/*"]
[workspace.package]
version = "0.10.1"
version = "0.10.4"
rust-version = "1.91"
edition = "2024"
description = "A CalDAV server"

View File

@@ -26,16 +26,18 @@ pub async fn get_objects_calendar_multiget<C: CalendarStore>(
let mut not_found = vec![];
for href in &cal_query.href {
if let Some(filename) = href.strip_prefix(path) {
if let Ok(href) = percent_encoding::percent_decode_str(href).decode_utf8()
&& let Some(filename) = href.strip_prefix(path)
{
let filename = filename.trim_start_matches('/');
if let Some(object_id) = filename.strip_suffix(".ics") {
match store.get_object(principal, cal_id, object_id, false).await {
Ok(object) => result.push(object),
Err(rustical_store::Error::NotFound) => not_found.push(href.to_owned()),
Err(rustical_store::Error::NotFound) => not_found.push(href.to_string()),
Err(err) => return Err(err.into()),
}
} else {
not_found.push(href.to_owned());
not_found.push(href.to_string());
}
} else {
not_found.push(href.to_owned());

View File

@@ -34,7 +34,9 @@ pub async fn get_objects_addressbook_multiget<AS: AddressbookStore>(
let mut not_found = vec![];
for href in &addressbook_multiget.href {
if let Some(filename) = href.strip_prefix(path) {
if let Ok(href) = percent_encoding::percent_decode_str(href).decode_utf8()
&& let Some(filename) = href.strip_prefix(path)
{
let filename = filename.trim_start_matches('/');
if let Some(object_id) = filename.strip_suffix(".vcf") {
match store
@@ -42,11 +44,11 @@ pub async fn get_objects_addressbook_multiget<AS: AddressbookStore>(
.await
{
Ok(object) => result.push(object),
Err(rustical_store::Error::NotFound) => not_found.push(href.to_owned()),
Err(rustical_store::Error::NotFound) => not_found.push(href.to_string()),
Err(err) => return Err(err.into()),
}
} else {
not_found.push(href.to_owned());
not_found.push(href.to_string());
}
} else {
not_found.push(href.to_owned());

View File

@@ -2,6 +2,7 @@ import { html, LitElement } from "lit";
import { customElement, property } from "lit/decorators.js";
import { Ref, createRef, ref } from 'lit/directives/ref.js';
import { escapeXml } from ".";
import { getTimezones } from "./timezones.ts";
@customElement("create-calendar-form")
export class CreateCalendarForm extends LitElement {

View File

@@ -2,6 +2,7 @@ import { i, x } from "./lit-DkXrt_Iv.mjs";
import { n as n$1, t } from "./property-B8WoKf1Y.mjs";
import { e, n } from "./ref-BwbQvJBB.mjs";
import { e as escapeXml } from "./index-_IB1wMbZ.mjs";
import { g as getTimezones } from "./timezones-B0vBBzCP.mjs";
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __decorateClass = (decorators, target, key, kind) => {

View File

@@ -2,18 +2,7 @@ import { i, x } from "./lit-DkXrt_Iv.mjs";
import { n as n$1, t } from "./property-B8WoKf1Y.mjs";
import { e, n } from "./ref-BwbQvJBB.mjs";
import { e as escapeXml } from "./index-_IB1wMbZ.mjs";
let timezonesPromise = null;
async function getTimezones() {
timezonesPromise ||= new Promise(async (resolve, reject) => {
try {
let response = await fetch("/frontend/_timezones.json");
resolve(await response.json());
} catch (e2) {
reject(e2);
}
});
return await timezonesPromise;
}
import { g as getTimezones } from "./timezones-B0vBBzCP.mjs";
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __decorateClass = (decorators, target, key, kind) => {

View File

@@ -0,0 +1,15 @@
let timezonesPromise = null;
async function getTimezones() {
timezonesPromise ||= new Promise(async (resolve, reject) => {
try {
let response = await fetch("/frontend/_timezones.json");
resolve(await response.json());
} catch (e) {
reject(e);
}
});
return await timezonesPromise;
}
export {
getTimezones as g
};

View File

@@ -795,6 +795,7 @@ impl CalendarStore for SqliteCalendarStore {
}
// Logs an operation to the events
// TODO: Log multiple updates
async fn log_object_operation(
tx: &mut Transaction<'_, Sqlite>,
principal: &str,

View File

@@ -173,7 +173,9 @@ pub fn make_app<AS: AddressbookStore, CS: CalendarStore, S: SubscriptionStore>(
tracing::debug!("unauthorized");
}
StatusCode::NOT_FOUND => {
tracing::warn!("client error");
// Clients like GNOME Calendar will try to reach /remote.php/webdav
// quite often clogging up the logs
tracing::info!("client error");
}
_ => {
tracing::error!("client error");