fix: queries not waiting for authentication

This commit is contained in:
Andrew Bastin
2021-10-03 19:12:31 +05:30
parent 84ad4071ad
commit ecdc7919ae
4 changed files with 105 additions and 14 deletions

View File

@@ -33,6 +33,11 @@ import {
Subscription,
} from "rxjs"
import { onBeforeUnmount, onMounted } from "@nuxtjs/composition-api"
import {
setLocalConfig,
getLocalConfig,
removeLocalConfig,
} from "~/newstore/localpersistence"
export type HoppUser = User & {
provider?: string
@@ -40,9 +45,10 @@ export type HoppUser = User & {
}
type AuthEvents =
| { event: "login"; user: HoppUser }
| { event: "logout" }
| { event: "authTokenUpdate"; user: HoppUser; newToken: string | null }
| { event: "probable_login"; user: HoppUser } // We have previous login state, but the app is waiting for authentication
| { event: "login"; user: HoppUser } // We are authenticated
| { event: "logout" } // No authentication and we have no previous state
| { event: "authTokenUpdate"; user: HoppUser; newToken: string | null } // Token has been updated
/**
* A BehaviorSubject emitting the currently logged in user (or null if not logged in)
@@ -58,6 +64,26 @@ export const authIdToken$ = new BehaviorSubject<string | null>(null)
*/
export const authEvents$ = new Subject<AuthEvents>()
/**
* Like currentUser$ but also gives probable user value
*/
export const probableUser$ = new BehaviorSubject<HoppUser | null>(null)
/**
* Resolves when the probable login resolves into proper login
*/
export const waitProbableLoginToConfirm = () =>
new Promise<void>((resolve, reject) => {
if (authIdToken$.value) resolve()
if (!probableUser$.value) reject(new Error("no_probable_user"))
const sub = authIdToken$.pipe(filter((token) => !!token)).subscribe(() => {
sub?.unsubscribe()
resolve()
})
})
/**
* Initializes the firebase authentication related subjects
*/
@@ -67,6 +93,17 @@ export function initAuth() {
let extraSnapshotStop: (() => void) | null = null
probableUser$.next(JSON.parse(getLocalConfig("login_state") ?? "null"))
currentUser$.subscribe((user) => {
if (user) {
probableUser$.next(user)
} else {
probableUser$.next(null)
removeLocalConfig("login_state")
}
})
onAuthStateChanged(auth, (user) => {
/** Whether the user was logged in before */
const wasLoggedIn = currentUser$.value !== null
@@ -135,6 +172,8 @@ export function initAuth() {
newToken: authIdToken$.value,
user: currentUser$.value!!, // Force not-null because user is defined
})
setLocalConfig("login_state", JSON.stringify(user))
} else {
authIdToken$.next(null)
}