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