aboutsummaryrefslogtreecommitdiff
path: root/packages/demobank-ui/src/pages/RegistrationPage.tsx
diff options
context:
space:
mode:
authorSebastian <sebasjm@gmail.com>2023-02-08 17:41:19 -0300
committerSebastian <sebasjm@gmail.com>2023-02-08 17:41:19 -0300
commita8c5a9696c1735a178158cbc9ac4f9bb4b6f013d (patch)
treefc24dbf06b548925dbc065a49060473fdd220c94 /packages/demobank-ui/src/pages/RegistrationPage.tsx
parent9b0d887a1bc292f652352c1dba4ed4243a88bbbe (diff)
downloadwallet-core-a8c5a9696c1735a178158cbc9ac4f9bb4b6f013d.tar.xz
impl accout management and refactor
Diffstat (limited to 'packages/demobank-ui/src/pages/RegistrationPage.tsx')
-rw-r--r--packages/demobank-ui/src/pages/RegistrationPage.tsx176
1 files changed, 63 insertions, 113 deletions
diff --git a/packages/demobank-ui/src/pages/RegistrationPage.tsx b/packages/demobank-ui/src/pages/RegistrationPage.tsx
index 29f1bf5ee..247ef8d80 100644
--- a/packages/demobank-ui/src/pages/RegistrationPage.tsx
+++ b/packages/demobank-ui/src/pages/RegistrationPage.tsx
@@ -13,38 +13,36 @@
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/>
*/
-import { Logger } from "@gnu-taler/taler-util";
-import { Fragment, h, VNode } from "preact";
-import { route } from "preact-router";
-import { StateUpdater, useState } from "preact/hooks";
-import { useBackendContext } from "../context/backend.js";
-import { PageStateType, usePageContext } from "../context/pageState.js";
+import { HttpStatusCode, Logger } from "@gnu-taler/taler-util";
import {
- InternationalizationAPI,
+ RequestError,
useTranslationContext,
} from "@gnu-taler/web-util/lib/index.browser";
-import { BackendStateHandler } from "../hooks/backend.js";
+import { Fragment, h, VNode } from "preact";
+import { useState } from "preact/hooks";
+import { useBackendContext } from "../context/backend.js";
+import { PageStateType } from "../context/pageState.js";
+import { useTestingAPI } from "../hooks/access.js";
import { bankUiSettings } from "../settings.js";
-import { getBankBackendBaseUrl, undefinedIfEmpty } from "../utils.js";
-import { BankFrame } from "./BankFrame.js";
+import { undefinedIfEmpty } from "../utils.js";
import { ShowInputErrorLabel } from "./ShowInputErrorLabel.js";
const logger = new Logger("RegistrationPage");
-export function RegistrationPage(): VNode {
+export function RegistrationPage({
+ onError,
+ onComplete,
+}: {
+ onComplete: () => void;
+ onError: (e: PageStateType["error"]) => void;
+}): VNode {
const { i18n } = useTranslationContext();
if (!bankUiSettings.allowRegistrations) {
return (
- <BankFrame>
- <p>{i18n.str`Currently, the bank is not accepting new registrations!`}</p>
- </BankFrame>
+ <p>{i18n.str`Currently, the bank is not accepting new registrations!`}</p>
);
}
- return (
- <BankFrame>
- <RegistrationForm />
- </BankFrame>
- );
+ return <RegistrationForm onComplete={onComplete} onError={onError} />;
}
export const USERNAME_REGEX = /^[a-z][a-zA-Z0-9]*$/;
@@ -53,13 +51,19 @@ export const PASSWORD_REGEX = /^[a-z0-9][a-zA-Z0-9]*$/;
/**
* Collect and submit registration data.
*/
-function RegistrationForm(): VNode {
+function RegistrationForm({
+ onComplete,
+ onError,
+}: {
+ onComplete: () => void;
+ onError: (e: PageStateType["error"]) => void;
+}): VNode {
const backend = useBackendContext();
- const { pageState, pageStateSetter } = usePageContext();
const [username, setUsername] = useState<string | undefined>();
const [password, setPassword] = useState<string | undefined>();
const [repeatPassword, setRepeatPassword] = useState<string | undefined>();
+ const { register } = useTestingAPI();
const { i18n } = useTranslationContext();
const errors = undefinedIfEmpty({
@@ -104,6 +108,7 @@ function RegistrationForm(): VNode {
name="register-un"
type="text"
placeholder="Username"
+ autocomplete="username"
value={username ?? ""}
onInput={(e): void => {
setUsername(e.currentTarget.value);
@@ -121,6 +126,7 @@ function RegistrationForm(): VNode {
name="register-pw"
id="register-pw"
placeholder="Password"
+ autocomplete="new-password"
value={password ?? ""}
required
onInput={(e): void => {
@@ -139,6 +145,7 @@ function RegistrationForm(): VNode {
style={{ marginBottom: 8 }}
name="register-repeat"
id="register-repeat"
+ autocomplete="new-password"
placeholder="Same password"
value={repeatPassword ?? ""}
required
@@ -155,19 +162,42 @@ function RegistrationForm(): VNode {
class="pure-button pure-button-primary btn-register"
type="submit"
disabled={!!errors}
- onClick={(e) => {
+ onClick={async (e) => {
e.preventDefault();
- if (!username || !password) return;
- registrationCall(
- { username, password },
- backend, // will store BE URL, if OK.
- pageStateSetter,
- i18n,
- );
- setUsername(undefined);
- setPassword(undefined);
- setRepeatPassword(undefined);
+ if (!username || !password) return;
+ try {
+ const credentials = { username, password };
+ await register(credentials);
+ setUsername(undefined);
+ setPassword(undefined);
+ setRepeatPassword(undefined);
+ backend.logIn(credentials);
+ onComplete();
+ } catch (error) {
+ if (error instanceof RequestError) {
+ const errorData: SandboxBackend.SandboxError =
+ error.info.error;
+ if (error.info.status === HttpStatusCode.Conflict) {
+ onError({
+ title: i18n.str`That username is already taken`,
+ description: errorData.error.description,
+ debug: JSON.stringify(error.info),
+ });
+ } else {
+ onError({
+ title: i18n.str`New registration gave response error`,
+ description: errorData.error.description,
+ debug: JSON.stringify(error.info),
+ });
+ }
+ } else if (error instanceof Error) {
+ onError({
+ title: i18n.str`Registration failed, please report`,
+ description: error.message,
+ });
+ }
+ }
}}
>
{i18n.str`Register`}
@@ -180,7 +210,7 @@ function RegistrationForm(): VNode {
setUsername(undefined);
setPassword(undefined);
setRepeatPassword(undefined);
- route("/account");
+ onComplete();
}}
>
{i18n.str`Cancel`}
@@ -192,83 +222,3 @@ function RegistrationForm(): VNode {
</Fragment>
);
}
-
-/**
- * This function requests /register.
- *
- * This function is responsible to change two states:
- * the backend's (to store the login credentials) and
- * the page's (to indicate a successful login or a problem).
- */
-async function registrationCall(
- req: { username: string; password: string },
- /**
- * FIXME: figure out if the two following
- * functions can be retrieved somewhat from
- * the state.
- */
- backend: BackendStateHandler,
- pageStateSetter: StateUpdater<PageStateType>,
- i18n: InternationalizationAPI,
-): Promise<void> {
- const url = getBankBackendBaseUrl();
-
- const headers = new Headers();
- headers.append("Content-Type", "application/json");
- const registerEndpoint = new URL("access-api/testing/register", url);
- let res: Response;
- try {
- res = await fetch(registerEndpoint.href, {
- method: "POST",
- body: JSON.stringify({
- username: req.username,
- password: req.password,
- }),
- headers,
- });
- } catch (error) {
- logger.error(
- `Could not POST new registration to the bank (${registerEndpoint.href})`,
- error,
- );
- pageStateSetter((prevState) => ({
- ...prevState,
-
- error: {
- title: i18n.str`Registration failed, please report`,
- debug: JSON.stringify(error),
- },
- }));
- return;
- }
- if (!res.ok) {
- const response = await res.json();
- if (res.status === 409) {
- pageStateSetter((prevState) => ({
- ...prevState,
-
- error: {
- title: i18n.str`That username is already taken`,
- debug: JSON.stringify(response),
- },
- }));
- } else {
- pageStateSetter((prevState) => ({
- ...prevState,
-
- error: {
- title: i18n.str`New registration gave response error`,
- debug: JSON.stringify(response),
- },
- }));
- }
- } else {
- // registration was ok
- backend.save({
- url,
- username: req.username,
- password: req.password,
- });
- route("/account");
- }
-}