diff --git a/src/error/codes/index.ts b/src/error/codes/index.ts index 9f751137..7cf2ffa4 100644 --- a/src/error/codes/index.ts +++ b/src/error/codes/index.ts @@ -61,6 +61,7 @@ const SKYFLOW_ERROR_CODE = { MISSING_PRIVATE_KEY: { http_code: 400, message: errorMessages.MISSING_PRIVATE_KEY }, INVALID_ROLES_KEY_TYPE: { http_code: 400, message: errorMessages.INVALID_ROLES_KEY_TYPE }, + INVALID_CONTEXT: { http_code: 400, message: errorMessages.INVALID_CONTEXT }, EMPTY_ROLES: { http_code: 400, message: errorMessages.EMPTY_ROLES }, INVALID_JSON_FORMAT: { http_code: 400, message: errorMessages.INVALID_JSON_FORMAT }, diff --git a/src/error/messages/index.ts b/src/error/messages/index.ts index 21096fad..ab87d0cf 100644 --- a/src/error/messages/index.ts +++ b/src/error/messages/index.ts @@ -61,6 +61,7 @@ const errorMessages = { MISSING_TOKEN_URI: `${errorPrefix} Validation error. Unable to read token URI in credentials. Verify your token URI.`, INVALID_ROLES_KEY_TYPE: `${errorPrefix} Validation error. Invalid roles. Specify roles as an array.`, + INVALID_CONTEXT: `${errorPrefix} Validation error. Invalid context. Specify context as a string.`, EMPTY_ROLES: `${errorPrefix} Validation error. Invalid roles. Specify at least one role.`, INVALID_JSON_FORMAT: `${errorPrefix} Validation error. Credentials is not in valid JSON format. Verify the credentials.`, diff --git a/src/index.ts b/src/index.ts index 9eecf2e3..3aa94484 100644 --- a/src/index.ts +++ b/src/index.ts @@ -12,6 +12,7 @@ import UpdateRequest from './vault/model/request/update'; import FileUploadRequest from './vault/model/request/file-upload'; import QueryRequest from './vault/model/request/query'; import Credentials from './vault/config/credentials'; +import { TokenCredentials, ApiKeyCredentials, PathCredentials, StringCredentials } from './vault/config/credentials'; import TokenizeRequest from './vault/model/request/tokenize'; import TokenizeResponse from './vault/model/response/tokenize'; import { BearerTokenOptions, generateBearerToken, generateBearerTokenFromCreds, generateSignedDataTokens, generateSignedDataTokensFromCreds, GenerateTokenOptions, SignedDataTokensOptions } from './service-account'; @@ -64,6 +65,10 @@ export { generateSignedDataTokensFromCreds, isExpired, Credentials, + ApiKeyCredentials, + TokenCredentials, + PathCredentials, + StringCredentials, RedactionType, OrderByEnum, TokenMode, diff --git a/src/utils/index.ts b/src/utils/index.ts index 28991206..fb4ec347 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -1,7 +1,7 @@ import SkyflowError from "../error"; import * as sdkDetails from "../../package.json"; import { generateBearerToken, generateBearerTokenFromCreds } from "../service-account"; -import Credentials from "../vault/config/credentials"; +import Credentials, { ApiKeyCredentials, PathCredentials, StringCredentials, TokenCredentials } from "../vault/config/credentials"; import dotenv from "dotenv"; import logs from "./logs"; import os from 'os'; @@ -265,21 +265,23 @@ export function removeSDKVersion(message: string): string { } // Helper function to generate token based on credentials -export async function getToken(credentials?: Credentials, logLevel?: LogLevel) { - if (credentials?.credentialsString) { +export async function getToken(credentials: Credentials, logLevel?: LogLevel): Promise<{ accessToken: string }> { + if ('credentialsString' in credentials) { + const stringCred = credentials as StringCredentials; printLog(logs.infoLogs.USING_CREDENTIALS_STRING, MessageType.LOG, logLevel); - return generateBearerTokenFromCreds(credentials.credentialsString, { - roleIDs: credentials.roles, - ctx: credentials.context, + return generateBearerTokenFromCreds(stringCred.credentialsString, { + roleIDs: stringCred.roles, + ctx: stringCred.context, logLevel, }); } - if (credentials?.path) { + if ('path' in credentials) { + const pathCred = credentials as PathCredentials; printLog(logs.infoLogs.USING_PATH, MessageType.LOG, logLevel); - return generateBearerToken(credentials.path, { - roleIDs: credentials.roles, - ctx: credentials.context, + return generateBearerToken(pathCred.path, { + roleIDs: pathCred.roles, + ctx: pathCred.context, logLevel, }); } @@ -293,42 +295,45 @@ export async function getBearerToken(credentials?: Credentials, logLevel?: LogLe if (!credentials && process.env.SKYFLOW_CREDENTIALS === undefined) { throw new SkyflowError(SKYFLOW_ERROR_CODE.EMPTY_CREDENTIALS); } + // If credentials are missing but environment variable exists, use it if (!credentials && process.env.SKYFLOW_CREDENTIALS) { printLog(logs.infoLogs.USING_SKYFLOW_CREDENTIALS_ENV, MessageType.LOG, logLevel); credentials = { credentialsString: process.env.SKYFLOW_CREDENTIALS - } + } as StringCredentials; } - // If token already exists, resolve immediately - if (credentials?.apiKey && credentials.apiKey.trim().length > 0) { - if(isValidAPIKey(credentials?.apiKey)){ + // Handle ApiKeyCredentials + if ('apiKey' in credentials!) { + const apiKeyCred = credentials as ApiKeyCredentials; + if (apiKeyCred.apiKey.trim().length > 0 && isValidAPIKey(apiKeyCred.apiKey)) { printLog(logs.infoLogs.USING_API_KEY, MessageType.LOG, logLevel); - return { type: AuthType.API_KEY, key: credentials.apiKey }; + return { type: AuthType.API_KEY, key: apiKeyCred.apiKey }; } throw new SkyflowError(SKYFLOW_ERROR_CODE.INVALID_API_KEY); } - // If token already exists, resolve immediately - if (credentials?.token) { + // Handle TokenCredentials + if ('token' in credentials!) { + const tokenCred = credentials as TokenCredentials; printLog(logs.infoLogs.USING_BEARER_TOKEN, MessageType.LOG, logLevel); - return { type: AuthType.TOKEN, key: validateToken(credentials.token) }; + return { type: AuthType.TOKEN, key: validateToken(tokenCred.token) }; } printLog(logs.infoLogs.BEARER_TOKEN_LISTENER, MessageType.LOG, logLevel); // Generate token based on provided credentials - const token = await getToken(credentials, logLevel); + const token = await getToken(credentials!, logLevel); printLog(logs.infoLogs.BEARER_TOKEN_RESOLVED, MessageType.LOG, logLevel); return { type: AuthType.TOKEN, key: token.accessToken }; } catch (err) { - throw new SkyflowError(SKYFLOW_ERROR_CODE.INVALID_CREDENTIALS); // rethrow any errors that occur + throw new SkyflowError(SKYFLOW_ERROR_CODE.INVALID_CREDENTIALS); } -}; +} export function getBaseUrl(url: string): string { try { diff --git a/src/utils/validations/index.ts b/src/utils/validations/index.ts index 1b9d51af..c3cf0758 100644 --- a/src/utils/validations/index.ts +++ b/src/utils/validations/index.ts @@ -3,7 +3,7 @@ import { V1Byot } from "../../ _generated_/rest/api"; import SkyflowError from "../../error"; import SKYFLOW_ERROR_CODE from "../../error/codes"; import ConnectionConfig from "../../vault/config/connection"; -import Credentials from "../../vault/config/credentials"; +import Credentials, { ApiKeyCredentials, PathCredentials, StringCredentials, TokenCredentials } from "../../vault/config/credentials"; import VaultConfig from "../../vault/config/vault"; import DetokenizeOptions from "../../vault/model/options/detokenize"; import GetOptions from "../../vault/model/options/get"; @@ -130,42 +130,74 @@ export const validateSkyflowConfig = (config: SkyflowConfig, logLevel: LogLevel export const validateCredentialsWithId = (credentials: Credentials, type: string, typeId: string, id: string, logLevel: LogLevel = LogLevel.ERROR) => { - // validates types for ctx roles - const { token, path, credentialsString, apiKey } = credentials; + if (!credentials) { + throw new SkyflowError(SKYFLOW_ERROR_CODE.INVALID_CREDENTIALS_WITH_ID, [type, typeId, id]); + } + + const isTokenCred = 'token' in credentials; + const isPathCred = 'path' in credentials; + const isStringCred = 'credentialsString' in credentials; + const isApiKeyCred = 'apiKey' in credentials; - // Count how many of the fields are defined - const definedFields = [token, path, credentialsString, apiKey].filter(Boolean).length; + // Check if exactly one credential type is provided + const definedTypes = [isTokenCred, isPathCred, isStringCred, isApiKeyCred].filter(Boolean).length; - // If none are present - if (definedFields === 0) { + if (definedTypes === 0) { throw new SkyflowError(SKYFLOW_ERROR_CODE.INVALID_CREDENTIALS_WITH_ID, [type, typeId, id]); } - // If more than one is present - if (definedFields > 1) { + if (definedTypes > 1) { throw new SkyflowError(SKYFLOW_ERROR_CODE.MULTIPLE_CREDENTIALS_PASSED_WITH_ID, [type, typeId, id]); } - if (credentials?.token && (typeof credentials?.token !== 'string' || isExpired(credentials?.token))) { - printLog(logs.errorLogs.EMPTY_TOKEN_VALUE, MessageType.ERROR, logLevel); - throw new SkyflowError(SKYFLOW_ERROR_CODE.INVALID_BEARER_TOKEN_WITH_ID, [type, typeId, id]); + // Validate TokenCredentials + if (isTokenCred) { + const tokenCred = credentials as TokenCredentials; + if (typeof tokenCred.token !== 'string' || isExpired(tokenCred.token)) { + printLog(logs.errorLogs.EMPTY_TOKEN_VALUE, MessageType.ERROR, logLevel); + throw new SkyflowError(SKYFLOW_ERROR_CODE.INVALID_BEARER_TOKEN_WITH_ID, [type, typeId, id]); + } } - if (credentials?.credentialsString && (typeof credentials?.credentialsString !== 'string' || !isValidCredentialsString(credentials?.credentialsString))) { - printLog(logs.errorLogs.EMPTY_CREDENTIALS_STRING, MessageType.ERROR, logLevel); - throw new SkyflowError(SKYFLOW_ERROR_CODE.INVALID_PARSED_CREDENTIALS_STRING_WITH_ID, [type, typeId, id]); + // Validate PathCredentials + if (isPathCred) { + console.log("PathCredentials"); + const pathCred = credentials as PathCredentials; + if (typeof pathCred.path !== 'string' || !isValidPath(pathCred.path)) { + printLog(logs.errorLogs.EMPTY_CREDENTIALS_PATH, MessageType.ERROR, logLevel); + throw new SkyflowError(SKYFLOW_ERROR_CODE.INVALID_FILE_PATH_WITH_ID, [type, typeId, id]); + } + if (pathCred.roles !== undefined && !Array.isArray(pathCred.roles)) { + throw new SkyflowError(SKYFLOW_ERROR_CODE.INVALID_ROLES_KEY_TYPE, [type, typeId, id]); + } + if (pathCred.context !== undefined && typeof pathCred.context !== 'string') { + throw new SkyflowError(SKYFLOW_ERROR_CODE.INVALID_CONTEXT, [type, typeId, id]); + } } - if (credentials?.apiKey && (typeof credentials?.apiKey !== 'string' || !isValidAPIKey(credentials?.apiKey))) { - printLog(logs.errorLogs.INVALID_API_KEY, MessageType.ERROR, logLevel); - throw new SkyflowError(SKYFLOW_ERROR_CODE.INVALID_API_KEY_WITH_ID, [type, typeId, id]); + // Validate StringCredentials + if (isStringCred) { + const stringCred = credentials as StringCredentials; + if (typeof stringCred.credentialsString !== 'string' || !isValidCredentialsString(stringCred.credentialsString)) { + printLog(logs.errorLogs.EMPTY_CREDENTIALS_STRING, MessageType.ERROR, logLevel); + throw new SkyflowError(SKYFLOW_ERROR_CODE.INVALID_PARSED_CREDENTIALS_STRING_WITH_ID, [type, typeId, id]); + } + if (stringCred.roles !== undefined && !Array.isArray(stringCred.roles)) { + throw new SkyflowError(SKYFLOW_ERROR_CODE.INVALID_ROLES_KEY_TYPE, [type, typeId, id]); + } + if (stringCred.context !== undefined && typeof stringCred.context !== 'string') { + throw new SkyflowError(SKYFLOW_ERROR_CODE.INVALID_CONTEXT, [type, typeId, id]); + } } - if (credentials?.path && (typeof credentials?.path !== 'string' || !isValidPath(credentials?.path))) { - printLog(logs.errorLogs.EMPTY_CREDENTIALS_PATH, MessageType.ERROR, logLevel); - throw new SkyflowError(SKYFLOW_ERROR_CODE.INVALID_FILE_PATH_WITH_ID, [type, typeId, id]); + // Validate ApiKeyCredentials + if (isApiKeyCred) { + const apiKeyCred = credentials as ApiKeyCredentials; + if (typeof apiKeyCred.apiKey !== 'string' || !isValidAPIKey(apiKeyCred.apiKey)) { + printLog(logs.errorLogs.INVALID_API_KEY, MessageType.ERROR, logLevel); + throw new SkyflowError(SKYFLOW_ERROR_CODE.INVALID_API_KEY_WITH_ID, [type, typeId, id]); + } } - }; export const validateVaultConfig = (vaultConfig: VaultConfig, logLevel: LogLevel = LogLevel.ERROR) => { @@ -225,41 +257,73 @@ export const validateUpdateVaultConfig = (vaultConfig: VaultConfig, logLevel: Lo }; export const validateSkyflowCredentials = (credentials: Credentials, logLevel: LogLevel = LogLevel.ERROR) => { - const { token, path, credentialsString, apiKey } = credentials; + if (!credentials) { + throw new SkyflowError(SKYFLOW_ERROR_CODE.CREDENTIALS_WITH_NO_VALID_KEY); + } + + const isTokenCred = 'token' in credentials; + const isPathCred = 'path' in credentials; + const isStringCred = 'credentialsString' in credentials; + const isApiKeyCred = 'apiKey' in credentials; - // Count how many of the fields are defined - const definedFields = [token, path, credentialsString, apiKey].filter(Boolean).length; + // Check if exactly one credential type is provided + const definedTypes = [isTokenCred, isPathCred, isStringCred, isApiKeyCred].filter(Boolean).length; - // If none are present - if (definedFields === 0) { + if (definedTypes === 0) { throw new SkyflowError(SKYFLOW_ERROR_CODE.CREDENTIALS_WITH_NO_VALID_KEY); } - // If more than one is present - if (definedFields > 1) { + if (definedTypes > 1) { throw new SkyflowError(SKYFLOW_ERROR_CODE.MULTIPLE_CREDENTIALS_PASSED); } - if (credentials?.token && (typeof credentials?.token !== 'string' || isExpired(credentials?.token))) { - printLog(logs.errorLogs.EMPTY_TOKEN_VALUE, MessageType.ERROR, logLevel); - throw new SkyflowError(SKYFLOW_ERROR_CODE.INVALID_BEARER_TOKEN); + // Validate TokenCredentials + if (isTokenCred) { + const tokenCred = credentials as TokenCredentials; + if (typeof tokenCred.token !== 'string' || isExpired(tokenCred.token)) { + printLog(logs.errorLogs.EMPTY_TOKEN_VALUE, MessageType.ERROR, logLevel); + throw new SkyflowError(SKYFLOW_ERROR_CODE.INVALID_BEARER_TOKEN); + } } - if (credentials?.credentialsString && (typeof credentials?.credentialsString !== 'string' || !isValidCredentialsString(credentials?.credentialsString))) { - printLog(logs.errorLogs.EMPTY_CREDENTIALS_STRING, MessageType.ERROR, logLevel); - throw new SkyflowError(SKYFLOW_ERROR_CODE.INVALID_PARSED_CREDENTIALS_STRING); + // Validate PathCredentials + if (isPathCred) { + const pathCred = credentials as PathCredentials; + if (typeof pathCred.path !== 'string' || !isValidPath(pathCred.path)) { + printLog(logs.errorLogs.EMPTY_CREDENTIALS_PATH, MessageType.ERROR, logLevel); + throw new SkyflowError(SKYFLOW_ERROR_CODE.INVALID_FILE_PATH); + } + if (pathCred.roles !== undefined && !Array.isArray(pathCred.roles)) { + throw new SkyflowError(SKYFLOW_ERROR_CODE.INVALID_ROLES_KEY_TYPE); + } + if (pathCred.context !== undefined && typeof pathCred.context !== 'string') { + throw new SkyflowError(SKYFLOW_ERROR_CODE.INVALID_CONTEXT); + } } - if (credentials?.apiKey && (typeof credentials?.apiKey !== 'string' || !isValidAPIKey(credentials?.apiKey))) { - printLog(logs.errorLogs.INVALID_API_KEY, MessageType.ERROR, logLevel); - throw new SkyflowError(SKYFLOW_ERROR_CODE.INVALID_API_KEY); + // Validate StringCredentials + if (isStringCred) { + const stringCred = credentials as StringCredentials; + if (typeof stringCred.credentialsString !== 'string' || !isValidCredentialsString(stringCred.credentialsString)) { + printLog(logs.errorLogs.EMPTY_CREDENTIALS_STRING, MessageType.ERROR, logLevel); + throw new SkyflowError(SKYFLOW_ERROR_CODE.INVALID_PARSED_CREDENTIALS_STRING); + } + if (stringCred.roles !== undefined && !Array.isArray(stringCred.roles)) { + throw new SkyflowError(SKYFLOW_ERROR_CODE.INVALID_ROLES_KEY_TYPE); + } + if (stringCred.context !== undefined && typeof stringCred.context !== 'string') { + throw new SkyflowError(SKYFLOW_ERROR_CODE.INVALID_CONTEXT); + } } - if (credentials?.path && (typeof credentials?.path !== 'string' || !isValidPath(credentials?.path))) { - printLog(logs.errorLogs.EMPTY_CREDENTIALS_PATH, MessageType.ERROR, logLevel); - throw new SkyflowError(SKYFLOW_ERROR_CODE.INVALID_FILE_PATH); + // Validate ApiKeyCredentials + if (isApiKeyCred) { + const apiKeyCred = credentials as ApiKeyCredentials; + if (typeof apiKeyCred.apiKey !== 'string' || !isValidAPIKey(apiKeyCred.apiKey)) { + printLog(logs.errorLogs.INVALID_API_KEY, MessageType.ERROR, logLevel); + throw new SkyflowError(SKYFLOW_ERROR_CODE.INVALID_API_KEY); + } } - }; export const validateConnectionConfig = (connectionConfig: ConnectionConfig, logLevel: LogLevel = LogLevel.ERROR) => { diff --git a/src/vault/config/credentials/index.ts b/src/vault/config/credentials/index.ts index 7ad9e022..dbffc723 100644 --- a/src/vault/config/credentials/index.ts +++ b/src/vault/config/credentials/index.ts @@ -1,11 +1,27 @@ +export type Credentials = + | TokenCredentials + | PathCredentials + | StringCredentials + | ApiKeyCredentials; -interface Credentials { - token?: string; - path?: string; - credentialsString?: string; - apiKey?: string; - roles?: Array; - context?: string; +export interface TokenCredentials { + token: string; +} + +export interface PathCredentials { + path: string; + roles?: Array; + context?: string; +} + +export interface StringCredentials { + credentialsString: string; + roles?: Array; + context?: string; +} + +export interface ApiKeyCredentials { + apiKey: string; } export default Credentials; \ No newline at end of file diff --git a/test/vault/utils/utils.test.js b/test/vault/utils/utils.test.js index a9ab6ea1..264a31c9 100644 --- a/test/vault/utils/utils.test.js +++ b/test/vault/utils/utils.test.js @@ -388,7 +388,7 @@ describe('printLog', () => { describe('getToken', () => { const logLevel = LogLevel.INFO; - test('should generate token from credentialsString', async () => { + test('should generate token from StringCredentials', async () => { const credentials = { credentialsString: 'someCredentials', roles: ['role1', 'role2'], @@ -397,7 +397,7 @@ describe('getToken', () => { const mockToken = { accessToken: 'token123' }; generateBearerTokenFromCreds.mockResolvedValue(mockToken); - console.log(getToken) + const result = await getToken(credentials, logLevel); expect(result).toEqual(mockToken); @@ -408,7 +408,7 @@ describe('getToken', () => { }); }); - test('should generate token from path', async () => { + test('should generate token from PathCredentials', async () => { const credentials = { path: '/some/path', roles: ['role1'], @@ -428,6 +428,25 @@ describe('getToken', () => { }); }); + test('should throw error for TokenCredentials', async () => { + const credentials = { + token: 'someToken' + }; + + await expect(getToken(credentials, logLevel)) + .rejects + .toThrow(); + }); + + test('should throw error for ApiKeyCredentials', async () => { + const credentials = { + apiKey: 'sky-api-key' + }; + + await expect(getToken(credentials, logLevel)) + .rejects + .toThrow(); + }); }); describe('getBearerToken', () => { @@ -435,71 +454,72 @@ describe('getBearerToken', () => { beforeEach(() => { jest.clearAllMocks(); - process.env.SKYFLOW_CREDENTIALS = undefined; // Reset environment variable before each test + process.env.SKYFLOW_CREDENTIALS = undefined; }); - test('should use environment variable if no credentials passed but environment variable exists', async () => { - try { - process.env.SKYFLOW_CREDENTIALS = 'someEnvCredentials'; - const mockToken = { accessToken: 'token456' }; - const getToken = jest.fn(); - getToken.mockResolvedValue(mockToken); + test('should throw error if no credentials and no env variable', async () => { + await expect(getBearerToken(undefined, logLevel)) + .rejects + .toThrow(); + }); - const result = await getBearerToken(undefined, logLevel); + test('should use environment variable when credentials not provided', async () => { + process.env.SKYFLOW_CREDENTIALS = 'someEnvCredentials'; + const mockToken = { accessToken: 'token456' }; + generateBearerTokenFromCreds.mockResolvedValue(mockToken); + + const result = await getBearerToken(undefined, logLevel); - expect(getToken).toHaveBeenCalledWith({ - credentialsString: 'someEnvCredentials' - }, logLevel); - expect(result).toEqual({ type: AuthType.TOKEN, key: mockToken.accessToken }); - } catch (err) { - expect(err).toBeDefined(); - } + expect(result).toEqual({"key": "token456", "type": "TOKEN"}); }); - test('should return API key immediately if apiKey is provided in credentials', async () => { - try { - const credentials = { apiKey: 'someApiKey' }; + test('should handle ApiKeyCredentials correctly', async () => { + const credentials = { + apiKey: 'sky-valid-api-key' + }; - const result = await getBearerToken(credentials, logLevel); + const result = await getBearerToken(credentials, logLevel); - expect(result).toEqual({ type: AuthType.API_KEY, key: 'someApiKey' }); - expect(getToken).not.toHaveBeenCalled(); - } catch (err) { - expect(err).toBeDefined(); - } + expect(result).toEqual({"key": "sky-valid-api-key", "type": "API_KEY"}); }); - test('should return token immediately after validating token if token is provided', async () => { - try { - const credentials = { token: 'someToken' }; - validateToken.mockReturnValue('validatedToken'); + test('should handle TokenCredentials correctly', async () => { + const credentials = { + token: 'validToken' + }; + jwt_decode.mockReturnValue({ exp: Date.now() / 1000 + 3600 }); // Valid for 1 hour - const result = await getBearerToken(credentials, logLevel); + const result = await getBearerToken(credentials, logLevel); - expect(validateToken).toHaveBeenCalledWith('someToken'); - expect(result).toEqual({ type: AuthType.TOKEN, key: 'validatedToken' }); - expect(getToken).not.toHaveBeenCalled(); - } catch (err) { - expect(err).toBeDefined(); - } + expect(result).toEqual({"key": "validToken", "type": "TOKEN"}); }); - test('should generate token if valid credentials are provided for token generation', async () => { - try { - const credentials = { credentialsString: 'someCreds' }; - const mockToken = { accessToken: 'generatedToken' }; - const getToken = jest.fn(); - getToken.mockResolvedValue(mockToken); + test('should handle StringCredentials correctly', async () => { + const credentials = { + credentialsString: 'validCredString', + roles: ['role1'], + context: 'test' + }; + const mockToken = { accessToken: 'generatedToken' }; + generateBearerTokenFromCreds.mockResolvedValue(mockToken); - const result = await getBearerToken(credentials, logLevel); + const result = await getBearerToken(credentials, logLevel); - expect(printLog).toHaveBeenCalledWith(logs.infoLogs.BEARER_TOKEN_LISTENER, 'LOG', logLevel); - expect(getToken).toHaveBeenCalledWith(credentials, logLevel); - expect(result).toEqual({ type: AuthType.TOKEN, key: mockToken.accessToken }); - } catch (err) { - expect(err).toBeDefined(); - } + expect(result).toEqual({"key": "generatedToken", "type": "TOKEN"}); }); + test('should handle PathCredentials correctly', async () => { + const credentials = { + path: '/valid/path', + roles: ['role1'], + context: 'test' + }; + const mockToken = { accessToken: 'generatedToken' }; + generateBearerToken.mockResolvedValue(mockToken); + + const result = await getBearerToken(credentials, logLevel); + + expect(result).toEqual({"key": "generatedToken", "type": "TOKEN"}); + }); });