taler-typescript-core

Wallet core logic and WebUIs for various components
Log | Files | Refs | Submodules | README | LICENSE

commit 55d6226c7a6270869c787e276dafe3efadf245b8
parent ee908dd7aee66f0756e8a393fc2e8945e20b0283
Author: Sebastian <sebasjm@gmail.com>
Date:   Wed, 21 Aug 2024 19:18:10 -0300

save kyc token

Diffstat:
Mpackages/kyc-ui/src/Routing.tsx | 27+++++++++++++++++++--------
Mpackages/kyc-ui/src/hooks/session.ts | 15++++++++++-----
Mpackages/kyc-ui/src/pages/CallengeCompleted.tsx | 11+++--------
Apackages/kyc-ui/src/pages/SaveToken.tsx | 39+++++++++++++++++++++++++++++++++++++++
Mpackages/kyc-ui/src/pages/Start.tsx | 39++++++++++++++++++++++++---------------
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>