mirror of
https://github.com/shuaiplus/nodewarden.git
synced 2026-06-20 21:00:41 +00:00
fix: enhance cipher handling with repairable URI support and sync improvements
This commit is contained in:
+15
-6
@@ -25,8 +25,8 @@ 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 { repairCipherKeyMismatches, repairCipherUriChecksums } from '@/lib/api/vault';
|
||||
import { getCachedVaultCoreSnapshot, invalidateVaultCoreSyncSnapshot, loadVaultCoreSyncSnapshot } from '@/lib/api/vault-sync';
|
||||
import { silentlyRepairBackupSettingsIfNeeded } from '@/lib/backup-settings-repair';
|
||||
import {
|
||||
parseSignalRTextFrames,
|
||||
@@ -1086,9 +1086,18 @@ export default function App() {
|
||||
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((uriChecksumCount) => {
|
||||
if (uriChecksumCount > 0) void refetchVaultCoreData();
|
||||
void repairCipherKeyMismatches(authedFetch, session, result.ciphers)
|
||||
.then(async (keyMismatchCount) => {
|
||||
if (keyMismatchCount > 0) {
|
||||
await invalidateVaultCoreSyncSnapshot(vaultCacheKey);
|
||||
void refetchVaultCoreData();
|
||||
return;
|
||||
}
|
||||
const uriChecksumCount = await repairCipherUriChecksums(authedFetch, session, result.ciphers);
|
||||
if (uriChecksumCount > 0) {
|
||||
await invalidateVaultCoreSyncSnapshot(vaultCacheKey);
|
||||
void refetchVaultCoreData();
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
// Best-effort compatibility repair must not interrupt normal vault loading.
|
||||
@@ -1106,7 +1115,7 @@ export default function App() {
|
||||
return () => {
|
||||
active = false;
|
||||
};
|
||||
}, [session?.symEncKey, session?.symMacKey, encryptedFolders, encryptedCiphers]);
|
||||
}, [session?.symEncKey, session?.symMacKey, vaultCacheKey, encryptedFolders, encryptedCiphers]);
|
||||
|
||||
useEffect(() => {
|
||||
if (IS_DEMO_MODE) return;
|
||||
|
||||
@@ -453,6 +453,7 @@ export function createAuthedFetch(getSession: () => SessionState | null, setSess
|
||||
if (!session?.accessToken) throw new Error('Unauthorized');
|
||||
const headers = new Headers(init.headers || {});
|
||||
headers.set('Authorization', `Bearer ${session.accessToken}`);
|
||||
headers.set('X-NodeWarden-Web', '1');
|
||||
|
||||
let resp = await retryableRequest(headers);
|
||||
if (resp.status !== 401 || (!session.refreshToken && session.authMode !== 'web-cookie')) return resp;
|
||||
@@ -461,6 +462,7 @@ export function createAuthedFetch(getSession: () => SessionState | null, setSess
|
||||
if (latest?.accessToken && latest.accessToken !== session.accessToken) {
|
||||
const latestHeaders = new Headers(init.headers || {});
|
||||
latestHeaders.set('Authorization', `Bearer ${latest.accessToken}`);
|
||||
latestHeaders.set('X-NodeWarden-Web', '1');
|
||||
resp = await retryableRequest(latestHeaders);
|
||||
if (resp.status !== 401) return resp;
|
||||
}
|
||||
@@ -486,6 +488,7 @@ export function createAuthedFetch(getSession: () => SessionState | null, setSess
|
||||
|
||||
const retryHeaders = new Headers(init.headers || {});
|
||||
retryHeaders.set('Authorization', `Bearer ${nextSession.accessToken}`);
|
||||
retryHeaders.set('X-NodeWarden-Web', '1');
|
||||
resp = await retryableRequest(retryHeaders);
|
||||
return resp;
|
||||
};
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import type { Cipher, Folder, Send } from '../types';
|
||||
import { getVaultRevisionDate } from './auth';
|
||||
import { loadCachedVaultCoreSnapshot, saveCachedVaultCoreSnapshot, type VaultCoreSnapshot } from '../vault-cache';
|
||||
import { clearCachedVaultCoreSnapshot, loadCachedVaultCoreSnapshot, saveCachedVaultCoreSnapshot, type VaultCoreSnapshot } from '../vault-cache';
|
||||
import { parseJson, type AuthedFetch } from './shared';
|
||||
|
||||
interface VaultSyncResponse {
|
||||
@@ -43,6 +43,14 @@ export async function getCachedVaultCoreSnapshot(cacheKey: string): Promise<Vaul
|
||||
return snapshot;
|
||||
}
|
||||
|
||||
export async function invalidateVaultCoreSyncSnapshot(cacheKey: string): Promise<void> {
|
||||
const normalizedKey = String(cacheKey || '').trim();
|
||||
if (!normalizedKey) return;
|
||||
pendingVaultCoreRequests.delete(normalizedKey);
|
||||
memoryVaultCoreCache.delete(normalizedKey);
|
||||
await clearCachedVaultCoreSnapshot(normalizedKey);
|
||||
}
|
||||
|
||||
export async function loadVaultCoreSyncSnapshot(authedFetch: AuthedFetch, cacheKey: string): Promise<VaultCoreSnapshot> {
|
||||
const normalizedKey = String(cacheKey || '').trim();
|
||||
if (!normalizedKey) return { ciphers: [], folders: [], sends: [] };
|
||||
|
||||
Reference in New Issue
Block a user