mirror of
https://github.com/usebruno/bruno.git
synced 2026-06-23 12:45:38 +00:00
feat: add WSSE authentication support to gRPC requests (#5455)
* feat: add WSSE authentication support to gRPC requests - Introduced WSSE authentication mode in GrpcAuth component. - Updated supported authentication modes to include WSSE. - Refactored gRPC event handlers to streamline authentication header setting. - Added notes regarding limitations of complex auth modes in gRPC. * fix: update authentication header retrieval in setAuthHeaders function - Refactored the setAuthHeaders function to correctly retrieve WSSE and OAuth2 refresh token URLs from the request object instead of the collectionAuth object. - Added comprehensive tests for various authentication modes, ensuring proper inheritance and request-level overrides for AWS v4, basic, bearer, digest, NTLM, WSSE, API key, and OAuth2 authentication methods. * chore: remove outdated comments on gRPC authentication limitations
This commit is contained in:
@@ -30,6 +30,10 @@ const GrpcAuthMode = ({ item, collection }) => {
|
||||
name: 'OAuth2',
|
||||
mode: 'oauth2'
|
||||
},
|
||||
{
|
||||
name: 'WSSE Auth',
|
||||
mode: 'wsse'
|
||||
},
|
||||
{
|
||||
name: 'Inherit',
|
||||
mode: 'inherit'
|
||||
|
||||
@@ -6,6 +6,7 @@ import BearerAuth from '../../Auth/BearerAuth';
|
||||
import BasicAuth from '../../Auth/BasicAuth';
|
||||
import ApiKeyAuth from '../../Auth/ApiKeyAuth';
|
||||
import OAuth2 from '../../Auth/OAuth2/index';
|
||||
import WsseAuth from '../../Auth/WsseAuth';
|
||||
import StyledWrapper from './StyledWrapper';
|
||||
import { humanizeRequestAuthMode } from 'utils/collections';
|
||||
import { getTreePathFromCollectionToItem } from 'utils/collections/index';
|
||||
@@ -13,7 +14,10 @@ import { updateRequestAuthMode, updateAuth } from 'providers/ReduxStore/slices/c
|
||||
import { saveRequest } from 'providers/ReduxStore/slices/collections/actions';
|
||||
|
||||
// List of auth modes supported by gRPC
|
||||
const supportedGrpcAuthModes = ['basic', 'bearer', 'apikey', 'oauth2', 'none', 'inherit'];
|
||||
// Note: Only header-based auth modes work with gRPC
|
||||
// Complex auth modes like AWS Sig v4, Digest, and NTLM require axios interceptors
|
||||
// and cannot be supported in gRPC requests as of now
|
||||
const supportedGrpcAuthModes = ['basic', 'bearer', 'apikey', 'oauth2', 'wsse', 'none', 'inherit'];
|
||||
|
||||
const GrpcAuth = ({ item, collection }) => {
|
||||
const dispatch = useDispatch();
|
||||
@@ -83,6 +87,9 @@ const GrpcAuth = ({ item, collection }) => {
|
||||
case 'oauth2': {
|
||||
return <OAuth2 collection={collection} item={item} updateAuth={updateAuth} request={request} save={save} />;
|
||||
}
|
||||
case 'wsse': {
|
||||
return <WsseAuth collection={collection} item={item} updateAuth={updateAuth} request={request} save={save} />;
|
||||
}
|
||||
case 'inherit': {
|
||||
const source = getEffectiveAuthSource();
|
||||
|
||||
|
||||
@@ -11,118 +11,7 @@ const { getProcessEnvVars } = require('../../store/process-env');
|
||||
const { getOAuth2TokenUsingPasswordCredentials, getOAuth2TokenUsingClientCredentials, getOAuth2TokenUsingAuthorizationCode } = require('../../utils/oauth2');
|
||||
const { interpolateString } = require('./interpolate-string');
|
||||
const path = require('node:path');
|
||||
|
||||
const setGrpcAuthHeaders = (grpcRequest, request, collectionRoot) => {
|
||||
const collectionAuth = get(collectionRoot, 'request.auth');
|
||||
if (collectionAuth && request.auth?.mode === 'inherit') {
|
||||
if (collectionAuth.mode === 'basic') {
|
||||
grpcRequest.basicAuth = {
|
||||
username: get(collectionAuth, 'basic.username'),
|
||||
password: get(collectionAuth, 'basic.password')
|
||||
};
|
||||
}
|
||||
|
||||
if (collectionAuth.mode === 'bearer') {
|
||||
grpcRequest.headers['Authorization'] = `Bearer ${get(collectionAuth, 'bearer.token')}`;
|
||||
}
|
||||
|
||||
if (collectionAuth.mode === 'apikey') {
|
||||
grpcRequest.headers[collectionAuth.apikey?.key] = collectionAuth.apikey?.value;
|
||||
|
||||
}
|
||||
|
||||
if (collectionAuth.mode === 'oauth2') {
|
||||
const grantType = get(collectionAuth, 'oauth2.grantType');
|
||||
|
||||
if (grantType === 'client_credentials') {
|
||||
grpcRequest.oauth2 = {
|
||||
grantType,
|
||||
accessTokenUrl: get(collectionAuth, 'oauth2.accessTokenUrl'),
|
||||
clientId: get(collectionAuth, 'oauth2.clientId'),
|
||||
clientSecret: get(collectionAuth, 'oauth2.clientSecret'),
|
||||
scope: get(collectionAuth, 'oauth2.scope'),
|
||||
credentialsPlacement: get(collectionAuth, 'oauth2.credentialsPlacement'),
|
||||
tokenPlacement: get(collectionAuth, 'oauth2.tokenPlacement'),
|
||||
tokenHeaderPrefix: get(collectionAuth, 'oauth2.tokenHeaderPrefix'),
|
||||
tokenQueryKey: get(collectionAuth, 'oauth2.tokenQueryKey')
|
||||
};
|
||||
} else if (grantType === 'password') {
|
||||
grpcRequest.oauth2 = {
|
||||
grantType,
|
||||
accessTokenUrl: get(collectionAuth, 'oauth2.accessTokenUrl'),
|
||||
username: get(collectionAuth, 'oauth2.username'),
|
||||
password: get(collectionAuth, 'oauth2.password'),
|
||||
clientId: get(collectionAuth, 'oauth2.clientId'),
|
||||
clientSecret: get(collectionAuth, 'oauth2.clientSecret'),
|
||||
scope: get(collectionAuth, 'oauth2.scope'),
|
||||
credentialsPlacement: get(collectionAuth, 'oauth2.credentialsPlacement'),
|
||||
tokenPlacement: get(collectionAuth, 'oauth2.tokenPlacement'),
|
||||
tokenHeaderPrefix: get(collectionAuth, 'oauth2.tokenHeaderPrefix'),
|
||||
tokenQueryKey: get(collectionAuth, 'oauth2.tokenQueryKey')
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (request.auth && request.auth.mode !== 'inherit') {
|
||||
if (request.auth.mode === 'basic') {
|
||||
grpcRequest.basicAuth = {
|
||||
username: get(request, 'auth.basic.username'),
|
||||
password: get(request, 'auth.basic.password')
|
||||
};
|
||||
}
|
||||
|
||||
if (request.auth.mode === 'bearer') {
|
||||
grpcRequest.headers['Authorization'] = `Bearer ${get(request, 'auth.bearer.token')}`;
|
||||
}
|
||||
|
||||
if (request.auth.mode === 'oauth2') {
|
||||
const grantType = get(request, 'auth.oauth2.grantType');
|
||||
|
||||
|
||||
if (grantType === 'client_credentials') {
|
||||
grpcRequest.oauth2 = {
|
||||
grantType,
|
||||
clientId: get(request, 'auth.oauth2.clientId'),
|
||||
clientSecret: get(request, 'auth.oauth2.clientSecret'),
|
||||
scope: get(request, 'auth.oauth2.scope'),
|
||||
accessTokenUrl: get(request, 'auth.oauth2.accessTokenUrl'),
|
||||
tokenPlacement: get(request, 'auth.oauth2.tokenPlacement'),
|
||||
credentialsPlacement: get(request, 'auth.oauth2.credentialsPlacement'),
|
||||
tokenHeaderPrefix: get(request, 'auth.oauth2.tokenHeaderPrefix'),
|
||||
tokenQueryKey: get(request, 'auth.oauth2.tokenQueryKey')
|
||||
};
|
||||
} else if (grantType === 'password') {
|
||||
grpcRequest.oauth2 = {
|
||||
grantType,
|
||||
username: get(request, 'auth.oauth2.username'),
|
||||
password: get(request, 'auth.oauth2.password'),
|
||||
clientId: get(request, 'auth.oauth2.clientId'),
|
||||
clientSecret: get(request, 'auth.oauth2.clientSecret'),
|
||||
scope: get(request, 'auth.oauth2.scope'),
|
||||
accessTokenUrl: get(request, 'auth.oauth2.accessTokenUrl'),
|
||||
tokenPlacement: get(request, 'auth.oauth2.tokenPlacement'),
|
||||
credentialsPlacement: get(request, 'auth.oauth2.credentialsPlacement'),
|
||||
tokenHeaderPrefix: get(request, 'auth.oauth2.tokenHeaderPrefix'),
|
||||
tokenQueryKey: get(request, 'auth.oauth2.tokenQueryKey')
|
||||
};
|
||||
} else if (grantType === 'authorization_code') {
|
||||
grpcRequest.oauth2 = {
|
||||
grantType,
|
||||
...get(request, 'auth.oauth2')
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
if (request.auth.mode === 'apikey') {
|
||||
grpcRequest.headers[request.auth.apikey?.key] = request.auth.apikey?.value;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return grpcRequest;
|
||||
}
|
||||
const { setAuthHeaders } = require('./prepare-request');
|
||||
|
||||
const prepareRequest = async (item, collection, environment, runtimeVariables, certsAndProxyConfig = {}) => {
|
||||
const request = item.draft ? item.draft.request : item.request;
|
||||
@@ -182,7 +71,7 @@ const prepareRequest = async (item, collection, environment, runtimeVariables, c
|
||||
oauth2CredentialVariables: request.oauth2CredentialVariables,
|
||||
}
|
||||
|
||||
grpcRequest = setGrpcAuthHeaders(grpcRequest, request, collectionRoot);
|
||||
grpcRequest = setAuthHeaders(grpcRequest, request, collectionRoot);
|
||||
|
||||
if (grpcRequest.oauth2) {
|
||||
let requestCopy = cloneDeep(grpcRequest);
|
||||
|
||||
@@ -43,8 +43,8 @@ const setAuthHeaders = (axiosRequest, request, collectionRoot) => {
|
||||
};
|
||||
break;
|
||||
case 'wsse':
|
||||
const username = get(request, 'auth.wsse.username', '');
|
||||
const password = get(request, 'auth.wsse.password', '');
|
||||
const username = get(collectionAuth, 'wsse.username', '');
|
||||
const password = get(collectionAuth, 'wsse.password', '');
|
||||
|
||||
const ts = new Date().toISOString();
|
||||
const nonce = crypto.randomBytes(16).toString('hex');
|
||||
@@ -193,7 +193,7 @@ const setAuthHeaders = (axiosRequest, request, collectionRoot) => {
|
||||
axiosRequest.oauth2 = {
|
||||
grantType: grantType,
|
||||
accessTokenUrl: get(request, 'auth.oauth2.accessTokenUrl'),
|
||||
refreshTokenUrl: get(collectionAuth, 'oauth2.refreshTokenUrl'),
|
||||
refreshTokenUrl: get(request, 'auth.oauth2.refreshTokenUrl'),
|
||||
username: get(request, 'auth.oauth2.username'),
|
||||
password: get(request, 'auth.oauth2.password'),
|
||||
clientId: get(request, 'auth.oauth2.clientId'),
|
||||
@@ -215,7 +215,7 @@ const setAuthHeaders = (axiosRequest, request, collectionRoot) => {
|
||||
callbackUrl: get(request, 'auth.oauth2.callbackUrl'),
|
||||
authorizationUrl: get(request, 'auth.oauth2.authorizationUrl'),
|
||||
accessTokenUrl: get(request, 'auth.oauth2.accessTokenUrl'),
|
||||
refreshTokenUrl: get(collectionAuth, 'oauth2.refreshTokenUrl'),
|
||||
refreshTokenUrl: get(request, 'auth.oauth2.refreshTokenUrl'),
|
||||
clientId: get(request, 'auth.oauth2.clientId'),
|
||||
clientSecret: get(request, 'auth.oauth2.clientSecret'),
|
||||
scope: get(request, 'auth.oauth2.scope'),
|
||||
@@ -251,7 +251,7 @@ const setAuthHeaders = (axiosRequest, request, collectionRoot) => {
|
||||
axiosRequest.oauth2 = {
|
||||
grantType: grantType,
|
||||
accessTokenUrl: get(request, 'auth.oauth2.accessTokenUrl'),
|
||||
refreshTokenUrl: get(collectionAuth, 'oauth2.refreshTokenUrl'),
|
||||
refreshTokenUrl: get(request, 'auth.oauth2.refreshTokenUrl'),
|
||||
clientId: get(request, 'auth.oauth2.clientId'),
|
||||
clientSecret: get(request, 'auth.oauth2.clientSecret'),
|
||||
scope: get(request, 'auth.oauth2.scope'),
|
||||
|
||||
959
packages/bruno-electron/tests/prepare-request.test.js
Normal file
959
packages/bruno-electron/tests/prepare-request.test.js
Normal file
@@ -0,0 +1,959 @@
|
||||
const crypto = require('node:crypto');
|
||||
|
||||
// Mock crypto.randomBytes to return predictable values for testing
|
||||
jest.mock('node:crypto', () => ({
|
||||
...jest.requireActual('node:crypto'),
|
||||
randomBytes: jest.fn(() => Buffer.from('1234567890abcdef', 'hex'))
|
||||
}));
|
||||
|
||||
// Mock the lodash get function with a more sophisticated mock
|
||||
const mockGet = jest.fn();
|
||||
jest.mock('lodash', () => ({
|
||||
get: mockGet,
|
||||
each: jest.fn(),
|
||||
filter: jest.fn(),
|
||||
find: jest.fn()
|
||||
}));
|
||||
|
||||
// Import the function to test
|
||||
const { setAuthHeaders } = require('../src/ipc/network/prepare-request');
|
||||
|
||||
describe('setAuthHeaders', () => {
|
||||
let mockAxiosRequest;
|
||||
let mockRequest;
|
||||
let mockCollectionRoot;
|
||||
|
||||
beforeEach(() => {
|
||||
// Reset all mocks
|
||||
jest.clearAllMocks();
|
||||
|
||||
// Reset crypto mock to return predictable values
|
||||
crypto.randomBytes.mockReturnValue(Buffer.from('1234567890abcdef', 'hex'));
|
||||
|
||||
// Setup default mock objects
|
||||
mockAxiosRequest = {
|
||||
headers: {}
|
||||
};
|
||||
|
||||
mockRequest = {
|
||||
auth: {
|
||||
mode: 'none'
|
||||
}
|
||||
};
|
||||
|
||||
mockCollectionRoot = {
|
||||
request: {
|
||||
auth: null
|
||||
}
|
||||
};
|
||||
|
||||
// Setup a more sophisticated mock for lodash get function
|
||||
mockGet.mockImplementation((obj, path, defaultValue) => {
|
||||
if (!obj) return defaultValue;
|
||||
|
||||
const keys = path.split('.');
|
||||
let current = obj;
|
||||
|
||||
for (const key of keys) {
|
||||
if (current && typeof current === 'object' && key in current) {
|
||||
current = current[key];
|
||||
} else {
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
|
||||
return current;
|
||||
});
|
||||
});
|
||||
|
||||
describe('Collection-level authentication inheritance', () => {
|
||||
test('should inherit AWS v4 authentication from collection', () => {
|
||||
mockCollectionRoot.request.auth = {
|
||||
mode: 'awsv4',
|
||||
awsv4: {
|
||||
accessKeyId: 'test-access-key',
|
||||
secretAccessKey: 'test-secret-key',
|
||||
sessionToken: 'test-session-token',
|
||||
service: 's3',
|
||||
region: 'us-east-1',
|
||||
profileName: 'default'
|
||||
}
|
||||
};
|
||||
|
||||
mockRequest.auth.mode = 'inherit';
|
||||
|
||||
const result = setAuthHeaders(mockAxiosRequest, mockRequest, mockCollectionRoot);
|
||||
|
||||
expect(result.awsv4config).toEqual({
|
||||
accessKeyId: 'test-access-key',
|
||||
secretAccessKey: 'test-secret-key',
|
||||
sessionToken: 'test-session-token',
|
||||
service: 's3',
|
||||
region: 'us-east-1',
|
||||
profileName: 'default'
|
||||
});
|
||||
});
|
||||
|
||||
test('should inherit basic authentication from collection', () => {
|
||||
mockCollectionRoot.request.auth = {
|
||||
mode: 'basic',
|
||||
basic: {
|
||||
username: 'testuser',
|
||||
password: 'testpass'
|
||||
}
|
||||
};
|
||||
|
||||
mockRequest.auth.mode = 'inherit';
|
||||
|
||||
const result = setAuthHeaders(mockAxiosRequest, mockRequest, mockCollectionRoot);
|
||||
|
||||
expect(result.basicAuth).toEqual({
|
||||
username: 'testuser',
|
||||
password: 'testpass'
|
||||
});
|
||||
});
|
||||
|
||||
test('should inherit bearer authentication from collection', () => {
|
||||
mockCollectionRoot.request.auth = {
|
||||
mode: 'bearer',
|
||||
bearer: {
|
||||
token: 'test-token'
|
||||
}
|
||||
};
|
||||
|
||||
mockRequest.auth.mode = 'inherit';
|
||||
|
||||
const result = setAuthHeaders(mockAxiosRequest, mockRequest, mockCollectionRoot);
|
||||
|
||||
expect(result.headers['Authorization']).toBe('Bearer test-token');
|
||||
});
|
||||
|
||||
test('should inherit digest authentication from collection', () => {
|
||||
mockCollectionRoot.request.auth = {
|
||||
mode: 'digest',
|
||||
digest: {
|
||||
username: 'testuser',
|
||||
password: 'testpass'
|
||||
}
|
||||
};
|
||||
|
||||
mockRequest.auth.mode = 'inherit';
|
||||
|
||||
const result = setAuthHeaders(mockAxiosRequest, mockRequest, mockCollectionRoot);
|
||||
|
||||
expect(result.digestConfig).toEqual({
|
||||
username: 'testuser',
|
||||
password: 'testpass'
|
||||
});
|
||||
});
|
||||
|
||||
test('should inherit NTLM authentication from collection', () => {
|
||||
mockCollectionRoot.request.auth = {
|
||||
mode: 'ntlm',
|
||||
ntlm: {
|
||||
username: 'testuser',
|
||||
password: 'testpass',
|
||||
domain: 'testdomain'
|
||||
}
|
||||
};
|
||||
|
||||
mockRequest.auth.mode = 'inherit';
|
||||
|
||||
const result = setAuthHeaders(mockAxiosRequest, mockRequest, mockCollectionRoot);
|
||||
|
||||
expect(result.ntlmConfig).toEqual({
|
||||
username: 'testuser',
|
||||
password: 'testpass',
|
||||
domain: 'testdomain'
|
||||
});
|
||||
});
|
||||
|
||||
test('should inherit WSSE authentication from collection', () => {
|
||||
mockCollectionRoot.request.auth = {
|
||||
mode: 'wsse',
|
||||
wsse: {
|
||||
username: 'testuser',
|
||||
password: 'testpass'
|
||||
}
|
||||
};
|
||||
|
||||
mockRequest.auth.mode = 'inherit';
|
||||
|
||||
const result = setAuthHeaders(mockAxiosRequest, mockRequest, mockCollectionRoot);
|
||||
|
||||
expect(result.headers['X-WSSE']).toMatch(/UsernameToken Username="testuser", PasswordDigest="[^"]+", Nonce="1234567890abcdef", Created="[^"]+"/);
|
||||
});
|
||||
|
||||
test('should inherit API key authentication from collection (header placement)', () => {
|
||||
mockCollectionRoot.request.auth = {
|
||||
mode: 'apikey',
|
||||
apikey: {
|
||||
key: 'X-API-Key',
|
||||
value: 'test-api-key',
|
||||
placement: 'header'
|
||||
}
|
||||
};
|
||||
|
||||
mockRequest.auth.mode = 'inherit';
|
||||
|
||||
const result = setAuthHeaders(mockAxiosRequest, mockRequest, mockCollectionRoot);
|
||||
|
||||
expect(result.headers['X-API-Key']).toBe('test-api-key');
|
||||
});
|
||||
|
||||
test('should inherit API key authentication from collection (query params placement)', () => {
|
||||
mockCollectionRoot.request.auth = {
|
||||
mode: 'apikey',
|
||||
apikey: {
|
||||
key: 'api_key',
|
||||
value: 'test-api-key',
|
||||
placement: 'queryparams'
|
||||
}
|
||||
};
|
||||
|
||||
mockRequest.auth.mode = 'inherit';
|
||||
|
||||
const result = setAuthHeaders(mockAxiosRequest, mockRequest, mockCollectionRoot);
|
||||
|
||||
expect(result.apiKeyAuthValueForQueryParams).toEqual({
|
||||
key: 'api_key',
|
||||
value: 'test-api-key',
|
||||
placement: 'queryparams'
|
||||
});
|
||||
});
|
||||
|
||||
test('should skip API key authentication when key is empty', () => {
|
||||
mockCollectionRoot.request.auth = {
|
||||
mode: 'apikey',
|
||||
apikey: {
|
||||
key: '',
|
||||
value: 'test-api-key',
|
||||
placement: 'header'
|
||||
}
|
||||
};
|
||||
|
||||
mockRequest.auth.mode = 'inherit';
|
||||
|
||||
const result = setAuthHeaders(mockAxiosRequest, mockRequest, mockCollectionRoot);
|
||||
|
||||
expect(result.headers['']).toBeUndefined();
|
||||
});
|
||||
});
|
||||
|
||||
describe('OAuth2 authentication inheritance', () => {
|
||||
test('should inherit OAuth2 password grant from collection', () => {
|
||||
mockCollectionRoot.request.auth = {
|
||||
mode: 'oauth2',
|
||||
oauth2: {
|
||||
grantType: 'password',
|
||||
accessTokenUrl: 'https://example.com/token',
|
||||
refreshTokenUrl: 'https://example.com/refresh',
|
||||
username: 'testuser',
|
||||
password: 'testpass',
|
||||
clientId: 'test-client',
|
||||
clientSecret: 'test-secret',
|
||||
scope: 'read write',
|
||||
credentialsPlacement: 'body',
|
||||
credentialsId: 'test-credentials',
|
||||
tokenPlacement: 'header',
|
||||
tokenHeaderPrefix: 'Bearer',
|
||||
tokenQueryKey: 'access_token',
|
||||
autoFetchToken: true,
|
||||
autoRefreshToken: true,
|
||||
additionalParameters: { authorization: [], token: [], refresh: [] }
|
||||
}
|
||||
};
|
||||
|
||||
mockRequest.auth.mode = 'inherit';
|
||||
|
||||
const result = setAuthHeaders(mockAxiosRequest, mockRequest, mockCollectionRoot);
|
||||
|
||||
expect(result.oauth2).toEqual({
|
||||
grantType: 'password',
|
||||
accessTokenUrl: 'https://example.com/token',
|
||||
refreshTokenUrl: 'https://example.com/refresh',
|
||||
username: 'testuser',
|
||||
password: 'testpass',
|
||||
clientId: 'test-client',
|
||||
clientSecret: 'test-secret',
|
||||
scope: 'read write',
|
||||
credentialsPlacement: 'body',
|
||||
credentialsId: 'test-credentials',
|
||||
tokenPlacement: 'header',
|
||||
tokenHeaderPrefix: 'Bearer',
|
||||
tokenQueryKey: 'access_token',
|
||||
autoFetchToken: true,
|
||||
autoRefreshToken: true,
|
||||
additionalParameters: { authorization: [], token: [], refresh: [] }
|
||||
});
|
||||
});
|
||||
|
||||
test('should inherit OAuth2 authorization_code grant from collection', () => {
|
||||
mockCollectionRoot.request.auth = {
|
||||
mode: 'oauth2',
|
||||
oauth2: {
|
||||
grantType: 'authorization_code',
|
||||
callbackUrl: 'https://example.com/callback',
|
||||
authorizationUrl: 'https://example.com/auth',
|
||||
accessTokenUrl: 'https://example.com/token',
|
||||
refreshTokenUrl: 'https://example.com/refresh',
|
||||
clientId: 'test-client',
|
||||
clientSecret: 'test-secret',
|
||||
scope: 'read write',
|
||||
state: 'random-state',
|
||||
pkce: true,
|
||||
credentialsPlacement: 'body',
|
||||
credentialsId: 'test-credentials',
|
||||
tokenPlacement: 'header',
|
||||
tokenHeaderPrefix: 'Bearer',
|
||||
tokenQueryKey: 'access_token',
|
||||
autoFetchToken: true,
|
||||
autoRefreshToken: true,
|
||||
additionalParameters: { authorization: [], token: [], refresh: [] }
|
||||
}
|
||||
};
|
||||
|
||||
mockRequest.auth.mode = 'inherit';
|
||||
|
||||
const result = setAuthHeaders(mockAxiosRequest, mockRequest, mockCollectionRoot);
|
||||
|
||||
expect(result.oauth2).toEqual({
|
||||
grantType: 'authorization_code',
|
||||
callbackUrl: 'https://example.com/callback',
|
||||
authorizationUrl: 'https://example.com/auth',
|
||||
accessTokenUrl: 'https://example.com/token',
|
||||
refreshTokenUrl: 'https://example.com/refresh',
|
||||
clientId: 'test-client',
|
||||
scope: 'read write',
|
||||
state: 'random-state',
|
||||
pkce: true,
|
||||
credentialsPlacement: 'body',
|
||||
clientSecret: 'test-secret',
|
||||
credentialsId: 'test-credentials',
|
||||
tokenPlacement: 'header',
|
||||
tokenHeaderPrefix: 'Bearer',
|
||||
tokenQueryKey: 'access_token',
|
||||
autoFetchToken: true,
|
||||
autoRefreshToken: true,
|
||||
additionalParameters: { authorization: [], token: [], refresh: [] }
|
||||
});
|
||||
});
|
||||
|
||||
test('should inherit OAuth2 implicit grant from collection', () => {
|
||||
mockCollectionRoot.request.auth = {
|
||||
mode: 'oauth2',
|
||||
oauth2: {
|
||||
grantType: 'implicit',
|
||||
callbackUrl: 'https://example.com/callback',
|
||||
authorizationUrl: 'https://example.com/auth',
|
||||
clientId: 'test-client',
|
||||
scope: 'read write',
|
||||
state: 'random-state',
|
||||
credentialsId: 'test-credentials',
|
||||
tokenPlacement: 'header',
|
||||
tokenHeaderPrefix: 'Bearer',
|
||||
tokenQueryKey: 'access_token',
|
||||
autoFetchToken: true,
|
||||
additionalParameters: { authorization: [], token: [], refresh: [] }
|
||||
}
|
||||
};
|
||||
|
||||
mockRequest.auth.mode = 'inherit';
|
||||
|
||||
const result = setAuthHeaders(mockAxiosRequest, mockRequest, mockCollectionRoot);
|
||||
|
||||
expect(result.oauth2).toEqual({
|
||||
grantType: 'implicit',
|
||||
callbackUrl: 'https://example.com/callback',
|
||||
authorizationUrl: 'https://example.com/auth',
|
||||
clientId: 'test-client',
|
||||
scope: 'read write',
|
||||
state: 'random-state',
|
||||
credentialsId: 'test-credentials',
|
||||
tokenPlacement: 'header',
|
||||
tokenHeaderPrefix: 'Bearer',
|
||||
tokenQueryKey: 'access_token',
|
||||
autoFetchToken: true,
|
||||
additionalParameters: { authorization: [], token: [], refresh: [] }
|
||||
});
|
||||
});
|
||||
|
||||
test('should inherit OAuth2 client_credentials grant from collection', () => {
|
||||
mockCollectionRoot.request.auth = {
|
||||
mode: 'oauth2',
|
||||
oauth2: {
|
||||
grantType: 'client_credentials',
|
||||
accessTokenUrl: 'https://example.com/token',
|
||||
refreshTokenUrl: 'https://example.com/refresh',
|
||||
clientId: 'test-client',
|
||||
clientSecret: 'test-secret',
|
||||
scope: 'read write',
|
||||
credentialsPlacement: 'body',
|
||||
credentialsId: 'test-credentials',
|
||||
tokenPlacement: 'header',
|
||||
tokenHeaderPrefix: 'Bearer',
|
||||
tokenQueryKey: 'access_token',
|
||||
autoFetchToken: true,
|
||||
autoRefreshToken: true,
|
||||
additionalParameters: { authorization: [], token: [], refresh: [] }
|
||||
}
|
||||
};
|
||||
|
||||
mockRequest.auth.mode = 'inherit';
|
||||
|
||||
const result = setAuthHeaders(mockAxiosRequest, mockRequest, mockCollectionRoot);
|
||||
|
||||
expect(result.oauth2).toEqual({
|
||||
grantType: 'client_credentials',
|
||||
accessTokenUrl: 'https://example.com/token',
|
||||
refreshTokenUrl: 'https://example.com/refresh',
|
||||
clientId: 'test-client',
|
||||
clientSecret: 'test-secret',
|
||||
scope: 'read write',
|
||||
credentialsPlacement: 'body',
|
||||
credentialsId: 'test-credentials',
|
||||
tokenPlacement: 'header',
|
||||
tokenHeaderPrefix: 'Bearer',
|
||||
tokenQueryKey: 'access_token',
|
||||
autoFetchToken: true,
|
||||
autoRefreshToken: true,
|
||||
additionalParameters: { authorization: [], token: [], refresh: [] }
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('Request-level authentication (overrides collection)', () => {
|
||||
test('should set AWS v4 authentication at request level', () => {
|
||||
mockCollectionRoot.request.auth = {
|
||||
mode: 'awsv4',
|
||||
awsv4: {
|
||||
accessKeyId: 'test-access-key',
|
||||
secretAccessKey: 'test-secret-key',
|
||||
sessionToken: 'test-session-token',
|
||||
service: 's3',
|
||||
region: 'us-east-1',
|
||||
profileName: 'default'
|
||||
}
|
||||
}
|
||||
mockRequest.auth = {
|
||||
mode: 'awsv4',
|
||||
awsv4: {
|
||||
accessKeyId: 'request-access-key',
|
||||
secretAccessKey: 'request-secret-key',
|
||||
sessionToken: 'request-session-token',
|
||||
service: 's3',
|
||||
region: 'us-west-2',
|
||||
profileName: 'production'
|
||||
}
|
||||
};
|
||||
|
||||
const result = setAuthHeaders(mockAxiosRequest, mockRequest, mockCollectionRoot);
|
||||
|
||||
expect(result.awsv4config).toEqual({
|
||||
accessKeyId: 'request-access-key',
|
||||
secretAccessKey: 'request-secret-key',
|
||||
sessionToken: 'request-session-token',
|
||||
service: 's3',
|
||||
region: 'us-west-2',
|
||||
profileName: 'production'
|
||||
});
|
||||
});
|
||||
|
||||
test('should set basic authentication at request level', () => {
|
||||
mockCollectionRoot.request.auth = {
|
||||
mode: 'basic',
|
||||
basic: {
|
||||
username: 'testuser',
|
||||
password: 'testpass'
|
||||
}
|
||||
};
|
||||
mockRequest.auth = {
|
||||
mode: 'basic',
|
||||
basic: {
|
||||
username: 'requestuser',
|
||||
password: 'requestpass'
|
||||
}
|
||||
};
|
||||
|
||||
const result = setAuthHeaders(mockAxiosRequest, mockRequest, mockCollectionRoot);
|
||||
|
||||
expect(result.basicAuth).toEqual({
|
||||
username: 'requestuser',
|
||||
password: 'requestpass'
|
||||
});
|
||||
});
|
||||
|
||||
test('should set bearer authentication at request level', () => {
|
||||
mockCollectionRoot.request.auth = {
|
||||
mode: 'bearer',
|
||||
bearer: {
|
||||
token: 'test-token'
|
||||
}
|
||||
};
|
||||
mockRequest.auth = {
|
||||
mode: 'bearer',
|
||||
bearer: {
|
||||
token: 'request-token'
|
||||
}
|
||||
};
|
||||
|
||||
const result = setAuthHeaders(mockAxiosRequest, mockRequest, mockCollectionRoot);
|
||||
|
||||
expect(result.headers['Authorization']).toBe('Bearer request-token');
|
||||
});
|
||||
|
||||
test('should set digest authentication at request level', () => {
|
||||
mockCollectionRoot.request.auth = {
|
||||
mode: 'digest',
|
||||
digest: {
|
||||
username: 'testuser',
|
||||
password: 'testpass'
|
||||
}
|
||||
};
|
||||
mockRequest.auth = {
|
||||
mode: 'digest',
|
||||
digest: {
|
||||
username: 'requestuser',
|
||||
password: 'requestpass'
|
||||
}
|
||||
};
|
||||
|
||||
const result = setAuthHeaders(mockAxiosRequest, mockRequest, mockCollectionRoot);
|
||||
|
||||
expect(result.digestConfig).toEqual({
|
||||
username: 'requestuser',
|
||||
password: 'requestpass'
|
||||
});
|
||||
});
|
||||
|
||||
test('should set NTLM authentication at request level', () => {
|
||||
mockCollectionRoot.request.auth = {
|
||||
mode: 'ntlm',
|
||||
ntlm: {
|
||||
username: 'testuser',
|
||||
password: 'testpass',
|
||||
domain: 'testdomain'
|
||||
}
|
||||
};
|
||||
mockRequest.auth = {
|
||||
mode: 'ntlm',
|
||||
ntlm: {
|
||||
username: 'requestuser',
|
||||
password: 'requestpass',
|
||||
domain: 'requestdomain'
|
||||
}
|
||||
};
|
||||
|
||||
const result = setAuthHeaders(mockAxiosRequest, mockRequest, mockCollectionRoot);
|
||||
|
||||
expect(result.ntlmConfig).toEqual({
|
||||
username: 'requestuser',
|
||||
password: 'requestpass',
|
||||
domain: 'requestdomain'
|
||||
});
|
||||
});
|
||||
|
||||
test('should set WSSE authentication at request level', () => {
|
||||
mockCollectionRoot.request.auth = {
|
||||
mode: 'wsse',
|
||||
wsse: {
|
||||
username: 'testuser',
|
||||
password: 'testpass'
|
||||
}
|
||||
};
|
||||
mockRequest.auth = {
|
||||
mode: 'wsse',
|
||||
wsse: {
|
||||
username: 'requestuser',
|
||||
password: 'requestpass'
|
||||
}
|
||||
};
|
||||
|
||||
const result = setAuthHeaders(mockAxiosRequest, mockRequest, mockCollectionRoot);
|
||||
|
||||
expect(result.headers['X-WSSE']).toMatch(/UsernameToken Username="requestuser", PasswordDigest="[^"]+", Nonce="1234567890abcdef", Created="[^"]+"/);
|
||||
});
|
||||
|
||||
test('should set API key authentication at request level (header placement)', () => {
|
||||
mockCollectionRoot.request.auth = {
|
||||
mode: 'apikey',
|
||||
apikey: {
|
||||
key: 'X-Request-API-Key',
|
||||
value: 'test-api-key',
|
||||
placement: 'header'
|
||||
}
|
||||
};
|
||||
mockRequest.auth = {
|
||||
mode: 'apikey',
|
||||
apikey: {
|
||||
key: 'X-Request-API-Key',
|
||||
value: 'request-api-key',
|
||||
placement: 'header'
|
||||
}
|
||||
};
|
||||
|
||||
const result = setAuthHeaders(mockAxiosRequest, mockRequest, mockCollectionRoot);
|
||||
|
||||
expect(result.headers['X-Request-API-Key']).toBe('request-api-key');
|
||||
});
|
||||
|
||||
test('should set API key authentication at request level (query params placement)', () => {
|
||||
mockCollectionRoot.request.auth = {
|
||||
mode: 'apikey',
|
||||
apikey: {
|
||||
key: 'X-Request-API-Key',
|
||||
value: 'test-api-key',
|
||||
placement: 'header'
|
||||
}
|
||||
};
|
||||
mockRequest.auth = {
|
||||
mode: 'apikey',
|
||||
apikey: {
|
||||
key: 'request_api_key',
|
||||
value: 'request-api-key',
|
||||
placement: 'queryparams'
|
||||
}
|
||||
};
|
||||
|
||||
const result = setAuthHeaders(mockAxiosRequest, mockRequest, mockCollectionRoot);
|
||||
|
||||
expect(result.apiKeyAuthValueForQueryParams).toEqual({
|
||||
key: 'request_api_key',
|
||||
value: 'request-api-key',
|
||||
placement: 'queryparams'
|
||||
});
|
||||
});
|
||||
|
||||
test('should set OAuth2 password grant at request level', () => {
|
||||
mockCollectionRoot.request.auth = {
|
||||
mode: 'oauth2',
|
||||
oauth2: {
|
||||
grantType: 'password',
|
||||
accessTokenUrl: 'https://collection.com/token',
|
||||
refreshTokenUrl: 'https://collection.com/refresh',
|
||||
username: 'collectionuser',
|
||||
password: 'collectionpass',
|
||||
clientId: 'collection-client',
|
||||
clientSecret: 'collection-secret',
|
||||
scope: 'read',
|
||||
credentialsPlacement: 'header',
|
||||
credentialsId: 'collection-credentials',
|
||||
tokenPlacement: 'query',
|
||||
tokenHeaderPrefix: 'Token',
|
||||
tokenQueryKey: 'token',
|
||||
autoFetchToken: false,
|
||||
autoRefreshToken: false,
|
||||
additionalParameters: { authorization: [], token: [], refresh: [] }
|
||||
}
|
||||
};
|
||||
mockRequest.auth = {
|
||||
mode: 'oauth2',
|
||||
oauth2: {
|
||||
grantType: 'password',
|
||||
accessTokenUrl: 'https://request.com/token',
|
||||
refreshTokenUrl: 'https://request.com/refresh',
|
||||
username: 'requestuser',
|
||||
password: 'requestpass',
|
||||
clientId: 'request-client',
|
||||
clientSecret: 'request-secret',
|
||||
scope: 'read',
|
||||
credentialsPlacement: 'header',
|
||||
credentialsId: 'request-credentials',
|
||||
tokenPlacement: 'query',
|
||||
tokenHeaderPrefix: 'Token',
|
||||
tokenQueryKey: 'token',
|
||||
autoFetchToken: false,
|
||||
autoRefreshToken: false,
|
||||
additionalParameters: { authorization: [], token: [], refresh: [] }
|
||||
}
|
||||
};
|
||||
|
||||
const result = setAuthHeaders(mockAxiosRequest, mockRequest, mockCollectionRoot);
|
||||
|
||||
expect(result.oauth2).toEqual({
|
||||
grantType: 'password',
|
||||
accessTokenUrl: 'https://request.com/token',
|
||||
refreshTokenUrl: 'https://request.com/refresh',
|
||||
username: 'requestuser',
|
||||
password: 'requestpass',
|
||||
clientId: 'request-client',
|
||||
clientSecret: 'request-secret',
|
||||
scope: 'read',
|
||||
credentialsPlacement: 'header',
|
||||
credentialsId: 'request-credentials',
|
||||
tokenPlacement: 'query',
|
||||
tokenHeaderPrefix: 'Token',
|
||||
tokenQueryKey: 'token',
|
||||
autoFetchToken: false,
|
||||
autoRefreshToken: false,
|
||||
additionalParameters: { authorization: [], token: [], refresh: [] }
|
||||
});
|
||||
});
|
||||
|
||||
test('should set OAuth2 authorization_code grant at request level', () => {
|
||||
mockCollectionRoot.request.auth = {
|
||||
mode: 'oauth2',
|
||||
oauth2: {
|
||||
grantType: 'password',
|
||||
callbackUrl: 'https://collection.com/callback',
|
||||
authorizationUrl: 'https://collection.com/auth',
|
||||
accessTokenUrl: 'https://collection.com/token',
|
||||
refreshTokenUrl: 'https://collection.com/refresh',
|
||||
username: 'collectionuser',
|
||||
password: 'collectionpass',
|
||||
clientId: 'collection-client',
|
||||
clientSecret: 'collection-secret',
|
||||
}
|
||||
};
|
||||
mockRequest.auth = {
|
||||
mode: 'oauth2',
|
||||
oauth2: {
|
||||
grantType: 'authorization_code',
|
||||
callbackUrl: 'https://request.com/callback',
|
||||
authorizationUrl: 'https://request.com/auth',
|
||||
accessTokenUrl: 'https://request.com/token',
|
||||
refreshTokenUrl: 'https://request.com/refresh',
|
||||
clientId: 'request-client',
|
||||
clientSecret: 'request-secret',
|
||||
scope: 'read',
|
||||
state: 'request-state',
|
||||
pkce: false,
|
||||
credentialsPlacement: 'body',
|
||||
credentialsId: 'request-credentials',
|
||||
tokenPlacement: 'header',
|
||||
tokenHeaderPrefix: 'Bearer',
|
||||
tokenQueryKey: 'access_token',
|
||||
autoFetchToken: true,
|
||||
autoRefreshToken: true,
|
||||
additionalParameters: { authorization: [], token: [], refresh: [] }
|
||||
}
|
||||
};
|
||||
|
||||
const result = setAuthHeaders(mockAxiosRequest, mockRequest, mockCollectionRoot);
|
||||
|
||||
expect(result.oauth2).toEqual({
|
||||
grantType: 'authorization_code',
|
||||
callbackUrl: 'https://request.com/callback',
|
||||
authorizationUrl: 'https://request.com/auth',
|
||||
accessTokenUrl: 'https://request.com/token',
|
||||
refreshTokenUrl: 'https://request.com/refresh',
|
||||
clientId: 'request-client',
|
||||
clientSecret: 'request-secret',
|
||||
scope: 'read',
|
||||
state: 'request-state',
|
||||
pkce: false,
|
||||
credentialsPlacement: 'body',
|
||||
credentialsId: 'request-credentials',
|
||||
tokenPlacement: 'header',
|
||||
tokenHeaderPrefix: 'Bearer',
|
||||
tokenQueryKey: 'access_token',
|
||||
autoFetchToken: true,
|
||||
autoRefreshToken: true,
|
||||
additionalParameters: { authorization: [], token: [], refresh: [] }
|
||||
});
|
||||
});
|
||||
|
||||
test('should set OAuth2 implicit grant at request level', () => {
|
||||
mockCollectionRoot.request.auth = {
|
||||
mode: 'oauth2',
|
||||
oauth2: {
|
||||
grantType: 'implicit',
|
||||
callbackUrl: 'https://collection.com/callback',
|
||||
authorizationUrl: 'https://collection.com/auth',
|
||||
clientId: 'collection-client',
|
||||
scope: 'read',
|
||||
state: 'collection-state',
|
||||
credentialsId: 'collection-credentials',
|
||||
tokenPlacement: 'header',
|
||||
tokenHeaderPrefix: 'Bearer',
|
||||
tokenQueryKey: 'access_token',
|
||||
autoFetchToken: true,
|
||||
additionalParameters: { authorization: [], token: [], refresh: [] }
|
||||
}
|
||||
};
|
||||
mockRequest.auth = {
|
||||
mode: 'oauth2',
|
||||
oauth2: {
|
||||
grantType: 'implicit',
|
||||
callbackUrl: 'https://request.com/callback',
|
||||
authorizationUrl: 'https://request.com/auth',
|
||||
clientId: 'request-client',
|
||||
scope: 'read',
|
||||
state: 'request-state',
|
||||
credentialsId: 'request-credentials',
|
||||
tokenPlacement: 'query',
|
||||
tokenHeaderPrefix: 'Token',
|
||||
tokenQueryKey: 'token',
|
||||
autoFetchToken: false,
|
||||
additionalParameters: { authorization: [], token: [], refresh: [] }
|
||||
}
|
||||
};
|
||||
|
||||
const result = setAuthHeaders(mockAxiosRequest, mockRequest, mockCollectionRoot);
|
||||
|
||||
expect(result.oauth2).toEqual({
|
||||
grantType: 'implicit',
|
||||
callbackUrl: 'https://request.com/callback',
|
||||
authorizationUrl: 'https://request.com/auth',
|
||||
clientId: 'request-client',
|
||||
credentialsId: 'request-credentials',
|
||||
scope: 'read',
|
||||
state: 'request-state',
|
||||
tokenPlacement: 'query',
|
||||
tokenHeaderPrefix: 'Token',
|
||||
tokenQueryKey: 'token',
|
||||
autoFetchToken: false,
|
||||
additionalParameters: { authorization: [], token: [], refresh: [] }
|
||||
});
|
||||
});
|
||||
|
||||
test('should set OAuth2 client_credentials grant at request level', () => {
|
||||
mockCollectionRoot.request.auth = {
|
||||
mode: 'oauth2',
|
||||
oauth2: {
|
||||
grantType: 'client_credentials',
|
||||
accessTokenUrl: 'https://collection.com/token',
|
||||
refreshTokenUrl: 'https://collection.com/refresh',
|
||||
clientId: 'collection-client',
|
||||
clientSecret: 'collection-secret',
|
||||
scope: 'read',
|
||||
credentialsPlacement: 'body',
|
||||
credentialsId: 'collection-credentials',
|
||||
tokenPlacement: 'header',
|
||||
tokenHeaderPrefix: 'Bearer',
|
||||
tokenQueryKey: 'access_token',
|
||||
autoFetchToken: true,
|
||||
autoRefreshToken: true,
|
||||
additionalParameters: { authorization: [], token: [], refresh: [] }
|
||||
}
|
||||
};
|
||||
mockRequest.auth = {
|
||||
mode: 'oauth2',
|
||||
oauth2: {
|
||||
grantType: 'client_credentials',
|
||||
accessTokenUrl: 'https://request.com/token',
|
||||
refreshTokenUrl: 'https://request.com/refresh',
|
||||
clientId: 'request-client',
|
||||
clientSecret: 'request-secret',
|
||||
scope: 'read',
|
||||
credentialsPlacement: 'body',
|
||||
credentialsId: 'request-credentials',
|
||||
tokenPlacement: 'header',
|
||||
tokenHeaderPrefix: 'Bearer',
|
||||
tokenQueryKey: 'access_token',
|
||||
autoFetchToken: true,
|
||||
autoRefreshToken: true,
|
||||
additionalParameters: { authorization: [], token: [], refresh: [] }
|
||||
}
|
||||
};
|
||||
|
||||
const result = setAuthHeaders(mockAxiosRequest, mockRequest, mockCollectionRoot);
|
||||
|
||||
expect(result.oauth2).toEqual({
|
||||
grantType: 'client_credentials',
|
||||
accessTokenUrl: 'https://request.com/token',
|
||||
refreshTokenUrl: 'https://request.com/refresh',
|
||||
clientId: 'request-client',
|
||||
clientSecret: 'request-secret',
|
||||
scope: 'read',
|
||||
credentialsPlacement: 'body',
|
||||
credentialsId: 'request-credentials',
|
||||
tokenPlacement: 'header',
|
||||
tokenHeaderPrefix: 'Bearer',
|
||||
tokenQueryKey: 'access_token',
|
||||
autoFetchToken: true,
|
||||
autoRefreshToken: true,
|
||||
additionalParameters: { authorization: [], token: [], refresh: [] }
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('Edge cases and error handling', () => {
|
||||
test('should handle missing collection auth gracefully', () => {
|
||||
mockCollectionRoot.request.auth = null;
|
||||
mockRequest.auth = {
|
||||
mode: 'basic',
|
||||
basic: {
|
||||
username: 'testuser',
|
||||
password: 'testpass'
|
||||
}
|
||||
};
|
||||
|
||||
const result = setAuthHeaders(mockAxiosRequest, mockRequest, mockCollectionRoot);
|
||||
|
||||
expect(result.basicAuth).toEqual({
|
||||
username: 'testuser',
|
||||
password: 'testpass'
|
||||
});
|
||||
});
|
||||
|
||||
test('should handle missing request auth gracefully', () => {
|
||||
mockRequest.auth = null;
|
||||
|
||||
const result = setAuthHeaders(mockAxiosRequest, mockRequest, mockCollectionRoot);
|
||||
|
||||
expect(result).toBe(mockAxiosRequest);
|
||||
expect(result.headers).toEqual({});
|
||||
});
|
||||
|
||||
test('should handle missing auth mode gracefully', () => {
|
||||
mockRequest.auth = {};
|
||||
|
||||
const result = setAuthHeaders(mockAxiosRequest, mockRequest, mockCollectionRoot);
|
||||
|
||||
expect(result).toBe(mockAxiosRequest);
|
||||
expect(result.headers).toEqual({});
|
||||
});
|
||||
|
||||
test('should handle unknown auth mode gracefully', () => {
|
||||
mockRequest.auth = {
|
||||
mode: 'unknown'
|
||||
};
|
||||
|
||||
const result = setAuthHeaders(mockAxiosRequest, mockRequest, mockCollectionRoot);
|
||||
|
||||
expect(result).toBe(mockAxiosRequest);
|
||||
expect(result.headers).toEqual({});
|
||||
});
|
||||
|
||||
test('should handle missing OAuth2 grant type gracefully', () => {
|
||||
mockRequest.auth = {
|
||||
mode: 'oauth2',
|
||||
oauth2: {}
|
||||
};
|
||||
|
||||
const result = setAuthHeaders(mockAxiosRequest, mockRequest, mockCollectionRoot);
|
||||
|
||||
expect(result).toBe(mockAxiosRequest);
|
||||
expect(result.oauth2).toBeUndefined();
|
||||
});
|
||||
|
||||
test('should handle unknown OAuth2 grant type gracefully', () => {
|
||||
mockRequest.auth = {
|
||||
mode: 'oauth2',
|
||||
oauth2: {
|
||||
grantType: 'unknown_grant'
|
||||
}
|
||||
};
|
||||
|
||||
const result = setAuthHeaders(mockAxiosRequest, mockRequest, mockCollectionRoot);
|
||||
|
||||
expect(result).toBe(mockAxiosRequest);
|
||||
expect(result.oauth2).toBeUndefined();
|
||||
});
|
||||
|
||||
test('should return the modified axiosRequest object', () => {
|
||||
mockRequest.auth = {
|
||||
mode: 'bearer',
|
||||
bearer: {
|
||||
token: 'test-token'
|
||||
}
|
||||
};
|
||||
|
||||
const result = setAuthHeaders(mockAxiosRequest, mockRequest, mockCollectionRoot);
|
||||
|
||||
expect(result).toBe(mockAxiosRequest);
|
||||
expect(result.headers['Authorization']).toBe('Bearer test-token');
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user