From e1d86816a7c07cb8ca2d54676d5cdbbe513f2ba7 Mon Sep 17 00:00:00 2001 From: Sebastian Date: Mon, 4 Sep 2023 14:17:55 -0300 Subject: backoffcie new version, lot of changes --- .../src/paths/instance/token/DetailPage.tsx | 165 +++++++++++++++++++++ .../src/paths/instance/token/index.tsx | 90 +++++++++++ .../src/paths/instance/token/stories.tsx | 28 ++++ 3 files changed, 283 insertions(+) create mode 100644 packages/merchant-backoffice-ui/src/paths/instance/token/DetailPage.tsx create mode 100644 packages/merchant-backoffice-ui/src/paths/instance/token/index.tsx create mode 100644 packages/merchant-backoffice-ui/src/paths/instance/token/stories.tsx (limited to 'packages/merchant-backoffice-ui/src/paths/instance/token') diff --git a/packages/merchant-backoffice-ui/src/paths/instance/token/DetailPage.tsx b/packages/merchant-backoffice-ui/src/paths/instance/token/DetailPage.tsx new file mode 100644 index 000000000..6ab2a2df6 --- /dev/null +++ b/packages/merchant-backoffice-ui/src/paths/instance/token/DetailPage.tsx @@ -0,0 +1,165 @@ +/* + This file is part of GNU Taler + (C) 2021-2023 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 + */ + +/** + * + * @author Sebastian Javier Marchano (sebasjm) + */ + +import { useTranslationContext } from "@gnu-taler/web-util/browser"; +import { Fragment, h, VNode } from "preact"; +import { useState } from "preact/hooks"; +import { AsyncButton } from "../../../components/exception/AsyncButton.js"; +import { FormProvider } from "../../../components/form/FormProvider.js"; +import { Input } from "../../../components/form/Input.js"; +import { useInstanceContext } from "../../../context/instance.js"; + +interface Props { + instanceId: string; + currentToken: string | undefined; + onClearToken: () => void; + onNewToken: (s: string) => void; + onBack?: () => void; +} + +export function DetailPage({ instanceId, currentToken: oldToken, onBack, onNewToken, onClearToken }: Props): VNode { + type State = { old_token: string; new_token: string; repeat_token: string }; + const [form, setValue] = useState>({ + old_token: "", + new_token: "", + repeat_token: "", + }); + const { i18n } = useTranslationContext(); + + const hasOldtoken = !!oldToken + const hasInputTheCorrectOldToken = hasOldtoken && oldToken !== form.old_token; + const errors = { + old_token: hasInputTheCorrectOldToken + ? i18n.str`is not the same as the current access token` + : undefined, + new_token: !form.new_token + ? i18n.str`cannot be empty` + : form.new_token === form.old_token + ? i18n.str`cannot be the same as the old token` + : undefined, + repeat_token: + form.new_token !== form.repeat_token + ? i18n.str`is not the same` + : undefined, + }; + + const hasErrors = Object.keys(errors).some( + (k) => (errors as any)[k] !== undefined, + ); + + const instance = useInstanceContext(); + + const text = i18n.str`You are updating the access token from instance with id ${instance.id}`; + + async function submitForm() { + if (hasErrors) return; + onNewToken(form.new_token as any) + } + + return ( +
+
+
+
+
+
+
+ + Instace id: {instanceId} + +
+
+
+
+
+
+ +
+
+
+ + {hasOldtoken && ( + + name="old_token" + label={i18n.str`Current access token`} + tooltip={i18n.str`access token currently in use`} + inputType="password" + /> + )} + {!hasInputTheCorrectOldToken && + {hasOldtoken && +

+ + Clearing the access token will mean public access to the instance. + +

+
+ +
+
+ } + + + name="new_token" + label={i18n.str`New access token`} + tooltip={i18n.str`next access token to be used`} + inputType="password" + /> + + name="repeat_token" + label={i18n.str`Repeat access token`} + tooltip={i18n.str`confirm the same access token`} + inputType="password" + /> +
} +
+
+ {onBack && ( + + )} + + Confirm change + +
+
+
+
+ +
+
+ ); +} diff --git a/packages/merchant-backoffice-ui/src/paths/instance/token/index.tsx b/packages/merchant-backoffice-ui/src/paths/instance/token/index.tsx new file mode 100644 index 000000000..d5910361b --- /dev/null +++ b/packages/merchant-backoffice-ui/src/paths/instance/token/index.tsx @@ -0,0 +1,90 @@ +/* + This file is part of GNU Taler + (C) 2021-2023 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 + */ +import { HttpStatusCode } from "@gnu-taler/taler-util"; +import { ErrorType, HttpError, useTranslationContext } from "@gnu-taler/web-util/browser"; +import { Fragment, VNode, h } from "preact"; +import { Loading } from "../../../components/exception/loading.js"; +import { MerchantBackend } from "../../../declaration.js"; +import { useInstanceAPI, useInstanceDetails } from "../../../hooks/instance.js"; +import { DetailPage } from "./DetailPage.js"; +import { useInstanceContext } from "../../../context/instance.js"; +import { useState } from "preact/hooks"; +import { NotificationCard } from "../../../components/menu/index.js"; +import { Notification } from "../../../utils/types.js"; +import { useBackendContext } from "../../../context/backend.js"; + +interface Props { + onUnauthorized: () => VNode; + onLoadError: (error: HttpError) => VNode; + onChange: () => void; + onNotFound: () => VNode; +} + +const PREFIX = "secret-token:" + +export default function Token({ + onLoadError, + onChange, + onUnauthorized, + onNotFound, +}: Props): VNode { + const { i18n } = useTranslationContext(); + + const [notif, setNotif] = useState(undefined); + const { clearToken, setNewToken } = useInstanceAPI(); + const { token: rootToken } = useBackendContext(); + const { token: instanceToken, id, admin } = useInstanceContext(); + + const currentToken = !admin ? rootToken : instanceToken + const hasPrefix = currentToken !== undefined && currentToken.startsWith(PREFIX) + return ( + + + => { + try { + await clearToken(); + onChange(); + } catch (error) { + if (error instanceof Error) { + setNotif({ + message: i18n.str`Failed to clear token`, + type: "ERROR", + description: error.message, + }); + } + } + }} + onNewToken={async (newToken): Promise => { + try { + await setNewToken(`secret-token:${newToken}`); + onChange(); + } catch (error) { + if (error instanceof Error) { + setNotif({ + message: i18n.str`Failed to set new token`, + type: "ERROR", + description: error.message, + }); + } + } + }} + /> + + ); +} diff --git a/packages/merchant-backoffice-ui/src/paths/instance/token/stories.tsx b/packages/merchant-backoffice-ui/src/paths/instance/token/stories.tsx new file mode 100644 index 000000000..5f0f56f2d --- /dev/null +++ b/packages/merchant-backoffice-ui/src/paths/instance/token/stories.tsx @@ -0,0 +1,28 @@ +/* + This file is part of GNU Taler + (C) 2021-2023 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 + */ + +/** + * + * @author Sebastian Javier Marchano (sebasjm) + */ + +import { DetailPage as TestedComponent } from "./DetailPage.js"; + +export default { + title: "Pages/Token", + component: TestedComponent, +}; + -- cgit v1.2.3 From 6c3cfa9be7a332c2cc8490f25ebd6c73c8244842 Mon Sep 17 00:00:00 2001 From: Sebastian Date: Fri, 8 Sep 2023 18:45:13 -0300 Subject: codespell fix --- build-system/taler-build-scripts | 2 +- packages/idb-bridge/src/backend-interface.ts | 2 +- packages/merchant-backoffice-ui/src/InstanceRoutes.tsx | 4 ++-- .../merchant-backoffice-ui/src/components/product/ProductForm.tsx | 2 +- .../merchant-backoffice-ui/src/paths/instance/token/DetailPage.tsx | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) (limited to 'packages/merchant-backoffice-ui/src/paths/instance/token') diff --git a/build-system/taler-build-scripts b/build-system/taler-build-scripts index 23538677f..001f5dd08 160000 --- a/build-system/taler-build-scripts +++ b/build-system/taler-build-scripts @@ -1 +1 @@ -Subproject commit 23538677f6c6be2a62f38dc6137ecdd1c76b7b15 +Subproject commit 001f5dd081fc8729ff8def90c4a1c3f93eb8689a diff --git a/packages/idb-bridge/src/backend-interface.ts b/packages/idb-bridge/src/backend-interface.ts index 3255261e2..690f92f54 100644 --- a/packages/idb-bridge/src/backend-interface.ts +++ b/packages/idb-bridge/src/backend-interface.ts @@ -144,7 +144,7 @@ export interface IndexMeta { unique: boolean; } -// FIXME: Instead of refering to an object store by name, +// FIXME: Instead of referring to an object store by name, // maybe refer to it via some internal, numeric ID? // This would simplify renaming. export interface Backend { diff --git a/packages/merchant-backoffice-ui/src/InstanceRoutes.tsx b/packages/merchant-backoffice-ui/src/InstanceRoutes.tsx index 4a4b3fee4..ee8db9a9f 100644 --- a/packages/merchant-backoffice-ui/src/InstanceRoutes.tsx +++ b/packages/merchant-backoffice-ui/src/InstanceRoutes.tsx @@ -118,7 +118,7 @@ export enum InstancePaths { validators_update = "/validators/:vid/update", validators_new = "/validators/new", - settings = "/inteface", + settings = "/interface", } // eslint-disable-next-line @typescript-eslint/no-empty-function @@ -252,7 +252,7 @@ export function InstanceRoutes({ instance={id} admin={admin} onShowSettings={() => { - route("/inteface") + route(InstancePaths.settings) }} path={path} onLogout={clearTokenAndGoToRoot} diff --git a/packages/merchant-backoffice-ui/src/components/product/ProductForm.tsx b/packages/merchant-backoffice-ui/src/components/product/ProductForm.tsx index 4cd90aa45..726a94f5e 100644 --- a/packages/merchant-backoffice-ui/src/components/product/ProductForm.tsx +++ b/packages/merchant-backoffice-ui/src/components/product/ProductForm.tsx @@ -148,7 +148,7 @@ export function ProductForm({ onSubscribe, initial, alreadyExist }: Props) { name="minimum_age" label={i18n.str`Age restricted`} tooltip={i18n.str`is this product restricted for customer below certain age?`} - help={i18n.str`can be overriden by the order configuration`} + help={i18n.str`can be overridden by the order configuration`} /> name="unit" diff --git a/packages/merchant-backoffice-ui/src/paths/instance/token/DetailPage.tsx b/packages/merchant-backoffice-ui/src/paths/instance/token/DetailPage.tsx index 6ab2a2df6..984880752 100644 --- a/packages/merchant-backoffice-ui/src/paths/instance/token/DetailPage.tsx +++ b/packages/merchant-backoffice-ui/src/paths/instance/token/DetailPage.tsx @@ -83,7 +83,7 @@ export function DetailPage({ instanceId, currentToken: oldToken, onBack, onNewTo
- Instace id: {instanceId} + Instance id: {instanceId}
-- cgit v1.2.3