commit 55d6226c7a6270869c787e276dafe3efadf245b8
parent ee908dd7aee66f0756e8a393fc2e8945e20b0283
Author: Sebastian <sebasjm@gmail.com>
Date: Wed, 21 Aug 2024 19:18:10 -0300
save kyc token
Diffstat:
5 files changed, 95 insertions(+), 36 deletions(-)
diff --git a/packages/kyc-ui/src/Routing.tsx b/packages/kyc-ui/src/Routing.tsx
@@ -15,6 +15,7 @@
*/
import {
+ Loading,
urlPattern,
useCurrentLocation,
useNavigationContext,
@@ -27,6 +28,7 @@ import { CallengeCompleted } from "./pages/CallengeCompleted.js";
import { Frame } from "./pages/Frame.js";
import { Start } from "./pages/Start.js";
import { FillForm } from "./pages/FillForm.js";
+import { SaveToken } from "./pages/SaveToken.js";
export function Routing(): VNode {
// check session and defined if this is
@@ -40,9 +42,10 @@ export function Routing(): VNode {
const publicPages = {
completed: urlPattern(/\/completed/, () => `#/completed`),
- start: urlPattern<{ token: string }>(
- /\/info\/(?<token>[0-9A-Za-z]+)/,
- ({ token }) => `#/start/${token}`,
+ start: urlPattern(/\/start/, () => `#/start`),
+ token: urlPattern<{ token: string }>(
+ /\/token\/(?<token>[0-9A-Za-z]+)/,
+ ({ token }) => `#/token/${token}`,
),
};
@@ -74,14 +77,22 @@ function PublicRounting(): VNode {
case undefined: {
return <div>not found</div>;
}
+ case "token": {
+ return (
+ <SaveToken
+ token={location.values.token as AccessToken}
+ onStarted={() => {
+ navigateTo(publicPages.start.url({}));
+ }}
+ />
+ );
+ }
case "start": {
return (
<Start
- //FIX: validate token
- token={location.values.token as AccessToken}
- // onCreated={() => {
- // navigateTo(publicPages.completed.url({}));
- // }}
+ onLoggedOut={() => {
+ navigateTo(publicPages.completed.url({}));
+ }}
/>
);
}
diff --git a/packages/kyc-ui/src/hooks/session.ts b/packages/kyc-ui/src/hooks/session.ts
@@ -17,7 +17,9 @@
import {
AccessToken,
Codec,
- buildCodecForObject
+ buildCodecForObject,
+ codecForAccessToken,
+ codecOptional,
} from "@gnu-taler/taler-util";
import { buildStorageKey, useLocalStorage } from "@gnu-taler/web-util/browser";
@@ -29,14 +31,14 @@ export type SessionId = {
accessToken: AccessToken;
};
-
export type SessionState = {
+ accessToken: AccessToken;
};
export const codecForSessionState = (): Codec<SessionState> =>
buildCodecForObject<SessionState>()
-// .property("completedURL", codecOptional(codecForStringURL()))
-// .property("lastAddress", codecOptional(codecForList(codecForLastAddress())))
+ .property("accessToken", codecForAccessToken())
+ // .property("lastAddress", codecOptional(codecForList(codecForLastAddress())))
.build("SessionState");
export interface SessionStateHandler {
@@ -59,7 +61,10 @@ export function useSessionState(): SessionStateHandler {
return {
state,
- start() {
+ start(s) {
+ update({
+ accessToken: s.accessToken,
+ });
},
};
}
diff --git a/packages/kyc-ui/src/pages/CallengeCompleted.tsx b/packages/kyc-ui/src/pages/CallengeCompleted.tsx
@@ -21,16 +21,11 @@ export function CallengeCompleted(): VNode {
const { state } = useSessionState();
const { i18n } = useTranslationContext();
-
+
return (
<div class="m-4">
- <Attention
- title={i18n.str`Kyc completed`}
- type="success"
- >
- <i18n.Translate>
- You will be redirected to nowhere
- </i18n.Translate>
+ <Attention title={i18n.str`Kyc completed`} type="success">
+ <i18n.Translate>You will be redirected to nowhere</i18n.Translate>
</Attention>
</div>
);
diff --git a/packages/kyc-ui/src/pages/SaveToken.tsx b/packages/kyc-ui/src/pages/SaveToken.tsx
@@ -0,0 +1,39 @@
+/*
+ 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 { AccessToken } from "@gnu-taler/taler-util";
+import { Loading } from "@gnu-taler/web-util/browser";
+import { h, VNode } from "preact";
+import { useSessionState } from "../hooks/session.js";
+import { useEffect } from "preact/hooks";
+
+interface Props {
+ token: AccessToken;
+ onStarted: () => void;
+}
+export function SaveToken({ token, onStarted }: Props): VNode {
+ const { start } = useSessionState();
+ useEffect(() => {
+ if (token) {
+ start({
+ accessToken: token,
+ });
+ onStarted();
+ }
+ }, [token]);
+
+ return <Loading />;
+}
diff --git a/packages/kyc-ui/src/pages/Start.tsx b/packages/kyc-ui/src/pages/Start.tsx
@@ -34,9 +34,10 @@ import { useState } from "preact/hooks";
import { ErrorLoadingWithDebug } from "../components/ErrorLoadingWithDebug.js";
import { useKycInfo } from "../hooks/kyc.js";
import { FillForm } from "./FillForm.js";
+import { useSessionState } from "../hooks/session.js";
type Props = {
- token: AccessToken;
+ onLoggedOut: () => void;
};
function ShowReqList({
@@ -188,16 +189,25 @@ function ShowReqList({
</Fragment>
);
}
-export function Start({ token }: Props): VNode {
+export function Start({ onLoggedOut }: Props): VNode {
+ const { state } = useSessionState();
const [req, setReq] = useState<KycRequirementInformation>();
+ if (!state) {
+ return <Loading />;
+ }
if (!req) {
- return <ShowReqList token={token} onFormSelected={(r) => setReq(r)} />;
+ return (
+ <ShowReqList
+ token={state.accessToken}
+ onFormSelected={(r) => setReq(r)}
+ />
+ );
}
return (
<FillForm
formId={req.form}
requirement={req}
- token={token}
+ token={state.accessToken}
onComplete={() => {
setReq(undefined);
}}
@@ -216,14 +226,16 @@ function RequirementRow({
const { lib } = useExchangeApiContext();
const [notification, withErrorHandler] = useLocalNotificationHandler();
const reqId = req.id;
- const startHandler =
- !reqId ? undefined :
- withErrorHandler(
+ const startHandler = !reqId
+ ? undefined
+ : withErrorHandler(
async () => {
- return lib.exchange.startKycProcess(reqId)
- }, (res) => {
- window.open(res.body.redirect_url, "_blank")
- });
+ return lib.exchange.startKycProcess(reqId);
+ },
+ (res) => {
+ window.open(res.body.redirect_url, "_blank");
+ },
+ );
switch (req.form) {
case "INFO": {
@@ -281,10 +293,7 @@ function RequirementRow({
</div>
<div class="min-w-0 flex-auto">
<p class="text-sm font-semibold leading-6 text-gray-900">
- <Button
- type="submit"
- handler={startHandler}
- >
+ <Button type="submit" handler={startHandler}>
<span class="absolute inset-x-0 -top-px bottom-0"></span>
<i18n.Translate>Begin KYC process</i18n.Translate>
</Button>