commit d6c8cc274c5350c86dbd0440b5531c171188e75e
parent be9995c91c24cf8da3e4f1818b9bb5bd49b6d7cc
Author: Sebastian <sebasjm@gmail.com>
Date: Wed, 30 Oct 2024 15:24:57 -0300
add support for bank token auth
Diffstat:
6 files changed, 96 insertions(+), 28 deletions(-)
diff --git a/packages/merchant-backoffice-ui/src/paths/instance/accounts/create/index.tsx b/packages/merchant-backoffice-ui/src/paths/instance/accounts/create/index.tsx
@@ -20,6 +20,7 @@
*/
import {
+ AccessToken,
FacadeCredentials,
HttpStatusCode,
OperationFail,
@@ -28,7 +29,7 @@ import {
TalerError,
TalerMerchantApi,
TalerRevenueHttpClient,
- opFixedSuccess
+ opFixedSuccess,
} from "@gnu-taler/taler-util";
import {
BrowserFetchHttpLib,
@@ -40,6 +41,7 @@ import { NotificationCard } from "../../../../components/menu/index.js";
import { useSessionContext } from "../../../../context/session.js";
import { Notification } from "../../../../utils/types.js";
import { CreatePage } from "./CreatePage.js";
+import { BasicOrTokenAuth } from "@gnu-taler/taler-util";
export type Entity = TalerMerchantApi.AccountAddDetails;
interface Props {
@@ -76,7 +78,8 @@ export default function CreateValidator({ onConfirm, onBack }: Props): VNode {
setNotif({
message: i18n.str`Could not create account`,
type: "ERROR",
- description: error instanceof Error ? error.message : String(error),
+ description:
+ error instanceof Error ? error.message : String(error),
});
});
}}
@@ -105,17 +108,23 @@ export async function testRevenueAPI(
revenueAPI.href,
new BrowserFetchHttpLib(),
);
- const auth =
+ const auth: BasicOrTokenAuth | undefined =
creds === undefined
? undefined
: creds.type === "none"
? undefined
: creds.type === "basic"
? {
+ type: "basic",
username: creds.username,
password: creds.password,
}
- : undefined;
+ : creds.type === "bearer"
+ ? {
+ type: "bearer",
+ token: creds.token as AccessToken,
+ }
+ : undefined;
try {
const config = await api.getConfig(auth);
@@ -131,10 +140,10 @@ export async function testRevenueAPI(
if (!resp.body.credit_account) {
return {
- type:"fail",
+ type: "fail",
case: TestRevenueErrorType.CANT_VALIDATE,
detail: undefined,
- }
+ };
}
return opFixedSuccess(resp.body.credit_account as PaytoString);
} catch (err) {
diff --git a/packages/merchant-backoffice-ui/src/paths/instance/accounts/update/UpdatePage.tsx b/packages/merchant-backoffice-ui/src/paths/instance/accounts/update/UpdatePage.tsx
@@ -54,7 +54,7 @@ type FormType = TalerMerchantApi.AccountPatchDetails & {
verified: boolean;
payto_uri?: PaytoString;
};
-const accountAuthType = ["unedit", "none", "basic"];
+const accountAuthType = ["unedit", "none", "basic", "bearer"];
interface Props {
onUpdate: (d: TalerMerchantApi.AccountPatchDetails) => Promise<void>;
onReplace: (
@@ -125,6 +125,13 @@ export function UpdatePage({
? i18n.str`Required`
: undefined,
+ token:
+ state.credit_facade_credentials?.type !== "bearer"
+ ? undefined
+ : !state.credit_facade_credentials.token
+ ? i18n.str`Required`
+ : undefined,
+
password:
state.credit_facade_credentials?.type !== "basic"
? undefined
@@ -157,9 +164,14 @@ export function UpdatePage({
password: state.credit_facade_credentials.password,
username: state.credit_facade_credentials.username,
}
- : {
- type: "none",
- };
+ : state.credit_facade_credentials.type === "bearer"
+ ? {
+ type: "bearer",
+ token: state.credit_facade_credentials.token,
+ }
+ : {
+ type: "none",
+ };
if (replacingAccountId) {
return onReplace(account, {
@@ -300,7 +312,8 @@ export function UpdatePage({
values={accountAuthType}
toStr={(str) => {
if (str === "none") return i18n.str`Without authentication`;
- if (str === "basic") return i18n.str`With authentication`;
+ if (str === "basic") return i18n.str`With password`;
+ if (str === "bearer") return i18n.str`With token`;
return i18n.str`Do not change`;
}}
/>
@@ -319,6 +332,16 @@ export function UpdatePage({
/>
</Fragment>
) : undefined}
+ {state.credit_facade_credentials?.type === "bearer" ? (
+ <Fragment>
+ <Input
+ name="credit_facade_credentials.token"
+ label={i18n.str`Token`}
+ inputType="password"
+ tooltip={i18n.str`Access token to access the account information.`}
+ />
+ </Fragment>
+ ) : undefined}
<InputToggle<FormType>
label={i18n.str`Match`}
tooltip={i18n.str`Check where the information match against the server info.`}
diff --git a/packages/taler-util/src/http-client/bank-revenue.ts b/packages/taler-util/src/http-client/bank-revenue.ts
@@ -30,12 +30,21 @@ import {
opSuccessFromHttp,
opUnknownFailure,
} from "../operation.js";
-import { LongPollParams, PaginationParams } from "../types-taler-common.js";
+import {
+ AccessToken,
+ LongPollParams,
+ PaginationParams,
+} from "../types-taler-common.js";
import {
codecForRevenueConfig,
codecForRevenueIncomingHistory,
} from "../types-taler-revenue.js";
-import { addLongPollingParam, addPaginationParams } from "./utils.js";
+import {
+ addLongPollingParam,
+ addPaginationParams,
+ BasicOrTokenAuth,
+ createAuthorizationHeader,
+} from "./utils.js";
export type TalerBankRevenueResultByMethod<
prop extends keyof TalerRevenueHttpClient,
@@ -44,10 +53,7 @@ export type TalerBankRevenueErrorsByMethod<
prop extends keyof TalerRevenueHttpClient,
> = FailCasesByMethod<TalerRevenueHttpClient, prop>;
-type UsernameAndPassword = {
- username: string;
- password: string;
-};
+
/**
* The API is used by the merchant (or other parties) to query
* for incoming transactions to their account.
@@ -62,7 +68,7 @@ export class TalerRevenueHttpClient {
this.httpLib = httpClient ?? createPlatformHttpLib();
}
- public readonly PROTOCOL_VERSION = "0:0:0";
+ public readonly PROTOCOL_VERSION = "1:0:0";
isCompatible(version: string): boolean {
const compare = LibtoolVersion.compare(this.PROTOCOL_VERSION, version);
@@ -73,14 +79,12 @@ export class TalerRevenueHttpClient {
* https://docs.taler.net/core/api-bank-revenue.html#get--config
*
*/
- async getConfig(auth?: UsernameAndPassword) {
+ async getConfig(auth?: BasicOrTokenAuth) {
const url = new URL(`config`, this.baseUrl);
const resp = await this.httpLib.fetch(url.href, {
method: "GET",
headers: {
- Authorization: auth
- ? makeBasicAuthHeader(auth.username, auth.password)
- : undefined,
+ Authorization: createAuthorizationHeader(auth),
},
});
switch (resp.status) {
@@ -100,7 +104,7 @@ export class TalerRevenueHttpClient {
* @returns
*/
async getHistory(
- auth?: UsernameAndPassword,
+ auth?: BasicOrTokenAuth,
params?: PaginationParams & LongPollParams,
) {
const url = new URL(`history`, this.baseUrl);
@@ -109,9 +113,7 @@ export class TalerRevenueHttpClient {
const resp = await this.httpLib.fetch(url.href, {
method: "GET",
headers: {
- Authorization: auth
- ? makeBasicAuthHeader(auth.username, auth.password)
- : undefined,
+ Authorization: createAuthorizationHeader(auth),
},
});
switch (resp.status) {
diff --git a/packages/taler-util/src/http-client/utils.ts b/packages/taler-util/src/http-client/utils.ts
@@ -46,6 +46,32 @@ export function makeBearerTokenAuthHeader(token: AccessToken): string {
return `Bearer ${token}`;
}
+export type BasicOrTokenAuth = BasicAuth | TokenAuth;
+
+export type BasicAuth = {
+ type: "basic";
+ username: string;
+ password: string;
+};
+
+export type TokenAuth = {
+ type: "bearer";
+ token: AccessToken;
+};
+
+export function createAuthorizationHeader(auth?: BasicOrTokenAuth): string | undefined {
+ if (!auth) return undefined;
+ switch (auth.type) {
+ case "basic": {
+ return makeBasicAuthHeader(auth.username, auth.password);
+ }
+ case "bearer": {
+ return makeBearerTokenAuthHeader(auth.token);
+ }
+ }
+ return undefined;
+}
+
/**
* https://bugs.gnunet.org/view.php?id=7949
*/
diff --git a/packages/taler-util/src/index.ts b/packages/taler-util/src/index.ts
@@ -22,7 +22,7 @@ export * from "./http-client/challenger.js";
export * from "./http-client/exchange.js";
export * from "./http-client/merchant.js";
export * from "./http-client/officer-account.js";
-export { CacheEvictor } from "./http-client/utils.js";
+export { CacheEvictor, BasicOrTokenAuth, BasicAuth, TokenAuth } from "./http-client/utils.js";
export * from "./http-status-codes.js";
export * from "./i18n.js";
export * from "./iban.js";
diff --git a/packages/taler-util/src/types-taler-merchant.ts b/packages/taler-util/src/types-taler-merchant.ts
@@ -1414,7 +1414,8 @@ export interface AccountAddDetails {
export type FacadeCredentials =
| NoFacadeCredentials
- | BasicAuthFacadeCredentials;
+ | BasicAuthFacadeCredentials
+ | BearerAuthFacadeCredentials;
export interface NoFacadeCredentials {
type: "none";
@@ -1430,6 +1431,13 @@ export interface BasicAuthFacadeCredentials {
password: string;
}
+export interface BearerAuthFacadeCredentials {
+ type: "bearer";
+
+ // token to use to authenticate
+ token: string;
+}
+
export interface AccountAddResponse {
// Hash over the wire details (including over the salt).
h_wire: HashCode;