use /taler-uri as redirection point to all taler uris
This commit is contained in:
parent
ebd0041956
commit
7b2de89444
@ -38,6 +38,7 @@ import { useAsyncAsHook } from "./hooks/useAsyncAsHook.js";
|
||||
import qrIcon from "./svg/qr_code_24px.svg";
|
||||
import settingsIcon from "./svg/settings_black_24dp.svg";
|
||||
import warningIcon from "./svg/warning_24px.svg";
|
||||
import { parseTalerUri, TalerUriAction } from "@gnu-taler/taler-util";
|
||||
|
||||
/**
|
||||
* List of pages used by the wallet
|
||||
@ -115,6 +116,7 @@ export const Pages = {
|
||||
"/settings/exchange/add/:currency?",
|
||||
),
|
||||
|
||||
defaultCta: pageDefinition<{ uri: string }>("/taler-uri/:uri"),
|
||||
cta: pageDefinition<{ action: string }>("/cta/:action"),
|
||||
ctaPay: "/cta/pay",
|
||||
ctaPayTemplate: "/cta/pay/template",
|
||||
@ -136,6 +138,34 @@ export const Pages = {
|
||||
),
|
||||
};
|
||||
|
||||
const talerUriActionToPageName: {
|
||||
[t in TalerUriAction]: keyof typeof Pages | undefined;
|
||||
} = {
|
||||
[TalerUriAction.Withdraw]: "ctaWithdraw",
|
||||
[TalerUriAction.Pay]: "ctaPay",
|
||||
[TalerUriAction.Tip]: "ctaTips",
|
||||
[TalerUriAction.Refund]: "ctaRefund",
|
||||
[TalerUriAction.PayPull]: "ctaInvoicePay",
|
||||
[TalerUriAction.PayPush]: "ctaTransferPickup",
|
||||
[TalerUriAction.Restore]: "ctaRecovery",
|
||||
[TalerUriAction.PayTemplate]: "ctaPayTemplate",
|
||||
[TalerUriAction.DevExperiment]: undefined,
|
||||
[TalerUriAction.Exchange]: undefined,
|
||||
[TalerUriAction.Auditor]: undefined,
|
||||
};
|
||||
|
||||
export function getPathnameForTalerURI(talerUri: string): string | undefined {
|
||||
const uri = parseTalerUri(talerUri);
|
||||
if (!uri) {
|
||||
return undefined;
|
||||
}
|
||||
const pageName = talerUriActionToPageName[uri.type];
|
||||
if (!pageName) {
|
||||
return undefined;
|
||||
}
|
||||
return `${Pages[pageName]}?talerUri=${encodeURIComponent(talerUri)}`;
|
||||
}
|
||||
|
||||
export type PopupNavBarOptions = "balance" | "backup" | "dev";
|
||||
export function PopupNavBar({ path }: { path?: PopupNavBarOptions }): VNode {
|
||||
const api = useBackendContext();
|
||||
|
@ -15,11 +15,11 @@
|
||||
*/
|
||||
|
||||
import {
|
||||
classifyTalerUri,
|
||||
Logger,
|
||||
TalerErrorCode,
|
||||
TalerUriType,
|
||||
TalerUriAction,
|
||||
TalerError,
|
||||
parseTalerUri,
|
||||
} from "@gnu-taler/taler-util";
|
||||
import { WalletOperations } from "@gnu-taler/taler-wallet-core";
|
||||
import { BackgroundOperations } from "../wxApi.js";
|
||||
@ -239,80 +239,83 @@ function openWalletURIFromPopup(maybeTalerUri: string): void {
|
||||
const talerUri = maybeTalerUri.startsWith("ext+")
|
||||
? maybeTalerUri.substring(4)
|
||||
: maybeTalerUri;
|
||||
const uriType = classifyTalerUri(talerUri);
|
||||
const uri = parseTalerUri(talerUri);
|
||||
if (!uri) {
|
||||
logger.warn(
|
||||
`Response with HTTP 402 the Taler header but could not classify ${talerUri}`,
|
||||
);
|
||||
return;
|
||||
}
|
||||
//FIXME: this should redirect to just one place
|
||||
// the target pathname should handle what happens if the endpoint is not there
|
||||
// like "trying to open from popup but this uri is not handled"
|
||||
|
||||
encodeURIComponent;
|
||||
let url: string | undefined = undefined;
|
||||
switch (uriType) {
|
||||
case TalerUriType.TalerWithdraw:
|
||||
switch (uri.type) {
|
||||
case TalerUriAction.Withdraw:
|
||||
url = chrome.runtime.getURL(
|
||||
`static/wallet.html#/cta/withdraw?talerWithdrawUri=${encodeURIComponent(
|
||||
`static/wallet.html#/cta/withdraw?talerUri=${encodeURIComponent(
|
||||
talerUri,
|
||||
)}`,
|
||||
);
|
||||
break;
|
||||
case TalerUriType.TalerRecovery:
|
||||
case TalerUriAction.Restore:
|
||||
url = chrome.runtime.getURL(
|
||||
`static/wallet.html#/cta/recovery?talerRecoveryUri=${encodeURIComponent(
|
||||
`static/wallet.html#/cta/recovery?talerUri=${encodeURIComponent(
|
||||
talerUri,
|
||||
)}`,
|
||||
);
|
||||
break;
|
||||
case TalerUriType.TalerPay:
|
||||
case TalerUriAction.Pay:
|
||||
url = chrome.runtime.getURL(
|
||||
`static/wallet.html#/cta/pay?talerPayUri=${encodeURIComponent(
|
||||
`static/wallet.html#/cta/pay?talerUri=${encodeURIComponent(talerUri)}`,
|
||||
);
|
||||
break;
|
||||
case TalerUriAction.Tip:
|
||||
url = chrome.runtime.getURL(
|
||||
`static/wallet.html#/cta/tip?talerUri=${encodeURIComponent(talerUri)}`,
|
||||
);
|
||||
break;
|
||||
case TalerUriAction.Refund:
|
||||
url = chrome.runtime.getURL(
|
||||
`static/wallet.html#/cta/refund?talerUri=${encodeURIComponent(
|
||||
talerUri,
|
||||
)}`,
|
||||
);
|
||||
break;
|
||||
case TalerUriType.TalerTip:
|
||||
case TalerUriAction.PayPull:
|
||||
url = chrome.runtime.getURL(
|
||||
`static/wallet.html#/cta/tip?talerTipUri=${encodeURIComponent(
|
||||
`static/wallet.html#/cta/invoice/pay?talerUri=${encodeURIComponent(
|
||||
talerUri,
|
||||
)}`,
|
||||
);
|
||||
break;
|
||||
case TalerUriType.TalerRefund:
|
||||
case TalerUriAction.PayPush:
|
||||
url = chrome.runtime.getURL(
|
||||
`static/wallet.html#/cta/refund?talerRefundUri=${encodeURIComponent(
|
||||
`static/wallet.html#/cta/transfer/pickup?talerUri=${encodeURIComponent(
|
||||
talerUri,
|
||||
)}`,
|
||||
);
|
||||
break;
|
||||
case TalerUriType.TalerPayPull:
|
||||
case TalerUriAction.PayTemplate:
|
||||
url = chrome.runtime.getURL(
|
||||
`static/wallet.html#/cta/invoice/pay?talerPayPullUri=${encodeURIComponent(
|
||||
`static/wallet.html#/cta/pay/template?talerUri=${encodeURIComponent(
|
||||
talerUri,
|
||||
)}`,
|
||||
);
|
||||
break;
|
||||
case TalerUriType.TalerPayPush:
|
||||
url = chrome.runtime.getURL(
|
||||
`static/wallet.html#/cta/transfer/pickup?talerPayPushUri=${encodeURIComponent(
|
||||
talerUri,
|
||||
)}`,
|
||||
);
|
||||
break;
|
||||
case TalerUriType.TalerPayTemplate:
|
||||
url = chrome.runtime.getURL(
|
||||
`static/wallet.html#/cta/pay/template?talerPayTemplateUri=${encodeURIComponent(
|
||||
talerUri,
|
||||
)}`,
|
||||
);
|
||||
break;
|
||||
case TalerUriType.Unknown:
|
||||
logger.warn(
|
||||
`Response with HTTP 402 the Taler header but could not classify ${talerUri}`,
|
||||
);
|
||||
return;
|
||||
case TalerUriType.TalerDevExperiment:
|
||||
case TalerUriAction.DevExperiment:
|
||||
logger.warn(`taler://dev-experiment URIs are not allowed in headers`);
|
||||
return;
|
||||
case TalerUriType.TalerTemplate:
|
||||
logger.warn(`taler://dev-template URIs are not allowed in headers`);
|
||||
case TalerUriAction.Exchange:
|
||||
logger.warn(`taler://exchange not yet supported`);
|
||||
return;
|
||||
case TalerUriAction.Auditor:
|
||||
logger.warn(`taler://auditor not yet supported`);
|
||||
return;
|
||||
default: {
|
||||
const error: never = uriType;
|
||||
const error: never = uri;
|
||||
logger.warn(
|
||||
`Response with HTTP 402 the Taler header "${error}", but header value is not a taler:// URI.`,
|
||||
);
|
||||
|
@ -20,7 +20,11 @@
|
||||
* @author sebasjm
|
||||
*/
|
||||
|
||||
import { TranslatedString } from "@gnu-taler/taler-util";
|
||||
import {
|
||||
TalerUriAction,
|
||||
TranslatedString,
|
||||
parseTalerUri,
|
||||
} from "@gnu-taler/taler-util";
|
||||
import { createHashHistory } from "history";
|
||||
import { ComponentChildren, Fragment, h, VNode } from "preact";
|
||||
import { route, Route, Router } from "preact-router";
|
||||
@ -55,7 +59,12 @@ import {
|
||||
WithdrawPageFromParams,
|
||||
WithdrawPageFromURI,
|
||||
} from "../cta/Withdraw/index.js";
|
||||
import { Pages, WalletNavBar, WalletNavBarOptions } from "../NavigationBar.js";
|
||||
import {
|
||||
Pages,
|
||||
WalletNavBar,
|
||||
WalletNavBarOptions,
|
||||
getPathnameForTalerURI,
|
||||
} from "../NavigationBar.js";
|
||||
import { platform } from "../platform/foreground.js";
|
||||
import CloseIcon from "../svg/close_24px.svg";
|
||||
import { AddBackupProviderPage } from "./AddBackupProvider/index.js";
|
||||
@ -285,12 +294,22 @@ export function Application(): VNode {
|
||||
{/**
|
||||
* CALL TO ACTION
|
||||
*/}
|
||||
<Route
|
||||
path={Pages.defaultCta.pattern}
|
||||
component={({ uri }: { uri: string }) => {
|
||||
const path = getPathnameForTalerURI(uri);
|
||||
if (!path) {
|
||||
return <Redirect to={Pages.balance} />;
|
||||
}
|
||||
return <Redirect to={path} />;
|
||||
}}
|
||||
/>
|
||||
<Route
|
||||
path={Pages.ctaPay}
|
||||
component={({ talerPayUri }: { talerPayUri: string }) => (
|
||||
component={({ talerUri }: { talerUri: string }) => (
|
||||
<CallToActionTemplate title={i18n.str`Digital cash payment`}>
|
||||
<PaymentPage
|
||||
talerPayUri={decodeURIComponent(talerPayUri)}
|
||||
talerPayUri={decodeURIComponent(talerUri)}
|
||||
goToWalletManualWithdraw={(amount?: string) =>
|
||||
redirectTo(Pages.receiveCash({ amount }))
|
||||
}
|
||||
@ -304,14 +323,10 @@ export function Application(): VNode {
|
||||
/>
|
||||
<Route
|
||||
path={Pages.ctaPayTemplate}
|
||||
component={({
|
||||
talerPayTemplateUri,
|
||||
}: {
|
||||
talerPayTemplateUri: string;
|
||||
}) => (
|
||||
component={({ talerUri }: { talerUri: string }) => (
|
||||
<CallToActionTemplate title={i18n.str`Digital cash payment`}>
|
||||
<PaymentTemplatePage
|
||||
talerTemplateUri={decodeURIComponent(talerPayTemplateUri)}
|
||||
talerTemplateUri={decodeURIComponent(talerUri)}
|
||||
goToWalletManualWithdraw={(amount?: string) =>
|
||||
redirectTo(Pages.receiveCash({ amount }))
|
||||
}
|
||||
@ -325,10 +340,10 @@ export function Application(): VNode {
|
||||
/>
|
||||
<Route
|
||||
path={Pages.ctaRefund}
|
||||
component={({ talerRefundUri }: { talerRefundUri: string }) => (
|
||||
component={({ talerUri }: { talerUri: string }) => (
|
||||
<CallToActionTemplate title={i18n.str`Digital cash refund`}>
|
||||
<RefundPage
|
||||
talerRefundUri={decodeURIComponent(talerRefundUri)}
|
||||
talerRefundUri={decodeURIComponent(talerUri)}
|
||||
cancel={() => redirectTo(Pages.balance)}
|
||||
onSuccess={(tid: string) =>
|
||||
redirectTo(Pages.balanceTransaction({ tid }))
|
||||
@ -339,10 +354,10 @@ export function Application(): VNode {
|
||||
/>
|
||||
<Route
|
||||
path={Pages.ctaTips}
|
||||
component={({ talerTipUri }: { talerTipUri: string }) => (
|
||||
component={({ talerUri }: { talerUri: string }) => (
|
||||
<CallToActionTemplate title={i18n.str`Digital cash tip`}>
|
||||
<TipPage
|
||||
talerTipUri={decodeURIComponent(talerTipUri)}
|
||||
talerTipUri={decodeURIComponent(talerUri)}
|
||||
onCancel={() => redirectTo(Pages.balance)}
|
||||
onSuccess={(tid: string) =>
|
||||
redirectTo(Pages.balanceTransaction({ tid }))
|
||||
@ -353,14 +368,10 @@ export function Application(): VNode {
|
||||
/>
|
||||
<Route
|
||||
path={Pages.ctaWithdraw}
|
||||
component={({
|
||||
talerWithdrawUri,
|
||||
}: {
|
||||
talerWithdrawUri: string;
|
||||
}) => (
|
||||
component={({ talerUri }: { talerUri: string }) => (
|
||||
<CallToActionTemplate title={i18n.str`Digital cash withdrawal`}>
|
||||
<WithdrawPageFromURI
|
||||
talerWithdrawUri={decodeURIComponent(talerWithdrawUri)}
|
||||
talerWithdrawUri={decodeURIComponent(talerUri)}
|
||||
cancel={() => redirectTo(Pages.balance)}
|
||||
onSuccess={(tid: string) =>
|
||||
redirectTo(Pages.balanceTransaction({ tid }))
|
||||
@ -387,15 +398,15 @@ export function Application(): VNode {
|
||||
path={Pages.ctaDeposit}
|
||||
component={({
|
||||
amount,
|
||||
talerDepositUri,
|
||||
talerUri,
|
||||
}: {
|
||||
amount: string;
|
||||
talerDepositUri: string;
|
||||
talerUri: string;
|
||||
}) => (
|
||||
<CallToActionTemplate title={i18n.str`Digital cash deposit`}>
|
||||
<DepositPageCTA
|
||||
amountStr={amount}
|
||||
talerDepositUri={decodeURIComponent(talerDepositUri)}
|
||||
talerDepositUri={decodeURIComponent(talerUri)}
|
||||
cancel={() => redirectTo(Pages.balance)}
|
||||
onSuccess={(tid: string) =>
|
||||
redirectTo(Pages.balanceTransaction({ tid }))
|
||||
@ -434,10 +445,10 @@ export function Application(): VNode {
|
||||
/>
|
||||
<Route
|
||||
path={Pages.ctaInvoicePay}
|
||||
component={({ talerPayPullUri }: { talerPayPullUri: string }) => (
|
||||
component={({ talerUri }: { talerUri: string }) => (
|
||||
<CallToActionTemplate title={i18n.str`Digital cash invoice`}>
|
||||
<InvoicePayPage
|
||||
talerPayPullUri={decodeURIComponent(talerPayPullUri)}
|
||||
talerPayPullUri={decodeURIComponent(talerUri)}
|
||||
goToWalletManualWithdraw={(amount?: string) =>
|
||||
redirectTo(Pages.receiveCash({ amount }))
|
||||
}
|
||||
@ -451,10 +462,10 @@ export function Application(): VNode {
|
||||
/>
|
||||
<Route
|
||||
path={Pages.ctaTransferPickup}
|
||||
component={({ talerPayPushUri }: { talerPayPushUri: string }) => (
|
||||
component={({ talerUri }: { talerUri: string }) => (
|
||||
<CallToActionTemplate title={i18n.str`Digital cash transfer`}>
|
||||
<TransferPickupPage
|
||||
talerPayPushUri={decodeURIComponent(talerPayPushUri)}
|
||||
talerPayPushUri={decodeURIComponent(talerUri)}
|
||||
onClose={() => redirectTo(Pages.balance)}
|
||||
onSuccess={(tid: string) =>
|
||||
redirectTo(Pages.balanceTransaction({ tid }))
|
||||
|
@ -34,6 +34,8 @@ import {
|
||||
WalletDiagnostics,
|
||||
makeErrorDetail,
|
||||
getErrorDetailFromException,
|
||||
parseTalerUri,
|
||||
TalerUriAction,
|
||||
} from "@gnu-taler/taler-util";
|
||||
import {
|
||||
DbAccess,
|
||||
@ -332,69 +334,17 @@ function parseTalerUriAndRedirect(tabId: number, maybeTalerUri: string): void {
|
||||
const talerUri = maybeTalerUri.startsWith("ext+")
|
||||
? maybeTalerUri.substring(4)
|
||||
: maybeTalerUri;
|
||||
const uriType = classifyTalerUri(talerUri);
|
||||
switch (uriType) {
|
||||
case TalerUriType.TalerWithdraw:
|
||||
return platform.redirectTabToWalletPage(
|
||||
tabId,
|
||||
`/cta/withdraw?talerWithdrawUri=${encodeURIComponent(talerUri)}`,
|
||||
);
|
||||
case TalerUriType.TalerPay:
|
||||
return platform.redirectTabToWalletPage(
|
||||
tabId,
|
||||
`/cta/pay?talerPayUri=${encodeURIComponent(talerUri)}`,
|
||||
);
|
||||
case TalerUriType.TalerTip:
|
||||
return platform.redirectTabToWalletPage(
|
||||
tabId,
|
||||
`/cta/tip?talerTipUri=${encodeURIComponent(talerUri)}`,
|
||||
);
|
||||
case TalerUriType.TalerRefund:
|
||||
return platform.redirectTabToWalletPage(
|
||||
tabId,
|
||||
`/cta/refund?talerRefundUri=${encodeURIComponent(talerUri)}`,
|
||||
);
|
||||
case TalerUriType.TalerPayPull:
|
||||
return platform.redirectTabToWalletPage(
|
||||
tabId,
|
||||
`/cta/invoice/pay?talerPayPullUri=${encodeURIComponent(talerUri)}`,
|
||||
);
|
||||
case TalerUriType.TalerPayPush:
|
||||
return platform.redirectTabToWalletPage(
|
||||
tabId,
|
||||
`/cta/transfer/pickup?talerPayPushUri=${encodeURIComponent(talerUri)}`,
|
||||
);
|
||||
case TalerUriType.TalerRecovery:
|
||||
return platform.redirectTabToWalletPage(
|
||||
tabId,
|
||||
`/cta/transfer/recovery?talerBackupUri=${encodeURIComponent(talerUri)}`,
|
||||
);
|
||||
case TalerUriType.TalerPayTemplate:
|
||||
return platform.redirectTabToWalletPage(
|
||||
tabId,
|
||||
`/cta/pay/template?talerPayTemplateUri=${encodeURIComponent(talerUri)}`,
|
||||
);
|
||||
return;
|
||||
case TalerUriType.Unknown:
|
||||
logger.warn(
|
||||
`Response with HTTP 402 the Taler header but could not classify ${talerUri}`,
|
||||
);
|
||||
return;
|
||||
case TalerUriType.TalerDevExperiment:
|
||||
// FIXME: Implement!
|
||||
logger.warn("not implemented");
|
||||
return;
|
||||
case TalerUriType.TalerTemplate:
|
||||
logger.warn("not implemented");
|
||||
return;
|
||||
default: {
|
||||
const error: never = uriType;
|
||||
logger.warn(
|
||||
`Response with HTTP 402 the Taler header "${error}", but header value is not a taler:// URI.`,
|
||||
);
|
||||
return;
|
||||
}
|
||||
const uri = parseTalerUri(talerUri);
|
||||
if (!uri) {
|
||||
logger.warn(
|
||||
`Response with HTTP 402 the Taler header but could not classify ${talerUri}`,
|
||||
);
|
||||
return;
|
||||
}
|
||||
return platform.redirectTabToWalletPage(
|
||||
tabId,
|
||||
`/taler-uri/${encodeURIComponent(talerUri)}`,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user