aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorFlorian Dold <florian.dold@gmail.com>2018-01-18 01:37:30 +0100
committerFlorian Dold <florian.dold@gmail.com>2018-01-18 01:37:30 +0100
commit82d9c2a7cd2e343866997438d44aa5422190a028 (patch)
tree3feef2e8b7db1680e42818419195c95946751783 /src
parentd4c2f6f6f992c36609c4a029afcb378a7f839ddf (diff)
access refunds correctly
Diffstat (limited to 'src')
-rw-r--r--src/dbTypes.ts3
-rw-r--r--src/i18n/de.po8
-rw-r--r--src/i18n/en-US.po8
-rw-r--r--src/i18n/fr.po8
-rw-r--r--src/i18n/it.po8
-rw-r--r--src/i18n/taler-wallet-webex.pot8
-rw-r--r--src/query.ts1
-rw-r--r--src/wallet.ts40
-rw-r--r--src/webex/pages/confirm-contract.tsx17
-rw-r--r--src/webex/wxApi.ts2
-rw-r--r--src/webex/wxBackend.ts6
11 files changed, 76 insertions, 33 deletions
diff --git a/src/dbTypes.ts b/src/dbTypes.ts
index 86f3e0a1e..9e9663219 100644
--- a/src/dbTypes.ts
+++ b/src/dbTypes.ts
@@ -782,6 +782,8 @@ export interface PurchaseRecord {
* Set to 0 if no refund was made on the purchase.
*/
timestamp_refund: number;
+
+ lastSessionSig: string | undefined;
}
@@ -889,6 +891,7 @@ export namespace Stores {
keyPath: "id",
});
}
+ urlIndex = new Index<string, ProposalDownloadRecord>(this, "urlIndex", "url");
timestampIndex = new Index<string, ProposalDownloadRecord>(this, "timestampIndex", "timestamp");
}
diff --git a/src/i18n/de.po b/src/i18n/de.po
index 5f163a0d3..1f6e98962 100644
--- a/src/i18n/de.po
+++ b/src/i18n/de.po
@@ -42,13 +42,13 @@ msgstr ""
msgid "Exchanges in the wallet:"
msgstr ""
-#: src/webex/pages/confirm-contract.tsx:175
+#: src/webex/pages/confirm-contract.tsx:188
#, c-format
msgid "You have insufficient funds of the requested currency in your wallet."
msgstr ""
#. tslint:disable-next-line:max-line-length
-#: src/webex/pages/confirm-contract.tsx:177
+#: src/webex/pages/confirm-contract.tsx:190
#, c-format
msgid ""
"You do not have any funds from an exchange that is accepted by this "
@@ -56,12 +56,12 @@ msgid ""
"wallet."
msgstr ""
-#: src/webex/pages/confirm-contract.tsx:236
+#: src/webex/pages/confirm-contract.tsx:249
#, c-format
msgid "The merchant%1$s offers you to purchase:\n"
msgstr ""
-#: src/webex/pages/confirm-contract.tsx:257
+#: src/webex/pages/confirm-contract.tsx:270
#, fuzzy, c-format
msgid "Confirm payment"
msgstr "Bezahlung bestätigen"
diff --git a/src/i18n/en-US.po b/src/i18n/en-US.po
index 0dfa852ca..3e47e952a 100644
--- a/src/i18n/en-US.po
+++ b/src/i18n/en-US.po
@@ -42,13 +42,13 @@ msgstr ""
msgid "Exchanges in the wallet:"
msgstr ""
-#: src/webex/pages/confirm-contract.tsx:175
+#: src/webex/pages/confirm-contract.tsx:188
#, c-format
msgid "You have insufficient funds of the requested currency in your wallet."
msgstr ""
#. tslint:disable-next-line:max-line-length
-#: src/webex/pages/confirm-contract.tsx:177
+#: src/webex/pages/confirm-contract.tsx:190
#, c-format
msgid ""
"You do not have any funds from an exchange that is accepted by this "
@@ -56,12 +56,12 @@ msgid ""
"wallet."
msgstr ""
-#: src/webex/pages/confirm-contract.tsx:236
+#: src/webex/pages/confirm-contract.tsx:249
#, c-format
msgid "The merchant%1$s offers you to purchase:\n"
msgstr ""
-#: src/webex/pages/confirm-contract.tsx:257
+#: src/webex/pages/confirm-contract.tsx:270
#, c-format
msgid "Confirm payment"
msgstr ""
diff --git a/src/i18n/fr.po b/src/i18n/fr.po
index 55677763b..97ff47067 100644
--- a/src/i18n/fr.po
+++ b/src/i18n/fr.po
@@ -42,13 +42,13 @@ msgstr ""
msgid "Exchanges in the wallet:"
msgstr ""
-#: src/webex/pages/confirm-contract.tsx:175
+#: src/webex/pages/confirm-contract.tsx:188
#, c-format
msgid "You have insufficient funds of the requested currency in your wallet."
msgstr ""
#. tslint:disable-next-line:max-line-length
-#: src/webex/pages/confirm-contract.tsx:177
+#: src/webex/pages/confirm-contract.tsx:190
#, c-format
msgid ""
"You do not have any funds from an exchange that is accepted by this "
@@ -56,12 +56,12 @@ msgid ""
"wallet."
msgstr ""
-#: src/webex/pages/confirm-contract.tsx:236
+#: src/webex/pages/confirm-contract.tsx:249
#, c-format
msgid "The merchant%1$s offers you to purchase:\n"
msgstr ""
-#: src/webex/pages/confirm-contract.tsx:257
+#: src/webex/pages/confirm-contract.tsx:270
#, c-format
msgid "Confirm payment"
msgstr ""
diff --git a/src/i18n/it.po b/src/i18n/it.po
index 55677763b..97ff47067 100644
--- a/src/i18n/it.po
+++ b/src/i18n/it.po
@@ -42,13 +42,13 @@ msgstr ""
msgid "Exchanges in the wallet:"
msgstr ""
-#: src/webex/pages/confirm-contract.tsx:175
+#: src/webex/pages/confirm-contract.tsx:188
#, c-format
msgid "You have insufficient funds of the requested currency in your wallet."
msgstr ""
#. tslint:disable-next-line:max-line-length
-#: src/webex/pages/confirm-contract.tsx:177
+#: src/webex/pages/confirm-contract.tsx:190
#, c-format
msgid ""
"You do not have any funds from an exchange that is accepted by this "
@@ -56,12 +56,12 @@ msgid ""
"wallet."
msgstr ""
-#: src/webex/pages/confirm-contract.tsx:236
+#: src/webex/pages/confirm-contract.tsx:249
#, c-format
msgid "The merchant%1$s offers you to purchase:\n"
msgstr ""
-#: src/webex/pages/confirm-contract.tsx:257
+#: src/webex/pages/confirm-contract.tsx:270
#, c-format
msgid "Confirm payment"
msgstr ""
diff --git a/src/i18n/taler-wallet-webex.pot b/src/i18n/taler-wallet-webex.pot
index 55677763b..97ff47067 100644
--- a/src/i18n/taler-wallet-webex.pot
+++ b/src/i18n/taler-wallet-webex.pot
@@ -42,13 +42,13 @@ msgstr ""
msgid "Exchanges in the wallet:"
msgstr ""
-#: src/webex/pages/confirm-contract.tsx:175
+#: src/webex/pages/confirm-contract.tsx:188
#, c-format
msgid "You have insufficient funds of the requested currency in your wallet."
msgstr ""
#. tslint:disable-next-line:max-line-length
-#: src/webex/pages/confirm-contract.tsx:177
+#: src/webex/pages/confirm-contract.tsx:190
#, c-format
msgid ""
"You do not have any funds from an exchange that is accepted by this "
@@ -56,12 +56,12 @@ msgid ""
"wallet."
msgstr ""
-#: src/webex/pages/confirm-contract.tsx:236
+#: src/webex/pages/confirm-contract.tsx:249
#, c-format
msgid "The merchant%1$s offers you to purchase:\n"
msgstr ""
-#: src/webex/pages/confirm-contract.tsx:257
+#: src/webex/pages/confirm-contract.tsx:270
#, c-format
msgid "Confirm payment"
msgstr ""
diff --git a/src/query.ts b/src/query.ts
index e45596c66..290d02a2a 100644
--- a/src/query.ts
+++ b/src/query.ts
@@ -685,6 +685,7 @@ export class QueryRoot {
put<T>(store: Store<T>, val: T, keyName?: string): QueryRoot {
this.checkFinished();
const doPut = (tx: IDBTransaction) => {
+ console.log("put into", store.name, "value", val);
const req = tx.objectStore(store.name).put(val);
if (keyName) {
req.onsuccess = () => {
diff --git a/src/wallet.ts b/src/wallet.ts
index 91da5873b..aa974369a 100644
--- a/src/wallet.ts
+++ b/src/wallet.ts
@@ -312,6 +312,7 @@ export class Wallet {
private processPreCoinThrottle: {[url: string]: number} = {};
private timerGroup: TimerGroup;
private speculativePayData: SpeculativePayData | undefined;
+ private cachedNextUrl: { [fulfillmentUrl: string]: string } = {};
/**
* Set of identifiers for running operations.
@@ -650,6 +651,7 @@ export class Wallet {
contractTerms: proposal.contractTerms,
contractTermsHash: proposal.contractTermsHash,
finished: false,
+ lastSessionSig: undefined,
merchantSig: proposal.merchantSig,
payReq,
refundsDone: {},
@@ -673,13 +675,19 @@ export class Wallet {
* Returns an id for it to retrieve it later.
*/
async downloadProposal(url: string): Promise<number> {
+
+ const oldProposal = await this.q().getIndexed(Stores.proposals.urlIndex, url);
+ if (oldProposal) {
+ return oldProposal.id!;
+ }
+
const { priv, pub } = await this.cryptoApi.createEddsaKeypair();
const parsed_url = new URI(url);
- url = parsed_url.setQuery({ nonce: pub }).href();
- console.log("downloading contract from '" + url + "'");
+ const urlWithNonce = parsed_url.setQuery({ nonce: pub }).href();
+ console.log("downloading contract from '" + urlWithNonce + "'");
let resp;
try {
- resp = await axios.get(url, { validateStatus: (s) => s === 200 });
+ resp = await axios.get(urlWithNonce, { validateStatus: (s) => s === 200 });
} catch (e) {
console.log("contract download failed", e);
throw e;
@@ -707,7 +715,7 @@ export class Wallet {
return id;
}
- async submitPay(purchase: PurchaseRecord, sessionId: string | undefined): Promise<ConfirmPayResult> {
+ private async submitPay(purchase: PurchaseRecord, sessionId: string | undefined): Promise<ConfirmPayResult> {
let resp;
const payReq = { ...purchase.payReq, session_id: sessionId };
try {
@@ -724,13 +732,17 @@ export class Wallet {
}
const merchantResp = resp.data;
console.log("got success from pay_url");
- await this.paymentSucceeded(purchase.contractTermsHash, merchantResp.sig);
const fu = new URI(purchase.contractTerms.fulfillment_url);
fu.addSearch("order_id", purchase.contractTerms.order_id);
if (merchantResp.session_sig) {
fu.addSearch("session_sig", merchantResp.session_sig);
+ purchase.lastSessionSig = merchantResp.session_sig;
+ console.log("updating session sig", purchase);
+ await this.q().put(Stores.purchases, purchase).finish();
}
+ await this.paymentSucceeded(purchase.contractTermsHash, merchantResp.sig);
const nextUrl = fu.href();
+ this.cachedNextUrl[purchase.contractTerms.fulfillment_url] = nextUrl;
return { nextUrl };
}
@@ -887,6 +899,7 @@ export class Wallet {
contractTerms: t.contractTerms,
contractTermsHash: t.contractTermsHash,
found: true,
+ lastSessionSig: t.lastSessionSig,
payReq: t.payReq,
};
}
@@ -911,6 +924,7 @@ export class Wallet {
contractTerms: t.contractTerms,
contractTermsHash: t.contractTermsHash,
found: true,
+ lastSessionSig: t.lastSessionSig,
payReq: t.payReq,
};
}
@@ -1075,7 +1089,7 @@ export class Wallet {
id: hash(senderWire),
senderWire,
};
- await this.q().put(Stores.senderWires, rec);
+ await this.q().put(Stores.senderWires, rec).finish();
}
await this.updateExchangeUsedTime(req.exchange);
@@ -2259,10 +2273,10 @@ export class Wallet {
}
- async paymentSucceeded(contractTermsHash: string, merchantSig: string): Promise<any> {
+ private async paymentSucceeded(contractTermsHash: string, merchantSig: string): Promise<any> {
const doPaymentSucceeded = async() => {
const t = await this.q().get<PurchaseRecord>(Stores.purchases,
- contractTermsHash);
+ contractTermsHash);
if (!t) {
console.error("contract not found");
return;
@@ -2560,7 +2574,7 @@ export class Wallet {
}
// FIXME: validate schema
- const refundPermissions = resp.data;
+ const refundPermissions = resp.data.refund_permissions;
if (!refundPermissions.length) {
console.warn("got empty refund list");
@@ -2871,8 +2885,14 @@ export class Wallet {
}
+ /**
+ * Synchronously get the paid URL for a resource from the plain fulfillment
+ * URL. Returns undefined if the fulfillment URL is not a resource that was
+ * payed for, or if it is not cached anymore. Use the asynchronous
+ * queryPaymentByFulfillmentUrl to avoid false negatives.
+ */
getNextUrlFromResourceUrl(resourceUrl: string): string | undefined {
- return;
+ return this.cachedNextUrl[resourceUrl];
}
/**
diff --git a/src/webex/pages/confirm-contract.tsx b/src/webex/pages/confirm-contract.tsx
index 090737475..c302239c6 100644
--- a/src/webex/pages/confirm-contract.tsx
+++ b/src/webex/pages/confirm-contract.tsx
@@ -105,6 +105,7 @@ interface ContractPromptProps {
proposalId?: number;
contractUrl?: string;
sessionId?: string;
+ resourceUrl?: string;
}
interface ContractPromptState {
@@ -146,6 +147,18 @@ class ContractPrompt extends React.Component<ContractPromptProps, ContractPrompt
}
async update() {
+ if (this.props.resourceUrl) {
+ const p = await wxApi.queryPaymentByFulfillmentUrl(this.props.resourceUrl);
+ console.log("query for resource url", this.props.resourceUrl, "result", p);
+ if (p.found) {
+ const nextUrl = new URI(p.contractTerms.fulfillment_url);
+ nextUrl.addSearch("order_id", p.contractTerms.order_id);
+ if (p.lastSessionSig) {
+ nextUrl.addSearch("session_sig", p.lastSessionSig);
+ }
+ location.href = nextUrl.href();
+ }
+ }
let proposalId = this.props.proposalId;
if (proposalId === undefined) {
if (this.props.contractUrl === undefined) {
@@ -285,7 +298,9 @@ document.addEventListener("DOMContentLoaded", () => {
const sessionId = query.sessionId;
const contractUrl = query.contractUrl;
+ const resourceUrl = query.resourceUrl;
+
ReactDOM.render(
- <ContractPrompt {...{ proposalId, contractUrl, sessionId }}/>,
+ <ContractPrompt {...{ proposalId, contractUrl, sessionId, resourceUrl }}/>,
document.getElementById("contract")!);
});
diff --git a/src/webex/wxApi.ts b/src/webex/wxApi.ts
index efebf21d1..84c44dbaa 100644
--- a/src/webex/wxApi.ts
+++ b/src/webex/wxApi.ts
@@ -238,7 +238,7 @@ export function confirmReserve(reservePub: string): Promise<void> {
/**
* Query for a payment by fulfillment URL.
*/
-export function queryPayment(url: string): Promise<QueryPaymentResult> {
+export function queryPaymentByFulfillmentUrl(url: string): Promise<QueryPaymentResult> {
return callBackend("query-payment", { url });
}
diff --git a/src/webex/wxBackend.ts b/src/webex/wxBackend.ts
index c0b42a768..7bbba1759 100644
--- a/src/webex/wxBackend.ts
+++ b/src/webex/wxBackend.ts
@@ -416,11 +416,12 @@ async function talerPay(fields: any, url: string, tabId: number): Promise<string
if (p.lastSessionSig) {
nextUrl.addSearch("session_sig", p.lastSessionSig);
}
- return url;
+ return nextUrl.href();
};
if (fields.resource_url) {
const p = await w.queryPaymentByFulfillmentUrl(fields.resource_url);
+ console.log("query for resource url", fields.resource_url, "result", p);
if (p.found) {
return goToPayment(p);
}
@@ -519,6 +520,9 @@ function handleHttpPayment(headerList: chrome.webRequest.HttpHeader[], url: stri
if (fields.session_id) {
uri.addSearch("sessionId", fields.session_id);
}
+ if (fields.resource_url) {
+ uri.addSearch("resourceUrl", fields.resource_url);
+ }
return { redirectUrl: uri.href() };
}