[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[taler-merchant-backoffice] 10/11: bank: implement withdrawal abort
From: |
gnunet |
Subject: |
[taler-merchant-backoffice] 10/11: bank: implement withdrawal abort |
Date: |
Mon, 20 Dec 2021 17:45:08 +0100 |
This is an automated email from the git hooks/post-receive script.
ms pushed a commit to branch master
in repository merchant-backoffice.
commit ee6e662d4838f5d0c48d7de589bb1f287ef99807
Author: ms <ms@taler.net>
AuthorDate: Mon Dec 20 10:35:36 2021 +0100
bank: implement withdrawal abort
---
packages/bank/src/pages/home/index.tsx | 139 +++++++++++++++++++++++-------
packages/bank/tests/__tests__/homepage.js | 4 +
2 files changed, 110 insertions(+), 33 deletions(-)
diff --git a/packages/bank/src/pages/home/index.tsx
b/packages/bank/src/pages/home/index.tsx
index baf9e75..fc52f58 100644
--- a/packages/bank/src/pages/home/index.tsx
+++ b/packages/bank/src/pages/home/index.tsx
@@ -55,6 +55,22 @@ interface AccountStateType {
* Helpers. *
***********/
+/**
+ * Craft headers with Authorization and Content-Type.
+ */
+function prepareHeaders(username: string, password: string) {
+ let headers = new Headers();
+ headers.append(
+ "Authorization",
+ `Basic ${Buffer.from(username + ":" + password).toString("base64")}`
+ );
+ headers.append(
+ "Content-Type",
+ "application/json"
+ )
+ return headers;
+}
+
const getRootPath = () => {
return typeof window !== undefined
? window.location.origin + window.location.pathname
@@ -123,6 +139,71 @@ function usePageState(
* a helper function.
*/
+/**
+ * Abort a withdrawal operation via the Access API's /abort.
+ */
+async function abortWithdrawalCall(
+ backendState: BackendStateTypeOpt,
+ withdrawalId: string | undefined,
+ pageStateSetter: StateUpdater<PageStateType>
+) {
+ if (typeof backendState === "undefined") {
+ console.log("No credentials found.");
+ pageStateSetter((prevState) => ({...prevState, hasError: true, error: "No
credentials found."}))
+ return;
+ }
+ if (typeof withdrawalId === "undefined") {
+ console.log("No withdrawal ID found.");
+ pageStateSetter((prevState) => ({...prevState, hasError: true, error: "No
withdrawal ID found."}))
+ return;
+ }
+
+ try {
+ const { username, password } = backendState;
+ let headers = prepareHeaders(username, password);
+ /**
+ * NOTE: tests show that when a same object is being
+ * POSTed, caching might prevent same requests from being
+ * made. Hence, trying to POST twice the same amount might
+ * get silently ignored.
+ *
+ * headers.append("cache-control", "no-store");
+ * headers.append("cache-control", "no-cache");
+ * headers.append("pragma", "no-cache");
+ * */
+
+ // Backend URL must have been stored _with_ a final slash.
+ const url = new URL(
+
`access-api/accounts/${backendState.username}/withdrawals/${withdrawalId}/abort`,
+ backendState.url
+ )
+ var res = await fetch(url.href, {method: 'POST', headers: headers})
+ } catch (error) {
+ console.log("Could not abort the withdrawal", error);
+ pageStateSetter((prevState) => ({
+ ...prevState,
+ hasError: true,
+ error: `Could not abort the withdrawal: ${error}`}))
+ return;
+ }
+ if (!res.ok) {
+ console.log(`Withdrawal abort gave response error (${res.status})`,
res.statusText);
+ pageStateSetter((prevState) => ({
+ ...prevState,
+ hasError: true,
+ error: `Withdrawal abortion gave response error (${res.status})`}))
+ return;
+ } else {
+ console.log("Withdrawal operation aborted!");
+ pageStateSetter((prevState) => {
+ delete prevState.talerWithdrawUri;
+ const { talerWithdrawUri, ...rest } = prevState;
+ return {
+ ...rest,
+ withdrawalOutcome: "Withdrawal aborted!"
+ }})
+ }
+}
/**
* This function confirms a withdrawal operation AFTER
@@ -139,23 +220,21 @@ async function confirmWithdrawalCall(
withdrawalId: string | undefined,
pageStateSetter: StateUpdater<PageStateType>
) {
+
if (typeof backendState === "undefined") {
- console.log("Page has a problem: no credentials found in the state.");
- pageStateSetter((prevState) => ({
- ...prevState,
- hasError: true,
- error: "No credentials found in the state"}))
+ console.log("No credentials found.");
+ pageStateSetter((prevState) => ({...prevState, hasError: true, error: "No
credentials found."}))
return;
}
if (typeof withdrawalId === "undefined") {
- pageStateSetter((prevState) => ({
- ...prevState,
- hasError: true,
- error: "Withdrawal ID wasn't found in the state; cannot confirm it."}))
+ console.log("No withdrawal ID found.");
+ pageStateSetter((prevState) => ({...prevState, hasError: true, error: "No
withdrawal ID found."}))
return;
}
+
try {
- let headers = new Headers();
+ const { username, password } = backendState;
+ let headers = prepareHeaders(username, password);
/**
* NOTE: tests show that when a same object is being
* POSTed, caching might prevent same requests from being
@@ -166,14 +245,7 @@ async function confirmWithdrawalCall(
* headers.append("cache-control", "no-cache");
* headers.append("pragma", "no-cache");
* */
- headers.append(
- "Authorization",
- `Basic ${Buffer.from(backendState.username + ":" +
backendState.password).toString("base64")}`
- );
- headers.append(
- "Content-Type",
- "application/json"
- )
+
// Backend URL must have been stored _with_ a final slash.
const url = new URL(
`access-api/accounts/${backendState.username}/withdrawals/${withdrawalId}/confirm`,
@@ -227,14 +299,12 @@ async function createWithdrawalCall(
) {
if (typeof backendState === "undefined") {
console.log("Page has a problem: no credentials found in the state.");
- pageStateSetter((prevState) => ({
- ...prevState,
- hasError: true,
- error: "No credentials found in the state"}))
+ pageStateSetter((prevState) => ({...prevState, hasError: true, error: "No
credentials given."}))
return;
}
try {
- let headers = new Headers();
+ const { username, password } = backendState;
+ let headers = prepareHeaders(username, password);
/**
* NOTE: tests show that when a same object is being
* POSTed, caching might prevent same requests from being
@@ -245,14 +315,7 @@ async function createWithdrawalCall(
* headers.append("cache-control", "no-cache");
* headers.append("pragma", "no-cache");
* */
- headers.append(
- "Authorization",
- `Basic ${Buffer.from(backendState.username + ":" +
backendState.password).toString("base64")}`
- );
- headers.append(
- "Content-Type",
- "application/json"
- )
+
// Backend URL must have been stored _with_ a final slash.
const url = new URL(
`access-api/accounts/${backendState.username}/withdrawals`,
@@ -501,6 +564,10 @@ export function BankHome(): VNode {
talerWithdrawUri={pageState.talerWithdrawUri}
accountLabel={backendState.username}>
+ <button onClick={() => {
+ pageStateSetter({...pageState, isLoggedIn: false})
+ }}>Sign out</button>
+
{!pageState.withdrawalInProgress && <button onClick={() => {
createWithdrawalCall(
"EUR:5",
@@ -515,12 +582,18 @@ export function BankHome(): VNode {
return {...rest, withdrawalInProgress:
false};})}}>Close</button>
}
- {pageState.talerWithdrawUri && <button onClick={() => {
+ {pageState.talerWithdrawUri && <div><button onClick={() => {
confirmWithdrawalCall(
backendState,
pageState.withdrawalId,
pageStateSetter);}}>Confirm withdrawal</button>
- }
+ <button onClick={() => {
+ abortWithdrawalCall(
+ backendState,
+ pageState.withdrawalId,
+ pageStateSetter);}}>Abort withdrawal</button>
+ </div>}
+
</Account>
</SWRWithCredentials>
);
diff --git a/packages/bank/tests/__tests__/homepage.js
b/packages/bank/tests/__tests__/homepage.js
index 5508453..d15433e 100644
--- a/packages/bank/tests/__tests__/homepage.js
+++ b/packages/bank/tests/__tests__/homepage.js
@@ -206,6 +206,10 @@ describe("home page", () => {
paytoUri: "payto://iban/123/ABC"
}))
fireEvent.click(signinButton);
+ expect(fetch).toHaveBeenCalledWith(
+ `http://localhost/demobanks/default/access-api/accounts/${username}`,
+ expect.anything()
+ )
await screen.findByText("balance is EUR:10", {exact: false})
})
--
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.
- [taler-merchant-backoffice] branch master updated (aa05541 -> 8003d41), gnunet, 2021/12/20
- [taler-merchant-backoffice] 03/11: bank tests, gnunet, 2021/12/20
- [taler-merchant-backoffice] 08/11: bank: fix URL, gnunet, 2021/12/20
- [taler-merchant-backoffice] 01/11: bank: implement login, gnunet, 2021/12/20
- [taler-merchant-backoffice] 04/11: bank: fix URL generation, gnunet, 2021/12/20
- [taler-merchant-backoffice] 10/11: bank: implement withdrawal abort,
gnunet <=
- [taler-merchant-backoffice] 02/11: Bank tests., gnunet, 2021/12/20
- [taler-merchant-backoffice] 11/11: bank: test withdrawal abort, gnunet, 2021/12/20
- [taler-merchant-backoffice] 09/11: bank: fix URL, gnunet, 2021/12/20
- [taler-merchant-backoffice] 06/11: remove misplaced comments, gnunet, 2021/12/20
- [taler-merchant-backoffice] 05/11: bank: make tests 'Content-Type' aware, gnunet, 2021/12/20
- [taler-merchant-backoffice] 07/11: bank: fix URL generation, gnunet, 2021/12/20