fix bug #5373: only allow existing payment redirection for contracts from the same merchant
This commit is contained in:
parent
9297bbc825
commit
f6c0108511
@ -733,10 +733,9 @@ export class Wallet {
|
|||||||
return fu.href();
|
return fu.href();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if a payment for the given taler://pay/ URI is possible.
|
* Check if a payment for the given taler://pay/ URI is possible.
|
||||||
*
|
*
|
||||||
* If the payment is possible, the signature are already generated but not
|
* If the payment is possible, the signature are already generated but not
|
||||||
* yet send to the merchant.
|
* yet send to the merchant.
|
||||||
*/
|
*/
|
||||||
@ -769,6 +768,31 @@ export class Wallet {
|
|||||||
|
|
||||||
console.log("proposal", proposal);
|
console.log("proposal", proposal);
|
||||||
|
|
||||||
|
const differentPurchase = await this.q().getIndexed(
|
||||||
|
Stores.purchases.fulfillmentUrlIndex,
|
||||||
|
proposal.contractTerms.fulfillment_url,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (differentPurchase) {
|
||||||
|
// We do this check to prevent merchant B to find out if we bought a
|
||||||
|
// digital product with merchant A by abusing the existing payment
|
||||||
|
// redirect feature.
|
||||||
|
if (
|
||||||
|
differentPurchase.contractTerms.merchant_pub !=
|
||||||
|
proposal.contractTerms.merchant_pub
|
||||||
|
) {
|
||||||
|
console.warn(
|
||||||
|
"merchant with different public key offered contract with same fulfillment URL as an existing purchase",
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return {
|
||||||
|
status: "paid",
|
||||||
|
contractTerms: differentPurchase.contractTerms,
|
||||||
|
nextUrl: this.getNextUrl(differentPurchase.contractTerms),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// First check if we already payed for it.
|
// First check if we already payed for it.
|
||||||
const purchase = await this.q().get(
|
const purchase = await this.q().get(
|
||||||
Stores.purchases,
|
Stores.purchases,
|
||||||
@ -779,7 +803,9 @@ export class Wallet {
|
|||||||
const paymentAmount = Amounts.parseOrThrow(proposal.contractTerms.amount);
|
const paymentAmount = Amounts.parseOrThrow(proposal.contractTerms.amount);
|
||||||
let wireFeeLimit;
|
let wireFeeLimit;
|
||||||
if (proposal.contractTerms.max_wire_fee) {
|
if (proposal.contractTerms.max_wire_fee) {
|
||||||
wireFeeLimit = Amounts.parseOrThrow(proposal.contractTerms.max_wire_fee);
|
wireFeeLimit = Amounts.parseOrThrow(
|
||||||
|
proposal.contractTerms.max_wire_fee,
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
wireFeeLimit = Amounts.getZero(paymentAmount.currency);
|
wireFeeLimit = Amounts.getZero(paymentAmount.currency);
|
||||||
}
|
}
|
||||||
@ -835,16 +861,12 @@ export class Wallet {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (uriResult.sessionId) {
|
if (uriResult.sessionId) {
|
||||||
await this.submitPay(
|
await this.submitPay(purchase.contractTermsHash, uriResult.sessionId);
|
||||||
purchase.contractTermsHash,
|
|
||||||
uriResult.sessionId,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
status: "paid",
|
status: "paid",
|
||||||
contractTerms: proposal.contractTerms,
|
contractTerms: proposal.contractTerms,
|
||||||
proposalId: proposal.id!,
|
|
||||||
nextUrl: this.getNextUrl(purchase.contractTerms),
|
nextUrl: this.getNextUrl(purchase.contractTerms),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -1126,7 +1148,6 @@ export class Wallet {
|
|||||||
return sp;
|
return sp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private async sendReserveInfoToBank(reservePub: string) {
|
private async sendReserveInfoToBank(reservePub: string) {
|
||||||
const reserve = await this.q().get<ReserveRecord>(
|
const reserve = await this.q().get<ReserveRecord>(
|
||||||
Stores.reserves,
|
Stores.reserves,
|
||||||
|
@ -471,9 +471,9 @@ export interface PreparePayResultError {
|
|||||||
error: string;
|
error: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export interface PreparePayResultPaid {
|
export interface PreparePayResultPaid {
|
||||||
status: "paid";
|
status: "paid";
|
||||||
proposalId: number;
|
|
||||||
contractTerms: ContractTerms;
|
contractTerms: ContractTerms;
|
||||||
nextUrl: string;
|
nextUrl: string;
|
||||||
}
|
}
|
||||||
|
@ -92,10 +92,14 @@ function TalerPayDialog({ talerPayUri }: { talerPayUri: string }) {
|
|||||||
);
|
);
|
||||||
|
|
||||||
const doPayment = async () => {
|
const doPayment = async () => {
|
||||||
|
if (payStatus.status !== "payment-possible") {
|
||||||
|
throw Error("invalid state");
|
||||||
|
}
|
||||||
|
const proposalId = payStatus.proposalId;
|
||||||
setNumTries(numTries + 1);
|
setNumTries(numTries + 1);
|
||||||
try {
|
try {
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
const res = await wxApi.confirmPay(payStatus!.proposalId!, undefined);
|
const res = await wxApi.confirmPay(proposalId, undefined);
|
||||||
document.location.href = res.nextUrl;
|
document.location.href = res.nextUrl;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(e);
|
console.error(e);
|
||||||
|
Loading…
Reference in New Issue
Block a user