save tos etag after forced refresh
This commit is contained in:
parent
a5f357f078
commit
984cbb7ab7
@ -731,14 +731,14 @@ export const codecForGetWithdrawalDetailsForAmountRequest =
|
|||||||
|
|
||||||
export interface AcceptExchangeTosRequest {
|
export interface AcceptExchangeTosRequest {
|
||||||
exchangeBaseUrl: string;
|
exchangeBaseUrl: string;
|
||||||
etag: string;
|
etag: string | undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const codecForAcceptExchangeTosRequest =
|
export const codecForAcceptExchangeTosRequest =
|
||||||
(): Codec<AcceptExchangeTosRequest> =>
|
(): Codec<AcceptExchangeTosRequest> =>
|
||||||
buildCodecForObject<AcceptExchangeTosRequest>()
|
buildCodecForObject<AcceptExchangeTosRequest>()
|
||||||
.property("exchangeBaseUrl", codecForString())
|
.property("exchangeBaseUrl", codecForString())
|
||||||
.property("etag", codecForString())
|
.property("etag", codecOptional(codecForString()))
|
||||||
.build("AcceptExchangeTosRequest");
|
.build("AcceptExchangeTosRequest");
|
||||||
|
|
||||||
export interface ApplyRefundRequest {
|
export interface ApplyRefundRequest {
|
||||||
|
@ -1276,7 +1276,7 @@ export class ExchangeService implements ExchangeServiceInterface {
|
|||||||
accTargetType,
|
accTargetType,
|
||||||
`${this.exchangeConfig.currency}:0.01`,
|
`${this.exchangeConfig.currency}:0.01`,
|
||||||
`${this.exchangeConfig.currency}:0.01`,
|
`${this.exchangeConfig.currency}:0.01`,
|
||||||
`${this.exchangeConfig.currency}:0.01`,
|
// `${this.exchangeConfig.currency}:0.01`,
|
||||||
"upload",
|
"upload",
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
@ -1888,10 +1888,8 @@ export class WalletCli {
|
|||||||
const resp = await sh(
|
const resp = await sh(
|
||||||
self.globalTestState,
|
self.globalTestState,
|
||||||
`wallet-${self.name}`,
|
`wallet-${self.name}`,
|
||||||
`taler-wallet-cli ${
|
`taler-wallet-cli ${self.timetravelArg ?? ""
|
||||||
self.timetravelArg ?? ""
|
} --no-throttle -LTRACE --wallet-db '${self.dbfile
|
||||||
} --no-throttle -LTRACE --wallet-db '${
|
|
||||||
self.dbfile
|
|
||||||
}' api '${op}' ${shellWrap(JSON.stringify(payload))}`,
|
}' api '${op}' ${shellWrap(JSON.stringify(payload))}`,
|
||||||
);
|
);
|
||||||
console.log("--- wallet core response ---");
|
console.log("--- wallet core response ---");
|
||||||
|
@ -363,13 +363,20 @@ async function provideExchangeRecord(
|
|||||||
ws: InternalWalletState,
|
ws: InternalWalletState,
|
||||||
baseUrl: string,
|
baseUrl: string,
|
||||||
now: Timestamp,
|
now: Timestamp,
|
||||||
): Promise<ExchangeRecord> {
|
): Promise<{
|
||||||
|
exchange: ExchangeRecord;
|
||||||
|
exchangeDetails: ExchangeDetailsRecord | undefined;
|
||||||
|
}> {
|
||||||
|
|
||||||
return await ws.db
|
return await ws.db
|
||||||
.mktx((x) => ({ exchanges: x.exchanges }))
|
.mktx((x) => ({
|
||||||
|
exchanges: x.exchanges,
|
||||||
|
exchangeDetails: x.exchangeDetails,
|
||||||
|
}))
|
||||||
.runReadWrite(async (tx) => {
|
.runReadWrite(async (tx) => {
|
||||||
let r = await tx.exchanges.get(baseUrl);
|
let exchange = await tx.exchanges.get(baseUrl);
|
||||||
if (!r) {
|
if (!exchange) {
|
||||||
r = {
|
const r = {
|
||||||
permanent: true,
|
permanent: true,
|
||||||
baseUrl: baseUrl,
|
baseUrl: baseUrl,
|
||||||
retryInfo: initRetryInfo(),
|
retryInfo: initRetryInfo(),
|
||||||
@ -379,8 +386,10 @@ async function provideExchangeRecord(
|
|||||||
nextRefreshCheck: now,
|
nextRefreshCheck: now,
|
||||||
};
|
};
|
||||||
await tx.exchanges.put(r);
|
await tx.exchanges.put(r);
|
||||||
|
exchange = r;
|
||||||
}
|
}
|
||||||
return r;
|
const exchangeDetails = await getExchangeDetails(tx, baseUrl);
|
||||||
|
return { exchange, exchangeDetails };
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -519,33 +528,15 @@ async function updateExchangeFromUrlImpl(
|
|||||||
exchange: ExchangeRecord;
|
exchange: ExchangeRecord;
|
||||||
exchangeDetails: ExchangeDetailsRecord;
|
exchangeDetails: ExchangeDetailsRecord;
|
||||||
}> {
|
}> {
|
||||||
logger.trace(`updating exchange info for ${baseUrl}`);
|
logger.info(`updating exchange info for ${baseUrl}, forced: ${forceNow}`);
|
||||||
const now = getTimestampNow();
|
const now = getTimestampNow();
|
||||||
baseUrl = canonicalizeBaseUrl(baseUrl);
|
baseUrl = canonicalizeBaseUrl(baseUrl);
|
||||||
|
|
||||||
const r = await provideExchangeRecord(ws, baseUrl, now);
|
const { exchange, exchangeDetails } = await provideExchangeRecord(ws, baseUrl, now);
|
||||||
|
|
||||||
if (!forceNow && r && !isTimestampExpired(r.nextUpdate)) {
|
if (!forceNow && exchangeDetails !== undefined && !isTimestampExpired(exchange.nextUpdate)) {
|
||||||
const res = await ws.db
|
|
||||||
.mktx((x) => ({
|
|
||||||
exchanges: x.exchanges,
|
|
||||||
exchangeDetails: x.exchangeDetails,
|
|
||||||
}))
|
|
||||||
.runReadOnly(async (tx) => {
|
|
||||||
const exchange = await tx.exchanges.get(baseUrl);
|
|
||||||
if (!exchange) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const exchangeDetails = await getExchangeDetails(tx, baseUrl);
|
|
||||||
if (!exchangeDetails) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
return { exchange, exchangeDetails };
|
|
||||||
});
|
|
||||||
if (res) {
|
|
||||||
logger.info("using existing exchange info");
|
logger.info("using existing exchange info");
|
||||||
return res;
|
return { exchange, exchangeDetails };
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.info("updating exchange /keys info");
|
logger.info("updating exchange /keys info");
|
||||||
@ -584,6 +575,7 @@ async function updateExchangeFromUrlImpl(
|
|||||||
timeout,
|
timeout,
|
||||||
acceptedFormat,
|
acceptedFormat,
|
||||||
);
|
);
|
||||||
|
const tosHasBeenAccepted = exchangeDetails?.termsOfServiceAcceptedEtag === tosDownload.tosEtag
|
||||||
|
|
||||||
let recoupGroupId: string | undefined;
|
let recoupGroupId: string | undefined;
|
||||||
|
|
||||||
@ -619,7 +611,7 @@ async function updateExchangeFromUrlImpl(
|
|||||||
exchangeBaseUrl: r.baseUrl,
|
exchangeBaseUrl: r.baseUrl,
|
||||||
wireInfo,
|
wireInfo,
|
||||||
termsOfServiceText: tosDownload.tosText,
|
termsOfServiceText: tosDownload.tosText,
|
||||||
termsOfServiceAcceptedEtag: undefined,
|
termsOfServiceAcceptedEtag: tosHasBeenAccepted ? tosDownload.tosEtag : undefined,
|
||||||
termsOfServiceContentType: tosDownload.tosContentType,
|
termsOfServiceContentType: tosDownload.tosContentType,
|
||||||
termsOfServiceLastEtag: tosDownload.tosEtag,
|
termsOfServiceLastEtag: tosDownload.tosEtag,
|
||||||
termsOfServiceAcceptedTimestamp: getTimestampNow(),
|
termsOfServiceAcceptedTimestamp: getTimestampNow(),
|
||||||
|
@ -27,9 +27,10 @@ export function TermsOfServiceSection({
|
|||||||
onReview,
|
onReview,
|
||||||
}: Props): VNode {
|
}: Props): VNode {
|
||||||
const { i18n } = useTranslationContext();
|
const { i18n } = useTranslationContext();
|
||||||
|
const ableToReviewTermsOfService = onReview !== undefined;
|
||||||
if (!reviewing) {
|
if (!reviewing) {
|
||||||
if (!reviewed) {
|
if (!reviewed) {
|
||||||
if (!onReview) {
|
if (!ableToReviewTermsOfService) {
|
||||||
return (
|
return (
|
||||||
<Fragment>
|
<Fragment>
|
||||||
{terms.status === "notfound" && (
|
{terms.status === "notfound" && (
|
||||||
@ -78,7 +79,7 @@ export function TermsOfServiceSection({
|
|||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<Fragment>
|
<Fragment>
|
||||||
{onReview && (
|
{ableToReviewTermsOfService && (
|
||||||
<section>
|
<section>
|
||||||
<LinkSuccess upperCased onClick={() => onReview(true)}>
|
<LinkSuccess upperCased onClick={() => onReview(true)}>
|
||||||
<i18n.Translate>Show terms of service</i18n.Translate>
|
<i18n.Translate>Show terms of service</i18n.Translate>
|
||||||
@ -96,7 +97,7 @@ export function TermsOfServiceSection({
|
|||||||
}
|
}
|
||||||
onToggle={() => {
|
onToggle={() => {
|
||||||
onAccept(!reviewed);
|
onAccept(!reviewed);
|
||||||
if (onReview) onReview(false);
|
if (ableToReviewTermsOfService) onReview(false);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</section>
|
</section>
|
||||||
@ -136,7 +137,7 @@ export function TermsOfServiceSection({
|
|||||||
)}
|
)}
|
||||||
</section>
|
</section>
|
||||||
)}
|
)}
|
||||||
{reviewed && onReview && (
|
{reviewed && ableToReviewTermsOfService && (
|
||||||
<section>
|
<section>
|
||||||
<LinkSuccess upperCased onClick={() => onReview(false)}>
|
<LinkSuccess upperCased onClick={() => onReview(false)}>
|
||||||
<i18n.Translate>Hide terms of service</i18n.Translate>
|
<i18n.Translate>Hide terms of service</i18n.Translate>
|
||||||
@ -155,7 +156,7 @@ export function TermsOfServiceSection({
|
|||||||
}
|
}
|
||||||
onToggle={() => {
|
onToggle={() => {
|
||||||
onAccept(!reviewed);
|
onAccept(!reviewed);
|
||||||
if (onReview) onReview(false);
|
if (ableToReviewTermsOfService) onReview(false);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</section>
|
</section>
|
||||||
|
@ -293,11 +293,14 @@ export function WithdrawPageWithParsedURI({
|
|||||||
|
|
||||||
const details = detailsHook.response;
|
const details = detailsHook.response;
|
||||||
|
|
||||||
const onAccept = async (): Promise<void> => {
|
const onAccept = async (accepted: boolean): Promise<void> => {
|
||||||
if (!exchange) return;
|
if (!exchange) return;
|
||||||
try {
|
try {
|
||||||
await wxApi.setExchangeTosAccepted(exchange, details.tos.version);
|
await wxApi.setExchangeTosAccepted(
|
||||||
setReviewed(true);
|
exchange,
|
||||||
|
accepted ? details.tos.version : undefined,
|
||||||
|
);
|
||||||
|
setReviewed(accepted);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (e instanceof Error) {
|
if (e instanceof Error) {
|
||||||
//FIXME: uncomment this and display error
|
//FIXME: uncomment this and display error
|
||||||
|
@ -20,6 +20,7 @@ import {
|
|||||||
CoinDumpJson,
|
CoinDumpJson,
|
||||||
ExchangeListItem,
|
ExchangeListItem,
|
||||||
NotificationType,
|
NotificationType,
|
||||||
|
Timestamp,
|
||||||
Translate,
|
Translate,
|
||||||
} from "@gnu-taler/taler-util";
|
} from "@gnu-taler/taler-util";
|
||||||
import { PendingTaskInfo } from "@gnu-taler/taler-wallet-core";
|
import { PendingTaskInfo } from "@gnu-taler/taler-wallet-core";
|
||||||
@ -246,7 +247,13 @@ export function View({
|
|||||||
{operations.reverse().map((o) => {
|
{operations.reverse().map((o) => {
|
||||||
return (
|
return (
|
||||||
<NotifyUpdateFadeOut key={hashObjectId(o)}>
|
<NotifyUpdateFadeOut key={hashObjectId(o)}>
|
||||||
<dt>{o.type}</dt>
|
<dt>
|
||||||
|
{o.type}{" "}
|
||||||
|
<Time
|
||||||
|
timestamp={o.timestampDue}
|
||||||
|
format="yy/MM/dd hh:mm:ss"
|
||||||
|
/>
|
||||||
|
</dt>
|
||||||
<dd>
|
<dd>
|
||||||
<pre>{JSON.stringify(o, undefined, 2)}</pre>
|
<pre>{JSON.stringify(o, undefined, 2)}</pre>
|
||||||
</dd>
|
</dd>
|
||||||
|
@ -319,7 +319,6 @@ try {
|
|||||||
function headerListener(
|
function headerListener(
|
||||||
details: chrome.webRequest.WebResponseHeadersDetails,
|
details: chrome.webRequest.WebResponseHeadersDetails,
|
||||||
): chrome.webRequest.BlockingResponse | undefined {
|
): chrome.webRequest.BlockingResponse | undefined {
|
||||||
console.log("header listener");
|
|
||||||
if (chrome.runtime.lastError) {
|
if (chrome.runtime.lastError) {
|
||||||
console.error(chrome.runtime.lastError);
|
console.error(chrome.runtime.lastError);
|
||||||
return;
|
return;
|
||||||
@ -329,13 +328,11 @@ function headerListener(
|
|||||||
console.warn("wallet not available while handling header");
|
console.warn("wallet not available while handling header");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
console.log("in header listener");
|
|
||||||
if (
|
if (
|
||||||
details.statusCode === 402 ||
|
details.statusCode === 402 ||
|
||||||
details.statusCode === 202 ||
|
details.statusCode === 202 ||
|
||||||
details.statusCode === 200
|
details.statusCode === 200
|
||||||
) {
|
) {
|
||||||
console.log(`got 402/202 from ${details.url}`);
|
|
||||||
for (const header of details.responseHeaders || []) {
|
for (const header of details.responseHeaders || []) {
|
||||||
if (header.name.toLowerCase() === "taler") {
|
if (header.name.toLowerCase() === "taler") {
|
||||||
const talerUri = header.value || "";
|
const talerUri = header.value || "";
|
||||||
|
Loading…
Reference in New Issue
Block a user