diff options
author | Florian Dold <florian@dold.me> | 2024-05-15 23:47:00 +0200 |
---|---|---|
committer | Florian Dold <florian@dold.me> | 2024-05-15 23:47:00 +0200 |
commit | ca3234b53f8d28ff9cc41af68a0057eaecf69df2 (patch) | |
tree | 4f35eef59ed65a0b4daf4dcae5876b1d008b4e30 /packages | |
parent | 6529421a5c09dec082f33ea80b1df2861e0bf5c9 (diff) |
wallet-core: phase out support for public key in taler://withdraw-exchange URI
Diffstat (limited to 'packages')
-rw-r--r-- | packages/taler-util/src/taleruri.test.ts | 52 | ||||
-rw-r--r-- | packages/taler-util/src/taleruri.ts | 18 | ||||
-rw-r--r-- | packages/taler-util/src/wallet-types.ts | 3 | ||||
-rw-r--r-- | packages/taler-wallet-core/src/exchanges.ts | 2 | ||||
-rw-r--r-- | packages/taler-wallet-core/src/wallet.ts | 7 | ||||
-rw-r--r-- | packages/taler-wallet-core/src/withdraw.ts | 4 | ||||
-rw-r--r-- | packages/taler-wallet-webextension/src/cta/Withdraw/state.ts | 1 | ||||
-rw-r--r-- | packages/taler-wallet-webextension/src/wallet/DeveloperPage.tsx | 121 |
8 files changed, 93 insertions, 115 deletions
diff --git a/packages/taler-util/src/taleruri.test.ts b/packages/taler-util/src/taleruri.test.ts index 7f10d21fd..b751efa34 100644 --- a/packages/taler-util/src/taleruri.test.ts +++ b/packages/taler-util/src/taleruri.test.ts @@ -423,24 +423,27 @@ test("taler dev exp URI (stringify)", (t) => { */ test("taler withdraw exchange URI (parse)", (t) => { + // Pubkey has been phased out, may no longer be specified. { - const r1 = parseWithdrawExchangeUri( + const rx1 = parseWithdrawExchangeUri( "taler://withdraw-exchange/exchange.demo.taler.net/someroot/GJKG23V4ZBHEH45YRK7TWQE8ZTY7JWTY5094TQJSRZN5DSDBX8E0?a=KUDOS%3A2", ); - if (!r1) { + if (rx1) { t.fail(); return; } - t.deepEqual( - r1.exchangePub, - "GJKG23V4ZBHEH45YRK7TWQE8ZTY7JWTY5094TQJSRZN5DSDBX8E0", - ); - t.deepEqual( - r1.exchangeBaseUrl, - "https://exchange.demo.taler.net/someroot/", + } + { + const rx2 = parseWithdrawExchangeUri( + "taler://withdraw-exchange/exchange.demo.taler.net/GJKG23V4ZBHEH45YRK7TWQE8ZTY7JWTY5094TQJSRZN5DSDBX8E0", ); - t.deepEqual(r1.amount, "KUDOS:2"); + if (rx2) { + t.fail(); + return; + } } + + // Now test well-formed URIs { const r2 = parseWithdrawExchangeUri( "taler://withdraw-exchange/exchange.demo.taler.net/someroot/", @@ -449,7 +452,6 @@ test("taler withdraw exchange URI (parse)", (t) => { t.fail(); return; } - t.deepEqual(r2.exchangePub, undefined); t.deepEqual(r2.amount, undefined); t.deepEqual( r2.exchangeBaseUrl, @@ -465,7 +467,6 @@ test("taler withdraw exchange URI (parse)", (t) => { t.fail(); return; } - t.deepEqual(r3.exchangePub, undefined); t.deepEqual(r3.amount, undefined); t.deepEqual(r3.exchangeBaseUrl, "https://exchange.demo.taler.net/"); } @@ -479,7 +480,6 @@ test("taler withdraw exchange URI (parse)", (t) => { t.fail(); return; } - t.deepEqual(r4.exchangePub, undefined); t.deepEqual(r4.amount, undefined); t.deepEqual(r4.exchangeBaseUrl, "https://exchange.demo.taler.net/"); } @@ -488,27 +488,21 @@ test("taler withdraw exchange URI (parse)", (t) => { test("taler withdraw exchange URI (stringify)", (t) => { const url = stringifyWithdrawExchange({ exchangeBaseUrl: "https://exchange.demo.taler.net", - exchangePub: "GJKG23V4ZBHEH45YRK7TWQE8ZTY7JWTY5094TQJSRZN5DSDBX8E0", }); - t.deepEqual( - url, - "taler://withdraw-exchange/exchange.demo.taler.net/GJKG23V4ZBHEH45YRK7TWQE8ZTY7JWTY5094TQJSRZN5DSDBX8E0", - ); + t.deepEqual(url, "taler://withdraw-exchange/exchange.demo.taler.net/"); }); test("taler withdraw exchange URI with amount (stringify)", (t) => { const url = stringifyWithdrawExchange({ exchangeBaseUrl: "https://exchange.demo.taler.net", - exchangePub: "GJKG23V4ZBHEH45YRK7TWQE8ZTY7JWTY5094TQJSRZN5DSDBX8E0", amount: "KUDOS:19" as AmountString, }); t.deepEqual( url, - "taler://withdraw-exchange/exchange.demo.taler.net/GJKG23V4ZBHEH45YRK7TWQE8ZTY7JWTY5094TQJSRZN5DSDBX8E0?a=KUDOS%3A19", + "taler://withdraw-exchange/exchange.demo.taler.net/?a=KUDOS%3A19", ); }); - /** * 5.13 action: add-exchange https://lsd.gnunet.org/lsd0006/#name-action-add-exchange */ @@ -522,10 +516,7 @@ test("taler add exchange URI (parse)", (t) => { t.fail(); return; } - t.deepEqual( - r1.exchangeBaseUrl, - "https://exchange.example.com/", - ); + t.deepEqual(r1.exchangeBaseUrl, "https://exchange.example.com/"); } { const r2 = parseAddExchangeUri( @@ -535,22 +526,15 @@ test("taler add exchange URI (parse)", (t) => { t.fail(); return; } - t.deepEqual( - r2.exchangeBaseUrl, - "https://exchanges.example.com/api/", - ); + t.deepEqual(r2.exchangeBaseUrl, "https://exchanges.example.com/api/"); } - }); test("taler add exchange URI (stringify)", (t) => { const url = stringifyAddExchange({ exchangeBaseUrl: "https://exchange.demo.taler.net", }); - t.deepEqual( - url, - "taler://add-exchange/exchange.demo.taler.net/", - ); + t.deepEqual(url, "taler://add-exchange/exchange.demo.taler.net/"); }); /** diff --git a/packages/taler-util/src/taleruri.ts b/packages/taler-util/src/taleruri.ts index b4f9db6ef..576736503 100644 --- a/packages/taler-util/src/taleruri.ts +++ b/packages/taler-util/src/taleruri.ts @@ -124,7 +124,6 @@ export interface BackupRestoreUri { export interface WithdrawExchangeUri { type: TalerUriAction.WithdrawExchange; exchangeBaseUrl: string; - exchangePub?: string; amount?: AmountString; } @@ -212,9 +211,7 @@ export function parseAddExchangeUriWithError(s: string) { const result: AddExchangeUri = { type: TalerUriAction.AddExchange, - exchangeBaseUrl: canonicalizeBaseUrl( - `${pi.body.innerProto}://${p}/`, - ), + exchangeBaseUrl: canonicalizeBaseUrl(`${pi.body.innerProto}://${p}/`), }; return opFixedSuccess(result); } @@ -507,7 +504,14 @@ export function parseWithdrawExchangeUri( return undefined; } const host = parts[0].toLowerCase(); - const exchangePub = parts.length > 1 ? parts[parts.length - 1] : undefined; + // Used to be the reserve public key, now it's empty! + const lastPathComponent = + parts.length > 1 ? parts[parts.length - 1] : undefined; + + if (lastPathComponent) { + // invalid taler://withdraw-exchange URI, must end with a slash + return undefined; + } const pathSegments = parts.slice(1, parts.length - 1); const hostAndSegments = [host, ...pathSegments].join("/"); const exchangeBaseUrl = canonicalizeBaseUrl( @@ -519,7 +523,6 @@ export function parseWithdrawExchangeUri( return { type: TalerUriAction.WithdrawExchange, exchangeBaseUrl, - exchangePub: exchangePub != "" ? exchangePub : undefined, amount, }; } @@ -641,13 +644,12 @@ export function stringifyRestoreUri({ export function stringifyWithdrawExchange({ exchangeBaseUrl, - exchangePub, amount, }: Omit<WithdrawExchangeUri, "type">): string { const { proto, path, query } = getUrlInfo(exchangeBaseUrl, { a: amount, }); - return `${proto}://withdraw-exchange/${path}${exchangePub ?? ""}${query}`; + return `${proto}://withdraw-exchange/${path}${query}`; } export function stringifyAddExchange({ diff --git a/packages/taler-util/src/wallet-types.ts b/packages/taler-util/src/wallet-types.ts index b9fd24754..5e8320f33 100644 --- a/packages/taler-util/src/wallet-types.ts +++ b/packages/taler-util/src/wallet-types.ts @@ -1721,15 +1721,12 @@ export interface AddExchangeRequest { * @deprecated use a separate API call to start a forced exchange update instead */ forceUpdate?: boolean; - - masterPub?: string; } export const codecForAddExchangeRequest = (): Codec<AddExchangeRequest> => buildCodecForObject<AddExchangeRequest>() .property("exchangeBaseUrl", codecForCanonBaseUrl()) .property("forceUpdate", codecOptional(codecForBoolean())) - .property("masterPub", codecOptional(codecForString())) .build("AddExchangeRequest"); export interface UpdateExchangeEntryRequest { diff --git a/packages/taler-wallet-core/src/exchanges.ts b/packages/taler-wallet-core/src/exchanges.ts index 6262ae4d3..d8063d561 100644 --- a/packages/taler-wallet-core/src/exchanges.ts +++ b/packages/taler-wallet-core/src/exchanges.ts @@ -1152,9 +1152,7 @@ export async function fetchFreshExchange( wex: WalletExecutionContext, baseUrl: string, options: { - cancellationToken?: CancellationToken; forceUpdate?: boolean; - expectedMasterPub?: string; } = {}, ): Promise<ReadyExchangeSummary> { if (!options.forceUpdate) { diff --git a/packages/taler-wallet-core/src/wallet.ts b/packages/taler-wallet-core/src/wallet.ts index fe03dbf62..b8ef4976d 100644 --- a/packages/taler-wallet-core/src/wallet.ts +++ b/packages/taler-wallet-core/src/wallet.ts @@ -660,9 +660,6 @@ async function handlePrepareWithdrawExchange( } const exchangeBaseUrl = parsedUri.exchangeBaseUrl; const exchange = await fetchFreshExchange(wex, exchangeBaseUrl); - if (parsedUri.exchangePub && exchange.masterPub != parsedUri.exchangePub) { - throw Error("mismatch of exchange master public key (URI vs actual)"); - } if (parsedUri.amount) { const amt = Amounts.parseOrThrow(parsedUri.amount); if (amt.currency !== exchange.currency) { @@ -822,9 +819,7 @@ async function dispatchRequestInternal( } case WalletApiOperation.AddExchange: { const req = codecForAddExchangeRequest().decode(payload); - await fetchFreshExchange(wex, req.exchangeBaseUrl, { - expectedMasterPub: req.masterPub, - }); + await fetchFreshExchange(wex, req.exchangeBaseUrl, {}); return {}; } case WalletApiOperation.TestingPing: { diff --git a/packages/taler-wallet-core/src/withdraw.ts b/packages/taler-wallet-core/src/withdraw.ts index 43256d3fe..0eb9a3dfe 100644 --- a/packages/taler-wallet-core/src/withdraw.ts +++ b/packages/taler-wallet-core/src/withdraw.ts @@ -2078,9 +2078,7 @@ export async function getExchangeWithdrawalInfo( ageRestricted: number | undefined, ): Promise<ExchangeWithdrawalDetails> { logger.trace("updating exchange"); - const exchange = await fetchFreshExchange(wex, exchangeBaseUrl, { - cancellationToken: wex.cancellationToken, - }); + const exchange = await fetchFreshExchange(wex, exchangeBaseUrl, {}); wex.cancellationToken.throwIfCancelled(); diff --git a/packages/taler-wallet-webextension/src/cta/Withdraw/state.ts b/packages/taler-wallet-webextension/src/cta/Withdraw/state.ts index 044f2434f..0b36be1fd 100644 --- a/packages/taler-wallet-webextension/src/cta/Withdraw/state.ts +++ b/packages/taler-wallet-webextension/src/cta/Withdraw/state.ts @@ -55,7 +55,6 @@ export function useComponentStateFromParams({ if (exchangeByTalerUri) { await api.wallet.call(WalletApiOperation.AddExchange, { exchangeBaseUrl: exchangeByTalerUri, - masterPub: uri.exchangePub, }); const info = await api.wallet.call( WalletApiOperation.GetExchangeDetailedInfo, diff --git a/packages/taler-wallet-webextension/src/wallet/DeveloperPage.tsx b/packages/taler-wallet-webextension/src/wallet/DeveloperPage.tsx index 53380e263..7b6ac8895 100644 --- a/packages/taler-wallet-webextension/src/wallet/DeveloperPage.tsx +++ b/packages/taler-wallet-webextension/src/wallet/DeveloperPage.tsx @@ -19,12 +19,10 @@ import { Amounts, CoinDumpJson, CoinStatus, - ExchangeListItem, ExchangeTosStatus, LogLevel, NotificationType, ScopeType, - parseWithdrawUri, stringifyWithdrawExchange, } from "@gnu-taler/taler-util"; import { WalletApiOperation } from "@gnu-taler/taler-wallet-core"; @@ -32,10 +30,19 @@ import { useTranslationContext } from "@gnu-taler/web-util/browser"; import { format } from "date-fns"; import { Fragment, VNode, h } from "preact"; import { useEffect, useRef, useState } from "preact/hooks"; +import { Pages } from "../NavigationBar.js"; import { Checkbox } from "../components/Checkbox.js"; import { SelectList } from "../components/SelectList.js"; import { Time } from "../components/Time.js"; -import { DestructiveText, LinkPrimary, NotifyUpdateFadeOut, SubTitle, SuccessText, WarningText } from "../components/styled/index.js"; +import { ActiveTasksTable } from "../components/WalletActivity.js"; +import { + DestructiveText, + LinkPrimary, + NotifyUpdateFadeOut, + SubTitle, + SuccessText, + WarningText, +} from "../components/styled/index.js"; import { useAlertContext } from "../context/alert.js"; import { useBackendContext } from "../context/backend.js"; import { useAsyncAsHook } from "../hooks/useAsyncAsHook.js"; @@ -44,9 +51,6 @@ import { Button } from "../mui/Button.js"; import { Grid } from "../mui/Grid.js"; import { Paper } from "../mui/Paper.js"; import { TextField } from "../mui/TextField.js"; -import { Pages } from "../NavigationBar.js"; -import { CoinInfo } from "@gnu-taler/taler-wallet-core/dbless"; -import { ActiveTasksTable } from "../components/WalletActivity.js"; type CoinsInfo = CoinDumpJson["coins"]; type CalculatedCoinfInfo = { @@ -72,7 +76,7 @@ function hashObjectId(o: any): string { return JSON.stringify(o); } -export function DeveloperPage({ }: Props): VNode { +export function DeveloperPage({}: Props): VNode { const { i18n } = useTranslationContext(); const [downloadedDatabase, setDownloadedDatabase] = useState< { time: Date; content: string } | undefined @@ -110,8 +114,8 @@ export function DeveloperPage({ }: Props): VNode { useEffect(() => { return api.listener.onUpdateNotification(listenAllEvents, (ev) => { - console.log("event", ev) - return hook?.retry() + console.log("event", ev); + return hook?.retry(); }); }); @@ -275,7 +279,6 @@ export function DeveloperPage({ }: Props): VNode { })} /> - <SubTitle> <i18n.Translate>Exchange Entries</i18n.Translate> </SubTitle> @@ -336,19 +339,31 @@ export function DeveloperPage({ }: Props): VNode { ); } } - const uri = !e.masterPub ? undefined : stringifyWithdrawExchange({ - exchangeBaseUrl: e.exchangeBaseUrl, - exchangePub: e.masterPub, - }); + const uri = !e.masterPub + ? undefined + : stringifyWithdrawExchange({ + exchangeBaseUrl: e.exchangeBaseUrl, + }); return ( <tr key={idx}> <td> <a href={!uri ? undefined : Pages.defaultCta({ uri })}> - {e.scopeInfo ? `${e.scopeInfo.currency} (${e.scopeInfo.type === ScopeType.Global ? "global" : "regional"})` : e.currency} + {e.scopeInfo + ? `${e.scopeInfo.currency} (${ + e.scopeInfo.type === ScopeType.Global + ? "global" + : "regional" + })` + : e.currency} </a> </td> <td> - <a href={new URL(`/keys`, e.exchangeBaseUrl).href} target="_blank">{e.exchangeBaseUrl}</a> + <a + href={new URL(`/keys`, e.exchangeBaseUrl).href} + target="_blank" + > + {e.exchangeBaseUrl} + </a> </td> <td> {e.exchangeEntryStatus} / {e.exchangeUpdateStatus} @@ -359,10 +374,10 @@ export function DeveloperPage({ }: Props): VNode { <td> {e.lastUpdateTimestamp ? AbsoluteTime.toIsoString( - AbsoluteTime.fromPreciseTimestamp( - e.lastUpdateTimestamp, - ), - ) + AbsoluteTime.fromPreciseTimestamp( + e.lastUpdateTimestamp, + ), + ) : "never"} </td> <td> @@ -381,31 +396,25 @@ export function DeveloperPage({ }: Props): VNode { </button> <button onClick={() => { - api.wallet.call( - WalletApiOperation.DeleteExchange, - { - exchangeBaseUrl: e.exchangeBaseUrl, - }, - ); + api.wallet.call(WalletApiOperation.DeleteExchange, { + exchangeBaseUrl: e.exchangeBaseUrl, + }); }} > Delete </button> <button onClick={() => { - api.wallet.call( - WalletApiOperation.DeleteExchange, - { - exchangeBaseUrl: e.exchangeBaseUrl, - purge: true, - }, - ); + api.wallet.call(WalletApiOperation.DeleteExchange, { + exchangeBaseUrl: e.exchangeBaseUrl, + purge: true, + }); }} > Purge </button> - {e.scopeInfo && e.masterPub && e.currency ? - (e.scopeInfo.type === ScopeType.Global ? + {e.scopeInfo && e.masterPub && e.currency ? ( + e.scopeInfo.type === ScopeType.Global ? ( <button onClick={() => { api.wallet.call( @@ -418,30 +427,27 @@ export function DeveloperPage({ }: Props): VNode { ); }} > - Make regional </button> - : e.scopeInfo.type === ScopeType.Auditor ? - undefined - - : e.scopeInfo.type === ScopeType.Exchange ? - <button - onClick={() => { - api.wallet.call( - WalletApiOperation.AddGlobalCurrencyExchange, - { - exchangeBaseUrl: e.exchangeBaseUrl, - currency: e.currency!, - exchangeMasterPub: e.masterPub!, - }, - ); - }} - > - - Make global - </button> - : undefined) : undefined - } + ) : e.scopeInfo.type === + ScopeType.Auditor ? undefined : e.scopeInfo.type === + ScopeType.Exchange ? ( + <button + onClick={() => { + api.wallet.call( + WalletApiOperation.AddGlobalCurrencyExchange, + { + exchangeBaseUrl: e.exchangeBaseUrl, + currency: e.currency!, + exchangeMasterPub: e.masterPub!, + }, + ); + }} + > + Make global + </button> + ) : undefined + ) : undefined} <button onClick={() => { api.wallet.call( @@ -469,7 +475,6 @@ export function DeveloperPage({ }: Props): VNode { </LinkPrimary> </div> - <Paper style={{ padding: 10, margin: 10 }}> <h3>Logging</h3> <div> |