From 271fa4f694dfff29d30debf0258a4f51a33f769e Mon Sep 17 00:00:00 2001 From: fern-api <115122769+fern-api[bot]@users.noreply.github.com> Date: Fri, 26 Jul 2024 09:57:40 -0400 Subject: [PATCH] :herb: introduce OAuth configuration --- .fernignore | 3 ++ src/core/auth/OAuthTokenProvider.ts | 57 +++++++++++++++++++++++++++++ src/index.ts | 2 +- src/wrapper/ChariotClient.ts | 30 +++++++++++++++ 4 files changed, 91 insertions(+), 1 deletion(-) create mode 100644 src/core/auth/OAuthTokenProvider.ts create mode 100644 src/wrapper/ChariotClient.ts diff --git a/.fernignore b/.fernignore index 084a8eb..b6e71ce 100644 --- a/.fernignore +++ b/.fernignore @@ -1 +1,4 @@ # Specify files that shouldn't be modified by Fern +src/wrapper/ +src/core/auth/OAuthTokenProvider.ts +src/index.ts diff --git a/src/core/auth/OAuthTokenProvider.ts b/src/core/auth/OAuthTokenProvider.ts new file mode 100644 index 0000000..de42764 --- /dev/null +++ b/src/core/auth/OAuthTokenProvider.ts @@ -0,0 +1,57 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as core from "../../core"; +import { Auth } from "../../api/resources/auth/client/Client"; + +/** + * The OAuthTokenProvider retrieves an OAuth access token, refreshing it as needed. + * The access token is then used as the bearer token in every authenticated request. + */ +export class OAuthTokenProvider { + private readonly BUFFER_IN_MINUTES = 2; + private readonly _clientId: core.Supplier; + private readonly _clientSecret: core.Supplier; + private readonly _authClient: Auth; + private _accessToken: string | undefined; + private _expiresAt: Date; + + constructor({ + clientId, + clientSecret, + authClient, + }: { + clientId: core.Supplier; + clientSecret: core.Supplier; + authClient: Auth; + }) { + this._clientId = clientId; + this._clientSecret = clientSecret; + this._authClient = authClient; + this._expiresAt = new Date(); + } + + public async getToken(): Promise { + if (this._accessToken && this._expiresAt > new Date()) { + return this._accessToken; + } + return this.refresh(); + } + + private async refresh(): Promise { + const tokenResponse = await this._authClient.getToken({ + clientId: await core.Supplier.get(this._clientId), + clientSecret: await core.Supplier.get(this._clientSecret), + }); + + this._accessToken = tokenResponse.accessToken; + this._expiresAt = this.getExpiresAt(tokenResponse.expiresIn, this.BUFFER_IN_MINUTES); + return this._accessToken; + } + + private getExpiresAt(expiresInSeconds: number, bufferInMinutes: number): Date { + const now = new Date(); + return new Date(now.getTime() + expiresInSeconds * 1000 - bufferInMinutes * 60 * 1000); + } +} \ No newline at end of file diff --git a/src/index.ts b/src/index.ts index 7b115aa..24bfc92 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,4 +1,4 @@ export * as Chariot from "./api"; -export { ChariotClient } from "./Client"; export { ChariotEnvironment } from "./environments"; export { ChariotError, ChariotTimeoutError } from "./errors"; +export { ChariotClient } from "./wrapper/ChariotClient"; diff --git a/src/wrapper/ChariotClient.ts b/src/wrapper/ChariotClient.ts new file mode 100644 index 0000000..58ea9c0 --- /dev/null +++ b/src/wrapper/ChariotClient.ts @@ -0,0 +1,30 @@ +import { Auth } from "api/resources/auth/client/Client"; +import { ChariotClient as FernClient } from "../Client"; +import * as core from "../core"; +import * as environments from "../environments"; +import { OAuthTokenProvider } from "core/auth/OAuthTokenProvider"; + +export declare namespace ChariotClient { + + interface Options { + environment?: core.Supplier; + clientId: core.Supplier; + clientSecret: core.Supplier; + } +} + +export class ChariotClient extends FernClient { + constructor(protected readonly _options: ChariotClient.Options) { + const _oauthTokenProvider = new OAuthTokenProvider({ + clientId: _options.clientId, + clientSecret: _options.clientSecret, + authClient: new Auth({ + environment: _options.environment, + }), + }); + super({ + ..._options, + token: async () => await _oauthTokenProvider.getToken(), + }) + } +} \ No newline at end of file