From ffd2e70fec069441d56db73da9fa9c8e0633e0dc Mon Sep 17 00:00:00 2001 From: Sebastian Date: Mon, 15 Apr 2024 13:56:21 -0300 Subject: fix #8724 --- .../src/components/form/InputNumber.tsx | 5 +- .../src/components/form/InputPaytoForm.tsx | 112 +++++++++++++++------ 2 files changed, 84 insertions(+), 33 deletions(-) (limited to 'packages/merchant-backoffice-ui/src') diff --git a/packages/merchant-backoffice-ui/src/components/form/InputNumber.tsx b/packages/merchant-backoffice-ui/src/components/form/InputNumber.tsx index 10b28cd93..38444b85d 100644 --- a/packages/merchant-backoffice-ui/src/components/form/InputNumber.tsx +++ b/packages/merchant-backoffice-ui/src/components/form/InputNumber.tsx @@ -53,8 +53,9 @@ export function InputNumber({ help={help} tooltip={tooltip} inputExtra={{ min: 0 }} - children={children} side={side} - /> + > + {children} + ); } diff --git a/packages/merchant-backoffice-ui/src/components/form/InputPaytoForm.tsx b/packages/merchant-backoffice-ui/src/components/form/InputPaytoForm.tsx index 3337e5f57..a0c15c77c 100644 --- a/packages/merchant-backoffice-ui/src/components/form/InputPaytoForm.tsx +++ b/packages/merchant-backoffice-ui/src/components/form/InputPaytoForm.tsx @@ -18,7 +18,11 @@ * * @author Sebastian Javier Marchano (sebasjm) */ -import { parsePaytoUri, PaytoUriGeneric, stringifyPaytoUri } from "@gnu-taler/taler-util"; +import { + parsePaytoUri, + PaytoUriGeneric, + stringifyPaytoUri, +} from "@gnu-taler/taler-util"; import { useTranslationContext } from "@gnu-taler/web-util/browser"; import { Fragment, h, VNode } from "preact"; import { COUNTRY_TABLE } from "../../utils/constants.js"; @@ -71,7 +75,7 @@ function checkAddressChecksum(address: string) { return true; } -function validateBitcoin( +function validateBitcoin_path1( addr: string, i18n: ReturnType["i18n"], ): string | undefined { @@ -84,7 +88,7 @@ function validateBitcoin( return i18n.str`This is not a valid bitcoin address.`; } -function validateEthereum( +function validateEthereum_path1( addr: string, i18n: ReturnType["i18n"], ): string | undefined { @@ -97,6 +101,29 @@ function validateEthereum( return i18n.str`This is not a valid Ethereum address.`; } +/** + * validates + * bank.com/ + * bank.com + * bank.com/path + * bank.com/path/subpath/ + */ +const DOMAIN_REGEX = /^[a-zA-Z0-9][a-zA-Z0-9-]{1,61}[a-zA-Z0-9](?:\.[a-zA-Z]{2,})+(\/[a-zA-Z0-9-.]+)*\/?$/ + +function validateTalerBank_path1( + addr: string, + i18n: ReturnType["i18n"], +): string | undefined { + console.log(addr, DOMAIN_REGEX.test(addr)) + try { + const valid = DOMAIN_REGEX.test(addr); + if (valid) return undefined; + } catch (e) { + console.log(e); + } + return i18n.str`This is not a valid host.`; +} + /** * An IBAN is validated by converting it into an integer and performing a * basic mod-97 operation (as described in ISO 7064) on it. @@ -111,7 +138,7 @@ function validateEthereum( * If the remainder is 1, the check digit test is passed and the IBAN might be valid. * */ -function validateIBAN( +function validateIBAN_path1( iban: string, i18n: ReturnType["i18n"], ): string | undefined { @@ -178,34 +205,36 @@ export function InputPaytoForm({ }: Props): VNode { const { value: initialValueStr, onChange } = useField(name); - const initialPayto = parsePaytoUri(initialValueStr ?? "") - const paths = !initialPayto ? [] : initialPayto.targetPath.split("/") + const initialPayto = parsePaytoUri(initialValueStr ?? ""); + const paths = !initialPayto ? [] : initialPayto.targetPath.split("/"); const initialPath1 = paths.length >= 1 ? paths[0] : undefined; const initialPath2 = paths.length >= 2 ? paths[1] : undefined; - const initial: Entity = initialPayto === undefined ? defaultTarget : { - target: initialPayto.targetType, - params: initialPayto.params, - path1: initialPath1, - path2: initialPath2, - } - const [value, setValue] = useState>(initial) + const initial: Entity = + initialPayto === undefined + ? defaultTarget + : { + target: initialPayto.targetType, + params: initialPayto.params, + path1: initialPath1, + path2: initialPath2, + }; + const [value, setValue] = useState>(initial); const { i18n } = useTranslationContext(); const errors: FormErrors = { - target: - value.target === noTargetValue - ? i18n.str`required` - : undefined, + target: value.target === noTargetValue ? i18n.str`required` : undefined, path1: !value.path1 ? i18n.str`required` : value.target === "iban" - ? validateIBAN(value.path1, i18n) + ? validateIBAN_path1(value.path1, i18n) : value.target === "bitcoin" - ? validateBitcoin(value.path1, i18n) + ? validateBitcoin_path1(value.path1, i18n) : value.target === "ethereum" - ? validateEthereum(value.path1, i18n) - : undefined, + ? validateEthereum_path1(value.path1, i18n) + : value.target === "x-taler-bank" + ? validateTalerBank_path1(value.path1, i18n) + : undefined, path2: value.target === "x-taler-bank" ? !value.path2 @@ -222,15 +251,22 @@ export function InputPaytoForm({ const hasErrors = Object.keys(errors).some( (k) => (errors as any)[k] !== undefined, ); - const str = hasErrors || !value.target ? undefined : stringifyPaytoUri({ - targetType: value.target, - targetPath: value.path2 ? `${value.path1}/${value.path2}` : (value.path1 ?? ""), - params: value.params ?? {} as any, - isKnown: false, - }) + + const path1WithSlash = value.path1 && !value.path1.endsWith("/") ? value.path1 + "/" : value.path1 + const str = + hasErrors || !value.target + ? undefined + : stringifyPaytoUri({ + targetType: value.target, + targetPath: value.path2 + ? `${path1WithSlash}${value.path2}` + : value.path1 ?? "", + params: value.params ?? ({} as any), + isKnown: false, + }); useEffect(() => { - onChange(str as any) - }, [str]) + onChange(str as any); + }, [str]); // const submit = useCallback((): void => { // // const accounts: TalerMerchantApi.AccountAddDetails[] = paytos; @@ -365,7 +401,23 @@ export function InputPaytoForm({ name="path1" readonly={readonly} label={i18n.str`Host`} + fromStr={(v) => { + if (v.startsWith("http")) { + try { + const url = new URL(v); + return url.host + url.pathname; + } catch { + return v; + } + } + return v; + }} tooltip={i18n.str`Bank host.`} + help={ +
Without scheme and may include subpath:
+
bank.com/
+
bank.com/path/subpath/
+
} /> name="path2" @@ -389,9 +441,7 @@ export function InputPaytoForm({ /> )} - ); } - -- cgit v1.2.3