repurchase detection
This commit is contained in:
parent
718f81bcd8
commit
5591077fe9
@ -65,12 +65,36 @@ var TalerNotify;
|
|||||||
document.addEventListener("taler-contract", function (e) {
|
document.addEventListener("taler-contract", function (e) {
|
||||||
// XXX: the merchant should just give us the parsed data ...
|
// XXX: the merchant should just give us the parsed data ...
|
||||||
var offer = JSON.parse(e.detail);
|
var offer = JSON.parse(e.detail);
|
||||||
|
if (!offer.contract) {
|
||||||
|
console.error("contract field missing");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var msg = {
|
||||||
|
type: "check-repurchase",
|
||||||
|
detail: {
|
||||||
|
contract: offer.contract
|
||||||
|
},
|
||||||
|
};
|
||||||
|
chrome.runtime.sendMessage(msg, function (resp) {
|
||||||
|
if (resp.error) {
|
||||||
|
console.error("wallet backend error", resp);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (resp.isRepurchase) {
|
||||||
|
console.log("doing repurchase");
|
||||||
|
console.assert(resp.existingFulfillmentUrl);
|
||||||
|
console.assert(resp.existingContractHash);
|
||||||
|
window.location.href = subst(resp.existingFulfillmentUrl, resp.existingContractHash);
|
||||||
|
}
|
||||||
|
else {
|
||||||
var uri = URI(chrome.extension.getURL("pages/confirm-contract.html"));
|
var uri = URI(chrome.extension.getURL("pages/confirm-contract.html"));
|
||||||
var params = {
|
var params = {
|
||||||
offer: JSON.stringify(offer),
|
offer: JSON.stringify(offer),
|
||||||
merchantPageUrl: document.location.href,
|
merchantPageUrl: document.location.href,
|
||||||
};
|
};
|
||||||
document.location.href = uri.query(params).href();
|
document.location.href = uri.query(params).href();
|
||||||
|
}
|
||||||
|
});
|
||||||
});
|
});
|
||||||
document.addEventListener('taler-execute-payment', function (e) {
|
document.addEventListener('taler-execute-payment', function (e) {
|
||||||
console.log("got taler-execute-payment in content page");
|
console.log("got taler-execute-payment in content page");
|
||||||
|
@ -77,12 +77,40 @@ namespace TalerNotify {
|
|||||||
document.addEventListener("taler-contract", function(e: CustomEvent) {
|
document.addEventListener("taler-contract", function(e: CustomEvent) {
|
||||||
// XXX: the merchant should just give us the parsed data ...
|
// XXX: the merchant should just give us the parsed data ...
|
||||||
let offer = JSON.parse(e.detail);
|
let offer = JSON.parse(e.detail);
|
||||||
|
|
||||||
|
if (!offer.contract) {
|
||||||
|
console.error("contract field missing");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let msg = {
|
||||||
|
type: "check-repurchase",
|
||||||
|
detail: {
|
||||||
|
contract: offer.contract
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
chrome.runtime.sendMessage(msg, (resp) => {
|
||||||
|
if (resp.error) {
|
||||||
|
console.error("wallet backend error", resp);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (resp.isRepurchase) {
|
||||||
|
console.log("doing repurchase");
|
||||||
|
console.assert(resp.existingFulfillmentUrl);
|
||||||
|
console.assert(resp.existingContractHash);
|
||||||
|
window.location.href = subst(resp.existingFulfillmentUrl,
|
||||||
|
resp.existingContractHash);
|
||||||
|
|
||||||
|
} else {
|
||||||
let uri = URI(chrome.extension.getURL("pages/confirm-contract.html"));
|
let uri = URI(chrome.extension.getURL("pages/confirm-contract.html"));
|
||||||
let params = {
|
let params = {
|
||||||
offer: JSON.stringify(offer),
|
offer: JSON.stringify(offer),
|
||||||
merchantPageUrl: document.location.href,
|
merchantPageUrl: document.location.href,
|
||||||
};
|
};
|
||||||
document.location.href = uri.query(params).href();
|
document.location.href = uri.query(params).href();
|
||||||
|
}
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
@ -51,10 +51,21 @@ export function openTalerDb(): Promise<IDBDatabase> {
|
|||||||
db.createObjectStore("denoms", {keyPath: "denomPub"});
|
db.createObjectStore("denoms", {keyPath: "denomPub"});
|
||||||
const coins = db.createObjectStore("coins", {keyPath: "coinPub"});
|
const coins = db.createObjectStore("coins", {keyPath: "coinPub"});
|
||||||
coins.createIndex("mintBaseUrl", "mintBaseUrl");
|
coins.createIndex("mintBaseUrl", "mintBaseUrl");
|
||||||
db.createObjectStore("transactions", {keyPath: "contractHash"});
|
const transactions = db.createObjectStore("transactions",
|
||||||
|
{keyPath: "contractHash"});
|
||||||
|
transactions.createIndex("repurchase",
|
||||||
|
[
|
||||||
|
"contract.merchant_pub",
|
||||||
|
"contract.repurchase_correlation_id"
|
||||||
|
]);
|
||||||
|
|
||||||
db.createObjectStore("precoins",
|
db.createObjectStore("precoins",
|
||||||
{keyPath: "coinPub", autoIncrement: true});
|
{keyPath: "coinPub", autoIncrement: true});
|
||||||
const history = db.createObjectStore("history", {keyPath: "id", autoIncrement: true});
|
const history = db.createObjectStore("history",
|
||||||
|
{
|
||||||
|
keyPath: "id",
|
||||||
|
autoIncrement: true
|
||||||
|
});
|
||||||
history.createIndex("timestamp", "timestamp");
|
history.createIndex("timestamp", "timestamp");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -287,6 +287,29 @@ class QueryRoot {
|
|||||||
.then(() => promise);
|
.then(() => promise);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get one object from a store by its key.
|
||||||
|
*/
|
||||||
|
getIndexed(storeName, indexName, key): Promise<any> {
|
||||||
|
if (key === void 0) {
|
||||||
|
throw Error("key must not be undefined");
|
||||||
|
}
|
||||||
|
|
||||||
|
const {resolve, promise} = openPromise();
|
||||||
|
|
||||||
|
const doGetIndexed = (tx) => {
|
||||||
|
const req = tx.objectStore(storeName).index(indexName).get(key);
|
||||||
|
req.onsuccess = (r) => {
|
||||||
|
resolve(req.result);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
this.addWork(doGetIndexed, storeName, false);
|
||||||
|
return Promise.resolve()
|
||||||
|
.then(() => this.finish())
|
||||||
|
.then(() => promise);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Finish the query, and start the query in the first place if necessary.
|
* Finish the query, and start the query in the first place if necessary.
|
||||||
*/
|
*/
|
||||||
|
@ -257,6 +257,13 @@ export namespace Amounts {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export interface CheckRepurchaseResult {
|
||||||
|
isRepurchase: boolean;
|
||||||
|
existingContractHash?: string;
|
||||||
|
existingFulfillmentUrl?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
export interface Notifier {
|
export interface Notifier {
|
||||||
notify();
|
notify();
|
||||||
}
|
}
|
@ -32,6 +32,7 @@ import {Reserve} from "./types";
|
|||||||
import {CryptoApi} from "./cryptoApi";
|
import {CryptoApi} from "./cryptoApi";
|
||||||
import {Coin} from "./types";
|
import {Coin} from "./types";
|
||||||
import {PayCoinInfo} from "./types";
|
import {PayCoinInfo} from "./types";
|
||||||
|
import {CheckRepurchaseResult} from "./types";
|
||||||
|
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
@ -279,8 +280,9 @@ interface CoinPaySig {
|
|||||||
|
|
||||||
interface Transaction {
|
interface Transaction {
|
||||||
contractHash: string;
|
contractHash: string;
|
||||||
contract: any;
|
contract: Contract;
|
||||||
payReq: any;
|
payReq: any;
|
||||||
|
merchantSig: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -512,6 +514,7 @@ export class Wallet {
|
|||||||
contractHash: offer.H_contract,
|
contractHash: offer.H_contract,
|
||||||
contract: offer.contract,
|
contract: offer.contract,
|
||||||
payReq: payReq,
|
payReq: payReq,
|
||||||
|
merchantSig: offer.merchant_sig,
|
||||||
};
|
};
|
||||||
|
|
||||||
console.log("pay request");
|
console.log("pay request");
|
||||||
@ -926,4 +929,29 @@ export class Wallet {
|
|||||||
.iter("history", {indexName: "timestamp"})
|
.iter("history", {indexName: "timestamp"})
|
||||||
.reduce(collect, [])
|
.reduce(collect, [])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
checkRepurchase(contract: Contract): Promise<CheckRepurchaseResult> {
|
||||||
|
if (!contract.repurchase_correlation_id) {
|
||||||
|
console.log("no repurchase: no correlation id");
|
||||||
|
return Promise.resolve({isRepurchase: false});
|
||||||
|
}
|
||||||
|
return Query(this.db)
|
||||||
|
.getIndexed("transactions",
|
||||||
|
"repurchase",
|
||||||
|
[contract.merchant_pub, contract.repurchase_correlation_id])
|
||||||
|
.then((result: Transaction) => {
|
||||||
|
console.log("db result", result);
|
||||||
|
let isRepurchase;
|
||||||
|
if (result) {
|
||||||
|
console.assert(result.contract.repurchase_correlation_id == contract.repurchase_correlation_id);
|
||||||
|
return {
|
||||||
|
isRepurchase: true,
|
||||||
|
existingContractHash: result.contractHash,
|
||||||
|
existingFulfillmentUrl: result.contract.fulfillment_url,
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
return {isRepurchase: false};
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
@ -22,6 +22,7 @@ import {Checkable} from "./checkable";
|
|||||||
import {AmountJson} from "./types";
|
import {AmountJson} from "./types";
|
||||||
import Port = chrome.runtime.Port;
|
import Port = chrome.runtime.Port;
|
||||||
import {Notifier} from "./types";
|
import {Notifier} from "./types";
|
||||||
|
import {Contract} from "./wallet";
|
||||||
|
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
@ -108,6 +109,10 @@ function makeHandlers(db: IDBDatabase,
|
|||||||
let amount = AmountJson.checked(detail.amount);
|
let amount = AmountJson.checked(detail.amount);
|
||||||
return wallet.getReserveCreationInfo(detail.baseUrl, amount);
|
return wallet.getReserveCreationInfo(detail.baseUrl, amount);
|
||||||
},
|
},
|
||||||
|
["check-repurchase"]: function(detail) {
|
||||||
|
let contract = Contract.checked(detail.contract);
|
||||||
|
return wallet.checkRepurchase(contract);
|
||||||
|
},
|
||||||
["get-history"]: function(detail) {
|
["get-history"]: function(detail) {
|
||||||
// TODO: limit history length
|
// TODO: limit history length
|
||||||
return wallet.getHistory();
|
return wallet.getHistory();
|
||||||
|
Loading…
Reference in New Issue
Block a user