in src/auth/auth-core.ts [357:437]
async init(): Promise<string | null | undefined> {
this._storage?.onTokenChange(async token => {
const isGuest = this.user ? this.user.guest : false;
if (isGuest && !token) {
return;
}
if (!token) {
this.logout();
} else {
try {
await this._detectUserChange(token.accessToken);
} catch (error) {
if (!(error instanceof Error)) {
throw error;
}
if (this._canShowDialogs()) {
this._showAuthDialog({nonInteractive: true, error});
}
}
}
});
this._domainStorage.onMessage(DOMAIN_USER_CHANGED_EVENT, (message: UserChange | null) => {
const {userID, serviceID} = message || {};
if (serviceID === this.config.clientId) {
return;
}
if (this.user && userID === this.user.id) {
return;
}
this.forceTokenUpdate();
});
let state: AuthState | undefined;
try {
// Look for token or error in hash
state = await this._checkForAuthResponse();
} catch (error) {
return error instanceof Error ? this.handleInitError(error) : undefined;
}
// Return endless promise in the background to avoid service start
if (state && state.nonRedirect) {
return new Promise(noop);
}
try {
// Check if there is a valid token
await this._tokenValidator?.validateToken();
// Checking if there is a message left by another app on this domain
const message = await this._domainStorage._messagesStorage.get<UserChange>(
`domain-message-${DOMAIN_USER_CHANGED_EVENT}`,
);
if (message) {
const {userID, serviceID} = message;
if (serviceID !== this.config.clientId && (!userID || this.user?.id !== userID)) {
this.forceTokenUpdate();
}
}
// Access token appears to be valid.
// We may resolve restoreLocation URL now
if (!state) {
// Check if we have requested to restore state anyway
state = await this._checkForStateRestoration();
}
this._initDeferred?.resolve?.(state && state.restoreLocation);
return state?.restoreLocation;
} catch (error) {
if (Auth.storageIsUnavailable) {
this._initDeferred?.resolve?.(); // No way to handle if cookies are disabled
await this.requestUser(); // Someone may expect user to be loaded as a part of token validation
return null;
}
return error instanceof Error ? this.handleInitValidationError(error) : undefined;
}
}