summaryrefslogtreecommitdiff
path: root/packages/challenger-ui/src/hooks/session.ts
diff options
context:
space:
mode:
authorSebastian <sebasjm@gmail.com>2024-04-21 14:57:13 -0300
committerSebastian <sebasjm@gmail.com>2024-04-22 08:52:56 -0300
commitd046653246d4b397bf81cfadbdfe2d91b46c7e7f (patch)
tree3cfb8e53eff69b17752767574e0b718fdfd2c974 /packages/challenger-ui/src/hooks/session.ts
parent94b2530f2f9ea0e0efdf6e933f6160105265a2c6 (diff)
downloadwallet-core-d046653246d4b397bf81cfadbdfe2d91b46c7e7f.tar.gz
wallet-core-d046653246d4b397bf81cfadbdfe2d91b46c7e7f.tar.bz2
wallet-core-d046653246d4b397bf81cfadbdfe2d91b46c7e7f.zip
challenger spa
Diffstat (limited to 'packages/challenger-ui/src/hooks/session.ts')
-rw-r--r--packages/challenger-ui/src/hooks/session.ts119
1 files changed, 119 insertions, 0 deletions
diff --git a/packages/challenger-ui/src/hooks/session.ts b/packages/challenger-ui/src/hooks/session.ts
new file mode 100644
index 000000000..4bb1bfbc8
--- /dev/null
+++ b/packages/challenger-ui/src/hooks/session.ts
@@ -0,0 +1,119 @@
+/*
+ This file is part of GNU Taler
+ (C) 2022-2024 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+ */
+
+import {
+ Codec,
+ buildCodecForObject,
+ codecForBoolean,
+ codecForNumber,
+ codecForString,
+ codecForStringURL,
+ codecForURL,
+ codecOptional,
+} from "@gnu-taler/taler-util";
+import { buildStorageKey, useLocalStorage } from "@gnu-taler/web-util/browser";
+import { mutate } from "swr";
+
+/**
+ * Has the information to reach and
+ * authenticate at the bank's backend.
+ */
+export type SessionId = {
+ clientId: string;
+ redirectURL: string;
+ state: string;
+};
+
+export type LastChallengeResponse = {
+ attemptsLeft: number;
+ nextSend: string;
+ transmitted: boolean;
+};
+
+export type SessionState = SessionId & {
+ email: string | undefined;
+ lastTry: LastChallengeResponse | undefined;
+ completedURL: string | undefined;
+};
+export const codecForLastChallengeResponse = (): Codec<LastChallengeResponse> =>
+ buildCodecForObject<LastChallengeResponse>()
+ .property("attemptsLeft", codecForNumber())
+ .property("nextSend", codecForString())
+ .property("transmitted", codecForBoolean())
+ .build("LastChallengeResponse");
+
+export const codecForSessionState = (): Codec<SessionState> =>
+ buildCodecForObject<SessionState>()
+ .property("clientId", codecForString())
+ .property("redirectURL", codecForStringURL())
+ .property("completedURL", codecOptional(codecForStringURL()))
+ .property("state", codecForString())
+ .property("lastTry", codecOptional(codecForLastChallengeResponse()))
+ .property("email", codecOptional(codecForString()))
+ .build("SessionState");
+
+export interface SessionStateHandler {
+ state: SessionState | undefined;
+ start(s: SessionId): void;
+ accepted(e: string, l: LastChallengeResponse): void;
+ completed(e: URL): void;
+}
+
+const SESSION_STATE_KEY = buildStorageKey(
+ "challenger-session",
+ codecForSessionState(),
+);
+
+/**
+ * Return getters and setters for
+ * login credentials and backend's
+ * base URL.
+ */
+export function useSessionState(): SessionStateHandler {
+ const { value: state, update } = useLocalStorage(SESSION_STATE_KEY);
+
+ return {
+ state,
+ start(info) {
+ update({
+ ...info,
+ lastTry: undefined,
+ completedURL: undefined,
+ email: undefined,
+ });
+ cleanAllCache();
+ },
+ accepted(email, lastTry) {
+ if (!state) return;
+ update({
+ ...state,
+ email,
+ lastTry,
+ });
+ },
+ completed(url) {
+ if (!state) return;
+ update({
+ ...state,
+ completedURL: url.href,
+ });
+ },
+ };
+}
+
+function cleanAllCache(): void {
+ mutate(() => true, undefined, { revalidate: false });
+}