/* This file is part of GNU Taler (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 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 */ /** * * @author Sebastian Javier Marchano (sebasjm) */ import { useTranslationContext } from "@gnu-taler/web-util/browser"; import { h, VNode } from "preact"; import { useState } from "preact/hooks"; import { AsyncButton } from "../../../components/exception/AsyncButton.js"; import { FormErrors, FormProvider, } from "../../../components/form/FormProvider.js"; import { DefaultInstanceFormFields } from "../../../components/instance/DefaultInstanceFormFields.js"; import { MerchantBackend } from "../../../declaration.js"; import { INSTANCE_ID_REGEX } from "../../../utils/constants.js"; import { undefinedIfEmpty } from "../../../utils/table.js"; import { SetTokenNewInstanceModal } from "../../../components/modal/index.js"; import { Duration } from "@gnu-taler/taler-util"; export type Entity = Omit, "default_wire_transfer_delay"> & { auth_token?: string; default_pay_delay: Duration, default_wire_transfer_delay: Duration, }; interface Props { onCreate: (d: MerchantBackend.Instances.InstanceConfigurationMessage) => Promise; onBack?: () => void; forceId?: string; } function with_defaults(id?: string): Partial { return { id, // accounts: [], user_type: "business", use_stefan: true, default_pay_delay: { d_ms: 2 * 60 * 60 * 1000 }, // two hours default_wire_transfer_delay: { d_ms: 2 * 60 * 60 * 24 * 1000 }, // two days }; } export function CreatePage({ onCreate, onBack, forceId }: Props): VNode { const [value, valueHandler] = useState(with_defaults(forceId)); const [isTokenSet, updateIsTokenSet] = useState(false); const [isTokenDialogActive, updateIsTokenDialogActive] = useState(false); const { i18n } = useTranslationContext(); const errors: FormErrors = { id: !value.id ? i18n.str`required` : !INSTANCE_ID_REGEX.test(value.id) ? i18n.str`is not valid` : undefined, name: !value.name ? i18n.str`required` : undefined, user_type: !value.user_type ? i18n.str`required` : value.user_type !== "business" && value.user_type !== "individual" ? i18n.str`should be business or individual` : undefined, // accounts: // !value.accounts || !value.accounts.length // ? i18n.str`required` // : undefinedIfEmpty( // value.accounts.map((p) => { // return !PAYTO_REGEX.test(p.payto_uri) // ? i18n.str`is not valid` // : undefined; // }), // ), default_pay_delay: !value.default_pay_delay ? i18n.str`required` : !!value.default_wire_transfer_delay && value.default_wire_transfer_delay.d_ms !== "forever" && value.default_pay_delay.d_ms !== "forever" && value.default_pay_delay.d_ms > value.default_wire_transfer_delay.d_ms ? i18n.str`pay delay can't be greater than wire transfer delay` : undefined, default_wire_transfer_delay: !value.default_wire_transfer_delay ? i18n.str`required` : undefined, address: undefinedIfEmpty({ address_lines: value.address?.address_lines && value.address?.address_lines.length > 7 ? i18n.str`max 7 lines` : undefined, }), jurisdiction: undefinedIfEmpty({ address_lines: value.address?.address_lines && value.address?.address_lines.length > 7 ? i18n.str`max 7 lines` : undefined, }), }; const hasErrors = Object.keys(errors).some( (k) => (errors as any)[k] !== undefined, ); const submit = (): Promise => { // use conversion instead of this const newValue = structuredClone(value); const newToken = newValue.auth_token; newValue.auth_token = undefined; newValue.auth = newToken === null || newToken === undefined ? { method: "external" } : { method: "token", token: `secret-token:${newToken}` }; if (!newValue.address) newValue.address = {}; if (!newValue.jurisdiction) newValue.jurisdiction = {}; // remove above use conversion // schema.validateSync(value, { abortEarly: false }) newValue.default_pay_delay = Duration.toTalerProtocolDuration(newValue.default_pay_delay!) as any newValue.default_wire_transfer_delay = Duration.toTalerProtocolDuration(newValue.default_wire_transfer_delay!) as any // delete value.default_pay_delay; // delete value.default_wire_transfer_delay; return onCreate(newValue as any as MerchantBackend.Instances.InstanceConfigurationMessage); }; function updateToken(token: string | null) { valueHandler((old) => ({ ...old, auth_token: token === null ? undefined : token, })); } return (
{isTokenDialogActive && ( { updateIsTokenDialogActive(false); updateIsTokenSet(false); }} onClear={() => { updateToken(null); updateIsTokenDialogActive(false); updateIsTokenSet(true); }} onConfirm={(newToken) => { updateToken(newToken); updateIsTokenDialogActive(false); updateIsTokenSet(true); }} /> )}
errors={errors} object={value} valueHandler={valueHandler} >

{!isTokenSet ? (

Access token is not yet configured. This instance can't be created.

) : value.auth_token === undefined ? (

No access token. Authorization must be handled externally.

) : (

Access token is set. Authorization is handled by the merchant backend.

)}
{onBack && ( )} Confirm
); }