fix: prevent WebDAV password from being silently cleared by unrelated saves

Two components (ProviderList, UsageScriptModal) directly spread the full
settings object from the query into settingsApi.save(), which includes
webdavSync with an empty password (cleared by get_settings_for_frontend
for security). The backend merge_settings_for_save only preserved
existing WebDAV config when the incoming field was None, not when it was
present with an empty password.

Frontend fix: strip webdavSync before saving in both components, matching
the pattern already used by useSettings hook.

Backend defense-in-depth: merge_settings_for_save now backfills the
existing password when the incoming one is empty, preventing future
regressions from similar oversights.
This commit is contained in:
Jason
2026-03-23 09:54:05 +08:00
parent 8aa6ec784b
commit 0a301a497c
3 changed files with 78 additions and 4 deletions
+2 -1
View File
@@ -267,7 +267,8 @@ const UsageScriptModal: React.FC<UsageScriptModalProps> = ({
setShowUsageConfirm(false);
try {
if (settingsData) {
await settingsApi.save({ ...settingsData, usageConfirmed: true });
const { webdavSync: _, ...rest } = settingsData;
await settingsApi.save({ ...rest, usageConfirmed: true });
await queryClient.invalidateQueries({ queryKey: ["settings"] });
}
} catch (error) {
+2 -1
View File
@@ -204,7 +204,8 @@ export function ProviderList({
setShowStreamCheckConfirm(false);
try {
if (settings) {
await settingsApi.save({ ...settings, streamCheckConfirmed: true });
const { webdavSync: _, ...rest } = settings;
await settingsApi.save({ ...rest, streamCheckConfirmed: true });
await queryClient.invalidateQueries({ queryKey: ["settings"] });
}
} catch (error) {