import { AbsoluteTime, Codec, buildCodecForObject, codecForAbsoluteTime, codecForString, } from "@gnu-taler/taler-util"; import { Account, LockedAccount, createNewAccount, unlockAccount, } from "../account.js"; import { buildStorageKey, useLocalStorage, useMemoryStorage, } from "@gnu-taler/web-util/browser"; export interface Officer { account: LockedAccount; when: AbsoluteTime; } const codecForLockedAccount = codecForString() as Codec; export const codecForOfficer = (): Codec => buildCodecForObject() .property("account", codecForLockedAccount) // FIXME .property("when", codecForAbsoluteTime) // FIXME .build("Officer"); export type OfficerState = OfficerNotReady | OfficerReady; export type OfficerNotReady = OfficerNotFound | OfficerLocked; interface OfficerNotFound { state: "not-found"; create: (password: string) => Promise; } interface OfficerLocked { state: "locked"; forget: () => void; tryUnlock: (password: string) => Promise; } interface OfficerReady { state: "ready"; account: Account; forget: () => void; lock: () => void; } const OFFICER_KEY = buildStorageKey("officer", codecForOfficer()); const ACCOUNT_KEY = buildStorageKey("account"); export function useOfficer(): OfficerState { const accountStorage = useMemoryStorage(ACCOUNT_KEY); const officerStorage = useLocalStorage(OFFICER_KEY); const officer = officerStorage.value; const account = accountStorage.value; if (officer === undefined) { return { state: "not-found", create: async (pwd: string) => { const { accountId, safe, signingKey } = await createNewAccount(pwd); officerStorage.update({ account: safe, when: AbsoluteTime.now(), }); accountStorage.update({ accountId, signingKey }); }, }; } if (account === undefined) { return { state: "locked", forget: () => { officerStorage.reset(); }, tryUnlock: async (pwd: string) => { const ac = await unlockAccount(officer.account, pwd); accountStorage.update(ac); }, }; } return { state: "ready", account: account, lock: () => { accountStorage.reset(); }, forget: () => { officerStorage.reset(); accountStorage.reset(); }, }; }