gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[taler-merchant-backoffice] branch master updated (1e8fbfc -> b3cf0bd)


From: gnunet
Subject: [taler-merchant-backoffice] branch master updated (1e8fbfc -> b3cf0bd)
Date: Thu, 07 Apr 2022 07:34:16 +0200

This is an automated email from the git hooks/post-receive script.

ms pushed a change to branch master
in repository merchant-backoffice.

    from 1e8fbfc  copying pybank's look.  WIP
     new af7f0fa  copying pybank's look.  WIP
     new b3cf0bd  mocks after taler-local

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 packages/bank/mocks/window.js          |   4 +-
 packages/bank/package.json             |   2 +-
 packages/bank/src/components/QR.tsx    |   2 +-
 packages/bank/src/pages/home/index.tsx | 183 +++++++++++++++++++++++++--------
 4 files changed, 144 insertions(+), 47 deletions(-)

diff --git a/packages/bank/mocks/window.js b/packages/bank/mocks/window.js
index c6185fa..f396ff9 100644
--- a/packages/bank/mocks/window.js
+++ b/packages/bank/mocks/window.js
@@ -18,9 +18,9 @@ Object.defineProperty(window, 'localStorage', {
 });
 Object.defineProperty(window, 'location', {
   value: {
-    origin: "http://localhost:5000";,
+    origin: "http://localhost:8080";, /* where taler-local rev proxy listens to 
*/
     search: "",
-    pathname: "/demobanks/default",
+    pathname: "/sandbox/demobanks/default",
   }
 })
 
diff --git a/packages/bank/package.json b/packages/bank/package.json
index 18c6adc..646322b 100644
--- a/packages/bank/package.json
+++ b/packages/bank/package.json
@@ -4,7 +4,7 @@
   "version": "0.1.0",
   "license": "MIT",
   "scripts": {
-    "dev": "preact watch --port ${PORT:=8080} --no-sw --no-esm -c 
preact.mock.js",
+    "dev": "preact watch --port ${PORT:=9090} --no-sw --no-esm -c 
preact.mock.js",
     "build": "preact build --no-sw --no-esm -c preact.single-config.js --dest 
build && sh remove-link-stylesheet.sh",
     "serve": "sirv build --port ${PORT:=8080} --cors --single",
     "lint": "eslint 'src/**/*.{js,jsx,ts,tsx}'",
diff --git a/packages/bank/src/components/QR.tsx 
b/packages/bank/src/components/QR.tsx
index 9a05f60..f154dde 100644
--- a/packages/bank/src/components/QR.tsx
+++ b/packages/bank/src/components/QR.tsx
@@ -36,7 +36,7 @@ export function QR({ text }: { text: string }): VNode {
         width: "100%",
         display: "flex",
         flexDirection: "column",
-        alignItems: "center",
+        alignItems: "left",
       }}
     >
       <div
diff --git a/packages/bank/src/pages/home/index.tsx 
b/packages/bank/src/pages/home/index.tsx
index 03f0661..070b78b 100644
--- a/packages/bank/src/pages/home/index.tsx
+++ b/packages/bank/src/pages/home/index.tsx
@@ -109,6 +109,9 @@ interface AccountStateType {
  * Helpers. *
  ***********/
 
+function genCaptchaNumbers(): string {
+  return `${Math.floor(Math.random() * 10)} + ${Math.floor(Math.random() * 
10)}`;
+}
 /**
  * Bring the state to show the public accounts page.
  */
@@ -124,7 +127,7 @@ function goPublicAccounts(pageStateSetter: 
StateUpdater<PageStateType>) {
 function validateAmount(maybeAmount: string): any {
   const amountRegex = "^[0-9]+(\.[0-9]+)?$";
   if (typeof maybeAmount !== "undefined" || maybeAmount !== "") {
-    console.log("Maybe valid amount", maybeAmount);
+    console.log("Maybe valid amount: " + maybeAmount);
     // tolerating comma instead of point.
     maybeAmount = maybeAmount.replace(",", ".");
     const re = RegExp(amountRegex)
@@ -515,9 +518,8 @@ async function createTransactionCall(
  * user should receive a QR code of the "taler://withdraw/" type and
  * supposed to scan it with their phone.
  *
- * TODO: (1) after the scan, the page should refresh itself and inform the
- * user about the operation's outcome.  (2) use POST helper.
- */
+ * TODO: (1) after the scan, the page should refresh itself and inform
+ * the user about the operation's outcome.  (2) use POST helper.  */
 async function createWithdrawalCall(
   amount: string,
   backendState: BackendStateTypeOpt,
@@ -563,7 +565,7 @@ async function createWithdrawalCall(
 
   console.log("Withdrawal operation created!");
   let resp = await res.json();
-  pageStateSetter((prevState) => ({
+  pageStateSetter((prevState: PageStateType) => ({
     ...prevState,
     withdrawalInProgress: true,
     talerWithdrawUri: resp.taler_withdraw_uri,
@@ -710,7 +712,7 @@ function BankFrame(Props: any): VNode {
         </div>
         <a href="https://taler.net/";>
         <img
-            src={talerLogo}
+          src={talerLogo}
          height="100"
          width="224"
          style="margin: 2em 2em">
@@ -815,7 +817,7 @@ function PaytoWireTransfer(Props: any): VNode {
           href="#"
           onClick={() => {
            console.log("switch to raw payto form");
-            pageStateSetter((prevState) => ({...prevState, isRawPayto: true}));
+            pageStateSetter((prevState: any) => ({...prevState, isRawPayto: 
true}));
          }}>{i18n`Want to try the raw payto://-format?`}
         </a></p>
       </div>
@@ -861,13 +863,108 @@ function PaytoWireTransfer(Props: any): VNode {
 }
 
 /**
- * Let user choose a amount and submit the withdtawal.
+ * Offer the QR code (and a clickable taler://-link) to
+ * permit the passing of exchange and reserve details to
+ * the bank.  Poll the backend until such operation is done.
+ */
+function TalerWithdrawalQRCode(Props: any): VNode {
+  const [pageState, pageStateSetter] = useContext(PageContext);
+  const {
+    withdrawalId,
+    talerWithdrawUri,
+    accountLabel,
+    backendState } = Props;
+  const i18n = useTranslator();
+  console.log(`Showing withdraw URI: ${talerWithdrawUri}`);
+  // polling the wallet:
+  const { data, error } = useSWR(
+    
`integration-api/accounts/${accountLabel}/withdrawal-operation/${withdrawalId}`
+  );
+  const captchaNumbers = {
+    a: Math.floor(Math.random() * 10),
+    b: Math.floor(Math.random() * 10)
+  }
+  var captchaAnswer = "";
+  // fall here as long as the wallet did NOT communicate:
+  if (typeof error !== "undefined") {
+    console.log("withdraw details not arrived at the bank...", error);
+    switch(error.status) {
+      case 404: {
+        return (<section id="main" class="content">
+          <h1 class="nav">{i18n`Withdraw to a Taler Wallet`}</h1>
+          <p>{i18n`You can use this QR code to withdraw to your mobile 
wallet:`}</p>
+          {QR({text: talerWithdrawUri})}
+          <p>Click <a href={talerWithdrawUri}>{i18n`this link`}</a> to open 
your Taler wallet!</p>
+          <br />
+          <a class="pure-button" onClick={() => {
+            pageStateSetter((prevState: PageStateType) => {
+              const { withdrawalOutcome, withdrawalId, talerWithdrawUri, 
...rest } = prevState;
+              return { ...rest, withdrawalInProgress: false };
+          })}}>{i18n`Abort`}</a>
+        </section>);
+      }
+      default: {
+        pageStateSetter((prevState: PageStateType) => ({...prevState, 
hasError: true, error: error }))
+        return <p>Could not complete the withdrawal: {error}</p>
+      }
+    }
+  }
+  // here the reserve public key and exchange payment details are known to the 
bank,
+  // ask for a confirmation (used to be the CAPTCHA page):
+  console.log("withdraw details arrived at the bank!");
+  return (<Fragment>
+    <h1 class="nav">{i18n`Confirm Withdrawal`}</h1>
+    <p><Translate>
+      Please, authorize this operation by answering the following question.
+    </Translate></p>
+    <div>
+      <label>What is <em>{captchaNumbers.a} + {captchaNumbers.b}</em> 
?&nbsp;</label>
+      <input
+        type="text"
+       required
+        onInput={(e): void => {
+          captchaAnswer = e.currentTarget.value;
+        }} />
+      <input
+        type="submit"
+        value="confirm"
+        onClick={ () => {
+          if (captchaAnswer == (captchaNumbers.a + 
captchaNumbers.b).toString()) {
+            confirmWithdrawalCall(
+              backendState,
+              pageState.withdrawalId,
+              pageStateSetter)
+           return;
+         }
+          pageStateSetter((prevState: PageStateType) =>
+           ({...prevState, hasError: true, error: "Answer is wrong."}))
+      }} />
+      <input
+        type="submit"
+        value="abort"
+        onClick={ () =>
+         abortWithdrawalCall(
+            backendState,
+            pageState.withdrawalId,
+            pageStateSetter
+         )} />
+    </div>
+    <p><Translate>
+      A this point, a <b>real</b> bank would ask for an additional
+      authentication proof (PIN/TAN, one time password, ..), instead
+      of a simple calculation.
+    </Translate></p>
+  </Fragment>);
+}
+
+/**
+ * Let the user choose an amount and submit the withdtawal.
  */
 function TalerWithdrawal(Props: any): VNode {
   const {backendState, pageStateSetter} = Props;
   const currency = useContext(CurrencyContext);
   const i18n = useTranslator();
-  var submitAmount = ""; // without currency.
+  var submitAmount = "5.00"; // must match the first <select> child.
   const amountRegex = "^[0-9]+(\.[0-9]+)?$";
 
   var submitButton = <input
@@ -893,10 +990,14 @@ function TalerWithdrawal(Props: any): VNode {
       <div>
         <h2>{i18n`Withdraw Money into a Taler wallet`}</h2>
         <div id="reserve-form"
-            class="pure-form"
-            name="tform">
+             class="pure-form"
+             name="tform">
           {i18n`Amount to withdraw`}:&nbsp;
-          <select id="reserve-amount" name="withdraw-amount" class="amount" 
autofocus>
+          <select id="reserve-amount"
+                 name="withdraw-amount"
+                 class="amount" autofocus
+                  onChange={(e): void => {
+                   submitAmount = e.currentTarget.value; }}>
             <option value="5.00">5.00</option>
             <option value="10.00">10.00</option>
             <option value="15.00">15.00</option>
@@ -963,7 +1064,7 @@ function LoginForm(Props: any): VNode {
  */
 function RegistrationForm(Props: any): VNode {
   const [pageState, pageStateSetter] = useContext(PageContext);
-  var submitData: CredentialsRequestType;
+  var submitData: CredentialsRequestType = {};
   const i18n = useTranslator();
 
   return (
@@ -1003,8 +1104,10 @@ function RegistrationForm(Props: any): VNode {
                 class="pure-button pure-button-primary"
                 onClick={() => {
                  console.log("maybe submitting the registration..");
-                 if (!("password" in submitData) || !("username" in 
submitData)) return;
-                 if (submitData.password.length === 0 || 
submitData.username.length === 0) return;
+                 if ((typeof submitData.password === "undefined") ||
+                     (typeof submitData.username === "undefined")) return;
+                 if (submitData.password.length === 0 ||
+                   submitData.username.length === 0) return;
                  console.log("submitting the registration..");
                   registrationCall(
                     submitData,
@@ -1092,6 +1195,7 @@ function Account(Props: any): VNode {
     tryManualTransfer,
     withdrawalOutcome,
     transferOutcome,
+    withdrawalId,
     talerWithdrawUri } = pageState;
   const i18n = useTranslator();
   const logOut = (
@@ -1113,7 +1217,7 @@ function Account(Props: any): VNode {
             tryManualTransfer: false,
           };
         });
-      }}>[{i18n`Logout`}]</a>);
+      }}>{i18n`Logout`}</a>);
 
   /**
    * This part shows a list of transactions: with 5 elements by
@@ -1201,14 +1305,17 @@ function Account(Props: any): VNode {
    * the outcome.
    */
   if (talerWithdrawUri) {
-    console.log(`Showing withdraw URI: ${talerWithdrawUri}`);
-    return (<Fragment>
-      <p>Scan the following QR code, and then confirm!</p>
-      <div>{QR({text: talerWithdrawUri})}</div>
-      <a href={talerWithdrawUri}></a>
-      <p>Withdraw address: <pre>{talerWithdrawUri}</pre></p>
-      {Props.children}
-    </Fragment>);
+    console.log("Bank created a new Taler withdrawal");
+    return (
+      <BankFrame>
+        {logOut}<br />
+        <TalerWithdrawalQRCode
+         accountLabel={accountLabel}
+         backendState={backendState}
+         withdrawalId={withdrawalId}
+         talerWithdrawUri={talerWithdrawUri} />
+      </BankFrame>
+    );
   }
   const balance = parseAmount(data.balance.amount)
   if (tryManualTransfer) {
@@ -1231,13 +1338,10 @@ function Account(Props: any): VNode {
     </section>
     <CurrencyContext.Provider value={balance.currency}>
       {Props.children}
+      <TalerWithdrawal
+        backendState={backendState}
+        pageStateSetter={pageStateSetter} />
     </CurrencyContext.Provider>
-    {
-      withdrawalInProgress && !transferOutcome &&
-        <TalerWithdrawal
-          backendState={backendState}
-          pageStateSetter={pageStateSetter} />
-    }
     <section id="main">
       <article>
         <h2>{i18n`Latest transactions:`}</h2>
@@ -1416,19 +1520,10 @@ export function BankHome(): VNode {
           backendUrl={backendState.url}>
         <PageContext.Provider value={[pageState, pageStateSetter]}>
           <Account accountLabel={backendState.username} 
backendState={backendState}>
-  
-            { /**
-               * No action is currently being performed (page is 'pristine'):
-               * offer the Taler withdrawal button.
-               */
-              !pageState.withdrawalInProgress && !pageState.transferOutcome && 
<TalerWithdrawal
-                backendState={backendState}
-               pageStateSetter={pageStateSetter} />
-            }
-  
             { /**
                * Wire transfer reached a persisten state: offer to
-               * return back to the pristine profile page.
+               * return back to the pristine profile page.  FIXME:
+              * move this into the Account component.
                */
               pageState.transferOutcome && <button onClick={() => {
                 pageStateSetter((prevState) => {
@@ -1438,7 +1533,8 @@ export function BankHome(): VNode {
   
             { /**
                * Withdrawal reached a persisten state: offer to
-               * return back to the pristine profile page.
+               * return back to the pristine profile page.  FIXME:
+              * move this into the Account component.
                */
               pageState.withdrawalOutcome && <button onClick={() => {
                 pageStateSetter((prevState) => {
@@ -1452,7 +1548,8 @@ export function BankHome(): VNode {
   
             { /**
                * The withdrawal QR code is rendered: offer to confirm
-               * or abort the operation.
+               * or abort the operation.  FIXME: move this into the Account
+              * component.
                */
               pageState.talerWithdrawUri && <div><button onClick={() => {
                 confirmWithdrawalCall(

-- 
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]