diff options
Diffstat (limited to 'packages/taler-util/src/http-client/utils.ts')
-rw-r--r-- | packages/taler-util/src/http-client/utils.ts | 116 |
1 files changed, 116 insertions, 0 deletions
diff --git a/packages/taler-util/src/http-client/utils.ts b/packages/taler-util/src/http-client/utils.ts new file mode 100644 index 000000000..bf186ce46 --- /dev/null +++ b/packages/taler-util/src/http-client/utils.ts @@ -0,0 +1,116 @@ +/* + This file is part of GNU Taler + (C) 2022-2024 Taler Systems S.A. + + GNU Taler is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ + +/** + * Imports. + */ +import { base64FromArrayBuffer } from "../base64.js"; +import { encodeCrock, getRandomBytes, stringToBytes } from "../taler-crypto.js"; +import { AccessToken, LongPollParams, PaginationParams } from "./types.js"; + +/** + * Helper function to generate the "Authorization" HTTP header. + */ +export function makeBasicAuthHeader( + username: string, + password: string, +): string { + const auth = `${username}:${password}`; + const authEncoded: string = base64FromArrayBuffer(stringToBytes(auth)); + return `Basic ${authEncoded}`; +} + +/** + * rfc8959 + * @param token + * @returns + */ +export function makeBearerTokenAuthHeader(token: AccessToken): string { + return `Bearer ${token}`; +} + +/** + * https://bugs.gnunet.org/view.php?id=7949 + */ +export function addPaginationParams(url: URL, pagination?: PaginationParams) { + if (!pagination) return; + if (pagination.offset) { + url.searchParams.set("start", pagination.offset); + } + const order = !pagination || pagination.order === "asc" ? 1 : -1; + const limit = + !pagination || !pagination.limit || pagination.limit === 0 + ? 5 + : Math.abs(pagination.limit); + //always send delta + url.searchParams.set("delta", String(order * limit)); +} + +export function addMerchantPaginationParams( + url: URL, + pagination?: PaginationParams, +) { + if (!pagination) return; + if (pagination.offset) { + url.searchParams.set("offset", pagination.offset); + } + const order = !pagination || pagination.order === "asc" ? 1 : -1; + const limit = + !pagination || !pagination.limit || pagination.limit === 0 + ? 5 + : Math.abs(pagination.limit); + //always send delta + url.searchParams.set("limit", String(order * limit)); +} + +export function addLongPollingParam(url: URL, param?: LongPollParams) { + if (!param) return; + if (param.timeoutMs) { + url.searchParams.set("long_poll_ms", String(param.timeoutMs)); + } +} + +export interface CacheEvictor<T> { + notifySuccess: (op: T) => Promise<void>; +} + +export const nullEvictor: CacheEvictor<unknown> = { + notifySuccess: () => Promise.resolve(), +}; + +export class IdempotencyRetry { + public readonly uid: string; + public readonly timesLeft: number; + public readonly maxTries: number; + + private constructor(timesLeft: number, maxTimesLeft: number) { + this.timesLeft = timesLeft; + this.maxTries = maxTimesLeft; + this.uid = encodeCrock(getRandomBytes(32)) + } + + static tryFiveTimes() { + return new IdempotencyRetry(5, 5) + } + + next(): IdempotencyRetry | undefined { + const left = this.timesLeft -1 + if (left <= 0) { + return undefined + } + return new IdempotencyRetry(left, this.maxTries); + } +} |