From 96ef5780020d47329a312e0cb55a7c04adae50da Mon Sep 17 00:00:00 2001 From: David Knaack Date: Thu, 7 May 2026 15:01:45 +0200 Subject: [PATCH 1/2] chore: Rename IAS convenience functions --- .changeset/empty-dryers-boil.md | 2 +- .changeset/stupid-files-create.md | 2 +- packages/connectivity/src/index.ts | 4 +- .../src/scp-cf/destination/ias-types.ts | 4 +- .../service-binding-to-destination.spec.ts | 82 +++++++++---------- .../service-binding-to-destination.ts | 4 +- .../src/scp-cf/identity-service.ts | 6 +- .../src/scp-cf/token-accessor.spec.ts | 62 +++++++------- .../connectivity/src/scp-cf/token-accessor.ts | 6 +- 9 files changed, 89 insertions(+), 83 deletions(-) diff --git a/.changeset/empty-dryers-boil.md b/.changeset/empty-dryers-boil.md index 9cd119ae44..c33b136130 100644 --- a/.changeset/empty-dryers-boil.md +++ b/.changeset/empty-dryers-boil.md @@ -2,5 +2,5 @@ '@sap-cloud-sdk/connectivity': minor --- -[New Functionality] Add `getIasDestination()` convenience function to build IAS-backed destinations. +[New Functionality] Add `createDestinationFromIasService()` convenience function to build IAS-backed destinations. This function aims to offer more convenience for obtaining IAS-backed destinations outside SAP BTP-environments. diff --git a/.changeset/stupid-files-create.md b/.changeset/stupid-files-create.md index 4005a17b77..31957eb414 100644 --- a/.changeset/stupid-files-create.md +++ b/.changeset/stupid-files-create.md @@ -2,5 +2,5 @@ '@sap-cloud-sdk/connectivity': minor --- -[New Functionality] Add `getIasToken()` convenience function to fetch IAS token. +[New Functionality] Add `getTokenFromIasService()` convenience function to fetch IAS token. This function aims to offer more convenience for obtaining IAS tokens outside SAP BTP-environments. diff --git a/packages/connectivity/src/index.ts b/packages/connectivity/src/index.ts index d3b6f8cc5a..0f72e52506 100644 --- a/packages/connectivity/src/index.ts +++ b/packages/connectivity/src/index.ts @@ -17,8 +17,8 @@ export { retrieveJwt, jwtBearerToken, serviceToken, - getIasToken, - getIasDestination, + getTokenFromIasService, + createDestinationFromIasService, isHttpDestination, assertHttpDestination, DestinationSelectionStrategies, diff --git a/packages/connectivity/src/scp-cf/destination/ias-types.ts b/packages/connectivity/src/scp-cf/destination/ias-types.ts index d70d96c276..c2de85ed3c 100644 --- a/packages/connectivity/src/scp-cf/destination/ias-types.ts +++ b/packages/connectivity/src/scp-cf/destination/ias-types.ts @@ -107,7 +107,7 @@ export interface IasOptionsBusinessUser extends IasOptionsBase { export type IasOptions = IasOptionsTechnicalUser | IasOptionsBusinessUser; /** - * Options for fetching an IAS token via {@link getIasToken}. + * Options for fetching an IAS token via {@link getTokenFromIasService}. */ export type IasTokenOptions = IasOptions & CachingOptions & { @@ -121,7 +121,7 @@ export type IasTokenOptions = IasOptions & }; /** - * Result of an IAS token request via {@link getIasToken}. + * Result of an IAS token request via {@link getTokenFromIasService}. * Contains the access token expiration information, and an optional refresh token (available for JWT bearer flows). */ export interface IasTokenResult { diff --git a/packages/connectivity/src/scp-cf/destination/service-binding-to-destination.spec.ts b/packages/connectivity/src/scp-cf/destination/service-binding-to-destination.spec.ts index 9909f3fbb2..4dd041f851 100644 --- a/packages/connectivity/src/scp-cf/destination/service-binding-to-destination.spec.ts +++ b/packages/connectivity/src/scp-cf/destination/service-binding-to-destination.spec.ts @@ -1,6 +1,6 @@ import { resolveServiceBinding } from '../environment-accessor/service-bindings'; import { decodeJwt } from '../jwt'; -import { serviceToken, getIasToken } from '../token-accessor'; +import { serviceToken, getTokenFromIasService } from '../token-accessor'; import { transformServiceBindingToClientCredentialsDestination, transformServiceBindingToDestination @@ -8,7 +8,7 @@ import { jest.mock('../token-accessor', () => ({ serviceToken: jest.fn(), - getIasToken: jest.fn() + getTokenFromIasService: jest.fn() })); jest.mock('../jwt', () => ({ @@ -123,7 +123,7 @@ const services = { describe('service binding to destination', () => { beforeAll(() => { (serviceToken as jest.Mock).mockResolvedValue('access-token'); - (getIasToken as jest.Mock).mockResolvedValue({ + (getTokenFromIasService as jest.Mock).mockResolvedValue({ token: 'ias-access-token', expiresIn: 3600 }); @@ -296,7 +296,7 @@ describe('service binding to destination', () => { ]) }) ); - expect(getIasToken).toHaveBeenCalledWith( + expect(getTokenFromIasService).toHaveBeenCalledWith( expect.objectContaining({ label: 'identity', name: 'my-identity-service' @@ -328,7 +328,7 @@ describe('service binding to destination', () => { ]) }) ); - expect(getIasToken).toHaveBeenCalledWith( + expect(getTokenFromIasService).toHaveBeenCalledWith( expect.objectContaining({ label: 'identity' }), @@ -351,7 +351,7 @@ describe('service binding to destination', () => { authentication: 'OAuth2ClientCredentials' }) ); - expect(getIasToken).toHaveBeenCalledWith( + expect(getTokenFromIasService).toHaveBeenCalledWith( expect.objectContaining({ label: 'identity' }), @@ -465,7 +465,7 @@ describe('service binding to destination', () => { authentication: 'OAuth2JWTBearer' }) ); - expect(getIasToken).toHaveBeenCalledWith( + expect(getTokenFromIasService).toHaveBeenCalledWith( expect.objectContaining({ label: 'identity' }), @@ -498,7 +498,7 @@ describe('service binding to destination', () => { authentication: 'OAuth2JWTBearer' }) ); - expect(getIasToken).toHaveBeenCalledWith( + expect(getTokenFromIasService).toHaveBeenCalledWith( expect.objectContaining({ label: 'identity' }), @@ -517,7 +517,7 @@ describe('service binding to destination', () => { beforeEach(() => { jest.clearAllMocks(); // Re-apply mock after clearAllMocks - (getIasToken as jest.Mock).mockResolvedValue({ + (getTokenFromIasService as jest.Mock).mockResolvedValue({ token: 'ias-access-token', expiresIn: 3600 }); @@ -545,7 +545,7 @@ describe('service binding to destination', () => { } ); - expect(getIasToken).toHaveBeenCalledWith( + expect(getTokenFromIasService).toHaveBeenCalledWith( expect.objectContaining({ label: 'identity' }), @@ -567,7 +567,7 @@ describe('service binding to destination', () => { } ); - expect(getIasToken).toHaveBeenCalledWith( + expect(getTokenFromIasService).toHaveBeenCalledWith( expect.objectContaining({ label: 'identity' }), @@ -586,7 +586,7 @@ describe('service binding to destination', () => { } ); - expect(getIasToken).toHaveBeenCalledWith( + expect(getTokenFromIasService).toHaveBeenCalledWith( expect.objectContaining({ label: 'identity' }), @@ -621,7 +621,7 @@ describe('service binding to destination', () => { } ); - expect(getIasToken).toHaveBeenCalledWith( + expect(getTokenFromIasService).toHaveBeenCalledWith( expect.objectContaining({ label: 'identity' }), @@ -640,19 +640,19 @@ describe('service binding to destination', () => { beforeEach(() => { jest.clearAllMocks(); // Re-apply mock after clearAllMocks - (getIasToken as jest.Mock).mockResolvedValue({ + (getTokenFromIasService as jest.Mock).mockResolvedValue({ token: 'ias-access-token', expiresIn: 3600 }); }); - it('passes useCache true by default to getIasToken', async () => { + it('passes useCache true by default to getTokenFromIasService', async () => { await transformServiceBindingToDestination( resolveServiceBinding('identity'), { jwt: { app_tid: 'tenant-123' } } ); - expect(getIasToken).toHaveBeenCalledWith( + expect(getTokenFromIasService).toHaveBeenCalledWith( expect.objectContaining({ label: 'identity' }), expect.objectContaining({ useCache: true }) ); @@ -664,7 +664,7 @@ describe('service binding to destination', () => { { jwt: { app_tid: 'tenant-123' }, useCache: false } ); - expect(getIasToken).toHaveBeenCalledWith( + expect(getTokenFromIasService).toHaveBeenCalledWith( expect.objectContaining({ label: 'identity' }), expect.objectContaining({ useCache: false }) ); @@ -676,13 +676,13 @@ describe('service binding to destination', () => { { jwt: { app_tid: 'tenant-123' }, useCache: true } ); - expect(getIasToken).toHaveBeenCalledWith( + expect(getTokenFromIasService).toHaveBeenCalledWith( expect.objectContaining({ label: 'identity' }), expect.objectContaining({ useCache: true }) ); }); - it('passes resource parameter to getIasToken', async () => { + it('passes resource parameter to getTokenFromIasService', async () => { const resource = { name: 'my-app' }; await transformServiceBindingToDestination( @@ -693,13 +693,13 @@ describe('service binding to destination', () => { } ); - expect(getIasToken).toHaveBeenCalledWith( + expect(getTokenFromIasService).toHaveBeenCalledWith( expect.objectContaining({ label: 'identity' }), expect.objectContaining({ resource }) ); }); - it('passes different resource parameters to getIasToken', async () => { + it('passes different resource parameters to getTokenFromIasService', async () => { await transformServiceBindingToDestination( resolveServiceBinding('identity'), { @@ -708,7 +708,7 @@ describe('service binding to destination', () => { } ); - expect(getIasToken).toHaveBeenCalledWith( + expect(getTokenFromIasService).toHaveBeenCalledWith( expect.objectContaining({ label: 'identity' }), expect.objectContaining({ resource: { name: 'app1' } }) ); @@ -721,20 +721,20 @@ describe('service binding to destination', () => { } ); - expect(getIasToken).toHaveBeenCalledTimes(2); - expect(getIasToken).toHaveBeenLastCalledWith( + expect(getTokenFromIasService).toHaveBeenCalledTimes(2); + expect(getTokenFromIasService).toHaveBeenLastCalledWith( expect.objectContaining({ label: 'identity' }), expect.objectContaining({ resource: { name: 'app2' } }) ); }); - it('passes jwt for tenant context to getIasToken', async () => { + it('passes jwt for tenant context to getTokenFromIasService', async () => { await transformServiceBindingToDestination( resolveServiceBinding('identity'), { jwt: { app_tid: 'tenant-123' } } ); - expect(getIasToken).toHaveBeenCalledWith( + expect(getTokenFromIasService).toHaveBeenCalledWith( expect.objectContaining({ label: 'identity' }), expect.objectContaining({ jwt: { app_tid: 'tenant-123' } }) ); @@ -744,14 +744,14 @@ describe('service binding to destination', () => { { jwt: { app_tid: 'tenant-456' } } ); - expect(getIasToken).toHaveBeenCalledTimes(2); - expect(getIasToken).toHaveBeenLastCalledWith( + expect(getTokenFromIasService).toHaveBeenCalledTimes(2); + expect(getTokenFromIasService).toHaveBeenLastCalledWith( expect.objectContaining({ label: 'identity' }), expect.objectContaining({ jwt: { app_tid: 'tenant-456' } }) ); }); - it('passes resource with providerClientId to getIasToken', async () => { + it('passes resource with providerClientId to getTokenFromIasService', async () => { const resource = { providerClientId: 'resource-client-123' }; await transformServiceBindingToDestination( @@ -762,13 +762,13 @@ describe('service binding to destination', () => { } ); - expect(getIasToken).toHaveBeenCalledWith( + expect(getTokenFromIasService).toHaveBeenCalledWith( expect.objectContaining({ label: 'identity' }), expect.objectContaining({ resource }) ); }); - it('passes resource with providerClientId and providerTenantId to getIasToken', async () => { + it('passes resource with providerClientId and providerTenantId to getTokenFromIasService', async () => { const resource = { providerClientId: 'resource-client-123', providerTenantId: 'resource-tenant-456' @@ -782,13 +782,13 @@ describe('service binding to destination', () => { } ); - expect(getIasToken).toHaveBeenCalledWith( + expect(getTokenFromIasService).toHaveBeenCalledWith( expect.objectContaining({ label: 'identity' }), expect.objectContaining({ resource }) ); }); - it('passes OAuth2JWTBearer authenticationType to getIasToken', async () => { + it('passes OAuth2JWTBearer authenticationType to getTokenFromIasService', async () => { await transformServiceBindingToDestination( resolveServiceBinding('identity'), { @@ -800,7 +800,7 @@ describe('service binding to destination', () => { } ); - expect(getIasToken).toHaveBeenCalledWith( + expect(getTokenFromIasService).toHaveBeenCalledWith( expect.objectContaining({ label: 'identity' }), expect.objectContaining({ authenticationType: 'OAuth2JWTBearer', @@ -809,19 +809,19 @@ describe('service binding to destination', () => { ); }); - it('calls getIasToken without jwt when no jwt is provided', async () => { + it('calls getTokenFromIasService without jwt when no jwt is provided', async () => { await transformServiceBindingToDestination( resolveServiceBinding('identity') ); - expect(getIasToken).toHaveBeenCalledTimes(1); - expect(getIasToken).toHaveBeenCalledWith( + expect(getTokenFromIasService).toHaveBeenCalledTimes(1); + expect(getTokenFromIasService).toHaveBeenCalledWith( expect.objectContaining({ label: 'identity' }), expect.objectContaining({ useCache: true }) ); }); - it('passes different service bindings to getIasToken', async () => { + it('passes different service bindings to getTokenFromIasService', async () => { const iasService1 = { ...services.identity[0], name: 'ias-service-1', @@ -846,7 +846,7 @@ describe('service binding to destination', () => { jwt: { app_tid: 'tenant-123' } }); - expect(getIasToken).toHaveBeenCalledWith( + expect(getTokenFromIasService).toHaveBeenCalledWith( expect.objectContaining({ name: 'ias-service-1' }), expect.objectContaining({ jwt: { app_tid: 'tenant-123' } }) ); @@ -855,8 +855,8 @@ describe('service binding to destination', () => { jwt: { app_tid: 'tenant-123' } }); - expect(getIasToken).toHaveBeenCalledTimes(2); - expect(getIasToken).toHaveBeenLastCalledWith( + expect(getTokenFromIasService).toHaveBeenCalledTimes(2); + expect(getTokenFromIasService).toHaveBeenLastCalledWith( expect.objectContaining({ name: 'ias-service-2' }), expect.objectContaining({ jwt: { app_tid: 'tenant-123' } }) ); diff --git a/packages/connectivity/src/scp-cf/destination/service-binding-to-destination.ts b/packages/connectivity/src/scp-cf/destination/service-binding-to-destination.ts index 5db2058889..3a1c1fe32b 100644 --- a/packages/connectivity/src/scp-cf/destination/service-binding-to-destination.ts +++ b/packages/connectivity/src/scp-cf/destination/service-binding-to-destination.ts @@ -1,4 +1,4 @@ -import { serviceToken, getIasToken } from '../token-accessor'; +import { serviceToken, getTokenFromIasService } from '../token-accessor'; import { buildDestination, buildIasDestination } from './build-ias-destination'; import type { Service } from '../environment-accessor'; import type { @@ -171,7 +171,7 @@ async function transformIasBindingToDestination( ...(options?.iasOptions || {}) }; - const { token } = await getIasToken(service, { + const { token } = await getTokenFromIasService(service, { jwt: options?.jwt, useCache: options?.useCache !== false, ...iasOptions diff --git a/packages/connectivity/src/scp-cf/identity-service.ts b/packages/connectivity/src/scp-cf/identity-service.ts index 3a4180484d..870011aa39 100644 --- a/packages/connectivity/src/scp-cf/identity-service.ts +++ b/packages/connectivity/src/scp-cf/identity-service.ts @@ -103,7 +103,7 @@ export async function fetchIasToken( IasTokenResponse, MiddlewareContext >(resilience(), { - fn: getIasTokenImpl, + fn: getTokenFromIasServiceImpl, fnArgument, context: { uri: fnArgument.serviceCredentials.url, @@ -207,7 +207,9 @@ function transformIasOptionsToXssecArgs( * @returns A promise resolving to the client credentials response. * @internal */ -async function getIasTokenImpl(arg: IasParameters): Promise { +async function getTokenFromIasServiceImpl( + arg: IasParameters +): Promise { const jwtForSubdomain = // For OAuth2JWTBearer authentication, subdomain will be extracted from the assertion arg.authenticationType === 'OAuth2JWTBearer' diff --git a/packages/connectivity/src/scp-cf/token-accessor.spec.ts b/packages/connectivity/src/scp-cf/token-accessor.spec.ts index bd848ab521..ae14d487d6 100644 --- a/packages/connectivity/src/scp-cf/token-accessor.spec.ts +++ b/packages/connectivity/src/scp-cf/token-accessor.spec.ts @@ -31,14 +31,14 @@ import { clientCredentialsTokenCache } from './client-credentials-token-cache'; import { jwtBearerToken, serviceToken, - getIasToken, - getIasDestination + getTokenFromIasService, + createDestinationFromIasService } from './token-accessor'; import { clearXsuaaServices } from './environment-accessor'; import type { Service } from './environment-accessor'; import type { ClientCredentialsResponse } from './xsuaa-service-types'; -// Mock fetchIasToken so getIasToken tests don't need to set up xssec internals +// Mock fetchIasToken so getTokenFromIasService tests don't need to set up xssec internals jest.mock('./identity-service', () => ({ ...jest.requireActual('./identity-service'), fetchIasToken: jest.fn(), @@ -380,7 +380,7 @@ describe('token accessor', () => { }); }); -describe('getIasToken()', () => { +describe('getTokenFromIasService()', () => { const identityServiceMock = jest.requireMock('./identity-service'); let mockFetchIasToken: jest.Mock; let mockGetIasAppTid: jest.Mock; @@ -431,7 +431,7 @@ describe('getIasToken()', () => { describe('input types', () => { it('accepts a Service object', async () => { - const result = await getIasToken(mockService); + const result = await getTokenFromIasService(mockService); expect(mockFetchIasToken).toHaveBeenCalledWith( mockService, @@ -443,7 +443,7 @@ describe('getIasToken()', () => { }); it('accepts raw ServiceCredentials and wraps them in a Service', async () => { - await getIasToken(mockService.credentials); + await getTokenFromIasService(mockService.credentials); expect(mockFetchIasToken).toHaveBeenCalledWith( expect.objectContaining({ @@ -458,7 +458,7 @@ describe('getIasToken()', () => { it('accepts a service type string and resolves the binding', async () => { // 'destination' is bound via mockServiceBindings() - await getIasToken('destination'); + await getTokenFromIasService('destination'); expect(mockFetchIasToken).toHaveBeenCalledWith( expect.objectContaining({ label: 'destination' }), @@ -469,7 +469,7 @@ describe('getIasToken()', () => { describe('return value', () => { it('returns an IasTokenResult with token, expiresIn, and no refreshToken by default', async () => { - const result = await getIasToken(mockService); + const result = await getTokenFromIasService(mockService); expect(result.token); expect(result.expiresIn).toBe(3600); @@ -482,7 +482,7 @@ describe('getIasToken()', () => { refresh_token: 'my-refresh-token' }); - const result = await getIasToken(mockService); + const result = await getTokenFromIasService(mockService); expect(result.token).toBe(rawAccessToken); expect(result.expiresIn).toBe(3600); @@ -492,7 +492,7 @@ describe('getIasToken()', () => { describe('authenticationType', () => { it('defaults to OAuth2ClientCredentials', async () => { - await getIasToken(mockService); + await getTokenFromIasService(mockService); expect(mockFetchIasToken).toHaveBeenCalledWith( expect.anything(), @@ -505,7 +505,7 @@ describe('getIasToken()', () => { it('passes OAuth2JWTBearer with assertion', async () => { const assertion = signedJwt({ user_uuid: 'user-1', app_tid: 'tid' }); - await getIasToken(mockService, { + await getTokenFromIasService(mockService, { authenticationType: 'OAuth2JWTBearer', assertion }); @@ -522,7 +522,7 @@ describe('getIasToken()', () => { it('does not resolve appTid for OAuth2JWTBearer', async () => { const assertion = signedJwt({ user_uuid: 'user-1', app_tid: 'tid' }); - await getIasToken(mockService, { + await getTokenFromIasService(mockService, { authenticationType: 'OAuth2JWTBearer', assertion }); @@ -536,7 +536,7 @@ describe('getIasToken()', () => { const jwt = { app_tid: 'subscriber-tid', iss: 'https://sub.example.com' }; mockGetIasAppTid.mockReturnValue('subscriber-tid'); - await getIasToken(mockService, { jwt }); + await getTokenFromIasService(mockService, { jwt }); expect(mockGetIasAppTid).toHaveBeenCalledWith( expect.objectContaining({ @@ -552,7 +552,7 @@ describe('getIasToken()', () => { }); it('does not call getIasAppTid when appTid is explicitly provided', async () => { - await getIasToken(mockService, { appTid: 'explicit-tid' }); + await getTokenFromIasService(mockService, { appTid: 'explicit-tid' }); expect(mockGetIasAppTid).not.toHaveBeenCalled(); expect(mockFetchIasToken).toHaveBeenCalledWith( @@ -564,7 +564,7 @@ describe('getIasToken()', () => { it('passes jwt to fetchIasToken for subdomain routing', async () => { const jwt = { app_tid: 'subscriber-tid', iss: 'https://sub.example.com' }; - await getIasToken(mockService, { jwt }); + await getTokenFromIasService(mockService, { jwt }); expect(mockFetchIasToken).toHaveBeenCalledWith( expect.anything(), @@ -575,7 +575,7 @@ describe('getIasToken()', () => { describe('caching', () => { it('passes useCache: true by default', async () => { - await getIasToken(mockService); + await getTokenFromIasService(mockService); expect(mockFetchIasToken).toHaveBeenCalledWith( expect.anything(), @@ -584,7 +584,7 @@ describe('getIasToken()', () => { }); it('passes useCache: false when explicitly disabled', async () => { - await getIasToken(mockService, { useCache: false }); + await getTokenFromIasService(mockService, { useCache: false }); expect(mockFetchIasToken).toHaveBeenCalledWith( expect.anything(), @@ -595,7 +595,9 @@ describe('getIasToken()', () => { describe('resource parameter', () => { it('passes resource (by name) to fetchIasToken', async () => { - await getIasToken(mockService, { resource: { name: 'my-app' } }); + await getTokenFromIasService(mockService, { + resource: { name: 'my-app' } + }); expect(mockFetchIasToken).toHaveBeenCalledWith( expect.anything(), @@ -604,7 +606,7 @@ describe('getIasToken()', () => { }); it('passes resource (by providerClientId) to fetchIasToken', async () => { - await getIasToken(mockService, { + await getTokenFromIasService(mockService, { resource: { providerClientId: 'provider-client', providerTenantId: 'provider-tenant' @@ -631,20 +633,22 @@ describe('getIasToken()', () => { ) ); - await expect(getIasToken(mockService)).rejects.toThrow( + await expect(getTokenFromIasService(mockService)).rejects.toThrow( 'Could not fetch IAS client for service "my-ias"' ); }); it('throws when service string cannot be resolved', async () => { - await expect(getIasToken('nonexistent-service')).rejects.toThrow( + await expect( + getTokenFromIasService('nonexistent-service') + ).rejects.toThrow( "Could not find service binding of type 'nonexistent-service'." ); }); }); }); -describe('getIasDestination()', () => { +describe('createDestinationFromIasService()', () => { const identityServiceMock = jest.requireMock('./identity-service'); let mockFetchIasToken: jest.Mock; let mockGetIasAppTid: jest.Mock; @@ -689,7 +693,7 @@ describe('getIasDestination()', () => { }); it('returns an HttpDestination with token and service URL', async () => { - const destination = await getIasDestination(mockCredentials); + const destination = await createDestinationFromIasService(mockCredentials); expect(destination).toEqual( expect.objectContaining({ @@ -707,7 +711,7 @@ describe('getIasDestination()', () => { }); it('includes mTLS key pair when certificate and key are present', async () => { - const destination = await getIasDestination(mockCredentials); + const destination = await createDestinationFromIasService(mockCredentials); expect(destination.mtlsKeyPair).toEqual({ cert: '-----BEGIN CERTIFICATE-----\ntest\n-----END CERTIFICATE-----', @@ -718,13 +722,13 @@ describe('getIasDestination()', () => { it('does not include mTLS key pair when certificate/key are absent', async () => { const { certificate: _c, key: _k, ...credsWithoutCert } = mockCredentials; - const destination = await getIasDestination(credsWithoutCert); + const destination = await createDestinationFromIasService(credsWithoutCert); expect(destination.mtlsKeyPair).toBeUndefined(); }); it('uses targetUrl when provided', async () => { - const destination = await getIasDestination(mockCredentials, { + const destination = await createDestinationFromIasService(mockCredentials, { targetUrl: 'https://custom-target.example.com' }); @@ -734,7 +738,7 @@ describe('getIasDestination()', () => { it('uses OAuth2JWTBearer authentication type when specified', async () => { const assertion = signedJwt({ user_uuid: 'user-1', app_tid: 'tid' }); - const destination = await getIasDestination(mockCredentials, { + const destination = await createDestinationFromIasService(mockCredentials, { authenticationType: 'OAuth2JWTBearer', assertion }); @@ -742,8 +746,8 @@ describe('getIasDestination()', () => { expect(destination.authentication).toBe('OAuth2JWTBearer'); }); - it('delegates to getIasToken with the provided options', async () => { - await getIasDestination(mockCredentials, { + it('delegates to getTokenFromIasService with the provided options', async () => { + await createDestinationFromIasService(mockCredentials, { useCache: false, jwt: { app_tid: 'tenant-123' } }); diff --git a/packages/connectivity/src/scp-cf/token-accessor.ts b/packages/connectivity/src/scp-cf/token-accessor.ts index 604ee521a0..a3c6ea3185 100644 --- a/packages/connectivity/src/scp-cf/token-accessor.ts +++ b/packages/connectivity/src/scp-cf/token-accessor.ts @@ -121,7 +121,7 @@ async function resolveIdentityService( * @param options - Options for IAS token retrieval. See {@link IasTokenOptions}. * @returns An {@link IasTokenResult} containing the access token, expiration, and optional refresh token. */ -export async function getIasToken( +export async function getTokenFromIasService( service: ServiceCredentials | 'identity' | Service = 'identity', options?: IasTokenOptions ): Promise { @@ -165,12 +165,12 @@ export async function getIasToken( * @param options - Options for IAS token retrieval and destination configuration. See {@link IasTokenOptions}. * @returns A promise that resolves to an HTTP destination. */ -export async function getIasDestination( +export async function createDestinationFromIasService( service: ServiceCredentials | 'identity' | Service = 'identity', options?: IasTokenOptions ): Promise { const resolvedService = await resolveIdentityService(service); - const { token } = await getIasToken(resolvedService, options); + const { token } = await getTokenFromIasService(resolvedService, options); const iasOptions: IasOptions = { authenticationType: 'OAuth2ClientCredentials', From 566ab30182eb4d8721e78341f9cac63db41a96a6 Mon Sep 17 00:00:00 2001 From: David Knaack Date: Fri, 8 May 2026 09:26:58 +0200 Subject: [PATCH 2/2] revert back to getIasToken() --- .changeset/stupid-files-create.md | 2 +- packages/connectivity/src/index.ts | 2 +- .../src/scp-cf/destination/ias-types.ts | 4 +- .../service-binding-to-destination.spec.ts | 82 +++++++++---------- .../service-binding-to-destination.ts | 4 +- .../src/scp-cf/identity-service.ts | 6 +- .../src/scp-cf/token-accessor.spec.ts | 44 +++++----- .../connectivity/src/scp-cf/token-accessor.ts | 4 +- 8 files changed, 72 insertions(+), 76 deletions(-) diff --git a/.changeset/stupid-files-create.md b/.changeset/stupid-files-create.md index 31957eb414..4005a17b77 100644 --- a/.changeset/stupid-files-create.md +++ b/.changeset/stupid-files-create.md @@ -2,5 +2,5 @@ '@sap-cloud-sdk/connectivity': minor --- -[New Functionality] Add `getTokenFromIasService()` convenience function to fetch IAS token. +[New Functionality] Add `getIasToken()` convenience function to fetch IAS token. This function aims to offer more convenience for obtaining IAS tokens outside SAP BTP-environments. diff --git a/packages/connectivity/src/index.ts b/packages/connectivity/src/index.ts index 0f72e52506..aaa32512f8 100644 --- a/packages/connectivity/src/index.ts +++ b/packages/connectivity/src/index.ts @@ -17,7 +17,7 @@ export { retrieveJwt, jwtBearerToken, serviceToken, - getTokenFromIasService, + getIasToken, createDestinationFromIasService, isHttpDestination, assertHttpDestination, diff --git a/packages/connectivity/src/scp-cf/destination/ias-types.ts b/packages/connectivity/src/scp-cf/destination/ias-types.ts index c2de85ed3c..d70d96c276 100644 --- a/packages/connectivity/src/scp-cf/destination/ias-types.ts +++ b/packages/connectivity/src/scp-cf/destination/ias-types.ts @@ -107,7 +107,7 @@ export interface IasOptionsBusinessUser extends IasOptionsBase { export type IasOptions = IasOptionsTechnicalUser | IasOptionsBusinessUser; /** - * Options for fetching an IAS token via {@link getTokenFromIasService}. + * Options for fetching an IAS token via {@link getIasToken}. */ export type IasTokenOptions = IasOptions & CachingOptions & { @@ -121,7 +121,7 @@ export type IasTokenOptions = IasOptions & }; /** - * Result of an IAS token request via {@link getTokenFromIasService}. + * Result of an IAS token request via {@link getIasToken}. * Contains the access token expiration information, and an optional refresh token (available for JWT bearer flows). */ export interface IasTokenResult { diff --git a/packages/connectivity/src/scp-cf/destination/service-binding-to-destination.spec.ts b/packages/connectivity/src/scp-cf/destination/service-binding-to-destination.spec.ts index 4dd041f851..9909f3fbb2 100644 --- a/packages/connectivity/src/scp-cf/destination/service-binding-to-destination.spec.ts +++ b/packages/connectivity/src/scp-cf/destination/service-binding-to-destination.spec.ts @@ -1,6 +1,6 @@ import { resolveServiceBinding } from '../environment-accessor/service-bindings'; import { decodeJwt } from '../jwt'; -import { serviceToken, getTokenFromIasService } from '../token-accessor'; +import { serviceToken, getIasToken } from '../token-accessor'; import { transformServiceBindingToClientCredentialsDestination, transformServiceBindingToDestination @@ -8,7 +8,7 @@ import { jest.mock('../token-accessor', () => ({ serviceToken: jest.fn(), - getTokenFromIasService: jest.fn() + getIasToken: jest.fn() })); jest.mock('../jwt', () => ({ @@ -123,7 +123,7 @@ const services = { describe('service binding to destination', () => { beforeAll(() => { (serviceToken as jest.Mock).mockResolvedValue('access-token'); - (getTokenFromIasService as jest.Mock).mockResolvedValue({ + (getIasToken as jest.Mock).mockResolvedValue({ token: 'ias-access-token', expiresIn: 3600 }); @@ -296,7 +296,7 @@ describe('service binding to destination', () => { ]) }) ); - expect(getTokenFromIasService).toHaveBeenCalledWith( + expect(getIasToken).toHaveBeenCalledWith( expect.objectContaining({ label: 'identity', name: 'my-identity-service' @@ -328,7 +328,7 @@ describe('service binding to destination', () => { ]) }) ); - expect(getTokenFromIasService).toHaveBeenCalledWith( + expect(getIasToken).toHaveBeenCalledWith( expect.objectContaining({ label: 'identity' }), @@ -351,7 +351,7 @@ describe('service binding to destination', () => { authentication: 'OAuth2ClientCredentials' }) ); - expect(getTokenFromIasService).toHaveBeenCalledWith( + expect(getIasToken).toHaveBeenCalledWith( expect.objectContaining({ label: 'identity' }), @@ -465,7 +465,7 @@ describe('service binding to destination', () => { authentication: 'OAuth2JWTBearer' }) ); - expect(getTokenFromIasService).toHaveBeenCalledWith( + expect(getIasToken).toHaveBeenCalledWith( expect.objectContaining({ label: 'identity' }), @@ -498,7 +498,7 @@ describe('service binding to destination', () => { authentication: 'OAuth2JWTBearer' }) ); - expect(getTokenFromIasService).toHaveBeenCalledWith( + expect(getIasToken).toHaveBeenCalledWith( expect.objectContaining({ label: 'identity' }), @@ -517,7 +517,7 @@ describe('service binding to destination', () => { beforeEach(() => { jest.clearAllMocks(); // Re-apply mock after clearAllMocks - (getTokenFromIasService as jest.Mock).mockResolvedValue({ + (getIasToken as jest.Mock).mockResolvedValue({ token: 'ias-access-token', expiresIn: 3600 }); @@ -545,7 +545,7 @@ describe('service binding to destination', () => { } ); - expect(getTokenFromIasService).toHaveBeenCalledWith( + expect(getIasToken).toHaveBeenCalledWith( expect.objectContaining({ label: 'identity' }), @@ -567,7 +567,7 @@ describe('service binding to destination', () => { } ); - expect(getTokenFromIasService).toHaveBeenCalledWith( + expect(getIasToken).toHaveBeenCalledWith( expect.objectContaining({ label: 'identity' }), @@ -586,7 +586,7 @@ describe('service binding to destination', () => { } ); - expect(getTokenFromIasService).toHaveBeenCalledWith( + expect(getIasToken).toHaveBeenCalledWith( expect.objectContaining({ label: 'identity' }), @@ -621,7 +621,7 @@ describe('service binding to destination', () => { } ); - expect(getTokenFromIasService).toHaveBeenCalledWith( + expect(getIasToken).toHaveBeenCalledWith( expect.objectContaining({ label: 'identity' }), @@ -640,19 +640,19 @@ describe('service binding to destination', () => { beforeEach(() => { jest.clearAllMocks(); // Re-apply mock after clearAllMocks - (getTokenFromIasService as jest.Mock).mockResolvedValue({ + (getIasToken as jest.Mock).mockResolvedValue({ token: 'ias-access-token', expiresIn: 3600 }); }); - it('passes useCache true by default to getTokenFromIasService', async () => { + it('passes useCache true by default to getIasToken', async () => { await transformServiceBindingToDestination( resolveServiceBinding('identity'), { jwt: { app_tid: 'tenant-123' } } ); - expect(getTokenFromIasService).toHaveBeenCalledWith( + expect(getIasToken).toHaveBeenCalledWith( expect.objectContaining({ label: 'identity' }), expect.objectContaining({ useCache: true }) ); @@ -664,7 +664,7 @@ describe('service binding to destination', () => { { jwt: { app_tid: 'tenant-123' }, useCache: false } ); - expect(getTokenFromIasService).toHaveBeenCalledWith( + expect(getIasToken).toHaveBeenCalledWith( expect.objectContaining({ label: 'identity' }), expect.objectContaining({ useCache: false }) ); @@ -676,13 +676,13 @@ describe('service binding to destination', () => { { jwt: { app_tid: 'tenant-123' }, useCache: true } ); - expect(getTokenFromIasService).toHaveBeenCalledWith( + expect(getIasToken).toHaveBeenCalledWith( expect.objectContaining({ label: 'identity' }), expect.objectContaining({ useCache: true }) ); }); - it('passes resource parameter to getTokenFromIasService', async () => { + it('passes resource parameter to getIasToken', async () => { const resource = { name: 'my-app' }; await transformServiceBindingToDestination( @@ -693,13 +693,13 @@ describe('service binding to destination', () => { } ); - expect(getTokenFromIasService).toHaveBeenCalledWith( + expect(getIasToken).toHaveBeenCalledWith( expect.objectContaining({ label: 'identity' }), expect.objectContaining({ resource }) ); }); - it('passes different resource parameters to getTokenFromIasService', async () => { + it('passes different resource parameters to getIasToken', async () => { await transformServiceBindingToDestination( resolveServiceBinding('identity'), { @@ -708,7 +708,7 @@ describe('service binding to destination', () => { } ); - expect(getTokenFromIasService).toHaveBeenCalledWith( + expect(getIasToken).toHaveBeenCalledWith( expect.objectContaining({ label: 'identity' }), expect.objectContaining({ resource: { name: 'app1' } }) ); @@ -721,20 +721,20 @@ describe('service binding to destination', () => { } ); - expect(getTokenFromIasService).toHaveBeenCalledTimes(2); - expect(getTokenFromIasService).toHaveBeenLastCalledWith( + expect(getIasToken).toHaveBeenCalledTimes(2); + expect(getIasToken).toHaveBeenLastCalledWith( expect.objectContaining({ label: 'identity' }), expect.objectContaining({ resource: { name: 'app2' } }) ); }); - it('passes jwt for tenant context to getTokenFromIasService', async () => { + it('passes jwt for tenant context to getIasToken', async () => { await transformServiceBindingToDestination( resolveServiceBinding('identity'), { jwt: { app_tid: 'tenant-123' } } ); - expect(getTokenFromIasService).toHaveBeenCalledWith( + expect(getIasToken).toHaveBeenCalledWith( expect.objectContaining({ label: 'identity' }), expect.objectContaining({ jwt: { app_tid: 'tenant-123' } }) ); @@ -744,14 +744,14 @@ describe('service binding to destination', () => { { jwt: { app_tid: 'tenant-456' } } ); - expect(getTokenFromIasService).toHaveBeenCalledTimes(2); - expect(getTokenFromIasService).toHaveBeenLastCalledWith( + expect(getIasToken).toHaveBeenCalledTimes(2); + expect(getIasToken).toHaveBeenLastCalledWith( expect.objectContaining({ label: 'identity' }), expect.objectContaining({ jwt: { app_tid: 'tenant-456' } }) ); }); - it('passes resource with providerClientId to getTokenFromIasService', async () => { + it('passes resource with providerClientId to getIasToken', async () => { const resource = { providerClientId: 'resource-client-123' }; await transformServiceBindingToDestination( @@ -762,13 +762,13 @@ describe('service binding to destination', () => { } ); - expect(getTokenFromIasService).toHaveBeenCalledWith( + expect(getIasToken).toHaveBeenCalledWith( expect.objectContaining({ label: 'identity' }), expect.objectContaining({ resource }) ); }); - it('passes resource with providerClientId and providerTenantId to getTokenFromIasService', async () => { + it('passes resource with providerClientId and providerTenantId to getIasToken', async () => { const resource = { providerClientId: 'resource-client-123', providerTenantId: 'resource-tenant-456' @@ -782,13 +782,13 @@ describe('service binding to destination', () => { } ); - expect(getTokenFromIasService).toHaveBeenCalledWith( + expect(getIasToken).toHaveBeenCalledWith( expect.objectContaining({ label: 'identity' }), expect.objectContaining({ resource }) ); }); - it('passes OAuth2JWTBearer authenticationType to getTokenFromIasService', async () => { + it('passes OAuth2JWTBearer authenticationType to getIasToken', async () => { await transformServiceBindingToDestination( resolveServiceBinding('identity'), { @@ -800,7 +800,7 @@ describe('service binding to destination', () => { } ); - expect(getTokenFromIasService).toHaveBeenCalledWith( + expect(getIasToken).toHaveBeenCalledWith( expect.objectContaining({ label: 'identity' }), expect.objectContaining({ authenticationType: 'OAuth2JWTBearer', @@ -809,19 +809,19 @@ describe('service binding to destination', () => { ); }); - it('calls getTokenFromIasService without jwt when no jwt is provided', async () => { + it('calls getIasToken without jwt when no jwt is provided', async () => { await transformServiceBindingToDestination( resolveServiceBinding('identity') ); - expect(getTokenFromIasService).toHaveBeenCalledTimes(1); - expect(getTokenFromIasService).toHaveBeenCalledWith( + expect(getIasToken).toHaveBeenCalledTimes(1); + expect(getIasToken).toHaveBeenCalledWith( expect.objectContaining({ label: 'identity' }), expect.objectContaining({ useCache: true }) ); }); - it('passes different service bindings to getTokenFromIasService', async () => { + it('passes different service bindings to getIasToken', async () => { const iasService1 = { ...services.identity[0], name: 'ias-service-1', @@ -846,7 +846,7 @@ describe('service binding to destination', () => { jwt: { app_tid: 'tenant-123' } }); - expect(getTokenFromIasService).toHaveBeenCalledWith( + expect(getIasToken).toHaveBeenCalledWith( expect.objectContaining({ name: 'ias-service-1' }), expect.objectContaining({ jwt: { app_tid: 'tenant-123' } }) ); @@ -855,8 +855,8 @@ describe('service binding to destination', () => { jwt: { app_tid: 'tenant-123' } }); - expect(getTokenFromIasService).toHaveBeenCalledTimes(2); - expect(getTokenFromIasService).toHaveBeenLastCalledWith( + expect(getIasToken).toHaveBeenCalledTimes(2); + expect(getIasToken).toHaveBeenLastCalledWith( expect.objectContaining({ name: 'ias-service-2' }), expect.objectContaining({ jwt: { app_tid: 'tenant-123' } }) ); diff --git a/packages/connectivity/src/scp-cf/destination/service-binding-to-destination.ts b/packages/connectivity/src/scp-cf/destination/service-binding-to-destination.ts index 3a1c1fe32b..5db2058889 100644 --- a/packages/connectivity/src/scp-cf/destination/service-binding-to-destination.ts +++ b/packages/connectivity/src/scp-cf/destination/service-binding-to-destination.ts @@ -1,4 +1,4 @@ -import { serviceToken, getTokenFromIasService } from '../token-accessor'; +import { serviceToken, getIasToken } from '../token-accessor'; import { buildDestination, buildIasDestination } from './build-ias-destination'; import type { Service } from '../environment-accessor'; import type { @@ -171,7 +171,7 @@ async function transformIasBindingToDestination( ...(options?.iasOptions || {}) }; - const { token } = await getTokenFromIasService(service, { + const { token } = await getIasToken(service, { jwt: options?.jwt, useCache: options?.useCache !== false, ...iasOptions diff --git a/packages/connectivity/src/scp-cf/identity-service.ts b/packages/connectivity/src/scp-cf/identity-service.ts index 870011aa39..3a4180484d 100644 --- a/packages/connectivity/src/scp-cf/identity-service.ts +++ b/packages/connectivity/src/scp-cf/identity-service.ts @@ -103,7 +103,7 @@ export async function fetchIasToken( IasTokenResponse, MiddlewareContext >(resilience(), { - fn: getTokenFromIasServiceImpl, + fn: getIasTokenImpl, fnArgument, context: { uri: fnArgument.serviceCredentials.url, @@ -207,9 +207,7 @@ function transformIasOptionsToXssecArgs( * @returns A promise resolving to the client credentials response. * @internal */ -async function getTokenFromIasServiceImpl( - arg: IasParameters -): Promise { +async function getIasTokenImpl(arg: IasParameters): Promise { const jwtForSubdomain = // For OAuth2JWTBearer authentication, subdomain will be extracted from the assertion arg.authenticationType === 'OAuth2JWTBearer' diff --git a/packages/connectivity/src/scp-cf/token-accessor.spec.ts b/packages/connectivity/src/scp-cf/token-accessor.spec.ts index ae14d487d6..9d962e03df 100644 --- a/packages/connectivity/src/scp-cf/token-accessor.spec.ts +++ b/packages/connectivity/src/scp-cf/token-accessor.spec.ts @@ -31,14 +31,14 @@ import { clientCredentialsTokenCache } from './client-credentials-token-cache'; import { jwtBearerToken, serviceToken, - getTokenFromIasService, + getIasToken, createDestinationFromIasService } from './token-accessor'; import { clearXsuaaServices } from './environment-accessor'; import type { Service } from './environment-accessor'; import type { ClientCredentialsResponse } from './xsuaa-service-types'; -// Mock fetchIasToken so getTokenFromIasService tests don't need to set up xssec internals +// Mock fetchIasToken so getIasToken tests don't need to set up xssec internals jest.mock('./identity-service', () => ({ ...jest.requireActual('./identity-service'), fetchIasToken: jest.fn(), @@ -380,7 +380,7 @@ describe('token accessor', () => { }); }); -describe('getTokenFromIasService()', () => { +describe('getIasToken()', () => { const identityServiceMock = jest.requireMock('./identity-service'); let mockFetchIasToken: jest.Mock; let mockGetIasAppTid: jest.Mock; @@ -431,7 +431,7 @@ describe('getTokenFromIasService()', () => { describe('input types', () => { it('accepts a Service object', async () => { - const result = await getTokenFromIasService(mockService); + const result = await getIasToken(mockService); expect(mockFetchIasToken).toHaveBeenCalledWith( mockService, @@ -443,7 +443,7 @@ describe('getTokenFromIasService()', () => { }); it('accepts raw ServiceCredentials and wraps them in a Service', async () => { - await getTokenFromIasService(mockService.credentials); + await getIasToken(mockService.credentials); expect(mockFetchIasToken).toHaveBeenCalledWith( expect.objectContaining({ @@ -458,7 +458,7 @@ describe('getTokenFromIasService()', () => { it('accepts a service type string and resolves the binding', async () => { // 'destination' is bound via mockServiceBindings() - await getTokenFromIasService('destination'); + await getIasToken('destination'); expect(mockFetchIasToken).toHaveBeenCalledWith( expect.objectContaining({ label: 'destination' }), @@ -469,7 +469,7 @@ describe('getTokenFromIasService()', () => { describe('return value', () => { it('returns an IasTokenResult with token, expiresIn, and no refreshToken by default', async () => { - const result = await getTokenFromIasService(mockService); + const result = await getIasToken(mockService); expect(result.token); expect(result.expiresIn).toBe(3600); @@ -482,7 +482,7 @@ describe('getTokenFromIasService()', () => { refresh_token: 'my-refresh-token' }); - const result = await getTokenFromIasService(mockService); + const result = await getIasToken(mockService); expect(result.token).toBe(rawAccessToken); expect(result.expiresIn).toBe(3600); @@ -492,7 +492,7 @@ describe('getTokenFromIasService()', () => { describe('authenticationType', () => { it('defaults to OAuth2ClientCredentials', async () => { - await getTokenFromIasService(mockService); + await getIasToken(mockService); expect(mockFetchIasToken).toHaveBeenCalledWith( expect.anything(), @@ -505,7 +505,7 @@ describe('getTokenFromIasService()', () => { it('passes OAuth2JWTBearer with assertion', async () => { const assertion = signedJwt({ user_uuid: 'user-1', app_tid: 'tid' }); - await getTokenFromIasService(mockService, { + await getIasToken(mockService, { authenticationType: 'OAuth2JWTBearer', assertion }); @@ -522,7 +522,7 @@ describe('getTokenFromIasService()', () => { it('does not resolve appTid for OAuth2JWTBearer', async () => { const assertion = signedJwt({ user_uuid: 'user-1', app_tid: 'tid' }); - await getTokenFromIasService(mockService, { + await getIasToken(mockService, { authenticationType: 'OAuth2JWTBearer', assertion }); @@ -536,7 +536,7 @@ describe('getTokenFromIasService()', () => { const jwt = { app_tid: 'subscriber-tid', iss: 'https://sub.example.com' }; mockGetIasAppTid.mockReturnValue('subscriber-tid'); - await getTokenFromIasService(mockService, { jwt }); + await getIasToken(mockService, { jwt }); expect(mockGetIasAppTid).toHaveBeenCalledWith( expect.objectContaining({ @@ -552,7 +552,7 @@ describe('getTokenFromIasService()', () => { }); it('does not call getIasAppTid when appTid is explicitly provided', async () => { - await getTokenFromIasService(mockService, { appTid: 'explicit-tid' }); + await getIasToken(mockService, { appTid: 'explicit-tid' }); expect(mockGetIasAppTid).not.toHaveBeenCalled(); expect(mockFetchIasToken).toHaveBeenCalledWith( @@ -564,7 +564,7 @@ describe('getTokenFromIasService()', () => { it('passes jwt to fetchIasToken for subdomain routing', async () => { const jwt = { app_tid: 'subscriber-tid', iss: 'https://sub.example.com' }; - await getTokenFromIasService(mockService, { jwt }); + await getIasToken(mockService, { jwt }); expect(mockFetchIasToken).toHaveBeenCalledWith( expect.anything(), @@ -575,7 +575,7 @@ describe('getTokenFromIasService()', () => { describe('caching', () => { it('passes useCache: true by default', async () => { - await getTokenFromIasService(mockService); + await getIasToken(mockService); expect(mockFetchIasToken).toHaveBeenCalledWith( expect.anything(), @@ -584,7 +584,7 @@ describe('getTokenFromIasService()', () => { }); it('passes useCache: false when explicitly disabled', async () => { - await getTokenFromIasService(mockService, { useCache: false }); + await getIasToken(mockService, { useCache: false }); expect(mockFetchIasToken).toHaveBeenCalledWith( expect.anything(), @@ -595,7 +595,7 @@ describe('getTokenFromIasService()', () => { describe('resource parameter', () => { it('passes resource (by name) to fetchIasToken', async () => { - await getTokenFromIasService(mockService, { + await getIasToken(mockService, { resource: { name: 'my-app' } }); @@ -606,7 +606,7 @@ describe('getTokenFromIasService()', () => { }); it('passes resource (by providerClientId) to fetchIasToken', async () => { - await getTokenFromIasService(mockService, { + await getIasToken(mockService, { resource: { providerClientId: 'provider-client', providerTenantId: 'provider-tenant' @@ -633,15 +633,13 @@ describe('getTokenFromIasService()', () => { ) ); - await expect(getTokenFromIasService(mockService)).rejects.toThrow( + await expect(getIasToken(mockService)).rejects.toThrow( 'Could not fetch IAS client for service "my-ias"' ); }); it('throws when service string cannot be resolved', async () => { - await expect( - getTokenFromIasService('nonexistent-service') - ).rejects.toThrow( + await expect(getIasToken('nonexistent-service')).rejects.toThrow( "Could not find service binding of type 'nonexistent-service'." ); }); @@ -746,7 +744,7 @@ describe('createDestinationFromIasService()', () => { expect(destination.authentication).toBe('OAuth2JWTBearer'); }); - it('delegates to getTokenFromIasService with the provided options', async () => { + it('delegates to getIasToken with the provided options', async () => { await createDestinationFromIasService(mockCredentials, { useCache: false, jwt: { app_tid: 'tenant-123' } diff --git a/packages/connectivity/src/scp-cf/token-accessor.ts b/packages/connectivity/src/scp-cf/token-accessor.ts index a3c6ea3185..bfd934e498 100644 --- a/packages/connectivity/src/scp-cf/token-accessor.ts +++ b/packages/connectivity/src/scp-cf/token-accessor.ts @@ -121,7 +121,7 @@ async function resolveIdentityService( * @param options - Options for IAS token retrieval. See {@link IasTokenOptions}. * @returns An {@link IasTokenResult} containing the access token, expiration, and optional refresh token. */ -export async function getTokenFromIasService( +export async function getIasToken( service: ServiceCredentials | 'identity' | Service = 'identity', options?: IasTokenOptions ): Promise { @@ -170,7 +170,7 @@ export async function createDestinationFromIasService( options?: IasTokenOptions ): Promise { const resolvedService = await resolveIdentityService(service); - const { token } = await getTokenFromIasService(resolvedService, options); + const { token } = await getIasToken(resolvedService, options); const iasOptions: IasOptions = { authenticationType: 'OAuth2ClientCredentials',