Observe login/logout changes for providers
This commit is contained in:
@@ -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;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user