taler-harness: remove axios usage, renovate some tests

This commit is contained in:
Florian Dold 2023-08-29 09:02:16 +02:00
parent 8941f29cb4
commit b13bd85215
No known key found for this signature in database
GPG Key ID: D2E4F00F29D02A4B
40 changed files with 667 additions and 920 deletions

View File

@ -40,7 +40,6 @@
"dependencies": { "dependencies": {
"@gnu-taler/taler-util": "workspace:*", "@gnu-taler/taler-util": "workspace:*",
"@gnu-taler/taler-wallet-core": "workspace:*", "@gnu-taler/taler-wallet-core": "workspace:*",
"axios": "^0.27.2",
"tslib": "^2.5.3" "tslib": "^2.5.3"
} }
} }

View File

@ -26,13 +26,13 @@ import {
j2s, j2s,
Logger, Logger,
} from "@gnu-taler/taler-util"; } from "@gnu-taler/taler-util";
import { createPlatformHttpLib } from "@gnu-taler/taler-util/http";
import { import {
AccessStats, AccessStats,
createNativeWalletHost2, createNativeWalletHost2,
Wallet, Wallet,
WalletApiOperation, WalletApiOperation,
} from "@gnu-taler/taler-wallet-core"; } from "@gnu-taler/taler-wallet-core";
import { harnessHttpLib } from "./harness/harness.js";
/** /**
* Entry point for the benchmark. * Entry point for the benchmark.
@ -46,11 +46,6 @@ export async function runBench1(configJson: any): Promise<void> {
// Validate the configuration file for this benchmark. // Validate the configuration file for this benchmark.
const b1conf = codecForBench1Config().decode(configJson); const b1conf = codecForBench1Config().decode(configJson);
const myHttpLib = createPlatformHttpLib({
enableThrottling: false,
allowHttp: true,
});
const numIter = b1conf.iterations ?? 1; const numIter = b1conf.iterations ?? 1;
const numDeposits = b1conf.deposits ?? 5; const numDeposits = b1conf.deposits ?? 5;
const restartWallet = b1conf.restartAfter ?? 20; const restartWallet = b1conf.restartAfter ?? 20;
@ -85,7 +80,7 @@ export async function runBench1(configJson: any): Promise<void> {
const res = await createNativeWalletHost2({ const res = await createNativeWalletHost2({
// No persistent DB storage. // No persistent DB storage.
persistentStoragePath: undefined, persistentStoragePath: undefined,
httpLib: myHttpLib, httpLib: harnessHttpLib,
config: { config: {
testing: { testing: {
insecureTrustExchange: trustExchange, insecureTrustExchange: trustExchange,

View File

@ -55,9 +55,11 @@ import {
RewardCreateRequest, RewardCreateRequest,
TippingReserveStatus, TippingReserveStatus,
WalletNotification, WalletNotification,
codecForAny,
} from "@gnu-taler/taler-util"; } from "@gnu-taler/taler-util";
import { import {
createPlatformHttpLib, createPlatformHttpLib,
expectSuccessResponseOrThrow,
readSuccessResponseJsonOrThrow, readSuccessResponseJsonOrThrow,
} from "@gnu-taler/taler-util/http"; } from "@gnu-taler/taler-util/http";
import { import {
@ -78,7 +80,6 @@ import {
WalletNotificationWaiter, WalletNotificationWaiter,
} from "@gnu-taler/taler-wallet-core/remote"; } from "@gnu-taler/taler-wallet-core/remote";
import { deepStrictEqual } from "assert"; import { deepStrictEqual } from "assert";
import axiosImp, { AxiosError } from "axios";
import { ChildProcess, spawn } from "child_process"; import { ChildProcess, spawn } from "child_process";
import * as fs from "fs"; import * as fs from "fs";
import * as http from "http"; import * as http from "http";
@ -87,12 +88,9 @@ import * as path from "path";
import * as readline from "readline"; import * as readline from "readline";
import { URL } from "url"; import { URL } from "url";
import { CoinConfig } from "./denomStructures.js"; import { CoinConfig } from "./denomStructures.js";
import { LibeufinNexusApi, LibeufinSandboxApi } from "./libeufin-apis.js";
const logger = new Logger("harness.ts"); const logger = new Logger("harness.ts");
const axios = axiosImp.default;
export async function delayMs(ms: number): Promise<void> { export async function delayMs(ms: number): Promise<void> {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
setTimeout(() => resolve(), ms); setTimeout(() => resolve(), ms);
@ -322,12 +320,6 @@ export class GlobalTestState {
); );
} }
assertAxiosError(e: any): asserts e is AxiosError {
if (!e.isAxiosError) {
throw Error("expected axios error");
}
}
assertTrue(b: boolean): asserts b { assertTrue(b: boolean): asserts b {
if (!b) { if (!b) {
throw Error("test assertion failed"); throw Error("test assertion failed");
@ -558,7 +550,10 @@ export async function pingProc(
while (true) { while (true) {
try { try {
logger.trace(`pinging ${serviceName} at ${url}`); logger.trace(`pinging ${serviceName} at ${url}`);
const resp = await axios.get(url); const resp = await harnessHttpLib.fetch(url);
if (resp.status !== 200) {
throw Error("non-200 status code");
}
logger.trace(`service ${serviceName} available`); logger.trace(`service ${serviceName} available`);
return; return;
} catch (e: any) { } catch (e: any) {
@ -583,289 +578,6 @@ class BankServiceBase {
) {} ) {}
} }
/**
* Work in progress. The key point is that both Sandbox and Nexus
* will be configured and started by this class.
*/
class LibEuFinBankService extends BankServiceBase implements BankServiceHandle {
sandboxProc: ProcessWrapper | undefined;
nexusProc: ProcessWrapper | undefined;
http = createPlatformHttpLib({
allowHttp: true,
enableThrottling: false,
});
static async create(
gc: GlobalTestState,
bc: BankConfig,
): Promise<LibEuFinBankService> {
return new LibEuFinBankService(gc, bc, "foo");
}
get port() {
return this.bankConfig.httpPort;
}
get nexusPort() {
return this.bankConfig.httpPort + 1000;
}
get nexusDbConn(): string {
return `jdbc:sqlite:${this.globalTestState.testDir}/libeufin-nexus.sqlite3`;
}
get sandboxDbConn(): string {
return `jdbc:sqlite:${this.globalTestState.testDir}/libeufin-sandbox.sqlite3`;
}
get nexusBaseUrl(): string {
return `http://localhost:${this.nexusPort}`;
}
get baseUrlDemobank(): string {
let url = new URL("demobanks/default/", this.baseUrlNetloc);
return url.href;
}
get bankAccessApiBaseUrl(): string {
let url = new URL("access-api/", this.baseUrlDemobank);
return url.href;
}
get baseUrlNetloc(): string {
return `http://localhost:${this.bankConfig.httpPort}/`;
}
get baseUrl(): string {
return this.bankAccessApiBaseUrl;
}
async setSuggestedExchange(
e: ExchangeServiceInterface,
exchangePayto: string,
) {
await sh(
this.globalTestState,
"libeufin-sandbox-set-default-exchange",
`libeufin-sandbox default-exchange ${e.baseUrl} ${exchangePayto}`,
{
...process.env,
LIBEUFIN_SANDBOX_DB_CONNECTION: this.sandboxDbConn,
},
);
}
// Create one at both sides: Sandbox and Nexus.
async createExchangeAccount(
accountName: string,
password: string,
): Promise<HarnessExchangeBankAccount> {
logger.info("Create Exchange account(s)!");
/**
* Many test cases try to create a Exchange account before
* starting the bank; that's because the Pybank did it entirely
* via the configuration file.
*/
await this.start();
await this.pingUntilAvailable();
await LibeufinSandboxApi.createDemobankAccount(accountName, password, {
baseUrl: this.bankAccessApiBaseUrl,
});
let bankAccountLabel = accountName;
await LibeufinSandboxApi.createDemobankEbicsSubscriber(
{
hostID: "talertestEbicsHost",
userID: "exchangeEbicsUser",
partnerID: "exchangeEbicsPartner",
},
bankAccountLabel,
{ baseUrl: this.baseUrlDemobank },
);
await LibeufinNexusApi.createUser(
{ baseUrl: this.nexusBaseUrl },
{
username: accountName,
password: password,
},
);
await LibeufinNexusApi.createEbicsBankConnection(
{ baseUrl: this.nexusBaseUrl },
{
name: "ebics-connection", // connection name.
ebicsURL: new URL("ebicsweb", this.baseUrlNetloc).href,
hostID: "talertestEbicsHost",
userID: "exchangeEbicsUser",
partnerID: "exchangeEbicsPartner",
},
);
await LibeufinNexusApi.connectBankConnection(
{ baseUrl: this.nexusBaseUrl },
"ebics-connection",
);
await LibeufinNexusApi.fetchAccounts(
{ baseUrl: this.nexusBaseUrl },
"ebics-connection",
);
await LibeufinNexusApi.importConnectionAccount(
{ baseUrl: this.nexusBaseUrl },
"ebics-connection", // connection name
accountName, // offered account label
`${accountName}-nexus-label`, // bank account label at Nexus
);
await LibeufinNexusApi.createTwgFacade(
{ baseUrl: this.nexusBaseUrl },
{
name: "exchange-facade",
connectionName: "ebics-connection",
accountName: `${accountName}-nexus-label`,
currency: "EUR",
reserveTransferLevel: "report",
},
);
await LibeufinNexusApi.postPermission(
{ baseUrl: this.nexusBaseUrl },
{
action: "grant",
permission: {
subjectId: accountName,
subjectType: "user",
resourceType: "facade",
resourceId: "exchange-facade", // facade name
permissionName: "facade.talerWireGateway.transfer",
},
},
);
await LibeufinNexusApi.postPermission(
{ baseUrl: this.nexusBaseUrl },
{
action: "grant",
permission: {
subjectId: accountName,
subjectType: "user",
resourceType: "facade",
resourceId: "exchange-facade", // facade name
permissionName: "facade.talerWireGateway.history",
},
},
);
// Set fetch task.
await LibeufinNexusApi.postTask(
{ baseUrl: this.nexusBaseUrl },
`${accountName}-nexus-label`,
{
name: "wirewatch-task",
cronspec: "* * *",
type: "fetch",
params: {
level: "all",
rangeType: "all",
},
},
);
await LibeufinNexusApi.postTask(
{ baseUrl: this.nexusBaseUrl },
`${accountName}-nexus-label`,
{
name: "aggregator-task",
cronspec: "* * *",
type: "submit",
params: {},
},
);
let facadesResp = await LibeufinNexusApi.getAllFacades({
baseUrl: this.nexusBaseUrl,
});
let accountInfoResp = await LibeufinSandboxApi.demobankAccountInfo(
"admin",
"secret",
{ baseUrl: this.bankAccessApiBaseUrl },
accountName, // bank account label.
);
return {
accountName: accountName,
accountPassword: password,
accountPaytoUri: accountInfoResp.data.paytoUri,
wireGatewayApiBaseUrl: facadesResp.data.facades[0].baseUrl,
};
}
async start(): Promise<void> {
/**
* Because many test cases try to create a Exchange bank
* account _before_ starting the bank (Pybank did it only via
* the config), it is possible that at this point Sandbox and
* Nexus are already running. Hence, this method only launches
* them if they weren't launched earlier.
*/
// Only go ahead if BOTH aren't running.
if (this.sandboxProc || this.nexusProc) {
logger.info("Nexus or Sandbox already running, not taking any action.");
return;
}
await sh(
this.globalTestState,
"libeufin-sandbox-config-demobank",
`libeufin-sandbox config --currency=${this.bankConfig.currency} default`,
{
...process.env,
LIBEUFIN_SANDBOX_DB_CONNECTION: this.sandboxDbConn,
LIBEUFIN_SANDBOX_ADMIN_PASSWORD: "secret",
},
);
this.sandboxProc = this.globalTestState.spawnService(
"libeufin-sandbox",
["serve", "--port", `${this.port}`],
"libeufin-sandbox",
{
...process.env,
LIBEUFIN_SANDBOX_DB_CONNECTION: this.sandboxDbConn,
LIBEUFIN_SANDBOX_ADMIN_PASSWORD: "secret",
},
);
await runCommand(
this.globalTestState,
"libeufin-nexus-superuser",
"libeufin-nexus",
["superuser", "admin", "--password", "test"],
{
...process.env,
LIBEUFIN_NEXUS_DB_CONNECTION: this.nexusDbConn,
},
);
this.nexusProc = this.globalTestState.spawnService(
"libeufin-nexus",
["serve", "--port", `${this.nexusPort}`],
"libeufin-nexus",
{
...process.env,
LIBEUFIN_NEXUS_DB_CONNECTION: this.nexusDbConn,
},
);
// need to wait here, because at this point
// a Ebics host needs to be created (RESTfully)
await this.pingUntilAvailable();
LibeufinSandboxApi.createEbicsHost(
{ baseUrl: this.baseUrlNetloc },
"talertestEbicsHost",
);
}
async pingUntilAvailable(): Promise<void> {
await pingProc(
this.sandboxProc,
`http://localhost:${this.bankConfig.httpPort}`,
"libeufin-sandbox",
);
await pingProc(
this.nexusProc,
`${this.nexusBaseUrl}/config`,
"libeufin-nexus",
);
}
}
/** /**
* Implementation of the bank service using the "taler-fakebank-run" tool. * Implementation of the bank service using the "taler-fakebank-run" tool.
*/ */
@ -1152,6 +864,9 @@ export class ExchangeService implements ExchangeServiceInterface {
"currency_round_unit", "currency_round_unit",
e.roundUnit ?? `${e.currency}:0.01`, e.roundUnit ?? `${e.currency}:0.01`,
); );
// Set to a high value to not break existing test cases where the merchant
// would cover all fees.
config.setString("exchange", "STEFAN_ABS", `${e.currency}:1`);
config.setString( config.setString(
"exchange", "exchange",
"revocation_dir", "revocation_dir",
@ -1636,20 +1351,30 @@ export interface DeleteTippingReserveArgs {
purge?: boolean; purge?: boolean;
} }
/**
* Default HTTP client handle for the integration test harness.
*/
export const harnessHttpLib = createPlatformHttpLib({
allowHttp: true,
enableThrottling: false,
});
export class MerchantApiClient { export class MerchantApiClient {
constructor( constructor(
private baseUrl: string, private baseUrl: string,
public readonly auth: MerchantAuthConfiguration, public readonly auth: MerchantAuthConfiguration,
) {} ) {}
// FIXME: Migrate everything to this in favor of axios httpClient = createPlatformHttpLib({ allowHttp: true, enableThrottling: false });
http = createPlatformHttpLib({ allowHttp: true, enableThrottling: false });
async changeAuth(auth: MerchantAuthConfiguration): Promise<void> { async changeAuth(auth: MerchantAuthConfiguration): Promise<void> {
const url = new URL("private/auth", this.baseUrl); const url = new URL("private/auth", this.baseUrl);
await axios.post(url.href, auth, { const res = await this.httpClient.fetch(url.href, {
method: "POST",
body: auth,
headers: this.makeAuthHeader(), headers: this.makeAuthHeader(),
}); });
await expectSuccessResponseOrThrow(res);
} }
async deleteTippingReserve(req: DeleteTippingReserveArgs): Promise<void> { async deleteTippingReserve(req: DeleteTippingReserveArgs): Promise<void> {
@ -1657,7 +1382,8 @@ export class MerchantApiClient {
if (req.purge) { if (req.purge) {
url.searchParams.set("purge", "YES"); url.searchParams.set("purge", "YES");
} }
const resp = await axios.delete(url.href, { const resp = await this.httpClient.fetch(url.href, {
method: "DELETE",
headers: this.makeAuthHeader(), headers: this.makeAuthHeader(),
}); });
logger.info(`delete status: ${resp.status}`); logger.info(`delete status: ${resp.status}`);
@ -1668,7 +1394,7 @@ export class MerchantApiClient {
req: CreateMerchantTippingReserveRequest, req: CreateMerchantTippingReserveRequest,
): Promise<MerchantReserveCreateConfirmation> { ): Promise<MerchantReserveCreateConfirmation> {
const url = new URL("private/reserves", this.baseUrl); const url = new URL("private/reserves", this.baseUrl);
const resp = await this.http.fetch(url.href, { const resp = await this.httpClient.fetch(url.href, {
method: "POST", method: "POST",
body: req, body: req,
headers: this.makeAuthHeader(), headers: this.makeAuthHeader(),
@ -1684,7 +1410,7 @@ export class MerchantApiClient {
console.log(this.makeAuthHeader()); console.log(this.makeAuthHeader());
const url = new URL("private", this.baseUrl); const url = new URL("private", this.baseUrl);
logger.info(`request url ${url.href}`); logger.info(`request url ${url.href}`);
const resp = await this.http.fetch(url.href, { const resp = await this.httpClient.fetch(url.href, {
method: "GET", method: "GET",
headers: this.makeAuthHeader(), headers: this.makeAuthHeader(),
}); });
@ -1694,7 +1420,7 @@ export class MerchantApiClient {
async getPrivateTipReserves(): Promise<TippingReserveStatus> { async getPrivateTipReserves(): Promise<TippingReserveStatus> {
console.log(this.makeAuthHeader()); console.log(this.makeAuthHeader());
const url = new URL("private/reserves", this.baseUrl); const url = new URL("private/reserves", this.baseUrl);
const resp = await this.http.fetch(url.href, { const resp = await this.httpClient.fetch(url.href, {
method: "GET", method: "GET",
headers: this.makeAuthHeader(), headers: this.makeAuthHeader(),
}); });
@ -1704,33 +1430,37 @@ export class MerchantApiClient {
async deleteInstance(instanceId: string) { async deleteInstance(instanceId: string) {
const url = new URL(`management/instances/${instanceId}`, this.baseUrl); const url = new URL(`management/instances/${instanceId}`, this.baseUrl);
await axios.delete(url.href, { const resp = await this.httpClient.fetch(url.href, {
method: "DELETE",
headers: this.makeAuthHeader(), headers: this.makeAuthHeader(),
}); });
await expectSuccessResponseOrThrow(resp);
} }
async createInstance(req: MerchantInstanceConfig): Promise<void> { async createInstance(req: MerchantInstanceConfig): Promise<void> {
const url = new URL("management/instances", this.baseUrl); const url = new URL("management/instances", this.baseUrl);
await axios.post(url.href, req, { await this.httpClient.fetch(url.href, {
method: "POST",
body: req,
headers: this.makeAuthHeader(), headers: this.makeAuthHeader(),
}); });
} }
async getInstances(): Promise<MerchantInstancesResponse> { async getInstances(): Promise<MerchantInstancesResponse> {
const url = new URL("management/instances", this.baseUrl); const url = new URL("management/instances", this.baseUrl);
const resp = await axios.get(url.href, { const resp = await this.httpClient.fetch(url.href, {
headers: this.makeAuthHeader(), headers: this.makeAuthHeader(),
}); });
return resp.data; return resp.json();
} }
async getInstanceFullDetails(instanceId: string): Promise<any> { async getInstanceFullDetails(instanceId: string): Promise<any> {
const url = new URL(`management/instances/${instanceId}`, this.baseUrl); const url = new URL(`management/instances/${instanceId}`, this.baseUrl);
try { try {
const resp = await axios.get(url.href, { const resp = await this.httpClient.fetch(url.href, {
headers: this.makeAuthHeader(), headers: this.makeAuthHeader(),
}); });
return resp.data; return resp.json();
} catch (e) { } catch (e) {
throw e; throw e;
} }
@ -1750,6 +1480,8 @@ export class MerchantApiClient {
/** /**
* FIXME: This should be deprecated in favor of MerchantApiClient * FIXME: This should be deprecated in favor of MerchantApiClient
*
* @deprecated use MerchantApiClient instead
*/ */
export namespace MerchantPrivateApi { export namespace MerchantPrivateApi {
export async function createOrder( export async function createOrder(
@ -1760,10 +1492,15 @@ export namespace MerchantPrivateApi {
): Promise<MerchantPostOrderResponse> { ): Promise<MerchantPostOrderResponse> {
const baseUrl = merchantService.makeInstanceBaseUrl(instanceName); const baseUrl = merchantService.makeInstanceBaseUrl(instanceName);
let url = new URL("private/orders", baseUrl); let url = new URL("private/orders", baseUrl);
const resp = await axios.post(url.href, req, { const resp = await harnessHttpLib.fetch(url.href, {
method: "POST",
body: req,
headers: withAuthorization as Record<string, string>, headers: withAuthorization as Record<string, string>,
}); });
return codecForMerchantPostOrderResponse().decode(resp.data); return readSuccessResponseJsonOrThrow(
resp,
codecForMerchantPostOrderResponse(),
);
} }
export async function createTemplate( export async function createTemplate(
@ -1774,7 +1511,9 @@ export namespace MerchantPrivateApi {
) { ) {
const baseUrl = merchantService.makeInstanceBaseUrl(instanceName); const baseUrl = merchantService.makeInstanceBaseUrl(instanceName);
let url = new URL("private/templates", baseUrl); let url = new URL("private/templates", baseUrl);
const resp = await axios.post(url.href, req, { const resp = await harnessHttpLib.fetch(url.href, {
method: "POST",
body: req,
headers: withAuthorization as Record<string, string>, headers: withAuthorization as Record<string, string>,
}); });
if (resp.status !== 204) { if (resp.status !== 204) {
@ -1794,10 +1533,13 @@ export namespace MerchantPrivateApi {
if (query.sessionId) { if (query.sessionId) {
reqUrl.searchParams.set("session_id", query.sessionId); reqUrl.searchParams.set("session_id", query.sessionId);
} }
const resp = await axios.get(reqUrl.href, { const resp = await harnessHttpLib.fetch(reqUrl.href, {
headers: withAuthorization as Record<string, string>, headers: withAuthorization as Record<string, string>,
}); });
return codecForMerchantOrderPrivateStatusResponse().decode(resp.data); return readSuccessResponseJsonOrThrow(
resp,
codecForMerchantOrderPrivateStatusResponse(),
);
} }
export async function giveRefund( export async function giveRefund(
@ -1813,12 +1555,16 @@ export namespace MerchantPrivateApi {
`private/orders/${r.orderId}/refund`, `private/orders/${r.orderId}/refund`,
merchantService.makeInstanceBaseUrl(r.instance), merchantService.makeInstanceBaseUrl(r.instance),
); );
const resp = await axios.post(reqUrl.href, { const resp = await harnessHttpLib.fetch(reqUrl.href, {
refund: r.amount, method: "POST",
reason: r.justification, body: {
refund: r.amount,
reason: r.justification,
},
}); });
const respBody = await resp.json();
return { return {
talerRefundUri: resp.data.taler_refund_uri, talerRefundUri: respBody.taler_refund_uri,
}; };
} }
@ -1830,9 +1576,9 @@ export namespace MerchantPrivateApi {
`private/reserves`, `private/reserves`,
merchantService.makeInstanceBaseUrl(instance), merchantService.makeInstanceBaseUrl(instance),
); );
const resp = await axios.get(reqUrl.href); const resp = await harnessHttpLib.fetch(reqUrl.href);
// FIXME: validate // FIXME: validate
return resp.data; return resp.json();
} }
export async function giveTip( export async function giveTip(
@ -1844,9 +1590,12 @@ export namespace MerchantPrivateApi {
`private/tips`, `private/tips`,
merchantService.makeInstanceBaseUrl(instance), merchantService.makeInstanceBaseUrl(instance),
); );
const resp = await axios.post(reqUrl.href, req); const resp = await harnessHttpLib.fetch(reqUrl.href, {
method: "POST",
body: req,
});
// FIXME: validate // FIXME: validate
return resp.data; return resp.json();
} }
} }
@ -2052,7 +1801,12 @@ export class MerchantService implements MerchantServiceInterface {
instanceConfig.defaultPayDelay ?? instanceConfig.defaultPayDelay ??
Duration.toTalerProtocolDuration(Duration.getForever()), Duration.toTalerProtocolDuration(Duration.getForever()),
}; };
await axios.post(url, body); const httpLib = createPlatformHttpLib({
allowHttp: true,
enableThrottling: false,
});
const resp = await httpLib.fetch(url, { method: "POST", body });
await expectSuccessResponseOrThrow(resp);
} }
makeInstanceBaseUrl(instanceName?: string): string { makeInstanceBaseUrl(instanceName?: string): string {

View File

@ -6,8 +6,21 @@
*/ */
import { URL } from "@gnu-taler/taler-util"; import { URL } from "@gnu-taler/taler-util";
import axiosImp from "axios"; import {
const axios = axiosImp.default; createPlatformHttpLib,
makeBasicAuthHeader,
} from "@gnu-taler/taler-util/http";
import {
LibeufinNexusTransactions,
LibeufinSandboxAdminBankAccountBalance,
NexusBankConnections,
NexusFacadeListResponse,
NexusGetPermissionsResponse,
NexusNewTransactionsInfo,
NexusTask,
NexusTaskCollection,
NexusUserResponse,
} from "./libeufin.js";
export interface LibeufinSandboxServiceInterface { export interface LibeufinSandboxServiceInterface {
baseUrl: string; baseUrl: string;
@ -163,30 +176,13 @@ export interface LibeufinSandboxAddIncomingRequest {
direction: string; direction: string;
} }
const libeufinHttpLib = createPlatformHttpLib();
/** /**
* APIs spread across Legacy and Access, it is therefore * APIs spread across Legacy and Access, it is therefore
* the "base URL" relative to which API every call addresses. * the "base URL" relative to which API every call addresses.
*/ */
export namespace LibeufinSandboxApi { export namespace LibeufinSandboxApi {
// Need Access API base URL.
export async function demobankAccountInfo(
username: string,
password: string,
libeufinSandboxService: LibeufinSandboxServiceInterface,
accountLabel: string,
) {
let url = new URL(
`accounts/${accountLabel}`,
libeufinSandboxService.baseUrl,
);
return await axios.get(url.href, {
auth: {
username: username,
password: password,
},
});
}
// Creates one bank account via the Access API. // Creates one bank account via the Access API.
// Need the /demobanks/$id/access-api as the base URL // Need the /demobanks/$id/access-api as the base URL
export async function createDemobankAccount( export async function createDemobankAccount(
@ -194,12 +190,15 @@ export namespace LibeufinSandboxApi {
password: string, password: string,
libeufinSandboxService: LibeufinSandboxServiceInterface, libeufinSandboxService: LibeufinSandboxServiceInterface,
iban: string | null = null, iban: string | null = null,
) { ): Promise<void> {
let url = new URL("testing/register", libeufinSandboxService.baseUrl); let url = new URL("testing/register", libeufinSandboxService.baseUrl);
await axios.post(url.href, { await libeufinHttpLib.fetch(url.href, {
username: username, method: "POST",
password: password, body: {
iban: iban, username: username,
password: password,
iban: iban,
},
}); });
} }
// Need /demobanks/$id as the base URL // Need /demobanks/$id as the base URL
@ -209,75 +208,57 @@ export namespace LibeufinSandboxApi {
libeufinSandboxService: LibeufinSandboxServiceInterface, libeufinSandboxService: LibeufinSandboxServiceInterface,
username: string = "admin", username: string = "admin",
password: string = "secret", password: string = "secret",
) { ): Promise<void> {
// baseUrl should already be pointed to one demobank. // baseUrl should already be pointed to one demobank.
let url = new URL("ebics/subscribers", libeufinSandboxService.baseUrl); let url = new URL("ebics/subscribers", libeufinSandboxService.baseUrl);
await axios.post( await libeufinHttpLib.fetch(url.href, {
url.href, method: "POST",
{ body: {
userID: req.userID, userID: req.userID,
hostID: req.hostID, hostID: req.hostID,
partnerID: req.partnerID, partnerID: req.partnerID,
demobankAccountLabel: demobankAccountLabel, demobankAccountLabel: demobankAccountLabel,
}, },
{ });
auth: {
username: "admin",
password: "secret",
},
},
);
} }
export async function rotateKeys( export async function rotateKeys(
libeufinSandboxService: LibeufinSandboxServiceInterface, libeufinSandboxService: LibeufinSandboxServiceInterface,
hostID: string, hostID: string,
) { ): Promise<void> {
const baseUrl = libeufinSandboxService.baseUrl; const baseUrl = libeufinSandboxService.baseUrl;
let url = new URL(`admin/ebics/hosts/${hostID}/rotate-keys`, baseUrl); let url = new URL(`admin/ebics/hosts/${hostID}/rotate-keys`, baseUrl);
await axios.post( await libeufinHttpLib.fetch(url.href, {
url.href, method: "POST",
{}, body: {},
{ });
auth: {
username: "admin",
password: "secret",
},
},
);
} }
export async function createEbicsHost( export async function createEbicsHost(
libeufinSandboxService: LibeufinSandboxServiceInterface, libeufinSandboxService: LibeufinSandboxServiceInterface,
hostID: string, hostID: string,
) { ): Promise<void> {
const baseUrl = libeufinSandboxService.baseUrl; const baseUrl = libeufinSandboxService.baseUrl;
let url = new URL("admin/ebics/hosts", baseUrl); let url = new URL("admin/ebics/hosts", baseUrl);
await axios.post( await libeufinHttpLib.fetch(url.href, {
url.href, method: "POST",
{ body: {
hostID, hostID,
ebicsVersion: "2.5", ebicsVersion: "2.5",
}, },
{ headers: { Authorization: makeBasicAuthHeader("admin", "secret") },
auth: { });
username: "admin",
password: "secret",
},
},
);
} }
export async function createBankAccount( export async function createBankAccount(
libeufinSandboxService: LibeufinSandboxServiceInterface, libeufinSandboxService: LibeufinSandboxServiceInterface,
req: BankAccountInfo, req: BankAccountInfo,
) { ): Promise<void> {
const baseUrl = libeufinSandboxService.baseUrl; const baseUrl = libeufinSandboxService.baseUrl;
let url = new URL(`admin/bank-accounts/${req.label}`, baseUrl); let url = new URL(`admin/bank-accounts/${req.label}`, baseUrl);
await axios.post(url.href, req, { await libeufinHttpLib.fetch(url.href, {
auth: { method: "POST",
username: "admin", body: req,
password: "secret", headers: { Authorization: makeBasicAuthHeader("admin", "secret") },
},
}); });
} }
@ -288,14 +269,13 @@ export namespace LibeufinSandboxApi {
export async function createEbicsSubscriber( export async function createEbicsSubscriber(
libeufinSandboxService: LibeufinSandboxServiceInterface, libeufinSandboxService: LibeufinSandboxServiceInterface,
req: CreateEbicsSubscriberRequest, req: CreateEbicsSubscriberRequest,
) { ): Promise<void> {
const baseUrl = libeufinSandboxService.baseUrl; const baseUrl = libeufinSandboxService.baseUrl;
let url = new URL("admin/ebics/subscribers", baseUrl); let url = new URL("admin/ebics/subscribers", baseUrl);
await axios.post(url.href, req, { await libeufinHttpLib.fetch(url.href, {
auth: { method: "POST",
username: "admin", body: req,
password: "secret", headers: { Authorization: makeBasicAuthHeader("admin", "secret") },
},
}); });
} }
@ -306,14 +286,13 @@ export namespace LibeufinSandboxApi {
export async function createEbicsBankAccount( export async function createEbicsBankAccount(
libeufinSandboxService: LibeufinSandboxServiceInterface, libeufinSandboxService: LibeufinSandboxServiceInterface,
req: CreateEbicsBankAccountRequest, req: CreateEbicsBankAccountRequest,
) { ): Promise<void> {
const baseUrl = libeufinSandboxService.baseUrl; const baseUrl = libeufinSandboxService.baseUrl;
let url = new URL("admin/ebics/bank-accounts", baseUrl); let url = new URL("admin/ebics/bank-accounts", baseUrl);
await axios.post(url.href, req, { await libeufinHttpLib.fetch(url.href, {
auth: { method: "POST",
username: "admin", body: req,
password: "secret", headers: { Authorization: makeBasicAuthHeader("admin", "secret") },
},
}); });
} }
@ -321,17 +300,16 @@ export namespace LibeufinSandboxApi {
libeufinSandboxService: LibeufinSandboxServiceInterface, libeufinSandboxService: LibeufinSandboxServiceInterface,
accountLabel: string, accountLabel: string,
req: SimulateIncomingTransactionRequest, req: SimulateIncomingTransactionRequest,
) { ): Promise<void> {
const baseUrl = libeufinSandboxService.baseUrl; const baseUrl = libeufinSandboxService.baseUrl;
let url = new URL( let url = new URL(
`admin/bank-accounts/${accountLabel}/simulate-incoming-transaction`, `admin/bank-accounts/${accountLabel}/simulate-incoming-transaction`,
baseUrl, baseUrl,
); );
await axios.post(url.href, req, { await libeufinHttpLib.fetch(url.href, {
auth: { method: "POST",
username: "admin", body: req,
password: "secret", headers: { Authorization: makeBasicAuthHeader("admin", "secret") },
},
}); });
} }
@ -344,13 +322,10 @@ export namespace LibeufinSandboxApi {
`admin/bank-accounts/${accountLabel}/transactions`, `admin/bank-accounts/${accountLabel}/transactions`,
baseUrl, baseUrl,
); );
const res = await axios.get(url.href, { const res = await libeufinHttpLib.fetch(url.href, {
auth: { headers: { Authorization: makeBasicAuthHeader("admin", "secret") },
username: "admin",
password: "secret",
},
}); });
return res.data as SandboxAccountTransactions; return (await res.json()) as SandboxAccountTransactions;
} }
export async function getCamt053( export async function getCamt053(
@ -359,61 +334,50 @@ export namespace LibeufinSandboxApi {
): Promise<any> { ): Promise<any> {
const baseUrl = libeufinSandboxService.baseUrl; const baseUrl = libeufinSandboxService.baseUrl;
let url = new URL("admin/payments/camt", baseUrl); let url = new URL("admin/payments/camt", baseUrl);
return await axios.post( return await libeufinHttpLib.fetch(url.href, {
url.href, method: "POST",
{ headers: { Authorization: makeBasicAuthHeader("admin", "secret") },
body: {
bankaccount: accountLabel, bankaccount: accountLabel,
type: 53, type: 53,
}, },
{ });
auth: {
username: "admin",
password: "secret",
},
},
);
} }
export async function getAccountInfoWithBalance( export async function getAccountInfoWithBalance(
libeufinSandboxService: LibeufinSandboxServiceInterface, libeufinSandboxService: LibeufinSandboxServiceInterface,
accountLabel: string, accountLabel: string,
): Promise<any> { ): Promise<LibeufinSandboxAdminBankAccountBalance> {
const baseUrl = libeufinSandboxService.baseUrl; const baseUrl = libeufinSandboxService.baseUrl;
let url = new URL(`admin/bank-accounts/${accountLabel}`, baseUrl); let url = new URL(`admin/bank-accounts/${accountLabel}`, baseUrl);
return await axios.get(url.href, { const res = await libeufinHttpLib.fetch(url.href, {
auth: { headers: { Authorization: makeBasicAuthHeader("admin", "secret") },
username: "admin",
password: "secret",
},
}); });
return res.json();
} }
} }
export namespace LibeufinNexusApi { export namespace LibeufinNexusApi {
export async function getAllConnections( export async function getAllConnections(
nexus: LibeufinNexusServiceInterface, nexus: LibeufinNexusServiceInterface,
): Promise<any> { ): Promise<NexusBankConnections> {
let url = new URL("bank-connections", nexus.baseUrl); let url = new URL("bank-connections", nexus.baseUrl);
const res = await axios.get(url.href, { const res = await libeufinHttpLib.fetch(url.href, {
auth: { headers: { Authorization: makeBasicAuthHeader("admin", "secret") },
username: "admin",
password: "test",
},
}); });
return res; return res.json();
} }
export async function deleteBankConnection( export async function deleteBankConnection(
libeufinNexusService: LibeufinNexusServiceInterface, libeufinNexusService: LibeufinNexusServiceInterface,
req: DeleteBankConnectionRequest, req: DeleteBankConnectionRequest,
): Promise<any> { ): Promise<void> {
const baseUrl = libeufinNexusService.baseUrl; const baseUrl = libeufinNexusService.baseUrl;
let url = new URL("bank-connections/delete-connection", baseUrl); let url = new URL("bank-connections/delete-connection", baseUrl);
return await axios.post(url.href, req, { await libeufinHttpLib.fetch(url.href, {
auth: { method: "POST",
username: "admin", headers: { Authorization: makeBasicAuthHeader("admin", "secret") },
password: "test", body: req,
},
}); });
} }
@ -423,9 +387,10 @@ export namespace LibeufinNexusApi {
): Promise<void> { ): Promise<void> {
const baseUrl = libeufinNexusService.baseUrl; const baseUrl = libeufinNexusService.baseUrl;
let url = new URL("bank-connections", baseUrl); let url = new URL("bank-connections", baseUrl);
await axios.post( await libeufinHttpLib.fetch(url.href, {
url.href, method: "POST",
{ headers: { Authorization: makeBasicAuthHeader("admin", "secret") },
body: {
source: "new", source: "new",
type: "ebics", type: "ebics",
name: req.name, name: req.name,
@ -437,13 +402,7 @@ export namespace LibeufinNexusApi {
systemID: req.systemID, systemID: req.systemID,
}, },
}, },
{ });
auth: {
username: "admin",
password: "test",
},
},
);
} }
export async function getBankAccount( export async function getBankAccount(
@ -452,12 +411,10 @@ export namespace LibeufinNexusApi {
): Promise<any> { ): Promise<any> {
const baseUrl = libeufinNexusService.baseUrl; const baseUrl = libeufinNexusService.baseUrl;
let url = new URL(`bank-accounts/${accountName}`, baseUrl); let url = new URL(`bank-accounts/${accountName}`, baseUrl);
return await axios.get(url.href, { const resp = await libeufinHttpLib.fetch(url.href, {
auth: { headers: { Authorization: makeBasicAuthHeader("admin", "secret") },
username: "admin",
password: "test",
},
}); });
return resp.json();
} }
export async function submitInitiatedPayment( export async function submitInitiatedPayment(
@ -470,16 +427,11 @@ export namespace LibeufinNexusApi {
`bank-accounts/${accountName}/payment-initiations/${paymentId}/submit`, `bank-accounts/${accountName}/payment-initiations/${paymentId}/submit`,
baseUrl, baseUrl,
); );
await axios.post( await libeufinHttpLib.fetch(url.href, {
url.href, method: "POST",
{}, headers: { Authorization: makeBasicAuthHeader("admin", "secret") },
{ body: {},
auth: { });
username: "admin",
password: "test",
},
},
);
} }
export async function fetchAccounts( export async function fetchAccounts(
@ -491,16 +443,11 @@ export namespace LibeufinNexusApi {
`bank-connections/${connectionName}/fetch-accounts`, `bank-connections/${connectionName}/fetch-accounts`,
baseUrl, baseUrl,
); );
await axios.post( await libeufinHttpLib.fetch(url.href, {
url.href, method: "POST",
{}, headers: { Authorization: makeBasicAuthHeader("admin", "secret") },
{ body: {},
auth: { });
username: "admin",
password: "test",
},
},
);
} }
export async function importConnectionAccount( export async function importConnectionAccount(
@ -514,37 +461,27 @@ export namespace LibeufinNexusApi {
`bank-connections/${connectionName}/import-account`, `bank-connections/${connectionName}/import-account`,
baseUrl, baseUrl,
); );
await axios.post( await libeufinHttpLib.fetch(url.href, {
url.href, method: "POST",
{ headers: { Authorization: makeBasicAuthHeader("admin", "secret") },
body: {
offeredAccountId, offeredAccountId,
nexusBankAccountId, nexusBankAccountId,
}, },
{ });
auth: {
username: "admin",
password: "test",
},
},
);
} }
export async function connectBankConnection( export async function connectBankConnection(
libeufinNexusService: LibeufinNexusServiceInterface, libeufinNexusService: LibeufinNexusServiceInterface,
connectionName: string, connectionName: string,
) { ): Promise<void> {
const baseUrl = libeufinNexusService.baseUrl; const baseUrl = libeufinNexusService.baseUrl;
let url = new URL(`bank-connections/${connectionName}/connect`, baseUrl); let url = new URL(`bank-connections/${connectionName}/connect`, baseUrl);
await axios.post( await libeufinHttpLib.fetch(url.href, {
url.href, method: "POST",
{}, headers: { Authorization: makeBasicAuthHeader("admin", "secret") },
{ body: {},
auth: { });
username: "admin",
password: "test",
},
},
);
} }
export async function getPaymentInitiations( export async function getPaymentInitiations(
@ -558,43 +495,33 @@ export namespace LibeufinNexusApi {
`/bank-accounts/${accountName}/payment-initiations`, `/bank-accounts/${accountName}/payment-initiations`,
baseUrl, baseUrl,
); );
let response = await axios.get(url.href, { let response = await libeufinHttpLib.fetch(url.href, {
auth: { headers: { Authorization: makeBasicAuthHeader("admin", "secret") },
username: username,
password: password,
},
}); });
const respJson = await response.json();
console.log( console.log(
`Payment initiations of: ${accountName}`, `Payment initiations of: ${accountName}`,
JSON.stringify(response.data, null, 2), JSON.stringify(respJson, null, 2),
); );
} }
export async function getConfig(
libeufinNexusService: LibeufinNexusServiceInterface,
): Promise<void> {
const baseUrl = libeufinNexusService.baseUrl;
let url = new URL(`/config`, baseUrl);
let response = await axios.get(url.href);
}
// Uses the Anastasis API to get a list of transactions. // Uses the Anastasis API to get a list of transactions.
export async function getAnastasisTransactions( export async function getAnastasisTransactions(
libeufinNexusService: LibeufinNexusServiceInterface, libeufinNexusService: LibeufinNexusServiceInterface,
anastasisBaseUrl: string, anastasisBaseUrl: string,
// FIXME: Nail down type!
params: {}, // of the request: {delta: 5, ..} params: {}, // of the request: {delta: 5, ..}
username: string = "admin", username: string = "admin",
password: string = "test", password: string = "test",
): Promise<any> { ): Promise<any> {
let url = new URL("history/incoming", anastasisBaseUrl); let url = new URL("history/incoming", anastasisBaseUrl);
let response = await axios.get(url.href, { for (const [k, v] of Object.entries(params)) {
params: params, url.searchParams.set(k, String(v));
auth: { }
username: username, let response = await libeufinHttpLib.fetch(url.href, {
password: password, headers: { Authorization: makeBasicAuthHeader("admin", "secret") },
},
}); });
return response; return response.json();
} }
// FIXME: this function should return some structured // FIXME: this function should return some structured
@ -604,16 +531,13 @@ export namespace LibeufinNexusApi {
accountName: string, accountName: string,
username: string = "admin", username: string = "admin",
password: string = "test", password: string = "test",
): Promise<any> { ): Promise<LibeufinNexusTransactions> {
const baseUrl = libeufinNexusService.baseUrl; const baseUrl = libeufinNexusService.baseUrl;
let url = new URL(`/bank-accounts/${accountName}/transactions`, baseUrl); let url = new URL(`/bank-accounts/${accountName}/transactions`, baseUrl);
let response = await axios.get(url.href, { let response = await libeufinHttpLib.fetch(url.href, {
auth: { headers: { Authorization: makeBasicAuthHeader("admin", "secret") },
username: username,
password: password,
},
}); });
return response; return response.json();
} }
export async function fetchTransactions( export async function fetchTransactions(
@ -623,25 +547,21 @@ export namespace LibeufinNexusApi {
level: string = "report", level: string = "report",
username: string = "admin", username: string = "admin",
password: string = "test", password: string = "test",
): Promise<any> { ): Promise<NexusNewTransactionsInfo> {
const baseUrl = libeufinNexusService.baseUrl; const baseUrl = libeufinNexusService.baseUrl;
let url = new URL( let url = new URL(
`/bank-accounts/${accountName}/fetch-transactions`, `/bank-accounts/${accountName}/fetch-transactions`,
baseUrl, baseUrl,
); );
return await axios.post( const resp = await libeufinHttpLib.fetch(url.href, {
url.href, method: "POST",
{ headers: { Authorization: makeBasicAuthHeader("admin", "secret") },
body: {
rangeType: rangeType, rangeType: rangeType,
level: level, level: level,
}, },
{ });
auth: { return resp.json();
username: username,
password: password,
},
},
);
} }
export async function changePassword( export async function changePassword(
@ -649,97 +569,109 @@ export namespace LibeufinNexusApi {
username: string, username: string,
req: UpdateNexusUserRequest, req: UpdateNexusUserRequest,
auth: NexusAuth, auth: NexusAuth,
) { ): Promise<void> {
const baseUrl = libeufinNexusService.baseUrl; const baseUrl = libeufinNexusService.baseUrl;
let url = new URL(`/users/${username}/password`, baseUrl); let url = new URL(`/users/${username}/password`, baseUrl);
await axios.post(url.href, req, auth); await libeufinHttpLib.fetch(url.href, {
method: "POST",
headers: { Authorization: makeBasicAuthHeader("admin", "secret") },
body: req,
});
} }
export async function getUser( export async function getUser(
libeufinNexusService: LibeufinNexusServiceInterface, libeufinNexusService: LibeufinNexusServiceInterface,
auth: NexusAuth, auth: NexusAuth,
): Promise<any> { ): Promise<NexusUserResponse> {
const baseUrl = libeufinNexusService.baseUrl; const baseUrl = libeufinNexusService.baseUrl;
let url = new URL(`/user`, baseUrl); let url = new URL(`/user`, baseUrl);
return await axios.get(url.href, auth); const resp = await libeufinHttpLib.fetch(url.href, {
headers: { Authorization: makeBasicAuthHeader("admin", "secret") },
});
return resp.json();
} }
export async function createUser( export async function createUser(
libeufinNexusService: LibeufinNexusServiceInterface, libeufinNexusService: LibeufinNexusServiceInterface,
req: CreateNexusUserRequest, req: CreateNexusUserRequest,
) { ): Promise<void> {
const baseUrl = libeufinNexusService.baseUrl; const baseUrl = libeufinNexusService.baseUrl;
let url = new URL(`/users`, baseUrl); let url = new URL(`/users`, baseUrl);
await axios.post(url.href, req, { await libeufinHttpLib.fetch(url.href, {
auth: { method: "POST",
username: "admin", headers: { Authorization: makeBasicAuthHeader("admin", "secret") },
password: "test", body: req,
},
}); });
} }
export async function getAllPermissions( export async function getAllPermissions(
libeufinNexusService: LibeufinNexusServiceInterface, libeufinNexusService: LibeufinNexusServiceInterface,
): Promise<any> { ): Promise<NexusGetPermissionsResponse> {
const baseUrl = libeufinNexusService.baseUrl; const baseUrl = libeufinNexusService.baseUrl;
let url = new URL(`/permissions`, baseUrl); let url = new URL(`/permissions`, baseUrl);
return await axios.get(url.href, { const resp = await libeufinHttpLib.fetch(url.href, {
auth: { headers: { Authorization: makeBasicAuthHeader("admin", "secret") },
username: "admin",
password: "test",
},
}); });
return resp.json();
} }
export async function postPermission( export async function postPermission(
libeufinNexusService: LibeufinNexusServiceInterface, libeufinNexusService: LibeufinNexusServiceInterface,
req: PostNexusPermissionRequest, req: PostNexusPermissionRequest,
) { ): Promise<void> {
const baseUrl = libeufinNexusService.baseUrl; const baseUrl = libeufinNexusService.baseUrl;
let url = new URL(`/permissions`, baseUrl); let url = new URL(`/permissions`, baseUrl);
await axios.post(url.href, req, { await libeufinHttpLib.fetch(url.href, {
auth: { method: "POST",
username: "admin", headers: { Authorization: makeBasicAuthHeader("admin", "secret") },
password: "test", body: req,
},
}); });
} }
export async function getTasks( export async function getAllTasks(
libeufinNexusService: LibeufinNexusServiceInterface,
bankAccountName: string,
): Promise<NexusTaskCollection> {
const baseUrl = libeufinNexusService.baseUrl;
let url = new URL(`/bank-accounts/${bankAccountName}/schedule`, baseUrl);
const resp = await libeufinHttpLib.fetch(url.href, {
headers: { Authorization: makeBasicAuthHeader("admin", "secret") },
});
return resp.json();
}
export async function getTask(
libeufinNexusService: LibeufinNexusServiceInterface, libeufinNexusService: LibeufinNexusServiceInterface,
bankAccountName: string, bankAccountName: string,
// When void, the request returns the list of all the // When void, the request returns the list of all the
// tasks under this bank account. // tasks under this bank account.
taskName: string | void, taskName: string,
): Promise<any> { ): Promise<NexusTask> {
const baseUrl = libeufinNexusService.baseUrl; const baseUrl = libeufinNexusService.baseUrl;
let url = new URL(`/bank-accounts/${bankAccountName}/schedule`, baseUrl); let url = new URL(
`/bank-accounts/${bankAccountName}/schedule/${taskName}`,
baseUrl,
);
if (taskName) url = new URL(taskName, `${url.href}/`); if (taskName) url = new URL(taskName, `${url.href}/`);
const resp = await libeufinHttpLib.fetch(url.href, {
// It's caller's responsibility to interpret the response. headers: { Authorization: makeBasicAuthHeader("admin", "secret") },
return await axios.get(url.href, {
auth: {
username: "admin",
password: "test",
},
}); });
return resp.json();
} }
export async function deleteTask( export async function deleteTask(
libeufinNexusService: LibeufinNexusServiceInterface, libeufinNexusService: LibeufinNexusServiceInterface,
bankAccountName: string, bankAccountName: string,
taskName: string, taskName: string,
) { ): Promise<void> {
const baseUrl = libeufinNexusService.baseUrl; const baseUrl = libeufinNexusService.baseUrl;
let url = new URL( let url = new URL(
`/bank-accounts/${bankAccountName}/schedule/${taskName}`, `/bank-accounts/${bankAccountName}/schedule/${taskName}`,
baseUrl, baseUrl,
); );
await axios.delete(url.href, { await libeufinHttpLib.fetch(url.href, {
auth: { method: "DELETE",
username: "admin", headers: { Authorization: makeBasicAuthHeader("admin", "secret") },
password: "test",
},
}); });
} }
@ -747,53 +679,50 @@ export namespace LibeufinNexusApi {
libeufinNexusService: LibeufinNexusServiceInterface, libeufinNexusService: LibeufinNexusServiceInterface,
bankAccountName: string, bankAccountName: string,
req: PostNexusTaskRequest, req: PostNexusTaskRequest,
): Promise<any> { ): Promise<void> {
const baseUrl = libeufinNexusService.baseUrl; const baseUrl = libeufinNexusService.baseUrl;
let url = new URL(`/bank-accounts/${bankAccountName}/schedule`, baseUrl); let url = new URL(`/bank-accounts/${bankAccountName}/schedule`, baseUrl);
return await axios.post(url.href, req, { await libeufinHttpLib.fetch(url.href, {
auth: { method: "POST",
username: "admin", headers: { Authorization: makeBasicAuthHeader("admin", "secret") },
password: "test", body: req,
},
}); });
} }
export async function deleteFacade( export async function deleteFacade(
libeufinNexusService: LibeufinNexusServiceInterface, libeufinNexusService: LibeufinNexusServiceInterface,
facadeName: string, facadeName: string,
): Promise<any> { ): Promise<void> {
const baseUrl = libeufinNexusService.baseUrl; const baseUrl = libeufinNexusService.baseUrl;
let url = new URL(`facades/${facadeName}`, baseUrl); let url = new URL(`facades/${facadeName}`, baseUrl);
return await axios.delete(url.href, { await libeufinHttpLib.fetch(url.href, {
auth: { method: "DELETE",
username: "admin", headers: { Authorization: makeBasicAuthHeader("admin", "secret") },
password: "test",
},
}); });
} }
export async function getAllFacades( export async function getAllFacades(
libeufinNexusService: LibeufinNexusServiceInterface, libeufinNexusService: LibeufinNexusServiceInterface,
): Promise<any> { ): Promise<NexusFacadeListResponse> {
const baseUrl = libeufinNexusService.baseUrl; const baseUrl = libeufinNexusService.baseUrl;
let url = new URL("facades", baseUrl); let url = new URL("facades", baseUrl);
return await axios.get(url.href, { const resp = await libeufinHttpLib.fetch(url.href, {
auth: { headers: { Authorization: makeBasicAuthHeader("admin", "secret") },
username: "admin",
password: "test",
},
}); });
// FIXME: Just return validated, typed response here!
return resp.json();
} }
export async function createAnastasisFacade( export async function createAnastasisFacade(
libeufinNexusService: LibeufinNexusServiceInterface, libeufinNexusService: LibeufinNexusServiceInterface,
req: CreateAnastasisFacadeRequest, req: CreateAnastasisFacadeRequest,
) { ): Promise<void> {
const baseUrl = libeufinNexusService.baseUrl; const baseUrl = libeufinNexusService.baseUrl;
let url = new URL("facades", baseUrl); let url = new URL("facades", baseUrl);
await axios.post( await libeufinHttpLib.fetch(url.href, {
url.href, method: "POST",
{ headers: { Authorization: makeBasicAuthHeader("admin", "secret") },
body: {
name: req.name, name: req.name,
type: "anastasis", type: "anastasis",
config: { config: {
@ -803,24 +732,19 @@ export namespace LibeufinNexusApi {
reserveTransferLevel: req.reserveTransferLevel, reserveTransferLevel: req.reserveTransferLevel,
}, },
}, },
{ });
auth: {
username: "admin",
password: "test",
},
},
);
} }
export async function createTwgFacade( export async function createTwgFacade(
libeufinNexusService: LibeufinNexusServiceInterface, libeufinNexusService: LibeufinNexusServiceInterface,
req: CreateTalerWireGatewayFacadeRequest, req: CreateTalerWireGatewayFacadeRequest,
) { ): Promise<void> {
const baseUrl = libeufinNexusService.baseUrl; const baseUrl = libeufinNexusService.baseUrl;
let url = new URL("facades", baseUrl); let url = new URL("facades", baseUrl);
await axios.post( await libeufinHttpLib.fetch(url.href, {
url.href, method: "POST",
{ headers: { Authorization: makeBasicAuthHeader("admin", "secret") },
body: {
name: req.name, name: req.name,
type: "taler-wire-gateway", type: "taler-wire-gateway",
config: { config: {
@ -830,33 +754,22 @@ export namespace LibeufinNexusApi {
reserveTransferLevel: req.reserveTransferLevel, reserveTransferLevel: req.reserveTransferLevel,
}, },
}, },
{ });
auth: {
username: "admin",
password: "test",
},
},
);
} }
export async function submitAllPaymentInitiations( export async function submitAllPaymentInitiations(
libeufinNexusService: LibeufinNexusServiceInterface, libeufinNexusService: LibeufinNexusServiceInterface,
accountId: string, accountId: string,
) { ): Promise<void> {
const baseUrl = libeufinNexusService.baseUrl; const baseUrl = libeufinNexusService.baseUrl;
let url = new URL( let url = new URL(
`/bank-accounts/${accountId}/submit-all-payment-initiations`, `/bank-accounts/${accountId}/submit-all-payment-initiations`,
baseUrl, baseUrl,
); );
await axios.post( await libeufinHttpLib.fetch(url.href, {
url.href, method: "POST",
{}, headers: { Authorization: makeBasicAuthHeader("admin", "secret") },
{ body: {},
auth: { });
username: "admin",
password: "test",
},
},
);
} }
} }

View File

@ -26,39 +26,32 @@
/** /**
* Imports. * Imports.
*/ */
import axios from "axios"; import { AmountString, Logger } from "@gnu-taler/taler-util";
import { URL, Logger } from "@gnu-taler/taler-util";
import { import {
GlobalTestState,
DbInfo, DbInfo,
pingProc, GlobalTestState,
ProcessWrapper, ProcessWrapper,
getRandomIban,
pingProc,
runCommand, runCommand,
setupDb, setupDb,
sh, sh,
getRandomIban,
} from "../harness/harness.js"; } from "../harness/harness.js";
import { import {
LibeufinSandboxApi,
LibeufinNexusApi,
CreateEbicsBankAccountRequest,
LibeufinSandboxServiceInterface,
CreateTalerWireGatewayFacadeRequest,
SimulateIncomingTransactionRequest,
SandboxAccountTransactions,
DeleteBankConnectionRequest,
CreateEbicsBankConnectionRequest,
UpdateNexusUserRequest,
NexusAuth,
CreateAnastasisFacadeRequest, CreateAnastasisFacadeRequest,
PostNexusTaskRequest, CreateEbicsBankAccountRequest,
PostNexusPermissionRequest, CreateEbicsBankConnectionRequest,
CreateNexusUserRequest, CreateNexusUserRequest,
CreateTalerWireGatewayFacadeRequest,
LibeufinNexusApi,
LibeufinSandboxApi,
LibeufinSandboxServiceInterface,
PostNexusPermissionRequest,
} from "../harness/libeufin-apis.js"; } from "../harness/libeufin-apis.js";
const logger = new Logger("libeufin.ts"); const logger = new Logger("libeufin.ts");
export { LibeufinSandboxApi, LibeufinNexusApi }; export { LibeufinNexusApi, LibeufinSandboxApi };
export interface LibeufinServices { export interface LibeufinServices {
libeufinSandbox: LibeufinSandboxService; libeufinSandbox: LibeufinSandboxService;
@ -76,7 +69,7 @@ export interface LibeufinNexusConfig {
databaseJdbcUri: string; databaseJdbcUri: string;
} }
interface LibeufinNexusMoneyMovement { export interface LibeufinNexusMoneyMovement {
amount: string; amount: string;
creditDebitIndicator: string; creditDebitIndicator: string;
details: { details: {
@ -103,11 +96,11 @@ interface LibeufinNexusMoneyMovement {
}; };
} }
interface LibeufinNexusBatches { export interface LibeufinNexusBatches {
batchTransactions: Array<LibeufinNexusMoneyMovement>; batchTransactions: Array<LibeufinNexusMoneyMovement>;
} }
interface LibeufinNexusTransaction { export interface LibeufinNexusTransaction {
amount: string; amount: string;
creditDebitIndicator: string; creditDebitIndicator: string;
status: string; status: string;
@ -118,7 +111,7 @@ interface LibeufinNexusTransaction {
batches: Array<LibeufinNexusBatches>; batches: Array<LibeufinNexusBatches>;
} }
interface LibeufinNexusTransactions { export interface LibeufinNexusTransactions {
transactions: Array<LibeufinNexusTransaction>; transactions: Array<LibeufinNexusTransaction>;
} }
@ -182,6 +175,146 @@ export interface LibeufinPreparedPaymentDetails {
nexusBankAccountName: string; nexusBankAccountName: string;
} }
export interface NexusBankConnection {
// connection type. For example "ebics".
type: string;
// connection name as given by the user at
// the moment of creation.
name: string;
}
export interface NexusBankConnections {
bankConnections: NexusBankConnection[];
}
export interface FacadeShowInfo {
// Name of the facade, same as the "fcid" parameter.
name: string;
// Type of the facade.
// For example, "taler-wire-gateway".
type: string;
// Bas URL of the facade.
baseUrl: string;
// details depending on the facade type.
config: any;
}
export interface FetchParams {
// Because transactions are delivered by banks in "batches",
// then every batch can have different qualities. This value
// lets the request specify which type of batch ought to be
// returned. Currently, the following two type are supported:
//
// 'report': typically includes only non booked transactions.
// 'statement': typically includes only booked transactions.
level: "report" | "statement" | "all";
// This type indicates the time range of the query.
// It allows the following values:
//
// 'latest': retrieves the last transactions from the bank.
// If there are older unread transactions, those will *not*
// be downloaded.
//
// 'all': retrieves all the transactions from the bank,
// until the oldest.
//
// 'previous-days': currently *not* implemented, it will allow
// the request to download transactions from
// today until N days before.
//
// 'since-last': retrieves all the transactions since the last
// time one was downloaded.
//
rangeType: "latest" | "all" | "previous-days" | "since-last";
}
export interface NexusTask {
// The resource being impacted by this operation.
// Typically a (Nexus) bank account being fetched
// or whose payments are submitted. In this cases,
// this value is the "bank-account" constant.
resourceType: string;
// Name of the resource. In case of "bank-account", that
// is the name under which the bank account was imported
// from the bank.
resourceId: string;
// Task name, equals 'taskId'
taskName: string;
// Values allowed are "fetch" or "submit".
taskType: string;
// FIXME: describe.
taskCronSpec: string;
// Only meaningful for "fetch" types.
taskParams: FetchParams;
// Timestamp in secons when the next iteration will run.
nextScheduledExecutionSec: number;
// Timestamp in seconds when the previous iteration ran.
prevScheduledExecutionSec: number;
}
export interface NexusNewTransactionsInfo {
// How many transactions are new to Nexus.
newTransactions: number;
// How many transactions got downloaded by the request.
// Note that a transaction can be downloaded multiple
// times but only counts as new once.
downloadedTransactions: number;
}
export interface NexusUserResponse {
// User name
username: string;
// Is this a super user?
superuser: boolean;
}
export interface NexusTaskShortInfo {
cronspec: string;
type: "fetch" | "submit";
params: FetchParams;
}
export interface NexusTaskCollection {
// This field can contain *multiple* objects of the type sampled below.
schedule: {
[taskName: string]: NexusTaskShortInfo;
};
}
export interface NexusFacadeListResponse {
facades: FacadeShowInfo[];
}
export interface LibeufinSandboxAdminBankAccountBalance {
// Balance in the $currency:$amount format.
balance: AmountString;
// IBAN of the bank account identified by $accountLabel
iban: string;
// BIC of the bank account identified by $accountLabel
bic: string;
// Mentions $accountLabel
label: string;
}
export interface LibeufinPermission {
subjectType: string;
subjectId: string;
resourceType: string;
resourceId: string;
permissionName: string;
}
export interface NexusGetPermissionsResponse {
permissions: LibeufinPermission[];
}
export class LibeufinSandboxService implements LibeufinSandboxServiceInterface { export class LibeufinSandboxService implements LibeufinSandboxServiceInterface {
static async create( static async create(
gc: GlobalTestState, gc: GlobalTestState,

View File

@ -191,12 +191,12 @@ configCli
const config = Configuration.load(); const config = Configuration.load();
let res; let res;
if (args.get.file) { if (args.get.file) {
res = config.getString(args.get.section, args.get.option);
} else {
res = config.getPath(args.get.section, args.get.option); res = config.getPath(args.get.section, args.get.option);
} else {
res = config.getString(args.get.section, args.get.option);
} }
if (res.isDefined()) { if (res.isDefined()) {
console.log(res.getValue()); console.log(res.required());
} else { } else {
console.warn("not found"); console.warn("not found");
process.exit(1); process.exit(1);

View File

@ -101,7 +101,7 @@ export async function runLibeufinApiBankaccountTest(t: GlobalTestState) {
nexus, nexus,
"local-mock", "local-mock",
); );
let el = findNexusPayment("mock subject", transactions.data); let el = findNexusPayment("mock subject", transactions);
t.assertTrue(el instanceof Object); t.assertTrue(el instanceof Object);
} }

View File

@ -45,12 +45,12 @@ export async function runLibeufinApiBankconnectionTest(t: GlobalTestState) {
}); });
let connections = await LibeufinNexusApi.getAllConnections(nexus); let connections = await LibeufinNexusApi.getAllConnections(nexus);
t.assertTrue(connections.data["bankConnections"].length == 1); t.assertTrue(connections.bankConnections.length == 1);
await LibeufinNexusApi.deleteBankConnection(nexus, { await LibeufinNexusApi.deleteBankConnection(nexus, {
bankConnectionId: "bankconnection-api-test-connection", bankConnectionId: "bankconnection-api-test-connection",
}); });
connections = await LibeufinNexusApi.getAllConnections(nexus); connections = await LibeufinNexusApi.getAllConnections(nexus);
t.assertTrue(connections.data["bankConnections"].length == 0); t.assertTrue(connections.bankConnections.length == 0);
} }
runLibeufinApiBankconnectionTest.suites = ["libeufin"]; runLibeufinApiBankconnectionTest.suites = ["libeufin"];

View File

@ -18,15 +18,16 @@
* Imports. * Imports.
*/ */
import { URL } from "@gnu-taler/taler-util"; import { URL } from "@gnu-taler/taler-util";
import axiosImp from "axios"; import { GlobalTestState, harnessHttpLib } from "../harness/harness.js";
import { GlobalTestState } from "../harness/harness.js";
import { import {
launchLibeufinServices, launchLibeufinServices,
NexusUserBundle, NexusUserBundle,
SandboxUserBundle, SandboxUserBundle,
} from "../harness/libeufin.js"; } from "../harness/libeufin.js";
import {
const axios = axiosImp.default; createPlatformHttpLib,
makeBasicAuthHeader,
} from "@gnu-taler/taler-util/http";
export async function runLibeufinApiFacadeBadRequestTest(t: GlobalTestState) { export async function runLibeufinApiFacadeBadRequestTest(t: GlobalTestState) {
/** /**
@ -50,21 +51,17 @@ export async function runLibeufinApiFacadeBadRequestTest(t: GlobalTestState) {
console.log("malformed facade"); console.log("malformed facade");
const baseUrl = libeufinServices.libeufinNexus.baseUrl; const baseUrl = libeufinServices.libeufinNexus.baseUrl;
let url = new URL("facades", baseUrl); let url = new URL("facades", baseUrl);
let resp = await axios.post( let resp = await harnessHttpLib.fetch(url.href, {
url.href, method: "POST",
{ body: {
name: "malformed-facade", name: "malformed-facade",
type: "taler-wire-gateway", type: "taler-wire-gateway",
config: {}, // malformation here. config: {}, // malformation here.
}, },
{ headers: {
auth: { Authorization: makeBasicAuthHeader("admin", "test"),
username: "admin",
password: "test",
},
validateStatus: () => true,
}, },
); });
t.assertTrue(resp.status == 400); t.assertTrue(resp.status == 400);
} }

View File

@ -51,20 +51,20 @@ export async function runLibeufinApiFacadeTest(t: GlobalTestState) {
libeufinServices.libeufinNexus, libeufinServices.libeufinNexus,
); );
// check that original facade shows up. // check that original facade shows up.
t.assertTrue(resp.data["facades"][0]["name"] == user01nexus.twgReq["name"]); t.assertTrue(resp.facades[0].name == user01nexus.twgReq["name"]);
const twgBaseUrl: string = resp.data["facades"][0]["baseUrl"]; const twgBaseUrl: string = resp.facades[0]["baseUrl"];
t.assertTrue(typeof twgBaseUrl === "string"); t.assertTrue(typeof twgBaseUrl === "string");
t.assertTrue(twgBaseUrl.startsWith("http://")); t.assertTrue(twgBaseUrl.startsWith("http://"));
t.assertTrue(twgBaseUrl.endsWith("/")); t.assertTrue(twgBaseUrl.endsWith("/"));
// delete it. // delete it.
resp = await LibeufinNexusApi.deleteFacade( await LibeufinNexusApi.deleteFacade(
libeufinServices.libeufinNexus, libeufinServices.libeufinNexus,
user01nexus.twgReq["name"], user01nexus.twgReq["name"],
); );
// check that no facades show up. resp = await LibeufinNexusApi.getAllFacades(libeufinServices.libeufinNexus);
t.assertTrue(!resp.data.hasOwnProperty("facades")); t.assertTrue(!resp.hasOwnProperty("facades"));
} }
runLibeufinApiFacadeTest.suites = ["libeufin"]; runLibeufinApiFacadeTest.suites = ["libeufin"];

View File

@ -46,7 +46,8 @@ export async function runLibeufinApiPermissionsTest(t: GlobalTestState) {
user01nexus.twgTransferPermission, user01nexus.twgTransferPermission,
); );
let transferPermission = await LibeufinNexusApi.getAllPermissions(nexus); let transferPermission = await LibeufinNexusApi.getAllPermissions(nexus);
let element = transferPermission.data["permissions"].pop(); let element = transferPermission["permissions"].pop();
t.assertTrue(!!element);
t.assertTrue( t.assertTrue(
element["permissionName"] == "facade.talerwiregateway.transfer" && element["permissionName"] == "facade.talerwiregateway.transfer" &&
element["subjectId"] == "username-01", element["subjectId"] == "username-01",
@ -58,7 +59,7 @@ export async function runLibeufinApiPermissionsTest(t: GlobalTestState) {
await LibeufinNexusApi.postPermission(nexus, denyTransfer); await LibeufinNexusApi.postPermission(nexus, denyTransfer);
transferPermission = await LibeufinNexusApi.getAllPermissions(nexus); transferPermission = await LibeufinNexusApi.getAllPermissions(nexus);
t.assertTrue(transferPermission.data["permissions"].length == 0); t.assertTrue(transferPermission["permissions"].length == 0);
} }
runLibeufinApiPermissionsTest.suites = ["libeufin"]; runLibeufinApiPermissionsTest.suites = ["libeufin"];

View File

@ -64,6 +64,6 @@ export async function runLibeufinApiSandboxTransactionsTest(
sandbox, sandbox,
"mock-account", "mock-account",
); );
t.assertAmountEquals(ret.data.balance, "EUR:2.1"); t.assertAmountEquals(ret.balance, "EUR:2.1");
} }
runLibeufinApiSandboxTransactionsTest.suites = ["libeufin"]; runLibeufinApiSandboxTransactionsTest.suites = ["libeufin"];

View File

@ -54,19 +54,19 @@ export async function runLibeufinApiSchedulingTest(t: GlobalTestState) {
rangeType: "all", rangeType: "all",
}, },
}); });
let resp = await LibeufinNexusApi.getTasks( let resp = await LibeufinNexusApi.getTask(
nexus, nexus,
user01nexus.localAccountName, user01nexus.localAccountName,
"test-task", "test-task",
); );
t.assertTrue(resp.data["taskName"] == "test-task"); t.assertTrue(resp.taskName == "test-task");
await LibeufinNexusApi.deleteTask( await LibeufinNexusApi.deleteTask(
nexus, nexus,
user01nexus.localAccountName, user01nexus.localAccountName,
"test-task", "test-task",
); );
try { try {
await LibeufinNexusApi.getTasks( await LibeufinNexusApi.getTask(
nexus, nexus,
user01nexus.localAccountName, user01nexus.localAccountName,
"test-task", "test-task",
@ -82,19 +82,19 @@ export async function runLibeufinApiSchedulingTest(t: GlobalTestState) {
type: "submit", type: "submit",
params: {}, params: {},
}); });
resp = await LibeufinNexusApi.getTasks( resp = await LibeufinNexusApi.getTask(
nexus, nexus,
user01nexus.localAccountName, user01nexus.localAccountName,
"test-task", "test-task",
); );
t.assertTrue(resp.data["taskName"] == "test-task"); t.assertTrue(resp.taskName == "test-task");
await LibeufinNexusApi.deleteTask( await LibeufinNexusApi.deleteTask(
nexus, nexus,
user01nexus.localAccountName, user01nexus.localAccountName,
"test-task", "test-task",
); );
try { try {
await LibeufinNexusApi.getTasks( await LibeufinNexusApi.getTask(
nexus, nexus,
user01nexus.localAccountName, user01nexus.localAccountName,
"test-task", "test-task",

View File

@ -56,8 +56,8 @@ export async function runLibeufinApiUsersTest(t: GlobalTestState) {
password: "got-changed", password: "got-changed",
}, },
}); });
console.log(resp.data); console.log(resp);
t.assertTrue(resp.data["username"] == "one" && !resp.data["superuser"]); t.assertTrue(resp["username"] == "one" && !resp["superuser"]);
} }
runLibeufinApiUsersTest.suites = ["libeufin"]; runLibeufinApiUsersTest.suites = ["libeufin"];

View File

@ -79,7 +79,7 @@ export async function runLibeufinC5xTest(t: GlobalTestState) {
libeufinServices.libeufinNexus, libeufinServices.libeufinNexus,
user01nexus.localAccountName, user01nexus.localAccountName,
); );
t.assertTrue(nexusTxs.data["transactions"].length == 0); t.assertTrue(nexusTxs["transactions"].length == 0);
// Addressing one payment to user 01 // Addressing one payment to user 01
await libeufinServices.libeufinSandbox.makeTransaction( await libeufinServices.libeufinSandbox.makeTransaction(
@ -95,8 +95,8 @@ export async function runLibeufinC5xTest(t: GlobalTestState) {
"all", // range "all", // range
"report", // C52 "report", // C52
); );
t.assertTrue(expectOne.data.newTransactions == 1); t.assertTrue(expectOne.newTransactions == 1);
t.assertTrue(expectOne.data.downloadedTransactions == 1); t.assertTrue(expectOne.downloadedTransactions == 1);
/* Expect zero payments being downloaded because the /* Expect zero payments being downloaded because the
* previous request consumed already the one pending * previous request consumed already the one pending
@ -108,8 +108,8 @@ export async function runLibeufinC5xTest(t: GlobalTestState) {
"all", // range "all", // range
"report", // C52 "report", // C52
); );
t.assertTrue(expectZero.data.newTransactions == 0); t.assertTrue(expectZero.newTransactions == 0);
t.assertTrue(expectZero.data.downloadedTransactions == 0); t.assertTrue(expectZero.downloadedTransactions == 0);
/** /**
* A statement should still account zero payments because * A statement should still account zero payments because
@ -121,8 +121,8 @@ export async function runLibeufinC5xTest(t: GlobalTestState) {
"all", // range "all", // range
"statement", // C53 "statement", // C53
); );
t.assertTrue(expectZero.data.newTransactions == 0); t.assertTrue(expectZero.newTransactions == 0);
t.assertTrue(expectZero.data.downloadedTransactions == 0); t.assertTrue(expectZero.downloadedTransactions == 0);
/** /**
* Ticking now. That books any pending transaction. * Ticking now. That books any pending transaction.
@ -141,7 +141,7 @@ export async function runLibeufinC5xTest(t: GlobalTestState) {
"all", // range "all", // range
"statement", // C53 "statement", // C53
); );
t.assertTrue(expectOne.data.downloadedTransactions == 1); t.assertTrue(expectOne.downloadedTransactions == 1);
t.assertTrue(expectOne.data.newTransactions == 0); t.assertTrue(expectOne.newTransactions == 0);
} }
runLibeufinC5xTest.suites = ["libeufin"]; runLibeufinC5xTest.suites = ["libeufin"];

View File

@ -53,9 +53,9 @@ export async function runLibeufinAnastasisFacadeTest(t: GlobalTestState) {
); );
// check that original facade shows up. // check that original facade shows up.
t.assertTrue( t.assertTrue(
resp.data["facades"][0]["name"] == user01nexus.anastasisReq["name"], resp["facades"][0]["name"] == user01nexus.anastasisReq["name"],
); );
const anastasisBaseUrl: string = resp.data["facades"][0]["baseUrl"]; const anastasisBaseUrl: string = resp["facades"][0]["baseUrl"];
t.assertTrue(typeof anastasisBaseUrl === "string"); t.assertTrue(typeof anastasisBaseUrl === "string");
t.assertTrue(anastasisBaseUrl.startsWith("http://")); t.assertTrue(anastasisBaseUrl.startsWith("http://"));
t.assertTrue(anastasisBaseUrl.endsWith("/")); t.assertTrue(anastasisBaseUrl.endsWith("/"));

View File

@ -77,7 +77,7 @@ export async function runLibeufinRefundTest(t: GlobalTestState) {
libeufinServices.libeufinNexus, libeufinServices.libeufinNexus,
user01nexus.localAccountName, user01nexus.localAccountName,
); );
t.assertTrue(nexusTxs.data["transactions"].length == 1); t.assertTrue(nexusTxs["transactions"].length == 1);
// Submit the reimbursement // Submit the reimbursement
await LibeufinNexusApi.submitInitiatedPayment( await LibeufinNexusApi.submitInitiatedPayment(

View File

@ -79,7 +79,7 @@ export async function runLibeufinSandboxWireTransferCliTest(
sandbox, sandbox,
"mock-account-2", "mock-account-2",
); );
console.log(ret.data.balance); console.log(ret.balance);
t.assertTrue(ret.data.balance == "EUR:1.89"); t.assertTrue(ret.balance == "EUR:1.89");
} }
runLibeufinSandboxWireTransferCliTest.suites = ["libeufin"]; runLibeufinSandboxWireTransferCliTest.suites = ["libeufin"];

View File

@ -23,8 +23,6 @@ import {
PreparePayResultType, PreparePayResultType,
} from "@gnu-taler/taler-util"; } from "@gnu-taler/taler-util";
import { WalletApiOperation } from "@gnu-taler/taler-wallet-core"; import { WalletApiOperation } from "@gnu-taler/taler-wallet-core";
import axiosImp from "axios";
const axios = axiosImp.default;
import { URL } from "url"; import { URL } from "url";
import { defaultCoinConfig } from "../harness/denomStructures.js"; import { defaultCoinConfig } from "../harness/denomStructures.js";
import { import {
@ -36,6 +34,7 @@ import {
ExchangeService, ExchangeService,
getPayto, getPayto,
GlobalTestState, GlobalTestState,
harnessHttpLib,
MerchantPrivateApi, MerchantPrivateApi,
MerchantService, MerchantService,
setupDb, setupDb,
@ -45,6 +44,7 @@ import {
FaultyMerchantTestEnvironment, FaultyMerchantTestEnvironment,
withdrawViaBank, withdrawViaBank,
} from "../harness/helpers.js"; } from "../harness/helpers.js";
import { createPlatformHttpLib } from "@gnu-taler/taler-util/http";
/** /**
* Run a test case with a simple TESTKUDOS Taler environment, consisting * Run a test case with a simple TESTKUDOS Taler environment, consisting
@ -186,9 +186,7 @@ export async function runMerchantExchangeConfusionTest(t: GlobalTestState) {
t.assertTrue(orderStatus.already_paid_order_id === undefined); t.assertTrue(orderStatus.already_paid_order_id === undefined);
let publicOrderStatusUrl = orderStatus.order_status_url; let publicOrderStatusUrl = orderStatus.order_status_url;
let publicOrderStatusResp = await axios.get(publicOrderStatusUrl, { let publicOrderStatusResp = await harnessHttpLib.fetch(publicOrderStatusUrl);
validateStatus: () => true,
});
if (publicOrderStatusResp.status != 402) { if (publicOrderStatusResp.status != 402) {
throw Error( throw Error(
@ -197,7 +195,7 @@ export async function runMerchantExchangeConfusionTest(t: GlobalTestState) {
} }
let pubUnpaidStatus = codecForMerchantOrderStatusUnpaid().decode( let pubUnpaidStatus = codecForMerchantOrderStatusUnpaid().decode(
publicOrderStatusResp.data, await publicOrderStatusResp.json(),
); );
console.log(pubUnpaidStatus); console.log(pubUnpaidStatus);
@ -221,9 +219,7 @@ export async function runMerchantExchangeConfusionTest(t: GlobalTestState) {
console.log("requesting", orderUrlWithHash.href); console.log("requesting", orderUrlWithHash.href);
publicOrderStatusResp = await axios.get(orderUrlWithHash.href, { publicOrderStatusResp = await harnessHttpLib.fetch(orderUrlWithHash.href);
validateStatus: () => true,
});
if (publicOrderStatusResp.status != 402) { if (publicOrderStatusResp.status != 402) {
throw Error( throw Error(
@ -232,7 +228,7 @@ export async function runMerchantExchangeConfusionTest(t: GlobalTestState) {
} }
pubUnpaidStatus = codecForMerchantOrderStatusUnpaid().decode( pubUnpaidStatus = codecForMerchantOrderStatusUnpaid().decode(
publicOrderStatusResp.data, await publicOrderStatusResp.json(),
); );
const confirmPayRes = await wallet.client.call( const confirmPayRes = await wallet.client.call(

View File

@ -17,9 +17,7 @@
/** /**
* Imports. * Imports.
*/ */
import { URL } from "@gnu-taler/taler-util"; import { TalerError, URL } from "@gnu-taler/taler-util";
import axiosImp from "axios";
const axios = axiosImp.default;
import { import {
ExchangeService, ExchangeService,
GlobalTestState, GlobalTestState,
@ -27,7 +25,9 @@ import {
MerchantService, MerchantService,
setupDb, setupDb,
getPayto, getPayto,
harnessHttpLib,
} from "../harness/harness.js"; } from "../harness/harness.js";
import { createPlatformHttpLib } from "@gnu-taler/taler-util/http";
/** /**
* Test instance deletion and authentication for it * Test instance deletion and authentication for it
@ -61,15 +61,17 @@ export async function runMerchantInstancesDeleteTest(t: GlobalTestState) {
const baseUrl = merchant.makeInstanceBaseUrl(); const baseUrl = merchant.makeInstanceBaseUrl();
{ {
const r = await axios.get(new URL("config", baseUrl).href); const r = await harnessHttpLib.fetch(new URL("config", baseUrl).href);
console.log(r.data); const data = await r.json();
t.assertDeepEqual(r.data.currency, "TESTKUDOS"); console.log(data);
t.assertDeepEqual(data.currency, "TESTKUDOS");
} }
// Instances should initially be empty // Instances should initially be empty
{ {
const r = await axios.get(new URL("management/instances", baseUrl).href); const r = await harnessHttpLib.fetch(new URL("management/instances", baseUrl).href);
t.assertDeepEqual(r.data.instances, []); const data = await r.json();
t.assertDeepEqual(data.instances, []);
} }
// Add an instance, no auth! // Add an instance, no auth!
@ -121,8 +123,8 @@ export async function runMerchantInstancesDeleteTest(t: GlobalTestState) {
await unauthMerchantClient.deleteInstance("myinst"); await unauthMerchantClient.deleteInstance("myinst");
}); });
console.log("Got expected exception", exc); console.log("Got expected exception", exc);
t.assertAxiosError(exc); t.assertTrue(exc instanceof TalerError);
t.assertDeepEqual(exc.response?.status, 401); t.assertDeepEqual(exc.errorDetail.httpStatusCode, 401);
} }
} }

View File

@ -18,8 +18,6 @@
* Imports. * Imports.
*/ */
import { Duration } from "@gnu-taler/taler-util"; import { Duration } from "@gnu-taler/taler-util";
import axiosImp from "axios";
const axios = axiosImp.default;
import { import {
ExchangeService, ExchangeService,
GlobalTestState, GlobalTestState,
@ -27,14 +25,14 @@ import {
MerchantService, MerchantService,
setupDb, setupDb,
getPayto, getPayto,
harnessHttpLib,
} from "../harness/harness.js"; } from "../harness/harness.js";
import { createPlatformHttpLib } from "@gnu-taler/taler-util/http";
/** /**
* Do basic checks on instance management and authentication. * Do basic checks on instance management and authentication.
*/ */
export async function runMerchantInstancesUrlsTest(t: GlobalTestState) { export async function runMerchantInstancesUrlsTest(t: GlobalTestState) {
// Set up test environment
const db = await setupDb(t); const db = await setupDb(t);
const exchange = ExchangeService.create(t, { const exchange = ExchangeService.create(t, {
@ -111,11 +109,10 @@ export async function runMerchantInstancesUrlsTest(t: GlobalTestState) {
}); });
async function check(url: string, token: string, expectedStatus: number) { async function check(url: string, token: string, expectedStatus: number) {
const resp = await axios.get(url, { const resp = await harnessHttpLib.fetch(url, {
headers: { headers: {
Authorization: `Bearer ${token}`, Authorization: `Bearer ${token}`,
}, },
validateStatus: () => true,
}); });
console.log( console.log(
`checking ${url}, expected ${expectedStatus}, got ${resp.status}`, `checking ${url}, expected ${expectedStatus}, got ${resp.status}`,

View File

@ -18,8 +18,6 @@
* Imports. * Imports.
*/ */
import { URL } from "@gnu-taler/taler-util"; import { URL } from "@gnu-taler/taler-util";
import axiosImp from "axios";
const axios = axiosImp.default;
import { import {
ExchangeService, ExchangeService,
GlobalTestState, GlobalTestState,
@ -27,7 +25,9 @@ import {
MerchantService, MerchantService,
setupDb, setupDb,
getPayto, getPayto,
harnessHttpLib,
} from "../harness/harness.js"; } from "../harness/harness.js";
import { createPlatformHttpLib } from "@gnu-taler/taler-util/http";
/** /**
* Do basic checks on instance management and authentication. * Do basic checks on instance management and authentication.
@ -61,15 +61,19 @@ export async function runMerchantInstancesTest(t: GlobalTestState) {
const baseUrl = merchant.makeInstanceBaseUrl(); const baseUrl = merchant.makeInstanceBaseUrl();
{ {
const r = await axios.get(new URL("config", baseUrl).href); const r = await harnessHttpLib.fetch(new URL("config", baseUrl).href);
console.log(r.data); const data = await r.json();
t.assertDeepEqual(r.data.currency, "TESTKUDOS"); console.log(data);
t.assertDeepEqual(data.currency, "TESTKUDOS");
} }
// Instances should initially be empty // Instances should initially be empty
{ {
const r = await axios.get(new URL("management/instances", baseUrl).href); const r = await harnessHttpLib.fetch(
t.assertDeepEqual(r.data.instances, []); new URL("management/instances", baseUrl).href,
);
const data = await r.json();
t.assertDeepEqual(data.instances, []);
} }
// Add an instance, no auth! // Add an instance, no auth!
@ -104,11 +108,14 @@ export async function runMerchantInstancesTest(t: GlobalTestState) {
// Check that a "malformed" bearer Authorization header gets ignored // Check that a "malformed" bearer Authorization header gets ignored
{ {
const url = merchant.makeInstanceBaseUrl(); const url = merchant.makeInstanceBaseUrl();
const resp = await axios.get(new URL("management/instances", url).href, { const resp = await harnessHttpLib.fetch(
headers: { new URL("management/instances", url).href,
Authorization: "foo bar-baz", {
headers: {
Authorization: "foo bar-baz",
},
}, },
}); );
t.assertDeepEqual(resp.status, 200); t.assertDeepEqual(resp.status, 200);
} }
@ -130,9 +137,7 @@ export async function runMerchantInstancesTest(t: GlobalTestState) {
}); });
console.log(exc); console.log(exc);
t.assertTrue(exc.errorDetail.httpStatusCode === 401);
t.assertAxiosError(exc);
t.assertTrue(exc.response?.status === 401);
merchantClient = new MerchantApiClient(merchant.makeInstanceBaseUrl(), { merchantClient = new MerchantApiClient(merchant.makeInstanceBaseUrl(), {
method: "token", method: "token",
@ -145,12 +150,15 @@ export async function runMerchantInstancesTest(t: GlobalTestState) {
// Now, try some variations. // Now, try some variations.
{ {
const url = merchant.makeInstanceBaseUrl(); const url = merchant.makeInstanceBaseUrl();
const resp = await axios.get(new URL("management/instances", url).href, { const resp = await harnessHttpLib.fetch(
headers: { new URL("management/instances", url).href,
// Note the spaces {
Authorization: "Bearer secret-token:foobar", headers: {
// Note the spaces
Authorization: "Bearer secret-token:foobar",
},
}, },
}); );
t.assertDeepEqual(resp.status, 200); t.assertDeepEqual(resp.status, 200);
} }
@ -176,7 +184,7 @@ export async function runMerchantInstancesTest(t: GlobalTestState) {
await unauthMerchantClient.deleteInstance("myinst"); await unauthMerchantClient.deleteInstance("myinst");
}); });
console.log(exc); console.log(exc);
t.assertAxiosError(exc); t.assertTrue(exc.errorDetail.httpStatusCode === 401);
t.assertDeepEqual(exc.response?.status, 401); t.assertDeepEqual(exc.response?.status, 401);
} }
} }

View File

@ -24,20 +24,18 @@ import {
codecForMerchantOrderStatusUnpaid, codecForMerchantOrderStatusUnpaid,
} from "@gnu-taler/taler-util"; } from "@gnu-taler/taler-util";
import { WalletApiOperation } from "@gnu-taler/taler-wallet-core"; import { WalletApiOperation } from "@gnu-taler/taler-wallet-core";
import axiosImp from "axios"; import { GlobalTestState, MerchantPrivateApi, harnessHttpLib } from "../harness/harness.js";
import { GlobalTestState, MerchantPrivateApi } from "../harness/harness.js";
import { import {
createSimpleTestkudosEnvironmentV2, createSimpleTestkudosEnvironmentV2,
withdrawViaBankV2 withdrawViaBankV2,
} from "../harness/helpers.js"; } from "../harness/helpers.js";
const axios = axiosImp.default; import { createPlatformHttpLib } from "@gnu-taler/taler-util/http";
/** /**
* Run test for basic, bank-integrated withdrawal. * Run test for basic, bank-integrated withdrawal.
*/ */
export async function runMerchantLongpollingTest(t: GlobalTestState) { export async function runMerchantLongpollingTest(t: GlobalTestState) {
// Set up test environment // Set up test environment
const { walletClient, bank, exchange, merchant } = const { walletClient, bank, exchange, merchant } =
await createSimpleTestkudosEnvironmentV2(t); await createSimpleTestkudosEnvironmentV2(t);
@ -83,9 +81,7 @@ export async function runMerchantLongpollingTest(t: GlobalTestState) {
// First, request order status without longpolling // First, request order status without longpolling
{ {
console.log("requesting", publicOrderStatusUrl.href); console.log("requesting", publicOrderStatusUrl.href);
let publicOrderStatusResp = await axios.get(publicOrderStatusUrl.href, { let publicOrderStatusResp = await harnessHttpLib.fetch(publicOrderStatusUrl.href);
validateStatus: () => true,
});
if (publicOrderStatusResp.status != 402) { if (publicOrderStatusResp.status != 402) {
throw Error( throw Error(
@ -98,9 +94,7 @@ export async function runMerchantLongpollingTest(t: GlobalTestState) {
publicOrderStatusUrl.searchParams.set("timeout_ms", "500"); publicOrderStatusUrl.searchParams.set("timeout_ms", "500");
console.log("requesting", publicOrderStatusUrl.href); console.log("requesting", publicOrderStatusUrl.href);
let publicOrderStatusResp = await axios.get(publicOrderStatusUrl.href, { let publicOrderStatusResp = await harnessHttpLib.fetch(publicOrderStatusUrl.href);
validateStatus: () => true,
});
if (publicOrderStatusResp.status != 402) { if (publicOrderStatusResp.status != 402) {
throw Error( throw Error(
@ -109,7 +103,7 @@ export async function runMerchantLongpollingTest(t: GlobalTestState) {
} }
let pubUnpaidStatus = codecForMerchantOrderStatusUnpaid().decode( let pubUnpaidStatus = codecForMerchantOrderStatusUnpaid().decode(
publicOrderStatusResp.data, await publicOrderStatusResp.json(),
); );
console.log(pubUnpaidStatus); console.log(pubUnpaidStatus);
@ -135,9 +129,7 @@ export async function runMerchantLongpollingTest(t: GlobalTestState) {
preparePayResp.contractTermsHash, preparePayResp.contractTermsHash,
); );
let publicOrderStatusPromise = axios.get(publicOrderStatusUrl.href, { let publicOrderStatusPromise = harnessHttpLib.fetch(publicOrderStatusUrl.href);
validateStatus: () => true,
});
t.assertTrue(preparePayResp.status === PreparePayResultType.PaymentPossible); t.assertTrue(preparePayResp.status === PreparePayResultType.PaymentPossible);
@ -152,15 +144,12 @@ export async function runMerchantLongpollingTest(t: GlobalTestState) {
} }
pubUnpaidStatus = codecForMerchantOrderStatusUnpaid().decode( pubUnpaidStatus = codecForMerchantOrderStatusUnpaid().decode(
publicOrderStatusResp.data, await publicOrderStatusResp.json(),
); );
const confirmPayRes = await walletClient.call( const confirmPayRes = await walletClient.call(WalletApiOperation.ConfirmPay, {
WalletApiOperation.ConfirmPay, proposalId: proposalId,
{ });
proposalId: proposalId,
},
);
t.assertTrue(confirmPayRes.type === ConfirmPayResultType.Done); t.assertTrue(confirmPayRes.type === ConfirmPayResultType.Done);
} }

View File

@ -17,12 +17,14 @@
/** /**
* Imports. * Imports.
*/ */
import { createPlatformHttpLib } from "@gnu-taler/taler-util/http";
import { import {
GlobalTestState, GlobalTestState,
MerchantPrivateApi, MerchantPrivateApi,
MerchantServiceInterface, MerchantServiceInterface,
WalletCli, WalletCli,
ExchangeServiceInterface, ExchangeServiceInterface,
harnessHttpLib,
} from "../harness/harness.js"; } from "../harness/harness.js";
import { import {
createSimpleTestkudosEnvironment, createSimpleTestkudosEnvironment,
@ -34,8 +36,6 @@ import {
PreparePayResultType, PreparePayResultType,
Duration, Duration,
} from "@gnu-taler/taler-util"; } from "@gnu-taler/taler-util";
import axiosImp from "axios";
const axios = axiosImp.default;
import { import {
WalletApiOperation, WalletApiOperation,
BankServiceHandle, BankServiceHandle,
@ -136,23 +136,19 @@ async function testRefundApiWithFulfillmentUrl(
preparePayResult.contractTermsHash, preparePayResult.contractTermsHash,
); );
let publicOrderStatusResp = await axios.get(publicOrderStatusUrl.href, { let publicOrderStatusResp = await harnessHttpLib.fetch(publicOrderStatusUrl.href);
validateStatus: () => true, const respData = await publicOrderStatusResp.json();
});
console.log(publicOrderStatusResp.data);
t.assertTrue(publicOrderStatusResp.status === 200); t.assertTrue(publicOrderStatusResp.status === 200);
t.assertAmountEquals(publicOrderStatusResp.data.refund_amount, "TESTKUDOS:5"); t.assertAmountEquals(respData.refund_amount, "TESTKUDOS:5");
publicOrderStatusUrl = new URL( publicOrderStatusUrl = new URL(
`orders/${orderId}`, `orders/${orderId}`,
merchant.makeInstanceBaseUrl(), merchant.makeInstanceBaseUrl(),
); );
console.log(`requesting order status via '${publicOrderStatusUrl.href}'`); console.log(`requesting order status via '${publicOrderStatusUrl.href}'`);
publicOrderStatusResp = await axios.get(publicOrderStatusUrl.href, { publicOrderStatusResp = await harnessHttpLib.fetch(publicOrderStatusUrl.href);
validateStatus: () => true,
});
console.log(publicOrderStatusResp.status); console.log(publicOrderStatusResp.status);
console.log(publicOrderStatusResp.data); console.log(await publicOrderStatusResp.json());
// We didn't give any authentication, so we should get a fulfillment URL back // We didn't give any authentication, so we should get a fulfillment URL back
t.assertTrue(publicOrderStatusResp.status === 403); t.assertTrue(publicOrderStatusResp.status === 403);
} }
@ -252,22 +248,20 @@ async function testRefundApiWithFulfillmentMessage(
preparePayResult.contractTermsHash, preparePayResult.contractTermsHash,
); );
let publicOrderStatusResp = await axios.get(publicOrderStatusUrl.href, { let publicOrderStatusResp = await harnessHttpLib.fetch(publicOrderStatusUrl.href);
validateStatus: () => true, let respData = await publicOrderStatusResp.json();
}); console.log(respData);
console.log(publicOrderStatusResp.data);
t.assertTrue(publicOrderStatusResp.status === 200); t.assertTrue(publicOrderStatusResp.status === 200);
t.assertAmountEquals(publicOrderStatusResp.data.refund_amount, "TESTKUDOS:5"); t.assertAmountEquals(respData.refund_amount, "TESTKUDOS:5");
publicOrderStatusUrl = new URL( publicOrderStatusUrl = new URL(
`orders/${orderId}`, `orders/${orderId}`,
merchant.makeInstanceBaseUrl(), merchant.makeInstanceBaseUrl(),
); );
publicOrderStatusResp = await axios.get(publicOrderStatusUrl.href, { publicOrderStatusResp = await harnessHttpLib.fetch(publicOrderStatusUrl.href);
validateStatus: () => true, respData = await publicOrderStatusResp.json();
}); console.log(respData);
console.log(publicOrderStatusResp.data);
// We didn't give any authentication, so we should get a fulfillment URL back // We didn't give any authentication, so we should get a fulfillment URL back
t.assertTrue(publicOrderStatusResp.status === 403); t.assertTrue(publicOrderStatusResp.status === 403);
} }

View File

@ -24,7 +24,6 @@ import {
encodeCrock, encodeCrock,
getRandomBytes, getRandomBytes,
} from "@gnu-taler/taler-util"; } from "@gnu-taler/taler-util";
import { createPlatformHttpLib } from "@gnu-taler/taler-util/http";
import { WalletApiOperation } from "@gnu-taler/taler-wallet-core"; import { WalletApiOperation } from "@gnu-taler/taler-wallet-core";
import { import {
BankService, BankService,
@ -33,17 +32,13 @@ import {
MerchantPrivateApi, MerchantPrivateApi,
MerchantService, MerchantService,
WalletCli, WalletCli,
harnessHttpLib,
} from "../harness/harness.js"; } from "../harness/harness.js";
import { import {
createSimpleTestkudosEnvironment, createSimpleTestkudosEnvironment,
withdrawViaBank, withdrawViaBank,
} from "../harness/helpers.js"; } from "../harness/helpers.js";
const httpLib = createPlatformHttpLib({
allowHttp: true,
enableThrottling: false,
});
interface Context { interface Context {
merchant: MerchantService; merchant: MerchantService;
merchantBaseUrl: string; merchantBaseUrl: string;
@ -51,6 +46,8 @@ interface Context {
exchange: ExchangeService; exchange: ExchangeService;
} }
const httpLib = harnessHttpLib;
async function testWithClaimToken( async function testWithClaimToken(
t: GlobalTestState, t: GlobalTestState,
c: Context, c: Context,

View File

@ -17,7 +17,7 @@
/** /**
* Imports. * Imports.
*/ */
import { GlobalTestState, MerchantPrivateApi } from "../harness/harness.js"; import { GlobalTestState, MerchantPrivateApi, harnessHttpLib } from "../harness/harness.js";
import { import {
withdrawViaBank, withdrawViaBank,
createFaultInjectedMerchantTestkudosEnvironment, createFaultInjectedMerchantTestkudosEnvironment,
@ -28,8 +28,6 @@ import {
ConfirmPayResultType, ConfirmPayResultType,
URL, URL,
} from "@gnu-taler/taler-util"; } from "@gnu-taler/taler-util";
import axiosImp from "axios";
const axios = axiosImp.default;
import { FaultInjectionRequestContext } from "../harness/faultInjection.js"; import { FaultInjectionRequestContext } from "../harness/faultInjection.js";
import { WalletApiOperation } from "@gnu-taler/taler-wallet-core"; import { WalletApiOperation } from "@gnu-taler/taler-wallet-core";
@ -86,9 +84,7 @@ export async function runPayPaidTest(t: GlobalTestState) {
t.assertTrue(orderStatus.already_paid_order_id === undefined); t.assertTrue(orderStatus.already_paid_order_id === undefined);
let publicOrderStatusUrl = orderStatus.order_status_url; let publicOrderStatusUrl = orderStatus.order_status_url;
let publicOrderStatusResp = await axios.get(publicOrderStatusUrl, { let publicOrderStatusResp = await harnessHttpLib.fetch(publicOrderStatusUrl);
validateStatus: () => true,
});
if (publicOrderStatusResp.status != 402) { if (publicOrderStatusResp.status != 402) {
throw Error( throw Error(
@ -97,7 +93,7 @@ export async function runPayPaidTest(t: GlobalTestState) {
} }
let pubUnpaidStatus = codecForMerchantOrderStatusUnpaid().decode( let pubUnpaidStatus = codecForMerchantOrderStatusUnpaid().decode(
publicOrderStatusResp.data, publicOrderStatusResp.json(),
); );
console.log(pubUnpaidStatus); console.log(pubUnpaidStatus);
@ -113,9 +109,7 @@ export async function runPayPaidTest(t: GlobalTestState) {
const proposalId = preparePayResp.proposalId; const proposalId = preparePayResp.proposalId;
publicOrderStatusResp = await axios.get(publicOrderStatusUrl, { publicOrderStatusResp = await harnessHttpLib.fetch(publicOrderStatusUrl);
validateStatus: () => true,
});
if (publicOrderStatusResp.status != 402) { if (publicOrderStatusResp.status != 402) {
throw Error( throw Error(
@ -124,7 +118,7 @@ export async function runPayPaidTest(t: GlobalTestState) {
} }
pubUnpaidStatus = codecForMerchantOrderStatusUnpaid().decode( pubUnpaidStatus = codecForMerchantOrderStatusUnpaid().decode(
publicOrderStatusResp.data, publicOrderStatusResp.json(),
); );
const confirmPayRes = await wallet.client.call( const confirmPayRes = await wallet.client.call(
@ -136,14 +130,12 @@ export async function runPayPaidTest(t: GlobalTestState) {
t.assertTrue(confirmPayRes.type === ConfirmPayResultType.Done); t.assertTrue(confirmPayRes.type === ConfirmPayResultType.Done);
publicOrderStatusResp = await axios.get(publicOrderStatusUrl, { publicOrderStatusResp = await harnessHttpLib.fetch(publicOrderStatusUrl);
validateStatus: () => true,
});
console.log(publicOrderStatusResp.data); console.log(publicOrderStatusResp.json());
if (publicOrderStatusResp.status != 200) { if (publicOrderStatusResp.status != 200) {
console.log(publicOrderStatusResp.data); console.log(publicOrderStatusResp.json());
throw Error( throw Error(
`expected status 200 (after paying), but got ${publicOrderStatusResp.status}`, `expected status 200 (after paying), but got ${publicOrderStatusResp.status}`,
); );

View File

@ -17,14 +17,12 @@
/** /**
* Imports. * Imports.
*/ */
import { GlobalTestState, MerchantPrivateApi } from "../harness/harness.js"; import { GlobalTestState, MerchantPrivateApi, harnessHttpLib } from "../harness/harness.js";
import { import {
withdrawViaBank, withdrawViaBank,
createFaultInjectedMerchantTestkudosEnvironment, createFaultInjectedMerchantTestkudosEnvironment,
} from "../harness/helpers.js"; } from "../harness/helpers.js";
import { import { FaultInjectionRequestContext } from "../harness/faultInjection.js";
FaultInjectionRequestContext,
} from "../harness/faultInjection.js";
import { import {
codecForMerchantOrderStatusUnpaid, codecForMerchantOrderStatusUnpaid,
ConfirmPayResultType, ConfirmPayResultType,
@ -35,9 +33,6 @@ import {
URL, URL,
} from "@gnu-taler/taler-util"; } from "@gnu-taler/taler-util";
import { WalletApiOperation } from "@gnu-taler/taler-wallet-core"; import { WalletApiOperation } from "@gnu-taler/taler-wallet-core";
import axiosImp from "axios";
const axios = axiosImp.default;
export async function runPaymentAbortTest(t: GlobalTestState) { export async function runPaymentAbortTest(t: GlobalTestState) {
// Set up test environment // Set up test environment
@ -75,9 +70,7 @@ export async function runPaymentAbortTest(t: GlobalTestState) {
t.assertTrue(orderStatus.already_paid_order_id === undefined); t.assertTrue(orderStatus.already_paid_order_id === undefined);
let publicOrderStatusUrl = orderStatus.order_status_url; let publicOrderStatusUrl = orderStatus.order_status_url;
let publicOrderStatusResp = await axios.get(publicOrderStatusUrl, { let publicOrderStatusResp = await harnessHttpLib.fetch(publicOrderStatusUrl);
validateStatus: () => true,
});
if (publicOrderStatusResp.status != 402) { if (publicOrderStatusResp.status != 402) {
throw Error( throw Error(
@ -86,7 +79,7 @@ export async function runPaymentAbortTest(t: GlobalTestState) {
} }
let pubUnpaidStatus = codecForMerchantOrderStatusUnpaid().decode( let pubUnpaidStatus = codecForMerchantOrderStatusUnpaid().decode(
publicOrderStatusResp.data, publicOrderStatusResp.json(),
); );
console.log(pubUnpaidStatus); console.log(pubUnpaidStatus);
@ -102,9 +95,7 @@ export async function runPaymentAbortTest(t: GlobalTestState) {
const proposalId = preparePayResp.proposalId; const proposalId = preparePayResp.proposalId;
publicOrderStatusResp = await axios.get(publicOrderStatusUrl, { publicOrderStatusResp = await harnessHttpLib.fetch(publicOrderStatusUrl);
validateStatus: () => true,
});
if (publicOrderStatusResp.status != 402) { if (publicOrderStatusResp.status != 402) {
throw Error( throw Error(
@ -113,7 +104,7 @@ export async function runPaymentAbortTest(t: GlobalTestState) {
} }
pubUnpaidStatus = codecForMerchantOrderStatusUnpaid().decode( pubUnpaidStatus = codecForMerchantOrderStatusUnpaid().decode(
publicOrderStatusResp.data, publicOrderStatusResp.json(),
); );
faultyMerchant.faultProxy.addFault({ faultyMerchant.faultProxy.addFault({

View File

@ -42,13 +42,15 @@ export async function runPaymentClaimTest(t: GlobalTestState) {
// Withdraw digital cash into the wallet. // Withdraw digital cash into the wallet.
await withdrawViaBankV2(t, { const wres = await withdrawViaBankV2(t, {
walletClient, walletClient,
bank, bank,
exchange, exchange,
amount: "TESTKUDOS:20", amount: "TESTKUDOS:20",
}); });
await wres.withdrawalFinishedCond;
// Set up order. // Set up order.
const orderResp = await MerchantPrivateApi.createOrder(merchant, "default", { const orderResp = await MerchantPrivateApi.createOrder(merchant, "default", {

View File

@ -37,13 +37,15 @@ export async function runPaymentIdempotencyTest(t: GlobalTestState) {
// Withdraw digital cash into the wallet. // Withdraw digital cash into the wallet.
await withdrawViaBankV2(t, { const wres = await withdrawViaBankV2(t, {
walletClient, walletClient,
bank, bank,
exchange, exchange,
amount: "TESTKUDOS:20", amount: "TESTKUDOS:20",
}); });
await wres.withdrawalFinishedCond;
// Set up order. // Set up order.
const orderResp = await MerchantPrivateApi.createOrder(merchant, "default", { const orderResp = await MerchantPrivateApi.createOrder(merchant, "default", {

View File

@ -50,7 +50,8 @@ export async function runPaymentTemplateTest(t: GlobalTestState) {
// Withdraw digital cash into the wallet. // Withdraw digital cash into the wallet.
await withdrawViaBankV2(t, { walletClient, bank, exchange, amount: "TESTKUDOS:20" }); const wres = await withdrawViaBankV2(t, { walletClient, bank, exchange, amount: "TESTKUDOS:20" });
await wres.withdrawalFinishedCond;
// Request a template payment // Request a template payment

View File

@ -17,23 +17,22 @@
/** /**
* Imports. * Imports.
*/ */
import { GlobalTestState, MerchantPrivateApi } from "../harness/harness.js";
import { import {
withdrawViaBank,
createFaultInjectedMerchantTestkudosEnvironment,
} from "../harness/helpers.js";
import { FaultInjectionResponseContext } from "../harness/faultInjection.js";
import {
codecForMerchantOrderStatusUnpaid,
ConfirmPayResultType, ConfirmPayResultType,
PreparePayResultType, PreparePayResultType,
TalerErrorCode, TalerErrorCode,
TalerErrorDetail, TalerErrorDetail,
URL, URL,
codecForMerchantOrderStatusUnpaid,
} from "@gnu-taler/taler-util"; } from "@gnu-taler/taler-util";
import { WalletApiOperation } from "@gnu-taler/taler-wallet-core"; import { WalletApiOperation } from "@gnu-taler/taler-wallet-core";
import axiosImp from "axios"; import { FaultInjectionResponseContext } from "../harness/faultInjection.js";
const axios = axiosImp.default; import { GlobalTestState, MerchantPrivateApi, harnessHttpLib } from "../harness/harness.js";
import {
createFaultInjectedMerchantTestkudosEnvironment,
withdrawViaBank,
} from "../harness/helpers.js";
/** /**
* Run test for a payment where the merchant has a transient * Run test for a payment where the merchant has a transient
@ -75,9 +74,7 @@ export async function runPaymentTransientTest(t: GlobalTestState) {
t.assertTrue(orderStatus.already_paid_order_id === undefined); t.assertTrue(orderStatus.already_paid_order_id === undefined);
let publicOrderStatusUrl = orderStatus.order_status_url; let publicOrderStatusUrl = orderStatus.order_status_url;
let publicOrderStatusResp = await axios.get(publicOrderStatusUrl, { let publicOrderStatusResp = await harnessHttpLib.fetch(publicOrderStatusUrl);
validateStatus: () => true,
});
if (publicOrderStatusResp.status != 402) { if (publicOrderStatusResp.status != 402) {
throw Error( throw Error(
@ -86,7 +83,7 @@ export async function runPaymentTransientTest(t: GlobalTestState) {
} }
let pubUnpaidStatus = codecForMerchantOrderStatusUnpaid().decode( let pubUnpaidStatus = codecForMerchantOrderStatusUnpaid().decode(
publicOrderStatusResp.data, publicOrderStatusResp.json(),
); );
console.log(pubUnpaidStatus); console.log(pubUnpaidStatus);
@ -102,9 +99,7 @@ export async function runPaymentTransientTest(t: GlobalTestState) {
const proposalId = preparePayResp.proposalId; const proposalId = preparePayResp.proposalId;
publicOrderStatusResp = await axios.get(publicOrderStatusUrl, { publicOrderStatusResp = await harnessHttpLib.fetch(publicOrderStatusUrl);
validateStatus: () => true,
});
if (publicOrderStatusResp.status != 402) { if (publicOrderStatusResp.status != 402) {
throw Error( throw Error(
@ -113,7 +108,7 @@ export async function runPaymentTransientTest(t: GlobalTestState) {
} }
pubUnpaidStatus = codecForMerchantOrderStatusUnpaid().decode( pubUnpaidStatus = codecForMerchantOrderStatusUnpaid().decode(
publicOrderStatusResp.data, publicOrderStatusResp.json(),
); );
let faultInjected = false; let faultInjected = false;
@ -165,14 +160,12 @@ export async function runPaymentTransientTest(t: GlobalTestState) {
// Now ask the merchant if paid // Now ask the merchant if paid
console.log("requesting", publicOrderStatusUrl); console.log("requesting", publicOrderStatusUrl);
publicOrderStatusResp = await axios.get(publicOrderStatusUrl, { publicOrderStatusResp = await harnessHttpLib.fetch(publicOrderStatusUrl);
validateStatus: () => true,
});
console.log(publicOrderStatusResp.data); console.log(publicOrderStatusResp.json());
if (publicOrderStatusResp.status != 200) { if (publicOrderStatusResp.status != 200) {
console.log(publicOrderStatusResp.data); console.log(publicOrderStatusResp.json());
throw Error( throw Error(
`expected status 200 (after paying), but got ${publicOrderStatusResp.status}`, `expected status 200 (after paying), but got ${publicOrderStatusResp.status}`,
); );

View File

@ -17,7 +17,7 @@
/** /**
* Imports. * Imports.
*/ */
import { GlobalTestState, MerchantPrivateApi } from "../harness/harness.js"; import { GlobalTestState, MerchantPrivateApi, harnessHttpLib } from "../harness/harness.js";
import { import {
PreparePayResultType, PreparePayResultType,
codecForMerchantOrderStatusUnpaid, codecForMerchantOrderStatusUnpaid,
@ -29,12 +29,6 @@ import {
createSimpleTestkudosEnvironmentV2, createSimpleTestkudosEnvironmentV2,
withdrawViaBankV2, withdrawViaBankV2,
} from "../harness/helpers.js"; } from "../harness/helpers.js";
import { createPlatformHttpLib } from "@gnu-taler/taler-util/http";
const httpLib = createPlatformHttpLib({
allowHttp: true,
enableThrottling: false,
});
/** /**
* Run test for basic, bank-integrated withdrawal. * Run test for basic, bank-integrated withdrawal.
@ -47,13 +41,15 @@ export async function runPaywallFlowTest(t: GlobalTestState) {
// Withdraw digital cash into the wallet. // Withdraw digital cash into the wallet.
await withdrawViaBankV2(t, { const wres = await withdrawViaBankV2(t, {
walletClient, walletClient,
bank, bank,
exchange, exchange,
amount: "TESTKUDOS:20", amount: "TESTKUDOS:20",
}); });
await wres.withdrawalFinishedCond;
/** /**
* ========================================================================= * =========================================================================
* Create an order and let the wallet pay under a session ID * Create an order and let the wallet pay under a session ID
@ -86,7 +82,7 @@ export async function runPaywallFlowTest(t: GlobalTestState) {
t.assertTrue(orderStatus.already_paid_order_id === undefined); t.assertTrue(orderStatus.already_paid_order_id === undefined);
let publicOrderStatusUrl = new URL(orderStatus.order_status_url); let publicOrderStatusUrl = new URL(orderStatus.order_status_url);
let publicOrderStatusResp = await httpLib.fetch(publicOrderStatusUrl.href); let publicOrderStatusResp = await harnessHttpLib.fetch(publicOrderStatusUrl.href);
if (publicOrderStatusResp.status != 402) { if (publicOrderStatusResp.status != 402) {
throw Error( throw Error(
@ -112,7 +108,7 @@ export async function runPaywallFlowTest(t: GlobalTestState) {
const proposalId = preparePayResp.proposalId; const proposalId = preparePayResp.proposalId;
console.log("requesting", publicOrderStatusUrl.href); console.log("requesting", publicOrderStatusUrl.href);
publicOrderStatusResp = await httpLib.fetch(publicOrderStatusUrl.href); publicOrderStatusResp = await harnessHttpLib.fetch(publicOrderStatusUrl.href);
console.log("response body", publicOrderStatusResp.json()); console.log("response body", publicOrderStatusResp.json());
if (publicOrderStatusResp.status != 402) { if (publicOrderStatusResp.status != 402) {
throw Error( throw Error(
@ -129,7 +125,7 @@ export async function runPaywallFlowTest(t: GlobalTestState) {
}); });
t.assertTrue(confirmPayRes.type === ConfirmPayResultType.Done); t.assertTrue(confirmPayRes.type === ConfirmPayResultType.Done);
publicOrderStatusResp = await httpLib.fetch(publicOrderStatusUrl.href); publicOrderStatusResp = await harnessHttpLib.fetch(publicOrderStatusUrl.href);
console.log(publicOrderStatusResp.json()); console.log(publicOrderStatusResp.json());
@ -231,7 +227,7 @@ export async function runPaywallFlowTest(t: GlobalTestState) {
console.log("requesting public status", publicOrderStatusUrl); console.log("requesting public status", publicOrderStatusUrl);
// Ask the order status of the claimed-but-unpaid order // Ask the order status of the claimed-but-unpaid order
publicOrderStatusResp = await httpLib.fetch(publicOrderStatusUrl.href); publicOrderStatusResp = await harnessHttpLib.fetch(publicOrderStatusUrl.href);
if (publicOrderStatusResp.status != 402) { if (publicOrderStatusResp.status != 402) {
throw Error(`expected status 402, but got ${publicOrderStatusResp.status}`); throw Error(`expected status 402, but got ${publicOrderStatusResp.status}`);

View File

@ -36,13 +36,15 @@ export async function runRefundAutoTest(t: GlobalTestState) {
// Withdraw digital cash into the wallet. // Withdraw digital cash into the wallet.
await withdrawViaBankV2(t, { const wres = await withdrawViaBankV2(t, {
walletClient, walletClient,
bank, bank,
exchange, exchange,
amount: "TESTKUDOS:20", amount: "TESTKUDOS:20",
}); });
await wres.withdrawalFinishedCond;
// Set up order. // Set up order.
const orderResp = await MerchantPrivateApi.createOrder(merchant, "default", { const orderResp = await MerchantPrivateApi.createOrder(merchant, "default", {
order: { order: {

View File

@ -45,13 +45,15 @@ export async function runRefundIncrementalTest(t: GlobalTestState) {
// Withdraw digital cash into the wallet. // Withdraw digital cash into the wallet.
await withdrawViaBankV2(t, { const wres = await withdrawViaBankV2(t, {
walletClient, walletClient,
bank, bank,
exchange, exchange,
amount: "TESTKUDOS:20", amount: "TESTKUDOS:20",
}); });
await wres.withdrawalFinishedCond;
// Set up order. // Set up order.
const orderResp = await MerchantPrivateApi.createOrder(merchant, "default", { const orderResp = await MerchantPrivateApi.createOrder(merchant, "default", {

View File

@ -17,22 +17,11 @@
/** /**
* Imports. * Imports.
*/ */
import { Amounts, Duration, PreparePayResultType } from "@gnu-taler/taler-util"; import { Amounts, PreparePayResultType } from "@gnu-taler/taler-util";
import { WalletApiOperation } from "@gnu-taler/taler-wallet-core"; import { WalletApiOperation } from "@gnu-taler/taler-wallet-core";
import { CoinConfig, defaultCoinConfig } from "../harness/denomStructures.js"; import { GlobalTestState, MerchantPrivateApi } from "../harness/harness.js";
import {
ExchangeService,
FakebankService,
getRandomIban,
GlobalTestState,
MerchantPrivateApi,
MerchantService,
setupDb,
WalletCli,
} from "../harness/harness.js";
import { import {
createSimpleTestkudosEnvironmentV2, createSimpleTestkudosEnvironmentV2,
withdrawViaBank,
withdrawViaBankV2, withdrawViaBankV2,
} from "../harness/helpers.js"; } from "../harness/helpers.js";
@ -50,13 +39,15 @@ export async function runWalletBalanceTest(t: GlobalTestState) {
// Withdraw digital cash into the wallet. // Withdraw digital cash into the wallet.
await withdrawViaBankV2(t, { const wres = await withdrawViaBankV2(t, {
walletClient, walletClient,
bank, bank,
exchange, exchange,
amount: "TESTKUDOS:20", amount: "TESTKUDOS:20",
}); });
await wres.withdrawalFinishedCond;
const order = { const order = {
summary: "Buy me!", summary: "Buy me!",
amount: "TESTKUDOS:5", amount: "TESTKUDOS:5",

View File

@ -23,7 +23,6 @@ import {
j2s, j2s,
TalerError, TalerError,
} from "@gnu-taler/taler-util"; } from "@gnu-taler/taler-util";
import { createPlatformHttpLib } from "@gnu-taler/taler-util/http";
import { import {
checkReserve, checkReserve,
CryptoDispatcher, CryptoDispatcher,
@ -36,7 +35,7 @@ import {
Wallet, Wallet,
withdrawCoin, withdrawCoin,
} from "@gnu-taler/taler-wallet-core"; } from "@gnu-taler/taler-wallet-core";
import { GlobalTestState } from "../harness/harness.js"; import { GlobalTestState, harnessHttpLib } from "../harness/harness.js";
import { createSimpleTestkudosEnvironmentV2 } from "../harness/helpers.js"; import { createSimpleTestkudosEnvironmentV2 } from "../harness/helpers.js";
/** /**
@ -47,10 +46,7 @@ export async function runWalletDblessTest(t: GlobalTestState) {
const { bank, exchange } = await createSimpleTestkudosEnvironmentV2(t); const { bank, exchange } = await createSimpleTestkudosEnvironmentV2(t);
const http = createPlatformHttpLib({ const http = harnessHttpLib;
allowHttp: true,
enableThrottling: false,
});
const cryptiDisp = new CryptoDispatcher( const cryptiDisp = new CryptoDispatcher(
new SynchronousCryptoWorkerFactoryPlain(), new SynchronousCryptoWorkerFactoryPlain(),
); );

View File

@ -19,7 +19,12 @@
import { CancellationToken } from "./CancellationToken.js"; import { CancellationToken } from "./CancellationToken.js";
import { Codec } from "./codec.js"; import { Codec } from "./codec.js";
import { j2s } from "./helpers.js"; import { j2s } from "./helpers.js";
import { TalerError, makeErrorDetail } from "./index.js"; import {
TalerError,
base64FromArrayBuffer,
makeErrorDetail,
stringToBytes,
} from "./index.js";
import { Logger } from "./logging.js"; import { Logger } from "./logging.js";
import { TalerErrorCode } from "./taler-error-codes.js"; import { TalerErrorCode } from "./taler-error-codes.js";
import { Duration, AbsoluteTime } from "./time.js"; import { Duration, AbsoluteTime } from "./time.js";
@ -306,6 +311,16 @@ export async function readSuccessResponseJsonOrThrow<T>(
throwUnexpectedRequestError(httpResponse, r.talerErrorResponse); throwUnexpectedRequestError(httpResponse, r.talerErrorResponse);
} }
export async function expectSuccessResponseOrThrow<T>(
httpResponse: HttpResponse,
): Promise<void> {
if (httpResponse.status >= 200 && httpResponse.status <= 299) {
return;
}
const errResp = await readTalerErrorResponse(httpResponse);
throwUnexpectedRequestError(httpResponse, errResp);
}
export async function readSuccessResponseTextOrErrorCode<T>( export async function readSuccessResponseTextOrErrorCode<T>(
httpResponse: HttpResponse, httpResponse: HttpResponse,
): Promise<ResponseOrError<string>> { ): Promise<ResponseOrError<string>> {
@ -452,3 +467,15 @@ export function getDefaultHeaders(method: string): Record<string, string> {
return headers; return headers;
} }
/**
* 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}`;
}

View File

@ -72,7 +72,6 @@
"@gnu-taler/idb-bridge": "workspace:*", "@gnu-taler/idb-bridge": "workspace:*",
"@gnu-taler/taler-util": "workspace:*", "@gnu-taler/taler-util": "workspace:*",
"@types/node": "^18.11.17", "@types/node": "^18.11.17",
"axios": "^0.27.2",
"big-integer": "^1.6.51", "big-integer": "^1.6.51",
"fflate": "^0.7.4", "fflate": "^0.7.4",
"tslib": "^2.5.3" "tslib": "^2.5.3"

View File

@ -44,7 +44,6 @@
"@types/web": "^0.0.82", "@types/web": "^0.0.82",
"@types/ws": "^8.5.3", "@types/ws": "^8.5.3",
"autoprefixer": "^10.4.14", "autoprefixer": "^10.4.14",
"axios": "^1.2.2",
"chokidar": "^3.5.3", "chokidar": "^3.5.3",
"esbuild": "^0.17.7", "esbuild": "^0.17.7",
"express": "^4.18.2", "express": "^4.18.2",

View File

@ -579,9 +579,6 @@ importers:
'@gnu-taler/taler-wallet-core': '@gnu-taler/taler-wallet-core':
specifier: workspace:* specifier: workspace:*
version: link:../taler-wallet-core version: link:../taler-wallet-core
axios:
specifier: ^0.27.2
version: 0.27.2
tslib: tslib:
specifier: ^2.5.3 specifier: ^2.5.3
version: 2.5.3 version: 2.5.3
@ -678,9 +675,6 @@ importers:
'@types/node': '@types/node':
specifier: ^18.11.17 specifier: ^18.11.17
version: 18.11.17 version: 18.11.17
axios:
specifier: ^0.27.2
version: 0.27.2
big-integer: big-integer:
specifier: ^1.6.51 specifier: ^1.6.51
version: 1.6.51 version: 1.6.51
@ -925,9 +919,6 @@ importers:
autoprefixer: autoprefixer:
specifier: ^10.4.14 specifier: ^10.4.14
version: 10.4.14(postcss@8.4.23) version: 10.4.14(postcss@8.4.23)
axios:
specifier: ^1.2.2
version: 1.2.2
chokidar: chokidar:
specifier: ^3.5.3 specifier: ^3.5.3
version: 3.5.3 version: 3.5.3
@ -6804,6 +6795,7 @@ packages:
/asynckit@0.4.0: /asynckit@0.4.0:
resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==}
dev: true
/at-least-node@1.0.0: /at-least-node@1.0.0:
resolution: {integrity: sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==} resolution: {integrity: sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==}
@ -6969,15 +6961,6 @@ packages:
- debug - debug
dev: true dev: true
/axios@0.27.2:
resolution: {integrity: sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==}
dependencies:
follow-redirects: 1.15.2
form-data: 4.0.0
transitivePeerDependencies:
- debug
dev: false
/axios@1.1.3: /axios@1.1.3:
resolution: {integrity: sha512-00tXVRwKx/FZr/IDVFt4C+f9FYairX517WoGCL6dpOntqLkZofjhu43F/Xl44UOpqa+9sLFDrG/XAnFsUYgkDA==} resolution: {integrity: sha512-00tXVRwKx/FZr/IDVFt4C+f9FYairX517WoGCL6dpOntqLkZofjhu43F/Xl44UOpqa+9sLFDrG/XAnFsUYgkDA==}
dependencies: dependencies:
@ -6988,16 +6971,6 @@ packages:
- debug - debug
dev: true dev: true
/axios@1.2.2:
resolution: {integrity: sha512-bz/J4gS2S3I7mpN/YZfGFTqhXTYzRho8Ay38w2otuuDR322KzFIWm/4W2K6gIwvWaws5n+mnb7D1lN9uD+QH6Q==}
dependencies:
follow-redirects: 1.15.2
form-data: 4.0.0
proxy-from-env: 1.1.0
transitivePeerDependencies:
- debug
dev: true
/axobject-query@2.2.0: /axobject-query@2.2.0:
resolution: {integrity: sha512-Td525n+iPOOyUQIeBfcASuG6uJsDOITl7Mds5gFyerkWiX7qhUTdYUBlSgNMyVqtSJqwpt1kXGLdUt6SykLMRA==} resolution: {integrity: sha512-Td525n+iPOOyUQIeBfcASuG6uJsDOITl7Mds5gFyerkWiX7qhUTdYUBlSgNMyVqtSJqwpt1kXGLdUt6SykLMRA==}
dev: true dev: true
@ -8069,6 +8042,7 @@ packages:
engines: {node: '>= 0.8'} engines: {node: '>= 0.8'}
dependencies: dependencies:
delayed-stream: 1.0.0 delayed-stream: 1.0.0
dev: true
/commander@2.17.1: /commander@2.17.1:
resolution: {integrity: sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg==} resolution: {integrity: sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg==}
@ -8918,6 +8892,7 @@ packages:
/delayed-stream@1.0.0: /delayed-stream@1.0.0:
resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==}
engines: {node: '>=0.4.0'} engines: {node: '>=0.4.0'}
dev: true
/depd@1.1.2: /depd@1.1.2:
resolution: {integrity: sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==} resolution: {integrity: sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==}
@ -10528,6 +10503,7 @@ packages:
peerDependenciesMeta: peerDependenciesMeta:
debug: debug:
optional: true optional: true
dev: true
/for-each@0.3.3: /for-each@0.3.3:
resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==} resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==}
@ -10604,6 +10580,7 @@ packages:
asynckit: 0.4.0 asynckit: 0.4.0
combined-stream: 1.0.8 combined-stream: 1.0.8
mime-types: 2.1.35 mime-types: 2.1.35
dev: true
/forwarded@0.2.0: /forwarded@0.2.0:
resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==} resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==}
@ -12669,12 +12646,14 @@ packages:
/mime-db@1.52.0: /mime-db@1.52.0:
resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==}
engines: {node: '>= 0.6'} engines: {node: '>= 0.6'}
dev: true
/mime-types@2.1.35: /mime-types@2.1.35:
resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==}
engines: {node: '>= 0.6'} engines: {node: '>= 0.6'}
dependencies: dependencies:
mime-db: 1.52.0 mime-db: 1.52.0
dev: true
/mime@1.6.0: /mime@1.6.0:
resolution: {integrity: sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==} resolution: {integrity: sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==}