commit fd45c98a9b4ee98d84fef82350aec4ece42853da
parent 53ed96d624fdcbf182594e47acfd484a9bf73dbf
Author: Sebastian <sebasjm@taler-systems.com>
Date: Mon, 12 Jan 2026 15:00:08 -0300
fix #10805
Diffstat:
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`}