11import type { FirebaseError , FirebaseApp } from 'firebase/app'
2- import { getAuth , onIdTokenChanged } from 'firebase/auth'
2+ import {
3+ getAuth ,
4+ onIdTokenChanged ,
5+ beforeAuthStateChanged ,
6+ User ,
7+ } from 'firebase/auth'
38import { VueFireAuth } from 'vuefire'
49import { defineNuxtPlugin , showError } from '#app'
510
@@ -13,15 +18,27 @@ export default defineNuxtPlugin((nuxtApp) => {
1318 VueFireAuth ( nuxtApp . payload . vuefireUser ) ( firebaseApp , nuxtApp . vueApp )
1419 const auth = getAuth ( firebaseApp )
1520 // send a post request to the server when auth state changes to mint a cookie
16- onIdTokenChanged ( auth , async ( user ) => {
17- const jwtToken = await user ?. getIdToken ( )
18- $fetch ( '/api/_vuefire/auth' , {
19- method : 'POST' ,
20- // if the token is undefined, the server will delete the cookie
21- body : { token : jwtToken } ,
22- } ) . catch ( ( reason : FirebaseError ) => {
23- // there is no need to return a rejected error as `onIdTokenChanged` won't use it
24- showError ( reason )
25- } )
21+ beforeAuthStateChanged ( auth , mintCookie , ( ) => {
22+ // rollback the auth state
23+ mintCookie ( auth . currentUser )
2624 } )
25+
26+ // we need both callback to avoid some race conditions
27+ onIdTokenChanged ( auth , mintCookie )
2728} )
29+
30+ /**
31+ * Sends a post request to the server to mint a cookie based auth session. The name of the cookie is defined in the
32+ * api.session.ts file.
33+ *
34+ * @param user - the user to mint a cookie for
35+ */
36+ async function mintCookie ( user : User | null ) {
37+ const jwtToken = await user ?. getIdToken ( )
38+ // throws if the server returns an error so that beforeAuthStateChanged can catch it to cancel
39+ await $fetch ( '/api/_vuefire/auth' , {
40+ method : 'POST' ,
41+ // if the token is undefined, the server will delete the cookie
42+ body : { token : jwtToken } ,
43+ } )
44+ }
0 commit comments