Compare commits
5 Commits
617236558e
...
37ce044181
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
37ce044181 | ||
|
|
12537896f2 | ||
|
|
ef00dde487 | ||
|
|
6ff0b1756d | ||
|
|
d39a1d86a9 |
12
CHANGELOG.md
12
CHANGELOG.md
@@ -1,23 +1,23 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
## 0.5.10 (2025-11-20)
|
## 0.5.7 (2025-11-20)
|
||||||
|
|
||||||
* Bundle the Ente Families web app so `family.<domain>` serves the correct invite/management UI instead of the placeholder photos build.
|
* Bundle the Ente Families web app so `family.<domain>` serves the correct invite/management UI instead of the placeholder photos build.
|
||||||
* Ship built-in billing plan JSON so Museum can resolve subscriptions (`family/add-member`, invite acceptance) on self-hosted installs without manual DB edits.
|
* Ship built-in billing plan JSON so Museum can resolve subscriptions (`family/add-member`, invite acceptance) on self-hosted installs without manual DB edits.
|
||||||
|
* Fix passkey enrollment on the accounts host by ensuring only the photos domain matches the `/api` proxy block.
|
||||||
## 0.5.7 (2025-11-18)
|
|
||||||
|
|
||||||
* Inject the API origin into all served HTML so the Next.js bundles (including `accounts/passkeys`) read the self-hosted endpoint instead of defaulting to `https://api.ente.io`
|
|
||||||
* Document the working Backblaze B2 CORS JSON that whitelists the wildcard origin + upload operations for desktop casts
|
|
||||||
|
|
||||||
## 0.5.6 (2025-11-18)
|
## 0.5.6 (2025-11-18)
|
||||||
|
|
||||||
* Allow the accounts frontend origin in Museum’s `webauthn.rporigins` when subdomain routing is enabled so passkey enrollment via the desktop flow succeeds
|
* 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
|
* 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)
|
## 0.5.5 (2025-11-18)
|
||||||
|
|
||||||
* Validate S3 data-center identifiers so replication only uses the canonical `b2-eu-cen`/`wasabi-eu-central-2-v3`/`scw-eu-fr-v3` keys and update the docs to reflect the upstream requirements
|
* Validate S3 data-center identifiers so replication only uses the canonical `b2-eu-cen`/`wasabi-eu-central-2-v3`/`scw-eu-fr-v3` keys and update the docs to reflect the upstream requirements
|
||||||
|
* Inject the API origin into all served HTML so the Next.js bundles (including `accounts/passkeys`) read the self-hosted endpoint instead of defaulting to `https://api.ente.io`
|
||||||
|
* Document the working Backblaze B2 CORS JSON that whitelists the wildcard origin + upload operations for desktop casts
|
||||||
|
|
||||||
## 0.5.4 (2025-11-18)
|
## 0.5.4 (2025-11-18)
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
"contactEmail": "contact@ente.io",
|
"contactEmail": "contact@ente.io",
|
||||||
"website": "https://ente.io",
|
"website": "https://ente.io",
|
||||||
"tagline": "Open source, end-to-end encrypted photo backup",
|
"tagline": "Open source, end-to-end encrypted photo backup",
|
||||||
"version": "0.5.10",
|
"version": "0.5.7",
|
||||||
"upstreamVersion": "git-main",
|
"upstreamVersion": "git-main",
|
||||||
"healthCheckPath": "/health",
|
"healthCheckPath": "/health",
|
||||||
"httpPort": 3080,
|
"httpPort": 3080,
|
||||||
|
|||||||
83
start.sh
83
start.sh
@@ -121,6 +121,67 @@ normalize_host() {
|
|||||||
esac
|
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")"
|
ACCOUNTS_HOST="$(normalize_host "$ACCOUNTS_HOST")"
|
||||||
AUTH_HOST="$(normalize_host "$AUTH_HOST")"
|
AUTH_HOST="$(normalize_host "$AUTH_HOST")"
|
||||||
CAST_HOST="$(normalize_host "$CAST_HOST")"
|
CAST_HOST="$(normalize_host "$CAST_HOST")"
|
||||||
@@ -155,7 +216,11 @@ else
|
|||||||
API_BASE="$BASE_URL"
|
API_BASE="$BASE_URL"
|
||||||
fi
|
fi
|
||||||
API_ORIGIN="${API_BASE}/api"
|
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 "Application base URL: $BASE_URL"
|
||||||
log INFO "Relying party ID: $RP_ID"
|
log INFO "Relying party ID: $RP_ID"
|
||||||
@@ -989,7 +1054,9 @@ cat > "$CADDY_CONFIG" <<EOF_CADDY
|
|||||||
respond 204
|
respond 204
|
||||||
}
|
}
|
||||||
|
|
||||||
handle_path /api/* {
|
@api_host host ${PHOTOS_HOST}
|
||||||
|
handle @api_host {
|
||||||
|
handle_path /api/* {
|
||||||
@api_cors_subdomain header Origin *
|
@api_cors_subdomain header Origin *
|
||||||
header @api_cors_subdomain {
|
header @api_cors_subdomain {
|
||||||
Access-Control-Allow-Origin {http.request.header.Origin}
|
Access-Control-Allow-Origin {http.request.header.Origin}
|
||||||
@@ -1006,6 +1073,7 @@ cat > "$CADDY_CONFIG" <<EOF_CADDY
|
|||||||
header_up X-Forwarded-For {http.request.header.X-Forwarded-For}
|
header_up X-Forwarded-For {http.request.header.X-Forwarded-For}
|
||||||
header_up X-Forwarded-Proto {http.request.header.X-Forwarded-Proto}
|
header_up X-Forwarded-Proto {http.request.header.X-Forwarded-Proto}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
handle /health {
|
handle /health {
|
||||||
@@ -1042,6 +1110,7 @@ cat > "$CADDY_CONFIG" <<EOF_CADDY
|
|||||||
}
|
}
|
||||||
|
|
||||||
@museum_api_get {
|
@museum_api_get {
|
||||||
|
host ${PHOTOS_HOST}
|
||||||
method GET HEAD
|
method GET HEAD
|
||||||
path_regexp museum_api_get ^/(admin|authenticator|billing|cast|collections|custom-domain|diff|discount|email-hash|emails-from-hashes|emergency-contacts|family|file|file-link|files|fire|info|job|mail|metrics|multipart-upload-urls|offers|options|pass-info|passkeys|public-collection|push|queue|remote-store|storage-bonus|thumbnail|trash|unknown-api|upload-urls|user|user-entity|verify-password)(/|$)
|
path_regexp museum_api_get ^/(admin|authenticator|billing|cast|collections|custom-domain|diff|discount|email-hash|emails-from-hashes|emergency-contacts|family|file|file-link|files|fire|info|job|mail|metrics|multipart-upload-urls|offers|options|pass-info|passkeys|public-collection|push|queue|remote-store|storage-bonus|thumbnail|trash|unknown-api|upload-urls|user|user-entity|verify-password)(/|$)
|
||||||
}
|
}
|
||||||
@@ -1055,6 +1124,7 @@ cat > "$CADDY_CONFIG" <<EOF_CADDY
|
|||||||
}
|
}
|
||||||
|
|
||||||
@write_methods {
|
@write_methods {
|
||||||
|
host ${PHOTOS_HOST}
|
||||||
not method GET
|
not method GET
|
||||||
not method HEAD
|
not method HEAD
|
||||||
}
|
}
|
||||||
@@ -1150,7 +1220,11 @@ cat > "$CADDY_CONFIG" <<EOF_CADDY
|
|||||||
respond 204
|
respond 204
|
||||||
}
|
}
|
||||||
|
|
||||||
handle_path /api/* {
|
@api_photos {
|
||||||
|
host ${PHOTOS_HOST}
|
||||||
|
path /api/*
|
||||||
|
}
|
||||||
|
handle @api_photos {
|
||||||
@api_cors_path header Origin *
|
@api_cors_path header Origin *
|
||||||
header @api_cors_path {
|
header @api_cors_path {
|
||||||
Access-Control-Allow-Origin {http.request.header.Origin}
|
Access-Control-Allow-Origin {http.request.header.Origin}
|
||||||
@@ -1167,6 +1241,7 @@ cat > "$CADDY_CONFIG" <<EOF_CADDY
|
|||||||
header_up X-Forwarded-For {http.request.header.X-Forwarded-For}
|
header_up X-Forwarded-For {http.request.header.X-Forwarded-For}
|
||||||
header_up X-Forwarded-Proto {http.request.header.X-Forwarded-Proto}
|
header_up X-Forwarded-Proto {http.request.header.X-Forwarded-Proto}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
handle /health {
|
handle /health {
|
||||||
@@ -1203,6 +1278,7 @@ cat > "$CADDY_CONFIG" <<EOF_CADDY
|
|||||||
}
|
}
|
||||||
|
|
||||||
@museum_api_get_path {
|
@museum_api_get_path {
|
||||||
|
host ${PHOTOS_HOST}
|
||||||
method GET HEAD
|
method GET HEAD
|
||||||
path_regexp museum_api_get_path ^/(admin|authenticator|billing|cast|collections|custom-domain|diff|discount|email-hash|emails-from-hashes|emergency-contacts|family|file|file-link|files|fire|info|job|mail|metrics|multipart-upload-urls|offers|options|pass-info|passkeys|public-collection|push|queue|remote-store|storage-bonus|thumbnail|trash|unknown-api|upload-urls|user|user-entity|verify-password)(/|$)
|
path_regexp museum_api_get_path ^/(admin|authenticator|billing|cast|collections|custom-domain|diff|discount|email-hash|emails-from-hashes|emergency-contacts|family|file|file-link|files|fire|info|job|mail|metrics|multipart-upload-urls|offers|options|pass-info|passkeys|public-collection|push|queue|remote-store|storage-bonus|thumbnail|trash|unknown-api|upload-urls|user|user-entity|verify-password)(/|$)
|
||||||
}
|
}
|
||||||
@@ -1216,6 +1292,7 @@ cat > "$CADDY_CONFIG" <<EOF_CADDY
|
|||||||
}
|
}
|
||||||
|
|
||||||
@write_methods_path {
|
@write_methods_path {
|
||||||
|
host ${PHOTOS_HOST}
|
||||||
not method GET
|
not method GET
|
||||||
not method HEAD
|
not method HEAD
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user