feat: add URI checksum repair functionality for ciphers

This commit is contained in:
shuaiplus
2026-05-18 01:59:02 +08:00
parent 776408e9d0
commit c50247b8fe
3 changed files with 162 additions and 0 deletions
+14
View File
@@ -25,6 +25,7 @@ import {
import { clearAuditLogs, getAuditLogSettings, listAdminInvites, listAdminUsers, listAuditLogs, saveAuditLogSettings, type AuditLogFilters } from '@/lib/api/admin';
import { getDomainRules, saveDomainRules } from '@/lib/api/domains';
import { getSends } from '@/lib/api/send';
import { repairCipherUriChecksums } from '@/lib/api/vault';
import { getCachedVaultCoreSnapshot, loadVaultCoreSyncSnapshot } from '@/lib/api/vault-sync';
import { silentlyRepairBackupSettingsIfNeeded } from '@/lib/backup-settings-repair';
import {
@@ -229,6 +230,7 @@ export default function App() {
const silentRefreshVaultRef = useRef<() => Promise<void>>(async () => {});
const refreshAuthorizedDevicesRef = useRef<() => Promise<void>>(async () => {});
const repairAttemptRef = useRef<string>('');
const uriChecksumRepairAttemptRef = useRef<string>('');
const pendingVaultCoreQueryRefreshRef = useRef<Promise<{ data?: VaultCoreSnapshot } | unknown> | null>(null);
const pendingVaultCoreRefreshRef = useRef<Promise<unknown> | null>(null);
const notificationRefreshTimerRef = useRef<number | null>(null);
@@ -1038,6 +1040,7 @@ export default function App() {
useEffect(() => {
if (session?.accessToken) return;
repairAttemptRef.current = '';
uriChecksumRepairAttemptRef.current = '';
}, [session?.accessToken]);
useEffect(() => {
@@ -1078,6 +1081,17 @@ export default function App() {
setDecryptedFolders(result.folders);
setDecryptedCiphers(result.ciphers);
setVaultInitialDecryptDone(true);
const repairKey = `${session.accessToken}:${encryptedCiphers.map((cipher) => `${cipher.id}:${cipher.revisionDate || ''}`).join(',')}`;
if (uriChecksumRepairAttemptRef.current !== repairKey) {
uriChecksumRepairAttemptRef.current = repairKey;
void repairCipherUriChecksums(authedFetch, session, result.ciphers)
.then((count) => {
if (count > 0) void refetchVaultCoreData();
})
.catch(() => {
// Best-effort compatibility repair must not interrupt normal vault loading.
});
}
} catch (error) {
if (!active) return;
const message = error instanceof Error ? error.message : t('txt_decrypt_failed_2');