import * as xssec from '@sap/xssec' ; import CircuitBreaker from 'opossum' ; import { JwtPayload } from './jsonwebtoken-type' ; import { parseSubdomain } from './subdomain-replacer' ; import { decodeJwt } from './jwt' ; import { Service } from './environment-accessor-types' ; import { circuitBreakerDefaultOptions , ResilienceOptions } from './resilience-options' ; import { ClientCredentialsResponse } from './xsuaa-service-types' ; import { resolveService } from './environment-accessor' ; let circuitBreaker ; function executeFunction < T extends ( ... args : any [ ] ) => any > ( fn , ... parameters ) { return fn ( ... parameters ) ; } function getCircuitBreaker ( ) { if ( ! circuitBreaker ) { circuitBreaker = new CircuitBreaker ( executeFunction , circuitBreakerDefaultOptions ) ; } return circuitBreaker ; } param fn returns function wrapInCircuitBreaker < T extends ( ... args : any [ ] ) => any > ( fn ) { return ( ... parameters ) => getCircuitBreaker ( ) . fire ( fn , ... parameters , { enableCircuitBreaker : false } ) ; } interface SubdomainAndZoneId { subdomain : string | null ; zoneId : string | null ; } param jwt returns internal export function getSubdomainAndZoneId ( jwt ? ) { let subdomain = null ; let zoneId = null ; if ( jwt ) { const jwtPayload = typeof jwt === 'string' ? decodeJwt ( jwt ) : jwt ; if ( jwtPayload . iss ) { subdomain = parseSubdomain ( jwtPayload . iss ) ; } if ( jwtPayload . zid ) { zoneId = jwtPayload . zid ; } } return { subdomain , zoneId } ; } param service param userJwt param options returns export function getClientCredentialsToken ( service , userJwt ? , options = { enableCircuitBreaker : true } ) { if ( options . enableCircuitBreaker ) { return wrapInCircuitBreaker ( getClientCredentialsToken ) ( service , userJwt ) ; } const serviceCredentials = resolveService ( service ) . credentials ; const subdomainAndZoneId = getSubdomainAndZoneId ( userJwt ) ; return new Promise ( ( resolve , reject ) => { xssec . requests . requestClientCredentialsToken ( subdomainAndZoneId . subdomain , serviceCredentials , null , subdomainAndZoneId . zoneId , ( err , token , tokenResponse ) => err ? reject ( err ) : resolve ( tokenResponse ) ) ; } ) ; } param service param userJwt param options returns export function getUserToken ( service , userJwt , options = { enableCircuitBreaker : true } ) { if ( options . enableCircuitBreaker ) { return wrapInCircuitBreaker ( getUserToken ) ( service , userJwt ) ; } const subdomainAndZoneId = getSubdomainAndZoneId ( userJwt ) ; return new Promise ( ( resolve , reject ) => xssec . requests . requestUserToken ( userJwt , service . credentials , null , null , subdomainAndZoneId . subdomain , subdomainAndZoneId . zoneId , ( err , token ) => ( err ? reject ( err ) : resolve ( token ) ) ) ) ; }