/* This file is part of GNU Taler (C) 2022 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 */ /** * Imports. */ import { HttpStatusCode } from "../http-status-codes.js"; import { HttpRequestLibrary, createPlatformHttpLib, makeBasicAuthHeader, readTalerErrorResponse, } from "../http.js"; import { LibtoolVersion } from "../libtool-version.js"; import { opEmptySuccess, opKnownHttpFailure, opSuccessFromHttp, opUnknownFailure, } from "../operation.js"; import { AccessToken, TokenRequest, codecForTokenSuccessResponse, codecForTokenSuccessResponseMerchant, } from "../types-taler-common.js"; import { makeBearerTokenAuthHeader } from "./utils.js"; export class TalerAuthenticationHttpClient { public readonly PROTOCOL_VERSION = "0:0:0"; httpLib: HttpRequestLibrary; constructor( readonly baseUrl: string, httpClient?: HttpRequestLibrary, ) { this.httpLib = httpClient ?? createPlatformHttpLib(); } isCompatible(version: string): boolean { const compare = LibtoolVersion.compare(this.PROTOCOL_VERSION, version); return compare?.compatible ?? false; } /** * https://docs.taler.net/core/api-corebank.html#post--accounts-$USERNAME-token * * @returns */ async createAccessTokenBasic( username: string, password: string, body: TokenRequest, ) { const url = new URL(`token`, this.baseUrl); const resp = await this.httpLib.fetch(url.href, { method: "POST", headers: { Authorization: makeBasicAuthHeader(username, password), }, body, }); switch (resp.status) { case HttpStatusCode.Ok: return opSuccessFromHttp(resp, codecForTokenSuccessResponse()); //FIXME: missing in docs case HttpStatusCode.Unauthorized: return opKnownHttpFailure(resp.status, resp); case HttpStatusCode.NotFound: return opKnownHttpFailure(resp.status, resp); default: return opUnknownFailure(resp, await readTalerErrorResponse(resp)); } } /** * * @returns */ async createAccessTokenBearer(token: AccessToken, body: TokenRequest) { const url = new URL(`token`, this.baseUrl); const resp = await this.httpLib.fetch(url.href, { method: "POST", headers: { Authorization: makeBearerTokenAuthHeader(token), }, body, }); switch (resp.status) { case HttpStatusCode.Ok: return opSuccessFromHttp(resp, codecForTokenSuccessResponseMerchant()); //FIXME: missing in docs case HttpStatusCode.Unauthorized: return opKnownHttpFailure(resp.status, resp); case HttpStatusCode.NotFound: return opKnownHttpFailure(resp.status, resp); default: return opUnknownFailure(resp, await readTalerErrorResponse(resp)); } } async deleteAccessToken(token: AccessToken) { const url = new URL(`token`, this.baseUrl); const resp = await this.httpLib.fetch(url.href, { method: "DELETE", headers: { Authorization: makeBearerTokenAuthHeader(token), }, }); switch (resp.status) { case HttpStatusCode.Ok: return opEmptySuccess(resp); //FIXME: missing in docs case HttpStatusCode.NotFound: return opKnownHttpFailure(resp.status, resp); default: return opUnknownFailure(resp, await readTalerErrorResponse(resp)); } } }