diff options
author | Florian Dold <florian.dold@gmail.com> | 2018-01-18 01:37:30 +0100 |
---|---|---|
committer | Florian Dold <florian.dold@gmail.com> | 2018-01-18 01:37:30 +0100 |
commit | 82d9c2a7cd2e343866997438d44aa5422190a028 (patch) | |
tree | 3feef2e8b7db1680e42818419195c95946751783 | |
parent | d4c2f6f6f992c36609c4a029afcb378a7f839ddf (diff) | |
download | wallet-core-82d9c2a7cd2e343866997438d44aa5422190a028.tar.xz |
access refunds correctly
-rw-r--r-- | src/dbTypes.ts | 3 | ||||
-rw-r--r-- | src/i18n/de.po | 8 | ||||
-rw-r--r-- | src/i18n/en-US.po | 8 | ||||
-rw-r--r-- | src/i18n/fr.po | 8 | ||||
-rw-r--r-- | src/i18n/it.po | 8 | ||||
-rw-r--r-- | src/i18n/taler-wallet-webex.pot | 8 | ||||
-rw-r--r-- | src/query.ts | 1 | ||||
-rw-r--r-- | src/wallet.ts | 40 | ||||
-rw-r--r-- | src/webex/pages/confirm-contract.tsx | 17 | ||||
-rw-r--r-- | src/webex/wxApi.ts | 2 | ||||
-rw-r--r-- | src/webex/wxBackend.ts | 6 |
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() }; } |