firebase-admin-edge 1.1.1 → 2.0.0

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.
Files changed (437) hide show
  1. package/README.md +102 -261
  2. package/dist/app-check/app-check-endpoints.d.ts +31 -0
  3. package/dist/app-check/app-check-endpoints.d.ts.map +1 -0
  4. package/dist/app-check/app-check-endpoints.js +75 -0
  5. package/dist/app-check/app-check-endpoints.js.map +1 -0
  6. package/dist/app-check/app-check-jwt.d.ts +16 -0
  7. package/dist/app-check/app-check-jwt.d.ts.map +1 -0
  8. package/dist/app-check/app-check-jwt.js +59 -0
  9. package/dist/app-check/app-check-jwt.js.map +1 -0
  10. package/dist/app-check/app-check.d.ts +43 -0
  11. package/dist/app-check/app-check.d.ts.map +1 -0
  12. package/dist/app-check/app-check.js +141 -0
  13. package/dist/app-check/app-check.js.map +1 -0
  14. package/dist/auth/auth-blocking-types.d.ts +44 -0
  15. package/dist/auth/auth-blocking-types.d.ts.map +1 -0
  16. package/dist/auth/auth-blocking-types.js +2 -0
  17. package/dist/auth/auth-blocking-types.js.map +1 -0
  18. package/dist/auth/auth-config-types.d.ts +146 -0
  19. package/dist/auth/auth-config-types.d.ts.map +1 -0
  20. package/dist/auth/auth-config-types.js +2 -0
  21. package/dist/auth/auth-config-types.js.map +1 -0
  22. package/dist/auth/auth-config.d.ts +15 -0
  23. package/dist/auth/auth-config.d.ts.map +1 -0
  24. package/dist/auth/auth-config.js +413 -0
  25. package/dist/auth/auth-config.js.map +1 -0
  26. package/dist/auth/auth-emulator.d.ts +7 -0
  27. package/dist/auth/auth-emulator.d.ts.map +1 -0
  28. package/dist/auth/auth-emulator.js +24 -0
  29. package/dist/auth/auth-emulator.js.map +1 -0
  30. package/dist/auth/auth-endpoint-errors.d.ts +2 -0
  31. package/dist/auth/auth-endpoint-errors.d.ts.map +1 -1
  32. package/dist/auth/auth-endpoint-errors.js +20 -1
  33. package/dist/auth/auth-endpoint-errors.js.map +1 -1
  34. package/dist/auth/email-link.d.ts +24 -0
  35. package/dist/auth/email-link.d.ts.map +1 -0
  36. package/dist/auth/email-link.js +103 -0
  37. package/dist/auth/email-link.js.map +1 -0
  38. package/dist/auth/firebase-admin-auth.d.ts +29 -4
  39. package/dist/auth/firebase-admin-auth.d.ts.map +1 -1
  40. package/dist/auth/firebase-admin-auth.js +192 -59
  41. package/dist/auth/firebase-admin-auth.js.map +1 -1
  42. package/dist/auth/firebase-auth-endpoints.d.ts +64 -5
  43. package/dist/auth/firebase-auth-endpoints.d.ts.map +1 -1
  44. package/dist/auth/firebase-auth-endpoints.js +258 -73
  45. package/dist/auth/firebase-auth-endpoints.js.map +1 -1
  46. package/dist/auth/firebase-auth.d.ts +78 -4
  47. package/dist/auth/firebase-auth.d.ts.map +1 -1
  48. package/dist/auth/firebase-auth.js +101 -8
  49. package/dist/auth/firebase-auth.js.map +1 -1
  50. package/dist/auth/firebase-jwt.d.ts +19 -10
  51. package/dist/auth/firebase-jwt.d.ts.map +1 -1
  52. package/dist/auth/firebase-jwt.js +176 -39
  53. package/dist/auth/firebase-jwt.js.map +1 -1
  54. package/dist/auth/firebase-types.d.ts +3 -0
  55. package/dist/auth/firebase-types.d.ts.map +1 -1
  56. package/dist/auth/google-oauth.d.ts +0 -1
  57. package/dist/auth/google-oauth.d.ts.map +1 -1
  58. package/dist/auth/google-oauth.js +16 -86
  59. package/dist/auth/google-oauth.js.map +1 -1
  60. package/dist/auth/project-config-manager.d.ts +10 -0
  61. package/dist/auth/project-config-manager.d.ts.map +1 -0
  62. package/dist/auth/project-config-manager.js +22 -0
  63. package/dist/auth/project-config-manager.js.map +1 -0
  64. package/dist/auth/provider-credential.d.ts +43 -0
  65. package/dist/auth/provider-credential.d.ts.map +1 -0
  66. package/dist/auth/provider-credential.js +107 -0
  67. package/dist/auth/provider-credential.js.map +1 -0
  68. package/dist/auth/provider-session.d.ts +10 -0
  69. package/dist/auth/provider-session.d.ts.map +1 -0
  70. package/dist/auth/provider-session.js +28 -0
  71. package/dist/auth/provider-session.js.map +1 -0
  72. package/dist/auth/tenant-manager.d.ts +17 -0
  73. package/dist/auth/tenant-manager.d.ts.map +1 -0
  74. package/dist/auth/tenant-manager.js +59 -0
  75. package/dist/auth/tenant-manager.js.map +1 -0
  76. package/dist/db/aggregate.d.ts +49 -0
  77. package/dist/db/aggregate.d.ts.map +1 -0
  78. package/dist/db/aggregate.js +115 -0
  79. package/dist/db/aggregate.js.map +1 -0
  80. package/dist/db/bulk-writer.d.ts +55 -0
  81. package/dist/db/bulk-writer.d.ts.map +1 -0
  82. package/dist/db/bulk-writer.js +257 -0
  83. package/dist/db/bulk-writer.js.map +1 -0
  84. package/dist/db/bundle-builder.d.ts +17 -0
  85. package/dist/db/bundle-builder.d.ts.map +1 -0
  86. package/dist/db/bundle-builder.js +118 -0
  87. package/dist/db/bundle-builder.js.map +1 -0
  88. package/dist/db/bytes.d.ts +12 -0
  89. package/dist/db/bytes.d.ts.map +1 -0
  90. package/dist/db/bytes.js +49 -0
  91. package/dist/db/bytes.js.map +1 -0
  92. package/dist/db/collection-group.d.ts +14 -0
  93. package/dist/db/collection-group.d.ts.map +1 -0
  94. package/dist/db/collection-group.js +43 -0
  95. package/dist/db/collection-group.js.map +1 -0
  96. package/dist/db/collection-reference.d.ts +21 -0
  97. package/dist/db/collection-reference.d.ts.map +1 -0
  98. package/dist/db/collection-reference.js +46 -0
  99. package/dist/db/collection-reference.js.map +1 -0
  100. package/dist/db/document-reference.d.ts +41 -0
  101. package/dist/db/document-reference.d.ts.map +1 -0
  102. package/dist/db/document-reference.js +125 -0
  103. package/dist/db/document-reference.js.map +1 -0
  104. package/dist/db/document-snapshot.d.ts +31 -0
  105. package/dist/db/document-snapshot.d.ts.map +1 -0
  106. package/dist/db/document-snapshot.js +103 -0
  107. package/dist/db/document-snapshot.js.map +1 -0
  108. package/dist/db/explain.d.ts +28 -0
  109. package/dist/db/explain.d.ts.map +1 -0
  110. package/dist/db/explain.js +61 -0
  111. package/dist/db/explain.js.map +1 -0
  112. package/dist/db/field-path.d.ts +10 -0
  113. package/dist/db/field-path.d.ts.map +1 -0
  114. package/dist/db/field-path.js +65 -0
  115. package/dist/db/field-path.js.map +1 -0
  116. package/dist/db/field-value.d.ts +17 -0
  117. package/dist/db/field-value.d.ts.map +1 -0
  118. package/dist/db/field-value.js +57 -0
  119. package/dist/db/field-value.js.map +1 -0
  120. package/dist/db/filter.d.ts +20 -0
  121. package/dist/db/filter.d.ts.map +1 -0
  122. package/dist/db/filter.js +48 -0
  123. package/dist/db/filter.js.map +1 -0
  124. package/dist/db/firestore-converter.d.ts +11 -0
  125. package/dist/db/firestore-converter.d.ts.map +1 -0
  126. package/dist/db/firestore-converter.js +14 -0
  127. package/dist/db/firestore-converter.js.map +1 -0
  128. package/dist/db/firestore-document.d.ts +62 -0
  129. package/dist/db/firestore-document.d.ts.map +1 -0
  130. package/dist/db/firestore-document.js +238 -0
  131. package/dist/db/firestore-document.js.map +1 -0
  132. package/dist/db/firestore-endpoints.d.ts +41 -0
  133. package/dist/db/firestore-endpoints.d.ts.map +1 -0
  134. package/dist/db/firestore-endpoints.js +735 -0
  135. package/dist/db/firestore-endpoints.js.map +1 -0
  136. package/dist/db/firestore-error-codes.d.ts +24 -0
  137. package/dist/db/firestore-error-codes.d.ts.map +1 -0
  138. package/dist/db/firestore-error-codes.js +24 -0
  139. package/dist/db/firestore-error-codes.js.map +1 -0
  140. package/dist/db/firestore-logging.d.ts +23 -0
  141. package/dist/db/firestore-logging.d.ts.map +1 -0
  142. package/dist/db/firestore-logging.js +41 -0
  143. package/dist/db/firestore-logging.js.map +1 -0
  144. package/dist/db/firestore-path.d.ts +4 -0
  145. package/dist/db/firestore-path.d.ts.map +1 -0
  146. package/dist/db/firestore-path.js +37 -0
  147. package/dist/db/firestore-path.js.map +1 -0
  148. package/dist/db/firestore-results.d.ts +12 -0
  149. package/dist/db/firestore-results.d.ts.map +1 -0
  150. package/dist/db/firestore-results.js +19 -0
  151. package/dist/db/firestore-results.js.map +1 -0
  152. package/dist/db/firestore-settings.d.ts +22 -0
  153. package/dist/db/firestore-settings.d.ts.map +1 -0
  154. package/dist/db/firestore-settings.js +83 -0
  155. package/dist/db/firestore-settings.js.map +1 -0
  156. package/dist/db/firestore-telemetry.d.ts +21 -0
  157. package/dist/db/firestore-telemetry.d.ts.map +1 -0
  158. package/dist/db/firestore-telemetry.js +84 -0
  159. package/dist/db/firestore-telemetry.js.map +1 -0
  160. package/dist/db/firestore-types.d.ts +25 -0
  161. package/dist/db/firestore-types.d.ts.map +1 -0
  162. package/dist/db/firestore-types.js +2 -0
  163. package/dist/db/firestore-types.js.map +1 -0
  164. package/dist/db/firestore.d.ts +151 -0
  165. package/dist/db/firestore.d.ts.map +1 -0
  166. package/dist/db/firestore.js +505 -0
  167. package/dist/db/firestore.js.map +1 -0
  168. package/dist/db/geo-point.d.ts +11 -0
  169. package/dist/db/geo-point.d.ts.map +1 -0
  170. package/dist/db/geo-point.js +29 -0
  171. package/dist/db/geo-point.js.map +1 -0
  172. package/dist/db/json-stream.d.ts +3 -0
  173. package/dist/db/json-stream.d.ts.map +1 -0
  174. package/dist/db/json-stream.js +117 -0
  175. package/dist/db/json-stream.js.map +1 -0
  176. package/dist/db/pipeline-expression.d.ts +293 -0
  177. package/dist/db/pipeline-expression.d.ts.map +1 -0
  178. package/dist/db/pipeline-expression.js +1436 -0
  179. package/dist/db/pipeline-expression.js.map +1 -0
  180. package/dist/db/pipeline-query.d.ts +6 -0
  181. package/dist/db/pipeline-query.d.ts.map +1 -0
  182. package/dist/db/pipeline-query.js +91 -0
  183. package/dist/db/pipeline-query.js.map +1 -0
  184. package/dist/db/pipeline.d.ts +120 -0
  185. package/dist/db/pipeline.d.ts.map +1 -0
  186. package/dist/db/pipeline.js +396 -0
  187. package/dist/db/pipeline.js.map +1 -0
  188. package/dist/db/query-document-snapshot.d.ts +2 -0
  189. package/dist/db/query-document-snapshot.d.ts.map +1 -0
  190. package/dist/db/query-document-snapshot.js +2 -0
  191. package/dist/db/query-document-snapshot.js.map +1 -0
  192. package/dist/db/query-partition.d.ts +14 -0
  193. package/dist/db/query-partition.d.ts.map +1 -0
  194. package/dist/db/query-partition.js +32 -0
  195. package/dist/db/query-partition.js.map +1 -0
  196. package/dist/db/query-request.d.ts +96 -0
  197. package/dist/db/query-request.d.ts.map +1 -0
  198. package/dist/db/query-request.js +283 -0
  199. package/dist/db/query-request.js.map +1 -0
  200. package/dist/db/query.d.ts +129 -0
  201. package/dist/db/query.d.ts.map +1 -0
  202. package/dist/db/query.js +468 -0
  203. package/dist/db/query.js.map +1 -0
  204. package/dist/db/recursive-delete.d.ts +6 -0
  205. package/dist/db/recursive-delete.d.ts.map +1 -0
  206. package/dist/db/recursive-delete.js +38 -0
  207. package/dist/db/recursive-delete.js.map +1 -0
  208. package/dist/db/snapshot-listener.d.ts +10 -0
  209. package/dist/db/snapshot-listener.d.ts.map +1 -0
  210. package/dist/db/snapshot-listener.js +71 -0
  211. package/dist/db/snapshot-listener.js.map +1 -0
  212. package/dist/db/timestamp.d.ts +29 -0
  213. package/dist/db/timestamp.d.ts.map +1 -0
  214. package/dist/db/timestamp.js +98 -0
  215. package/dist/db/timestamp.js.map +1 -0
  216. package/dist/db/transaction.d.ts +44 -0
  217. package/dist/db/transaction.d.ts.map +1 -0
  218. package/dist/db/transaction.js +177 -0
  219. package/dist/db/transaction.js.map +1 -0
  220. package/dist/db/value-equality.d.ts +3 -0
  221. package/dist/db/value-equality.d.ts.map +1 -0
  222. package/dist/db/value-equality.js +29 -0
  223. package/dist/db/value-equality.js.map +1 -0
  224. package/dist/db/vector-query.d.ts +38 -0
  225. package/dist/db/vector-query.d.ts.map +1 -0
  226. package/dist/db/vector-query.js +110 -0
  227. package/dist/db/vector-query.js.map +1 -0
  228. package/dist/db/vector-value.d.ts +8 -0
  229. package/dist/db/vector-value.d.ts.map +1 -0
  230. package/dist/db/vector-value.js +25 -0
  231. package/dist/db/vector-value.js.map +1 -0
  232. package/dist/db/write-batch.d.ts +25 -0
  233. package/dist/db/write-batch.d.ts.map +1 -0
  234. package/dist/db/write-batch.js +72 -0
  235. package/dist/db/write-batch.js.map +1 -0
  236. package/dist/db/write-request.d.ts +36 -0
  237. package/dist/db/write-request.d.ts.map +1 -0
  238. package/dist/db/write-request.js +257 -0
  239. package/dist/db/write-request.js.map +1 -0
  240. package/dist/firebase-edge-server.d.ts +143 -36
  241. package/dist/firebase-edge-server.d.ts.map +1 -1
  242. package/dist/firebase-edge-server.js +463 -258
  243. package/dist/firebase-edge-server.js.map +1 -1
  244. package/dist/index.d.ts +6 -0
  245. package/dist/index.d.ts.map +1 -1
  246. package/dist/index.js +5 -0
  247. package/dist/index.js.map +1 -1
  248. package/dist/rest-fetch.d.ts +1 -1
  249. package/dist/rest-fetch.d.ts.map +1 -1
  250. package/dist/storage/storage-acl.d.ts +48 -0
  251. package/dist/storage/storage-acl.d.ts.map +1 -0
  252. package/dist/storage/storage-acl.js +101 -0
  253. package/dist/storage/storage-acl.js.map +1 -0
  254. package/dist/storage/storage-bucket-endpoints.d.ts +10 -0
  255. package/dist/storage/storage-bucket-endpoints.d.ts.map +1 -0
  256. package/dist/storage/storage-bucket-endpoints.js +514 -0
  257. package/dist/storage/storage-bucket-endpoints.js.map +1 -0
  258. package/dist/storage/storage-bucket-types.d.ts +183 -0
  259. package/dist/storage/storage-bucket-types.d.ts.map +1 -0
  260. package/dist/storage/storage-bucket-types.js +2 -0
  261. package/dist/storage/storage-bucket-types.js.map +1 -0
  262. package/dist/storage/storage-bucket.d.ts +122 -0
  263. package/dist/storage/storage-bucket.d.ts.map +1 -0
  264. package/dist/storage/storage-bucket.js +544 -0
  265. package/dist/storage/storage-bucket.js.map +1 -0
  266. package/dist/storage/storage-channel.d.ts +10 -0
  267. package/dist/storage/storage-channel.d.ts.map +1 -0
  268. package/dist/storage/storage-channel.js +15 -0
  269. package/dist/storage/storage-channel.js.map +1 -0
  270. package/dist/storage/storage-checksum.d.ts +35 -0
  271. package/dist/storage/storage-checksum.d.ts.map +1 -0
  272. package/dist/storage/storage-checksum.js +312 -0
  273. package/dist/storage/storage-checksum.js.map +1 -0
  274. package/dist/storage/storage-endpoints.d.ts +14 -0
  275. package/dist/storage/storage-endpoints.d.ts.map +1 -0
  276. package/dist/storage/storage-endpoints.js +721 -0
  277. package/dist/storage/storage-endpoints.js.map +1 -0
  278. package/dist/storage/storage-file.d.ts +126 -0
  279. package/dist/storage/storage-file.d.ts.map +1 -0
  280. package/dist/storage/storage-file.js +604 -0
  281. package/dist/storage/storage-file.js.map +1 -0
  282. package/dist/storage/storage-hmac-key.d.ts +26 -0
  283. package/dist/storage/storage-hmac-key.d.ts.map +1 -0
  284. package/dist/storage/storage-hmac-key.js +45 -0
  285. package/dist/storage/storage-hmac-key.js.map +1 -0
  286. package/dist/storage/storage-iam.d.ts +20 -0
  287. package/dist/storage/storage-iam.d.ts.map +1 -0
  288. package/dist/storage/storage-iam.js +43 -0
  289. package/dist/storage/storage-iam.js.map +1 -0
  290. package/dist/storage/storage-md5.d.ts +11 -0
  291. package/dist/storage/storage-md5.d.ts.map +1 -0
  292. package/dist/storage/storage-md5.js +96 -0
  293. package/dist/storage/storage-md5.js.map +1 -0
  294. package/dist/storage/storage-notification.d.ts +24 -0
  295. package/dist/storage/storage-notification.d.ts.map +1 -0
  296. package/dist/storage/storage-notification.js +40 -0
  297. package/dist/storage/storage-notification.js.map +1 -0
  298. package/dist/storage/storage-progress.d.ts +4 -0
  299. package/dist/storage/storage-progress.d.ts.map +1 -0
  300. package/dist/storage/storage-progress.js +17 -0
  301. package/dist/storage/storage-progress.js.map +1 -0
  302. package/dist/storage/storage-reference-endpoints.d.ts +63 -0
  303. package/dist/storage/storage-reference-endpoints.d.ts.map +1 -0
  304. package/dist/storage/storage-reference-endpoints.js +276 -0
  305. package/dist/storage/storage-reference-endpoints.js.map +1 -0
  306. package/dist/storage/storage-reference-helpers.d.ts +12 -0
  307. package/dist/storage/storage-reference-helpers.d.ts.map +1 -0
  308. package/dist/storage/storage-reference-helpers.js +72 -0
  309. package/dist/storage/storage-reference-helpers.js.map +1 -0
  310. package/dist/storage/storage-reference-signing.d.ts +40 -0
  311. package/dist/storage/storage-reference-signing.d.ts.map +1 -0
  312. package/dist/storage/storage-reference-signing.js +289 -0
  313. package/dist/storage/storage-reference-signing.js.map +1 -0
  314. package/dist/storage/storage-reference-types.d.ts +76 -0
  315. package/dist/storage/storage-reference-types.d.ts.map +1 -0
  316. package/dist/storage/storage-reference-types.js +2 -0
  317. package/dist/storage/storage-reference-types.js.map +1 -0
  318. package/dist/storage/storage-results.d.ts +8 -0
  319. package/dist/storage/storage-results.d.ts.map +1 -0
  320. package/dist/storage/storage-results.js +32 -0
  321. package/dist/storage/storage-results.js.map +1 -0
  322. package/dist/storage/storage-resumable.d.ts +18 -0
  323. package/dist/storage/storage-resumable.d.ts.map +1 -0
  324. package/dist/storage/storage-resumable.js +166 -0
  325. package/dist/storage/storage-resumable.js.map +1 -0
  326. package/dist/storage/storage-retry.d.ts +9 -0
  327. package/dist/storage/storage-retry.d.ts.map +1 -0
  328. package/dist/storage/storage-retry.js +104 -0
  329. package/dist/storage/storage-retry.js.map +1 -0
  330. package/dist/storage/storage-signed-url.d.ts +9 -0
  331. package/dist/storage/storage-signed-url.d.ts.map +1 -0
  332. package/dist/storage/storage-signed-url.js +96 -0
  333. package/dist/storage/storage-signed-url.js.map +1 -0
  334. package/dist/storage/storage-special-endpoints.d.ts +10 -0
  335. package/dist/storage/storage-special-endpoints.d.ts.map +1 -0
  336. package/dist/storage/storage-special-endpoints.js +394 -0
  337. package/dist/storage/storage-special-endpoints.js.map +1 -0
  338. package/dist/storage/storage-special-types.d.ts +154 -0
  339. package/dist/storage/storage-special-types.d.ts.map +1 -0
  340. package/dist/storage/storage-special-types.js +2 -0
  341. package/dist/storage/storage-special-types.js.map +1 -0
  342. package/dist/storage/storage-types.d.ts +251 -0
  343. package/dist/storage/storage-types.d.ts.map +1 -0
  344. package/dist/storage/storage-types.js +2 -0
  345. package/dist/storage/storage-types.js.map +1 -0
  346. package/dist/storage/storage-upload-stream.d.ts +41 -0
  347. package/dist/storage/storage-upload-stream.d.ts.map +1 -0
  348. package/dist/storage/storage-upload-stream.js +335 -0
  349. package/dist/storage/storage-upload-stream.js.map +1 -0
  350. package/dist/storage/storage-xml-signing.d.ts +17 -0
  351. package/dist/storage/storage-xml-signing.d.ts.map +1 -0
  352. package/dist/storage/storage-xml-signing.js +144 -0
  353. package/dist/storage/storage-xml-signing.js.map +1 -0
  354. package/dist/storage/storage.d.ts +152 -0
  355. package/dist/storage/storage.d.ts.map +1 -0
  356. package/dist/storage/storage.js +532 -0
  357. package/dist/storage/storage.js.map +1 -0
  358. package/dist/utils/token-cache.d.ts.map +1 -1
  359. package/dist/utils/token-cache.js +3 -2
  360. package/dist/utils/token-cache.js.map +1 -1
  361. package/package.json +22 -6
  362. package/dist/auth/auth-endpoint-errors.test.d.ts +0 -2
  363. package/dist/auth/auth-endpoint-errors.test.d.ts.map +0 -1
  364. package/dist/auth/auth-endpoint-errors.test.js +0 -411
  365. package/dist/auth/auth-endpoint-errors.test.js.map +0 -1
  366. package/dist/auth/email-action-request.test.d.ts +0 -2
  367. package/dist/auth/email-action-request.test.d.ts.map +0 -1
  368. package/dist/auth/email-action-request.test.js +0 -128
  369. package/dist/auth/email-action-request.test.js.map +0 -1
  370. package/dist/auth/errors.test.d.ts +0 -2
  371. package/dist/auth/errors.test.d.ts.map +0 -1
  372. package/dist/auth/errors.test.js +0 -123
  373. package/dist/auth/errors.test.js.map +0 -1
  374. package/dist/auth/firebase-admin-auth.test.d.ts +0 -2
  375. package/dist/auth/firebase-admin-auth.test.d.ts.map +0 -1
  376. package/dist/auth/firebase-admin-auth.test.js +0 -1542
  377. package/dist/auth/firebase-admin-auth.test.js.map +0 -1
  378. package/dist/auth/firebase-auth-endpoints.test.d.ts +0 -2
  379. package/dist/auth/firebase-auth-endpoints.test.d.ts.map +0 -1
  380. package/dist/auth/firebase-auth-endpoints.test.js +0 -1082
  381. package/dist/auth/firebase-auth-endpoints.test.js.map +0 -1
  382. package/dist/auth/firebase-auth.test.d.ts +0 -2
  383. package/dist/auth/firebase-auth.test.d.ts.map +0 -1
  384. package/dist/auth/firebase-auth.test.js +0 -167
  385. package/dist/auth/firebase-auth.test.js.map +0 -1
  386. package/dist/auth/firebase-jwt.test.d.ts +0 -2
  387. package/dist/auth/firebase-jwt.test.d.ts.map +0 -1
  388. package/dist/auth/firebase-jwt.test.js +0 -164
  389. package/dist/auth/firebase-jwt.test.js.map +0 -1
  390. package/dist/auth/github-oauth.d.ts +0 -19
  391. package/dist/auth/github-oauth.d.ts.map +0 -1
  392. package/dist/auth/github-oauth.js +0 -145
  393. package/dist/auth/github-oauth.js.map +0 -1
  394. package/dist/auth/github-oauth.test.d.ts +0 -2
  395. package/dist/auth/github-oauth.test.d.ts.map +0 -1
  396. package/dist/auth/github-oauth.test.js +0 -202
  397. package/dist/auth/github-oauth.test.js.map +0 -1
  398. package/dist/auth/google-oauth.test.d.ts +0 -2
  399. package/dist/auth/google-oauth.test.d.ts.map +0 -1
  400. package/dist/auth/google-oauth.test.js +0 -200
  401. package/dist/auth/google-oauth.test.js.map +0 -1
  402. package/dist/auth/oauth.d.ts +0 -3
  403. package/dist/auth/oauth.d.ts.map +0 -1
  404. package/dist/auth/oauth.js +0 -48
  405. package/dist/auth/oauth.js.map +0 -1
  406. package/dist/auth/oauth.test.d.ts +0 -2
  407. package/dist/auth/oauth.test.d.ts.map +0 -1
  408. package/dist/auth/oauth.test.js +0 -109
  409. package/dist/auth/oauth.test.js.map +0 -1
  410. package/dist/auth/user-batch.test.d.ts +0 -2
  411. package/dist/auth/user-batch.test.d.ts.map +0 -1
  412. package/dist/auth/user-batch.test.js +0 -73
  413. package/dist/auth/user-batch.test.js.map +0 -1
  414. package/dist/auth/user-import.test.d.ts +0 -2
  415. package/dist/auth/user-import.test.d.ts.map +0 -1
  416. package/dist/auth/user-import.test.js +0 -217
  417. package/dist/auth/user-import.test.js.map +0 -1
  418. package/dist/auth/user-record.test.d.ts +0 -2
  419. package/dist/auth/user-record.test.d.ts.map +0 -1
  420. package/dist/auth/user-record.test.js +0 -198
  421. package/dist/auth/user-record.test.js.map +0 -1
  422. package/dist/auth/user-request.test.d.ts +0 -2
  423. package/dist/auth/user-request.test.d.ts.map +0 -1
  424. package/dist/auth/user-request.test.js +0 -327
  425. package/dist/auth/user-request.test.js.map +0 -1
  426. package/dist/firebase-edge-errors.test.d.ts +0 -2
  427. package/dist/firebase-edge-errors.test.d.ts.map +0 -1
  428. package/dist/firebase-edge-errors.test.js +0 -72
  429. package/dist/firebase-edge-errors.test.js.map +0 -1
  430. package/dist/firebase-edge-server.test.d.ts +0 -2
  431. package/dist/firebase-edge-server.test.d.ts.map +0 -1
  432. package/dist/firebase-edge-server.test.js +0 -293
  433. package/dist/firebase-edge-server.test.js.map +0 -1
  434. package/dist/rest-fetch.test.d.ts +0 -2
  435. package/dist/rest-fetch.test.d.ts.map +0 -1
  436. package/dist/rest-fetch.test.js +0 -164
  437. package/dist/rest-fetch.test.js.map +0 -1
@@ -1,1082 +0,0 @@
1
- import { describe, it, expect, vi, beforeEach } from 'vitest';
2
- import { generateEmailActionLink, deleteAccountsAdmin, importAccountsAdmin, getAccountsInfo, createAccountAdmin, updateAccountAdmin, deleteAccountAdmin, refreshFirebaseIdToken, createAuthUri, signInWithIdp, signInWithCustomToken, getAccountInfo, downloadAccount, createSessionCookie, getJWKs, getPublicKeys, sendOobCode, signInWithEmailLink, linkWithOAuthCredential, unlinkProvider } from './firebase-auth-endpoints.js';
3
- import * as restFetch from '../rest-fetch.js';
4
- import { FirebaseEdgeError, FirebaseEndpointErrorInfo } from './errors.js';
5
- vi.mock('../rest-fetch.js');
6
- describe('firebase-auth-endpoints', () => {
7
- const mockFetch = vi.fn();
8
- const API_KEY = 'test-api-key';
9
- const PROJECT_ID = 'test-project';
10
- const ACCESS_TOKEN = 'test-access-token';
11
- beforeEach(() => {
12
- vi.clearAllMocks();
13
- });
14
- describe('generateEmailActionLink', () => {
15
- const body = {
16
- requestType: 'PASSWORD_RESET',
17
- email: 'person@example.com',
18
- returnOobLink: true,
19
- continueUrl: 'https://example.com/login'
20
- };
21
- it.each([undefined, 'tenant'])('requests a link without sending email for tenant %s', async (tenant) => {
22
- vi.mocked(restFetch.restFetch).mockResolvedValue({
23
- data: { oobLink: 'https://example.com/action' },
24
- error: null
25
- });
26
- expect(await generateEmailActionLink(PROJECT_ID, body, ACCESS_TOKEN, mockFetch, tenant)).toEqual({ data: 'https://example.com/action', error: null });
27
- expect(restFetch.restFetch).toHaveBeenCalledWith(`https://identitytoolkit.googleapis.com/v1/projects/test-project${tenant ? '/tenants/tenant' : ''}/accounts:sendOobCode`, {
28
- body,
29
- bearerToken: ACCESS_TOKEN,
30
- global: { fetch: mockFetch }
31
- });
32
- });
33
- it('maps Firebase errors', async () => {
34
- vi.mocked(restFetch.restFetch).mockResolvedValue({
35
- data: null,
36
- error: { error: { code: 400, message: 'EMAIL_NOT_FOUND' } }
37
- });
38
- const result = await generateEmailActionLink(PROJECT_ID, body, ACCESS_TOKEN);
39
- expect(result.data).toBeNull();
40
- expect(result.error).toBeInstanceOf(FirebaseEdgeError);
41
- });
42
- it('preserves ordinary transport errors', async () => {
43
- const cause = new Error('network');
44
- vi.mocked(restFetch.restFetch).mockResolvedValue({
45
- data: null,
46
- error: cause
47
- });
48
- expect(await generateEmailActionLink(PROJECT_ID, body, ACCESS_TOKEN)).toEqual({ data: null, error: cause });
49
- });
50
- it.each([null, {}, { oobLink: '' }, { oobLink: 123 }])('rejects an absent or invalid link %j', async (data) => {
51
- vi.mocked(restFetch.restFetch).mockResolvedValue({
52
- data,
53
- error: null
54
- });
55
- const result = await generateEmailActionLink(PROJECT_ID, body, ACCESS_TOKEN);
56
- expect(result.data).toBeNull();
57
- expect(result.error).toBeInstanceOf(Error);
58
- });
59
- });
60
- it('sends custom claims through the existing admin update endpoint', async () => {
61
- vi.mocked(restFetch.restFetch).mockResolvedValue({
62
- data: { localId: 'uid' },
63
- error: null
64
- });
65
- await updateAccountAdmin(PROJECT_ID, 'uid', { customAttributes: '{"role":"editor"}' }, ACCESS_TOKEN, mockFetch, 'tenant');
66
- expect(restFetch.restFetch).toHaveBeenCalledWith('https://identitytoolkit.googleapis.com/v1/projects/test-project/tenants/tenant/accounts:update', {
67
- body: { localId: 'uid', customAttributes: '{"role":"editor"}' },
68
- bearerToken: ACCESS_TOKEN,
69
- global: { fetch: mockFetch }
70
- });
71
- });
72
- describe('bulk admin endpoints', () => {
73
- it.each([undefined, 'tenant'])('posts a forced delete batch to tenant %s', async (tenantId) => {
74
- vi.mocked(restFetch.restFetch).mockResolvedValue({
75
- data: {},
76
- error: null
77
- });
78
- expect(await deleteAccountsAdmin(PROJECT_ID, ['one', 'two'], ACCESS_TOKEN, mockFetch, tenantId)).toEqual({ data: {}, error: null });
79
- expect(restFetch.restFetch).toHaveBeenCalledWith(`https://identitytoolkit.googleapis.com/v1/projects/test-project${tenantId ? '/tenants/tenant' : ''}/accounts:batchDelete`, {
80
- body: { localIds: ['one', 'two'], force: true },
81
- bearerToken: ACCESS_TOKEN,
82
- global: { fetch: mockFetch }
83
- });
84
- });
85
- it.each([undefined, 'tenant'])('posts imported users and hash settings to tenant %s', async (tenantId) => {
86
- const body = {
87
- users: [{ localId: 'uid', passwordHash: 'AQ==' }],
88
- hashAlgorithm: 'BCRYPT'
89
- };
90
- const response = { error: [{ index: 0, message: 'failure' }] };
91
- vi.mocked(restFetch.restFetch).mockResolvedValue({
92
- data: response,
93
- error: null
94
- });
95
- expect(await importAccountsAdmin(PROJECT_ID, body, ACCESS_TOKEN, mockFetch, tenantId)).toEqual({ data: response, error: null });
96
- expect(restFetch.restFetch).toHaveBeenCalledWith(`https://identitytoolkit.googleapis.com/v1/projects/test-project${tenantId ? '/tenants/tenant' : ''}/accounts:batchCreate`, {
97
- body,
98
- bearerToken: ACCESS_TOKEN,
99
- global: { fetch: mockFetch }
100
- });
101
- });
102
- it('maps HTTP errors and preserves non-JSON failures', async () => {
103
- vi.mocked(restFetch.restFetch).mockResolvedValue({
104
- data: null,
105
- error: { error: { code: 403, message: 'PERMISSION_DENIED' } }
106
- });
107
- expect((await deleteAccountsAdmin(PROJECT_ID, ['uid'], ACCESS_TOKEN))
108
- .error).toMatchObject({
109
- code: FirebaseEndpointErrorInfo.ENDPOINT_PERMISSION_DENIED.code
110
- });
111
- expect((await importAccountsAdmin(PROJECT_ID, { users: [] }, ACCESS_TOKEN)).error).toMatchObject({
112
- code: FirebaseEndpointErrorInfo.ENDPOINT_PERMISSION_DENIED.code
113
- });
114
- vi.mocked(restFetch.restFetch).mockResolvedValue({
115
- data: null,
116
- error: 'Unavailable'
117
- });
118
- expect((await deleteAccountsAdmin(PROJECT_ID, ['uid'], ACCESS_TOKEN))
119
- .error?.message).toContain('Unavailable');
120
- expect((await importAccountsAdmin(PROJECT_ID, { users: [] }, ACCESS_TOKEN)).error?.message).toContain('Unavailable');
121
- });
122
- it('sends phone lookups as an array', async () => {
123
- vi.mocked(restFetch.restFetch).mockResolvedValue({
124
- data: {
125
- users: [{ localId: 'uid', phoneNumber: '+15555550100' }]
126
- },
127
- error: null
128
- });
129
- const result = await getAccountInfo({ phoneNumber: '+15555550100' }, ACCESS_TOKEN, PROJECT_ID, 'tenant', mockFetch);
130
- expect(result.data).toMatchObject({
131
- localId: 'uid',
132
- phoneNumber: '+15555550100'
133
- });
134
- expect(restFetch.restFetch).toHaveBeenCalledWith(expect.stringContaining('/tenants/tenant/accounts:lookup'), expect.objectContaining({
135
- body: { phoneNumber: ['+15555550100'], tenantId: 'tenant' }
136
- }));
137
- });
138
- });
139
- describe('getAccountsInfo', () => {
140
- it.each([undefined, 'tenant'])('looks up a mixed batch for tenant %s', async (tenantId) => {
141
- const body = {
142
- localId: ['uid'],
143
- email: ['user@example.com'],
144
- phoneNumber: ['+15555550100'],
145
- federatedUserId: [
146
- { providerId: 'google.com', rawId: 'external' }
147
- ]
148
- };
149
- const data = { users: [{ localId: 'uid' }] };
150
- vi.mocked(restFetch.restFetch).mockResolvedValue({
151
- data,
152
- error: null
153
- });
154
- expect(await getAccountsInfo(body, ACCESS_TOKEN, PROJECT_ID, tenantId, mockFetch)).toEqual({ data, error: null });
155
- expect(restFetch.restFetch).toHaveBeenCalledWith(`https://identitytoolkit.googleapis.com/v1/projects/test-project${tenantId ? '/tenants/tenant' : ''}/accounts:lookup`, {
156
- body,
157
- bearerToken: ACCESS_TOKEN,
158
- global: { fetch: mockFetch }
159
- });
160
- });
161
- it('allows a successful response with no matching users', async () => {
162
- vi.mocked(restFetch.restFetch).mockResolvedValue({
163
- data: {},
164
- error: null
165
- });
166
- expect(await getAccountsInfo({ localId: ['missing'] }, ACCESS_TOKEN, PROJECT_ID)).toEqual({ data: {}, error: null });
167
- });
168
- it('maps Firebase failures and normalizes plain-text errors', async () => {
169
- vi.mocked(restFetch.restFetch)
170
- .mockResolvedValueOnce({
171
- data: null,
172
- error: {
173
- error: { code: 403, message: 'PERMISSION_DENIED' }
174
- }
175
- })
176
- .mockResolvedValueOnce({ data: null, error: 'Unavailable' });
177
- expect((await getAccountsInfo({ localId: ['uid'] }, ACCESS_TOKEN, PROJECT_ID)).error).toMatchObject({
178
- code: FirebaseEndpointErrorInfo.ENDPOINT_PERMISSION_DENIED.code
179
- });
180
- expect((await getAccountsInfo({ localId: ['uid'] }, ACCESS_TOKEN, PROJECT_ID)).error?.message).toContain('Unavailable');
181
- });
182
- });
183
- describe('admin user writes', () => {
184
- it.each([undefined, 'tenant'])('creates at the accounts resource for tenant %s', async (tenantId) => {
185
- vi.mocked(restFetch.restFetch).mockResolvedValue({
186
- data: { localId: 'uid' },
187
- error: null
188
- });
189
- expect(await createAccountAdmin(PROJECT_ID, { email: 'user@example.com', disabled: false }, ACCESS_TOKEN, mockFetch, tenantId)).toEqual({ data: { localId: 'uid' }, error: null });
190
- expect(restFetch.restFetch).toHaveBeenCalledWith(`https://identitytoolkit.googleapis.com/v1/projects/test-project${tenantId ? '/tenants/tenant' : ''}/accounts`, {
191
- body: { email: 'user@example.com', disabled: false },
192
- bearerToken: ACCESS_TOKEN,
193
- global: { fetch: mockFetch }
194
- });
195
- });
196
- it('reuses the update endpoint for admin user changes', async () => {
197
- vi.mocked(restFetch.restFetch).mockResolvedValue({
198
- data: { localId: 'uid' },
199
- error: null
200
- });
201
- await updateAccountAdmin(PROJECT_ID, 'uid', { disableUser: true, deleteAttribute: ['PHOTO_URL'] }, ACCESS_TOKEN, mockFetch, 'tenant');
202
- expect(restFetch.restFetch).toHaveBeenCalledWith('https://identitytoolkit.googleapis.com/v1/projects/test-project/tenants/tenant/accounts:update', {
203
- body: {
204
- localId: 'uid',
205
- disableUser: true,
206
- deleteAttribute: ['PHOTO_URL']
207
- },
208
- bearerToken: ACCESS_TOKEN,
209
- global: { fetch: mockFetch }
210
- });
211
- });
212
- it.each([undefined, 'tenant'])('deletes a single UID for tenant %s', async (tenantId) => {
213
- vi.mocked(restFetch.restFetch).mockResolvedValue({
214
- data: {},
215
- error: null
216
- });
217
- expect(await deleteAccountAdmin(PROJECT_ID, 'uid', ACCESS_TOKEN, mockFetch, tenantId)).toEqual({ error: null });
218
- expect(restFetch.restFetch).toHaveBeenCalledWith(`https://identitytoolkit.googleapis.com/v1/projects/test-project${tenantId ? '/tenants/tenant' : ''}/accounts:delete`, {
219
- body: { localId: 'uid' },
220
- bearerToken: ACCESS_TOKEN,
221
- global: { fetch: mockFetch }
222
- });
223
- });
224
- it.each(['EMAIL_EXISTS', 'USER_NOT_FOUND', 'PERMISSION_DENIED'])('maps %s write errors', async (message) => {
225
- vi.mocked(restFetch.restFetch).mockResolvedValue({
226
- data: null,
227
- error: { error: { code: 400, message } }
228
- });
229
- expect((await createAccountAdmin(PROJECT_ID, {}, ACCESS_TOKEN))
230
- .error).toBeInstanceOf(FirebaseEdgeError);
231
- expect((await updateAccountAdmin(PROJECT_ID, 'uid', {}, ACCESS_TOKEN)).error).toBeInstanceOf(FirebaseEdgeError);
232
- expect((await deleteAccountAdmin(PROJECT_ID, 'uid', ACCESS_TOKEN))
233
- .error).toBeInstanceOf(FirebaseEdgeError);
234
- });
235
- it('normalizes non-JSON errors for admin writes', async () => {
236
- vi.mocked(restFetch.restFetch).mockResolvedValue({
237
- data: null,
238
- error: 'Unavailable'
239
- });
240
- expect((await createAccountAdmin(PROJECT_ID, {}, ACCESS_TOKEN)).error
241
- ?.message).toContain('Unavailable');
242
- expect((await updateAccountAdmin(PROJECT_ID, 'uid', {}, ACCESS_TOKEN))
243
- .error?.message).toContain('Unavailable');
244
- expect((await deleteAccountAdmin(PROJECT_ID, 'uid', ACCESS_TOKEN))
245
- .error?.message).toContain('Unavailable');
246
- });
247
- it('looks up the complete record with a UID array', async () => {
248
- vi.mocked(restFetch.restFetch).mockResolvedValue({
249
- data: { users: [{ localId: 'uid' }] },
250
- error: null
251
- });
252
- await getAccountInfo({ uid: 'uid' }, ACCESS_TOKEN, PROJECT_ID);
253
- expect(restFetch.restFetch).toHaveBeenCalledWith(expect.stringContaining('/accounts:lookup'), expect.objectContaining({ body: { localId: ['uid'] } }));
254
- });
255
- });
256
- describe('downloadAccount', () => {
257
- it('encodes opaque pagination tokens and sends a body-free authenticated GET', async () => {
258
- const actual = await vi.importActual('../rest-fetch.js');
259
- vi.mocked(restFetch.restFetch).mockImplementationOnce(actual.restFetch);
260
- const fetchFn = vi
261
- .fn()
262
- .mockResolvedValue(Response.json({ users: [] }));
263
- await downloadAccount(ACCESS_TOKEN, PROJECT_ID, 25, 'a+/=? &', 'tenant', fetchFn);
264
- const [url, options] = fetchFn.mock.calls[0];
265
- const parsed = new URL(String(url));
266
- expect(parsed.pathname).toBe('/v1/projects/test-project/tenants/tenant/accounts:batchGet');
267
- expect(parsed.searchParams.get('nextPageToken')).toBe('a+/=? &');
268
- expect(parsed.searchParams.get('maxResults')).toBe('25');
269
- expect(options).toMatchObject({
270
- method: 'GET',
271
- body: undefined,
272
- headers: { Authorization: `Bearer ${ACCESS_TOKEN}` }
273
- });
274
- });
275
- it('normalizes an actual non-JSON HTTP failure', async () => {
276
- const actual = await vi.importActual('../rest-fetch.js');
277
- vi.mocked(restFetch.restFetch).mockImplementationOnce(actual.restFetch);
278
- const fetchFn = vi
279
- .fn()
280
- .mockResolvedValue(new Response('Service unavailable', { status: 503 }));
281
- const result = await downloadAccount(ACCESS_TOKEN, PROJECT_ID, 25, undefined, undefined, fetchFn);
282
- expect(result.data).toBeNull();
283
- expect(result.error?.message).toContain('Service unavailable');
284
- });
285
- it('propagates JSON decoding failures to the admin error handler', async () => {
286
- const actual = await vi.importActual('../rest-fetch.js');
287
- vi.mocked(restFetch.restFetch).mockImplementationOnce(actual.restFetch);
288
- const fetchFn = vi.fn().mockResolvedValue(new Response('{', {
289
- headers: { 'content-type': 'application/json' }
290
- }));
291
- await expect(downloadAccount(ACCESS_TOKEN, PROJECT_ID, 25, undefined, undefined, fetchFn)).rejects.toBeInstanceOf(SyntaxError);
292
- });
293
- it('downloads the default page through the admin URL and shared fetch helper', async () => {
294
- const data = { users: [{ localId: 'uid' }], nextPageToken: 'next' };
295
- vi.mocked(restFetch.restFetch).mockResolvedValue({
296
- data,
297
- error: null
298
- });
299
- expect(await downloadAccount(ACCESS_TOKEN, PROJECT_ID)).toEqual({
300
- data,
301
- error: null
302
- });
303
- expect(restFetch.restFetch).toHaveBeenCalledWith('https://identitytoolkit.googleapis.com/v1/projects/test-project/accounts:batchGet', {
304
- method: 'GET',
305
- bearerToken: ACCESS_TOKEN,
306
- global: { fetch: undefined },
307
- params: { maxResults: '1000' }
308
- });
309
- });
310
- it('forwards tenant, pagination, and custom fetch options', async () => {
311
- vi.mocked(restFetch.restFetch).mockResolvedValue({
312
- data: {},
313
- error: null
314
- });
315
- await downloadAccount(ACCESS_TOKEN, PROJECT_ID, 10, 'opaque+/=', 'tenant', mockFetch);
316
- expect(restFetch.restFetch).toHaveBeenCalledWith('https://identitytoolkit.googleapis.com/v1/projects/test-project/tenants/tenant/accounts:batchGet', {
317
- method: 'GET',
318
- bearerToken: ACCESS_TOKEN,
319
- global: { fetch: mockFetch },
320
- params: { maxResults: '10', nextPageToken: 'opaque+/=' }
321
- });
322
- });
323
- it('maps Firebase API errors', async () => {
324
- vi.mocked(restFetch.restFetch).mockResolvedValue({
325
- data: null,
326
- error: { error: { code: 403, message: 'PERMISSION_DENIED' } }
327
- });
328
- const result = await downloadAccount(ACCESS_TOKEN, PROJECT_ID);
329
- expect(result.data).toBeNull();
330
- expect(result.error).toBeInstanceOf(FirebaseEdgeError);
331
- expect(result.error).toMatchObject({
332
- code: FirebaseEndpointErrorInfo.ENDPOINT_PERMISSION_DENIED.code
333
- });
334
- });
335
- it('normalizes non-JSON error responses', async () => {
336
- vi.mocked(restFetch.restFetch).mockResolvedValue({
337
- data: null,
338
- error: 'Service unavailable'
339
- });
340
- const result = await downloadAccount(ACCESS_TOKEN, PROJECT_ID);
341
- expect(result.data).toBeNull();
342
- expect(result.error).toBeInstanceOf(Error);
343
- expect(result.error?.message).toContain('Service unavailable');
344
- });
345
- });
346
- describe('refreshFirebaseIdToken', () => {
347
- it('should refresh token successfully', async () => {
348
- const mockResponse = {
349
- access_token: 'new-token',
350
- refresh_token: 'new-refresh-token'
351
- };
352
- const restFetchSpy = vi
353
- .mocked(restFetch.restFetch)
354
- .mockResolvedValue({
355
- data: mockResponse,
356
- error: null
357
- });
358
- const result = await refreshFirebaseIdToken('refresh-token', API_KEY, mockFetch);
359
- expect(result.data).toEqual(mockResponse);
360
- expect(result.error).toBeNull();
361
- expect(restFetchSpy).toHaveBeenCalledWith('https://securetoken.googleapis.com/v1/token', expect.objectContaining({
362
- body: {
363
- grant_type: 'refresh_token',
364
- refresh_token: 'refresh-token'
365
- },
366
- params: { key: API_KEY },
367
- form: true,
368
- global: { fetch: mockFetch }
369
- }));
370
- });
371
- it('should handle error response', async () => {
372
- const mockError = {
373
- code: 400,
374
- message: 'INVALID_GRANT: Invalid refresh token'
375
- };
376
- vi.mocked(restFetch.restFetch).mockResolvedValue({
377
- data: null,
378
- error: { error: mockError }
379
- });
380
- const result = await refreshFirebaseIdToken('invalid-token', API_KEY);
381
- expect(result.data).toBeNull();
382
- expect(result.error).toBeInstanceOf(FirebaseEdgeError);
383
- expect(result.error.code).toBe(FirebaseEndpointErrorInfo.ENDPOINT_INVALID_REFRESH_TOKEN.code);
384
- });
385
- });
386
- describe('createAuthUri', () => {
387
- it('should create auth URI successfully', async () => {
388
- const mockResponse = { authUri: 'https://auth.example.com' };
389
- const restFetchSpy = vi
390
- .mocked(restFetch.restFetch)
391
- .mockResolvedValue({
392
- data: mockResponse,
393
- error: null
394
- });
395
- const result = await createAuthUri('https://redirect.com', API_KEY, undefined, mockFetch);
396
- expect(result.data).toEqual(mockResponse);
397
- expect(restFetchSpy).toHaveBeenCalled();
398
- expect(result.error).toBeNull();
399
- expect(restFetchSpy).toHaveBeenCalledWith('https://identitytoolkit.googleapis.com/v1/accounts:createAuthUri', expect.objectContaining({
400
- body: {
401
- continueUri: 'https://redirect.com',
402
- providerId: 'google.com'
403
- },
404
- params: { key: API_KEY },
405
- global: { fetch: mockFetch }
406
- }));
407
- });
408
- it('should create auth URI with tenant ID', async () => {
409
- const mockResponse = { authUri: 'https://auth.example.com' };
410
- const tenantId = 'tenant-123';
411
- const restFetchSpy = vi
412
- .mocked(restFetch.restFetch)
413
- .mockResolvedValue({
414
- data: mockResponse,
415
- error: null
416
- });
417
- const result = await createAuthUri('https://redirect.com', API_KEY, tenantId, mockFetch);
418
- expect(result.data).toEqual(mockResponse);
419
- expect(result.error).toBeNull();
420
- expect(restFetchSpy).toHaveBeenCalledWith('https://identitytoolkit.googleapis.com/v1/accounts:createAuthUri', expect.objectContaining({
421
- body: {
422
- continueUri: 'https://redirect.com',
423
- providerId: 'google.com',
424
- tenantId: tenantId
425
- },
426
- params: { key: API_KEY },
427
- global: { fetch: mockFetch }
428
- }));
429
- });
430
- });
431
- describe('signInWithIdp', () => {
432
- it('should sign in with IDP successfully', async () => {
433
- const mockResponse = {
434
- idToken: 'firebase-token',
435
- refreshToken: 'refresh'
436
- };
437
- vi.mocked(restFetch.restFetch).mockResolvedValue({
438
- data: mockResponse,
439
- error: null
440
- });
441
- const result = await signInWithIdp('provider-token', 'https://request.com', 'google.com', API_KEY, undefined, mockFetch);
442
- expect(result.data).toEqual(mockResponse);
443
- expect(result.error).toBeNull();
444
- expect(restFetch.restFetch).toHaveBeenCalledWith('https://identitytoolkit.googleapis.com/v1/accounts:signInWithIdp', expect.objectContaining({
445
- body: {
446
- postBody: 'id_token=provider-token&providerId=google.com',
447
- requestUri: 'https://request.com',
448
- returnSecureToken: true,
449
- returnIdpCredential: true
450
- }
451
- }));
452
- });
453
- it('should sign in with IDP and tenant ID', async () => {
454
- const mockResponse = {
455
- idToken: 'firebase-token',
456
- refreshToken: 'refresh'
457
- };
458
- const tenantId = 'tenant-456';
459
- const restFetchSpy = vi
460
- .mocked(restFetch.restFetch)
461
- .mockResolvedValue({
462
- data: mockResponse,
463
- error: null
464
- });
465
- const result = await signInWithIdp('provider-token', 'https://request.com', 'google.com', API_KEY, tenantId, mockFetch);
466
- expect(result.data).toEqual(mockResponse);
467
- expect(result.error).toBeNull();
468
- expect(restFetchSpy).toHaveBeenCalledWith('https://identitytoolkit.googleapis.com/v1/accounts:signInWithIdp', expect.objectContaining({
469
- body: {
470
- postBody: 'id_token=provider-token&providerId=google.com',
471
- requestUri: 'https://request.com',
472
- returnSecureToken: true,
473
- returnIdpCredential: true,
474
- tenantId: tenantId
475
- }
476
- }));
477
- });
478
- it('should use access_token for GitHub provider', async () => {
479
- const mockResponse = {
480
- idToken: 'firebase-token',
481
- refreshToken: 'refresh'
482
- };
483
- const restFetchSpy = vi
484
- .mocked(restFetch.restFetch)
485
- .mockResolvedValue({
486
- data: mockResponse,
487
- error: null
488
- });
489
- const result = await signInWithIdp('github-token', 'https://request.com', 'github.com', API_KEY, undefined, mockFetch);
490
- expect(result.data).toEqual(mockResponse);
491
- expect(restFetchSpy).toHaveBeenCalledWith('https://identitytoolkit.googleapis.com/v1/accounts:signInWithIdp', expect.objectContaining({
492
- body: expect.objectContaining({
493
- postBody: 'access_token=github-token&providerId=github.com'
494
- })
495
- }));
496
- });
497
- });
498
- describe('signInWithCustomToken', () => {
499
- it('should sign in with custom token successfully', async () => {
500
- const mockResponse = { idToken: 'firebase-token' };
501
- vi.mocked(restFetch.restFetch).mockResolvedValue({
502
- data: mockResponse,
503
- error: null
504
- });
505
- const result = await signInWithCustomToken('jwt-token', API_KEY, undefined, mockFetch);
506
- expect(result.data).toEqual(mockResponse);
507
- expect(result.error).toBeNull();
508
- });
509
- it('should sign in with custom token and tenant ID', async () => {
510
- const mockResponse = { idToken: 'firebase-token' };
511
- const tenantId = 'tenant-789';
512
- const restFetchSpy = vi
513
- .mocked(restFetch.restFetch)
514
- .mockResolvedValue({
515
- data: mockResponse,
516
- error: null
517
- });
518
- const result = await signInWithCustomToken('jwt-token', API_KEY, tenantId, mockFetch);
519
- expect(result.data).toEqual(mockResponse);
520
- expect(result.error).toBeNull();
521
- expect(restFetchSpy).toHaveBeenCalledWith('https://identitytoolkit.googleapis.com/v1/accounts:signInWithCustomToken', expect.objectContaining({
522
- body: {
523
- token: 'jwt-token',
524
- returnSecureToken: true,
525
- tenantId: tenantId
526
- }
527
- }));
528
- });
529
- });
530
- describe('getAccountInfo', () => {
531
- it('should get account info successfully', async () => {
532
- const mockUser = { localId: 'user-123', email: 'test@example.com' };
533
- vi.mocked(restFetch.restFetch).mockResolvedValue({
534
- data: { users: [mockUser] },
535
- error: null
536
- });
537
- const result = await getAccountInfo({ uid: 'user-123' }, ACCESS_TOKEN, PROJECT_ID, undefined, mockFetch);
538
- expect(result.data).toEqual(mockUser);
539
- expect(result.error).toBeNull();
540
- });
541
- it('should get account info with tenant ID', async () => {
542
- const mockUser = { localId: 'user-123', email: 'test@example.com' };
543
- const tenantId = 'tenant-abc';
544
- const restFetchSpy = vi
545
- .mocked(restFetch.restFetch)
546
- .mockResolvedValue({
547
- data: { users: [mockUser] },
548
- error: null
549
- });
550
- const result = await getAccountInfo({ uid: 'user-123' }, ACCESS_TOKEN, PROJECT_ID, tenantId, mockFetch);
551
- expect(result.data).toEqual(mockUser);
552
- expect(result.error).toBeNull();
553
- expect(restFetchSpy).toHaveBeenCalledWith(`https://identitytoolkit.googleapis.com/v1/projects/${PROJECT_ID}/tenants/${tenantId}/accounts:lookup`, expect.objectContaining({
554
- body: {
555
- localId: ['user-123'],
556
- tenantId: tenantId
557
- },
558
- bearerToken: ACCESS_TOKEN
559
- }));
560
- });
561
- it('should return null when no users found', async () => {
562
- vi.mocked(restFetch.restFetch).mockResolvedValue({
563
- data: { users: [] },
564
- error: null
565
- });
566
- const result = await getAccountInfo({ uid: 'user-123' }, ACCESS_TOKEN, PROJECT_ID);
567
- expect(result.data).toBeNull();
568
- });
569
- });
570
- describe('createSessionCookie', () => {
571
- it('should create session cookie with default expiry (14 days in seconds)', async () => {
572
- const mockResponse = { sessionCookie: 'cookie-value' };
573
- const restFetchSpy = vi
574
- .mocked(restFetch.restFetch)
575
- .mockResolvedValue({
576
- data: mockResponse,
577
- error: null
578
- });
579
- const result = await createSessionCookie('id-token', ACCESS_TOKEN, PROJECT_ID, undefined, undefined, mockFetch);
580
- expect(result.data).toBe('cookie-value');
581
- expect(restFetchSpy).toHaveBeenCalledWith(`https://identitytoolkit.googleapis.com/v1/projects/${PROJECT_ID}:createSessionCookie`, expect.objectContaining({
582
- body: expect.objectContaining({
583
- // default is 14 days in ms converted to seconds
584
- validDuration: 1209600
585
- })
586
- }));
587
- });
588
- it('should create session cookie with tenant ID', async () => {
589
- const mockResponse = { sessionCookie: 'cookie-value' };
590
- const tenantId = 'tenant-def';
591
- const restFetchSpy = vi
592
- .mocked(restFetch.restFetch)
593
- .mockResolvedValue({
594
- data: mockResponse,
595
- error: null
596
- });
597
- const result = await createSessionCookie('id-token', ACCESS_TOKEN, PROJECT_ID, 3600000, // 1 hour in ms
598
- tenantId, mockFetch);
599
- expect(result.data).toBe('cookie-value');
600
- expect(restFetchSpy).toHaveBeenCalledWith(`https://identitytoolkit.googleapis.com/v1/projects/${PROJECT_ID}/tenants/${tenantId}:createSessionCookie`, expect.objectContaining({
601
- body: {
602
- idToken: 'id-token',
603
- validDuration: 3600, // converted to seconds
604
- tenantId: tenantId
605
- },
606
- bearerToken: ACCESS_TOKEN
607
- }));
608
- });
609
- it('should create session cookie with custom expiry (using seconds)', async () => {
610
- const mockResponse = { sessionCookie: 'cookie-value' };
611
- vi.mocked(restFetch.restFetch).mockResolvedValue({
612
- data: mockResponse,
613
- error: null
614
- });
615
- const result = await createSessionCookie('id-token', ACCESS_TOKEN, PROJECT_ID, 3600, // 1 hour in seconds
616
- undefined, mockFetch);
617
- expect(result.data).toBe('cookie-value');
618
- });
619
- });
620
- describe('getJWKs', () => {
621
- it('should get JWKs successfully', async () => {
622
- const mockKeys = [{ kid: 'key-1', kty: 'RSA' }];
623
- vi.mocked(restFetch.restFetch).mockResolvedValue({
624
- data: { keys: mockKeys },
625
- error: null
626
- });
627
- const result = await getJWKs(mockFetch);
628
- expect(result.data).toEqual(mockKeys);
629
- expect(result.error).toBeNull();
630
- });
631
- it('should return null when no keys found', async () => {
632
- vi.mocked(restFetch.restFetch).mockResolvedValue({
633
- data: null,
634
- error: null
635
- });
636
- const result = await getJWKs();
637
- expect(result.data).toBeNull();
638
- });
639
- });
640
- describe('getPublicKeys', () => {
641
- it('should get public keys successfully', async () => {
642
- const mockKeys = { 'key-1': 'public-key-value' };
643
- vi.mocked(restFetch.restFetch).mockResolvedValue({
644
- data: mockKeys,
645
- error: null
646
- });
647
- const result = await getPublicKeys(mockFetch);
648
- expect(result.data).toEqual(mockKeys);
649
- expect(result.error).toBeNull();
650
- });
651
- it('should handle error response', async () => {
652
- const mockError = {
653
- code: 403,
654
- message: 'PERMISSION_DENIED: Failed to fetch keys'
655
- };
656
- vi.mocked(restFetch.restFetch).mockResolvedValue({
657
- data: null,
658
- error: { error: mockError }
659
- });
660
- const result = await getPublicKeys();
661
- expect(result.data).toBeNull();
662
- expect(result.error).toBeInstanceOf(FirebaseEdgeError);
663
- expect(result.error.code).toBe(FirebaseEndpointErrorInfo.ENDPOINT_PERMISSION_DENIED.code);
664
- });
665
- });
666
- describe('createAdminIdentityURL (indirectly via functions)', () => {
667
- it('should call createSessionCookie URL without /accounts segment', async () => {
668
- const mockResponse = { sessionCookie: 'cookie-value' };
669
- const restFetchSpy = vi
670
- .mocked(restFetch.restFetch)
671
- .mockResolvedValue({
672
- data: mockResponse,
673
- error: null
674
- });
675
- const idToken = 'id-token';
676
- const token = 'access-token';
677
- const projectId = 'test-project';
678
- const result = await createSessionCookie(idToken, token, projectId, 3600_000, undefined, vi.fn());
679
- expect(result.data).toBe('cookie-value');
680
- expect(restFetchSpy).toHaveBeenCalledTimes(1);
681
- const [calledUrl, options] = restFetchSpy.mock
682
- .calls[0];
683
- const opts = options;
684
- expect(calledUrl).toBe(`https://identitytoolkit.googleapis.com/v1/projects/${projectId}:createSessionCookie`);
685
- expect(opts.bearerToken).toBe(token);
686
- expect(opts.body?.idToken).toBe(idToken);
687
- });
688
- it('should call createSessionCookie tenant URL when tenant ID provided', async () => {
689
- const mockResponse = { sessionCookie: 'cookie-value' };
690
- const tenantId = 'tenant-test';
691
- const restFetchSpy = vi
692
- .mocked(restFetch.restFetch)
693
- .mockResolvedValue({
694
- data: mockResponse,
695
- error: null
696
- });
697
- const result = await createSessionCookie('id-token', 'access-token', 'test-project', 3600_000, tenantId, vi.fn());
698
- expect(result.data).toBe('cookie-value');
699
- const [calledUrl] = restFetchSpy.mock.calls[0];
700
- expect(calledUrl).toBe(`https://identitytoolkit.googleapis.com/v1/projects/test-project/tenants/${tenantId}:createSessionCookie`);
701
- });
702
- it('should call accounts lookup URL with /accounts segment via getAccountInfo', async () => {
703
- const mockUser = { localId: 'user-123', email: 'test@example.com' };
704
- const restFetchSpy = vi
705
- .mocked(restFetch.restFetch)
706
- .mockResolvedValue({
707
- data: { users: [mockUser] },
708
- error: null
709
- });
710
- const uid = 'user-123';
711
- const token = 'access-token';
712
- const projectId = 'test-project';
713
- const result = await getAccountInfo({ uid }, token, projectId, undefined, vi.fn());
714
- expect(result.data).toEqual(mockUser);
715
- expect(restFetchSpy).toHaveBeenCalledTimes(1);
716
- const [calledUrl, options] = restFetchSpy.mock
717
- .calls[0];
718
- const opts = options;
719
- expect(calledUrl).toBe(`https://identitytoolkit.googleapis.com/v1/projects/${projectId}/accounts:lookup`);
720
- expect(opts.bearerToken).toBe(token);
721
- expect(opts.body?.localId).toEqual([uid]);
722
- });
723
- it('should call accounts lookup tenant URL when tenant ID provided', async () => {
724
- const mockUser = { localId: 'user-123', email: 'test@example.com' };
725
- const tenantId = 'tenant-lookup';
726
- const restFetchSpy = vi
727
- .mocked(restFetch.restFetch)
728
- .mockResolvedValue({
729
- data: { users: [mockUser] },
730
- error: null
731
- });
732
- const result = await getAccountInfo({ uid: 'user-123' }, 'access-token', 'test-project', tenantId, vi.fn());
733
- expect(result.data).toEqual(mockUser);
734
- const [calledUrl] = restFetchSpy.mock.calls[0];
735
- expect(calledUrl).toBe(`https://identitytoolkit.googleapis.com/v1/projects/test-project/tenants/${tenantId}/accounts:lookup`);
736
- });
737
- });
738
- describe('createSessionCookie with ms input', () => {
739
- it('should convert ms to seconds when creating session cookie', async () => {
740
- const mockResponse = { sessionCookie: 'cookie-value' };
741
- const restFetchSpy = vi
742
- .mocked(restFetch.restFetch)
743
- .mockResolvedValue({
744
- data: mockResponse,
745
- error: null
746
- });
747
- const result = await createSessionCookie('id-token', ACCESS_TOKEN, PROJECT_ID, 1209600000, // 14 days in ms
748
- undefined, // tenantId
749
- mockFetch);
750
- expect(result.data).toBe('cookie-value');
751
- expect(restFetchSpy).toHaveBeenCalledWith(expect.stringContaining('createSessionCookie'), expect.objectContaining({
752
- body: expect.objectContaining({
753
- validDuration: 1209600
754
- })
755
- }));
756
- });
757
- });
758
- describe('sendOobCode', () => {
759
- it('should send password reset email successfully', async () => {
760
- const mockResponse = { email: 'test@example.com' };
761
- const restFetchSpy = vi
762
- .mocked(restFetch.restFetch)
763
- .mockResolvedValue({
764
- data: mockResponse,
765
- error: null
766
- });
767
- const result = await sendOobCode('PASSWORD_RESET', API_KEY, { email: 'test@example.com' }, undefined, mockFetch);
768
- expect(result.data).toEqual(mockResponse);
769
- expect(result.error).toBeNull();
770
- expect(restFetchSpy).toHaveBeenCalledWith('https://identitytoolkit.googleapis.com/v1/accounts:sendOobCode', expect.objectContaining({
771
- body: expect.objectContaining({
772
- requestType: 'PASSWORD_RESET',
773
- email: 'test@example.com',
774
- canHandleCodeInApp: false
775
- }),
776
- params: { key: API_KEY }
777
- }));
778
- });
779
- it('should send verification email successfully', async () => {
780
- const mockResponse = { email: 'test@example.com' };
781
- const restFetchSpy = vi
782
- .mocked(restFetch.restFetch)
783
- .mockResolvedValue({
784
- data: mockResponse,
785
- error: null
786
- });
787
- const result = await sendOobCode('VERIFY_EMAIL', API_KEY, { idToken: 'test-id-token' }, undefined, mockFetch);
788
- expect(result.data).toEqual(mockResponse);
789
- expect(result.error).toBeNull();
790
- expect(restFetchSpy).toHaveBeenCalledWith('https://identitytoolkit.googleapis.com/v1/accounts:sendOobCode', expect.objectContaining({
791
- body: expect.objectContaining({
792
- requestType: 'VERIFY_EMAIL',
793
- idToken: 'test-id-token',
794
- canHandleCodeInApp: false
795
- })
796
- }));
797
- });
798
- it('should include continue URL when provided', async () => {
799
- const mockResponse = { email: 'test@example.com' };
800
- const restFetchSpy = vi
801
- .mocked(restFetch.restFetch)
802
- .mockResolvedValue({
803
- data: mockResponse,
804
- error: null
805
- });
806
- const result = await sendOobCode('PASSWORD_RESET', API_KEY, {
807
- email: 'test@example.com',
808
- continueUrl: 'https://example.com/reset'
809
- }, undefined, mockFetch);
810
- expect(result.data).toEqual(mockResponse);
811
- expect(restFetchSpy).toHaveBeenCalledWith(expect.any(String), expect.objectContaining({
812
- body: expect.objectContaining({
813
- continueUrl: 'https://example.com/reset'
814
- })
815
- }));
816
- });
817
- it('should include locale header when provided', async () => {
818
- const mockResponse = { email: 'test@example.com' };
819
- const restFetchSpy = vi
820
- .mocked(restFetch.restFetch)
821
- .mockResolvedValue({
822
- data: mockResponse,
823
- error: null
824
- });
825
- const result = await sendOobCode('PASSWORD_RESET', API_KEY, { email: 'test@example.com', locale: 'es' }, undefined, mockFetch);
826
- expect(result.data).toEqual(mockResponse);
827
- expect(restFetchSpy).toHaveBeenCalledWith(expect.any(String), expect.objectContaining({
828
- headers: { 'X-Firebase-Locale': 'es' }
829
- }));
830
- });
831
- it('should include tenant ID when provided', async () => {
832
- const mockResponse = { email: 'test@example.com' };
833
- const tenantId = 'tenant-123';
834
- const restFetchSpy = vi
835
- .mocked(restFetch.restFetch)
836
- .mockResolvedValue({
837
- data: mockResponse,
838
- error: null
839
- });
840
- const result = await sendOobCode('PASSWORD_RESET', API_KEY, { email: 'test@example.com' }, tenantId, mockFetch);
841
- expect(result.data).toEqual(mockResponse);
842
- expect(restFetchSpy).toHaveBeenCalledWith(expect.any(String), expect.objectContaining({
843
- body: expect.objectContaining({
844
- tenantId: tenantId
845
- })
846
- }));
847
- });
848
- it('should handle error response', async () => {
849
- const mockError = {
850
- code: 400,
851
- message: 'INVALID_EMAIL'
852
- };
853
- vi.mocked(restFetch.restFetch).mockResolvedValue({
854
- data: null,
855
- error: { error: mockError }
856
- });
857
- const result = await sendOobCode('PASSWORD_RESET', API_KEY, {
858
- email: 'invalid-email'
859
- });
860
- expect(result.data).toBeNull();
861
- expect(result.error).toBeInstanceOf(FirebaseEdgeError);
862
- });
863
- });
864
- describe('signInWithEmailLink', () => {
865
- it('should sign in with email link successfully', async () => {
866
- const mockResponse = {
867
- idToken: 'test-id-token',
868
- refreshToken: 'test-refresh-token',
869
- localId: 'test-uid'
870
- };
871
- const restFetchSpy = vi
872
- .mocked(restFetch.restFetch)
873
- .mockResolvedValue({
874
- data: mockResponse,
875
- error: null
876
- });
877
- const result = await signInWithEmailLink('test-oob-code', 'test@example.com', API_KEY, undefined, undefined, mockFetch);
878
- expect(result.data).toEqual(mockResponse);
879
- expect(result.error).toBeNull();
880
- expect(restFetchSpy).toHaveBeenCalledWith('https://identitytoolkit.googleapis.com/v1/accounts:signInWithEmailLink', expect.objectContaining({
881
- body: {
882
- oobCode: 'test-oob-code',
883
- email: 'test@example.com'
884
- },
885
- params: { key: API_KEY }
886
- }));
887
- });
888
- it('should include idToken when linking account', async () => {
889
- const mockResponse = {
890
- idToken: 'new-id-token',
891
- refreshToken: 'new-refresh-token',
892
- localId: 'test-uid'
893
- };
894
- const restFetchSpy = vi
895
- .mocked(restFetch.restFetch)
896
- .mockResolvedValue({
897
- data: mockResponse,
898
- error: null
899
- });
900
- const result = await signInWithEmailLink('test-oob-code', 'test@example.com', API_KEY, 'existing-id-token', undefined, mockFetch);
901
- expect(result.data).toEqual(mockResponse);
902
- expect(restFetchSpy).toHaveBeenCalledWith(expect.any(String), expect.objectContaining({
903
- body: expect.objectContaining({
904
- idToken: 'existing-id-token'
905
- })
906
- }));
907
- });
908
- it('should include tenant ID when provided', async () => {
909
- const mockResponse = {
910
- idToken: 'test-id-token',
911
- localId: 'test-uid'
912
- };
913
- const tenantId = 'tenant-456';
914
- const restFetchSpy = vi
915
- .mocked(restFetch.restFetch)
916
- .mockResolvedValue({
917
- data: mockResponse,
918
- error: null
919
- });
920
- const result = await signInWithEmailLink('test-oob-code', 'test@example.com', API_KEY, undefined, tenantId, mockFetch);
921
- expect(result.data).toEqual(mockResponse);
922
- expect(restFetchSpy).toHaveBeenCalledWith(expect.any(String), expect.objectContaining({
923
- body: expect.objectContaining({
924
- tenantId: tenantId
925
- })
926
- }));
927
- });
928
- it('should handle error response', async () => {
929
- const mockError = {
930
- code: 400,
931
- message: 'INVALID_OOB_CODE'
932
- };
933
- vi.mocked(restFetch.restFetch).mockResolvedValue({
934
- data: null,
935
- error: { error: mockError }
936
- });
937
- const result = await signInWithEmailLink('invalid-code', 'test@example.com', API_KEY);
938
- expect(result.data).toBeNull();
939
- expect(result.error).toBeInstanceOf(FirebaseEdgeError);
940
- });
941
- });
942
- describe('linkWithOAuthCredential', () => {
943
- it('should link OAuth credential successfully', async () => {
944
- const mockResponse = {
945
- idToken: 'new-id-token',
946
- refreshToken: 'new-refresh-token',
947
- localId: 'test-uid',
948
- federatedId: 'google-user-id'
949
- };
950
- const restFetchSpy = vi
951
- .mocked(restFetch.restFetch)
952
- .mockResolvedValue({
953
- data: mockResponse,
954
- error: null
955
- });
956
- const result = await linkWithOAuthCredential('existing-id-token', 'google-provider-token', 'https://example.com/callback', 'google.com', API_KEY, undefined, mockFetch);
957
- expect(result.data).toEqual(mockResponse);
958
- expect(result.error).toBeNull();
959
- expect(restFetchSpy).toHaveBeenCalledWith('https://identitytoolkit.googleapis.com/v1/accounts:signInWithIdp', expect.objectContaining({
960
- body: expect.objectContaining({
961
- idToken: 'existing-id-token',
962
- postBody: 'id_token=google-provider-token&providerId=google.com',
963
- requestUri: 'https://example.com/callback',
964
- returnSecureToken: true,
965
- returnIdpCredential: true
966
- }),
967
- params: { key: API_KEY }
968
- }));
969
- });
970
- it('should use access_token for GitHub provider when linking', async () => {
971
- const mockResponse = {
972
- idToken: 'new-id-token',
973
- localId: 'test-uid'
974
- };
975
- const restFetchSpy = vi
976
- .mocked(restFetch.restFetch)
977
- .mockResolvedValue({
978
- data: mockResponse,
979
- error: null
980
- });
981
- const result = await linkWithOAuthCredential('existing-id-token', 'github-access-token', 'https://example.com/callback', 'github.com', API_KEY, undefined, mockFetch);
982
- expect(result.data).toEqual(mockResponse);
983
- expect(restFetchSpy).toHaveBeenCalledWith(expect.any(String), expect.objectContaining({
984
- body: expect.objectContaining({
985
- postBody: 'access_token=github-access-token&providerId=github.com'
986
- })
987
- }));
988
- });
989
- it('should include tenant ID when provided', async () => {
990
- const mockResponse = {
991
- idToken: 'new-id-token',
992
- localId: 'test-uid'
993
- };
994
- const tenantId = 'tenant-789';
995
- const restFetchSpy = vi
996
- .mocked(restFetch.restFetch)
997
- .mockResolvedValue({
998
- data: mockResponse,
999
- error: null
1000
- });
1001
- const result = await linkWithOAuthCredential('existing-id-token', 'provider-token', 'https://example.com/callback', 'google.com', API_KEY, tenantId, mockFetch);
1002
- expect(result.data).toEqual(mockResponse);
1003
- expect(restFetchSpy).toHaveBeenCalledWith(expect.any(String), expect.objectContaining({
1004
- body: expect.objectContaining({
1005
- tenantId: tenantId
1006
- })
1007
- }));
1008
- });
1009
- it('should handle error response', async () => {
1010
- const mockError = {
1011
- code: 400,
1012
- message: 'CREDENTIAL_TOO_OLD_LOGIN_AGAIN'
1013
- };
1014
- vi.mocked(restFetch.restFetch).mockResolvedValue({
1015
- data: null,
1016
- error: { error: mockError }
1017
- });
1018
- const result = await linkWithOAuthCredential('old-id-token', 'provider-token', 'https://example.com/callback', 'google.com', API_KEY);
1019
- expect(result.data).toBeNull();
1020
- expect(result.error).toBeInstanceOf(FirebaseEdgeError);
1021
- });
1022
- });
1023
- describe('unlinkProvider', () => {
1024
- it('should unlink provider successfully', async () => {
1025
- const mockResponse = {
1026
- localId: 'test-uid',
1027
- email: 'test@example.com',
1028
- providerUserInfo: []
1029
- };
1030
- const restFetchSpy = vi
1031
- .mocked(restFetch.restFetch)
1032
- .mockResolvedValue({
1033
- data: mockResponse,
1034
- error: null
1035
- });
1036
- const result = await unlinkProvider('test-id-token', 'google.com', API_KEY, undefined, mockFetch);
1037
- expect(result.data).toEqual(mockResponse);
1038
- expect(result.error).toBeNull();
1039
- expect(restFetchSpy).toHaveBeenCalledWith('https://identitytoolkit.googleapis.com/v1/accounts:update', expect.objectContaining({
1040
- body: {
1041
- idToken: 'test-id-token',
1042
- deleteProvider: ['google.com']
1043
- },
1044
- params: { key: API_KEY }
1045
- }));
1046
- });
1047
- it('should include tenant ID when provided', async () => {
1048
- const mockResponse = {
1049
- localId: 'test-uid',
1050
- providerUserInfo: []
1051
- };
1052
- const tenantId = 'tenant-abc';
1053
- const restFetchSpy = vi
1054
- .mocked(restFetch.restFetch)
1055
- .mockResolvedValue({
1056
- data: mockResponse,
1057
- error: null
1058
- });
1059
- const result = await unlinkProvider('test-id-token', 'github.com', API_KEY, tenantId, mockFetch);
1060
- expect(result.data).toEqual(mockResponse);
1061
- expect(restFetchSpy).toHaveBeenCalledWith(expect.any(String), expect.objectContaining({
1062
- body: expect.objectContaining({
1063
- tenantId: tenantId
1064
- })
1065
- }));
1066
- });
1067
- it('should handle error response', async () => {
1068
- const mockError = {
1069
- code: 400,
1070
- message: 'INVALID_ID_TOKEN'
1071
- };
1072
- vi.mocked(restFetch.restFetch).mockResolvedValue({
1073
- data: null,
1074
- error: { error: mockError }
1075
- });
1076
- const result = await unlinkProvider('invalid-token', 'google.com', API_KEY);
1077
- expect(result.data).toBeNull();
1078
- expect(result.error).toBeInstanceOf(FirebaseEdgeError);
1079
- });
1080
- });
1081
- });
1082
- //# sourceMappingURL=firebase-auth-endpoints.test.js.map