From 7a88a8d9cf5c2b5e4829252682648e83d06aab27 Mon Sep 17 00:00:00 2001 From: roberthicks Date: Wed, 11 Dec 2024 12:23:36 -0500 Subject: [PATCH] feat: Add oauth support --- src/lib/request/request.ts | 21 ++++++++++-- src/lib/request/requestManager.ts | 55 +++++++++++++++++++++++-------- 2 files changed, 60 insertions(+), 16 deletions(-) diff --git a/src/lib/request/request.ts b/src/lib/request/request.ts index c80f7e9..236747a 100644 --- a/src/lib/request/request.ts +++ b/src/lib/request/request.ts @@ -42,6 +42,7 @@ const getTopParentModuleName = (parent: NodeModule | null): string => { const makeSnykRequest = async ( request: SnykRequest, snykToken = '', + oauthBearerToken = '', apiUrl = DEFAULT_API, apiUrlREST = DEFAULT_REST_API, userAgentPrefix = '', @@ -57,12 +58,20 @@ const makeSnykRequest = async ( userAgentPrefix != '' && !userAgentPrefix.endsWith('/') ? userAgentPrefix + '/' : userAgentPrefix; + + // prioritize snykToken but use oauthBearerToken if snykToken isn't provided + const authorizationToken = snykToken + ? `token ${snykToken}` + : oauthBearerToken + ? `Bearer ${oauthBearerToken}` + : ''; + const requestHeaders: Record = { 'Content-Type': request.useRESTApi && request.body ? 'application/vnd.api+json' : 'application/json', - Authorization: 'token ' + snykToken, + Authorization: authorizationToken, 'User-Agent': `${topParentModuleName}${userAgentPrefixChecked}tech-services/snyk-request-manager/1.0`, }; let apiClient; @@ -70,7 +79,10 @@ const makeSnykRequest = async ( apiClient = axios.create({ baseURL: request.useRESTApi ? apiUrlREST : apiUrl, responseType: 'json', - headers: { ...requestHeaders, ...request.headers }, + headers: { + ...requestHeaders, + ...request.headers, + }, transitional: { clarifyTimeoutError: true, }, @@ -81,7 +93,10 @@ const makeSnykRequest = async ( apiClient = axios.create({ baseURL: request.useRESTApi ? apiUrlREST : apiUrl, responseType: 'json', - headers: { ...requestHeaders, ...request.headers }, + headers: { + ...requestHeaders, + ...request.headers, + }, transitional: { clarifyTimeoutError: true, }, diff --git a/src/lib/request/requestManager.ts b/src/lib/request/requestManager.ts index 0f7aa15..5446b8e 100644 --- a/src/lib/request/requestManager.ts +++ b/src/lib/request/requestManager.ts @@ -46,6 +46,11 @@ function getRESTAPI(endpoint: string): string { return new URL(`${apiData.protocol}//${apiData.host}/rest`).toString(); } +function getOauthToken(): string { + const oauthToken: string = process.env.OAUTH_BEARER_TOKEN || ''; + return oauthToken; +} + const getConfig = (): { endpoint: string; token: string } => { const snykApiEndpoint: string = process.env.SNYK_API || @@ -69,6 +74,7 @@ class RequestsManager { _retryCounter: Map; _MAX_RETRY_COUNT: number; _snykToken: string; + _oauthBearerToken?: string; // Optional OAuth token _userAgentPrefix?: string; //snykToken = '', burstSize = 10, period = 500, maxRetryCount = 5 @@ -82,6 +88,7 @@ class RequestsManager { this._events = {}; this._retryCounter = new Map(); this._MAX_RETRY_COUNT = params?.maxRetryCount || 5; + this._oauthBearerToken = getOauthToken(); this._snykToken = params?.snykToken ?? this._userConfig.token; this._apiUrl = this._userConfig.endpoint; this._apiUrlREST = getRESTAPI(this._userConfig.endpoint); @@ -101,19 +108,41 @@ class RequestsManager { _makeRequest = async (request: QueuedRequest): Promise => { const requestId = request.id; try { - const response = await makeSnykRequest( - request.snykRequest, - this._snykToken, - this._apiUrl, - this._apiUrlREST, - this._userAgentPrefix, - ); - this._emit({ - eventType: eventType.data, - channel: request.channel, - requestId, - data: response, - }); + // Pass oauthBearerToken if available + if ( + this._oauthBearerToken != null && + this._oauthBearerToken.trim() != '' + ) { + const response = await makeSnykRequest( + request.snykRequest, + '', + this._oauthBearerToken, + this._apiUrl, + this._apiUrlREST, + this._userAgentPrefix, + ); + this._emit({ + eventType: eventType.data, + channel: request.channel, + requestId, + data: response, + }); + } else { + const response = await makeSnykRequest( + request.snykRequest, + this._snykToken, + '', + this._apiUrl, + this._apiUrlREST, + this._userAgentPrefix, + ); + this._emit({ + eventType: eventType.data, + channel: request.channel, + requestId, + data: response, + }); + } } catch (err) { const overloadedError = requestsManagerError.requestsManagerErrorOverload( err,