Skip to content

Commit e5e67eb

Browse files
committed
move ias-specific opts to iasOptions & refactor parameter handling
1 parent 6ab8a1f commit e5e67eb

File tree

5 files changed

+62
-31
lines changed

5 files changed

+62
-31
lines changed

packages/connectivity/src/scp-cf/destination/destination-from-vcap.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,29 @@ export type ServiceBindingTransformOptions = {
9191
* The JWT payload used to fetch destinations.
9292
*/
9393
jwt?: JwtPayload;
94+
/**
95+
* The options for IAS token retrieval.
96+
*/
97+
iasOptions?: {
98+
/**
99+
* The target URL of the destination that the IAS token is requested for.
100+
*/
101+
targetUrl?: string;
102+
/**
103+
* The application name registered in IAS for App-to-App communication.
104+
* The token will only be usable to call the requested application.
105+
*/
106+
appName?: string;
107+
/**
108+
* The BTP tenant ID the token should be requested for.
109+
* Required for cross-tenant communication.
110+
*/
111+
appTenantId?: string;
112+
/**
113+
* Additional parameters to be sent along with the token request.
114+
*/
115+
extraParams?: Record<string, string>;
116+
};
94117
} & CachingOptions;
95118

96119
/**

packages/connectivity/src/scp-cf/destination/service-binding-to-destination.spec.ts

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -311,9 +311,7 @@ describe('service binding to destination', () => {
311311
it('transforms identity (IAS) service binding with appName parameter', async () => {
312312
const destination = await transformServiceBindingToDestination(
313313
resolveServiceBinding('identity'),
314-
{ appName: 'my-app' } as Parameters<
315-
typeof transformServiceBindingToDestination
316-
>[1]
314+
{ iasOptions: { appName: 'my-app' } }
317315
);
318316
expect(destination).toEqual(
319317
expect.objectContaining({
@@ -332,6 +330,20 @@ describe('service binding to destination', () => {
332330
);
333331
});
334332

333+
it('transforms identity (IAS) service binding with custom targetUrl', async () => {
334+
const destination = await transformServiceBindingToDestination(
335+
resolveServiceBinding('identity'),
336+
{ iasOptions: { targetUrl: 'https://custom-target.example.com' } }
337+
);
338+
expect(destination).toEqual(
339+
expect.objectContaining({
340+
url: 'https://custom-target.example.com',
341+
name: 'my-identity-service',
342+
authentication: 'OAuth2ClientCredentials'
343+
})
344+
);
345+
});
346+
335347
it('transforms identity (IAS) service binding and includes mTLS cert/key in destination', async () => {
336348
const destination = await transformServiceBindingToDestination(
337349
resolveServiceBinding('identity')

packages/connectivity/src/scp-cf/destination/service-binding-to-destination.ts

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -184,21 +184,15 @@ async function xfS4hanaCloudBindingToDestination(
184184

185185
async function iasBindingToDestination(
186186
service: Service,
187-
options?: ServiceBindingTransformOptions & {
188-
targetUrl?: string;
189-
appName?: string;
190-
appTenantId?: string;
191-
extraParams?: Record<string, string>;
192-
}
187+
options?: ServiceBindingTransformOptions
193188
): Promise<Destination> {
194-
const { access_token } = await getIasClientCredentialsToken(service, {
195-
appName: options?.appName,
196-
appTenantId: options?.appTenantId,
197-
extraParams: options?.extraParams
198-
});
189+
const { access_token } = await getIasClientCredentialsToken(
190+
service,
191+
options?.iasOptions ?? {}
192+
);
199193
const destination = buildClientCredentialsDestination(
200194
access_token,
201-
options?.targetUrl ?? service.credentials.url,
195+
options?.iasOptions?.targetUrl ?? service.credentials.url,
202196
service.name
203197
);
204198

packages/connectivity/src/scp-cf/identity-service.spec.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ describe('getIasClientCredentialsToken', () => {
8585
headers: {
8686
'Content-Type': 'application/x-www-form-urlencoded'
8787
},
88-
data: 'grant_type=client_credentials&client_id=test-client-id&refresh_token=0',
88+
data: 'grant_type=client_credentials&client_id=test-client-id&refresh_token=0&token_format=jwt',
8989
httpsAgent: expect.any(Object)
9090
})
9191
);
@@ -113,7 +113,7 @@ describe('getIasClientCredentialsToken', () => {
113113
headers: expect.objectContaining({
114114
'Content-Type': 'application/x-www-form-urlencoded'
115115
}),
116-
data: 'grant_type=client_credentials&client_id=test-client-id&refresh_token=0&client_secret=test-client-secret'
116+
data: 'grant_type=client_credentials&client_id=test-client-id&refresh_token=0&token_format=jwt&client_secret=test-client-secret'
117117
})
118118
);
119119
});
@@ -127,7 +127,7 @@ describe('getIasClientCredentialsToken', () => {
127127

128128
expect(mockedAxios.request).toHaveBeenCalledWith(
129129
expect.objectContaining({
130-
data: 'grant_type=client_credentials&client_id=test-client-id&resource=urn%3Asap%3Aidentity%3Aapplication%3Aprovider%3Aname%3Amy-app&refresh_token=0'
130+
data: 'grant_type=client_credentials&client_id=test-client-id&resource=urn%3Asap%3Aidentity%3Aapplication%3Aprovider%3Aname%3Amy-app&refresh_token=0&token_format=jwt'
131131
})
132132
);
133133
});
@@ -141,7 +141,7 @@ describe('getIasClientCredentialsToken', () => {
141141

142142
expect(mockedAxios.request).toHaveBeenCalledWith(
143143
expect.objectContaining({
144-
data: 'grant_type=client_credentials&client_id=test-client-id&app_tid=tenant-123&refresh_token=0'
144+
data: 'grant_type=client_credentials&client_id=test-client-id&app_tid=tenant-123&refresh_token=0&token_format=jwt'
145145
})
146146
);
147147
});
@@ -156,7 +156,7 @@ describe('getIasClientCredentialsToken', () => {
156156

157157
expect(mockedAxios.request).toHaveBeenCalledWith(
158158
expect.objectContaining({
159-
data: 'grant_type=client_credentials&client_id=test-client-id&resource=urn%3Asap%3Aidentity%3Aapplication%3Aprovider%3Aname%3Amy-app&app_tid=tenant-123&refresh_token=0'
159+
data: 'grant_type=client_credentials&client_id=test-client-id&resource=urn%3Asap%3Aidentity%3Aapplication%3Aprovider%3Aname%3Amy-app&app_tid=tenant-123&refresh_token=0&token_format=jwt'
160160
})
161161
);
162162
});

packages/connectivity/src/scp-cf/identity-service.ts

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,10 @@ import { createLogger } from '@sap-cloud-sdk/util';
55
import axios from 'axios';
66
import { decodeJwt, isXsuaaToken } from './jwt';
77
import { resolveServiceBinding } from './environment-accessor';
8-
import type { DestinationOptions } from './destination';
8+
import type {
9+
DestinationOptions,
10+
ServiceBindingTransformOptions
11+
} from './destination';
912
import type { MiddlewareContext } from '@sap-cloud-sdk/resilience';
1013
import type { Service, ServiceCredentials } from './environment-accessor';
1114
import type { RawAxiosRequestConfig } from 'axios';
@@ -63,11 +66,7 @@ interface IasParameters {
6366
*/
6467
export async function getIasClientCredentialsToken(
6568
service: string | Service,
66-
options: {
67-
appName?: string;
68-
appTenantId?: string;
69-
extraParams?: Record<string, string>;
70-
}
69+
options: ServiceBindingTransformOptions['iasOptions'] = {}
7170
): Promise<ClientCredentialsResponse> {
7271
const resolvedService = resolveServiceBinding(service);
7372

@@ -116,11 +115,8 @@ export async function getIasClientCredentialsToken(
116115
params.append('refresh_token', '0');
117116
// };
118117

119-
for (const [paramKey, paramValue] of Object.entries(
120-
arg.extraParams || {}
121-
)) {
122-
params.append(paramKey, paramValue);
123-
}
118+
// Ensure JWT token format
119+
params.append('token_format', 'jwt');
124120

125121
const tokenUrl = `${url}/oauth2/token`;
126122
const headers: Record<string, string> = {
@@ -150,6 +146,12 @@ export async function getIasClientCredentialsToken(
150146
);
151147
}
152148

149+
for (const [paramKey, paramValue] of Object.entries(
150+
arg.extraParams || {}
151+
)) {
152+
params.append(paramKey, paramValue);
153+
}
154+
153155
requestConfig.data = params.toString();
154156

155157
logger.info(params.toString());

0 commit comments

Comments
 (0)