diff options
Diffstat (limited to 'packages/merchant-backoffice-ui/src/paths/instance/otp_devices/create')
4 files changed, 42 insertions, 47 deletions
diff --git a/packages/merchant-backoffice-ui/src/paths/instance/otp_devices/create/Create.stories.tsx b/packages/merchant-backoffice-ui/src/paths/instance/otp_devices/create/Create.stories.tsx index 26f851cc8..36b31ebe8 100644 --- a/packages/merchant-backoffice-ui/src/paths/instance/otp_devices/create/Create.stories.tsx +++ b/packages/merchant-backoffice-ui/src/paths/instance/otp_devices/create/Create.stories.tsx @@ -1,6 +1,6 @@ /* This file is part of GNU Taler - (C) 2021-2023 Taler Systems S.A. + (C) 2021-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 diff --git a/packages/merchant-backoffice-ui/src/paths/instance/otp_devices/create/CreatePage.tsx b/packages/merchant-backoffice-ui/src/paths/instance/otp_devices/create/CreatePage.tsx index 5f1ae26a3..d5522c2d4 100644 --- a/packages/merchant-backoffice-ui/src/paths/instance/otp_devices/create/CreatePage.tsx +++ b/packages/merchant-backoffice-ui/src/paths/instance/otp_devices/create/CreatePage.tsx @@ -1,6 +1,6 @@ /* This file is part of GNU Taler - (C) 2021-2023 Taler Systems S.A. + (C) 2021-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 @@ -19,8 +19,13 @@ * @author Sebastian Javier Marchano (sebasjm) */ +import { + TalerMerchantApi, + isRfc3548Base32Charset, + randomRfc3548Base32Key, +} from "@gnu-taler/taler-util"; import { useTranslationContext } from "@gnu-taler/web-util/browser"; -import { Fragment, h, VNode } from "preact"; +import { Fragment, VNode, h } from "preact"; import { useState } from "preact/hooks"; import { AsyncButton } from "../../../../components/exception/AsyncButton.js"; import { @@ -28,18 +33,10 @@ import { FormProvider, } from "../../../../components/form/FormProvider.js"; import { Input } from "../../../../components/form/Input.js"; -import { InputCurrency } from "../../../../components/form/InputCurrency.js"; -import { InputDuration } from "../../../../components/form/InputDuration.js"; -import { InputNumber } from "../../../../components/form/InputNumber.js"; -import { useBackendContext } from "../../../../context/backend.js"; -import { MerchantBackend } from "../../../../declaration.js"; import { InputSelector } from "../../../../components/form/InputSelector.js"; import { InputWithAddon } from "../../../../components/form/InputWithAddon.js"; -import { isBase32RFC3548Charset, randomBase32Key } from "../../../../utils/crypto.js"; -import { QR } from "../../../../components/exception/QR.js"; -import { useInstanceContext } from "../../../../context/instance.js"; -type Entity = MerchantBackend.OTP.OtpDeviceAddDetails; +type Entity = TalerMerchantApi.OtpDeviceAddDetails; interface Props { onCreate: (d: Entity) => Promise<void>; @@ -49,32 +46,32 @@ interface Props { const algorithms = [0, 1, 2]; const algorithmsNames = ["off", "30s 8d TOTP-SHA1", "30s 8d eTOTP-SHA1"]; - export function CreatePage({ onCreate, onBack }: Props): VNode { const { i18n } = useTranslationContext(); - const backend = useBackendContext(); const [state, setState] = useState<Partial<Entity>>({}); const [showKey, setShowKey] = useState(false); const errors: FormErrors<Entity> = { - otp_device_id: !state.otp_device_id ? i18n.str`required` + otp_device_id: !state.otp_device_id + ? i18n.str`required` : !/[a-zA-Z0-9]*/.test(state.otp_device_id) ? i18n.str`no valid. only characters and numbers` : undefined, otp_algorithm: !state.otp_algorithm ? i18n.str`required` : undefined, - otp_key: !state.otp_key ? i18n.str`required` : - !isBase32RFC3548Charset(state.otp_key) + otp_key: !state.otp_key + ? i18n.str`required` + : !isRfc3548Base32Charset(state.otp_key) ? i18n.str`just letters and numbers from 2 to 7` : state.otp_key.length !== 32 ? i18n.str`size of the key should be 32` : undefined, - otp_device_description: !state.otp_device_description ? i18n.str`required` + otp_device_description: !state.otp_device_description + ? i18n.str`required` : !/[a-zA-Z0-9]*/.test(state.otp_device_description) ? i18n.str`no valid. only characters and numbers` : undefined, - }; const hasErrors = Object.keys(errors).some( @@ -115,7 +112,7 @@ export function CreatePage({ onCreate, onBack }: Props): VNode { toStr={(v) => algorithmsNames[v]} fromStr={(v) => Number(v)} /> - {state.otp_algorithm && state.otp_algorithm > 0 ? ( + {state.otp_algorithm ? ( <Fragment> <InputWithAddon<Entity> expand @@ -129,7 +126,7 @@ export function CreatePage({ onCreate, onBack }: Props): VNode { setShowKey(!showKey); }} addonAfter={ - <span class="icon" > + <span class="icon"> {showKey ? ( <i class="mdi mdi-eye" /> ) : ( @@ -142,7 +139,11 @@ export function CreatePage({ onCreate, onBack }: Props): VNode { data-tooltip={i18n.str`generate random secret key`} class="button is-info mr-3" onClick={(e) => { - setState((s) => ({ ...s, otp_key: randomBase32Key() })); + setState((s) => ({ + ...s, + otp_key: randomRfc3548Base32Key(), + })); + e.preventDefault(); }} > <i18n.Translate>random</i18n.Translate> diff --git a/packages/merchant-backoffice-ui/src/paths/instance/otp_devices/create/CreatedSuccessfully.tsx b/packages/merchant-backoffice-ui/src/paths/instance/otp_devices/create/CreatedSuccessfully.tsx index db3842711..7723bec81 100644 --- a/packages/merchant-backoffice-ui/src/paths/instance/otp_devices/create/CreatedSuccessfully.tsx +++ b/packages/merchant-backoffice-ui/src/paths/instance/otp_devices/create/CreatedSuccessfully.tsx @@ -1,6 +1,6 @@ /* This file is part of GNU Taler - (C) 2021-2023 Taler Systems S.A. + (C) 2021-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 @@ -14,41 +14,35 @@ GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/> */ +import { TalerMerchantApi } from "@gnu-taler/taler-util"; import { useTranslationContext } from "@gnu-taler/web-util/browser"; -import { Fragment, VNode, h } from "preact"; +import { VNode, h } from "preact"; import { QR } from "../../../../components/exception/QR.js"; import { CreatedSuccessfully as Template } from "../../../../components/notifications/CreatedSuccessfully.js"; -import { useInstanceContext } from "../../../../context/instance.js"; -import { MerchantBackend } from "../../../../declaration.js"; -import { useBackendContext } from "../../../../context/backend.js"; +import { useSessionContext } from "../../../../context/session.js"; -type Entity = MerchantBackend.OTP.OtpDeviceAddDetails; +type Entity = TalerMerchantApi.OtpDeviceAddDetails; interface Props { entity: Entity; onConfirm: () => void; } -function isNotUndefined<X>(x: X | undefined): x is X { - return !!x; -} - export function CreatedSuccessfully({ entity, onConfirm, }: Props): VNode { const { i18n } = useTranslationContext(); - const { url: backendURL } = useBackendContext() - const { id: instanceId } = useInstanceContext(); - const issuer = new URL(backendURL).hostname; - const qrText = `otpauth://totp/${instanceId}/${entity.otp_device_id}?issuer=${issuer}&algorithm=SHA1&digits=8&period=30&secret=${entity.otp_key}`; - const qrTextSafe = `otpauth://totp/${instanceId}/${entity.otp_device_id}?issuer=${issuer}&algorithm=SHA1&digits=8&period=30&secret=${entity.otp_key.substring(0, 6)}...`; + const { state } = useSessionContext(); + const issuer = state.backendUrl.href; + const qrText = `otpauth://totp/${state.instance}/${entity.otp_device_id}?issuer=${issuer}&algorithm=SHA1&digits=8&period=30&secret=${entity.otp_key}`; + const qrTextSafe = `otpauth://totp/${state.instance}/${entity.otp_device_id}?issuer=${issuer}&algorithm=SHA1&digits=8&period=30&secret=${entity.otp_key.substring(0, 6)}...`; return ( <Template onConfirm={onConfirm} > <p class="is-size-5"> <i18n.Translate> - You can scan the next QR code with your device or safe the key before continue. + You can scan the next QR code with your device or save the key before continuing. </i18n.Translate> </p> <div class="field is-horizontal"> diff --git a/packages/merchant-backoffice-ui/src/paths/instance/otp_devices/create/index.tsx b/packages/merchant-backoffice-ui/src/paths/instance/otp_devices/create/index.tsx index 648846793..8ab0e1f26 100644 --- a/packages/merchant-backoffice-ui/src/paths/instance/otp_devices/create/index.tsx +++ b/packages/merchant-backoffice-ui/src/paths/instance/otp_devices/create/index.tsx @@ -1,6 +1,6 @@ /* This file is part of GNU Taler - (C) 2021-2023 Taler Systems S.A. + (C) 2021-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 @@ -19,28 +19,28 @@ * @author Sebastian Javier Marchano (sebasjm) */ +import { TalerMerchantApi } from "@gnu-taler/taler-util"; import { useTranslationContext } from "@gnu-taler/web-util/browser"; -import { Fragment, h, VNode } from "preact"; +import { Fragment, VNode, h } from "preact"; import { useState } from "preact/hooks"; import { NotificationCard } from "../../../../components/menu/index.js"; -import { MerchantBackend } from "../../../../declaration.js"; -import { useWebhookAPI } from "../../../../hooks/webhooks.js"; +import { useSessionContext } from "../../../../context/session.js"; import { Notification } from "../../../../utils/types.js"; import { CreatePage } from "./CreatePage.js"; -import { useOtpDeviceAPI } from "../../../../hooks/otp.js"; import { CreatedSuccessfully } from "./CreatedSuccessfully.js"; -export type Entity = MerchantBackend.OTP.OtpDeviceAddDetails; +export type Entity = TalerMerchantApi.OtpDeviceAddDetails; interface Props { onBack?: () => void; onConfirm: () => void; } export default function CreateValidator({ onConfirm, onBack }: Props): VNode { - const { createOtpDevice } = useOtpDeviceAPI(); + const { lib: api } = useSessionContext(); + const { state } = useSessionContext(); const [notif, setNotif] = useState<Notification | undefined>(undefined); const { i18n } = useTranslationContext(); - const [created, setCreated] = useState<MerchantBackend.OTP.OtpDeviceAddDetails | null>(null) + const [created, setCreated] = useState<TalerMerchantApi.OtpDeviceAddDetails | null>(null) if (created) { return <CreatedSuccessfully entity={created} onConfirm={onConfirm} /> @@ -52,7 +52,7 @@ export default function CreateValidator({ onConfirm, onBack }: Props): VNode { <CreatePage onBack={onBack} onCreate={(request: Entity) => { - return createOtpDevice(request) + return api.instance.addOtpDevice(state.token, request) .then((d) => { setCreated(request) }) |