@aws-amplify/auth
Version:
Auth category of aws-amplify
156 lines (154 loc) • 5.63 kB
JavaScript
'use strict';
Object.defineProperty(exports, "__esModule", { value: true });
exports.TokenOrchestrator = void 0;
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
const core_1 = require("@aws-amplify/core");
const utils_1 = require("@aws-amplify/core/internals/utils");
const assertServiceError_1 = require("../../../errors/utils/assertServiceError");
const AuthError_1 = require("../../../errors/AuthError");
const oAuthStore_1 = require("../utils/oauth/oAuthStore");
const inflightPromise_1 = require("../utils/oauth/inflightPromise");
class TokenOrchestrator {
constructor() {
this.waitForInflightOAuth = (0, utils_1.isBrowser)()
? async () => {
if (!(await oAuthStore_1.oAuthStore.loadOAuthInFlight())) {
return;
}
if (this.inflightPromise) {
return this.inflightPromise;
}
// when there is valid oauth config and there is an inflight oauth flow, try
// to block async calls that require fetching tokens before the oauth flow completes
// e.g. getCurrentUser, fetchAuthSession etc.
this.inflightPromise = new Promise((resolve, _reject) => {
(0, inflightPromise_1.addInflightPromise)(resolve);
});
return this.inflightPromise;
}
: async () => {
// no-op for non-browser environments
};
}
setAuthConfig(authConfig) {
oAuthStore_1.oAuthStore.setAuthConfig(authConfig.Cognito);
this.authConfig = authConfig;
}
setTokenRefresher(tokenRefresher) {
this.tokenRefresher = tokenRefresher;
}
setAuthTokenStore(tokenStore) {
this.tokenStore = tokenStore;
}
getTokenStore() {
if (!this.tokenStore) {
throw new AuthError_1.AuthError({
name: 'EmptyTokenStoreException',
message: 'TokenStore not set',
});
}
return this.tokenStore;
}
getTokenRefresher() {
if (!this.tokenRefresher) {
throw new AuthError_1.AuthError({
name: 'EmptyTokenRefresherException',
message: 'TokenRefresher not set',
});
}
return this.tokenRefresher;
}
async getTokens(options) {
let tokens;
try {
(0, utils_1.assertTokenProviderConfig)(this.authConfig?.Cognito);
}
catch (_err) {
// Token provider not configured
return null;
}
await this.waitForInflightOAuth();
this.inflightPromise = undefined;
tokens = await this.getTokenStore().loadTokens();
const username = await this.getTokenStore().getLastAuthUser();
if (tokens === null) {
return null;
}
const idTokenExpired = !!tokens?.idToken &&
(0, utils_1.isTokenExpired)({
expiresAt: (tokens.idToken?.payload?.exp ?? 0) * 1000,
clockDrift: tokens.clockDrift ?? 0,
});
const accessTokenExpired = (0, utils_1.isTokenExpired)({
expiresAt: (tokens.accessToken?.payload?.exp ?? 0) * 1000,
clockDrift: tokens.clockDrift ?? 0,
});
if (options?.forceRefresh || idTokenExpired || accessTokenExpired) {
tokens = await this.refreshTokens({
tokens,
username,
});
if (tokens === null) {
return null;
}
}
return {
accessToken: tokens?.accessToken,
idToken: tokens?.idToken,
signInDetails: tokens?.signInDetails,
};
}
async refreshTokens({ tokens, username, }) {
try {
const { signInDetails } = tokens;
const newTokens = await this.getTokenRefresher()({
tokens,
authConfig: this.authConfig,
username,
});
newTokens.signInDetails = signInDetails;
await this.setTokens({ tokens: newTokens });
core_1.Hub.dispatch('auth', { event: 'tokenRefresh' }, 'Auth', utils_1.AMPLIFY_SYMBOL);
return newTokens;
}
catch (err) {
return this.handleErrors(err);
}
}
handleErrors(err) {
(0, assertServiceError_1.assertServiceError)(err);
if (err.name !== utils_1.AmplifyErrorCode.NetworkError) {
// TODO(v6): Check errors on client
this.clearTokens();
}
core_1.Hub.dispatch('auth', {
event: 'tokenRefresh_failure',
data: { error: err },
}, 'Auth', utils_1.AMPLIFY_SYMBOL);
if (err.name.startsWith('NotAuthorizedException')) {
return null;
}
throw err;
}
async setTokens({ tokens }) {
return this.getTokenStore().storeTokens(tokens);
}
async clearTokens() {
return this.getTokenStore().clearTokens();
}
getDeviceMetadata(username) {
return this.getTokenStore().getDeviceMetadata(username);
}
clearDeviceMetadata(username) {
return this.getTokenStore().clearDeviceMetadata(username);
}
setOAuthMetadata(metadata) {
return this.getTokenStore().setOAuthMetadata(metadata);
}
getOAuthMetadata() {
return this.getTokenStore().getOAuthMetadata();
}
}
exports.TokenOrchestrator = TokenOrchestrator;
//# sourceMappingURL=TokenOrchestrator.js.map