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 && instance ? (
+ {instance ? (
- {isPasswordOk && admin && !mimic && (
+ {admin && !mimic && (
)}
- {isPasswordOk &&
+ {isPasswordOk ?
Log out
-
- }
+ :
+
+ resetBackend()}
+ >
+
+
+
+
+
+
+ }
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