support claim tokens

This commit is contained in:
Florian Dold 2020-07-30 17:28:09 +05:30
parent 78718d3534
commit b51932cc85
No known key found for this signature in database
GPG Key ID: D2E4F00F29D02A4B
5 changed files with 34 additions and 8 deletions

View File

@ -603,11 +603,17 @@ async function processDownloadProposalImpl(
).href; ).href;
logger.trace("downloading contract from '" + orderClaimUrl + "'"); logger.trace("downloading contract from '" + orderClaimUrl + "'");
const reqestBody = { const requestBody: {
nonce: string,
token?: string;
} = {
nonce: proposal.noncePub, nonce: proposal.noncePub,
}; };
if (proposal.claimToken) {
requestBody.token = proposal.claimToken;
}
const resp = await ws.http.postJson(orderClaimUrl, reqestBody); const resp = await ws.http.postJson(orderClaimUrl, requestBody);
const proposalResp = await readSuccessResponseJsonOrThrow( const proposalResp = await readSuccessResponseJsonOrThrow(
resp, resp,
codecForProposal(), codecForProposal(),
@ -715,6 +721,7 @@ async function startDownloadProposal(
merchantBaseUrl: string, merchantBaseUrl: string,
orderId: string, orderId: string,
sessionId: string | undefined, sessionId: string | undefined,
claimToken: string | undefined,
): Promise<string> { ): Promise<string> {
const oldProposal = await ws.db.getIndexed( const oldProposal = await ws.db.getIndexed(
Stores.proposals.urlAndOrderIdIndex, Stores.proposals.urlAndOrderIdIndex,
@ -732,6 +739,7 @@ async function startDownloadProposal(
download: undefined, download: undefined,
noncePriv: priv, noncePriv: priv,
noncePub: pub, noncePub: pub,
claimToken,
timestamp: getTimestampNow(), timestamp: getTimestampNow(),
merchantBaseUrl, merchantBaseUrl,
orderId, orderId,
@ -865,7 +873,7 @@ export async function preparePayForUri(
`invalid taler://pay URI (${talerPayUri})`, `invalid taler://pay URI (${talerPayUri})`,
{ {
talerPayUri, talerPayUri,
} },
); );
} }
@ -874,6 +882,7 @@ export async function preparePayForUri(
uriResult.merchantBaseUrl, uriResult.merchantBaseUrl,
uriResult.orderId, uriResult.orderId,
uriResult.sessionId, uriResult.sessionId,
uriResult.claimToken,
); );
let proposal = await ws.db.get(Stores.proposals, proposalId); let proposal = await ws.db.get(Stores.proposals, proposalId);
@ -912,7 +921,7 @@ export async function preparePayForUri(
const res = await getCoinsForPayment(ws, contractData); const res = await getCoinsForPayment(ws, contractData);
if (!res) { if (!res) {
console.log("not confirming payment, insufficient coins"); logger.info("not confirming payment, insufficient coins");
return { return {
status: PreparePayResultType.InsufficientBalance, status: PreparePayResultType.InsufficientBalance,
contractTerms: d.contractTermsRaw, contractTerms: d.contractTermsRaw,
@ -957,7 +966,7 @@ export async function preparePayForUri(
status: PreparePayResultType.AlreadyConfirmed, status: PreparePayResultType.AlreadyConfirmed,
contractTerms: purchase.contractTermsRaw, contractTerms: purchase.contractTermsRaw,
paid: false, paid: false,
}; };
} else if (purchase.paymentSubmitPending) { } else if (purchase.paymentSubmitPending) {
return { return {
status: PreparePayResultType.AlreadyConfirmed, status: PreparePayResultType.AlreadyConfirmed,
@ -1020,7 +1029,7 @@ export async function confirmPay(
if (!res) { if (!res) {
// Should not happen, since checkPay should be called first // Should not happen, since checkPay should be called first
console.log("not confirming payment, insufficient coins"); logger.warn("not confirming payment, insufficient coins");
throw Error("insufficient balance"); throw Error("insufficient balance");
} }

View File

@ -873,6 +873,8 @@ export interface ProposalRecord {
*/ */
noncePub: string; noncePub: string;
claimToken: string | undefined;
proposalStatus: ProposalStatus; proposalStatus: ProposalStatus;
repurchaseProposalId: string | undefined; repurchaseProposalId: string | undefined;

View File

@ -63,6 +63,17 @@ test("taler pay url parsing: instance", (t) => {
t.is(r1.orderId, "myorder"); t.is(r1.orderId, "myorder");
}); });
test("taler pay url parsing (claim token)", (t) => {
const url1 = "taler://pay/example.com/instances/myinst/myorder/?c=ASDF";
const r1 = parsePayUri(url1);
if (!r1) {
t.fail();
return;
}
t.is(r1.merchantBaseUrl, "https://example.com/instances/myinst/");
t.is(r1.orderId, "myorder");
t.is(r1.claimToken, "ASDF");
});
test("taler refund uri parsing: non-https #1", (t) => { test("taler refund uri parsing: non-https #1", (t) => {
const url1 = "taler+http://refund/example.com/myorder"; const url1 = "taler+http://refund/example.com/myorder";

View File

@ -18,6 +18,7 @@ export interface PayUriResult {
merchantBaseUrl: string; merchantBaseUrl: string;
orderId: string; orderId: string;
sessionId: string; sessionId: string;
claimToken: string | undefined;
} }
export interface WithdrawUriResult { export interface WithdrawUriResult {
@ -136,6 +137,8 @@ export function parsePayUri(s: string): PayUriResult | undefined {
return undefined; return undefined;
} }
const c = pi?.rest.split("?"); const c = pi?.rest.split("?");
const q = new URLSearchParams(c[1] ?? "");
const claimToken = q.get("c") ?? undefined;
const parts = c[0].split("/"); const parts = c[0].split("/");
if (parts.length < 3) { if (parts.length < 3) {
return undefined; return undefined;
@ -151,6 +154,7 @@ export function parsePayUri(s: string): PayUriResult | undefined {
merchantBaseUrl, merchantBaseUrl,
orderId, orderId,
sessionId: sessionId, sessionId: sessionId,
claimToken,
}; };
} }

View File

@ -7,5 +7,5 @@ def test_payments(exchange, bank, merchant, wallet):
pay_uri = merchant.gen_pay_uri("TESTKUDOS:2") pay_uri = merchant.gen_pay_uri("TESTKUDOS:2")
# TODO fix # TODO fix
# result = wallet.cmd("preparePay", {"talerPayUri": pay_uri}) result = wallet.cmd("preparePay", {"talerPayUri": pay_uri})
# print_json(result) print_json(result)