From 1653130de893a0a1bdbdef785244aa6ae34ca4e7 Mon Sep 17 00:00:00 2001 From: Sebastian Date: Thu, 14 Sep 2023 12:14:21 -0300 Subject: update how access token management is handled --- .../src/ApplicationReadyRoutes.tsx | 2 +- .../merchant-backoffice-ui/src/hooks/backend.ts | 2 +- .../merchant-backoffice-ui/src/hooks/instance.ts | 20 +++--- .../src/paths/instance/token/DetailPage.tsx | 77 ++++++++++++---------- .../src/paths/instance/token/index.tsx | 37 +++++++---- 5 files changed, 80 insertions(+), 58 deletions(-) (limited to 'packages/merchant-backoffice-ui') diff --git a/packages/merchant-backoffice-ui/src/ApplicationReadyRoutes.tsx b/packages/merchant-backoffice-ui/src/ApplicationReadyRoutes.tsx index 8bfbdb076..ebfa2b6d6 100644 --- a/packages/merchant-backoffice-ui/src/ApplicationReadyRoutes.tsx +++ b/packages/merchant-backoffice-ui/src/ApplicationReadyRoutes.tsx @@ -114,7 +114,7 @@ export function ApplicationReadyRoutes(): VNode { diff --git a/packages/merchant-backoffice-ui/src/hooks/backend.ts b/packages/merchant-backoffice-ui/src/hooks/backend.ts index fe4155788..eaeede103 100644 --- a/packages/merchant-backoffice-ui/src/hooks/backend.ts +++ b/packages/merchant-backoffice-ui/src/hooks/backend.ts @@ -266,7 +266,7 @@ export function useBackendBaseRequest(): useBackendBaseRequestType { endpoint: string, options: RequestOptions = {}, ): Promise> { - return requestHandler(backend, endpoint, { token, ...options }).then(res => { + return requestHandler(backend, endpoint, { ...options, token }).then(res => { return res }).catch(err => { throw err diff --git a/packages/merchant-backoffice-ui/src/hooks/instance.ts b/packages/merchant-backoffice-ui/src/hooks/instance.ts index 50f9487a3..0677191db 100644 --- a/packages/merchant-backoffice-ui/src/hooks/instance.ts +++ b/packages/merchant-backoffice-ui/src/hooks/instance.ts @@ -36,8 +36,8 @@ interface InstanceAPI { data: MerchantBackend.Instances.InstanceReconfigurationMessage, ) => Promise; deleteInstance: () => Promise; - clearToken: () => Promise; - setNewToken: (token: AccessToken) => Promise; + clearAccessToken: (currentToken: AccessToken | undefined) => Promise; + setNewAccessToken: (currentToken: AccessToken | undefined, token: AccessToken) => Promise; } export function useAdminAPI(): AdminAPI { @@ -111,18 +111,20 @@ export function useManagementAPI(instanceId: string): InstanceAPI { mutateAll(/\/management\/instances/); }; - const clearToken = async (): Promise => { + const clearAccessToken = async (currentToken: AccessToken | undefined): Promise => { await request(`/management/instances/${instanceId}/auth`, { method: "POST", + token: currentToken, data: { method: "external" }, }); mutateAll(/\/management\/instances/); }; - const setNewToken = async (newToken: AccessToken): Promise => { + const setNewAccessToken = async (currentToken: AccessToken | undefined, newToken: AccessToken): Promise => { await request(`/management/instances/${instanceId}/auth`, { method: "POST", + token: currentToken, data: { method: "token", token: newToken }, }); @@ -137,7 +139,7 @@ export function useManagementAPI(instanceId: string): InstanceAPI { mutateAll(/\/management\/instances/); }; - return { updateInstance, deleteInstance, setNewToken, clearToken }; + return { updateInstance, deleteInstance, setNewAccessToken, clearAccessToken }; } export function useInstanceAPI(): InstanceAPI { @@ -172,18 +174,20 @@ export function useInstanceAPI(): InstanceAPI { mutate([`/private/`], null); }; - const clearToken = async (): Promise => { + const clearAccessToken = async (currentToken: AccessToken | undefined): Promise => { await request(`/private/auth`, { method: "POST", + token: currentToken, data: { method: "external" }, }); mutate([`/private/`], null); }; - const setNewToken = async (newToken: AccessToken): Promise => { + const setNewAccessToken = async (currentToken: AccessToken | undefined, newToken: AccessToken): Promise => { await request(`/private/auth`, { method: "POST", + token: currentToken, data: { method: "token", token: newToken }, }); @@ -198,7 +202,7 @@ export function useInstanceAPI(): InstanceAPI { mutate([`/private/`], null); }; - return { updateInstance, deleteInstance, setNewToken, clearToken }; + return { updateInstance, deleteInstance, setNewAccessToken, clearAccessToken }; } export function useInstanceDetails(): HttpResponse< 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 4b0db200a..89dba63b2 100644 --- a/packages/merchant-backoffice-ui/src/paths/instance/token/DetailPage.tsx +++ b/packages/merchant-backoffice-ui/src/paths/instance/token/DetailPage.tsx @@ -30,13 +30,13 @@ import { AccessToken } from "../../../declaration.js"; interface Props { instanceId: string; - currentToken: string | undefined; - onClearToken: () => void; - onNewToken: (s: AccessToken) => void; + hasToken: boolean | undefined; + onClearToken: (c: AccessToken | undefined) => void; + onNewToken: (c: AccessToken | undefined, s: AccessToken) => void; onBack?: () => void; } -export function DetailPage({ instanceId, currentToken: oldToken, onBack, onNewToken, onClearToken }: Props): VNode { +export function DetailPage({ instanceId, hasToken, onBack, onNewToken, onClearToken }: Props): VNode { type State = { old_token: string; new_token: string; repeat_token: string }; const [form, setValue] = useState>({ old_token: "", @@ -45,11 +45,9 @@ export function DetailPage({ instanceId, currentToken: oldToken, onBack, onNewTo }); 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` + old_token: hasToken && !form.old_token + ? i18n.str`you need your access token to perform the operation` : undefined, new_token: !form.new_token ? i18n.str`cannot be empty` @@ -72,8 +70,9 @@ export function DetailPage({ instanceId, currentToken: oldToken, onBack, onNewTo async function submitForm() { if (hasErrors) return; + const ot = hasToken ? `secret-token:${form.old_token}` as AccessToken : undefined; const nt = `secret-token:${form.new_token}` as AccessToken; - onNewToken(nt) + onNewToken(ot, nt) } return ( @@ -98,32 +97,38 @@ export function DetailPage({ instanceId, currentToken: oldToken, onBack, onNewTo
- {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. - -

-
- -
-
- } + + {hasToken && ( + + + name="old_token" + label={i18n.str`Current access token`} + tooltip={i18n.str`access token currently in use`} + inputType="password" + /> +

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

+
+ +
+
+ )} + name="new_token" @@ -137,7 +142,7 @@ export function DetailPage({ instanceId, currentToken: oldToken, onBack, onNewTo tooltip={i18n.str`confirm the same access token`} inputType="password" /> -
} +
{onBack && ( diff --git a/packages/merchant-backoffice-ui/src/paths/instance/token/index.tsx b/packages/merchant-backoffice-ui/src/paths/instance/token/index.tsx index 0a49448f8..bc2bd9fa3 100644 --- a/packages/merchant-backoffice-ui/src/paths/instance/token/index.tsx +++ b/packages/merchant-backoffice-ui/src/paths/instance/token/index.tsx @@ -33,8 +33,6 @@ interface Props { onNotFound: () => VNode; } -const PREFIX = "secret-token:" - export default function Token({ onLoadError, onChange, @@ -44,21 +42,36 @@ export default function Token({ const { i18n } = useTranslationContext(); const [notif, setNotif] = useState(undefined); - const { clearToken, setNewToken } = useInstanceAPI(); - const { token: rootToken } = useBackendContext(); - const { token: instanceToken, id, admin } = useInstanceContext(); + const { clearAccessToken, setNewAccessToken } = useInstanceAPI(); + const { id } = useInstanceContext(); + const result = useInstanceDetails() + + if (result.loading) return ; + if (!result.ok) { + if ( + result.type === ErrorType.CLIENT && + result.status === HttpStatusCode.Unauthorized + ) + return onUnauthorized(); + if ( + result.type === ErrorType.CLIENT && + result.status === HttpStatusCode.NotFound + ) + return onNotFound(); + return onLoadError(result); + } + + const hasToken = result.data.auth.method === "token" - const currentToken = !admin ? rootToken : instanceToken - const hasPrefix = currentToken !== undefined && currentToken.token.startsWith(PREFIX) return ( => { + hasToken={hasToken} + onClearToken={async (currentToken): Promise => { try { - await clearToken(); + await clearAccessToken(currentToken); onChange(); } catch (error) { if (error instanceof Error) { @@ -70,9 +83,9 @@ export default function Token({ } } }} - onNewToken={async (newToken): Promise => { + onNewToken={async (currentToken, newToken): Promise => { try { - await setNewToken(newToken); + await setNewAccessToken(currentToken, newToken); onChange(); } catch (error) { if (error instanceof Error) { -- cgit v1.2.3 From 59ef010b0e1f1eaf938a20a46f52d7c94af7b10d Mon Sep 17 00:00:00 2001 From: Sebastian Date: Thu, 14 Sep 2023 13:10:21 -0300 Subject: update testing --- .../merchant-backoffice-ui/src/context/backend.test.ts | 4 ++-- .../merchant-backoffice-ui/src/hooks/instance.test.ts | 4 ++-- .../src/paths/instance/update/UpdatePage.tsx | 4 ---- .../src/paths/instance/update/index.tsx | 17 ++++------------- 4 files changed, 8 insertions(+), 21 deletions(-) (limited to 'packages/merchant-backoffice-ui') diff --git a/packages/merchant-backoffice-ui/src/context/backend.test.ts b/packages/merchant-backoffice-ui/src/context/backend.test.ts index b042d5a25..ad6393e29 100644 --- a/packages/merchant-backoffice-ui/src/context/backend.test.ts +++ b/packages/merchant-backoffice-ui/src/context/backend.test.ts @@ -64,7 +64,7 @@ describe("backend context api ", () => { } as MerchantBackend.Instances.QueryInstancesResponse, }); - management.setNewToken("another_token" as AccessToken); + management.setNewAccessToken(undefined,"another_token" as AccessToken); }, ({ instance, management, admin }) => { expect(env.assertJustExpectedRequestWereMade()).deep.eq({ @@ -113,7 +113,7 @@ describe("backend context api ", () => { name: "instance_name", } as MerchantBackend.Instances.QueryInstancesResponse, }); - instance.setNewToken("another_token" as AccessToken); + instance.setNewAccessToken(undefined, "another_token" as AccessToken); }, ({ instance, management, admin }) => { expect(env.assertJustExpectedRequestWereMade()).deep.eq({ diff --git a/packages/merchant-backoffice-ui/src/hooks/instance.test.ts b/packages/merchant-backoffice-ui/src/hooks/instance.test.ts index a7b8d047c..0c0c44590 100644 --- a/packages/merchant-backoffice-ui/src/hooks/instance.test.ts +++ b/packages/merchant-backoffice-ui/src/hooks/instance.test.ts @@ -158,7 +158,7 @@ describe("instance api interaction with details", () => { }, } as MerchantBackend.Instances.QueryInstancesResponse, }); - api.setNewToken("secret" as AccessToken); + api.setNewAccessToken(undefined, "secret" as AccessToken); }, ({ query, api }) => { expect(env.assertJustExpectedRequestWereMade()).deep.eq({ @@ -234,7 +234,7 @@ describe("instance api interaction with details", () => { } as MerchantBackend.Instances.QueryInstancesResponse, }); - api.clearToken(); + api.clearAccessToken(undefined); }, ({ query, api }) => { expect(env.assertJustExpectedRequestWereMade()).deep.eq({ diff --git a/packages/merchant-backoffice-ui/src/paths/instance/update/UpdatePage.tsx b/packages/merchant-backoffice-ui/src/paths/instance/update/UpdatePage.tsx index a1c608f15..01a3d0252 100644 --- a/packages/merchant-backoffice-ui/src/paths/instance/update/UpdatePage.tsx +++ b/packages/merchant-backoffice-ui/src/paths/instance/update/UpdatePage.tsx @@ -39,9 +39,6 @@ type Entity = MerchantBackend.Instances.InstanceReconfigurationMessage & { //MerchantBackend.Instances.InstanceAuthConfigurationMessage interface Props { onUpdate: (d: Entity) => void; - onChangeAuth: ( - d: MerchantBackend.Instances.InstanceAuthConfigurationMessage, - ) => Promise; selected: MerchantBackend.Instances.QueryInstancesResponse; isLoading: boolean; onBack: () => void; @@ -78,7 +75,6 @@ function getTokenValuePart(t?: string): string | undefined { export function UpdatePage({ onUpdate, - onChangeAuth, selected, onBack, }: Props): VNode { diff --git a/packages/merchant-backoffice-ui/src/paths/instance/update/index.tsx b/packages/merchant-backoffice-ui/src/paths/instance/update/index.tsx index 6c5e7a514..e44cf5c0f 100644 --- a/packages/merchant-backoffice-ui/src/paths/instance/update/index.tsx +++ b/packages/merchant-backoffice-ui/src/paths/instance/update/index.tsx @@ -46,17 +46,17 @@ export interface Props { } export default function Update(props: Props): VNode { - const { updateInstance, clearToken, setNewToken } = useInstanceAPI(); + const { updateInstance } = useInstanceAPI(); const result = useInstanceDetails(); - return CommonUpdate(props, result, updateInstance, clearToken, setNewToken); + return CommonUpdate(props, result, updateInstance, ); } export function AdminUpdate(props: Props & { instanceId: string }): VNode { - const { updateInstance, clearToken, setNewToken } = useManagementAPI( + const { updateInstance } = useManagementAPI( props.instanceId, ); const result = useManagedInstanceDetails(props.instanceId); - return CommonUpdate(props, result, updateInstance, clearToken, setNewToken); + return CommonUpdate(props, result, updateInstance, ); } function CommonUpdate( @@ -73,8 +73,6 @@ function CommonUpdate( MerchantBackend.ErrorDetail >, updateInstance: any, - clearToken: () => Promise, - setNewToken: (t: AccessToken) => Promise, ): VNode { const [notif, setNotif] = useState(undefined); const { i18n } = useTranslationContext(); @@ -114,13 +112,6 @@ function CommonUpdate( }), ); }} - onChangeAuth={( - d: MerchantBackend.Instances.InstanceAuthConfigurationMessage, - ): Promise => { - const apiCall = - d.method === "external" ? clearToken() : setNewToken(d.token! as AccessToken); - return apiCall.then(onConfirm).catch(onUpdateError); - }} /> ); -- cgit v1.2.3 From 467f96869536a76ed0d129e38f237a77b31b1f60 Mon Sep 17 00:00:00 2001 From: Florian Dold Date: Thu, 28 Sep 2023 17:50:53 +0200 Subject: build system: support DESTDIR --- Makefile | 23 ++++++++++++++--------- packages/aml-backoffice-ui/Makefile | 3 ++- packages/anastasis-cli/Makefile | 21 +++++++++++---------- packages/demobank-ui/Makefile | 3 ++- packages/merchant-backoffice-ui/Makefile | 3 ++- packages/taler-harness/Makefile | 22 ++++++++++++---------- packages/taler-wallet-cli/Makefile | 27 ++++++++++++++------------- 7 files changed, 57 insertions(+), 45 deletions(-) (limited to 'packages/merchant-backoffice-ui') diff --git a/Makefile b/Makefile index 45deb0d2c..7b4003b74 100644 --- a/Makefile +++ b/Makefile @@ -9,6 +9,11 @@ git-archive-all = ./build-system/taler-build-scripts/archive-with-submodules/git include .config.mk +# Let recursive Makefiles know that they're being invoked +# from the top-level makefile. +export TOPLEVEL := yes +export TOP_DESTDIR := $(abspath $(DESTDIR)) + .PHONY: compile compile: pnpm install -r --frozen-lockfile @@ -121,18 +126,18 @@ lint: install: pnpm install --frozen-lockfile pnpm run compile - make -C packages/taler-wallet-cli TOPLEVEL=yes install-nodeps - make -C packages/anastasis-cli TOPLEVEL=yes install-nodeps - make -C packages/taler-harness TOPLEVEL=yes install-nodeps - make -C packages/demobank-ui TOPLEVEL=yes install-nodeps - make -C packages/merchant-backoffice-ui TOPLEVEL=yes install-nodeps - make -C packages/aml-backoffice-ui TOPLEVEL=yes install-nodeps + $(MAKE) -C packages/taler-wallet-cli install-nodeps + $(MAKE) -C packages/anastasis-cli install-nodeps + $(MAKE) -C packages/taler-harness install-nodeps + $(MAKE) -C packages/demobank-ui install-nodeps + $(MAKE) -C packages/merchant-backoffice-ui install-nodeps + $(MAKE) -C packages/aml-backoffice-ui install-nodeps .PHONY: install-tools # Install taler-wallet-cli, anastasis-cli and taler-harness install-tools: pnpm install --frozen-lockfile --filter @gnu-taler/taler-wallet-cli... --filter @gnu-taler/anastasis-cli... --filter @gnu-taler/taler-harness... pnpm run --filter @gnu-taler/taler-wallet-cli... --filter @gnu-taler/anastasis-cli... --filter @gnu-taler/taler-harness... compile - make -C packages/taler-wallet-cli TOPLEVEL=yes install-nodeps - make -C packages/anastasis-cli TOPLEVEL=yes install-nodeps - make -C packages/taler-harness TOPLEVEL=yes install-nodeps + $(MAKE) -C packages/taler-wallet-cli install-nodeps + $(MAKE) -C packages/anastasis-cli install-nodeps + $(MAKE) -C packages/taler-harness install-nodeps diff --git a/packages/aml-backoffice-ui/Makefile b/packages/aml-backoffice-ui/Makefile index 2653ce92f..64f9f83d1 100644 --- a/packages/aml-backoffice-ui/Makefile +++ b/packages/aml-backoffice-ui/Makefile @@ -3,6 +3,7 @@ ifeq ($(TOPLEVEL), yes) $(info top-level build) -include ../../.config.mk + override DESTDIR := $(TOP_DESTDIR) else $(info package-level build) -include ../../.config.mk @@ -15,7 +16,7 @@ $(info prefix is $(prefix)) all: @echo run \'make install\' to install -spa_dir=$(prefix)/share/taler/aml-backoffice-ui +spa_dir=$(DESTDIR)$(prefix)/share/taler/aml-backoffice-ui .PHONY: install-nodeps install-nodeps: diff --git a/packages/anastasis-cli/Makefile b/packages/anastasis-cli/Makefile index 292f7000f..de6c92a7b 100644 --- a/packages/anastasis-cli/Makefile +++ b/packages/anastasis-cli/Makefile @@ -3,6 +3,7 @@ ifeq ($(TOPLEVEL), yes) $(info top-level build) -include ../../.config.mk + override DESTDIR := $(TOP_DESTDIR) else $(info package-level build) -include ../../.config.mk @@ -20,19 +21,19 @@ warn-noprefix: @echo "no prefix configured, did you run ./configure?" install: warn-noprefix else -install_target = $(prefix)/lib/anastasis-cli +bindir = $(DESTDIR)$(prefix)/bin +libdir = $(DESTDIR)$(prefix)/lib/anastasis-cli +nodedir = $(libdir)/node_modules/anastasis-cli .PHONY: install install-nodeps deps install-nodeps: ./build-node.mjs - install -d $(prefix)/bin - install -d $(install_target)/bin - install -d $(install_target)/node_modules/anastasis-cli - install -d $(install_target)/node_modules/anastasis-cli/bin - install -d $(install_target)/node_modules/anastasis-cli/dist - install ./dist/anastasis-cli-bundled.cjs $(install_target)/node_modules/anastasis-cli/dist/ - install ./dist/anastasis-cli-bundled.cjs.map $(install_target)/node_modules/anastasis-cli/dist/ - install ./bin/anastasis-cli.mjs $(install_target)/node_modules/anastasis-cli/bin/ - ln -sf $(install_target)/node_modules/anastasis-cli/bin/anastasis-cli.mjs $(prefix)/bin/anastasis-cli + install -d $(bindir) + install -d $(nodedir)/bin + install -d $(nodedir)/dist + install ./dist/anastasis-cli-bundled.cjs $(nodedir)/dist/ + install ./dist/anastasis-cli-bundled.cjs.map $(nodedir)/dist/ + install ./bin/anastasis-cli.mjs $(nodedir)/bin/ + ln -sf $(nodedir)/bin/anastasis-cli.mjs $(bindir)/anastasis-cli deps: pnpm install --frozen-lockfile --filter @gnu-taler/anastasis-cli... install: diff --git a/packages/demobank-ui/Makefile b/packages/demobank-ui/Makefile index 8e41cc7c6..2399cc427 100644 --- a/packages/demobank-ui/Makefile +++ b/packages/demobank-ui/Makefile @@ -3,6 +3,7 @@ ifeq ($(TOPLEVEL), yes) $(info top-level build) -include ../../.config.mk + override DESTDIR := $(TOP_DESTDIR) else $(info package-level build) -include ../../.config.mk @@ -15,7 +16,7 @@ $(info prefix is $(prefix)) all: @echo run \'make install\' to install -spa_dir=$(prefix)/share/taler/demobank-ui +spa_dir=$(DESTDIR)$(prefix)/share/taler/demobank-ui .PHONY: deps deps: diff --git a/packages/merchant-backoffice-ui/Makefile b/packages/merchant-backoffice-ui/Makefile index 1f7e0bf2b..7175ef723 100644 --- a/packages/merchant-backoffice-ui/Makefile +++ b/packages/merchant-backoffice-ui/Makefile @@ -3,6 +3,7 @@ ifeq ($(TOPLEVEL), yes) $(info top-level build) -include ../../.config.mk + override DESTDIR := $(TOP_DESTDIR) else $(info package-level build) -include ../../.config.mk @@ -15,7 +16,7 @@ $(info prefix is $(prefix)) all: @echo run \'make install\' to install -spa_dir=$(prefix)/share/taler/merchant-backoffice +spa_dir=$(DESTDIR)$(prefix)/share/taler/merchant-backoffice .PHONY: deps deps: diff --git a/packages/taler-harness/Makefile b/packages/taler-harness/Makefile index ed8365dc8..f9967419d 100644 --- a/packages/taler-harness/Makefile +++ b/packages/taler-harness/Makefile @@ -3,6 +3,7 @@ ifeq ($(TOPLEVEL), yes) $(info top-level build) -include ../../.config.mk + override DESTDIR := $(TOP_DESTDIR) else $(info package-level build) -include ../../.config.mk @@ -20,19 +21,20 @@ warn-noprefix: @echo "no prefix configured, did you run ./configure?" install: warn-noprefix else -install_target = $(prefix)/lib/taler-harness +BINDIR = $(DESTDIR)$(prefix)/bin +LIBDIR = $(DESTDIR)$(prefix)/lib/taler-harness +NODEDIR = $(LIBDIR)/node_modules/taler-harness .PHONY: install deps install-nodeps install-nodeps: ./build.mjs - install -d $(prefix)/bin - install -d $(install_target)/bin - install -d $(install_target)/node_modules/taler-harness - install -d $(install_target)/node_modules/taler-harness/bin - install -d $(install_target)/node_modules/taler-harness/dist - install ./dist/taler-harness-bundled.cjs $(install_target)/node_modules/taler-harness/dist/ - install ./dist/taler-harness-bundled.cjs.map $(install_target)/node_modules/taler-harness/dist/ - install ./bin/taler-harness.mjs $(install_target)/node_modules/taler-harness/bin/ - ln -sf $(install_target)/node_modules/taler-harness/bin/taler-harness.mjs $(prefix)/bin/taler-harness + install -d $(BINDIR) + install -d $(NODEDIR) + install -d $(NODEDIR)/bin + install -d $(NODEDIR)/dist + install ./dist/taler-harness-bundled.cjs $(NODEDIR)/dist/ + install ./dist/taler-harness-bundled.cjs.map $(NODEDIR)/dist/ + install ./bin/taler-harness.mjs $(NODEDIR)/bin/ + ln -sf $(NODEDIR)/bin/taler-harness.mjs $(BINDIR)/taler-harness deps: pnpm install --frozen-lockfile --filter @gnu-taler/taler-harness... install: diff --git a/packages/taler-wallet-cli/Makefile b/packages/taler-wallet-cli/Makefile index 6d695e9c1..6bfe05fc5 100644 --- a/packages/taler-wallet-cli/Makefile +++ b/packages/taler-wallet-cli/Makefile @@ -3,6 +3,7 @@ ifeq ($(TOPLEVEL), yes) $(info top-level build) -include ../../.config.mk + override DESTDIR := $(TOP_DESTDIR) else $(info package-level build) -include ../../.config.mk @@ -20,23 +21,23 @@ warn-noprefix: @echo "no prefix configured, did you run ./configure?" install: warn-noprefix else -install_target = $(prefix)/lib/taler-wallet-cli +LIBDIR = $(DESTDIR)$(prefix)/lib/taler-wallet-cli +BINDIR=$(DESTDIR)$(prefix)/bin +NODEDIR=$(LIBDIR)/node_modules/taler-wallet-cli .PHONY: install install-nodeps deps install-nodeps: ./build-node.mjs - @echo installing wallet CLI to $(install_target) - install -d $(prefix)/bin - install -d $(install_target)/build - install -d $(install_target)/bin - install -d $(install_target)/node_modules/taler-wallet-cli - install -d $(install_target)/node_modules/taler-wallet-cli/bin - install -d $(install_target)/node_modules/taler-wallet-cli/dist - install ./dist/taler-wallet-cli-bundled.cjs $(install_target)/node_modules/taler-wallet-cli/dist/ - install ./dist/taler-wallet-cli-bundled.cjs.map $(install_target)/node_modules/taler-wallet-cli/dist/ - install ./bin/taler-wallet-cli.mjs $(install_target)/node_modules/taler-wallet-cli/bin/ - install ../idb-bridge/node_modules/better-sqlite3/build/Release/better_sqlite3.node $(install_target)/build/ \ + @echo installing wallet CLI to $(DESTDIR)$(prefix) + install -d $(BINDIR) + install -d $(LIBDIR)/build + install -d $(NODEDIR)/bin + install -d $(NODEDIR)/dist + install ./dist/taler-wallet-cli-bundled.cjs $(NODEDIR)/dist/ + install ./dist/taler-wallet-cli-bundled.cjs.map $(NODEDIR)/dist/ + install ./bin/taler-wallet-cli.mjs $(NODEDIR)/bin/ + install ../idb-bridge/node_modules/better-sqlite3/build/Release/better_sqlite3.node $(LIBDIR)/build/ \ || echo "sqlite3 unavailable, better-sqlite3 native module not found" - ln -sf $(install_target)/node_modules/taler-wallet-cli/bin/taler-wallet-cli.mjs $(prefix)/bin/taler-wallet-cli + ln -sf $(NODESIR)/bin/taler-wallet-cli.mjs $(BINDIR)/taler-wallet-cli deps: pnpm install --frozen-lockfile --filter @gnu-taler/taler-wallet-cli... pnpm run --filter @gnu-taler/taler-wallet-cli... compile -- cgit v1.2.3 From 851b2da39c3297ede3d267f3d2534cac213261c1 Mon Sep 17 00:00:00 2001 From: Sebastian Date: Wed, 4 Oct 2023 14:36:03 -0300 Subject: fixing issues reported by Christian, wip --- .../src/pages/PaytoWireTransferForm.tsx | 4 +- .../demobank-ui/src/pages/WithdrawalQRCode.tsx | 2 +- .../merchant-backoffice-ui/src/Application.tsx | 4 +- .../merchant-backoffice-ui/src/InstanceRoutes.tsx | 30 ++++++------- .../src/components/form/InputStock.tsx | 5 +-- .../src/components/menu/SideBar.tsx | 29 ++++++++---- .../src/components/menu/index.tsx | 8 ++-- .../src/components/product/ProductForm.tsx | 6 +-- .../merchant-backoffice-ui/src/context/backend.ts | 26 +++++++++-- .../merchant-backoffice-ui/src/declaration.d.ts | 4 +- packages/merchant-backoffice-ui/src/hooks/index.ts | 3 +- packages/merchant-backoffice-ui/src/hooks/otp.ts | 4 +- .../merchant-backoffice-ui/src/hooks/product.ts | 17 ++++++- .../src/paths/instance/products/list/Table.tsx | 13 +++--- .../src/paths/instance/products/list/index.tsx | 52 +++++++++++++++++++++- .../paths/instance/reserves/create/CreatePage.tsx | 27 +++++++---- .../instance/validators/create/CreatePage.tsx | 6 +-- .../validators/create/CreatedSuccessfully.tsx | 2 +- .../instance/validators/update/UpdatePage.tsx | 2 +- .../src/paths/instance/validators/update/index.tsx | 2 +- .../src/paths/login/index.tsx | 17 +++---- .../merchant-backoffice-ui/src/schemas/index.ts | 3 +- .../merchant-backoffice-ui/src/utils/constants.ts | 2 +- packages/web-util/src/index.build.ts | 2 +- 24 files changed, 185 insertions(+), 85 deletions(-) (limited to 'packages/merchant-backoffice-ui') diff --git a/packages/demobank-ui/src/pages/PaytoWireTransferForm.tsx b/packages/demobank-ui/src/pages/PaytoWireTransferForm.tsx index 69a9a07b2..52dbd4ff6 100644 --- a/packages/demobank-ui/src/pages/PaytoWireTransferForm.tsx +++ b/packages/demobank-ui/src/pages/PaytoWireTransferForm.tsx @@ -363,14 +363,14 @@ export function PaytoWireTransferForm({ */ export function doAutoFocus(element: HTMLElement | null) { if (element) { - window.requestIdleCallback(() => { + setTimeout(() => { element.focus() element.scrollIntoView({ behavior: "smooth", block: "center", inline: "center" }) - }) + }, 100) } } diff --git a/packages/demobank-ui/src/pages/WithdrawalQRCode.tsx b/packages/demobank-ui/src/pages/WithdrawalQRCode.tsx index 2d90b410c..91c5da718 100644 --- a/packages/demobank-ui/src/pages/WithdrawalQRCode.tsx +++ b/packages/demobank-ui/src/pages/WithdrawalQRCode.tsx @@ -150,7 +150,7 @@ export function WithdrawalQRCode({ details={{ account, reserve: data.selected_reserve_pub, - amount: Amounts.parseOrThrow("usd:10.00") + amount: Amounts.parseOrThrow(data.amount) }} onAborted={() => { notifyInfo(i18n.str`Operation canceled`); diff --git a/packages/merchant-backoffice-ui/src/Application.tsx b/packages/merchant-backoffice-ui/src/Application.tsx index 1a7617643..f0a7de53b 100644 --- a/packages/merchant-backoffice-ui/src/Application.tsx +++ b/packages/merchant-backoffice-ui/src/Application.tsx @@ -60,7 +60,7 @@ export function Application(): VNode { * @returns */ function ApplicationStatusRoutes(): VNode { - const { url: backendURL, updateToken, changeBackend } = useBackendContext(); + const { changeBackend, selected: backendSelected } = useBackendContext(); const result = useBackendConfig(); const { i18n } = useTranslationContext(); @@ -69,7 +69,7 @@ function ApplicationStatusRoutes(): VNode { : { currency: "unknown", version: "unknown" }; const ctx = useMemo(() => ({ currency, version }), [currency, version]); - if (!backendURL) { + if (!backendSelected) { return ( diff --git a/packages/merchant-backoffice-ui/src/InstanceRoutes.tsx b/packages/merchant-backoffice-ui/src/InstanceRoutes.tsx index c2a9d3b18..f5372db8d 100644 --- a/packages/merchant-backoffice-ui/src/InstanceRoutes.tsx +++ b/packages/merchant-backoffice-ui/src/InstanceRoutes.tsx @@ -87,9 +87,9 @@ export enum InstancePaths { bank_update = "/bank/:bid/update", bank_new = "/bank/new", - product_list = "/products", - product_update = "/product/:pid/update", - product_new = "/product/new", + inventory_list = "/inventory", + inventory_update = "/inventory/:pid/update", + inventory_new = "/inventory/new", order_list = "/orders", order_new = "/order/new", @@ -347,42 +347,42 @@ export function InstanceRoutes({ onLoadError={ServerErrorRedirectTo(InstancePaths.error)} /> {/** - * Product pages + * Inventory pages */} { - route(InstancePaths.product_new); + route(InstancePaths.inventory_new); }} onSelect={(id: string) => { - route(InstancePaths.product_update.replace(":pid", id)); + route(InstancePaths.inventory_update.replace(":pid", id)); }} onNotFound={IfAdminCreateDefaultOr(NotFoundPage)} /> { - route(InstancePaths.product_list); + route(InstancePaths.inventory_list); }} onBack={() => { - route(InstancePaths.product_list); + route(InstancePaths.inventory_list); }} onNotFound={IfAdminCreateDefaultOr(NotFoundPage)} /> { - route(InstancePaths.product_list); + route(InstancePaths.inventory_list); }} onBack={() => { - route(InstancePaths.product_list); + route(InstancePaths.inventory_list); }} /> {/** @@ -405,7 +405,7 @@ export function InstanceRoutes({ path={InstancePaths.bank_update} component={BankAccountUpdatePage} onUnauthorized={LoginPageAccessDenied} - onLoadError={ServerErrorRedirectTo(InstancePaths.product_list)} + onLoadError={ServerErrorRedirectTo(InstancePaths.inventory_list)} onConfirm={() => { route(InstancePaths.bank_list); }} diff --git a/packages/merchant-backoffice-ui/src/components/form/InputStock.tsx b/packages/merchant-backoffice-ui/src/components/form/InputStock.tsx index 012d14977..1d18685c5 100644 --- a/packages/merchant-backoffice-ui/src/components/form/InputStock.tsx +++ b/packages/merchant-backoffice-ui/src/components/form/InputStock.tsx @@ -212,10 +212,7 @@ export function InputStock({ withTimestampSupport /> - - name="address" - label={i18n.str`Delivery address`} - > + name="address" label={i18n.str`Warehouse address`}> diff --git a/packages/merchant-backoffice-ui/src/components/menu/SideBar.tsx b/packages/merchant-backoffice-ui/src/components/menu/SideBar.tsx index 3d5f20c85..402134096 100644 --- a/packages/merchant-backoffice-ui/src/components/menu/SideBar.tsx +++ b/packages/merchant-backoffice-ui/src/components/menu/SideBar.tsx @@ -49,7 +49,7 @@ export function Sidebar({ isPasswordOk }: Props): VNode { const config = useConfigContext(); - const { url: backendURL } = useBackendContext() + const { url: backendURL, resetBackend } = useBackendContext() const { i18n } = useTranslationContext(); const kycStatus = useInstanceKYCDetails(); const needKYC = kycStatus.ok && kycStatus.data.type === "redirect"; @@ -80,7 +80,7 @@ export function Sidebar({
- {isPasswordOk && admin && !mimic && ( + {admin && !mimic && (
  • Log out -
  • - } + : +
  • + resetBackend()} + > + + + + + Change server + + +
  • + }
    diff --git a/packages/merchant-backoffice-ui/src/components/menu/index.tsx b/packages/merchant-backoffice-ui/src/components/menu/index.tsx index cb318906f..b8ac2c9ab 100644 --- a/packages/merchant-backoffice-ui/src/components/menu/index.tsx +++ b/packages/merchant-backoffice-ui/src/components/menu/index.tsx @@ -30,11 +30,11 @@ function getInstanceTitle(path: string, id: string): string { return `${id}: Orders`; case InstancePaths.order_new: return `${id}: New order`; - case InstancePaths.product_list: - return `${id}: Products`; - case InstancePaths.product_new: + case InstancePaths.inventory_list: + return `${id}: Inventory`; + case InstancePaths.inventory_new: return `${id}: New product`; - case InstancePaths.product_update: + case InstancePaths.inventory_update: return `${id}: Update product`; case InstancePaths.reserves_new: return `${id}: New reserve`; diff --git a/packages/merchant-backoffice-ui/src/components/product/ProductForm.tsx b/packages/merchant-backoffice-ui/src/components/product/ProductForm.tsx index 8bebbd298..e91e8c876 100644 --- a/packages/merchant-backoffice-ui/src/components/product/ProductForm.tsx +++ b/packages/merchant-backoffice-ui/src/components/product/ProductForm.tsx @@ -146,9 +146,9 @@ export function ProductForm({ onSubscribe, initial, alreadyExist }: Props) { /> name="minimum_age" - label={i18n.str`Age restricted`} + label={i18n.str`Age restriction`} tooltip={i18n.str`is this product restricted for customer below certain age?`} - help={i18n.str`can be overridden by the order configuration`} + help={i18n.str`minimum age of the buyer`} /> name="unit" @@ -165,7 +165,7 @@ export function ProductForm({ onSubscribe, initial, alreadyExist }: Props) { name="stock" label={i18n.str`Stock`} alreadyExist={alreadyExist} - tooltip={i18n.str`product inventory for products with finite supply (for internal use only)`} + tooltip={i18n.str`inventory for products with finite supply (for internal use only)`} /> name="taxes" diff --git a/packages/merchant-backoffice-ui/src/context/backend.ts b/packages/merchant-backoffice-ui/src/context/backend.ts index 056f9a192..d4a9abd5f 100644 --- a/packages/merchant-backoffice-ui/src/context/backend.ts +++ b/packages/merchant-backoffice-ui/src/context/backend.ts @@ -20,35 +20,55 @@ */ import { createContext, h, VNode } from "preact"; -import { useContext } from "preact/hooks"; +import { useContext, useState } from "preact/hooks"; import { LoginToken } from "../declaration.js"; import { useBackendDefaultToken, useBackendURL } from "../hooks/index.js"; +import { buildStorageKey, useLocalStorage } from "@gnu-taler/web-util/browser"; +import { codecForBoolean } from "@gnu-taler/taler-util"; interface BackendContextType { url: string, + selected: boolean; token?: LoginToken; updateToken: (token: LoginToken | undefined) => void; changeBackend: (url: string) => void; + resetBackend: () => void; } const BackendContext = createContext({ url: "", + selected: false, token: undefined, updateToken: () => null, changeBackend: () => null, + resetBackend: () => null, }); +const BACKEND_SELECTED = buildStorageKey("backend-selected", codecForBoolean()); + function useBackendContextState( defaultUrl?: string, ): BackendContextType { - const [url, changeBackend] = useBackendURL(defaultUrl); + const [url, changeBackend2] = useBackendURL(defaultUrl); const [token, updateToken] = useBackendDefaultToken(); + const {value, update} = useLocalStorage(BACKEND_SELECTED) + + function changeBackend(s:string) { + changeBackend2(s) + update(true) + } + + function resetBackend() { + update(false) + } return { url, token, + selected: value ?? false, updateToken, - changeBackend + changeBackend, + resetBackend }; } diff --git a/packages/merchant-backoffice-ui/src/declaration.d.ts b/packages/merchant-backoffice-ui/src/declaration.d.ts index c3e6ea3da..dc53e3e83 100644 --- a/packages/merchant-backoffice-ui/src/declaration.d.ts +++ b/packages/merchant-backoffice-ui/src/declaration.d.ts @@ -1327,7 +1327,7 @@ export namespace MerchantBackend { otp_device_id: string; // Human-readable description for the device. - otp_description: string; + otp_device_description: string; // A base64-encoded key otp_key: string; @@ -1341,7 +1341,7 @@ export namespace MerchantBackend { interface OtpDevicePatchDetails { // Human-readable description for the device. - otp_description: string; + otp_device_description: string; // A base64-encoded key otp_key: string | undefined; diff --git a/packages/merchant-backoffice-ui/src/hooks/index.ts b/packages/merchant-backoffice-ui/src/hooks/index.ts index ee696779f..498e4eb78 100644 --- a/packages/merchant-backoffice-ui/src/hooks/index.ts +++ b/packages/merchant-backoffice-ui/src/hooks/index.ts @@ -31,7 +31,8 @@ const calculateRootPath = () => { typeof window !== undefined ? window.location.origin + window.location.pathname : "/"; - return rootPath; + + return rootPath.replace("webui/",""); }; const loginTokenCodec = buildCodecForObject() diff --git a/packages/merchant-backoffice-ui/src/hooks/otp.ts b/packages/merchant-backoffice-ui/src/hooks/otp.ts index 3544b4881..93eefeea5 100644 --- a/packages/merchant-backoffice-ui/src/hooks/otp.ts +++ b/packages/merchant-backoffice-ui/src/hooks/otp.ts @@ -30,13 +30,13 @@ const useSWR = _useSWR as unknown as SWRHook; const MOCKED_DEVICES: Record = { "1": { - otp_description: "first device", + otp_device_description: "first device", otp_algorithm: 1, otp_device_id: "1", otp_key: "123", }, "2": { - otp_description: "second device", + otp_device_description: "second device", otp_algorithm: 0, otp_device_id: "2", otp_key: "456", diff --git a/packages/merchant-backoffice-ui/src/hooks/product.ts b/packages/merchant-backoffice-ui/src/hooks/product.ts index 8ecaefaa6..e06ea8ed8 100644 --- a/packages/merchant-backoffice-ui/src/hooks/product.ts +++ b/packages/merchant-backoffice-ui/src/hooks/product.ts @@ -26,6 +26,9 @@ import _useSWR, { SWRHook, useSWRConfig } from "swr"; const useSWR = _useSWR as unknown as SWRHook; export interface ProductAPI { + getProduct: ( + id: string, + ) => Promise; createProduct: ( data: MerchantBackend.Products.ProductAddDetail, ) => Promise; @@ -66,7 +69,7 @@ export function useProductAPI(): ProductAPI { data, }); - return await mutateAll(/.*"\/private\/products.*/); + return await mutateAll(/.*\/private\/products.*/); }; const deleteProduct = async (productId: string): Promise => { @@ -88,7 +91,17 @@ export function useProductAPI(): ProductAPI { return await mutateAll(/.*"\/private\/products.*/); }; - return { createProduct, updateProduct, deleteProduct, lockProduct }; + const getProduct = async ( + productId: string, + ): Promise => { + await request(`/private/products/${productId}`, { + method: "GET", + }); + + return + }; + + return { createProduct, updateProduct, deleteProduct, lockProduct, getProduct }; } export function useInstanceProducts(): HttpResponse< diff --git a/packages/merchant-backoffice-ui/src/paths/instance/products/list/Table.tsx b/packages/merchant-backoffice-ui/src/paths/instance/products/list/Table.tsx index cbfe1d573..db73217ed 100644 --- a/packages/merchant-backoffice-ui/src/paths/instance/products/list/Table.tsx +++ b/packages/merchant-backoffice-ui/src/paths/instance/products/list/Table.tsx @@ -66,7 +66,7 @@ export function CardTable({ - Products + Inventory

    Taxes - Profit + Sales Stock @@ -190,18 +190,21 @@ function Table({ src={i.image ? i.image : emptyImage} style={{ border: "solid black 1px", - width: 100, - height: 100, + maxHeight: "2em", + width: "auto", + height: "auto", }} /> rowSelection !== i.id && rowSelectionHandler(i.id) } style={{ cursor: "pointer" }} > - {i.description} + {i.description.length > 30 ? i.description.substring(0, 30) + "..." : i.description} diff --git a/packages/merchant-backoffice-ui/src/paths/instance/products/list/index.tsx b/packages/merchant-backoffice-ui/src/paths/instance/products/list/index.tsx index 85c50e5ed..274a7c2ea 100644 --- a/packages/merchant-backoffice-ui/src/paths/instance/products/list/index.tsx +++ b/packages/merchant-backoffice-ui/src/paths/instance/products/list/index.tsx @@ -53,7 +53,7 @@ export default function ProductList({ onNotFound, }: Props): VNode { const result = useInstanceProducts(); - const { deleteProduct, updateProduct } = useProductAPI(); + const { deleteProduct, updateProduct, getProduct } = useProductAPI(); const [deleting, setDeleting] = useState(null); const [notif, setNotif] = useState(undefined); @@ -74,11 +74,61 @@ export default function ProductList({ return onNotFound(); return onLoadError(result); } + const [errorId, setErrorId] = useState( + undefined, + ); + + const [productId, setProductId] = useState() + async function testIfProductExistAndSelect(orderId: string | undefined): Promise { + if (!orderId) { + setErrorId(i18n.str`Enter a product id`); + return; + } + try { + await getProduct(orderId); + onSelect(orderId); + setErrorId(undefined); + } catch { + setErrorId(i18n.str`product not found`); + } + } return (
    +
    +
    +
    +
    +
    + setProductId(e.currentTarget.value)} + placeholder={i18n.str`product id`} + /> + {errorId &&

    {errorId}

    } +
    + + + +
    +
    +
    +
    + >([]); const [exchangeQueryError, setExchangeQueryError] = useState< string | undefined @@ -123,19 +125,26 @@ function ViewStep({ { - return fetch(`${reserve.exchange_url}wire`) - .then((r) => r.json()) + if (!reserve.exchange_url) { + return Promise.resolve(); + } + + return request(reserve.exchange_url, "keys") //
    fetch(`${reserve.exchange_url}wire`) .then((r) => { - const wireMethods = r.accounts.map((a: any) => { - const match = PAYTO_WIRE_METHOD_LOOKUP.exec(a.payto_uri); - return (match && match[1]) || ""; - }); + if (r.loading) return; + if (r.ok) { + const wireMethods = r.data.accounts.map((a: any) => { + const match = PAYTO_WIRE_METHOD_LOOKUP.exec(a.payto_uri); + return (match && match[1]) || ""; + }); + } setWireMethods(wireMethods); setCurrentStep(Steps.WIRE_METHOD); return; }) - .catch((r: any) => { - setExchangeQueryError(r.message); + .catch((r: RequestError<{}>) => { + console.log(r.cause) + setExchangeQueryError(r.cause.message); }); }} data-tooltip={ diff --git a/packages/merchant-backoffice-ui/src/paths/instance/validators/create/CreatePage.tsx b/packages/merchant-backoffice-ui/src/paths/instance/validators/create/CreatePage.tsx index bdc86d226..cebc1ade6 100644 --- a/packages/merchant-backoffice-ui/src/paths/instance/validators/create/CreatePage.tsx +++ b/packages/merchant-backoffice-ui/src/paths/instance/validators/create/CreatePage.tsx @@ -70,8 +70,8 @@ export function CreatePage({ onCreate, onBack }: Props): VNode { : state.otp_key.length !== 32 ? i18n.str`size of the key should be 32` : undefined, - otp_description: !state.otp_description ? i18n.str`required` - : !/[a-zA-Z0-9]*/.test(state.otp_description) + otp_device_description: !state.otp_device_description ? i18n.str`required` + : !/[a-zA-Z0-9]*/.test(state.otp_device_description) ? i18n.str`no valid. only characters and numbers` : undefined, @@ -103,7 +103,7 @@ export function CreatePage({ onCreate, onBack }: Props): VNode { tooltip={i18n.str`Internal id on the system`} /> - name="otp_description" + name="otp_device_description" label={i18n.str`Descripiton`} tooltip={i18n.str`Useful to identify the device physically`} /> diff --git a/packages/merchant-backoffice-ui/src/paths/instance/validators/create/CreatedSuccessfully.tsx b/packages/merchant-backoffice-ui/src/paths/instance/validators/create/CreatedSuccessfully.tsx index 22ae55677..db3842711 100644 --- a/packages/merchant-backoffice-ui/src/paths/instance/validators/create/CreatedSuccessfully.tsx +++ b/packages/merchant-backoffice-ui/src/paths/instance/validators/create/CreatedSuccessfully.tsx @@ -77,7 +77,7 @@ export function CreatedSuccessfully({

    diff --git a/packages/merchant-backoffice-ui/src/paths/instance/validators/update/UpdatePage.tsx b/packages/merchant-backoffice-ui/src/paths/instance/validators/update/UpdatePage.tsx index 585c12e11..79be9802f 100644 --- a/packages/merchant-backoffice-ui/src/paths/instance/validators/update/UpdatePage.tsx +++ b/packages/merchant-backoffice-ui/src/paths/instance/validators/update/UpdatePage.tsx @@ -87,7 +87,7 @@ export function UpdatePage({ device, onUpdate, onBack }: Props): VNode { errors={errors} > - name="otp_description" + name="otp_device_description" label={i18n.str`Description`} tooltip={i18n.str`dddd`} /> diff --git a/packages/merchant-backoffice-ui/src/paths/instance/validators/update/index.tsx b/packages/merchant-backoffice-ui/src/paths/instance/validators/update/index.tsx index 9a27ccfee..52f6c6c29 100644 --- a/packages/merchant-backoffice-ui/src/paths/instance/validators/update/index.tsx +++ b/packages/merchant-backoffice-ui/src/paths/instance/validators/update/index.tsx @@ -80,7 +80,7 @@ export default function UpdateValidator({ device={{ id: vid, otp_algorithm: result.data.otp_algorithm, - otp_description: result.data.device_description, + otp_device_description: result.data.device_description, otp_key: undefined, otp_ctr: result.data.otp_ctr }} diff --git a/packages/merchant-backoffice-ui/src/paths/login/index.tsx b/packages/merchant-backoffice-ui/src/paths/login/index.tsx index 9948307e4..a9e3c3a1b 100644 --- a/packages/merchant-backoffice-ui/src/paths/login/index.tsx +++ b/packages/merchant-backoffice-ui/src/paths/login/index.tsx @@ -52,7 +52,7 @@ function cleanUp(s: string): string { } export function LoginPage({ onConfirm }: Props): VNode { - const { url: backendURL, changeBackend } = useBackendContext(); + const { url: backendURL, changeBackend, resetBackend } = useBackendContext(); const { admin, id } = useInstanceContext(); const { requestNewLoginToken } = useCredentialsChecker(); const [token, setToken] = useState(""); @@ -73,10 +73,9 @@ export function LoginPage({ onConfirm }: Props): VNode { }, [backendURL, id, token]) async function changeServer() { - changeBackend("") + resetBackend() } - console.log(admin, id) if (admin && id !== "default") { //admin trying to access another instance return (
    @@ -211,10 +210,7 @@ export function LoginPage({ onConfirm }: Props): VNode { borderTop: 0, }} > - + Change server @@ -304,11 +300,8 @@ export function ConnectionPage({ onConfirm }: { onConfirm: (s: string) => void } borderTop: 0, }} > - - Try again + + Connect
    diff --git a/packages/merchant-backoffice-ui/src/schemas/index.ts b/packages/merchant-backoffice-ui/src/schemas/index.ts index 4be77595b..c97d41204 100644 --- a/packages/merchant-backoffice-ui/src/schemas/index.ts +++ b/packages/merchant-backoffice-ui/src/schemas/index.ts @@ -22,6 +22,7 @@ import { isAfter, isFuture } from "date-fns"; import * as yup from "yup"; import { AMOUNT_REGEX, PAYTO_REGEX } from "../utils/constants.js"; +import { Amounts } from "@gnu-taler/taler-util"; yup.setLocale({ mixed: { @@ -38,7 +39,7 @@ function listOfPayToUrisAreValid(values?: (string | undefined)[]): boolean { } function currencyWithAmountIsValid(value?: string): boolean { - return !!value && AMOUNT_REGEX.test(value); + return !!value && Amounts.parse(value) !== undefined; } function currencyGreaterThan0(value?: string) { if (value) { diff --git a/packages/merchant-backoffice-ui/src/utils/constants.ts b/packages/merchant-backoffice-ui/src/utils/constants.ts index fea9cb7e2..7c4e288b3 100644 --- a/packages/merchant-backoffice-ui/src/utils/constants.ts +++ b/packages/merchant-backoffice-ui/src/utils/constants.ts @@ -25,7 +25,7 @@ export const PAYTO_REGEX = export const PAYTO_WIRE_METHOD_LOOKUP = /payto:\/\/([a-zA-Z][a-zA-Z0-9-.]+)\/.*/; -export const AMOUNT_REGEX = /^[a-zA-Z][a-zA-Z]*:[0-9][0-9,]*\.?[0-9,]*$/; +export const AMOUNT_REGEX = /^[a-zA-Z][a-zA-Z]{1,11}:[0-9][0-9,]*\.?[0-9,]*$/; export const INSTANCE_ID_LOOKUP = /\/instances\/([^/]*)\/?$/; diff --git a/packages/web-util/src/index.build.ts b/packages/web-util/src/index.build.ts index 6ee1be20a..0e8e7cec3 100644 --- a/packages/web-util/src/index.build.ts +++ b/packages/web-util/src/index.build.ts @@ -54,7 +54,7 @@ if (GIT_ROOT === "/") { // eslint-disable-next-line no-undef process.exit(1); } -const GIT_HASH = GIT_ROOT === "/" ? undefined : git_hash(); +const GIT_HASH = git_hash(); const buf = fs.readFileSync(path.join(BASE, "package.json")); let _package = JSON.parse(buf.toString("utf-8")); -- cgit v1.2.3