taler-typescript-core

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

commit c2b9a77f559b3c79f1e0b9cd75daf56ab691ed8c
parent f074734752fbf2b853a6b067ea5b267d1838fef5
Author: Sebastian <sebasjm@taler-systems.com>
Date:   Mon,  9 Feb 2026 12:43:36 -0300

fix #11029

Diffstat:
Mpackages/merchant-backoffice-ui/src/paths/newAccount/index.tsx | 41++++++++++++++++++++++++++++++-----------
Mpackages/taler-util/src/types-taler-merchant.ts | 12++++++++++--
2 files changed, 40 insertions(+), 13 deletions(-)

diff --git a/packages/merchant-backoffice-ui/src/paths/newAccount/index.tsx b/packages/merchant-backoffice-ui/src/paths/newAccount/index.tsx @@ -94,7 +94,10 @@ export function NewAccount({ onCancel, onCreated }: Props): VNode { const { i18n } = useTranslationContext(); const { lib, logIn, config } = useSessionContext(); - const { value: savedForm, update: saveForm } = useLocalStorage(NEWACCOUNT_STATE_KEY, {}); + const { value: savedForm, update: saveForm } = useLocalStorage( + NEWACCOUNT_STATE_KEY, + {}, + ); const [value, setValue] = useState<Partial<Account>>(savedForm); @@ -103,6 +106,14 @@ export function NewAccount({ onCancel, onCreated }: Props): VNode { const serverRequiresSms = config.mandatory_tan_channels?.indexOf(TanChannel.SMS) !== -1; + let phoneRegex: RegExp | undefined = undefined; + if (config.phone_regex) + try { + phoneRegex = new RegExp(config.phone_regex); + } catch (e) { + console.log("invalid phone regex", e); + } + const errors = undefinedIfEmpty<FormErrors<Account>>({ id: !value.id ? i18n.str`Required` @@ -127,10 +138,14 @@ export function NewAccount({ onCancel, onCreated }: Props): VNode { ? undefined : !value.phone ? i18n.str`Required` - : !value.phone.startsWith("+") - ? i18n.str`Should start with +` - : !PHONE_JUST_NUMBERS_REGEX.test(value.phone) - ? i18n.str`A phone number consists of numbers only` + : !phoneRegex + ? !value.phone.startsWith("+") + ? i18n.str`Should start with +` + : !PHONE_JUST_NUMBERS_REGEX.test(value.phone) + ? i18n.str`A phone number consists of numbers only` + : undefined + : !phoneRegex.test(value.phone) + ? i18n.str`Invalid phone number` : undefined, tos: !value.tos ? i18n.str`Required` : undefined, }); @@ -155,7 +170,7 @@ export function NewAccount({ onCancel, onCreated }: Props): VNode { phone: next.phone, tos: next.tos, }; - saveForm(saved) + saveForm(saved); } const [notification, safeFunctionHandler] = useLocalNotificationBetter(); @@ -194,7 +209,7 @@ export function NewAccount({ onCancel, onCreated }: Props): VNode { if (success) { logIn(req.id, success.access_token); } - saveForm({}) + saveForm({}); onCreated(); }; create.onFail = (fail) => { @@ -311,10 +326,14 @@ export function NewAccount({ onCancel, onCreated }: Props): VNode { borderTop: 0, }} > - <button class="button" type="button" onClick={() => { - saveForm({}) - onCancel() - }}> + <button + class="button" + type="button" + onClick={() => { + saveForm({}); + onCancel(); + }} + > <i18n.Translate>Cancel</i18n.Translate> </button> <ButtonBetterBulma onClick={create} type="submit"> diff --git a/packages/taler-util/src/types-taler-merchant.ts b/packages/taler-util/src/types-taler-merchant.ts @@ -1243,6 +1243,12 @@ export interface MerchantVersionResponse { // Since **v25**. report_generators: string[]; + // Posix regular expression for allowed phone numbers; + // applies when creating or patching an instance. + // Optional, can be NULL for no restrictions. + // Since **v26**. + phone_regex?: string; + // Array of exchanges trusted by the merchant. // Since protocol **v6**. exchanges: ExchangeConfigInfo[]; @@ -3184,7 +3190,6 @@ export interface ExpectedTransferDetails { } interface ExchangeTransferReconciliationDetails { - // ID of the order for which these are the // reconciliation details. order_id: string; @@ -3199,7 +3204,6 @@ interface ExchangeTransferReconciliationDetails { // Deposit fees paid to the exchange for this order. deposit_fee: AmountString; - } export interface OtpDeviceAddDetails { @@ -4159,6 +4163,10 @@ export const codecForTalerMerchantConfigResponse = "report_generators", codecOptionalDefault(codecForList(codecForString()), []), ) + .property( + "phone_regex", + codecOptional(codecForString()), + ) .property("exchanges", codecForList(codecForExchangeConfigInfo())) .property("implementation", codecOptional(codecForString())) .property(