Store bank account information for reserve.

Fixes #4852.
This commit is contained in:
Florian Dold 2017-07-20 02:17:55 +02:00
parent 8d5b1e539b
commit a8bd05298e
No known key found for this signature in database
GPG Key ID: D2E4F00F29D02A4B
3 changed files with 87 additions and 52 deletions

View File

@ -35,6 +35,7 @@ import {
import {ImplicitStateComponent, StateHolder} from "../components"; import {ImplicitStateComponent, StateHolder} from "../components";
import { import {
createReserve,
getCurrency, getCurrency,
getExchangeInfo, getExchangeInfo,
getReserveCreationInfo, getReserveCreationInfo,
@ -242,6 +243,7 @@ interface ExchangeSelectionProps {
callback_url: string; callback_url: string;
wt_types: string[]; wt_types: string[];
currencyRecord: CurrencyRecord|null; currencyRecord: CurrencyRecord|null;
sender_wire: object | undefined;
} }
interface ManualSelectionProps { interface ManualSelectionProps {
@ -529,7 +531,8 @@ class ExchangeSelection extends ImplicitStateComponent<ExchangeSelectionProps> {
this.confirmReserveImpl(this.reserveCreationInfo()!, this.confirmReserveImpl(this.reserveCreationInfo()!,
this.url()!, this.url()!,
this.props.amount, this.props.amount,
this.props.callback_url); this.props.callback_url,
this.props.sender_wire);
} }
/** /**
@ -555,53 +558,55 @@ class ExchangeSelection extends ImplicitStateComponent<ExchangeSelectionProps> {
} }
} }
confirmReserveImpl(rci: ReserveCreationInfo, async confirmReserveImpl(rci: ReserveCreationInfo,
exchange: string, exchange: string,
amount: AmountJson, amount: AmountJson,
callback_url: string) { callback_url: string,
const d = {exchange: canonicalizeBaseUrl(exchange), amount}; sender_wire: object | undefined) {
const cb = (rawResp: any) => { const rawResp = await createReserve({
if (!rawResp) { amount,
throw Error("empty response"); exchange: canonicalizeBaseUrl(exchange),
senderWire: sender_wire,
});
if (!rawResp) {
throw Error("empty response");
}
// FIXME: filter out types that bank/exchange don't have in common
const wireDetails = rci.wireInfo;
const filteredWireDetails: any = {};
for (const wireType in wireDetails) {
if (this.props.wt_types.findIndex((x) => x.toLowerCase() === wireType.toLowerCase()) < 0) {
continue;
} }
// FIXME: filter out types that bank/exchange don't have in common const obj = Object.assign({}, wireDetails[wireType]);
const wireDetails = rci.wireInfo; // The bank doesn't need to know about fees
const filteredWireDetails: any = {}; delete obj.fees;
for (const wireType in wireDetails) { // Consequently the bank can't verify signatures anyway, so
if (this.props.wt_types.findIndex((x) => x.toLowerCase() === wireType.toLowerCase()) < 0) { // we delete this extra data, to make the request URL shorter.
continue; delete obj.salt;
} delete obj.sig;
const obj = Object.assign({}, wireDetails[wireType]); filteredWireDetails[wireType] = obj;
// The bank doesn't need to know about fees }
delete obj.fees; if (!rawResp.error) {
// Consequently the bank can't verify signatures anyway, so const resp = CreateReserveResponse.checked(rawResp);
// we delete this extra data, to make the request URL shorter. const q: {[name: string]: string|number} = {
delete obj.salt; amount_currency: amount.currency,
delete obj.sig; amount_fraction: amount.fraction,
filteredWireDetails[wireType] = obj; amount_value: amount.value,
exchange: resp.exchange,
reserve_pub: resp.reservePub,
wire_details: JSON.stringify(filteredWireDetails),
};
const url = new URI(callback_url).addQuery(q);
if (!url.is("absolute")) {
throw Error("callback url is not absolute");
} }
if (!rawResp.error) { console.log("going to", url.href());
const resp = CreateReserveResponse.checked(rawResp); document.location.href = url.href();
const q: {[name: string]: string|number} = { } else {
amount_currency: amount.currency, this.statusString(
amount_fraction: amount.fraction, i18n.str`Oops, something went wrong. The wallet responded with error status (${rawResp.error}).`);
amount_value: amount.value, }
exchange: resp.exchange,
reserve_pub: resp.reservePub,
wire_details: JSON.stringify(filteredWireDetails),
};
const url = new URI(callback_url).addQuery(q);
if (!url.is("absolute")) {
throw Error("callback url is not absolute");
}
console.log("going to", url.href());
document.location.href = url.href();
} else {
this.statusString(
i18n.str`Oops, something went wrong. The wallet responded with error status (${rawResp.error}).`);
}
};
chrome.runtime.sendMessage({type: "create-reserve", detail: d}, cb);
} }
renderStatus(): any { renderStatus(): any {
@ -632,6 +637,11 @@ async function main() {
throw Error(i18n.str`Can't parse wire_types: ${e.message}`); throw Error(i18n.str`Can't parse wire_types: ${e.message}`);
} }
let sender_wire;
if (query.sender_wire) {
sender_wire = JSON.parse(query.sender_wire);
}
const suggestedExchangeUrl = query.suggested_exchange_url; const suggestedExchangeUrl = query.suggested_exchange_url;
const currencyRecord = await getCurrency(amount.currency); const currencyRecord = await getCurrency(amount.currency);
@ -641,6 +651,7 @@ async function main() {
currencyRecord, currencyRecord,
suggestedExchangeUrl, suggestedExchangeUrl,
wt_types, wt_types,
sender_wire,
}; };
ReactDOM.render(<ExchangeSelection {...args} />, document.getElementById( ReactDOM.render(<ExchangeSelection {...args} />, document.getElementById(

View File

@ -264,7 +264,7 @@ export function paymentFailed(contractTermsHash: string): Promise<void> {
* Get the payment cookie for the current tab, or undefined if no payment * Get the payment cookie for the current tab, or undefined if no payment
* cookie was set. * cookie was set.
*/ */
export function getTabCookie(contractTermsHash: string, merchantSig: string): Promise<any> { export function getTabCookie(): Promise<any> {
return callBackend("get-tab-cookie", { }); return callBackend("get-tab-cookie", { });
} }
@ -283,6 +283,13 @@ export function checkUpgrade(): Promise<UpgradeResponse> {
return callBackend("check-upgrade", { }); return callBackend("check-upgrade", { });
} }
/**
* Create a reserve.
*/
export function createReserve(args: { amount: AmountJson, exchange: string, senderWire?: object }): Promise<any> {
return callBackend("create-reserve", args);
}
/** /**
* Reset database * Reset database
*/ */

View File

@ -114,6 +114,7 @@ function handleMessage(sender: MessageSender,
const d = { const d = {
amount: detail.amount, amount: detail.amount,
exchange: detail.exchange, exchange: detail.exchange,
senderWire: detail.senderWire,
}; };
const req = CreateReserveRequest.checked(d); const req = CreateReserveRequest.checked(d);
return needsWallet().createReserve(req); return needsWallet().createReserve(req);
@ -414,15 +415,29 @@ function handleBankRequest(wallet: Wallet, headerList: chrome.webRequest.HttpHea
} }
} }
const reservePub = headers["x-taler-reserve-pub"]; const operation = headers["x-taler-operation"];
if (reservePub !== undefined) {
console.log(`confirming reserve ${reservePub} via 201`); if (!operation) {
wallet.confirmReserve({reservePub}); // Not a taler related request.
return; return;
} }
const amount = headers["x-taler-amount"]; if (operation == "confirm-reserve") {
if (amount) { const reservePub = headers["x-taler-reserve-pub"];
if (reservePub !== undefined) {
console.log(`confirming reserve ${reservePub} via 201`);
wallet.confirmReserve({reservePub});
}
console.warn("got 'X-Taler-Operation: confirm-reserve' without 'X-Taler-Reserve-Pub'");
return;
}
if (operation == "create-reserve") {
const amount = headers["x-taler-amount"];
if (!amount) {
console.log("202 not understood (X-Taler-Amount missing)");
return;
}
const callbackUrl = headers["x-taler-callback-url"]; const callbackUrl = headers["x-taler-callback-url"];
if (!callbackUrl) { if (!callbackUrl) {
console.log("202 not understood (X-Taler-Callback-Url missing)"); console.log("202 not understood (X-Taler-Callback-Url missing)");
@ -452,6 +467,7 @@ function handleBankRequest(wallet: Wallet, headerList: chrome.webRequest.HttpHea
callback_url: new URI(callbackUrl) .absoluteTo(url), callback_url: new URI(callbackUrl) .absoluteTo(url),
suggested_exchange_url: headers["x-taler-suggested-exchange"], suggested_exchange_url: headers["x-taler-suggested-exchange"],
wt_types: wtTypes, wt_types: wtTypes,
sender_wire: headers["x-taler-sender-wire"],
}; };
const uri = new URI(chrome.extension.getURL("/src/webex/pages/confirm-create-reserve.html")); const uri = new URI(chrome.extension.getURL("/src/webex/pages/confirm-create-reserve.html"));
const redirectUrl = uri.query(params).href(); const redirectUrl = uri.query(params).href();
@ -460,7 +476,8 @@ function handleBankRequest(wallet: Wallet, headerList: chrome.webRequest.HttpHea
chrome.tabs.update(tabId, {url: redirectUrl}); chrome.tabs.update(tabId, {url: redirectUrl});
return; return;
} }
// no known headers found, not a taler request ...
console.log("Ignoring unknown X-Taler-Operation:", operation);
} }