From b1418c081c682052f85e9ca3fcb004fdef9db7c8 Mon Sep 17 00:00:00 2001 From: Andrew Bastin Date: Mon, 5 Jul 2021 12:44:43 -0400 Subject: [PATCH] feat: auth event subject --- helpers/fb/auth.ts | 36 +++++++++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/helpers/fb/auth.ts b/helpers/fb/auth.ts index 5fa323a45..08a7c0874 100644 --- a/helpers/fb/auth.ts +++ b/helpers/fb/auth.ts @@ -1,11 +1,16 @@ import firebase from "firebase" -import { BehaviorSubject } from "rxjs" +import { BehaviorSubject, Subject } from "rxjs" export type HoppUser = firebase.User & { provider?: string accessToken?: string } +type AuthEvents = + | { event: "login"; user: HoppUser } + | { event: "logout" } + | { event: "authTokenUpdate"; user: HoppUser; newToken: string | null } + /** * A BehaviorSubject emitting the currently logged in user (or null if not logged in) */ @@ -15,6 +20,11 @@ export const currentUser$ = new BehaviorSubject(null) */ export const authIdToken$ = new BehaviorSubject(null) +/** + * A subject that emits events related to authentication flows + */ +export const authEvents$ = new Subject() + /** * Initializes the firebase authentication related subjects */ @@ -22,6 +32,9 @@ export function initAuth() { let extraSnapshotStop: (() => void) | null = null firebase.auth().onAuthStateChanged((user) => { + /** Whether the user was logged in before */ + const wasLoggedIn = currentUser$.value !== null + if (!user && extraSnapshotStop) { extraSnapshotStop() extraSnapshotStop = null @@ -61,14 +74,35 @@ export function initAuth() { userUpdate.provider = data.provider userUpdate.accessToken = data.accessToken } + + currentUser$.next(userUpdate) }) } currentUser$.next(user) + + // User wasn't found before, but now is there (login happened) + if (!wasLoggedIn && user) { + authEvents$.next({ + event: "login", + user: currentUser$.value!!, + }) + } else if (wasLoggedIn && !user) { + // User was found before, but now is not there (logout happened) + authEvents$.next({ + event: "logout", + }) + } }) firebase.auth().onIdTokenChanged(async (user) => { if (user) { authIdToken$.next(await user.getIdToken()) + + authEvents$.next({ + event: "authTokenUpdate", + newToken: authIdToken$.value, + user: currentUser$.value!!, // Force not-null because user is defined + }) } else { authIdToken$.next(null) }