Files
duplicati_preview/public/modules/clientSecrets.js
T

99 lines
2.7 KiB
JavaScript

const DB_NAME = 'duplicati-browser-secrets';
const STORE_NAME = 'source-secrets';
const DB_VERSION = 1;
const GLOBAL_SOURCE_ID = '__global_defaults__';
function openDatabase() {
return new Promise((resolve, reject) => {
const request = indexedDB.open(DB_NAME, DB_VERSION);
request.onerror = () => reject(request.error ?? new Error('Failed to open IndexedDB.'));
request.onupgradeneeded = () => {
const database = request.result;
if (!database.objectStoreNames.contains(STORE_NAME)) {
database.createObjectStore(STORE_NAME, { keyPath: 'sourceId' });
}
};
request.onsuccess = () => resolve(request.result);
});
}
async function withStore(mode, callback) {
const database = await openDatabase();
return new Promise((resolve, reject) => {
const transaction = database.transaction(STORE_NAME, mode);
const store = transaction.objectStore(STORE_NAME);
let callbackResult;
try {
callbackResult = callback(store);
} catch (error) {
transaction.abort();
database.close();
reject(error);
return;
}
transaction.onerror = () => {
database.close();
reject(transaction.error ?? new Error('IndexedDB transaction failed.'));
};
transaction.oncomplete = () => {
database.close();
resolve(callbackResult);
};
});
}
export async function loadClientSecrets(sourceId) {
const database = await openDatabase();
return new Promise((resolve, reject) => {
const transaction = database.transaction(STORE_NAME, 'readonly');
const store = transaction.objectStore(STORE_NAME);
const request = store.get(sourceId);
request.onerror = () => {
database.close();
reject(request.error ?? new Error('Failed to load browser secrets.'));
};
request.onsuccess = () => {
database.close();
resolve(request.result ?? null);
};
});
}
export async function loadGlobalClientSecrets() {
return loadClientSecrets(GLOBAL_SOURCE_ID);
}
export async function saveClientSecrets(sourceId, secrets) {
const record = {
sourceId,
webdavBaseUrl: secrets.webdavBaseUrl,
authMode: secrets.authMode,
username: secrets.username,
password: secrets.password,
passphrase: secrets.passphrase,
updatedAt: new Date().toISOString()
};
return withStore('readwrite', (store) => store.put(record));
}
export async function saveGlobalClientSecrets(secrets) {
return saveClientSecrets(GLOBAL_SOURCE_ID, secrets);
}
export async function removeClientSecrets(sourceId) {
return withStore('readwrite', (store) => store.delete(sourceId));
}
export async function removeGlobalClientSecrets() {
return removeClientSecrets(GLOBAL_SOURCE_ID);
}