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) }