mirror of
https://github.com/usebruno/bruno.git
synced 2026-06-16 04:11:29 +00:00
* feat: enhance OAuth2 support in snippet generation * Updated getAuthHeaders function to handle OAuth2 authentication, including token retrieval and placement. * Added tests for OAuth2 scenarios, ensuring correct Authorization header generation and handling of edge cases. * Improved error handling for access token retrieval from stored credentials. * refactor: standardize comparison operators in getAuthHeaders function * Updated comparison operators in the getAuthHeaders function to use strict equality (===) for improved consistency and reliability in credential checks. * fix: correct block structure in OAuth2 case of getAuthHeaders function * Added missing block structure for the 'oauth2' case in the getAuthHeaders function to ensure proper execution flow and maintain code clarity. * feat: enhance OAuth2 credential retrieval in getAuthHeaders function * Updated getAuthHeaders function to support retrieval of stored OAuth2 credentials based on collection and item context. * Improved access token handling by checking for existing credentials before falling back to default values. * Enhanced test coverage for OAuth2 scenarios to ensure accurate token management and error handling. * fix: preserve tokenHeaderPrefix value in OAuth2 configuration * Updated snippet-generator.spec.js to ensure that the tokenHeaderPrefix from OAuth2 configuration is preserved, allowing for empty string scenarios. * Default to 'Bearer' only if the tokenHeaderPrefix is undefined, enhancing flexibility in token management. * fix: ensure consistent formatting of authorization header in OAuth2 handling * Updated getAuthHeaders function to always trim the final result of the authorization header for consistent formatting. * Adjusted snippet-generator.spec.js to reflect the same trimming logic for the access token, enhancing test reliability. * fix: clarify token placement handling in getAuthHeaders function * Updated comments in the getAuthHeaders function to specify that when tokenPlacement is 'url', no auth headers are added, and that token placement in the URL/query params must be managed separately. * fix: ensure safe handling of OAuth2 credentials in getAuthHeaders function * Updated getAuthHeaders function to default to an empty array when accessing oauth2Credentials, preventing potential errors when no credentials are available.
124 lines
4.3 KiB
JavaScript
124 lines
4.3 KiB
JavaScript
import get from 'lodash/get';
|
|
import { find } from 'lodash';
|
|
import { interpolate } from '@usebruno/common';
|
|
import { getAllVariables } from 'utils/collections/index';
|
|
|
|
export const getAuthHeaders = (collectionRootAuth, requestAuth, collection = null, item = null) => {
|
|
// Discovered edge case where code generation fails when you create a collection which has not been saved yet:
|
|
// Collection auth therefore null, and request inherits from collection, therefore it is also null
|
|
// TypeError: Cannot read properties of undefined (reading 'mode')
|
|
// at getAuthHeaders
|
|
if (!collectionRootAuth && !requestAuth) {
|
|
return [];
|
|
}
|
|
|
|
const auth = collectionRootAuth && ['inherit'].includes(requestAuth?.mode) ? collectionRootAuth : requestAuth;
|
|
|
|
switch (auth.mode) {
|
|
case 'basic':
|
|
const username = get(auth, 'basic.username', '');
|
|
const password = get(auth, 'basic.password', '');
|
|
const basicToken = Buffer.from(`${username}:${password}`).toString('base64');
|
|
|
|
return [
|
|
{
|
|
enabled: true,
|
|
name: 'Authorization',
|
|
value: `Basic ${basicToken}`
|
|
}
|
|
];
|
|
case 'bearer':
|
|
return [
|
|
{
|
|
enabled: true,
|
|
name: 'Authorization',
|
|
value: `Bearer ${get(auth, 'bearer.token', '')}`
|
|
}
|
|
];
|
|
case 'apikey':
|
|
const apiKeyAuth = get(auth, 'apikey', {});
|
|
const key = get(apiKeyAuth, 'key', '');
|
|
const value = get(apiKeyAuth, 'value', '');
|
|
const placement = get(apiKeyAuth, 'placement', 'header');
|
|
|
|
if (placement === 'header') {
|
|
return [
|
|
{
|
|
enabled: true,
|
|
name: key,
|
|
value: value
|
|
}
|
|
];
|
|
}
|
|
return [];
|
|
case 'oauth2': {
|
|
const oauth2Config = get(auth, 'oauth2', {});
|
|
const tokenPlacement = get(oauth2Config, 'tokenPlacement', 'header');
|
|
const tokenHeaderPrefix = get(oauth2Config, 'tokenHeaderPrefix', 'Bearer');
|
|
|
|
// Only add header if token placement is 'header'
|
|
if (tokenPlacement === 'header') {
|
|
// Try to get access token from persisted credentials
|
|
let accessToken = '<access_token>';
|
|
|
|
if (collection && item) {
|
|
try {
|
|
const grantType = get(oauth2Config, 'grantType', '');
|
|
// For implicit grant type, use authorizationUrl; for others, use accessTokenUrl
|
|
const urlToLookup = grantType === 'implicit'
|
|
? get(oauth2Config, 'authorizationUrl', '')
|
|
: get(oauth2Config, 'accessTokenUrl', '');
|
|
const credentialsId = get(oauth2Config, 'credentialsId', 'credentials');
|
|
const collectionUid = get(collection, 'uid');
|
|
|
|
if (urlToLookup && collectionUid) {
|
|
// Interpolate the URL with variables
|
|
const variables = getAllVariables(collection, item);
|
|
const interpolatedUrl = interpolate(urlToLookup, variables);
|
|
|
|
// Look up stored credentials
|
|
const credentialsData = find(
|
|
collection?.oauth2Credentials || [],
|
|
(creds) =>
|
|
creds?.url === interpolatedUrl
|
|
&& creds?.collectionUid === collectionUid
|
|
&& creds?.credentialsId === credentialsId
|
|
);
|
|
|
|
if (credentialsData?.credentials?.access_token) {
|
|
accessToken = credentialsData.credentials.access_token;
|
|
}
|
|
}
|
|
} catch (error) {
|
|
console.error('Error retrieving OAuth2 access token:', error);
|
|
// Fall back to placeholder if lookup fails
|
|
}
|
|
}
|
|
|
|
// Build the authorization header value
|
|
// If tokenHeaderPrefix is empty, just use the token
|
|
// Otherwise, use the format: "prefix token"
|
|
// Always trim the final result for consistent formatting
|
|
const headerValue = (
|
|
tokenHeaderPrefix
|
|
? `${tokenHeaderPrefix} ${accessToken}`
|
|
: accessToken
|
|
).trim();
|
|
|
|
return [
|
|
{
|
|
enabled: true,
|
|
name: 'Authorization',
|
|
value: headerValue
|
|
}
|
|
];
|
|
}
|
|
// If tokenPlacement is 'url', this function does not add any auth headers;
|
|
// token placement in the URL/query params must be handled elsewhere.
|
|
return [];
|
|
}
|
|
default:
|
|
return [];
|
|
}
|
|
};
|