From d39a1d86a947f42e445d4665a84a8b72af151c35 Mon Sep 17 00:00:00 2001 From: Andreas Dueren Date: Thu, 20 Nov 2025 12:15:01 -0600 Subject: [PATCH] Fix accounts passkey routing --- CHANGELOG.md | 2 ++ start.sh | 73 ++++++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 73 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 092cac4..40a3cb4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,8 @@ * Allow the accounts frontend origin in Museum’s `webauthn.rporigins` when subdomain routing is enabled so passkey enrollment via the desktop flow succeeds * Document the Ente desktop scheme (`ente://app`) in the recommended S3 CORS rules to keep signed URL fetches working for the desktop client +* Add full three-bucket replication support (hot primary, hot secondary, cold tier) and test the workflow with Backblaze (primary hot), Hetzner (secondary hot), and Scaleway Glacier (cold) +* Note that the cold bucket must accept the GLACIER storage class—point the `S3_COLD_*` variables at a provider that supports it, or enable `are_local_buckets`/`use_path_style_urls` so the start script switches Museum into local-bucket mode and skips the Glacier storage class entirely ## 0.5.5 (2025-11-18) diff --git a/start.sh b/start.sh index edac763..9d4f3bb 100755 --- a/start.sh +++ b/start.sh @@ -121,6 +121,67 @@ normalize_host() { esac } +common_domain_suffix_two() { + local host_a="$1" + local host_b="$2" + local IFS='.' + local -a parts_a=() + local -a parts_b=() + read -ra parts_a <<< "$host_a" + read -ra parts_b <<< "$host_b" + local i=$(( ${#parts_a[@]} - 1 )) + local j=$(( ${#parts_b[@]} - 1 )) + local suffix="" + + while [ $i -ge 0 ] && [ $j -ge 0 ]; do + if [ "${parts_a[$i]}" = "${parts_b[$j]}" ]; then + if [ -z "$suffix" ]; then + suffix="${parts_a[$i]}" + else + suffix="${parts_a[$i]}.$suffix" + fi + ((i--)) + ((j--)) + else + break + fi + done + + printf '%s\n' "$suffix" +} + +common_domain_suffix() { + if [ "$#" -eq 0 ]; then + return + fi + + local suffix="$1" + shift + + while [ "$#" -gt 0 ] && [ -n "$suffix" ]; do + suffix="$(common_domain_suffix_two "$suffix" "$1")" + shift + done + + printf '%s\n' "$suffix" +} + +derive_default_rp_id() { + local hosts=("$PHOTOS_HOST") + if [ "$USE_SUBDOMAIN_ROUTING" = true ]; then + hosts+=("$ACCOUNTS_HOST" "$AUTH_HOST" "$CAST_HOST" "$ALBUMS_HOST" "$FAMILY_HOST") + fi + + local suffix + suffix="$(common_domain_suffix "${hosts[@]}")" + + if [ -n "$suffix" ]; then + printf '%s\n' "$suffix" + else + printf '%s\n' "$PHOTOS_HOST" + fi +} + ACCOUNTS_HOST="$(normalize_host "$ACCOUNTS_HOST")" AUTH_HOST="$(normalize_host "$AUTH_HOST")" CAST_HOST="$(normalize_host "$CAST_HOST")" @@ -155,7 +216,11 @@ else API_BASE="$BASE_URL" fi API_ORIGIN="${API_BASE}/api" -RP_ID="$PHOTOS_HOST" +if [ -n "${WEBAUTHN_RP_ID:-}" ]; then + RP_ID="$WEBAUTHN_RP_ID" +else + RP_ID="$(derive_default_rp_id)" +fi log INFO "Application base URL: $BASE_URL" log INFO "Relying party ID: $RP_ID" @@ -989,7 +1054,9 @@ cat > "$CADDY_CONFIG" < "$CADDY_CONFIG" < "$CADDY_CONFIG" <