[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[taler-wallet-core] 07/19: fix: show error message on login and registra
From: |
gnunet |
Subject: |
[taler-wallet-core] 07/19: fix: show error message on login and registration form, prevent saving password on localstorage |
Date: |
Wed, 07 Dec 2022 20:08:35 +0100 |
This is an automated email from the git hooks/post-receive script.
sebasjm pushed a commit to branch master
in repository wallet-core.
commit ac2f680f6805534fdebad41755d7e112a00cd15a
Author: Sebastian <sebasjm@gmail.com>
AuthorDate: Wed Dec 7 10:53:06 2022 -0300
fix: show error message on login and registration form, prevent saving
password on localstorage
---
packages/demobank-ui/src/pages/home/index.tsx | 240 +++++++++-----------------
1 file changed, 81 insertions(+), 159 deletions(-)
diff --git a/packages/demobank-ui/src/pages/home/index.tsx
b/packages/demobank-ui/src/pages/home/index.tsx
index 884113e85..9927f965c 100644
--- a/packages/demobank-ui/src/pages/home/index.tsx
+++ b/packages/demobank-ui/src/pages/home/index.tsx
@@ -213,32 +213,6 @@ function useWireTransferRequestType(
return [retObj, retSetter];
}
-/**
- * Stores in the state a object containing a 'username'
- * and 'password' field, in order to avoid losing the
- * handle of the data entered by the user in <input> fields.
- */
-type CredentialsRequestTypeOpt = CredentialsRequestType | undefined;
-function useCredentialsRequestType(
- state?: CredentialsRequestType,
-): [CredentialsRequestTypeOpt, StateUpdater<CredentialsRequestTypeOpt>] {
- const ret = hooks.useLocalStorage(
- "credentials-request-state",
- JSON.stringify(state),
- );
- const retObj: CredentialsRequestTypeOpt = ret[0]
- ? JSON.parse(ret[0])
- : ret[0];
- const retSetter: StateUpdater<CredentialsRequestTypeOpt> = function (val) {
- const newVal =
- val instanceof Function
- ? JSON.stringify(val(retObj))
- : JSON.stringify(val);
- ret[1](newVal);
- };
- return [retObj, retSetter];
-}
-
/**
* Request preparators.
*
@@ -597,7 +571,7 @@ async function createWithdrawalCall(
}
async function loginCall(
- req: CredentialsRequestType,
+ req: { username: string; password: string },
/**
* FIXME: figure out if the two following
* functions can be retrieved from the state.
@@ -629,7 +603,7 @@ async function loginCall(
* the page's (to indicate a successful login or a problem).
*/
async function registrationCall(
- req: CredentialsRequestType,
+ req: { username: string; password: string },
/**
* FIXME: figure out if the two following
* functions can be retrieved somewhat from
@@ -882,11 +856,7 @@ function ShowInputErrorLabel({
isDirty: boolean;
}): VNode {
if (message && isDirty)
- return (
- <div class="informational informational-fail" style={{ marginTop: 8 }}>
- {message}
- </div>
- );
+ return <div style={{ marginTop: 8, color: "red" }}>{message}</div>;
return <Fragment />;
}
@@ -1488,24 +1458,6 @@ function PaymentOptions({ currency }: { currency?:
string }): VNode {
);
}
-function RegistrationButton(Props: any): VNode {
- const { backendStateSetter, pageStateSetter } = Props;
- const { i18n } = useTranslationContext();
- if (bankUiSettings.allowRegistrations)
- return (
- <button
- class="pure-button pure-button-secondary btn-cancel"
- onClick={() => {
- route("/register");
- }}
- >
- {i18n.str`Register`}
- </button>
- );
-
- return <span />;
-}
-
function undefinedIfEmpty<T extends object>(obj: T): T | undefined {
return Object.keys(obj).some((k) => (obj as any)[k] !== undefined)
? obj
@@ -1514,21 +1466,21 @@ function undefinedIfEmpty<T extends object>(obj: T): T
| undefined {
/**
* Collect and submit login data.
*/
-function LoginForm(Props: any): VNode {
- const { backendStateSetter, pageStateSetter } = Props;
- const [submitData, submitDataSetter] = useCredentialsRequestType();
+function LoginForm(): VNode {
+ const [backendState, backendStateSetter] = useBackendState();
+ const { pageState, pageStateSetter } = usePageContext();
+ const [username, setUsername] = useState<string | undefined>();
+ const [password, setPassword] = useState<string | undefined>();
const { i18n } = useTranslationContext();
const ref = useRef<HTMLInputElement>(null);
useEffect(() => {
ref.current?.focus();
}, []);
- const errors = !submitData
- ? undefined
- : undefinedIfEmpty({
- username: !submitData.username ? i18n.str`Missing username` :
undefined,
- password: !submitData.password ? i18n.str`Missing password` :
undefined,
- });
+ const errors = undefinedIfEmpty({
+ username: !username ? i18n.str`Missing username` : undefined,
+ password: !password ? i18n.str`Missing password` : undefined,
+ });
return (
<div class="login-div">
@@ -1544,16 +1496,17 @@ function LoginForm(Props: any): VNode {
type="text"
name="username"
id="username"
- value={submitData && submitData.username}
+ value={username ?? ""}
placeholder="Username"
required
onInput={(e): void => {
- submitDataSetter((submitData: any) => ({
- ...submitData,
- username: e.currentTarget.value,
- }));
+ setUsername(e.currentTarget.value);
}}
/>
+ <ShowInputErrorLabel
+ message={errors?.username}
+ isDirty={username !== undefined}
+ />
<p class="passFieldLabel loginFieldLabel formFieldLabel">
<label for="password">{i18n.str`Password:`}</label>
</p>
@@ -1561,50 +1514,48 @@ function LoginForm(Props: any): VNode {
type="password"
name="password"
id="password"
- value={submitData && submitData.password}
+ value={password ?? ""}
placeholder="Password"
required
onInput={(e): void => {
- submitDataSetter((submitData: any) => ({
- ...submitData,
- password: e.currentTarget.value,
- }));
+ setPassword(e.currentTarget.value);
}}
/>
+ <ShowInputErrorLabel
+ message={errors?.password}
+ isDirty={password !== undefined}
+ />
<br />
<button
type="submit"
class="pure-button pure-button-primary"
disabled={!!errors}
onClick={() => {
- if (typeof submitData === "undefined") {
- console.log("login data is undefined", submitData);
- return;
- }
- if (!submitData.password || !submitData.username) {
- console.log(
- "username or password is the empty string",
- submitData,
- );
- return;
- }
+ if (!username || !password) return;
loginCall(
- // Deep copy, to avoid the cleanup
- // below make data disappear.
- { ...submitData },
+ { username, password },
backendStateSetter,
pageStateSetter,
);
- submitDataSetter({
- password: "",
- repeatPassword: "",
- username: "",
- });
+ setUsername(undefined);
+ setPassword(undefined);
}}
>
{i18n.str`Login`}
</button>
- {RegistrationButton(Props)}
+
+ {bankUiSettings.allowRegistrations ? (
+ <button
+ class="pure-button pure-button-secondary btn-cancel"
+ onClick={() => {
+ route("/register");
+ }}
+ >
+ {i18n.str`Register`}
+ </button>
+ ) : (
+ <div />
+ )}
</div>
</form>
</div>
@@ -1615,24 +1566,23 @@ function LoginForm(Props: any): VNode {
* Collect and submit registration data.
*/
function RegistrationForm(): VNode {
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
-
const [backendState, backendStateSetter] = useBackendState();
const { pageState, pageStateSetter } = usePageContext();
- const [submitData, submitDataSetter] = useCredentialsRequestType();
+ const [username, setUsername] = useState<string | undefined>();
+ const [password, setPassword] = useState<string | undefined>();
+ const [repeatPassword, setRepeatPassword] = useState<string | undefined>();
+
const { i18n } = useTranslationContext();
- const errors = !submitData
- ? undefined
- : undefinedIfEmpty({
- username: !submitData.username ? i18n.str`Missing username` :
undefined,
- password: !submitData.password ? i18n.str`Missing password` :
undefined,
- repeatPassword: !submitData.repeatPassword
- ? i18n.str`Missing password`
- : submitData.repeatPassword !== submitData.password
- ? i18n.str`Password don't match`
- : undefined,
- });
+ const errors = undefinedIfEmpty({
+ username: !username ? i18n.str`Missing username` : undefined,
+ password: !password ? i18n.str`Missing password` : undefined,
+ repeatPassword: !repeatPassword
+ ? i18n.str`Missing password`
+ : repeatPassword !== password
+ ? i18n.str`Password don't match`
+ : undefined,
+ });
return (
<Fragment>
@@ -1650,16 +1600,15 @@ function RegistrationForm(): VNode {
name="register-un"
type="text"
placeholder="Username"
- value={submitData && submitData.username}
- required
+ value={username ?? ""}
onInput={(e): void => {
- submitDataSetter((submitData: any) => ({
- ...submitData,
- username: e.currentTarget.value,
- }));
+ setUsername(e.currentTarget.value);
}}
/>
- <br />
+ <ShowInputErrorLabel
+ message={errors?.username}
+ isDirty={username !== undefined}
+ />
<p class="unameFieldLabel registerFieldLabel formFieldLabel">
<label for="register-pw">{i18n.str`Password:`}</label>
</p>
@@ -1668,15 +1617,16 @@ function RegistrationForm(): VNode {
name="register-pw"
id="register-pw"
placeholder="Password"
- value={submitData && submitData.password}
+ value={password ?? ""}
required
onInput={(e): void => {
- submitDataSetter((submitData: any) => ({
- ...submitData,
- password: e.currentTarget.value,
- }));
+ setPassword(e.currentTarget.value);
}}
/>
+ <ShowInputErrorLabel
+ message={errors?.password}
+ isDirty={username !== undefined}
+ />
<p class="unameFieldLabel registerFieldLabel formFieldLabel">
<label for="register-repeat">{i18n.str`Repeat
Password:`}</label>
</p>
@@ -1686,57 +1636,31 @@ function RegistrationForm(): VNode {
name="register-repeat"
id="register-repeat"
placeholder="Same password"
- value={submitData && submitData.repeatPassword}
+ value={repeatPassword ?? ""}
required
onInput={(e): void => {
- submitDataSetter((submitData: any) => ({
- ...submitData,
- repeatPassword: e.currentTarget.value,
- }));
+ setRepeatPassword(e.currentTarget.value);
}}
/>
+ <ShowInputErrorLabel
+ message={errors?.repeatPassword}
+ isDirty={username !== undefined}
+ />
<br />
- {/*
- <label for="phone">{i18n.str`Phone number:`}</label>
- // FIXME: add input validation (must start with +, otherwise
only numbers)
- <input
- name="phone"
- id="phone"
- type="phone"
- placeholder="+CC-123456789"
- value={submitData && submitData.phone}
- required
- onInput={(e): void => {
- submitDataSetter((submitData: any) => ({
- ...submitData,
- phone: e.currentTarget.value,
- }))}} />
- <br />
- */}
<button
class="pure-button pure-button-primary btn-register"
disabled={!!errors}
onClick={() => {
- console.log("maybe submitting the registration..");
- if (!submitData) return;
+ if (!username || !password) return;
registrationCall(
- { ...submitData },
+ { username, password },
backendStateSetter, // will store BE URL, if OK.
pageStateSetter,
);
- console.log("Clearing the input data");
- /**
- * FIXME: clearing the data should be done by setting
- * it to undefined, instead of the empty strings, just
- * like done in the login function. Now set to the empty
- * strings due to a non lively update of the <input> fields
- * after setting to undefined.
- */
- submitDataSetter({
- username: "",
- password: "",
- repeatPassword: "",
- });
+
+ setUsername(undefined);
+ setPassword(undefined);
+ setRepeatPassword(undefined);
}}
>
{i18n.str`Register`}
@@ -1745,11 +1669,9 @@ function RegistrationForm(): VNode {
<button
class="pure-button pure-button-secondary btn-cancel"
onClick={() => {
- submitDataSetter({
- username: "",
- password: "",
- repeatPassword: "",
- });
+ setUsername(undefined);
+ setPassword(undefined);
+ setRepeatPassword(undefined);
route("/account");
}}
>
--
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.
- [taler-wallet-core] 13/19: also listen for tab title change, (continued)
- [taler-wallet-core] 13/19: also listen for tab title change, gnunet, 2022/12/07
- [taler-wallet-core] 01/19: pretty, gnunet, 2022/12/07
- [taler-wallet-core] 05/19: fix: empty form should not allow the "send" button, gnunet, 2022/12/07
- [taler-wallet-core] 19/19: no-fix: user logger instead of console.log, gnunet, 2022/12/07
- [taler-wallet-core] 11/19: no-fix: removing unused showPublicHistories, gnunet, 2022/12/07
- [taler-wallet-core] 15/19: fix jsx config, gnunet, 2022/12/07
- [taler-wallet-core] 14/19: fix: updating the title is better that location.hash, gnunet, 2022/12/07
- [taler-wallet-core] 08/19: no-fix: move out routing, gnunet, 2022/12/07
- [taler-wallet-core] 16/19: no-fix: remove unused, gnunet, 2022/12/07
- [taler-wallet-core] 12/19: no-fix: moved out AccountPage, gnunet, 2022/12/07
- [taler-wallet-core] 07/19: fix: show error message on login and registration form, prevent saving password on localstorage,
gnunet <=
- [taler-wallet-core] 18/19: feature: useLocalStorage also update when the localStorage has been updated from other window, gnunet, 2022/12/07
- [taler-wallet-core] 06/19: fix: better loading page while waiting for server response, gnunet, 2022/12/07
- [taler-wallet-core] 17/19: no-fix: remove 'any' and login status is taken from backend, gnunet, 2022/12/07
- [taler-wallet-core] 09/19: no-fix: moving out public histories page, gnunet, 2022/12/07
- [taler-wallet-core] 10/19: no-fix: moving out registration page, gnunet, 2022/12/07