Observe login/logout changes for providers

This commit is contained in:
Marcus Eide
2020-06-09 11:44:07 +02:00
committed by Raghunandan
parent 990ab12669
commit fa320b5e34
3 changed files with 80 additions and 15 deletions
@@ -21,6 +21,8 @@ import { OAuthApi, AccessTokenOptions } from '../../../definitions/auth';
import { OAuthRequestApi, AuthProvider } from '../../../definitions';
import { SessionManager } from '../../../../lib/AuthSessionManager/types';
import { StaticAuthSessionManager } from '../../../../lib/AuthSessionManager';
import { BehaviorSubject } from '../../../../lib';
import { Observable } from '../../../../types';
type CreateOptions = {
// TODO(Rugvip): These two should be grabbed from global config when available, they're not unique to GithubAuth
@@ -80,12 +82,31 @@ class GithubAuth implements OAuthApi {
constructor(private readonly sessionManager: SessionManager<GithubSession>) {}
private session: GithubSession | undefined;
private readonly subject = new BehaviorSubject<GithubSession | undefined>(
undefined,
);
session$(): Observable<GithubSession | undefined> {
return this.subject;
}
getSession(): GithubSession | undefined {
return this.session;
}
setSession(session?: GithubSession): void {
this.session = session;
this.subject.next(session);
}
async getAccessToken(scope?: string, options?: AccessTokenOptions) {
const normalizedScopes = GithubAuth.normalizeScope(scope);
const session = await this.sessionManager.getSession({
...options,
scopes: normalizedScopes,
});
this.setSession(session);
if (session) {
return session.accessToken;
}
@@ -94,6 +115,7 @@ class GithubAuth implements OAuthApi {
async logout() {
await this.sessionManager.removeSession();
this.setSession();
}
static normalizeScope(scope?: string): Set<string> {
@@ -29,6 +29,8 @@ import {
import { OAuthRequestApi, AuthProvider } from '../../../definitions';
import { SessionManager } from '../../../../lib/AuthSessionManager/types';
import { RefreshingAuthSessionManager } from '../../../../lib/AuthSessionManager';
import { BehaviorSubject } from '../../../../lib';
import { Observable } from '../../../../types';
type CreateOptions = {
// TODO(Rugvip): These two should be grabbed from global config when available, they're not unique to GoogleAuth
@@ -101,6 +103,24 @@ class GoogleAuth implements OAuthApi, OpenIdConnectApi, ProfileInfoApi {
constructor(private readonly sessionManager: SessionManager<GoogleSession>) {}
private session: GoogleSession | undefined;
private readonly subject = new BehaviorSubject<GoogleSession | undefined>(
undefined,
);
session$(): Observable<GoogleSession | undefined> {
return this.subject;
}
getSession(): GoogleSession | undefined {
return this.session;
}
setSession(session?: GoogleSession): void {
this.session = session;
this.subject.next(session);
}
async getAccessToken(
scope?: string | string[],
options?: AccessTokenOptions,
@@ -110,6 +130,7 @@ class GoogleAuth implements OAuthApi, OpenIdConnectApi, ProfileInfoApi {
...options,
scopes: normalizedScopes,
});
this.setSession(session);
if (session) {
return session.accessToken;
}
@@ -118,6 +139,7 @@ class GoogleAuth implements OAuthApi, OpenIdConnectApi, ProfileInfoApi {
async getIdToken(options: IdTokenOptions = {}) {
const session = await this.sessionManager.getSession(options);
this.setSession(session);
if (session) {
return session.idToken;
}
@@ -126,6 +148,7 @@ class GoogleAuth implements OAuthApi, OpenIdConnectApi, ProfileInfoApi {
async logout() {
await this.sessionManager.removeSession();
this.setSession();
}
async getProfile(options: ProfileInfoOptions = {}) {
@@ -60,23 +60,43 @@ const useProviders = () => {
},
]);
const setIsSignedIn = async () => {
const signInChecks = await Promise.all(
providers.map(provider =>
provider.identity
? provider.api.getIdToken({ optional: true })
: provider.api.getAccessToken('', { optional: true }),
),
);
useEffect(() => {
// On page load we check the status of sign-in/sign-out for all the providers
// by making a optional getIdToken or getAccessToken request.
const setIsSignedIn = async () => {
const signInChecks = await Promise.all(
providers.map(provider => {
return provider.identity
? provider.api.getIdToken({ optional: true })
: provider.api.getAccessToken('', { optional: true });
}),
);
signInChecks.map((result, i) => {
providers[i].isSignedIn = !!result;
signInChecks.map((result, i) => {
providers[i].isSignedIn = !!result;
});
setProviders(providers);
};
setIsSignedIn();
// Any sign-in/sign-out activity on any provider is observed here
providers.map((provider, index) => {
provider.api.session$().subscribe((session: any) => {
if (session) {
const currentProvider = providers[index];
currentProvider.isSignedIn = true;
setProviders([
...providers.slice(0, index),
currentProvider,
...providers.slice(index + 1, providers.length),
]);
}
});
});
setProviders(providers);
};
setIsSignedIn();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
return providers;
};