feat: load all accounts req

This commit is contained in:
2025-05-24 12:16:11 +02:00
parent 04bd27607f
commit 68e2ece877

View File

@ -22,29 +22,59 @@ export interface CreateAccountRequest {
export const useAccountRepo = () => {
const { db } = useDbContext();
const encryptToken = useCallback(async (token: string) => {
const encoder = new TextEncoder();
const iv = crypto.getRandomValues(new Uint8Array(12));
const getDeviceKey = useCallback(async () => {
const deviceId = await getDeviceId();
const deviceKey = await deriveDeviceKey(deviceId);
const cipherText = await crypto.subtle.encrypt(
{ name: "AES-GCM", iv },
deviceKey,
encoder.encode(token)
);
return {
data: Array.from(new Uint8Array(cipherText)),
iv: Array.from(iv),
};
return deviceKey;
}, []);
const encryptToken = useCallback(
async (token: string) => {
const encoder = new TextEncoder();
const iv = crypto.getRandomValues(new Uint8Array(12));
const deviceKey = await getDeviceKey();
const cipherText = await crypto.subtle.encrypt(
{ name: "AES-GCM", iv },
deviceKey,
encoder.encode(token)
);
return {
data: Array.from(new Uint8Array(cipherText)),
iv: Array.from(iv),
};
},
[getDeviceKey]
);
const decryptToken = useCallback(
async (encrypted: { data: number[]; iv: number[] }) => {
const decoder = new TextDecoder();
const deviceKey = await getDeviceKey();
const decrypted = await crypto.subtle.decrypt(
{
name: "AES-GCM",
iv: new Uint8Array(encrypted.iv),
},
deviceKey,
new Uint8Array(encrypted.data)
);
return decoder.decode(decrypted);
},
[getDeviceKey]
);
const save = useCallback(
async (req: CreateAccountRequest) => {
console.log({ db });
if (!db) throw new Error("No database connection");
const access = await encryptToken(req.access);
const refresh = await encryptToken(req.refresh);
@ -60,5 +90,34 @@ export const useAccountRepo = () => {
[db, encryptToken]
);
return { save };
const loadAll = useCallback(async () => {
if (!db) throw new Error("No database connection");
const tx = db.transaction("accounts", "readonly");
const store = tx.objectStore("accounts");
const accounts: LocalAccount[] = await store.getAll();
const results = [];
for (const account of accounts) {
try {
const accessToken = await decryptToken(account.access);
const refreshToken = await decryptToken(account.refresh);
results.push({
accountId: account.accountId,
label: account.label,
email: account.email,
access: accessToken,
refresh: refreshToken,
updatedAt: account.updatedAt,
});
} catch (err) {
console.warn(`Failed to decrypt account ${account.label}:`, err);
}
}
return results;
}, [db, decryptToken]);
return { save, loadAll };
};