diff options
Diffstat (limited to 'packages/exchange-backoffice-ui/src/hooks/useOfficer.ts')
-rw-r--r-- | packages/exchange-backoffice-ui/src/hooks/useOfficer.ts | 100 |
1 files changed, 100 insertions, 0 deletions
diff --git a/packages/exchange-backoffice-ui/src/hooks/useOfficer.ts b/packages/exchange-backoffice-ui/src/hooks/useOfficer.ts new file mode 100644 index 000000000..2ed375846 --- /dev/null +++ b/packages/exchange-backoffice-ui/src/hooks/useOfficer.ts @@ -0,0 +1,100 @@ +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<LockedAccount>; + +export const codecForOfficer = (): Codec<Officer> => + buildCodecForObject<Officer>() + .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<void>; +} +interface OfficerLocked { + state: "locked"; + forget: () => void; + tryUnlock: (password: string) => Promise<void>; +} +interface OfficerReady { + state: "ready"; + account: Account; + forget: () => void; + lock: () => void; +} + +const OFFICER_KEY = buildStorageKey("officer", codecForOfficer()); +const ACCOUNT_KEY = buildStorageKey<Account>("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(); + }, + }; +} |