summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastian <sebasjm@gmail.com>2023-12-01 14:50:13 -0300
committerSebastian <sebasjm@gmail.com>2023-12-01 14:50:13 -0300
commit685f747b6a24ae0d25f2bb458074c955e5acdbc4 (patch)
tree317b3738e532e1d993aca617181c69aa137c21ba
parent6b1bee3fe0e933b3c7421fc6d3d0425a01c41e30 (diff)
downloadwallet-core-685f747b6a24ae0d25f2bb458074c955e5acdbc4.tar.gz
wallet-core-685f747b6a24ae0d25f2bb458074c955e5acdbc4.tar.bz2
wallet-core-685f747b6a24ae0d25f2bb458074c955e5acdbc4.zip
sync demobank with new libeufin API, still missing when the withdrawal operation is not the same user that created the transfer
-rw-r--r--packages/demobank-ui/src/hooks/access.ts14
-rw-r--r--packages/demobank-ui/src/pages/OperationState/index.ts4
-rw-r--r--packages/demobank-ui/src/pages/OperationState/state.ts34
-rw-r--r--packages/demobank-ui/src/pages/OperationState/views.tsx48
-rw-r--r--packages/demobank-ui/src/pages/PublicHistoriesPage.tsx3
-rw-r--r--packages/demobank-ui/src/pages/QrCodeSection.tsx7
-rw-r--r--packages/demobank-ui/src/pages/WithdrawalConfirmationQuestion.tsx33
-rw-r--r--packages/demobank-ui/src/pages/WithdrawalQRCode.tsx11
-rw-r--r--packages/demobank-ui/src/pages/account/ShowAccountDetails.tsx16
-rw-r--r--packages/demobank-ui/src/pages/account/UpdateAccountPassword.tsx14
10 files changed, 116 insertions, 68 deletions
diff --git a/packages/demobank-ui/src/hooks/access.ts b/packages/demobank-ui/src/hooks/access.ts
index da9812ffa..1e09c444a 100644
--- a/packages/demobank-ui/src/hooks/access.ts
+++ b/packages/demobank-ui/src/hooks/access.ts
@@ -14,7 +14,7 @@
GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
*/
-import { AccessToken, TalerCoreBankResultByMethod, TalerHttpError } from "@gnu-taler/taler-util";
+import { AccessToken, TalerBankIntegrationResultByMethod, TalerCoreBankResultByMethod, TalerHttpError } from "@gnu-taler/taler-util";
import { useState } from "preact/hooks";
import { MAX_RESULT_SIZE, PAGE_SIZE } from "../utils.js";
import { useBackendState } from "./backend.js";
@@ -62,10 +62,10 @@ export function useWithdrawalDetails(wid: string) {
const { api } = useBankCoreApiContext();
async function fetcher([wid]: [string]) {
- return await api.getWithdrawalById(wid)
+ return await api.getIntegrationAPI().getWithdrawalOperationById(wid)
}
- const { data, error } = useSWR<TalerCoreBankResultByMethod<"getWithdrawalById">, TalerHttpError>(
+ const { data, error } = useSWR<TalerBankIntegrationResultByMethod<"getWithdrawalOperationById">, TalerHttpError>(
[wid, "getWithdrawalById"], fetcher, {
refreshInterval: 1000,
refreshWhenHidden: false,
@@ -110,12 +110,12 @@ export function useTransactionDetails(account: string, tid: number) {
return undefined;
}
-export function usePublicAccounts(initial?: number) {
+export function usePublicAccounts(filterAccount: string |undefined ,initial?: number) {
const [offset, setOffset] = useState<number | undefined>(initial);
const { api } = useBankCoreApiContext();
- async function fetcher([txid]: [number | undefined]) {
- return await api.getPublicAccounts({
+ async function fetcher([account, txid]: [string | undefined , number | undefined]) {
+ return await api.getPublicAccounts({account},{
limit: MAX_RESULT_SIZE,
offset: txid ? String(txid) : undefined,
order: "asc"
@@ -123,7 +123,7 @@ export function usePublicAccounts(initial?: number) {
}
const { data, error } = useSWR<TalerCoreBankResultByMethod<"getPublicAccounts">, TalerHttpError>(
- [offset, "getPublicAccounts"], fetcher, {
+ [filterAccount, offset, "getPublicAccounts"], fetcher, {
refreshInterval: 0,
refreshWhenHidden: false,
revalidateOnFocus: false,
diff --git a/packages/demobank-ui/src/pages/OperationState/index.ts b/packages/demobank-ui/src/pages/OperationState/index.ts
index 120fd7b45..0776bbed5 100644
--- a/packages/demobank-ui/src/pages/OperationState/index.ts
+++ b/packages/demobank-ui/src/pages/OperationState/index.ts
@@ -83,8 +83,8 @@ export namespace State {
}
export interface NeedConfirmation {
status: "need-confirmation",
- onAbort: () => Promise<TalerCoreBankErrorsByMethod<"abortWithdrawalById"> | undefined>;
- onConfirm: () => Promise<TalerCoreBankErrorsByMethod<"confirmWithdrawalById"> | undefined>;
+ onAbort: undefined | (() => Promise<TalerCoreBankErrorsByMethod<"abortWithdrawalById"> | undefined>);
+ onConfirm: undefined | (() => Promise<TalerCoreBankErrorsByMethod<"confirmWithdrawalById"> | undefined>);
error: undefined;
busy: boolean,
}
diff --git a/packages/demobank-ui/src/pages/OperationState/state.ts b/packages/demobank-ui/src/pages/OperationState/state.ts
index 30f7419f0..da924104a 100644
--- a/packages/demobank-ui/src/pages/OperationState/state.ts
+++ b/packages/demobank-ui/src/pages/OperationState/state.ts
@@ -74,7 +74,8 @@ export function useComponentState({ currency, onClose }: Props): utils.Recursive
const wid = withdrawalOperationId
async function doAbort() {
- const resp = await api.abortWithdrawalById(wid);
+ if (!creds) return;
+ const resp = await api.abortWithdrawalById(creds, wid);
if (resp.type === "ok") {
updateSettings("currentWithdrawalOperationId", undefined)
onClose();
@@ -84,8 +85,9 @@ export function useComponentState({ currency, onClose }: Props): utils.Recursive
}
async function doConfirm(): Promise<TalerCoreBankErrorsByMethod<"confirmWithdrawalById"> | undefined> {
+ if (!creds) return;
setBusy({})
- const resp = await api.confirmWithdrawalById(wid);
+ const resp = await api.confirmWithdrawalById(creds, wid);
setBusy(undefined)
if (resp.type === "ok") {
mutate(() => true)//clean withdrawal state
@@ -142,23 +144,12 @@ export function useComponentState({ currency, onClose }: Props): utils.Recursive
},
}
}
- case "invalid-id": {
- return {
- status: "aborted",
- error: undefined,
- onClose: async () => {
- updateSettings("currentWithdrawalOperationId", undefined)
- onClose()
- },
- }
-
- }
- default: assertUnreachable(result)
+ default: assertUnreachable(result.case)
}
}
const { body: data } = result;
- if (data.aborted) {
+ if (data.status === "aborted") {
return {
status: "aborted",
error: undefined,
@@ -169,7 +160,7 @@ export function useComponentState({ currency, onClose }: Props): utils.Recursive
}
}
- if (data.confirmation_done) {
+ if (data.status === "confirmed") {
if (!settings.showWithdrawalSuccess) {
updateSettings("currentWithdrawalOperationId", undefined)
onClose()
@@ -184,12 +175,15 @@ export function useComponentState({ currency, onClose }: Props): utils.Recursive
}
}
- if (!data.selection_done) {
+ if (data.status === "pending") {
return {
status: "ready",
error: undefined,
uri: parsedUri,
- onClose: doAbort,
+ onClose: !creds ? (async () => {
+ onClose();
+ return undefined
+ }) : doAbort,
}
}
@@ -216,9 +210,9 @@ export function useComponentState({ currency, onClose }: Props): utils.Recursive
return {
status: "need-confirmation",
error: undefined,
- onAbort: doAbort,
+ onAbort: !creds ? undefined : doAbort,
busy: !!busy,
- onConfirm: doConfirm
+ onConfirm: !creds ? undefined : doConfirm
}
}
diff --git a/packages/demobank-ui/src/pages/OperationState/views.tsx b/packages/demobank-ui/src/pages/OperationState/views.tsx
index a06147039..a3b30c179 100644
--- a/packages/demobank-ui/src/pages/OperationState/views.tsx
+++ b/packages/demobank-ui/src/pages/OperationState/views.tsx
@@ -69,6 +69,7 @@ export function NeedConfirmationView({ error, onAbort: doAbort, onConfirm: doCon
async function onCancel() {
errorHandler(async () => {
+ if (!doAbort) return;
const resp = await doAbort()
if (!resp) return;
switch (resp.case) {
@@ -97,6 +98,7 @@ export function NeedConfirmationView({ error, onAbort: doAbort, onConfirm: doCon
async function onConfirm() {
errorHandler(async () => {
+ if (!doConfirm) return;
const hasError = await doConfirm()
if (!hasError) {
if (!settings.showWithdrawalSuccess) {
@@ -186,26 +188,34 @@ export function NeedConfirmationView({ error, onAbort: doAbort, onConfirm: doCon
<ShowInputErrorLabel message={errors?.answer} isDirty={captchaAnswer !== undefined} />
</div>
</div>
- <div class="flex items-center justify-between gap-x-6 border-t border-gray-900/10 px-4 py-4 sm:px-8">
- <button type="button" class="text-sm font-semibold leading-6 text-gray-900"
- onClick={(e) => {
- e.preventDefault()
- onCancel()
- }}
- >
- <i18n.Translate>Cancel</i18n.Translate></button>
- <button type="submit"
- class="disabled:opacity-50 disabled:cursor-default cursor-pointer rounded-md bg-indigo-600 px-3 py-2 text-sm font-semibold text-white shadow-sm hover:bg-indigo-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600"
- disabled={!!errors}
- onClick={(e) => {
- e.preventDefault()
- onConfirm()
- }}
- >
- <i18n.Translate>Transfer</i18n.Translate>
- </button>
- </div>
+ {!doAbort || !doConfirm ?
+ <Attention type="warning" title={i18n.str`not logged in`}>
+ <i18n.Translate>
+ You need to log in as pepito to complete the operation
+ </i18n.Translate>
+ </Attention>
+ :
+ <div class="flex items-center justify-between gap-x-6 border-t border-gray-900/10 px-4 py-4 sm:px-8">
+ <button type="button" class="text-sm font-semibold leading-6 text-gray-900"
+ onClick={(e) => {
+ e.preventDefault()
+ onCancel()
+ }}
+ >
+ <i18n.Translate>Cancel</i18n.Translate></button>
+ <button type="submit"
+ class="disabled:opacity-50 disabled:cursor-default cursor-pointer rounded-md bg-indigo-600 px-3 py-2 text-sm font-semibold text-white shadow-sm hover:bg-indigo-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600"
+ disabled={!!errors}
+ onClick={(e) => {
+ e.preventDefault()
+ onConfirm()
+ }}
+ >
+ <i18n.Translate>Transfer</i18n.Translate>
+ </button>
+ </div>
+ }
</form>
</div>
<div class="px-4 mt-4 ">
diff --git a/packages/demobank-ui/src/pages/PublicHistoriesPage.tsx b/packages/demobank-ui/src/pages/PublicHistoriesPage.tsx
index 7d93e7222..eb6f6fd27 100644
--- a/packages/demobank-ui/src/pages/PublicHistoriesPage.tsx
+++ b/packages/demobank-ui/src/pages/PublicHistoriesPage.tsx
@@ -32,7 +32,8 @@ interface Props { }
export function PublicHistoriesPage({ }: Props): VNode {
const { i18n } = useTranslationContext();
- const result = usePublicAccounts();
+ //TODO: implemented filter by account name
+ const result = usePublicAccounts(undefined);
const firstAccount = result && !(result instanceof TalerError) && result.data.public_accounts.length > 0
? result.data.public_accounts[0].account_name
: undefined;
diff --git a/packages/demobank-ui/src/pages/QrCodeSection.tsx b/packages/demobank-ui/src/pages/QrCodeSection.tsx
index f1394b3f6..60beb012e 100644
--- a/packages/demobank-ui/src/pages/QrCodeSection.tsx
+++ b/packages/demobank-ui/src/pages/QrCodeSection.tsx
@@ -30,6 +30,7 @@ import { useBankCoreApiContext } from "../context/config.js";
import { withRuntimeErrorHandling } from "../utils.js";
import { assertUnreachable } from "./WithdrawalOperationPage.js";
import { LocalNotificationBanner } from "@gnu-taler/web-util/browser";
+import { useBackendState } from "../hooks/backend.js";
export function QrCodeSection({
withdrawUri,
@@ -40,6 +41,9 @@ export function QrCodeSection({
}): VNode {
const { i18n } = useTranslationContext();
const talerWithdrawUri = stringifyWithdrawUri(withdrawUri);
+ const { state: credentials } = useBackendState();
+ const creds = credentials.status !== "loggedIn" ? undefined : credentials
+
useEffect(() => {
//Taler Wallet WebExtension is listening to headers response and tab updates.
//In the SPA there is no header response with the Taler URI so
@@ -58,7 +62,8 @@ export function QrCodeSection({
async function doAbort() {
await handleError(async () => {
- const resp = await api.abortWithdrawalById(withdrawUri.withdrawalOperationId);
+ if (!creds) return;
+ const resp = await api.abortWithdrawalById(creds, withdrawUri.withdrawalOperationId);
if (resp.type === "ok") {
onAborted();
} else {
diff --git a/packages/demobank-ui/src/pages/WithdrawalConfirmationQuestion.tsx b/packages/demobank-ui/src/pages/WithdrawalConfirmationQuestion.tsx
index bfb118c6c..e21c0917b 100644
--- a/packages/demobank-ui/src/pages/WithdrawalConfirmationQuestion.tsx
+++ b/packages/demobank-ui/src/pages/WithdrawalConfirmationQuestion.tsx
@@ -20,10 +20,13 @@ import {
PaytoUri,
PaytoUriIBAN,
PaytoUriTalerBank,
+ TalerError,
TranslatedString,
WithdrawUriResult
} from "@gnu-taler/taler-util";
import {
+ ErrorLoading,
+ Loading,
notifyInfo,
useLocalNotification,
useTranslationContext
@@ -38,6 +41,10 @@ import { undefinedIfEmpty, withRuntimeErrorHandling } from "../utils.js";
import { RenderAmount } from "./PaytoWireTransferForm.js";
import { assertUnreachable } from "./WithdrawalOperationPage.js";
import { LocalNotificationBanner } from "@gnu-taler/web-util/browser";
+import { useBackendState } from "../hooks/backend.js";
+import { useWithdrawalDetails } from "../hooks/access.js";
+import { OperationState } from "./OperationState/index.js";
+import { OperationNotFound } from "./WithdrawalQRCode.js";
const logger = new Logger("WithdrawalConfirmationQuestion");
@@ -60,8 +67,23 @@ export function WithdrawalConfirmationQuestion({
withdrawUri,
}: Props): VNode {
const { i18n } = useTranslationContext();
- const [settings, updateSettings] = usePreferences()
-
+ const [settings] = usePreferences()
+ const { state: credentials } = useBackendState();
+ const creds = credentials.status !== "loggedIn" ? undefined : credentials
+ const withdrawalInfo = useWithdrawalDetails(withdrawUri.withdrawalOperationId)
+ if (!withdrawalInfo) {
+ return <Loading />
+ }
+ if (withdrawalInfo instanceof TalerError) {
+ return <ErrorLoading error={withdrawalInfo} />
+ }
+ if (withdrawalInfo.type === "fail") {
+ switch(withdrawalInfo.case) {
+ case "not-found": return <OperationNotFound onClose={onAborted} />
+ default: assertUnreachable(withdrawalInfo.case)
+ }
+ }
+
const captchaNumbers = useMemo(() => {
return {
a: Math.floor(Math.random() * 10),
@@ -87,7 +109,8 @@ export function WithdrawalConfirmationQuestion({
async function doTransfer() {
setBusy({})
await handleError(async () => {
- const resp = await api.confirmWithdrawalById(withdrawUri.withdrawalOperationId);
+ if (!creds) return;
+ const resp = await api.confirmWithdrawalById(creds, withdrawUri.withdrawalOperationId);
if (resp.type === "ok") {
mutate(() => true)// clean any info that we have
if (!settings.showWithdrawalSuccess) {
@@ -135,7 +158,8 @@ export function WithdrawalConfirmationQuestion({
async function doCancel() {
setBusy({})
await handleError(async () => {
- const resp = await api.abortWithdrawalById(withdrawUri.withdrawalOperationId);
+ if (!creds) return;
+ const resp = await api.abortWithdrawalById(creds, withdrawUri.withdrawalOperationId);
if (resp.type === "ok") {
onAborted();
} else {
@@ -217,6 +241,7 @@ export function WithdrawalConfirmationQuestion({
<ShowInputErrorLabel message={errors?.answer} isDirty={captchaAnswer !== undefined} />
</div>
</div>
+
<div class="flex items-center justify-between gap-x-6 border-t border-gray-900/10 px-4 py-4 sm:px-8">
<button type="button" class="text-sm font-semibold leading-6 text-gray-900"
onClick={doCancel}
diff --git a/packages/demobank-ui/src/pages/WithdrawalQRCode.tsx b/packages/demobank-ui/src/pages/WithdrawalQRCode.tsx
index 52e3c63ee..0c3d83c3b 100644
--- a/packages/demobank-ui/src/pages/WithdrawalQRCode.tsx
+++ b/packages/demobank-ui/src/pages/WithdrawalQRCode.tsx
@@ -58,14 +58,13 @@ export function WithdrawalQRCode({
if (result.type === "fail") {
switch (result.case) {
case "not-found": return <OperationNotFound onClose={onClose} />
- case "invalid-id": return <OperationNotFound onClose={onClose} />
- default: assertUnreachable(result)
+ default: assertUnreachable(result.case)
}
}
const { body: data } = result;
- if (data.aborted) {
+ if (data.status === "aborted") {
return <section id="main" class="content">
<h1 class="nav">{i18n.str`Operation aborted`}</h1>
<section>
@@ -93,7 +92,7 @@ export function WithdrawalQRCode({
</section>
}
- if (data.confirmation_done) {
+ if (data.status === "confirmed") {
return <div class="relative ml-auto mr-auto transform overflow-hidden rounded-lg bg-white px-4 pb-4 pt-5 text-left shadow-xl transition-all sm:my-8 sm:w-full sm:max-w-sm sm:p-6">
<div>
<div class="mx-auto flex h-12 w-12 items-center justify-center rounded-full bg-green-100">
@@ -128,7 +127,7 @@ export function WithdrawalQRCode({
}
- if (!data.selection_done) {
+ if (data.status === "pending") {
return (
<QrCodeSection
withdrawUri={withdrawUri}
@@ -173,7 +172,7 @@ export function WithdrawalQRCode({
}
-function OperationNotFound({ onClose }: { onClose: () => void }): VNode {
+export function OperationNotFound({ onClose }: { onClose: () => void }): VNode {
const { i18n } = useTranslationContext();
return <div class="relative ml-auto mr-auto transform overflow-hidden rounded-lg bg-white px-4 pb-4 pt-5 text-left shadow-xl transition-all sm:my-8 sm:w-full sm:max-w-sm sm:p-6">
<div>
diff --git a/packages/demobank-ui/src/pages/account/ShowAccountDetails.tsx b/packages/demobank-ui/src/pages/account/ShowAccountDetails.tsx
index 4332284e8..b5579c199 100644
--- a/packages/demobank-ui/src/pages/account/ShowAccountDetails.tsx
+++ b/packages/demobank-ui/src/pages/account/ShowAccountDetails.tsx
@@ -82,9 +82,21 @@ export function ShowAccountDetails({
description: resp.detail.hint as TranslatedString,
debug: resp.detail,
})
- case "cant-change-legal-name-or-admin": return notify({
+ case "admin-cant-be-exchange": return notify({
type: "error",
- title: i18n.str`Can't change legal name`,
+ title: i18n.str`This is an administration account, changing to exchange account is denied.`,
+ description: resp.detail.hint as TranslatedString,
+ debug: resp.detail,
+ })
+ case "user-cant-change-name": return notify({
+ type: "error",
+ title: i18n.str`You can't change the legal name, please contact the your account administrator.`,
+ description: resp.detail.hint as TranslatedString,
+ debug: resp.detail,
+ })
+ case "user-cant-change-debt": return notify({
+ type: "error",
+ title: i18n.str`You can't change the debt limit, please contact the your account administrator.`,
description: resp.detail.hint as TranslatedString,
debug: resp.detail,
})
diff --git a/packages/demobank-ui/src/pages/account/UpdateAccountPassword.tsx b/packages/demobank-ui/src/pages/account/UpdateAccountPassword.tsx
index 3c00ad1b8..eef2a0692 100644
--- a/packages/demobank-ui/src/pages/account/UpdateAccountPassword.tsx
+++ b/packages/demobank-ui/src/pages/account/UpdateAccountPassword.tsx
@@ -61,16 +61,18 @@ export function UpdateAccountPassword({
type: "error",
title: i18n.str`Not authorized to change the password, maybe the session is invalid.`
})
- case "old-password-invalid-or-not-allowed": return notify({
- type: "error",
- title: current ?
- i18n.str`This user have no right on to change the password.` :
- i18n.str`This user have no right on to change the password or the old password doesn't match.`
- })
case "not-found": return notify({
type: "error",
title: i18n.str`Account not found`
})
+ case "user-require-old-password": return notify({
+ type: "error",
+ title: i18n.str`Old password need to be provided in order to change new one. If you don't have it contact your account administrator.`
+ })
+ case "wrong-old-password": return notify({
+ type: "error",
+ title: i18n.str`Your current password doesn't match, can't change to a new password.`
+ })
default: assertUnreachable(resp)
}
}