Skip to content

Commit cd5168a

Browse files
committed
fix(ssr): appcheck force app
1 parent 4ce2284 commit cd5168a

File tree

7 files changed

+69
-85
lines changed

7 files changed

+69
-85
lines changed

Diff for: packages/nuxt/playground/nuxt.config.ts

+5-7
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,11 @@ export default defineNuxtConfig({
1414

1515
alias: {
1616
// import the dev version directly
17-
vuefire: fileURLToPath(new URL('../../../src/index.ts', import.meta.url)),
17+
'vuefire/server': fileURLToPath(
18+
new URL('../../../src/server/index.ts', import.meta.url)
19+
),
1820
'vuefire/*': fileURLToPath(new URL('../../../src/*', import.meta.url)),
21+
vuefire: fileURLToPath(new URL('../../../src/index.ts', import.meta.url)),
1922
},
2023

2124
modules: [
@@ -45,12 +48,7 @@ export default defineNuxtConfig({
4548
admin: {
4649
config: {},
4750
serviceAccount: resolve(
48-
fileURLToPath(
49-
new URL(
50-
'./vue-fire-store-firebase-adminsdk.json',
51-
import.meta.url
52-
)
53-
)
51+
fileURLToPath(new URL('./service-account.json', import.meta.url))
5452
),
5553
},
5654
},

Diff for: packages/nuxt/src/module.ts

+4-4
Original file line numberDiff line numberDiff line change
@@ -105,20 +105,20 @@ const VueFire: NuxtModule<VueFireNuxtModuleOptions> =
105105
}
106106
nuxt.options.appConfig.firebaseAdmin = options.admin
107107
}
108-
109-
addPlugin(resolve(runtimeDir, '2.admin-plugin.server'))
110108
}
111109

112110
nuxt.hook('modules:done', () => {
113-
// addPlugin(resolve(runtimeDir, 'plugin'))
114-
111+
// plugin are added in reverse order
115112
addPluginTemplate({
116113
src: normalize(resolve(templatesDir, 'plugin.ejs')),
117114

118115
options: {
119116
...options,
117+
ssr: nuxt.options.ssr,
120118
},
121119
})
120+
addPlugin(resolve(runtimeDir, 'plugins/admin.server'))
121+
addPlugin(resolve(runtimeDir, 'plugins/app'))
122122
})
123123
},
124124
})

Diff for: packages/nuxt/src/runtime/plugin.ts

-45
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import admin from 'firebase-admin'
22
import { VueFireAppCheckServer } from 'vuefire/server'
33
import { config } from 'firebase-functions'
4+
import type { FirebaseApp } from '@firebase/app-types'
45
import { defineNuxtPlugin, useAppConfig } from '#app'
56

67
export default defineNuxtPlugin((nuxtApp) => {
@@ -13,28 +14,34 @@ export default defineNuxtPlugin((nuxtApp) => {
1314
return
1415
}
1516

17+
const firebaseApp = nuxtApp.$firebaseApp as FirebaseApp
18+
1619
// only initialize the admin sdk once
1720
if (!admin.apps.length) {
1821
const adminApp = admin.initializeApp({
1922
...firebaseAdmin.config,
2023
credential:
24+
// when deployed we get direct access to the config
2125
process.env.NODE_ENV === 'production'
22-
? // when deployed we get direct access to the config
23-
config().firebase
26+
? config().firebase
2427
: admin.credential.cert(firebaseAdmin.serviceAccount),
2528
})
2629

2730
if (vuefireOptions.appCheck) {
28-
if (!firebaseConfig.appId) {
31+
// NOTE: necessary in VueFireAppCheckServer
32+
if (!firebaseApp.options.appId) {
2933
throw new Error(
3034
'[VueFire]: Missing "appId" in firebase config. This is necessary to use the app-check module on the server.'
3135
)
3236
}
33-
VueFireAppCheckServer(adminApp, firebaseConfig.appId)
37+
38+
VueFireAppCheckServer(adminApp, firebaseApp)
3439
}
3540
}
3641

3742
return {
38-
adminApp: admin.app(),
43+
provide: {
44+
adminApp: admin.app(),
45+
},
3946
}
4047
})

Diff for: packages/nuxt/src/runtime/plugins/app.ts

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import { initializeApp } from 'firebase/app'
2+
import { defineNuxtPlugin, useAppConfig } from '#app'
3+
4+
/**
5+
* Initializes the app and provides it to others.
6+
*/
7+
8+
export default defineNuxtPlugin(() => {
9+
const appConfig = useAppConfig()
10+
11+
const firebaseApp = initializeApp(appConfig.firebaseConfig)
12+
13+
return {
14+
provide: {
15+
firebaseApp,
16+
},
17+
}
18+
})

Diff for: packages/nuxt/templates/plugin.ejs

+24-20
Original file line numberDiff line numberDiff line change
@@ -33,40 +33,44 @@ import {
3333

3434
export default defineNuxtPlugin((nuxtApp) => {
3535
const appConfig = useAppConfig()
36-
const firebaseConfig = toRaw(appConfig).firebaseConfig
3736

38-
const firebaseApp = initializeApp(firebaseConfig)
37+
const firebaseApp = nuxtApp.$firebaseApp
3938

4039
// TODO: emulator option
4140
// connectFirestoreEmulator(getFirestore(firebaseApp), 'localhost', 8080)
4241
// connectDatabaseEmulator(getDatabase(firebaseApp), 'localhost', 8081)
4342

43+
const modules = []
44+
45+
<% if(options.auth) { %>
46+
// Auth
47+
<% } %>
48+
49+
<% if(options.appCheck) { %>
50+
if (process.client) {
51+
modules.push(VueFireAppCheck({
52+
...appConfig.vuefireOptions.appCheck,
53+
provider: '<%= options.appCheck.provider %>' === 'ReCaptchaV3'
54+
? new ReCaptchaV3Provider('<%= options.appCheck.key %>')
55+
: new CustomProvider({
56+
getToken: () => Promise.resolve({ token: '', expireTimeMillis: 1 })
57+
}),
58+
}))
59+
}
60+
<% } %>
61+
4462
nuxtApp.vueApp.use(VueFire, {
4563
firebaseApp,
46-
modules: [
47-
<% if(options.auth) { %>
48-
// Auth
49-
<% } %>
50-
<% if(options.appCheck) { %>
51-
VueFireAppCheck({
52-
...appConfig.vuefireOptions.appCheck,
53-
provider: process.isClient
54-
? new ReCaptchaV3Provider('<%= options.appCheck.key %>')
55-
: new CustomProvider({
56-
getToken: () => Promise.resolve({ token: '', expireTimeMillis: 1 })
57-
}),
58-
}),
59-
<% } %>
60-
],
64+
modules,
6165
})
6266

67+
<% if(options.ssr) { %>
6368
if (process.server) {
64-
// TODO: pass the firebaseApp
69+
// collect the initial state
6570
nuxtApp.payload.vuefire = useSSRInitialState(undefined, firebaseApp)
6671
} else if (nuxtApp.payload?.vuefire) {
6772
// hydrate the plugin state from nuxtApp.payload.vuefire
6873
useSSRInitialState(nuxtApp.payload.vuefire, firebaseApp)
6974
}
70-
71-
return {}
75+
<% } %>
7276
})

Diff for: src/server/app-check.ts

+6-4
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,32 @@
11
import type { app } from 'firebase-admin'
2+
import type { FirebaseApp } from 'firebase/app'
23
import { CustomProvider, initializeAppCheck } from 'firebase/app-check'
34

45
/**
56
* Adds AppCheck using the Firebase Admin SDK. This is necessary on the Server if you have configured AppCheck on the
67
* client.
78
*
89
* @param adminApp - firebase-admin app
9-
* @param appId - appId option passed to firebase/app initializeApp()
10+
* @param firebaseApp - firebase/app initializeApp()
1011
* @param param2 options
1112
*/
1213
export function VueFireAppCheckServer(
1314
adminApp: app.App,
14-
appId: string,
15+
firebaseApp: FirebaseApp,
1516
{
1617
// default to 1 week
1718
ttlMillis = 604_800_000,
1819
}: {
1920
ttlMillis?: number
2021
} = {}
2122
) {
22-
initializeAppCheck(undefined, {
23+
initializeAppCheck(firebaseApp, {
2324
provider: new CustomProvider({
2425
getToken: () =>
2526
adminApp
2627
.appCheck()
27-
.createToken(appId, { ttlMillis })
28+
// NOTE: appId is checked on the server plugin
29+
.createToken(firebaseApp.options.appId!, { ttlMillis })
2830
.then(({ token, ttlMillis: expireTimeMillis }) => ({
2931
token,
3032
expireTimeMillis,

0 commit comments

Comments
 (0)