feat(nextcloud): use user's image for avatar (#434)

- add /ocs/v1.php/cloud/user route (same as /ocs/v2.php/cloud/user )
    - add also /remote.php/dav/avatars/{user}/{size}.png route (used by Nextcloud sync)

    note: webp are transcoded in png, no cache but using pragma HTTP header
This commit is contained in:
Edouard Vanbelle
2026-06-08 15:25:36 +02:00
committed by GitHub
parent 6811e3e4f7
commit 2ad55879f3
2 changed files with 172 additions and 5 deletions
+15
View File
@@ -80,6 +80,13 @@ pub fn nextcloud_routes_with_state(state: Arc<AppState>) -> Router<Arc<AppState>
// Protected routes — require Basic Auth via app passwords.
let protected = Router::new()
// Both v1 and v2 of the singular cloud/user endpoint return the
// same payload shape — NC's URL-versioning is a transport
// convention, not a protocol break for this endpoint. Older
// NC clients (and some third-party libraries) still hit v1
// first; without this route they get a 404 even though the
// handler exists.
.route("/ocs/v1.php/cloud/user", get(ocs_handler::handle_user_info))
.route("/ocs/v2.php/cloud/user", get(ocs_handler::handle_user_info))
.route(
"/ocs/v1.php/cloud/users/{userid}",
@@ -126,6 +133,14 @@ pub fn nextcloud_routes_with_state(state: Arc<AppState>) -> Router<Arc<AppState>
"/index.php/avatar/{user}/{size}",
get(avatar_handler::handle_avatar),
)
// NC desktop + several mobile clients fetch avatars from the
// DAV-shaped URL (with a literal `.png` extension on the
// size segment). Same SVG payload, different URL shape — the
// wrapper handler strips the extension and delegates.
.route(
"/remote.php/dav/avatars/{user}/{size}",
get(avatar_handler::handle_dav_avatar),
)
.route(
"/remote.php/dav/files/{user}/{*subpath}",
any(handle_dav_files),