@depup/mongodb 7.1.0-depup.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/LICENSE.md +201 -0
- package/README.md +33 -0
- package/etc/prepare.js +12 -0
- package/lib/admin.js +136 -0
- package/lib/admin.js.map +1 -0
- package/lib/bson.js +85 -0
- package/lib/bson.js.map +1 -0
- package/lib/bulk/common.js +835 -0
- package/lib/bulk/common.js.map +1 -0
- package/lib/bulk/ordered.js +67 -0
- package/lib/bulk/ordered.js.map +1 -0
- package/lib/bulk/unordered.js +92 -0
- package/lib/bulk/unordered.js.map +1 -0
- package/lib/change_stream.js +513 -0
- package/lib/change_stream.js.map +1 -0
- package/lib/client-side-encryption/auto_encrypter.js +272 -0
- package/lib/client-side-encryption/auto_encrypter.js.map +1 -0
- package/lib/client-side-encryption/client_encryption.js +609 -0
- package/lib/client-side-encryption/client_encryption.js.map +1 -0
- package/lib/client-side-encryption/errors.js +138 -0
- package/lib/client-side-encryption/errors.js.map +1 -0
- package/lib/client-side-encryption/mongocryptd_manager.js +85 -0
- package/lib/client-side-encryption/mongocryptd_manager.js.map +1 -0
- package/lib/client-side-encryption/providers/aws.js +23 -0
- package/lib/client-side-encryption/providers/aws.js.map +1 -0
- package/lib/client-side-encryption/providers/azure.js +132 -0
- package/lib/client-side-encryption/providers/azure.js.map +1 -0
- package/lib/client-side-encryption/providers/gcp.js +16 -0
- package/lib/client-side-encryption/providers/gcp.js.map +1 -0
- package/lib/client-side-encryption/providers/index.js +43 -0
- package/lib/client-side-encryption/providers/index.js.map +1 -0
- package/lib/client-side-encryption/state_machine.js +427 -0
- package/lib/client-side-encryption/state_machine.js.map +1 -0
- package/lib/cmap/auth/auth_provider.js +51 -0
- package/lib/cmap/auth/auth_provider.js.map +1 -0
- package/lib/cmap/auth/aws4.js +161 -0
- package/lib/cmap/auth/aws4.js.map +1 -0
- package/lib/cmap/auth/aws_temporary_credentials.js +103 -0
- package/lib/cmap/auth/aws_temporary_credentials.js.map +1 -0
- package/lib/cmap/auth/gssapi.js +155 -0
- package/lib/cmap/auth/gssapi.js.map +1 -0
- package/lib/cmap/auth/mongo_credentials.js +169 -0
- package/lib/cmap/auth/mongo_credentials.js.map +1 -0
- package/lib/cmap/auth/mongodb_aws.js +128 -0
- package/lib/cmap/auth/mongodb_aws.js.map +1 -0
- package/lib/cmap/auth/mongodb_oidc/automated_callback_workflow.js +84 -0
- package/lib/cmap/auth/mongodb_oidc/automated_callback_workflow.js.map +1 -0
- package/lib/cmap/auth/mongodb_oidc/azure_machine_workflow.js +62 -0
- package/lib/cmap/auth/mongodb_oidc/azure_machine_workflow.js.map +1 -0
- package/lib/cmap/auth/mongodb_oidc/callback_workflow.js +141 -0
- package/lib/cmap/auth/mongodb_oidc/callback_workflow.js.map +1 -0
- package/lib/cmap/auth/mongodb_oidc/command_builders.js +44 -0
- package/lib/cmap/auth/mongodb_oidc/command_builders.js.map +1 -0
- package/lib/cmap/auth/mongodb_oidc/gcp_machine_workflow.js +39 -0
- package/lib/cmap/auth/mongodb_oidc/gcp_machine_workflow.js.map +1 -0
- package/lib/cmap/auth/mongodb_oidc/human_callback_workflow.js +122 -0
- package/lib/cmap/auth/mongodb_oidc/human_callback_workflow.js.map +1 -0
- package/lib/cmap/auth/mongodb_oidc/k8s_machine_workflow.js +32 -0
- package/lib/cmap/auth/mongodb_oidc/k8s_machine_workflow.js.map +1 -0
- package/lib/cmap/auth/mongodb_oidc/token_cache.js +52 -0
- package/lib/cmap/auth/mongodb_oidc/token_cache.js.map +1 -0
- package/lib/cmap/auth/mongodb_oidc/token_machine_workflow.js +23 -0
- package/lib/cmap/auth/mongodb_oidc/token_machine_workflow.js.map +1 -0
- package/lib/cmap/auth/mongodb_oidc.js +73 -0
- package/lib/cmap/auth/mongodb_oidc.js.map +1 -0
- package/lib/cmap/auth/plain.js +26 -0
- package/lib/cmap/auth/plain.js.map +1 -0
- package/lib/cmap/auth/providers.js +22 -0
- package/lib/cmap/auth/providers.js.map +1 -0
- package/lib/cmap/auth/scram.js +254 -0
- package/lib/cmap/auth/scram.js.map +1 -0
- package/lib/cmap/auth/x509.js +36 -0
- package/lib/cmap/auth/x509.js.map +1 -0
- package/lib/cmap/command_monitoring_events.js +223 -0
- package/lib/cmap/command_monitoring_events.js.map +1 -0
- package/lib/cmap/commands.js +535 -0
- package/lib/cmap/commands.js.map +1 -0
- package/lib/cmap/connect.js +381 -0
- package/lib/cmap/connect.js.map +1 -0
- package/lib/cmap/connection.js +571 -0
- package/lib/cmap/connection.js.map +1 -0
- package/lib/cmap/connection_pool.js +558 -0
- package/lib/cmap/connection_pool.js.map +1 -0
- package/lib/cmap/connection_pool_events.js +190 -0
- package/lib/cmap/connection_pool_events.js.map +1 -0
- package/lib/cmap/errors.js +108 -0
- package/lib/cmap/errors.js.map +1 -0
- package/lib/cmap/handshake/client_metadata.js +242 -0
- package/lib/cmap/handshake/client_metadata.js.map +1 -0
- package/lib/cmap/metrics.js +62 -0
- package/lib/cmap/metrics.js.map +1 -0
- package/lib/cmap/stream_description.js +70 -0
- package/lib/cmap/stream_description.js.map +1 -0
- package/lib/cmap/wire_protocol/compression.js +178 -0
- package/lib/cmap/wire_protocol/compression.js.map +1 -0
- package/lib/cmap/wire_protocol/constants.js +21 -0
- package/lib/cmap/wire_protocol/constants.js.map +1 -0
- package/lib/cmap/wire_protocol/on_data.js +111 -0
- package/lib/cmap/wire_protocol/on_data.js.map +1 -0
- package/lib/cmap/wire_protocol/on_demand/document.js +222 -0
- package/lib/cmap/wire_protocol/on_demand/document.js.map +1 -0
- package/lib/cmap/wire_protocol/responses.js +315 -0
- package/lib/cmap/wire_protocol/responses.js.map +1 -0
- package/lib/cmap/wire_protocol/shared.js +35 -0
- package/lib/cmap/wire_protocol/shared.js.map +1 -0
- package/lib/collection.js +751 -0
- package/lib/collection.js.map +1 -0
- package/lib/connection_string.js +1090 -0
- package/lib/connection_string.js.map +1 -0
- package/lib/constants.js +170 -0
- package/lib/constants.js.map +1 -0
- package/lib/cursor/abstract_cursor.js +924 -0
- package/lib/cursor/abstract_cursor.js.map +1 -0
- package/lib/cursor/aggregation_cursor.js +164 -0
- package/lib/cursor/aggregation_cursor.js.map +1 -0
- package/lib/cursor/change_stream_cursor.js +104 -0
- package/lib/cursor/change_stream_cursor.js.map +1 -0
- package/lib/cursor/client_bulk_write_cursor.js +52 -0
- package/lib/cursor/client_bulk_write_cursor.js.map +1 -0
- package/lib/cursor/explainable_cursor.js +36 -0
- package/lib/cursor/explainable_cursor.js.map +1 -0
- package/lib/cursor/find_cursor.js +399 -0
- package/lib/cursor/find_cursor.js.map +1 -0
- package/lib/cursor/list_collections_cursor.js +34 -0
- package/lib/cursor/list_collections_cursor.js.map +1 -0
- package/lib/cursor/list_indexes_cursor.js +32 -0
- package/lib/cursor/list_indexes_cursor.js.map +1 -0
- package/lib/cursor/list_search_indexes_cursor.js +14 -0
- package/lib/cursor/list_search_indexes_cursor.js.map +1 -0
- package/lib/cursor/run_command_cursor.js +94 -0
- package/lib/cursor/run_command_cursor.js.map +1 -0
- package/lib/db.js +419 -0
- package/lib/db.js.map +1 -0
- package/lib/deps.js +112 -0
- package/lib/deps.js.map +1 -0
- package/lib/encrypter.js +106 -0
- package/lib/encrypter.js.map +1 -0
- package/lib/error.js +1380 -0
- package/lib/error.js.map +1 -0
- package/lib/explain.js +59 -0
- package/lib/explain.js.map +1 -0
- package/lib/gridfs/download.js +305 -0
- package/lib/gridfs/download.js.map +1 -0
- package/lib/gridfs/index.js +164 -0
- package/lib/gridfs/index.js.map +1 -0
- package/lib/gridfs/upload.js +358 -0
- package/lib/gridfs/upload.js.map +1 -0
- package/lib/index.js +193 -0
- package/lib/index.js.map +1 -0
- package/lib/mongo_client.js +557 -0
- package/lib/mongo_client.js.map +1 -0
- package/lib/mongo_client_auth_providers.js +80 -0
- package/lib/mongo_client_auth_providers.js.map +1 -0
- package/lib/mongo_logger.js +655 -0
- package/lib/mongo_logger.js.map +1 -0
- package/lib/mongo_types.js +56 -0
- package/lib/mongo_types.js.map +1 -0
- package/lib/operations/aggregate.js +90 -0
- package/lib/operations/aggregate.js.map +1 -0
- package/lib/operations/client_bulk_write/client_bulk_write.js +51 -0
- package/lib/operations/client_bulk_write/client_bulk_write.js.map +1 -0
- package/lib/operations/client_bulk_write/command_builder.js +340 -0
- package/lib/operations/client_bulk_write/command_builder.js.map +1 -0
- package/lib/operations/client_bulk_write/common.js +3 -0
- package/lib/operations/client_bulk_write/common.js.map +1 -0
- package/lib/operations/client_bulk_write/executor.js +120 -0
- package/lib/operations/client_bulk_write/executor.js.map +1 -0
- package/lib/operations/client_bulk_write/results_merger.js +204 -0
- package/lib/operations/client_bulk_write/results_merger.js.map +1 -0
- package/lib/operations/command.js +83 -0
- package/lib/operations/command.js.map +1 -0
- package/lib/operations/count.js +45 -0
- package/lib/operations/count.js.map +1 -0
- package/lib/operations/create_collection.js +109 -0
- package/lib/operations/create_collection.js.map +1 -0
- package/lib/operations/delete.js +125 -0
- package/lib/operations/delete.js.map +1 -0
- package/lib/operations/distinct.js +61 -0
- package/lib/operations/distinct.js.map +1 -0
- package/lib/operations/drop.js +93 -0
- package/lib/operations/drop.js.map +1 -0
- package/lib/operations/end_sessions.js +34 -0
- package/lib/operations/end_sessions.js.map +1 -0
- package/lib/operations/estimated_document_count.js +41 -0
- package/lib/operations/estimated_document_count.js.map +1 -0
- package/lib/operations/execute_operation.js +239 -0
- package/lib/operations/execute_operation.js.map +1 -0
- package/lib/operations/find.js +148 -0
- package/lib/operations/find.js.map +1 -0
- package/lib/operations/find_and_modify.js +158 -0
- package/lib/operations/find_and_modify.js.map +1 -0
- package/lib/operations/get_more.js +62 -0
- package/lib/operations/get_more.js.map +1 -0
- package/lib/operations/indexes.js +186 -0
- package/lib/operations/indexes.js.map +1 -0
- package/lib/operations/insert.js +70 -0
- package/lib/operations/insert.js.map +1 -0
- package/lib/operations/kill_cursors.js +43 -0
- package/lib/operations/kill_cursors.js.map +1 -0
- package/lib/operations/list_collections.js +53 -0
- package/lib/operations/list_collections.js.map +1 -0
- package/lib/operations/list_databases.js +40 -0
- package/lib/operations/list_databases.js.map +1 -0
- package/lib/operations/operation.js +102 -0
- package/lib/operations/operation.js.map +1 -0
- package/lib/operations/profiling_level.js +43 -0
- package/lib/operations/profiling_level.js.map +1 -0
- package/lib/operations/remove_user.js +27 -0
- package/lib/operations/remove_user.js.map +1 -0
- package/lib/operations/rename.js +38 -0
- package/lib/operations/rename.js.map +1 -0
- package/lib/operations/run_command.js +47 -0
- package/lib/operations/run_command.js.map +1 -0
- package/lib/operations/search_indexes/create.js +33 -0
- package/lib/operations/search_indexes/create.js.map +1 -0
- package/lib/operations/search_indexes/drop.js +43 -0
- package/lib/operations/search_indexes/drop.js.map +1 -0
- package/lib/operations/search_indexes/update.js +35 -0
- package/lib/operations/search_indexes/update.js.map +1 -0
- package/lib/operations/set_profiling_level.js +53 -0
- package/lib/operations/set_profiling_level.js.map +1 -0
- package/lib/operations/stats.js +27 -0
- package/lib/operations/stats.js.map +1 -0
- package/lib/operations/update.js +188 -0
- package/lib/operations/update.js.map +1 -0
- package/lib/operations/validate_collection.js +37 -0
- package/lib/operations/validate_collection.js.map +1 -0
- package/lib/read_concern.js +73 -0
- package/lib/read_concern.js.map +1 -0
- package/lib/read_preference.js +191 -0
- package/lib/read_preference.js.map +1 -0
- package/lib/sdam/common.js +49 -0
- package/lib/sdam/common.js.map +1 -0
- package/lib/sdam/events.js +146 -0
- package/lib/sdam/events.js.map +1 -0
- package/lib/sdam/monitor.js +544 -0
- package/lib/sdam/monitor.js.map +1 -0
- package/lib/sdam/server.js +404 -0
- package/lib/sdam/server.js.map +1 -0
- package/lib/sdam/server_description.js +204 -0
- package/lib/sdam/server_description.js.map +1 -0
- package/lib/sdam/server_selection.js +294 -0
- package/lib/sdam/server_selection.js.map +1 -0
- package/lib/sdam/server_selection_events.js +85 -0
- package/lib/sdam/server_selection_events.js.map +1 -0
- package/lib/sdam/srv_polling.js +108 -0
- package/lib/sdam/srv_polling.js.map +1 -0
- package/lib/sdam/topology.js +652 -0
- package/lib/sdam/topology.js.map +1 -0
- package/lib/sdam/topology_description.js +383 -0
- package/lib/sdam/topology_description.js.map +1 -0
- package/lib/sessions.js +892 -0
- package/lib/sessions.js.map +1 -0
- package/lib/sort.js +103 -0
- package/lib/sort.js.map +1 -0
- package/lib/timeout.js +296 -0
- package/lib/timeout.js.map +1 -0
- package/lib/transactions.js +135 -0
- package/lib/transactions.js.map +1 -0
- package/lib/utils.js +1163 -0
- package/lib/utils.js.map +1 -0
- package/lib/write_concern.js +100 -0
- package/lib/write_concern.js.map +1 -0
- package/mongodb.d.ts +9018 -0
- package/package.json +197 -0
- package/src/admin.ts +173 -0
- package/src/bson.ts +149 -0
- package/src/bulk/common.ts +1251 -0
- package/src/bulk/ordered.ts +83 -0
- package/src/bulk/unordered.ts +115 -0
- package/src/change_stream.ts +1160 -0
- package/src/client-side-encryption/auto_encrypter.ts +469 -0
- package/src/client-side-encryption/client_encryption.ts +1150 -0
- package/src/client-side-encryption/errors.ts +144 -0
- package/src/client-side-encryption/mongocryptd_manager.ts +100 -0
- package/src/client-side-encryption/providers/aws.ts +33 -0
- package/src/client-side-encryption/providers/azure.ts +181 -0
- package/src/client-side-encryption/providers/gcp.ts +16 -0
- package/src/client-side-encryption/providers/index.ts +207 -0
- package/src/client-side-encryption/state_machine.ts +651 -0
- package/src/cmap/auth/auth_provider.ts +77 -0
- package/src/cmap/auth/aws4.ts +207 -0
- package/src/cmap/auth/aws_temporary_credentials.ts +129 -0
- package/src/cmap/auth/gssapi.ts +203 -0
- package/src/cmap/auth/mongo_credentials.ts +292 -0
- package/src/cmap/auth/mongodb_aws.ts +179 -0
- package/src/cmap/auth/mongodb_oidc/automated_callback_workflow.ts +88 -0
- package/src/cmap/auth/mongodb_oidc/azure_machine_workflow.ts +73 -0
- package/src/cmap/auth/mongodb_oidc/callback_workflow.ts +188 -0
- package/src/cmap/auth/mongodb_oidc/command_builders.ts +53 -0
- package/src/cmap/auth/mongodb_oidc/gcp_machine_workflow.ts +46 -0
- package/src/cmap/auth/mongodb_oidc/human_callback_workflow.ts +141 -0
- package/src/cmap/auth/mongodb_oidc/k8s_machine_workflow.ts +31 -0
- package/src/cmap/auth/mongodb_oidc/token_cache.ts +62 -0
- package/src/cmap/auth/mongodb_oidc/token_machine_workflow.ts +22 -0
- package/src/cmap/auth/mongodb_oidc.ts +185 -0
- package/src/cmap/auth/plain.ts +25 -0
- package/src/cmap/auth/providers.ts +22 -0
- package/src/cmap/auth/scram.ts +344 -0
- package/src/cmap/auth/x509.ts +43 -0
- package/src/cmap/command_monitoring_events.ts +316 -0
- package/src/cmap/commands.ts +788 -0
- package/src/cmap/connect.ts +518 -0
- package/src/cmap/connection.ts +931 -0
- package/src/cmap/connection_pool.ts +831 -0
- package/src/cmap/connection_pool_events.ts +300 -0
- package/src/cmap/errors.ts +119 -0
- package/src/cmap/handshake/client_metadata.ts +353 -0
- package/src/cmap/metrics.ts +58 -0
- package/src/cmap/stream_description.ts +96 -0
- package/src/cmap/wire_protocol/compression.ts +211 -0
- package/src/cmap/wire_protocol/constants.ts +17 -0
- package/src/cmap/wire_protocol/on_data.ts +139 -0
- package/src/cmap/wire_protocol/on_demand/document.ts +358 -0
- package/src/cmap/wire_protocol/responses.ts +393 -0
- package/src/cmap/wire_protocol/shared.ts +48 -0
- package/src/collection.ts +1314 -0
- package/src/connection_string.ts +1297 -0
- package/src/constants.ts +176 -0
- package/src/cursor/abstract_cursor.ts +1247 -0
- package/src/cursor/aggregation_cursor.ts +245 -0
- package/src/cursor/change_stream_cursor.ts +171 -0
- package/src/cursor/client_bulk_write_cursor.ts +83 -0
- package/src/cursor/explainable_cursor.ts +51 -0
- package/src/cursor/find_cursor.ts +497 -0
- package/src/cursor/list_collections_cursor.ts +50 -0
- package/src/cursor/list_indexes_cursor.ts +37 -0
- package/src/cursor/list_search_indexes_cursor.ts +20 -0
- package/src/cursor/run_command_cursor.ts +178 -0
- package/src/db.ts +621 -0
- package/src/deps.ts +227 -0
- package/src/encrypter.ts +127 -0
- package/src/error.ts +1567 -0
- package/src/explain.ts +124 -0
- package/src/gridfs/download.ts +483 -0
- package/src/gridfs/index.ts +264 -0
- package/src/gridfs/upload.ts +537 -0
- package/src/index.ts +633 -0
- package/src/mongo_client.ts +1155 -0
- package/src/mongo_client_auth_providers.ts +87 -0
- package/src/mongo_logger.ts +1081 -0
- package/src/mongo_types.ts +678 -0
- package/src/operations/aggregate.ts +153 -0
- package/src/operations/client_bulk_write/client_bulk_write.ts +72 -0
- package/src/operations/client_bulk_write/command_builder.ts +487 -0
- package/src/operations/client_bulk_write/common.ts +276 -0
- package/src/operations/client_bulk_write/executor.ts +149 -0
- package/src/operations/client_bulk_write/results_merger.ts +260 -0
- package/src/operations/command.ts +171 -0
- package/src/operations/count.ts +74 -0
- package/src/operations/create_collection.ts +218 -0
- package/src/operations/delete.ts +183 -0
- package/src/operations/distinct.ts +92 -0
- package/src/operations/drop.ts +130 -0
- package/src/operations/end_sessions.ts +44 -0
- package/src/operations/estimated_document_count.ts +61 -0
- package/src/operations/execute_operation.ts +319 -0
- package/src/operations/find.ts +254 -0
- package/src/operations/find_and_modify.ts +319 -0
- package/src/operations/get_more.ts +108 -0
- package/src/operations/indexes.ts +418 -0
- package/src/operations/insert.ts +108 -0
- package/src/operations/kill_cursors.ts +64 -0
- package/src/operations/list_collections.ts +108 -0
- package/src/operations/list_databases.ts +68 -0
- package/src/operations/operation.ts +181 -0
- package/src/operations/profiling_level.ts +46 -0
- package/src/operations/remove_user.ts +36 -0
- package/src/operations/rename.ts +60 -0
- package/src/operations/run_command.ts +79 -0
- package/src/operations/search_indexes/create.ts +56 -0
- package/src/operations/search_indexes/drop.ts +58 -0
- package/src/operations/search_indexes/update.ts +45 -0
- package/src/operations/set_profiling_level.ts +74 -0
- package/src/operations/stats.ts +37 -0
- package/src/operations/update.ts +318 -0
- package/src/operations/validate_collection.ts +50 -0
- package/src/read_concern.ts +88 -0
- package/src/read_preference.ts +256 -0
- package/src/sdam/common.ts +74 -0
- package/src/sdam/events.ts +219 -0
- package/src/sdam/monitor.ts +771 -0
- package/src/sdam/server.ts +595 -0
- package/src/sdam/server_description.ts +297 -0
- package/src/sdam/server_selection.ts +415 -0
- package/src/sdam/server_selection_events.ts +142 -0
- package/src/sdam/srv_polling.ts +146 -0
- package/src/sdam/topology.ts +1100 -0
- package/src/sdam/topology_description.ts +548 -0
- package/src/sessions.ts +1244 -0
- package/src/sort.ts +141 -0
- package/src/timeout.ts +405 -0
- package/src/transactions.ts +181 -0
- package/src/utils.ts +1434 -0
- package/src/write_concern.ts +183 -0
- package/tsconfig.json +46 -0
|
@@ -0,0 +1,292 @@
|
|
|
1
|
+
// Resolves the default auth mechanism according to
|
|
2
|
+
// Resolves the default auth mechanism according to
|
|
3
|
+
import type { Document } from '../../bson';
|
|
4
|
+
import {
|
|
5
|
+
MongoAPIError,
|
|
6
|
+
MongoInvalidArgumentError,
|
|
7
|
+
MongoMissingCredentialsError
|
|
8
|
+
} from '../../error';
|
|
9
|
+
import type { AWSCredentialProvider } from './aws_temporary_credentials';
|
|
10
|
+
import { GSSAPICanonicalizationValue } from './gssapi';
|
|
11
|
+
import type { OIDCCallbackFunction } from './mongodb_oidc';
|
|
12
|
+
import { AUTH_MECHS_AUTH_SRC_EXTERNAL, AuthMechanism } from './providers';
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* @see https://github.com/mongodb/specifications/blob/master/source/auth/auth.md
|
|
16
|
+
*/
|
|
17
|
+
function getDefaultAuthMechanism(hello: Document | null): AuthMechanism {
|
|
18
|
+
if (hello) {
|
|
19
|
+
// If hello contains saslSupportedMechs, use scram-sha-256
|
|
20
|
+
// if it is available, else scram-sha-1
|
|
21
|
+
if (Array.isArray(hello.saslSupportedMechs)) {
|
|
22
|
+
return hello.saslSupportedMechs.includes(AuthMechanism.MONGODB_SCRAM_SHA256)
|
|
23
|
+
? AuthMechanism.MONGODB_SCRAM_SHA256
|
|
24
|
+
: AuthMechanism.MONGODB_SCRAM_SHA1;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// Default auth mechanism for 4.0 and higher.
|
|
29
|
+
return AuthMechanism.MONGODB_SCRAM_SHA256;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const ALLOWED_ENVIRONMENT_NAMES: AuthMechanismProperties['ENVIRONMENT'][] = [
|
|
33
|
+
'test',
|
|
34
|
+
'azure',
|
|
35
|
+
'gcp',
|
|
36
|
+
'k8s'
|
|
37
|
+
];
|
|
38
|
+
const ALLOWED_HOSTS_ERROR = 'Auth mechanism property ALLOWED_HOSTS must be an array of strings.';
|
|
39
|
+
|
|
40
|
+
/** @internal */
|
|
41
|
+
export const DEFAULT_ALLOWED_HOSTS = [
|
|
42
|
+
'*.mongodb.net',
|
|
43
|
+
'*.mongodb-qa.net',
|
|
44
|
+
'*.mongodb-dev.net',
|
|
45
|
+
'*.mongodbgov.net',
|
|
46
|
+
'localhost',
|
|
47
|
+
'127.0.0.1',
|
|
48
|
+
'::1',
|
|
49
|
+
'*.mongo.com'
|
|
50
|
+
];
|
|
51
|
+
|
|
52
|
+
/** Error for when the token audience is missing in the environment. */
|
|
53
|
+
const TOKEN_RESOURCE_MISSING_ERROR =
|
|
54
|
+
'TOKEN_RESOURCE must be set in the auth mechanism properties when ENVIRONMENT is azure or gcp.';
|
|
55
|
+
|
|
56
|
+
/** @public */
|
|
57
|
+
export interface AuthMechanismProperties extends Document {
|
|
58
|
+
SERVICE_HOST?: string;
|
|
59
|
+
SERVICE_NAME?: string;
|
|
60
|
+
SERVICE_REALM?: string;
|
|
61
|
+
CANONICALIZE_HOST_NAME?: GSSAPICanonicalizationValue;
|
|
62
|
+
/** @internal */
|
|
63
|
+
AWS_SESSION_TOKEN?: string;
|
|
64
|
+
/** A user provided OIDC machine callback function. */
|
|
65
|
+
OIDC_CALLBACK?: OIDCCallbackFunction;
|
|
66
|
+
/** A user provided OIDC human interacted callback function. */
|
|
67
|
+
OIDC_HUMAN_CALLBACK?: OIDCCallbackFunction;
|
|
68
|
+
/** The OIDC environment. Note that 'test' is for internal use only. */
|
|
69
|
+
ENVIRONMENT?: 'test' | 'azure' | 'gcp' | 'k8s';
|
|
70
|
+
/** Allowed hosts that OIDC auth can connect to. */
|
|
71
|
+
ALLOWED_HOSTS?: string[];
|
|
72
|
+
/** The resource token for OIDC auth in Azure and GCP. */
|
|
73
|
+
TOKEN_RESOURCE?: string;
|
|
74
|
+
/**
|
|
75
|
+
* A custom AWS credential provider to use. An example using the AWS SDK default provider chain:
|
|
76
|
+
*
|
|
77
|
+
* ```ts
|
|
78
|
+
* const client = new MongoClient(process.env.MONGODB_URI, {
|
|
79
|
+
* authMechanismProperties: {
|
|
80
|
+
* AWS_CREDENTIAL_PROVIDER: fromNodeProviderChain()
|
|
81
|
+
* }
|
|
82
|
+
* });
|
|
83
|
+
* ```
|
|
84
|
+
*
|
|
85
|
+
* Using a custom function that returns AWS credentials:
|
|
86
|
+
*
|
|
87
|
+
* ```ts
|
|
88
|
+
* const client = new MongoClient(process.env.MONGODB_URI, {
|
|
89
|
+
* authMechanismProperties: {
|
|
90
|
+
* AWS_CREDENTIAL_PROVIDER: async () => {
|
|
91
|
+
* return {
|
|
92
|
+
* accessKeyId: process.env.ACCESS_KEY_ID,
|
|
93
|
+
* secretAccessKey: process.env.SECRET_ACCESS_KEY
|
|
94
|
+
* }
|
|
95
|
+
* }
|
|
96
|
+
* }
|
|
97
|
+
* });
|
|
98
|
+
* ```
|
|
99
|
+
*/
|
|
100
|
+
AWS_CREDENTIAL_PROVIDER?: AWSCredentialProvider;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/** @public */
|
|
104
|
+
export interface MongoCredentialsOptions {
|
|
105
|
+
username?: string;
|
|
106
|
+
password: string;
|
|
107
|
+
source: string;
|
|
108
|
+
db?: string;
|
|
109
|
+
mechanism?: AuthMechanism;
|
|
110
|
+
mechanismProperties: AuthMechanismProperties;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* A representation of the credentials used by MongoDB
|
|
115
|
+
* @public
|
|
116
|
+
*/
|
|
117
|
+
export class MongoCredentials {
|
|
118
|
+
/** The username used for authentication */
|
|
119
|
+
readonly username: string;
|
|
120
|
+
/** The password used for authentication */
|
|
121
|
+
readonly password: string;
|
|
122
|
+
/** The database that the user should authenticate against */
|
|
123
|
+
readonly source: string;
|
|
124
|
+
/** The method used to authenticate */
|
|
125
|
+
readonly mechanism: AuthMechanism;
|
|
126
|
+
/** Special properties used by some types of auth mechanisms */
|
|
127
|
+
readonly mechanismProperties: AuthMechanismProperties;
|
|
128
|
+
|
|
129
|
+
constructor(options: MongoCredentialsOptions) {
|
|
130
|
+
this.username = options.username ?? '';
|
|
131
|
+
this.password = options.password;
|
|
132
|
+
this.source = options.source;
|
|
133
|
+
if (!this.source && options.db) {
|
|
134
|
+
this.source = options.db;
|
|
135
|
+
}
|
|
136
|
+
this.mechanism = options.mechanism || AuthMechanism.MONGODB_DEFAULT;
|
|
137
|
+
this.mechanismProperties = options.mechanismProperties || {};
|
|
138
|
+
|
|
139
|
+
if (this.mechanism === AuthMechanism.MONGODB_OIDC && !this.mechanismProperties.ALLOWED_HOSTS) {
|
|
140
|
+
this.mechanismProperties = {
|
|
141
|
+
...this.mechanismProperties,
|
|
142
|
+
ALLOWED_HOSTS: DEFAULT_ALLOWED_HOSTS
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
Object.freeze(this.mechanismProperties);
|
|
147
|
+
Object.freeze(this);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/** Determines if two MongoCredentials objects are equivalent */
|
|
151
|
+
equals(other: MongoCredentials): boolean {
|
|
152
|
+
return (
|
|
153
|
+
this.mechanism === other.mechanism &&
|
|
154
|
+
this.username === other.username &&
|
|
155
|
+
this.password === other.password &&
|
|
156
|
+
this.source === other.source
|
|
157
|
+
);
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* If the authentication mechanism is set to "default", resolves the authMechanism
|
|
162
|
+
* based on the server version and server supported sasl mechanisms.
|
|
163
|
+
*
|
|
164
|
+
* @param hello - A hello response from the server
|
|
165
|
+
*/
|
|
166
|
+
resolveAuthMechanism(hello: Document | null): MongoCredentials {
|
|
167
|
+
// If the mechanism is not "default", then it does not need to be resolved
|
|
168
|
+
if (this.mechanism.match(/DEFAULT/i)) {
|
|
169
|
+
return new MongoCredentials({
|
|
170
|
+
username: this.username,
|
|
171
|
+
password: this.password,
|
|
172
|
+
source: this.source,
|
|
173
|
+
mechanism: getDefaultAuthMechanism(hello),
|
|
174
|
+
mechanismProperties: this.mechanismProperties
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
return this;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
validate(): void {
|
|
182
|
+
if (
|
|
183
|
+
(this.mechanism === AuthMechanism.MONGODB_GSSAPI ||
|
|
184
|
+
this.mechanism === AuthMechanism.MONGODB_PLAIN ||
|
|
185
|
+
this.mechanism === AuthMechanism.MONGODB_SCRAM_SHA1 ||
|
|
186
|
+
this.mechanism === AuthMechanism.MONGODB_SCRAM_SHA256) &&
|
|
187
|
+
!this.username
|
|
188
|
+
) {
|
|
189
|
+
throw new MongoMissingCredentialsError(`Username required for mechanism '${this.mechanism}'`);
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
if (this.mechanism === AuthMechanism.MONGODB_OIDC) {
|
|
193
|
+
if (
|
|
194
|
+
this.username &&
|
|
195
|
+
this.mechanismProperties.ENVIRONMENT &&
|
|
196
|
+
this.mechanismProperties.ENVIRONMENT !== 'azure'
|
|
197
|
+
) {
|
|
198
|
+
throw new MongoInvalidArgumentError(
|
|
199
|
+
`username and ENVIRONMENT '${this.mechanismProperties.ENVIRONMENT}' may not be used together for mechanism '${this.mechanism}'.`
|
|
200
|
+
);
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
if (this.username && this.password) {
|
|
204
|
+
throw new MongoInvalidArgumentError(
|
|
205
|
+
`No password is allowed in ENVIRONMENT '${this.mechanismProperties.ENVIRONMENT}' for '${this.mechanism}'.`
|
|
206
|
+
);
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
if (
|
|
210
|
+
(this.mechanismProperties.ENVIRONMENT === 'azure' ||
|
|
211
|
+
this.mechanismProperties.ENVIRONMENT === 'gcp') &&
|
|
212
|
+
!this.mechanismProperties.TOKEN_RESOURCE
|
|
213
|
+
) {
|
|
214
|
+
throw new MongoInvalidArgumentError(TOKEN_RESOURCE_MISSING_ERROR);
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
if (
|
|
218
|
+
this.mechanismProperties.ENVIRONMENT &&
|
|
219
|
+
!ALLOWED_ENVIRONMENT_NAMES.includes(this.mechanismProperties.ENVIRONMENT)
|
|
220
|
+
) {
|
|
221
|
+
throw new MongoInvalidArgumentError(
|
|
222
|
+
`Currently only a ENVIRONMENT in ${ALLOWED_ENVIRONMENT_NAMES.join(
|
|
223
|
+
','
|
|
224
|
+
)} is supported for mechanism '${this.mechanism}'.`
|
|
225
|
+
);
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
if (
|
|
229
|
+
!this.mechanismProperties.ENVIRONMENT &&
|
|
230
|
+
!this.mechanismProperties.OIDC_CALLBACK &&
|
|
231
|
+
!this.mechanismProperties.OIDC_HUMAN_CALLBACK
|
|
232
|
+
) {
|
|
233
|
+
throw new MongoInvalidArgumentError(
|
|
234
|
+
`Either a ENVIRONMENT, OIDC_CALLBACK, or OIDC_HUMAN_CALLBACK must be specified for mechanism '${this.mechanism}'.`
|
|
235
|
+
);
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
if (this.mechanismProperties.ALLOWED_HOSTS) {
|
|
239
|
+
const hosts = this.mechanismProperties.ALLOWED_HOSTS;
|
|
240
|
+
if (!Array.isArray(hosts)) {
|
|
241
|
+
throw new MongoInvalidArgumentError(ALLOWED_HOSTS_ERROR);
|
|
242
|
+
}
|
|
243
|
+
for (const host of hosts) {
|
|
244
|
+
if (typeof host !== 'string') {
|
|
245
|
+
throw new MongoInvalidArgumentError(ALLOWED_HOSTS_ERROR);
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
if (AUTH_MECHS_AUTH_SRC_EXTERNAL.has(this.mechanism)) {
|
|
252
|
+
if (this.source != null && this.source !== '$external') {
|
|
253
|
+
// TODO(NODE-3485): Replace this with a MongoAuthValidationError
|
|
254
|
+
throw new MongoAPIError(
|
|
255
|
+
`Invalid source '${this.source}' for mechanism '${this.mechanism}' specified.`
|
|
256
|
+
);
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
if (this.mechanism === AuthMechanism.MONGODB_PLAIN && this.source == null) {
|
|
261
|
+
// TODO(NODE-3485): Replace this with a MongoAuthValidationError
|
|
262
|
+
throw new MongoAPIError('PLAIN Authentication Mechanism needs an auth source');
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
if (this.mechanism === AuthMechanism.MONGODB_X509 && this.password != null) {
|
|
266
|
+
if (this.password === '') {
|
|
267
|
+
Reflect.set(this, 'password', undefined);
|
|
268
|
+
return;
|
|
269
|
+
}
|
|
270
|
+
// TODO(NODE-3485): Replace this with a MongoAuthValidationError
|
|
271
|
+
throw new MongoAPIError(`Password not allowed for mechanism MONGODB-X509`);
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
const canonicalization = this.mechanismProperties.CANONICALIZE_HOST_NAME ?? false;
|
|
275
|
+
if (!Object.values(GSSAPICanonicalizationValue).includes(canonicalization)) {
|
|
276
|
+
throw new MongoAPIError(`Invalid CANONICALIZE_HOST_NAME value: ${canonicalization}`);
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
static merge(
|
|
281
|
+
creds: MongoCredentials | undefined,
|
|
282
|
+
options: Partial<MongoCredentialsOptions>
|
|
283
|
+
): MongoCredentials {
|
|
284
|
+
return new MongoCredentials({
|
|
285
|
+
username: options.username ?? creds?.username ?? '',
|
|
286
|
+
password: options.password ?? creds?.password ?? '',
|
|
287
|
+
mechanism: options.mechanism ?? creds?.mechanism ?? AuthMechanism.MONGODB_DEFAULT,
|
|
288
|
+
mechanismProperties: options.mechanismProperties ?? creds?.mechanismProperties ?? {},
|
|
289
|
+
source: options.source ?? options.db ?? creds?.source ?? 'admin'
|
|
290
|
+
});
|
|
291
|
+
}
|
|
292
|
+
}
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
import type { Binary, BSONSerializeOptions } from '../../bson';
|
|
2
|
+
import * as BSON from '../../bson';
|
|
3
|
+
import {
|
|
4
|
+
MongoCompatibilityError,
|
|
5
|
+
MongoMissingCredentialsError,
|
|
6
|
+
MongoRuntimeError
|
|
7
|
+
} from '../../error';
|
|
8
|
+
import { ByteUtils, maxWireVersion, ns, randomBytes } from '../../utils';
|
|
9
|
+
import { type AuthContext, AuthProvider } from './auth_provider';
|
|
10
|
+
import {
|
|
11
|
+
type AWSCredentialProvider,
|
|
12
|
+
AWSSDKCredentialProvider,
|
|
13
|
+
type AWSTempCredentials
|
|
14
|
+
} from './aws_temporary_credentials';
|
|
15
|
+
import { aws4Sign } from './aws4';
|
|
16
|
+
import { MongoCredentials } from './mongo_credentials';
|
|
17
|
+
import { AuthMechanism } from './providers';
|
|
18
|
+
|
|
19
|
+
const ASCII_N = 110;
|
|
20
|
+
const bsonOptions: BSONSerializeOptions = {
|
|
21
|
+
useBigInt64: false,
|
|
22
|
+
promoteLongs: true,
|
|
23
|
+
promoteValues: true,
|
|
24
|
+
promoteBuffers: false,
|
|
25
|
+
bsonRegExp: false
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
interface AWSSaslContinuePayload {
|
|
29
|
+
a: string;
|
|
30
|
+
d: string;
|
|
31
|
+
t?: string;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export class MongoDBAWS extends AuthProvider {
|
|
35
|
+
private credentialFetcher: AWSSDKCredentialProvider;
|
|
36
|
+
|
|
37
|
+
constructor(credentialProvider?: AWSCredentialProvider) {
|
|
38
|
+
super();
|
|
39
|
+
this.credentialFetcher = new AWSSDKCredentialProvider(credentialProvider);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
override async auth(authContext: AuthContext): Promise<void> {
|
|
43
|
+
const { connection } = authContext;
|
|
44
|
+
if (!authContext.credentials) {
|
|
45
|
+
throw new MongoMissingCredentialsError('AuthContext must provide credentials.');
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
if (maxWireVersion(connection) < 9) {
|
|
49
|
+
throw new MongoCompatibilityError(
|
|
50
|
+
'MONGODB-AWS authentication requires MongoDB version 4.4 or later'
|
|
51
|
+
);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
authContext.credentials = await makeTempCredentials(
|
|
55
|
+
authContext.credentials,
|
|
56
|
+
this.credentialFetcher
|
|
57
|
+
);
|
|
58
|
+
|
|
59
|
+
const { credentials } = authContext;
|
|
60
|
+
|
|
61
|
+
const accessKeyId = credentials.username;
|
|
62
|
+
const secretAccessKey = credentials.password;
|
|
63
|
+
// Allow the user to specify an AWS session token for authentication with temporary credentials.
|
|
64
|
+
const sessionToken = credentials.mechanismProperties.AWS_SESSION_TOKEN;
|
|
65
|
+
|
|
66
|
+
// If all three defined, include sessionToken, else only include username and pass
|
|
67
|
+
const awsCredentials = sessionToken
|
|
68
|
+
? { accessKeyId, secretAccessKey, sessionToken }
|
|
69
|
+
: { accessKeyId, secretAccessKey };
|
|
70
|
+
|
|
71
|
+
const db = credentials.source;
|
|
72
|
+
const nonce = await randomBytes(32);
|
|
73
|
+
|
|
74
|
+
// All messages between MongoDB clients and servers are sent as BSON objects
|
|
75
|
+
// in the payload field of saslStart and saslContinue.
|
|
76
|
+
const saslStart = {
|
|
77
|
+
saslStart: 1,
|
|
78
|
+
mechanism: 'MONGODB-AWS',
|
|
79
|
+
payload: BSON.serialize({ r: nonce, p: ASCII_N }, bsonOptions)
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
const saslStartResponse = await connection.command(ns(`${db}.$cmd`), saslStart, undefined);
|
|
83
|
+
|
|
84
|
+
const serverResponse = BSON.deserialize(saslStartResponse.payload.buffer, bsonOptions) as {
|
|
85
|
+
s: Binary;
|
|
86
|
+
h: string;
|
|
87
|
+
};
|
|
88
|
+
const host = serverResponse.h;
|
|
89
|
+
const serverNonce = serverResponse.s.buffer;
|
|
90
|
+
if (serverNonce.length !== 64) {
|
|
91
|
+
// TODO(NODE-3483)
|
|
92
|
+
throw new MongoRuntimeError(`Invalid server nonce length ${serverNonce.length}, expected 64`);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
if (!ByteUtils.equals(serverNonce.subarray(0, nonce.byteLength), nonce)) {
|
|
96
|
+
// throw because the serverNonce's leading 32 bytes must equal the client nonce's 32 bytes
|
|
97
|
+
// https://github.com/mongodb/specifications/blob/master/source/auth/auth.md#conversation-5
|
|
98
|
+
|
|
99
|
+
// TODO(NODE-3483)
|
|
100
|
+
throw new MongoRuntimeError('Server nonce does not begin with client nonce');
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
if (host.length < 1 || host.length > 255 || host.indexOf('..') !== -1) {
|
|
104
|
+
// TODO(NODE-3483)
|
|
105
|
+
throw new MongoRuntimeError(`Server returned an invalid host: "${host}"`);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
const body = 'Action=GetCallerIdentity&Version=2011-06-15';
|
|
109
|
+
const headers = await aws4Sign(
|
|
110
|
+
{
|
|
111
|
+
method: 'POST',
|
|
112
|
+
host,
|
|
113
|
+
region: deriveRegion(serverResponse.h),
|
|
114
|
+
service: 'sts',
|
|
115
|
+
headers: {
|
|
116
|
+
'Content-Type': 'application/x-www-form-urlencoded',
|
|
117
|
+
'Content-Length': body.length,
|
|
118
|
+
'X-MongoDB-Server-Nonce': ByteUtils.toBase64(serverNonce),
|
|
119
|
+
'X-MongoDB-GS2-CB-Flag': 'n'
|
|
120
|
+
},
|
|
121
|
+
path: '/',
|
|
122
|
+
body,
|
|
123
|
+
date: new Date()
|
|
124
|
+
},
|
|
125
|
+
awsCredentials
|
|
126
|
+
);
|
|
127
|
+
|
|
128
|
+
const payload: AWSSaslContinuePayload = {
|
|
129
|
+
a: headers.Authorization,
|
|
130
|
+
d: headers['X-Amz-Date']
|
|
131
|
+
};
|
|
132
|
+
|
|
133
|
+
if (sessionToken) {
|
|
134
|
+
payload.t = sessionToken;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
const saslContinue = {
|
|
138
|
+
saslContinue: 1,
|
|
139
|
+
conversationId: saslStartResponse.conversationId,
|
|
140
|
+
payload: BSON.serialize(payload, bsonOptions)
|
|
141
|
+
};
|
|
142
|
+
|
|
143
|
+
await connection.command(ns(`${db}.$cmd`), saslContinue, undefined);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
async function makeTempCredentials(
|
|
148
|
+
credentials: MongoCredentials,
|
|
149
|
+
awsCredentialFetcher: AWSSDKCredentialProvider
|
|
150
|
+
): Promise<MongoCredentials> {
|
|
151
|
+
function makeMongoCredentialsFromAWSTemp(creds: AWSTempCredentials) {
|
|
152
|
+
// The AWS session token (creds.Token) may or may not be set.
|
|
153
|
+
if (!creds.AccessKeyId || !creds.SecretAccessKey) {
|
|
154
|
+
throw new MongoMissingCredentialsError('Could not obtain temporary MONGODB-AWS credentials');
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
return new MongoCredentials({
|
|
158
|
+
username: creds.AccessKeyId,
|
|
159
|
+
password: creds.SecretAccessKey,
|
|
160
|
+
source: credentials.source,
|
|
161
|
+
mechanism: AuthMechanism.MONGODB_AWS,
|
|
162
|
+
mechanismProperties: {
|
|
163
|
+
AWS_SESSION_TOKEN: creds.Token
|
|
164
|
+
}
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
const temporaryCredentials = await awsCredentialFetcher.getCredentials();
|
|
168
|
+
|
|
169
|
+
return makeMongoCredentialsFromAWSTemp(temporaryCredentials);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
function deriveRegion(host: string) {
|
|
173
|
+
const parts = host.split('.');
|
|
174
|
+
if (parts.length === 1 || parts[1] === 'amazonaws') {
|
|
175
|
+
return 'us-east-1';
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
return parts[1];
|
|
179
|
+
}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { MONGODB_ERROR_CODES, MongoError, MongoOIDCError } from '../../../error';
|
|
2
|
+
import { Timeout, TimeoutError } from '../../../timeout';
|
|
3
|
+
import { type Connection } from '../../connection';
|
|
4
|
+
import { type MongoCredentials } from '../mongo_credentials';
|
|
5
|
+
import {
|
|
6
|
+
OIDC_VERSION,
|
|
7
|
+
type OIDCCallbackFunction,
|
|
8
|
+
type OIDCCallbackParams,
|
|
9
|
+
type OIDCResponse
|
|
10
|
+
} from '../mongodb_oidc';
|
|
11
|
+
import { AUTOMATED_TIMEOUT_MS, CallbackWorkflow } from './callback_workflow';
|
|
12
|
+
import { type TokenCache } from './token_cache';
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Class implementing behaviour for the non human callback workflow.
|
|
16
|
+
* @internal
|
|
17
|
+
*/
|
|
18
|
+
export class AutomatedCallbackWorkflow extends CallbackWorkflow {
|
|
19
|
+
/**
|
|
20
|
+
* Instantiate the human callback workflow.
|
|
21
|
+
*/
|
|
22
|
+
constructor(cache: TokenCache, callback: OIDCCallbackFunction) {
|
|
23
|
+
super(cache, callback);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Execute the OIDC callback workflow.
|
|
28
|
+
*/
|
|
29
|
+
async execute(connection: Connection, credentials: MongoCredentials): Promise<void> {
|
|
30
|
+
// If there is a cached access token, try to authenticate with it. If
|
|
31
|
+
// authentication fails with an Authentication error (18),
|
|
32
|
+
// invalidate the access token, fetch a new access token, and try
|
|
33
|
+
// to authenticate again.
|
|
34
|
+
// If the server fails for any other reason, do not clear the cache.
|
|
35
|
+
if (this.cache.hasAccessToken) {
|
|
36
|
+
const token = this.cache.getAccessToken();
|
|
37
|
+
if (!connection.accessToken) {
|
|
38
|
+
connection.accessToken = token;
|
|
39
|
+
}
|
|
40
|
+
try {
|
|
41
|
+
return await this.finishAuthentication(connection, credentials, token);
|
|
42
|
+
} catch (error) {
|
|
43
|
+
if (
|
|
44
|
+
error instanceof MongoError &&
|
|
45
|
+
error.code === MONGODB_ERROR_CODES.AuthenticationFailed
|
|
46
|
+
) {
|
|
47
|
+
this.cache.removeAccessToken();
|
|
48
|
+
return await this.execute(connection, credentials);
|
|
49
|
+
} else {
|
|
50
|
+
throw error;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
const response = await this.fetchAccessToken(credentials);
|
|
55
|
+
this.cache.put(response);
|
|
56
|
+
connection.accessToken = response.accessToken;
|
|
57
|
+
await this.finishAuthentication(connection, credentials, response.accessToken);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Fetches the access token using the callback.
|
|
62
|
+
*/
|
|
63
|
+
protected async fetchAccessToken(credentials: MongoCredentials): Promise<OIDCResponse> {
|
|
64
|
+
const controller = new AbortController();
|
|
65
|
+
const params: OIDCCallbackParams = {
|
|
66
|
+
timeoutContext: controller.signal,
|
|
67
|
+
version: OIDC_VERSION
|
|
68
|
+
};
|
|
69
|
+
if (credentials.username) {
|
|
70
|
+
params.username = credentials.username;
|
|
71
|
+
}
|
|
72
|
+
if (credentials.mechanismProperties.TOKEN_RESOURCE) {
|
|
73
|
+
params.tokenAudience = credentials.mechanismProperties.TOKEN_RESOURCE;
|
|
74
|
+
}
|
|
75
|
+
const timeout = Timeout.expires(AUTOMATED_TIMEOUT_MS);
|
|
76
|
+
try {
|
|
77
|
+
return await Promise.race([this.executeAndValidateCallback(params), timeout]);
|
|
78
|
+
} catch (error) {
|
|
79
|
+
if (TimeoutError.is(error)) {
|
|
80
|
+
controller.abort();
|
|
81
|
+
throw new MongoOIDCError(`OIDC callback timed out after ${AUTOMATED_TIMEOUT_MS}ms.`);
|
|
82
|
+
}
|
|
83
|
+
throw error;
|
|
84
|
+
} finally {
|
|
85
|
+
timeout.clear();
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { addAzureParams, AZURE_BASE_URL } from '../../../client-side-encryption/providers/azure';
|
|
2
|
+
import { MongoAzureError } from '../../../error';
|
|
3
|
+
import { get } from '../../../utils';
|
|
4
|
+
import type { OIDCCallbackFunction, OIDCCallbackParams, OIDCResponse } from '../mongodb_oidc';
|
|
5
|
+
|
|
6
|
+
/** Azure request headers. */
|
|
7
|
+
const AZURE_HEADERS = Object.freeze({ Metadata: 'true', Accept: 'application/json' });
|
|
8
|
+
|
|
9
|
+
/** Invalid endpoint result error. */
|
|
10
|
+
const ENDPOINT_RESULT_ERROR =
|
|
11
|
+
'Azure endpoint did not return a value with only access_token and expires_in properties';
|
|
12
|
+
|
|
13
|
+
/** Error for when the token audience is missing in the environment. */
|
|
14
|
+
const TOKEN_RESOURCE_MISSING_ERROR =
|
|
15
|
+
'TOKEN_RESOURCE must be set in the auth mechanism properties when ENVIRONMENT is azure.';
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* The callback function to be used in the automated callback workflow.
|
|
19
|
+
* @param params - The OIDC callback parameters.
|
|
20
|
+
* @returns The OIDC response.
|
|
21
|
+
*/
|
|
22
|
+
export const callback: OIDCCallbackFunction = async (
|
|
23
|
+
params: OIDCCallbackParams
|
|
24
|
+
): Promise<OIDCResponse> => {
|
|
25
|
+
const tokenAudience = params.tokenAudience;
|
|
26
|
+
const username = params.username;
|
|
27
|
+
if (!tokenAudience) {
|
|
28
|
+
throw new MongoAzureError(TOKEN_RESOURCE_MISSING_ERROR);
|
|
29
|
+
}
|
|
30
|
+
const response = await getAzureTokenData(tokenAudience, username);
|
|
31
|
+
if (!isEndpointResultValid(response)) {
|
|
32
|
+
throw new MongoAzureError(ENDPOINT_RESULT_ERROR);
|
|
33
|
+
}
|
|
34
|
+
return response;
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Hit the Azure endpoint to get the token data.
|
|
39
|
+
*/
|
|
40
|
+
async function getAzureTokenData(tokenAudience: string, username?: string): Promise<OIDCResponse> {
|
|
41
|
+
const url = new URL(AZURE_BASE_URL);
|
|
42
|
+
addAzureParams(url, tokenAudience, username);
|
|
43
|
+
const response = await get(url, {
|
|
44
|
+
headers: AZURE_HEADERS
|
|
45
|
+
});
|
|
46
|
+
if (response.status !== 200) {
|
|
47
|
+
throw new MongoAzureError(
|
|
48
|
+
`Status code ${response.status} returned from the Azure endpoint. Response body: ${response.body}`
|
|
49
|
+
);
|
|
50
|
+
}
|
|
51
|
+
const result = JSON.parse(response.body);
|
|
52
|
+
return {
|
|
53
|
+
accessToken: result.access_token,
|
|
54
|
+
expiresInSeconds: Number(result.expires_in)
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Determines if a result returned from the endpoint is valid.
|
|
60
|
+
* This means the result is not nullish, contains the access_token required field
|
|
61
|
+
* and the expires_in required field.
|
|
62
|
+
*/
|
|
63
|
+
function isEndpointResultValid(
|
|
64
|
+
token: unknown
|
|
65
|
+
): token is { access_token: unknown; expires_in: unknown } {
|
|
66
|
+
if (token == null || typeof token !== 'object') return false;
|
|
67
|
+
return (
|
|
68
|
+
'accessToken' in token &&
|
|
69
|
+
typeof token.accessToken === 'string' &&
|
|
70
|
+
'expiresInSeconds' in token &&
|
|
71
|
+
typeof token.expiresInSeconds === 'number'
|
|
72
|
+
);
|
|
73
|
+
}
|