diff options
8 files changed, 129 insertions, 120 deletions
diff --git a/packages/taler-harness/src/index.ts b/packages/taler-harness/src/index.ts index 889fbe4ca..561d70c4f 100644 --- a/packages/taler-harness/src/index.ts +++ b/packages/taler-harness/src/index.ts @@ -64,12 +64,12 @@ import { delayMs, runTestWithState, } from "./harness/harness.js"; -import { getTestInfo, runTests } from "./integrationtests/testrunner.js"; -import { lintExchangeDeployment } from "./lint.js"; import { createSimpleTestkudosEnvironmentV2, createWalletDaemonWithClient, } from "./harness/helpers.js"; +import { getTestInfo, runTests } from "./integrationtests/testrunner.js"; +import { lintExchangeDeployment } from "./lint.js"; const logger = new Logger("taler-harness:index.ts"); @@ -396,8 +396,10 @@ deploymentCli const merchantClient = new MerchantApiClient( args.tipTopup.merchantBaseUrl, { - method: "token", - token: args.tipTopup.merchantApikey, + auth: { + method: "token", + token: args.tipTopup.merchantApikey, + }, }, ); @@ -447,8 +449,10 @@ deploymentCli const merchantClient = new MerchantApiClient( args.tipCleanup.merchantBaseUrl, { - method: "token", - token: args.tipCleanup.merchantApikey, + auth: { + method: "token", + token: args.tipCleanup.merchantApikey, + }, }, ); @@ -567,8 +571,10 @@ deploymentCli const merchantClient = new MerchantApiClient( args.tipStatus.merchantBaseUrl, { - method: "token", - token: args.tipStatus.merchantApikey, + auth: { + method: "token", + token: args.tipStatus.merchantApikey, + }, }, ); diff --git a/packages/taler-harness/src/integrationtests/test-merchant-instances-delete.ts b/packages/taler-harness/src/integrationtests/test-merchant-instances-delete.ts index 4508b9976..c0c9353e4 100644 --- a/packages/taler-harness/src/integrationtests/test-merchant-instances-delete.ts +++ b/packages/taler-harness/src/integrationtests/test-merchant-instances-delete.ts @@ -95,7 +95,9 @@ export async function runMerchantInstancesDeleteTest(t: GlobalTestState) { }); let merchantClient = new MerchantApiClient(merchant.makeInstanceBaseUrl(), { - method: "external", + auth: { + method: "external", + }, }); await merchantClient.changeAuth({ @@ -104,8 +106,10 @@ export async function runMerchantInstancesDeleteTest(t: GlobalTestState) { }); merchantClient = new MerchantApiClient(merchant.makeInstanceBaseUrl(), { - method: "token", - token: "secret-token:foobar", + auth: { + method: "token", + token: "secret-token:foobar", + }, }); // Check that deleting an instance checks the auth @@ -114,8 +118,10 @@ export async function runMerchantInstancesDeleteTest(t: GlobalTestState) { const unauthMerchantClient = new MerchantApiClient( merchant.makeInstanceBaseUrl(), { - method: "token", - token: "secret-token:invalid", + auth: { + method: "token", + token: "secret-token:invalid", + }, }, ); diff --git a/packages/taler-harness/src/integrationtests/test-merchant-instances-urls.ts b/packages/taler-harness/src/integrationtests/test-merchant-instances-urls.ts index 7236436ac..b631ea1a4 100644 --- a/packages/taler-harness/src/integrationtests/test-merchant-instances-urls.ts +++ b/packages/taler-harness/src/integrationtests/test-merchant-instances-urls.ts @@ -22,7 +22,6 @@ import { ExchangeService, GlobalTestState, MerchantService, - generateRandomPayto, harnessHttpLib, setupDb, } from "../harness/harness.js"; @@ -55,8 +54,10 @@ export async function runMerchantInstancesUrlsTest(t: GlobalTestState) { const clientForDefault = new MerchantApiClient( merchant.makeInstanceBaseUrl(), { - method: "token", - token: "secret-token:i-am-default", + auth: { + method: "token", + token: "secret-token:i-am-default", + }, }, ); diff --git a/packages/taler-harness/src/integrationtests/test-merchant-instances.ts b/packages/taler-harness/src/integrationtests/test-merchant-instances.ts index a77e9ca51..188451e15 100644 --- a/packages/taler-harness/src/integrationtests/test-merchant-instances.ts +++ b/packages/taler-harness/src/integrationtests/test-merchant-instances.ts @@ -22,9 +22,9 @@ import { ExchangeService, GlobalTestState, MerchantService, - setupDb, generateRandomPayto, harnessHttpLib, + setupDb, } from "../harness/harness.js"; /** @@ -105,7 +105,9 @@ export async function runMerchantInstancesTest(t: GlobalTestState) { }); let merchantClient = new MerchantApiClient(merchant.makeInstanceBaseUrl(), { - method: "external", + auth: { + method: "external", + }, }); { @@ -148,8 +150,10 @@ export async function runMerchantInstancesTest(t: GlobalTestState) { t.assertTrue(exc.errorDetail.httpStatusCode === 401); merchantClient = new MerchantApiClient(merchant.makeInstanceBaseUrl(), { - method: "token", - token: "secret-token:foobar", + auth: { + method: "token", + token: "secret-token:foobar", + }, }); // With the new client auth settings, request should work again. @@ -184,7 +188,9 @@ export async function runMerchantInstancesTest(t: GlobalTestState) { const unauthMerchantClient = new MerchantApiClient( merchant.makeInstanceBaseUrl(), { - method: "external", + auth: { + method: "external", + }, }, ); diff --git a/packages/taler-harness/src/integrationtests/test-otp.ts b/packages/taler-harness/src/integrationtests/test-otp.ts index d7c82ecdf..dd6c45e4c 100644 --- a/packages/taler-harness/src/integrationtests/test-otp.ts +++ b/packages/taler-harness/src/integrationtests/test-otp.ts @@ -1,6 +1,6 @@ /* This file is part of GNU Taler - (C) 2020 Taler Systems S.A. + (C) 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 diff --git a/packages/taler-util/src/MerchantApiClient.ts b/packages/taler-util/src/MerchantApiClient.ts index 86c72651e..561226ba9 100644 --- a/packages/taler-util/src/MerchantApiClient.ts +++ b/packages/taler-util/src/MerchantApiClient.ts @@ -16,31 +16,55 @@ import { codecForAny } from "./codec.js"; import { + TalerMerchantApi, + codecForMerchantConfig, +} from "./http-client/types.js"; +import { HttpStatusCode } from "./http-status-codes.js"; +import { createPlatformHttpLib, expectSuccessResponseOrThrow, readSuccessResponseJsonOrThrow, } from "./http.js"; import { FacadeCredentials } from "./libeufin-api-types.js"; +import { LibtoolVersion } from "./libtool-version.js"; import { Logger } from "./logging.js"; import { - MerchantReserveCreateConfirmation, - codecForMerchantReserveCreateConfirmation, - TippingReserveStatus, MerchantInstancesResponse, + MerchantOrderPrivateStatusResponse, MerchantPostOrderRequest, MerchantPostOrderResponse, - codecForMerchantPostOrderResponse, - MerchantOrderPrivateStatusResponse, - codecForMerchantOrderPrivateStatusResponse, - RewardCreateRequest, - RewardCreateConfirmation, + MerchantReserveCreateConfirmation, MerchantTemplateAddDetails, + RewardCreateConfirmation, + RewardCreateRequest, + TippingReserveStatus, + codecForMerchantOrderPrivateStatusResponse, + codecForMerchantPostOrderResponse, + codecForMerchantReserveCreateConfirmation, } from "./merchant-api-types.js"; +import { + FailCasesByMethod, + OperationFail, + OperationOk, + ResultByMethod, + opEmptySuccess, + opKnownHttpFailure, + opSuccess, + opUnknownFailure, +} from "./operation.js"; import { AmountString } from "./taler-types.js"; import { TalerProtocolDuration } from "./time.js"; const logger = new Logger("MerchantApiClient.ts"); +// FIXME: Explain! +export type TalerMerchantResultByMethod<prop extends keyof MerchantApiClient> = + ResultByMethod<MerchantApiClient, prop>; + +// FIXME: Explain! +export type TalerMerchantErrorsByMethod<prop extends keyof MerchantApiClient> = + FailCasesByMethod<MerchantApiClient, prop>; + export interface MerchantAuthConfiguration { method: "external" | "token"; token?: string; @@ -69,23 +93,6 @@ export interface CreateMerchantTippingReserveRequest { wire_method: string; } -interface OtpDeviceAddDetails { - // Device ID to use. - otp_device_id: string; - - // Human-readable description for the device. - otp_device_description: string; - - // A base64-encoded key - otp_key: string; - - // Algorithm for computing the POS confirmation. - otp_algorithm: number; - - // Counter for counter-based OTP devices. - otp_ctr?: number; -} - export interface DeleteTippingReserveArgs { reservePub: string; purge?: boolean; @@ -123,6 +130,23 @@ export interface PrivateOrderStatusQuery { sessionId?: string; } +export interface OtpDeviceAddDetails { + // Device ID to use. + otp_device_id: string; + + // Human-readable description for the device. + otp_device_description: string; + + // A base64-encoded key + otp_key: string; + + // Algorithm for computing the POS confirmation. + otp_algorithm: number; + + // Counter for counter-based OTP devices. + otp_ctr?: number; +} + /** * Client for the GNU Taler merchant backend. */ @@ -135,10 +159,15 @@ export class MerchantApiClient { readonly auth: MerchantAuthConfiguration; - constructor(baseUrl: string, auth?: MerchantAuthConfiguration) { + public readonly PROTOCOL_VERSION = "6:0:2"; + + constructor( + baseUrl: string, + options: { auth?: MerchantAuthConfiguration } = {}, + ) { this.baseUrl = baseUrl; - this.auth = auth ?? { + this.auth = options?.auth ?? { method: "external", }; } @@ -338,13 +367,44 @@ export class MerchantApiClient { } } - async createOtpDevice(req: OtpDeviceAddDetails): Promise<void> { + isCompatible(version: string): boolean { + const compare = LibtoolVersion.compare(this.PROTOCOL_VERSION, version); + return compare?.compatible ?? false; + } + /** + * https://docs.taler.net/core/api-merchant.html#get--config + * + */ + async getConfig(): Promise<OperationOk<TalerMerchantApi.VersionResponse>> { + const url = new URL(`config`, this.baseUrl); + const resp = await this.httpClient.fetch(url.href, { + method: "GET", + }); + switch (resp.status) { + case HttpStatusCode.Ok: + return opSuccess(resp, codecForMerchantConfig()); + default: + return opUnknownFailure(resp, await resp.text()); + } + } + + async createOtpDevice( + req: OtpDeviceAddDetails, + ): Promise<OperationOk<void> | OperationFail<HttpStatusCode.NotFound>> { let url = new URL("private/templates", this.baseUrl); const resp = await this.httpClient.fetch(url.href, { method: "POST", body: req, headers: this.makeAuthHeader(), }); + switch (resp.status) { + case HttpStatusCode.Ok: + return opEmptySuccess(resp); + case HttpStatusCode.NotFound: + return opKnownHttpFailure(resp.status, resp); + default: + return opUnknownFailure(resp, await resp.text()); + } } private makeAuthHeader(): Record<string, string> { diff --git a/packages/taler-util/src/http-client/merchant.ts b/packages/taler-util/src/http-client/merchant.ts deleted file mode 100644 index d23bdeb17..000000000 --- a/packages/taler-util/src/http-client/merchant.ts +++ /dev/null @@ -1,69 +0,0 @@ -/* - 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/> - */ - -import { HttpRequestLibrary } from "../http-common.js"; -import { HttpStatusCode } from "../http-status-codes.js"; -import { createPlatformHttpLib } from "../http.js"; -import { LibtoolVersion } from "../libtool-version.js"; -import { - FailCasesByMethod, - ResultByMethod, - opSuccess, - opUnknownFailure, -} from "../operation.js"; -import { codecForMerchantConfig } from "./types.js"; - -export type TalerMerchantResultByMethod< - prop extends keyof TalerMerchantHttpClient, -> = ResultByMethod<TalerMerchantHttpClient, prop>; -export type TalerMerchantErrorsByMethod< - prop extends keyof TalerMerchantHttpClient, -> = FailCasesByMethod<TalerMerchantHttpClient, prop>; - -/** - */ -export class TalerMerchantHttpClient { - httpLib: HttpRequestLibrary; - public readonly PROTOCOL_VERSION = "6:0:2"; - - 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-merchant.html#get--config - * - */ - async getConfig() { - const url = new URL(`config`, this.baseUrl); - const resp = await this.httpLib.fetch(url.href, { - method: "GET", - }); - switch (resp.status) { - case HttpStatusCode.Ok: - return opSuccess(resp, codecForMerchantConfig()); - default: - return opUnknownFailure(resp, await resp.text()); - } - } -} diff --git a/packages/taler-util/src/index.ts b/packages/taler-util/src/index.ts index 53d3e137a..a32b730a9 100644 --- a/packages/taler-util/src/index.ts +++ b/packages/taler-util/src/index.ts @@ -45,7 +45,6 @@ export * from "./MerchantApiClient.js"; export * from "./bank-api-client.js"; export * from "./http-client/bank-core.js"; export * from "./http-client/exchange.js"; -export * from "./http-client/merchant.js"; export * from "./http-client/officer-account.js"; export * from "./http-client/bank-integration.js"; export * from "./http-client/bank-revenue.js"; |