@sap-cloud-sdk/connectivity
Version:
SAP Cloud SDK for JavaScript connectivity
131 lines • 6.6 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.serviceToken = serviceToken;
exports.jwtBearerToken = jwtBearerToken;
exports.getIasToken = getIasToken;
exports.createDestinationFromIasService = createDestinationFromIasService;
const util_1 = require("@sap-cloud-sdk/util");
const jwt_1 = require("./jwt");
const client_credentials_token_cache_1 = require("./client-credentials-token-cache");
const environment_accessor_1 = require("./environment-accessor");
const xsuaa_service_1 = require("./xsuaa-service");
const identity_service_1 = require("./identity-service");
const build_ias_destination_1 = require("./destination/build-ias-destination");
/**
* Returns an access token that can be used to call the given service. The token is fetched via a client credentials grant with the credentials of the given service.
* If multiple instances of the provided service exist, the first instance will be selected.
* When a JWT is passed, the tenant of the JWT will be used when performing the grant.
* When no JWT is passed, the grant will be performed using the provider tenant.
*
* Throws an error if there is no instance of the given service type or the XSUAA service, or if the request to the XSUAA service fails.
* @param service - The type of the service or an instance of {@link Service}.
* @param options - Options to influence caching behavior (see {@link CachingOptions}) and a JWT. By default, caching and usage of a circuit breaker are enabled.
* @returns Access token.
*/
async function serviceToken(service, options) {
const opts = {
useCache: true,
enableCircuitBreaker: true,
...options
};
const serviceBinding = (0, environment_accessor_1.resolveServiceBinding)(service);
const serviceCredentials = serviceBinding.credentials;
const tenantForCaching = options?.jwt
? (0, jwt_1.getTenantId)(options.jwt) || (0, jwt_1.getSubdomain)(options.jwt)
: (0, jwt_1.getTenantIdFromBinding)() || (0, jwt_1.getDefaultTenantId)();
if (opts.useCache) {
const cachedToken = client_credentials_token_cache_1.clientCredentialsTokenCache.getToken(tenantForCaching, serviceCredentials.clientid);
if (cachedToken) {
return cachedToken.access_token;
}
}
try {
const token = await (0, xsuaa_service_1.getClientCredentialsToken)(serviceBinding, options?.jwt);
if (opts.useCache) {
client_credentials_token_cache_1.clientCredentialsTokenCache.cacheToken(tenantForCaching, serviceCredentials.clientid, token);
}
return token.access_token;
}
catch (err) {
throw new util_1.ErrorWithCause(`Could not fetch client credentials token for service of type "${serviceBinding.label}".`, err);
}
}
/**
* Returns a JWT bearer token that can be used to call the given service.
* The token is fetched via a JWT bearer token grant using the user token + client credentials.
*
* Throws an error if there is no instance of the given service type.
* @param jwt - The JWT of the user for whom the access token should be fetched.
* @param service - The type of the service or an instance of {@link Service}.
* @returns A JWT bearer token.
*/
async function jwtBearerToken(jwt, service) {
const resolvedService = (0, environment_accessor_1.resolveServiceBinding)(service);
return (0, xsuaa_service_1.getUserToken)(resolvedService, jwt);
}
/**
* @internal
*/
async function resolveIdentityService(service) {
if (typeof service === 'string') {
return (0, environment_accessor_1.resolveServiceBinding)(service);
}
return 'credentials' in service
? service
: { name: 'identity', label: 'identity', tags: [], credentials: service };
}
/**
* Returns an IAS token from the Identity Authentication Service.
* Supports both technical user (OAuth2ClientCredentials) and business user (OAuth2JWTBearer) flows.
* @remarks
* Prefer using `'identity'` (default) for the `service` parameter.
* Passing raw ServiceCredentials or Service directly is only recommended for environments where service bindings are unavailable as they hardcode the credentials.
* @param service - Service credentials {@link ServiceCredentials}, the service type (always 'identity' for IAS), or a {@link Service} binding.
* @param options - Options for IAS token retrieval. See {@link IasTokenOptions}.
* @returns An {@link IasTokenResult} containing the access token, expiration, and optional refresh token.
*/
async function getIasToken(service = 'identity', options) {
const useCache = options?.useCache !== false;
const jwt = options?.jwt;
const iasOptions = {
authenticationType: 'OAuth2ClientCredentials',
...options
};
const resolvedService = await resolveIdentityService(service);
// Resolve appTid from requestAs for technical user flows
if (iasOptions.authenticationType !== 'OAuth2JWTBearer' &&
!iasOptions.appTid) {
iasOptions.appTid = (0, identity_service_1.getIasAppTid)(iasOptions, resolvedService, jwt);
}
const response = await (0, identity_service_1.fetchIasToken)(resolvedService, {
...iasOptions,
jwt,
useCache
});
return {
token: response.access_token,
expiresIn: response.expires_in,
refreshToken: response.refresh_token
};
}
/**
* Creates an {@link Destination} from IAS service credentials.
* Fetches an IAS token and builds a destination with the token, mTLS key pair (if available),
* and the target URL.
* @remarks
* Prefer using `'identity'` (default) for the `service` parameter.
* Passing raw ServiceCredentials or Service directly is only recommended for environments where service bindings are unavailable as they hardcode the credentials.
* @param service - Service credentials {@link ServiceCredentials}, the service type (always 'identity' for IAS), or a {@link Service} binding.
* @param options - Options for IAS token retrieval and destination configuration. See {@link IasTokenOptions}.
* @returns A promise that resolves to an HTTP destination.
*/
async function createDestinationFromIasService(service = 'identity', options) {
const resolvedService = await resolveIdentityService(service);
const { token } = await getIasToken(resolvedService, options);
const iasOptions = {
authenticationType: 'OAuth2ClientCredentials',
...options
};
return (0, build_ias_destination_1.buildIasDestination)(token, resolvedService, iasOptions);
}
//# sourceMappingURL=token-accessor.js.map