in lib/token/sso_token_provider.js [113:229]
load: function load(callback) {
var self = this;
var profiles = iniLoader.loadFrom({ isConfig: true });
var profile = profiles[this.profile] || {};
if (Object.keys(profile).length === 0) {
throw AWS.util.error(
new Error('Profile "' + this.profile + '" not found'),
{ code: 'SSOTokenProviderFailure' }
);
} else if (!profile['sso_session']) {
throw AWS.util.error(
new Error('Profile "' + this.profile + '" is missing required property "sso_session".'),
{ code: 'SSOTokenProviderFailure' }
);
}
var ssoSessionName = profile['sso_session'];
var ssoSessions = iniLoader.loadSsoSessionsFrom();
var ssoSession = ssoSessions[ssoSessionName];
if (!ssoSession) {
throw AWS.util.error(
new Error('Sso session "' + ssoSessionName + '" not found'),
{ code: 'SSOTokenProviderFailure' }
);
} else if (!ssoSession['sso_start_url']) {
throw AWS.util.error(
new Error('Sso session "' + this.profile + '" is missing required property "sso_start_url".'),
{ code: 'SSOTokenProviderFailure' }
);
} else if (!ssoSession['sso_region']) {
throw AWS.util.error(
new Error('Sso session "' + this.profile + '" is missing required property "sso_region".'),
{ code: 'SSOTokenProviderFailure' }
);
}
var hasher = crypto.createHash('sha1');
var fileName = hasher.update(ssoSessionName).digest('hex') + '.json';
var cachePath = path.join(iniLoader.getHomeDir(), '.aws', 'sso', 'cache', fileName);
var tokenFromCache = JSON.parse(fs.readFileSync(cachePath));
if (!tokenFromCache) {
throw AWS.util.error(
new Error('Cached token not found. Please log in using "aws sso login"'
+ ' for profile "' + this.profile + '".'),
{ code: 'SSOTokenProviderFailure' }
);
}
validateTokenKey(tokenFromCache, 'accessToken');
validateTokenKey(tokenFromCache, 'expiresAt');
var currentTime = AWS.util.date.getDate().getTime();
var adjustedTime = new Date(currentTime + this.expiryWindow * 1000);
var tokenExpireTime = new Date(tokenFromCache['expiresAt']);
if (tokenExpireTime > adjustedTime) {
// Token is valid and not expired.
self.token = tokenFromCache.accessToken;
self.expireTime = tokenExpireTime;
self.expired = false;
callback(null);
return;
}
// Skip new refresh, if last refresh was done within 30 seconds.
if (currentTime - lastRefreshAttemptTime < 30 * 1000) {
refreshUnsuccessful(currentTime, tokenExpireTime, callback);
return;
}
// Token is in expiry window, refresh from SSOOIDC.createToken() call.
validateTokenKey(tokenFromCache, 'clientId');
validateTokenKey(tokenFromCache, 'clientSecret');
validateTokenKey(tokenFromCache, 'refreshToken');
if (!self.service || self.service.config.region !== ssoSession.sso_region) {
self.service = new AWS.SSOOIDC({ region: ssoSession.sso_region });
}
var params = {
clientId: tokenFromCache.clientId,
clientSecret: tokenFromCache.clientSecret,
refreshToken: tokenFromCache.refreshToken,
grantType: 'refresh_token',
};
lastRefreshAttemptTime = AWS.util.date.getDate().getTime();
self.service.createToken(params, function(err, data) {
if (err || !data) {
refreshUnsuccessful(currentTime, tokenExpireTime, callback);
} else {
try {
validateTokenKey(data, 'accessToken');
validateTokenKey(data, 'expiresIn');
self.expired = false;
self.token = data.accessToken;
self.expireTime = new Date(Date.now() + data.expiresIn * 1000);
callback(null);
try {
// Write updated token data to disk.
tokenFromCache.accessToken = data.accessToken;
tokenFromCache.expiresAt = self.expireTime.toISOString();
tokenFromCache.refreshToken = data.refreshToken;
fs.writeFileSync(cachePath, JSON.stringify(tokenFromCache, null, 2));
} catch (error) {
// Swallow error if unable to write token to file.
}
} catch (error) {
refreshUnsuccessful(currentTime, tokenExpireTime, callback);
}
}
});
},