mirror of
https://github.com/shuaiplus/nodewarden.git
synced 2026-06-21 05:10:41 +00:00
feat: implement vault synchronization and decryption improvements
- Added background synchronization for vault core data, including optional folder updates. - Introduced a new API endpoint to retrieve the vault revision date. - Enhanced vault synchronization logic to utilize a caching mechanism for improved performance. - Created a new vault cache module to handle IndexedDB storage for vault core snapshots. - Implemented a worker for asynchronous decryption of vault data, improving UI responsiveness. - Updated main application settings to adjust query stale time for better data freshness. - Refactored vault-related API functions to support cache keys for more efficient data retrieval.
This commit is contained in:
@@ -0,0 +1,108 @@
|
||||
import type { Cipher, Folder } from './types';
|
||||
|
||||
export interface VaultCoreSnapshot {
|
||||
ciphers: Cipher[];
|
||||
folders: Folder[];
|
||||
}
|
||||
|
||||
interface VaultCoreCacheRecord {
|
||||
cacheKey: string;
|
||||
revisionStamp: number;
|
||||
savedAt: number;
|
||||
snapshot: VaultCoreSnapshot;
|
||||
}
|
||||
|
||||
const DB_NAME = 'nodewarden-web-cache';
|
||||
const DB_VERSION = 1;
|
||||
const VAULT_CORE_STORE = 'vault-core';
|
||||
|
||||
let dbPromise: Promise<IDBDatabase | null> | null = null;
|
||||
|
||||
function supportsIndexedDb(): boolean {
|
||||
return typeof indexedDB !== 'undefined';
|
||||
}
|
||||
|
||||
function openDatabase(): Promise<IDBDatabase | null> {
|
||||
if (!supportsIndexedDb()) return Promise.resolve(null);
|
||||
if (dbPromise) return dbPromise;
|
||||
dbPromise = new Promise((resolve) => {
|
||||
try {
|
||||
const request = indexedDB.open(DB_NAME, DB_VERSION);
|
||||
request.onupgradeneeded = () => {
|
||||
const db = request.result;
|
||||
if (!db.objectStoreNames.contains(VAULT_CORE_STORE)) {
|
||||
db.createObjectStore(VAULT_CORE_STORE, { keyPath: 'cacheKey' });
|
||||
}
|
||||
};
|
||||
request.onsuccess = () => resolve(request.result);
|
||||
request.onerror = () => resolve(null);
|
||||
request.onblocked = () => resolve(null);
|
||||
} catch {
|
||||
resolve(null);
|
||||
}
|
||||
});
|
||||
return dbPromise;
|
||||
}
|
||||
|
||||
function withStore<T>(
|
||||
mode: IDBTransactionMode,
|
||||
run: (store: IDBObjectStore) => Promise<T>
|
||||
): Promise<T | null> {
|
||||
return openDatabase().then((db) => {
|
||||
if (!db) return null;
|
||||
return new Promise<T | null>((resolve) => {
|
||||
try {
|
||||
const tx = db.transaction(VAULT_CORE_STORE, mode);
|
||||
const store = tx.objectStore(VAULT_CORE_STORE);
|
||||
void run(store).then(resolve).catch(() => resolve(null));
|
||||
tx.onerror = () => resolve(null);
|
||||
tx.onabort = () => resolve(null);
|
||||
} catch {
|
||||
resolve(null);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
export async function loadCachedVaultCoreSnapshot(cacheKey: string): Promise<VaultCoreCacheRecord | null> {
|
||||
const normalized = String(cacheKey || '').trim();
|
||||
if (!normalized) return null;
|
||||
return withStore('readonly', (store) => new Promise<VaultCoreCacheRecord | null>((resolve) => {
|
||||
const request = store.get(normalized);
|
||||
request.onsuccess = () => {
|
||||
const record = request.result as VaultCoreCacheRecord | undefined;
|
||||
resolve(record || null);
|
||||
};
|
||||
request.onerror = () => resolve(null);
|
||||
}));
|
||||
}
|
||||
|
||||
export async function saveCachedVaultCoreSnapshot(
|
||||
cacheKey: string,
|
||||
revisionStamp: number,
|
||||
snapshot: VaultCoreSnapshot
|
||||
): Promise<void> {
|
||||
const normalized = String(cacheKey || '').trim();
|
||||
if (!normalized) return;
|
||||
await withStore('readwrite', (store) => new Promise<void>((resolve) => {
|
||||
const record: VaultCoreCacheRecord = {
|
||||
cacheKey: normalized,
|
||||
revisionStamp,
|
||||
savedAt: Date.now(),
|
||||
snapshot,
|
||||
};
|
||||
const request = store.put(record);
|
||||
request.onsuccess = () => resolve();
|
||||
request.onerror = () => resolve();
|
||||
}));
|
||||
}
|
||||
|
||||
export async function clearCachedVaultCoreSnapshot(cacheKey: string): Promise<void> {
|
||||
const normalized = String(cacheKey || '').trim();
|
||||
if (!normalized) return;
|
||||
await withStore('readwrite', (store) => new Promise<void>((resolve) => {
|
||||
const request = store.delete(normalized);
|
||||
request.onsuccess = () => resolve();
|
||||
request.onerror = () => resolve();
|
||||
}));
|
||||
}
|
||||
Reference in New Issue
Block a user