@prmichaelsen/firebase-admin-sdk-v8 2.0.2 → 2.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -30,28 +30,50 @@ npm install firebase-admin-sdk-v8
30
30
 
31
31
  ## 🚀 Quick Start
32
32
 
33
- ### 1. Set Environment Variables
33
+ ### 1. Initialize the SDK
34
34
 
35
- ```env
36
- # Firebase Admin Service Account (JSON string) - REQUIRED
37
- FIREBASE_ADMIN_SERVICE_ACCOUNT_KEY='{"type":"service_account","project_id":"...","private_key":"...","client_email":"..."}'
35
+ **Option A: Cloudflare Workers / Edge Runtimes (Recommended)**
38
36
 
39
- # Firebase Project ID - REQUIRED (use either variable name)
40
- FIREBASE_PROJECT_ID=your-project-id
41
- # OR
42
- PUBLIC_FIREBASE_PROJECT_ID=your-project-id
43
-
44
- # Optional: Standard Firebase client config (for reference)
45
- FIREBASE_API_KEY=your-api-key
46
- FIREBASE_AUTH_DOMAIN=your-project.firebaseapp.com
47
- FIREBASE_STORAGE_BUCKET=your-project.appspot.com
48
- FIREBASE_MESSAGING_SENDER_ID=your-sender-id
49
- FIREBASE_APP_ID=your-app-id
37
+ ```typescript
38
+ import { initializeApp, verifyIdToken } from '@prmichaelsen/firebase-admin-sdk-v8';
39
+
40
+ export default {
41
+ async fetch(request: Request, env: Env): Promise<Response> {
42
+ // Initialize with env variables
43
+ initializeApp({
44
+ serviceAccount: env.FIREBASE_ADMIN_SERVICE_ACCOUNT_KEY,
45
+ projectId: env.FIREBASE_PROJECT_ID
46
+ });
47
+
48
+ // Now use the SDK
49
+ const token = request.headers.get('authorization')?.split('Bearer ')[1];
50
+ const user = await verifyIdToken(token);
51
+
52
+ return new Response(JSON.stringify({ user }));
53
+ }
54
+ };
55
+ ```
56
+
57
+ **Option B: Node.js / Traditional Environments**
58
+
59
+ ```typescript
60
+ import { initializeApp } from '@prmichaelsen/firebase-admin-sdk-v8';
61
+
62
+ // Option 1: Explicit initialization
63
+ initializeApp({
64
+ serviceAccount: JSON.parse(process.env.FIREBASE_ADMIN_SERVICE_ACCOUNT_KEY!),
65
+ projectId: process.env.FIREBASE_PROJECT_ID
66
+ });
67
+
68
+ // Option 2: Auto-detect from process.env (no initialization needed)
69
+ // The SDK will automatically use process.env if initializeApp() is not called
50
70
  ```
51
71
 
52
- **Required Environment Variables:**
53
- - `FIREBASE_ADMIN_SERVICE_ACCOUNT_KEY` - Your Firebase service account JSON (as a string)
54
- - `FIREBASE_PROJECT_ID` or `PUBLIC_FIREBASE_PROJECT_ID` - Your Firebase project ID
72
+ **Environment Variables (if not using initializeApp):**
73
+ ```env
74
+ FIREBASE_ADMIN_SERVICE_ACCOUNT_KEY='{"type":"service_account",...}'
75
+ FIREBASE_PROJECT_ID=your-project-id
76
+ ```
55
77
 
56
78
  ### 2. Verify ID Tokens
57
79
 
package/dist/index.d.mts CHANGED
@@ -175,6 +175,67 @@ interface BatchWriteResult {
175
175
  }>;
176
176
  }
177
177
 
178
+ /**
179
+ * Firebase Admin SDK v8 - Configuration
180
+ * Manages SDK configuration and credentials
181
+ */
182
+
183
+ /**
184
+ * SDK Configuration
185
+ */
186
+ interface SDKConfig {
187
+ serviceAccount?: ServiceAccount | string;
188
+ projectId?: string;
189
+ }
190
+ /**
191
+ * Initialize the Firebase Admin SDK with configuration
192
+ * This is optional - the SDK will fall back to environment variables if not called
193
+ *
194
+ * @param config - SDK configuration
195
+ *
196
+ * @example
197
+ * ```typescript
198
+ * // Cloudflare Workers
199
+ * export default {
200
+ * async fetch(request, env) {
201
+ * initializeApp({
202
+ * serviceAccount: env.FIREBASE_ADMIN_SERVICE_ACCOUNT_KEY,
203
+ * projectId: env.FIREBASE_PROJECT_ID
204
+ * });
205
+ * // ... use SDK
206
+ * }
207
+ * }
208
+ * ```
209
+ *
210
+ * @example
211
+ * ```typescript
212
+ * // Node.js (optional - will use process.env by default)
213
+ * initializeApp({
214
+ * serviceAccount: JSON.parse(process.env.FIREBASE_ADMIN_SERVICE_ACCOUNT_KEY),
215
+ * projectId: process.env.FIREBASE_PROJECT_ID
216
+ * });
217
+ * ```
218
+ */
219
+ declare function initializeApp(config: SDKConfig): void;
220
+ /**
221
+ * Get the current SDK configuration
222
+ */
223
+ declare function getConfig(): SDKConfig;
224
+ /**
225
+ * Clear the SDK configuration (useful for testing)
226
+ */
227
+ declare function clearConfig(): void;
228
+ /**
229
+ * Get service account from config or environment
230
+ * Priority: 1) globalConfig, 2) process.env
231
+ */
232
+ declare function getServiceAccount(): ServiceAccount;
233
+ /**
234
+ * Get Firebase project ID from config or environment
235
+ * Priority: 1) globalConfig, 2) process.env
236
+ */
237
+ declare function getProjectId(): string;
238
+
178
239
  /**
179
240
  * Firebase Admin SDK v8 - Authentication
180
241
  * ID token verification supporting both Firebase v9 and v10 token formats
@@ -451,22 +512,4 @@ declare function getAdminAccessToken(): Promise<string>;
451
512
  */
452
513
  declare function clearTokenCache(): void;
453
514
 
454
- /**
455
- * Firebase Admin SDK v8 - Service Account Management
456
- */
457
-
458
- /**
459
- * Get Firebase service account from environment variable
460
- * @throws {Error} If FIREBASE_ADMIN_SERVICE_ACCOUNT_KEY is not set
461
- * @returns {ServiceAccount} Parsed service account credentials
462
- */
463
- declare function getServiceAccount(): ServiceAccount;
464
- /**
465
- * Get Firebase project ID from environment
466
- * Checks multiple possible environment variable names
467
- * @throws {Error} If no project ID is found
468
- * @returns {string} Firebase project ID
469
- */
470
- declare function getProjectId(): string;
471
-
472
- export { type BatchWrite, type BatchWriteResult, type DataObject, type DecodedIdToken, FieldValue, type FieldValue$1 as FieldValueSentinel, FieldValueType, type FirestoreDocument, type FirestoreValue, type QueryFilter, type QueryOptions, type QueryOrder, type ServiceAccount, type SetOptions, type TokenResponse, type UpdateOptions, type UserInfo, type WhereFilterOp, addDocument, batchWrite, clearTokenCache, deleteDocument, getAdminAccessToken, getAuth, getDocument, getProjectId, getServiceAccount, getUserFromToken, queryDocuments, setDocument, updateDocument, verifyIdToken };
515
+ export { type BatchWrite, type BatchWriteResult, type DataObject, type DecodedIdToken, FieldValue, type FieldValue$1 as FieldValueSentinel, FieldValueType, type FirestoreDocument, type FirestoreValue, type QueryFilter, type QueryOptions, type QueryOrder, type ServiceAccount, type SetOptions, type TokenResponse, type UpdateOptions, type UserInfo, type WhereFilterOp, addDocument, batchWrite, clearConfig, clearTokenCache, deleteDocument, getAdminAccessToken, getAuth, getConfig, getDocument, getProjectId, getServiceAccount, getUserFromToken, initializeApp, queryDocuments, setDocument, updateDocument, verifyIdToken };
package/dist/index.d.ts CHANGED
@@ -175,6 +175,67 @@ interface BatchWriteResult {
175
175
  }>;
176
176
  }
177
177
 
178
+ /**
179
+ * Firebase Admin SDK v8 - Configuration
180
+ * Manages SDK configuration and credentials
181
+ */
182
+
183
+ /**
184
+ * SDK Configuration
185
+ */
186
+ interface SDKConfig {
187
+ serviceAccount?: ServiceAccount | string;
188
+ projectId?: string;
189
+ }
190
+ /**
191
+ * Initialize the Firebase Admin SDK with configuration
192
+ * This is optional - the SDK will fall back to environment variables if not called
193
+ *
194
+ * @param config - SDK configuration
195
+ *
196
+ * @example
197
+ * ```typescript
198
+ * // Cloudflare Workers
199
+ * export default {
200
+ * async fetch(request, env) {
201
+ * initializeApp({
202
+ * serviceAccount: env.FIREBASE_ADMIN_SERVICE_ACCOUNT_KEY,
203
+ * projectId: env.FIREBASE_PROJECT_ID
204
+ * });
205
+ * // ... use SDK
206
+ * }
207
+ * }
208
+ * ```
209
+ *
210
+ * @example
211
+ * ```typescript
212
+ * // Node.js (optional - will use process.env by default)
213
+ * initializeApp({
214
+ * serviceAccount: JSON.parse(process.env.FIREBASE_ADMIN_SERVICE_ACCOUNT_KEY),
215
+ * projectId: process.env.FIREBASE_PROJECT_ID
216
+ * });
217
+ * ```
218
+ */
219
+ declare function initializeApp(config: SDKConfig): void;
220
+ /**
221
+ * Get the current SDK configuration
222
+ */
223
+ declare function getConfig(): SDKConfig;
224
+ /**
225
+ * Clear the SDK configuration (useful for testing)
226
+ */
227
+ declare function clearConfig(): void;
228
+ /**
229
+ * Get service account from config or environment
230
+ * Priority: 1) globalConfig, 2) process.env
231
+ */
232
+ declare function getServiceAccount(): ServiceAccount;
233
+ /**
234
+ * Get Firebase project ID from config or environment
235
+ * Priority: 1) globalConfig, 2) process.env
236
+ */
237
+ declare function getProjectId(): string;
238
+
178
239
  /**
179
240
  * Firebase Admin SDK v8 - Authentication
180
241
  * ID token verification supporting both Firebase v9 and v10 token formats
@@ -451,22 +512,4 @@ declare function getAdminAccessToken(): Promise<string>;
451
512
  */
452
513
  declare function clearTokenCache(): void;
453
514
 
454
- /**
455
- * Firebase Admin SDK v8 - Service Account Management
456
- */
457
-
458
- /**
459
- * Get Firebase service account from environment variable
460
- * @throws {Error} If FIREBASE_ADMIN_SERVICE_ACCOUNT_KEY is not set
461
- * @returns {ServiceAccount} Parsed service account credentials
462
- */
463
- declare function getServiceAccount(): ServiceAccount;
464
- /**
465
- * Get Firebase project ID from environment
466
- * Checks multiple possible environment variable names
467
- * @throws {Error} If no project ID is found
468
- * @returns {string} Firebase project ID
469
- */
470
- declare function getProjectId(): string;
471
-
472
- export { type BatchWrite, type BatchWriteResult, type DataObject, type DecodedIdToken, FieldValue, type FieldValue$1 as FieldValueSentinel, FieldValueType, type FirestoreDocument, type FirestoreValue, type QueryFilter, type QueryOptions, type QueryOrder, type ServiceAccount, type SetOptions, type TokenResponse, type UpdateOptions, type UserInfo, type WhereFilterOp, addDocument, batchWrite, clearTokenCache, deleteDocument, getAdminAccessToken, getAuth, getDocument, getProjectId, getServiceAccount, getUserFromToken, queryDocuments, setDocument, updateDocument, verifyIdToken };
515
+ export { type BatchWrite, type BatchWriteResult, type DataObject, type DecodedIdToken, FieldValue, type FieldValue$1 as FieldValueSentinel, FieldValueType, type FirestoreDocument, type FirestoreValue, type QueryFilter, type QueryOptions, type QueryOrder, type ServiceAccount, type SetOptions, type TokenResponse, type UpdateOptions, type UserInfo, type WhereFilterOp, addDocument, batchWrite, clearConfig, clearTokenCache, deleteDocument, getAdminAccessToken, getAuth, getConfig, getDocument, getProjectId, getServiceAccount, getUserFromToken, initializeApp, queryDocuments, setDocument, updateDocument, verifyIdToken };
package/dist/index.js CHANGED
@@ -23,14 +23,17 @@ __export(index_exports, {
23
23
  FieldValue: () => FieldValue,
24
24
  addDocument: () => addDocument,
25
25
  batchWrite: () => batchWrite,
26
+ clearConfig: () => clearConfig,
26
27
  clearTokenCache: () => clearTokenCache,
27
28
  deleteDocument: () => deleteDocument,
28
29
  getAdminAccessToken: () => getAdminAccessToken,
29
30
  getAuth: () => getAuth,
31
+ getConfig: () => getConfig,
30
32
  getDocument: () => getDocument,
31
33
  getProjectId: () => getProjectId,
32
34
  getServiceAccount: () => getServiceAccount,
33
35
  getUserFromToken: () => getUserFromToken,
36
+ initializeApp: () => initializeApp,
34
37
  queryDocuments: () => queryDocuments,
35
38
  setDocument: () => setDocument,
36
39
  updateDocument: () => updateDocument,
@@ -38,12 +41,28 @@ __export(index_exports, {
38
41
  });
39
42
  module.exports = __toCommonJS(index_exports);
40
43
 
41
- // src/service-account.ts
44
+ // src/config.ts
45
+ var globalConfig = {};
46
+ function initializeApp(config) {
47
+ globalConfig = { ...config };
48
+ }
49
+ function getConfig() {
50
+ return globalConfig;
51
+ }
52
+ function clearConfig() {
53
+ globalConfig = {};
54
+ }
42
55
  function getServiceAccount() {
43
- const key = process.env.FIREBASE_ADMIN_SERVICE_ACCOUNT_KEY;
56
+ if (globalConfig.serviceAccount) {
57
+ if (typeof globalConfig.serviceAccount === "string") {
58
+ return JSON.parse(globalConfig.serviceAccount);
59
+ }
60
+ return globalConfig.serviceAccount;
61
+ }
62
+ const key = typeof process !== "undefined" && process.env?.FIREBASE_ADMIN_SERVICE_ACCOUNT_KEY;
44
63
  if (!key) {
45
64
  throw new Error(
46
- `FIREBASE_ADMIN_SERVICE_ACCOUNT_KEY environment variable is not set. Please provide your Firebase service account JSON as a string. Example: FIREBASE_ADMIN_SERVICE_ACCOUNT_KEY='{"type":"service_account",...}'`
65
+ "Firebase service account not configured. Either call initializeApp({ serviceAccount: ... }) or set FIREBASE_ADMIN_SERVICE_ACCOUNT_KEY environment variable."
47
66
  );
48
67
  }
49
68
  try {
@@ -73,13 +92,18 @@ function getServiceAccount() {
73
92
  }
74
93
  }
75
94
  function getProjectId() {
76
- const projectId = process.env.FIREBASE_PROJECT_ID || process.env.PUBLIC_FIREBASE_PROJECT_ID;
77
- if (!projectId) {
78
- throw new Error(
79
- "Firebase project ID not found. Please set one of: FIREBASE_PROJECT_ID or PUBLIC_FIREBASE_PROJECT_ID"
80
- );
95
+ if (globalConfig.projectId) {
96
+ return globalConfig.projectId;
97
+ }
98
+ if (typeof process !== "undefined" && process.env) {
99
+ const projectId = process.env.FIREBASE_PROJECT_ID || process.env.PUBLIC_FIREBASE_PROJECT_ID;
100
+ if (projectId) {
101
+ return projectId;
102
+ }
81
103
  }
82
- return projectId;
104
+ throw new Error(
105
+ "Firebase project ID not configured. Either call initializeApp({ projectId: ... }) or set FIREBASE_PROJECT_ID environment variable."
106
+ );
83
107
  }
84
108
 
85
109
  // src/x509.ts
@@ -173,18 +197,22 @@ async function importPublicKeyFromX509(pem) {
173
197
  // src/auth.ts
174
198
  var publicKeysCache = null;
175
199
  var publicKeysCacheExpiry = 0;
176
- async function fetchPublicKeys() {
200
+ async function fetchPublicKeys(issuer) {
201
+ let endpoint = "https://www.googleapis.com/robot/v1/metadata/x509/securetoken@system.gserviceaccount.com";
202
+ if (issuer && issuer.includes("session.firebase.google.com")) {
203
+ endpoint = "https://www.googleapis.com/identitytoolkit/v3/relyingparty/publicKeys";
204
+ }
177
205
  if (publicKeysCache && Date.now() < publicKeysCacheExpiry) {
178
206
  return publicKeysCache;
179
207
  }
180
- const response = await fetch(
181
- "https://www.googleapis.com/robot/v1/metadata/x509/securetoken@system.gserviceaccount.com"
182
- );
208
+ console.log(`[fetchPublicKeys] Fetching from: ${endpoint}`);
209
+ const response = await fetch(endpoint);
183
210
  if (!response.ok) {
184
- throw new Error("Failed to fetch Firebase public keys");
211
+ throw new Error(`Failed to fetch Firebase public keys from ${endpoint}`);
185
212
  }
186
213
  publicKeysCache = await response.json();
187
214
  publicKeysCacheExpiry = Date.now() + 36e5;
215
+ console.log(`[fetchPublicKeys] Fetched ${Object.keys(publicKeysCache || {}).length} keys`);
188
216
  return publicKeysCache;
189
217
  }
190
218
  function base64UrlDecode(str) {
@@ -257,13 +285,20 @@ async function verifyIdToken(idToken) {
257
285
  if (payload.sub.length > 128) {
258
286
  throw new Error("Subject too long");
259
287
  }
260
- const publicKeys = await fetchPublicKeys();
261
- const publicKeyPem = publicKeys[header.kid];
288
+ let publicKeys = await fetchPublicKeys(payload.iss);
289
+ let publicKeyPem = publicKeys[header.kid];
262
290
  if (!publicKeyPem) {
263
- const availableKids = Object.keys(publicKeys).join(", ");
264
- throw new Error(
265
- `Public key not found for kid: ${header.kid}. Available kids: ${availableKids}. This might indicate a key rotation issue or the token is from a different Firebase project.`
266
- );
291
+ console.log(`[verifyIdToken] Key ${header.kid} not found in cache, refreshing keys...`);
292
+ publicKeysCache = null;
293
+ publicKeysCacheExpiry = 0;
294
+ publicKeys = await fetchPublicKeys(payload.iss);
295
+ publicKeyPem = publicKeys[header.kid];
296
+ if (!publicKeyPem) {
297
+ const availableKids = Object.keys(publicKeys).join(", ");
298
+ throw new Error(
299
+ `Public key not found for kid: ${header.kid}. Available kids: ${availableKids}. This might indicate the token is from a different Firebase project or was signed with a very old key.`
300
+ );
301
+ }
267
302
  }
268
303
  const publicKey = await importPublicKeyFromX509(publicKeyPem);
269
304
  const isValid = await verifySignature(idToken, publicKey);
@@ -863,14 +898,17 @@ async function batchWrite(operations) {
863
898
  FieldValue,
864
899
  addDocument,
865
900
  batchWrite,
901
+ clearConfig,
866
902
  clearTokenCache,
867
903
  deleteDocument,
868
904
  getAdminAccessToken,
869
905
  getAuth,
906
+ getConfig,
870
907
  getDocument,
871
908
  getProjectId,
872
909
  getServiceAccount,
873
910
  getUserFromToken,
911
+ initializeApp,
874
912
  queryDocuments,
875
913
  setDocument,
876
914
  updateDocument,
package/dist/index.mjs CHANGED
@@ -1,9 +1,25 @@
1
- // src/service-account.ts
1
+ // src/config.ts
2
+ var globalConfig = {};
3
+ function initializeApp(config) {
4
+ globalConfig = { ...config };
5
+ }
6
+ function getConfig() {
7
+ return globalConfig;
8
+ }
9
+ function clearConfig() {
10
+ globalConfig = {};
11
+ }
2
12
  function getServiceAccount() {
3
- const key = process.env.FIREBASE_ADMIN_SERVICE_ACCOUNT_KEY;
13
+ if (globalConfig.serviceAccount) {
14
+ if (typeof globalConfig.serviceAccount === "string") {
15
+ return JSON.parse(globalConfig.serviceAccount);
16
+ }
17
+ return globalConfig.serviceAccount;
18
+ }
19
+ const key = typeof process !== "undefined" && process.env?.FIREBASE_ADMIN_SERVICE_ACCOUNT_KEY;
4
20
  if (!key) {
5
21
  throw new Error(
6
- `FIREBASE_ADMIN_SERVICE_ACCOUNT_KEY environment variable is not set. Please provide your Firebase service account JSON as a string. Example: FIREBASE_ADMIN_SERVICE_ACCOUNT_KEY='{"type":"service_account",...}'`
22
+ "Firebase service account not configured. Either call initializeApp({ serviceAccount: ... }) or set FIREBASE_ADMIN_SERVICE_ACCOUNT_KEY environment variable."
7
23
  );
8
24
  }
9
25
  try {
@@ -33,13 +49,18 @@ function getServiceAccount() {
33
49
  }
34
50
  }
35
51
  function getProjectId() {
36
- const projectId = process.env.FIREBASE_PROJECT_ID || process.env.PUBLIC_FIREBASE_PROJECT_ID;
37
- if (!projectId) {
38
- throw new Error(
39
- "Firebase project ID not found. Please set one of: FIREBASE_PROJECT_ID or PUBLIC_FIREBASE_PROJECT_ID"
40
- );
52
+ if (globalConfig.projectId) {
53
+ return globalConfig.projectId;
54
+ }
55
+ if (typeof process !== "undefined" && process.env) {
56
+ const projectId = process.env.FIREBASE_PROJECT_ID || process.env.PUBLIC_FIREBASE_PROJECT_ID;
57
+ if (projectId) {
58
+ return projectId;
59
+ }
41
60
  }
42
- return projectId;
61
+ throw new Error(
62
+ "Firebase project ID not configured. Either call initializeApp({ projectId: ... }) or set FIREBASE_PROJECT_ID environment variable."
63
+ );
43
64
  }
44
65
 
45
66
  // src/x509.ts
@@ -133,18 +154,22 @@ async function importPublicKeyFromX509(pem) {
133
154
  // src/auth.ts
134
155
  var publicKeysCache = null;
135
156
  var publicKeysCacheExpiry = 0;
136
- async function fetchPublicKeys() {
157
+ async function fetchPublicKeys(issuer) {
158
+ let endpoint = "https://www.googleapis.com/robot/v1/metadata/x509/securetoken@system.gserviceaccount.com";
159
+ if (issuer && issuer.includes("session.firebase.google.com")) {
160
+ endpoint = "https://www.googleapis.com/identitytoolkit/v3/relyingparty/publicKeys";
161
+ }
137
162
  if (publicKeysCache && Date.now() < publicKeysCacheExpiry) {
138
163
  return publicKeysCache;
139
164
  }
140
- const response = await fetch(
141
- "https://www.googleapis.com/robot/v1/metadata/x509/securetoken@system.gserviceaccount.com"
142
- );
165
+ console.log(`[fetchPublicKeys] Fetching from: ${endpoint}`);
166
+ const response = await fetch(endpoint);
143
167
  if (!response.ok) {
144
- throw new Error("Failed to fetch Firebase public keys");
168
+ throw new Error(`Failed to fetch Firebase public keys from ${endpoint}`);
145
169
  }
146
170
  publicKeysCache = await response.json();
147
171
  publicKeysCacheExpiry = Date.now() + 36e5;
172
+ console.log(`[fetchPublicKeys] Fetched ${Object.keys(publicKeysCache || {}).length} keys`);
148
173
  return publicKeysCache;
149
174
  }
150
175
  function base64UrlDecode(str) {
@@ -217,13 +242,20 @@ async function verifyIdToken(idToken) {
217
242
  if (payload.sub.length > 128) {
218
243
  throw new Error("Subject too long");
219
244
  }
220
- const publicKeys = await fetchPublicKeys();
221
- const publicKeyPem = publicKeys[header.kid];
245
+ let publicKeys = await fetchPublicKeys(payload.iss);
246
+ let publicKeyPem = publicKeys[header.kid];
222
247
  if (!publicKeyPem) {
223
- const availableKids = Object.keys(publicKeys).join(", ");
224
- throw new Error(
225
- `Public key not found for kid: ${header.kid}. Available kids: ${availableKids}. This might indicate a key rotation issue or the token is from a different Firebase project.`
226
- );
248
+ console.log(`[verifyIdToken] Key ${header.kid} not found in cache, refreshing keys...`);
249
+ publicKeysCache = null;
250
+ publicKeysCacheExpiry = 0;
251
+ publicKeys = await fetchPublicKeys(payload.iss);
252
+ publicKeyPem = publicKeys[header.kid];
253
+ if (!publicKeyPem) {
254
+ const availableKids = Object.keys(publicKeys).join(", ");
255
+ throw new Error(
256
+ `Public key not found for kid: ${header.kid}. Available kids: ${availableKids}. This might indicate the token is from a different Firebase project or was signed with a very old key.`
257
+ );
258
+ }
227
259
  }
228
260
  const publicKey = await importPublicKeyFromX509(publicKeyPem);
229
261
  const isValid = await verifySignature(idToken, publicKey);
@@ -822,14 +854,17 @@ export {
822
854
  FieldValue,
823
855
  addDocument,
824
856
  batchWrite,
857
+ clearConfig,
825
858
  clearTokenCache,
826
859
  deleteDocument,
827
860
  getAdminAccessToken,
828
861
  getAuth,
862
+ getConfig,
829
863
  getDocument,
830
864
  getProjectId,
831
865
  getServiceAccount,
832
866
  getUserFromToken,
867
+ initializeApp,
833
868
  queryDocuments,
834
869
  setDocument,
835
870
  updateDocument,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@prmichaelsen/firebase-admin-sdk-v8",
3
- "version": "2.0.2",
3
+ "version": "2.0.5",
4
4
  "description": "Firebase Admin SDK for Cloudflare Workers and edge runtimes using REST APIs",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",