summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastian <sebasjm@gmail.com>2024-04-15 13:56:21 -0300
committerSebastian <sebasjm@gmail.com>2024-04-15 13:56:21 -0300
commitffd2e70fec069441d56db73da9fa9c8e0633e0dc (patch)
tree2110dbbf9ed2aece0cdc3305968be8e477b80c82
parente07f801aa0d22d84f88ea149bfba82b73c2c9f9c (diff)
downloadwallet-core-ffd2e70fec069441d56db73da9fa9c8e0633e0dc.tar.gz
wallet-core-ffd2e70fec069441d56db73da9fa9c8e0633e0dc.tar.bz2
wallet-core-ffd2e70fec069441d56db73da9fa9c8e0633e0dc.zip
fix #8724
-rw-r--r--packages/merchant-backoffice-ui/src/components/form/InputNumber.tsx5
-rw-r--r--packages/merchant-backoffice-ui/src/components/form/InputPaytoForm.tsx112
2 files changed, 84 insertions, 33 deletions
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<T>({
help={help}
tooltip={tooltip}
inputExtra={{ min: 0 }}
- children={children}
side={side}
- />
+ >
+ {children}
+ </InputWithAddon>
);
}
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<typeof useTranslationContext>["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<typeof useTranslationContext>["i18n"],
): string | undefined {
@@ -98,6 +102,29 @@ function validateEthereum(
}
/**
+ * 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<typeof useTranslationContext>["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.
* If the IBAN is valid, the remainder equals 1.
@@ -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<typeof useTranslationContext>["i18n"],
): string | undefined {
@@ -178,34 +205,36 @@ export function InputPaytoForm<T>({
}: Props<keyof T>): VNode {
const { value: initialValueStr, onChange } = useField<T>(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<Partial<Entity>>(initial)
+ const initial: Entity =
+ initialPayto === undefined
+ ? defaultTarget
+ : {
+ target: initialPayto.targetType,
+ params: initialPayto.params,
+ path1: initialPath1,
+ path2: initialPath2,
+ };
+ const [value, setValue] = useState<Partial<Entity>>(initial);
const { i18n } = useTranslationContext();
const errors: FormErrors<Entity> = {
- 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<T>({
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<T>({
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={<Fragment>
+ <div><i18n.Translate>Without scheme and may include subpath:</i18n.Translate></div>
+ <div>bank.com/</div>
+ <div>bank.com/path/subpath/</div>
+ </Fragment>}
/>
<Input<Entity>
name="path2"
@@ -389,9 +441,7 @@ export function InputPaytoForm<T>({
/>
</Fragment>
)}
-
</FormProvider>
</InputGroup>
);
}
-