From a7c8f0f3edd738a59d719105cda3aa8821886b90 Mon Sep 17 00:00:00 2001 From: Sebastian Date: Mon, 15 Apr 2024 12:01:16 -0300 Subject: fix #8604 --- packages/taler-util/src/codec.ts | 34 ++++++++++++++++++++++ .../taler-util/src/http-client/authentication.ts | 4 +-- packages/taler-util/src/http-client/types.ts | 16 +++++++++- packages/taler-util/src/http-client/utils.ts | 2 +- 4 files changed, 52 insertions(+), 4 deletions(-) (limited to 'packages/taler-util') diff --git a/packages/taler-util/src/codec.ts b/packages/taler-util/src/codec.ts index 701fc8835..678c3f092 100644 --- a/packages/taler-util/src/codec.ts +++ b/packages/taler-util/src/codec.ts @@ -360,6 +360,40 @@ export function codecForStringURL(shouldEndWithSlash?: boolean): Codec { }; } +/** + * Return a codec for a value that must be a string. + */ +export function codecForURL(shouldEndWithSlash?: boolean): Codec { + return { + decode(x: any, c?: Context): URL { + if (typeof x !== "string") { + throw new DecodingError( + `expected string at ${renderContext(c)} but got ${typeof x}`, + ); + } + if (shouldEndWithSlash && !x.endsWith("/")) { + throw new DecodingError( + `expected URL string that ends with slash at ${renderContext( + c, + )} but got ${x}`, + ); + } + try { + const url = new URL(x); + return url; + } catch (e) { + if (e instanceof Error) { + throw new DecodingError(e.message); + } else { + throw new DecodingError( + `expected an URL string at ${renderContext(c)} but got "${x}"`, + ); + } + } + }, + }; +} + /** * Codec that allows any value. */ diff --git a/packages/taler-util/src/http-client/authentication.ts b/packages/taler-util/src/http-client/authentication.ts index b8affee7b..8897a2fa0 100644 --- a/packages/taler-util/src/http-client/authentication.ts +++ b/packages/taler-util/src/http-client/authentication.ts @@ -92,14 +92,14 @@ export class TalerAuthenticationHttpClient { * @returns */ async createAccessTokenBearer( - token: string, + token: AccessToken, body: TalerAuthentication.TokenRequest, ) { const url = new URL(`token`, this.baseUrl); const resp = await this.httpLib.fetch(url.href, { method: "POST", headers: { - Authorization: makeBearerTokenAuthHeader(token as AccessToken), + Authorization: makeBearerTokenAuthHeader(token), }, body, }); diff --git a/packages/taler-util/src/http-client/types.ts b/packages/taler-util/src/http-client/types.ts index 35603264a..94eafb329 100644 --- a/packages/taler-util/src/http-client/types.ts +++ b/packages/taler-util/src/http-client/types.ts @@ -185,10 +185,24 @@ export interface LoginToken { } declare const __ac_token: unique symbol; +/** + * Use `createAccessToken(string)` function to build one. + */ export type AccessToken = string & { [__ac_token]: true; }; +/** + * Create a rfc8959 access token. + * Adds secret-token: prefix if there is none. + * + * @param token + * @returns + */ +export function createAccessToken(token: string): AccessToken { + return (token.startsWith("secret-token:") ? token : `secret-token:${token}`) as AccessToken +} + declare const __officer_signature: unique symbol; export type OfficerSignature = string & { [__officer_signature]: true; @@ -3604,7 +3618,7 @@ export namespace TalerMerchantApi { // After the auth token has been set (with method "token"), // the value must be provided in a "Authorization: Bearer $token" // header. - token?: string; + token?: AccessToken; } export interface InstanceReconfigurationMessage { diff --git a/packages/taler-util/src/http-client/utils.ts b/packages/taler-util/src/http-client/utils.ts index c579cd852..bf186ce46 100644 --- a/packages/taler-util/src/http-client/utils.ts +++ b/packages/taler-util/src/http-client/utils.ts @@ -39,7 +39,7 @@ export function makeBasicAuthHeader( * @returns */ export function makeBearerTokenAuthHeader(token: AccessToken): string { - return `Bearer secret-token:${token}`; + return `Bearer ${token}`; } /** -- cgit v1.2.3