-
-
Notifications
You must be signed in to change notification settings - Fork 342
/
Copy pathplugin-authenticate-user.server.ts
77 lines (68 loc) · 2.73 KB
/
plugin-authenticate-user.server.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
import { signInWithCustomToken, getAuth, type Auth } from 'firebase/auth'
import {
type DecodedIdToken,
getAuth as getAdminAuth,
} from 'firebase-admin/auth'
import type { FirebaseApp } from 'firebase/app'
import type { App as AdminApp } from 'firebase-admin/app'
import { VueFireAuthServer } from 'vuefire/server'
import { DECODED_ID_TOKEN_SYMBOL, UserSymbol } from '../constants'
import { logger } from '../logging'
import { defineNuxtPlugin, useRequestEvent } from '#imports'
/**
* Setups the auth state based on the cookie.
*/
export default defineNuxtPlugin(async (nuxtApp) => {
const event = useRequestEvent()
const firebaseApp = nuxtApp.$firebaseApp as FirebaseApp
const firebaseAdminApp = nuxtApp.$firebaseAdminApp as AdminApp
const auth = nuxtApp.$firebaseAuth as Auth
const decodedToken = nuxtApp[
// we cannot use a symbol to index
DECODED_ID_TOKEN_SYMBOL as unknown as string
] as DecodedIdToken | null | undefined
const uid = decodedToken?.uid
const tenant = decodedToken?.firebase?.tenant
const adminAuth = tenant
? getAdminAuth(firebaseAdminApp).tenantManager().authForTenant(tenant)
: getAdminAuth(firebaseAdminApp)
// this is also undefined if the user hasn't enabled the session cookie option
if (uid) {
// reauthenticate if the user is not the same (e.g. invalidated)
// OR multi tenancy is used, otherwise tenantId won't be present in SSR accessToken
if (auth.currentUser?.uid !== uid || tenant) {
const customToken = await adminAuth
.createCustomToken(uid)
.catch((err) => {
logger.error('Error creating custom token', err)
return null
})
// console.timeLog('token', `got token for ${user.uid}`)
if (customToken) {
logger.debug('Signing in with custom token')
// Update firebase/auth tenantId to ensure it is set during SSR
auth.tenantId = tenant ?? null
// TODO: allow user to handle error?
await signInWithCustomToken(auth, customToken)
// console.timeLog('token', `signed in with token for ${user.uid}`)
// console.timeEnd('token')
// TODO: token expiration (1h)
}
}
// inject the current user into the app
const user = auth.currentUser
nuxtApp[
// we cannot use a symbol to index
UserSymbol as unknown as string
] = user
// expose the user to requests
// FIXME: should be doable in nitro server routes too
// use addServerPlugin
event.context.user = user
// Hydrates the user
nuxtApp.payload.vuefireUser = user?.toJSON()
}
// logger.debug('setting up user for app', firebaseApp.name, user?.uid)
// provide the user data to the app during ssr
VueFireAuthServer(firebaseApp, nuxtApp.vueApp, auth.currentUser)
})