From db1397b1cb42aecc314b80b56a084c1ce3eca9a2 Mon Sep 17 00:00:00 2001 From: Yarin Vaknin Date: Fri, 17 Feb 2023 12:51:16 +0200 Subject: [PATCH 1/3] add support for async auth provider --- README.md | 15 +++++++++++++++ src/api-client.ts | 26 +++++++++++++++++--------- src/fireblocks-sdk.ts | 1 + src/iauth-provider.ts | 4 ++-- 4 files changed, 35 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index f76c1869..1368f429 100644 --- a/README.md +++ b/README.md @@ -90,6 +90,21 @@ You can get more data on the Fireblocks error using the following fields: - `error.response.data.message`: Explanation of the Fireblocks error - `error.response.headers['x-request-id']`: The request ID correlated to the API request, should be provided on support tickets / Github issues +#### Async Auth Provider +You can supply an async auth provider instance with the following interface: +```ts +export interface IAuthProvider { + signJwt(path: string, bodyJson?: any): Promise; + getApiKey(): Promise; +} +``` +But you need to make sure to provide sdkOptions to the constructor, with `useAsyncAuthProvider: true` +For example: +```ts +new FireblocksSDK(privateKey, userId, serverAddress, asyncAuthProvider, { + useAsyncAuthProvider: true +}); +``` \ No newline at end of file diff --git a/src/api-client.ts b/src/api-client.ts index c32608a5..111aed9e 100644 --- a/src/api-client.ts +++ b/src/api-client.ts @@ -14,12 +14,20 @@ export class ApiClient { baseURL: this.apiBaseUrl, proxy: this.options?.proxy, timeout: this.options?.timeoutInMs, - headers: { - "X-API-Key": this.authProvider.getApiKey(), + headers: !options.useAsyncAuthProvider ? { + "X-API-Key": this.authProvider.getApiKey() as string, "User-Agent": this.getUserAgent() - } + } : undefined }); + if (options.useAsyncAuthProvider) { + this.axiosInstance.interceptors.request.use(async (config: any) => { + config.headers.common["X-API-Key"] = await this.authProvider.getApiKey(); + config.headers.common["User-Agent"] = this.getUserAgent(); + return config; + }); + } + if (options.customAxiosOptions?.interceptors?.response) { this.axiosInstance.interceptors.response.use(options.customAxiosOptions.interceptors.response.onFulfilled, options.customAxiosOptions.interceptors.response.onRejected); } @@ -37,7 +45,7 @@ export class ApiClient { } public async issueGetRequestForTransactionPages(path: string): Promise { - const token = this.authProvider.signJwt(path); + const token = await this.authProvider.signJwt(path); const res = await this.axiosInstance.get(path, { headers: {"Authorization": `Bearer ${token}`} }); @@ -51,7 +59,7 @@ export class ApiClient { } public async issueGetRequest(path: string): Promise { - const token = this.authProvider.signJwt(path); + const token = await this.authProvider.signJwt(path); const res = await this.axiosInstance.get(path, { headers: {"Authorization": `Bearer ${token}`} }); @@ -59,7 +67,7 @@ export class ApiClient { } public async issuePostRequest(path: string, body: any, requestOptions?: RequestOptions): Promise { - const token = this.authProvider.signJwt(path, body); + const token = await this.authProvider.signJwt(path, body); const headers: any = {"Authorization": `Bearer ${token}`}; const idempotencyKey = requestOptions?.idempotencyKey; if (idempotencyKey) { @@ -70,7 +78,7 @@ export class ApiClient { } public async issuePutRequest(path: string, body: any): Promise { - const token = this.authProvider.signJwt(path, body); + const token = await this.authProvider.signJwt(path, body); const res = (await this.axiosInstance.put(path, body, { headers: {"Authorization": `Bearer ${token}`} })); @@ -78,7 +86,7 @@ export class ApiClient { } public async issuePatchRequest(path: string, body: any): Promise { - const token = this.authProvider.signJwt(path, body); + const token = await this.authProvider.signJwt(path, body); const res = (await this.axiosInstance.patch(path, body, { headers: {"Authorization": `Bearer ${token}`} })); @@ -86,7 +94,7 @@ export class ApiClient { } public async issueDeleteRequest(path: string): Promise { - const token = this.authProvider.signJwt(path); + const token = await this.authProvider.signJwt(path); const res = (await this.axiosInstance.delete(path, { headers: {"Authorization": `Bearer ${token}`} })); diff --git a/src/fireblocks-sdk.ts b/src/fireblocks-sdk.ts index ee65965f..1eaa1a96 100644 --- a/src/fireblocks-sdk.ts +++ b/src/fireblocks-sdk.ts @@ -91,6 +91,7 @@ export interface SDKOptions { }; } }; + useAsyncAuthProvider?: boolean; } export class FireblocksSDK { diff --git a/src/iauth-provider.ts b/src/iauth-provider.ts index afbfa7e2..93540de2 100644 --- a/src/iauth-provider.ts +++ b/src/iauth-provider.ts @@ -1,5 +1,5 @@ export interface IAuthProvider { - signJwt(path: string, bodyJson?: any): string; + signJwt(path: string, bodyJson?: any): string | Promise; - getApiKey(): string; + getApiKey(): string | Promise; } From d60d92bd63911b3daed3a1e8ad0c97494847828f Mon Sep 17 00:00:00 2001 From: Yarin Vaknin Date: Fri, 17 Feb 2023 13:45:05 +0200 Subject: [PATCH 2/3] export IAuthProvider type --- src/fireblocks-sdk.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/fireblocks-sdk.ts b/src/fireblocks-sdk.ts index 1eaa1a96..c13fe05c 100644 --- a/src/fireblocks-sdk.ts +++ b/src/fireblocks-sdk.ts @@ -67,6 +67,8 @@ import { AxiosInterceptorOptions, AxiosProxyConfig, AxiosResponse } from "axios" export * from "./types"; +export * from "./iauth-provider"; + export interface SDKOptions { /** HTTP request timeout */ timeoutInMs?: number; From 7cfd9eb33305f666e0b837e6673d057af3e7967f Mon Sep 17 00:00:00 2001 From: Yarin Vaknin Date: Fri, 17 Feb 2023 14:19:25 +0200 Subject: [PATCH 3/3] fix readme, remove redundant configuration --- README.md | 17 +++++------------ src/api-client.ts | 16 +++++----------- src/fireblocks-sdk.ts | 1 - 3 files changed, 10 insertions(+), 24 deletions(-) diff --git a/README.md b/README.md index 1368f429..2011291c 100644 --- a/README.md +++ b/README.md @@ -90,21 +90,14 @@ You can get more data on the Fireblocks error using the following fields: - `error.response.data.message`: Explanation of the Fireblocks error - `error.response.headers['x-request-id']`: The request ID correlated to the API request, should be provided on support tickets / Github issues -#### Async Auth Provider -You can supply an async auth provider instance with the following interface: +#### Auth Provider +You can supply an async auth provider instance that implements the following interface: ```ts export interface IAuthProvider { - signJwt(path: string, bodyJson?: any): Promise; + signJwt(path: string, bodyJson?: any): string | Promise; - getApiKey(): Promise; + getApiKey(): string | Promise; } ``` -But you need to make sure to provide sdkOptions to the constructor, with `useAsyncAuthProvider: true` - -For example: -```ts -new FireblocksSDK(privateKey, userId, serverAddress, asyncAuthProvider, { - useAsyncAuthProvider: true -}); -``` \ No newline at end of file +Methods can be async. \ No newline at end of file diff --git a/src/api-client.ts b/src/api-client.ts index 111aed9e..90e3c9ed 100644 --- a/src/api-client.ts +++ b/src/api-client.ts @@ -14,19 +14,13 @@ export class ApiClient { baseURL: this.apiBaseUrl, proxy: this.options?.proxy, timeout: this.options?.timeoutInMs, - headers: !options.useAsyncAuthProvider ? { - "X-API-Key": this.authProvider.getApiKey() as string, - "User-Agent": this.getUserAgent() - } : undefined }); - if (options.useAsyncAuthProvider) { - this.axiosInstance.interceptors.request.use(async (config: any) => { - config.headers.common["X-API-Key"] = await this.authProvider.getApiKey(); - config.headers.common["User-Agent"] = this.getUserAgent(); - return config; - }); - } + this.axiosInstance.interceptors.request.use(async (config: any) => { + config.headers.common["X-API-Key"] = await this.authProvider.getApiKey(); + config.headers.common["User-Agent"] = this.getUserAgent(); + return config; + }); if (options.customAxiosOptions?.interceptors?.response) { this.axiosInstance.interceptors.response.use(options.customAxiosOptions.interceptors.response.onFulfilled, options.customAxiosOptions.interceptors.response.onRejected); diff --git a/src/fireblocks-sdk.ts b/src/fireblocks-sdk.ts index c13fe05c..e2dd1594 100644 --- a/src/fireblocks-sdk.ts +++ b/src/fireblocks-sdk.ts @@ -93,7 +93,6 @@ export interface SDKOptions { }; } }; - useAsyncAuthProvider?: boolean; } export class FireblocksSDK {