in src/auth/auth-core.ts [201:314]
constructor(config: Partial<AuthConfig> & Pick<AuthConfig, 'serverUri'>) {
if (!config) {
throw new Error('Config is required');
}
if (config.serverUri === null || config.serverUri === undefined) {
throw new Error('"serverUri" property is required');
}
const unsupportedParams = ['redirect_uri', 'request_credentials', 'client_id'].filter(param =>
Object.prototype.hasOwnProperty.call(config, param),
);
if (unsupportedParams.length !== 0) {
throw new Error(
`The following parameters are no longer supported: ${unsupportedParams.join(', ')}. Please change them from snake_case to camelCase.`,
);
}
config.userFields = config.userFields || [];
this.config = {...Auth.DEFAULT_CONFIG, ...config};
const {clientId, redirect, redirectUri, requestCredentials, scope} = this.config;
const serverUriLength = this.config.serverUri.length;
if (serverUriLength > 0 && this.config.serverUri.charAt(serverUriLength - 1) !== '/') {
this.config.serverUri += '/';
}
this.config.userParams = {
query: {
fields: [...new Set(Auth.DEFAULT_CONFIG.userFields.concat(config.userFields))].join(),
},
};
if (!scope.includes(Auth.DEFAULT_CONFIG.clientId)) {
scope.push(Auth.DEFAULT_CONFIG.clientId);
}
this._storage = new AuthStorage({
messagePrefix: `${clientId}-message-`,
stateKeyPrefix: `${clientId}-states-`,
tokenKey: `${clientId}-token`,
userKey: `${clientId}-user-`,
});
this._domainStorage = new AuthStorage({messagePrefix: 'domain-message-'});
this._requestBuilder = new AuthRequestBuilder(
{
authorization: this.config.serverUri + Auth.API_PATH + Auth.API_AUTH_PATH,
clientId,
redirect,
redirectUri,
requestCredentials,
scopes: scope,
},
this._storage,
);
let {backgroundRefreshTimeout} = this.config;
if (!backgroundRefreshTimeout) {
backgroundRefreshTimeout = this.config.embeddedLogin ? DEFAULT_BACKGROUND_TIMEOUT : BACKGROUND_REDIRECT_TIMEOUT;
}
this._backgroundFlow = new BackgroundFlow(this._requestBuilder, this._storage, backgroundRefreshTimeout);
if (this.config.EmbeddedLoginFlow) {
this._embeddedFlow = new this.config.EmbeddedLoginFlow(
this._requestBuilder,
this._storage,
this.config.translations ?? getTranslationsWithFallback(),
);
}
const API_BASE = this.config.serverUri + Auth.API_PATH;
const fetchConfig = config.fetchCredentials ? {credentials: config.fetchCredentials} : undefined;
this.http = new HTTP(this, API_BASE, fetchConfig);
const getUser = async (token: string) => {
const user = await this.getUser(token);
this.user = user;
return user;
};
this._tokenValidator = new TokenValidator(this.config, getUser, this._storage);
if (this.config.onLogout) {
this.addListener(LOGOUT_EVENT, this.config.onLogout);
}
if (this.config.reloadOnUserChange) {
this.addListener(USER_CHANGED_EVENT, () => {
// Timeout is needed to ensure all other listeners triggered before stopping current page
setTimeout(() => this._reloadCurrentPage());
});
}
this.addListener(LOGOUT_POSTPONED_EVENT, () => this._setPostponed(true));
this.addListener(USER_CHANGE_POSTPONED_EVENT, () => this._setPostponed(true));
this.addListener(USER_CHANGED_EVENT, () => this._setPostponed(false));
this.addListener(USER_CHANGED_EVENT, (user: AuthUser | null | undefined | void) => {
if (user) {
this._updateDomainUser(user.id);
}
});
if (this.config.cacheCurrentUser) {
this.addListener(LOGOUT_EVENT, () => this._storage?.wipeCachedCurrentUser());
this.addListener(USER_CHANGED_EVENT, () => this._storage?.onUserChanged());
}
this._createInitDeferred();
this.setUpPreconnect(config.serverUri);
}