taler-typescript-core

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

commit fd45c98a9b4ee98d84fef82350aec4ece42853da
parent 53ed96d624fdcbf182594e47acfd484a9bf73dbf
Author: Sebastian <sebasjm@taler-systems.com>
Date:   Mon, 12 Jan 2026 15:00:08 -0300

fix #10805

Diffstat:
Apackages/merchant-backoffice-ui/src/components/form/InputPassword.tsx | 69+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mpackages/merchant-backoffice-ui/src/paths/admin/create/CreatePage.tsx | 20++++++++++++++------
Mpackages/merchant-backoffice-ui/src/paths/instance/accounts/create/CreatePage.tsx | 5+++--
Mpackages/merchant-backoffice-ui/src/paths/instance/accounts/update/UpdatePage.tsx | 9+++++----
Mpackages/merchant-backoffice-ui/src/paths/instance/password/DetailPage.tsx | 9+++++----
Mpackages/merchant-backoffice-ui/src/paths/newAccount/index.tsx | 5+++--
Mpackages/merchant-backoffice-ui/src/paths/resetAccount/index.tsx | 5+++--
7 files changed, 102 insertions(+), 20 deletions(-)

diff --git a/packages/merchant-backoffice-ui/src/components/form/InputPassword.tsx b/packages/merchant-backoffice-ui/src/components/form/InputPassword.tsx @@ -0,0 +1,69 @@ +/* + 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 <http://www.gnu.org/licenses/> + */ + +/** + * + * @author Sebastian Javier Marchano (sebasjm) + */ +import { ComponentChildren, h, VNode } from "preact"; +import { useState } from "preact/hooks"; +import { InputWithAddon } from "./InputWithAddon.js"; +import { InputProps } from "./useField.js"; + +export interface Props<T> extends InputProps<T> { + expand?: boolean; + addonAfter?: ComponentChildren; + children?: ComponentChildren; + side?: ComponentChildren; +} + +export function InputPassword<T>({ + name, + readonly, + label, + placeholder, + help, + tooltip, + expand, + addonAfter, + children, + side, +}: Props<keyof T>): VNode { + const [hide, setHide] = useState(true); + return ( + <InputWithAddon<T> + name={name} + readonly={readonly} + side={side} + label={label} + placeholder={placeholder} + help={help} + tooltip={tooltip} + addonAfterAction={() => { + setHide((h) => !h); + }} + addonAfter={ + <span class="icon"> + {hide ? <i class="mdi mdi-eye-off" /> : <i class="mdi mdi-eye" />} + </span> + } + inputType={hide ? "password" : "text"} + expand={expand} + > + {children} + </InputWithAddon> + ); +} diff --git a/packages/merchant-backoffice-ui/src/paths/admin/create/CreatePage.tsx b/packages/merchant-backoffice-ui/src/paths/admin/create/CreatePage.tsx @@ -53,6 +53,7 @@ import { } from "../../../utils/constants.js"; import { undefinedIfEmpty } from "../../../utils/table.js"; import { FOREVER_REFRESHABLE_TOKEN } from "../../login/index.js"; +import { InputPassword } from "../../../components/form/InputPassword.js"; const TALER_SCREEN_ID = 25; @@ -74,13 +75,20 @@ const twoHours = Duration.fromSpec({ hours: 2 }); const oneDay = Duration.fromSpec({ days: 1 }); const twoDays = Duration.fromSpec({ days: 2 }); -function with_defaults(id: string | undefined, config: TalerMerchantApi.MerchantVersionResponse): Partial<Entity> { +function with_defaults( + id: string | undefined, + config: TalerMerchantApi.MerchantVersionResponse, +): Partial<Entity> { return { id, use_stefan: true, - default_pay_delay: config.default_pay_delay ?? Duration.toTalerProtocolDuration(twoHours), - default_refund_delay: config.default_refund_delay ?? Duration.toTalerProtocolDuration(oneDay), - default_wire_transfer_delay: config.default_wire_transfer_delay ?? Duration.toTalerProtocolDuration(twoDays), + default_pay_delay: + config.default_pay_delay ?? Duration.toTalerProtocolDuration(twoHours), + default_refund_delay: + config.default_refund_delay ?? Duration.toTalerProtocolDuration(oneDay), + default_wire_transfer_delay: + config.default_wire_transfer_delay ?? + Duration.toTalerProtocolDuration(twoDays), }; } @@ -236,11 +244,11 @@ export function CreatePage({ onConfirm, onBack, forceId }: Props): VNode { readonlyId={!!forceId} showId={!forceId} /> - <Input<Entity> + <InputPassword<Entity> + expand name="password" label={i18n.str`New password`} tooltip={i18n.str`Next password to be used`} - inputType="password" /> <Input<Entity> name="repeat" diff --git a/packages/merchant-backoffice-ui/src/paths/instance/accounts/create/CreatePage.tsx b/packages/merchant-backoffice-ui/src/paths/instance/accounts/create/CreatePage.tsx @@ -55,6 +55,7 @@ import { safeConvertURL } from "../update/UpdatePage.js"; import { TestRevenueErrorType, testRevenueAPI } from "./index.js"; import { FragmentPersonaFlag } from "../../../../components/menu/SideBar.js"; import { UIElement, usePreference } from "../../../../hooks/preference.js"; +import { InputPassword } from "../../../../components/form/InputPassword.js"; const TALER_SCREEN_ID = 33; @@ -284,9 +285,9 @@ export function CreatePage({ onCreated, onBack }: Props): VNode { label={i18n.str`Username`} tooltip={i18n.str`Username to access the account information.`} /> - <Input + <InputPassword name="credit_facade_credentials.password" - inputType="password" + expand label={i18n.str`Password`} tooltip={i18n.str`Password to access the account information.`} /> diff --git a/packages/merchant-backoffice-ui/src/paths/instance/accounts/update/UpdatePage.tsx b/packages/merchant-backoffice-ui/src/paths/instance/accounts/update/UpdatePage.tsx @@ -56,6 +56,7 @@ import { undefinedIfEmpty } from "../../../../utils/table.js"; import { TestRevenueErrorType, testRevenueAPI } from "../create/index.js"; import { FragmentPersonaFlag } from "../../../../components/menu/SideBar.js"; import { UIElement, usePreference } from "../../../../hooks/preference.js"; +import { InputPassword } from "../../../../components/form/InputPassword.js"; const TALER_SCREEN_ID = 36; @@ -371,9 +372,9 @@ export function UpdatePage({ account, onUpdated, onBack }: Props): VNode { label={i18n.str`Username`} tooltip={i18n.str`Username to access the account information.`} /> - <Input + <InputPassword name="credit_facade_credentials.password" - inputType="password" + expand label={i18n.str`Password`} tooltip={i18n.str`Password to access the account information.`} /> @@ -381,10 +382,10 @@ export function UpdatePage({ account, onUpdated, onBack }: Props): VNode { ) : undefined} {state.credit_facade_credentials?.type === "bearer" ? ( <Fragment> - <Input + <InputPassword name="credit_facade_credentials.token" label={i18n.str`Token`} - inputType="password" + expand tooltip={i18n.str`Access token to access the account information.`} /> </Fragment> diff --git a/packages/merchant-backoffice-ui/src/paths/instance/password/DetailPage.tsx b/packages/merchant-backoffice-ui/src/paths/instance/password/DetailPage.tsx @@ -29,6 +29,7 @@ import { useState } from "preact/hooks"; import { FormErrors, FormProvider } from "../../../components/form/FormProvider.js"; import { Input } from "../../../components/form/Input.js"; import { undefinedIfEmpty } from "../../../utils/table.js"; +import { InputPassword } from "../../../components/form/InputPassword.js"; const TALER_SCREEN_ID = 53; @@ -98,18 +99,18 @@ export function DetailPage({ <FormProvider errors={errors} object={form} valueHandler={setValue}> <Fragment> {withoutCurrentPassword ? undefined : ( - <Input<State> + <InputPassword<State> name="current" label={i18n.str`Current password`} tooltip={i18n.str`In order to verify that you have access.`} - inputType="password" + expand /> )} - <Input<State> + <InputPassword<State> name="next" + expand label={i18n.str`New password`} tooltip={i18n.str`Next password to be used`} - inputType="password" /> <Input<State> name="repeat" diff --git a/packages/merchant-backoffice-ui/src/paths/newAccount/index.tsx b/packages/merchant-backoffice-ui/src/paths/newAccount/index.tsx @@ -46,6 +46,7 @@ import { INSTANCE_ID_REGEX, PHONE_JUST_NUMBERS_REGEX, } from "../../utils/constants.js"; +import { InputPassword } from "../../components/form/InputPassword.js"; const TALER_SCREEN_ID = 80; @@ -223,10 +224,10 @@ export function NewAccount({ onCancel, onCreated }: Props): VNode { label={i18n.str`Business name`} tooltip={i18n.str`Legal name of the business represented by this instance.`} /> - <Input<Account> + <InputPassword<Account> + expand label={i18n.str`New password`} tooltip={i18n.str`Next password to be used`} - inputType="password" name="password" /> <Input<Account> diff --git a/packages/merchant-backoffice-ui/src/paths/resetAccount/index.tsx b/packages/merchant-backoffice-ui/src/paths/resetAccount/index.tsx @@ -39,6 +39,7 @@ import { SolveMFAChallenges } from "../../components/SolveMFA.js"; import { useSessionContext } from "../../context/session.js"; import { FOREVER_REFRESHABLE_TOKEN } from "../login/index.js"; import { undefinedIfEmpty } from "../../utils/table.js"; +import { InputPassword } from "../../components/form/InputPassword.js"; const TALER_SCREEN_ID = 82; @@ -159,10 +160,10 @@ export function ResetAccount({ object={value} valueHandler={valueHandler} > - <Input<Form> + <InputPassword<Form> label={i18n.str`New password`} - inputType="password" name="password" + expand /> <Input<Form> label={i18n.str`Repeat password`}