feat(sync): auto-build Nextcloud/ownCloud DAV path from the server URL
For nextcloud/owncloud, WebDavTarget now derives the canonical …/remote.php/dav/files/<user>/ path from the entered server URL (origin only, so a pasted full path normalizes too); other providers use the URL verbatim. test_sync_target also reuses the stored password when editing an existing webdav target (unless a new one is typed), so Test works after a URL fix without re-entering the password. Fixes the confusing 'bare host connects, full URL fails' behavior (the former was a 404 false-positive, the latter a blank-secret 401).
This commit is contained in:
@@ -2349,15 +2349,46 @@ pub async fn test_sync_target(
|
||||
let hints = provider_setup_hints(config.provider_hint.as_deref());
|
||||
let (target, temp_ref): (Box<dyn SyncTarget>, Option<String>) =
|
||||
if let Some(id) = config.id.clone() {
|
||||
// Existing target (any kind) — dispatch to its concrete impl.
|
||||
let row = state
|
||||
.store
|
||||
.get_sync_target(&id)
|
||||
.await
|
||||
.map_err(|e| WaError::new("sync", e.to_string()))?;
|
||||
let target = crate::sync::build_sync_target(&row)
|
||||
.map_err(|e| WaError::new("sync", e.to_string()))?;
|
||||
(target, None)
|
||||
if row.kind == "webdav" {
|
||||
// Editing an existing webdav target: test the values on screen but
|
||||
// reuse the STORED password (via its credential_ref) unless the user
|
||||
// typed a new one — so "Test" works after a URL fix without having to
|
||||
// re-enter the password.
|
||||
let (credential_ref, temp_ref) =
|
||||
if let Some(secret) = config.secret.as_deref().filter(|s| !s.is_empty()) {
|
||||
let temp_ref = format!("wa-sync-test-{}", uuid::Uuid::new_v4());
|
||||
crate::sync::credentials::set(&temp_ref, secret)
|
||||
.map_err(|e| WaError::new("sync", e.to_string()))?;
|
||||
(temp_ref.clone(), Some(temp_ref))
|
||||
} else {
|
||||
(row.credential_ref.clone(), None)
|
||||
};
|
||||
let target = crate::sync::WebDavTarget {
|
||||
base_url: config.base_url.clone().or(row.base_url.clone()).unwrap_or_default(),
|
||||
provider_hint: config.provider_hint.clone().or(row.provider_hint.clone()),
|
||||
remote_base_path: config
|
||||
.remote_base_path
|
||||
.clone()
|
||||
.unwrap_or(row.remote_base_path.clone()),
|
||||
username: config.username.clone().or(row.username.clone()).unwrap_or_default(),
|
||||
credential_ref,
|
||||
third_party: false,
|
||||
allow_plaintext_lan: config
|
||||
.allow_plaintext_lan
|
||||
.unwrap_or(row.allow_plaintext_lan),
|
||||
};
|
||||
(Box::new(target), temp_ref)
|
||||
} else {
|
||||
// Non-webdav (OAuth) target — dispatch to its concrete impl as-is.
|
||||
let target = crate::sync::build_sync_target(&row)
|
||||
.map_err(|e| WaError::new("sync", e.to_string()))?;
|
||||
(target, None)
|
||||
}
|
||||
} else {
|
||||
// Unsaved WebDAV target: stash the secret under a temp credential_ref so
|
||||
// the same resolve-at-use path works, then clean it up after the test.
|
||||
@@ -2372,6 +2403,7 @@ pub async fn test_sync_target(
|
||||
}
|
||||
let target = crate::sync::WebDavTarget {
|
||||
base_url,
|
||||
provider_hint: config.provider_hint.clone(),
|
||||
remote_base_path: config
|
||||
.remote_base_path
|
||||
.clone()
|
||||
@@ -3028,6 +3060,13 @@ mod tests {
|
||||
enabled,
|
||||
third_party,
|
||||
host: Some(host.to_string()),
|
||||
upload_transcript: true,
|
||||
upload_notes: true,
|
||||
upload_summary: true,
|
||||
upload_recording: false,
|
||||
trigger_on_finalize: true,
|
||||
allow_plaintext_lan: false,
|
||||
encrypt_before_upload: false,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user