mongodb 4.2.1 → 4.4.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 +2 -2
- package/lib/admin.js +3 -3
- package/lib/admin.js.map +1 -1
- package/lib/bson.js +16 -14
- package/lib/bson.js.map +1 -1
- package/lib/bulk/common.js +7 -7
- package/lib/bulk/common.js.map +1 -1
- package/lib/bulk/ordered.js +1 -1
- package/lib/bulk/ordered.js.map +1 -1
- package/lib/bulk/unordered.js +1 -1
- package/lib/bulk/unordered.js.map +1 -1
- package/lib/change_stream.js +6 -6
- package/lib/change_stream.js.map +1 -1
- package/lib/cmap/auth/auth_provider.js.map +1 -1
- package/lib/cmap/auth/gssapi.js +52 -10
- package/lib/cmap/auth/gssapi.js.map +1 -1
- package/lib/cmap/auth/mongo_credentials.js +36 -27
- package/lib/cmap/auth/mongo_credentials.js.map +1 -1
- package/lib/cmap/auth/mongocr.js +2 -2
- package/lib/cmap/auth/mongocr.js.map +1 -1
- package/lib/cmap/auth/mongodb_aws.js +6 -6
- package/lib/cmap/auth/mongodb_aws.js.map +1 -1
- package/lib/cmap/auth/plain.js +1 -1
- package/lib/cmap/auth/plain.js.map +1 -1
- package/lib/cmap/auth/providers.js +21 -0
- package/lib/cmap/auth/providers.js.map +1 -0
- package/lib/cmap/auth/scram.js +4 -4
- package/lib/cmap/auth/scram.js.map +1 -1
- package/lib/cmap/auth/x509.js +1 -1
- package/lib/cmap/auth/x509.js.map +1 -1
- package/lib/cmap/command_monitoring_events.js +3 -2
- package/lib/cmap/command_monitoring_events.js.map +1 -1
- package/lib/cmap/commands.js +14 -8
- package/lib/cmap/commands.js.map +1 -1
- package/lib/cmap/connect.js +119 -37
- package/lib/cmap/connect.js.map +1 -1
- package/lib/cmap/connection.js +36 -35
- package/lib/cmap/connection.js.map +1 -1
- package/lib/cmap/connection_pool.js +19 -30
- package/lib/cmap/connection_pool.js.map +1 -1
- package/lib/cmap/message_stream.js +3 -3
- package/lib/cmap/message_stream.js.map +1 -1
- package/lib/cmap/stream_description.js +4 -4
- package/lib/cmap/stream_description.js.map +1 -1
- package/lib/cmap/wire_protocol/compression.js +2 -1
- package/lib/cmap/wire_protocol/compression.js.map +1 -1
- package/lib/cmap/wire_protocol/shared.js +4 -3
- package/lib/cmap/wire_protocol/shared.js.map +1 -1
- package/lib/collection.js +46 -47
- package/lib/collection.js.map +1 -1
- package/lib/connection_string.js +93 -54
- package/lib/connection_string.js.map +1 -1
- package/lib/constants.js +113 -1
- package/lib/constants.js.map +1 -1
- package/lib/cursor/abstract_cursor.js +5 -5
- package/lib/cursor/abstract_cursor.js.map +1 -1
- package/lib/cursor/aggregation_cursor.js +1 -1
- package/lib/cursor/aggregation_cursor.js.map +1 -1
- package/lib/cursor/find_cursor.js +2 -1
- package/lib/cursor/find_cursor.js.map +1 -1
- package/lib/db.js +23 -13
- package/lib/db.js.map +1 -1
- package/lib/deps.js +0 -1
- package/lib/deps.js.map +1 -1
- package/lib/encrypter.js +12 -4
- package/lib/encrypter.js.map +1 -1
- package/lib/error.js +47 -24
- package/lib/error.js.map +1 -1
- package/lib/gridfs/download.js +1 -1
- package/lib/gridfs/download.js.map +1 -1
- package/lib/gridfs/index.js +3 -3
- package/lib/gridfs/index.js.map +1 -1
- package/lib/gridfs/upload.js +3 -2
- package/lib/gridfs/upload.js.map +1 -1
- package/lib/index.js +83 -81
- package/lib/index.js.map +1 -1
- package/lib/logger.js +1 -1
- package/lib/logger.js.map +1 -1
- package/lib/mongo_client.js +5 -5
- package/lib/mongo_client.js.map +1 -1
- package/lib/mongo_types.js.map +1 -1
- package/lib/operations/add_user.js +3 -3
- package/lib/operations/add_user.js.map +1 -1
- package/lib/operations/aggregate.js +1 -1
- package/lib/operations/aggregate.js.map +1 -1
- package/lib/operations/bulk_write.js.map +1 -1
- package/lib/operations/collections.js +1 -1
- package/lib/operations/collections.js.map +1 -1
- package/lib/operations/command.js +5 -6
- package/lib/operations/command.js.map +1 -1
- package/lib/operations/common_functions.js.map +1 -1
- package/lib/operations/connect.js +4 -13
- package/lib/operations/connect.js.map +1 -1
- package/lib/operations/count.js +1 -1
- package/lib/operations/count.js.map +1 -1
- package/lib/operations/count_documents.js.map +1 -1
- package/lib/operations/create_collection.js +3 -2
- package/lib/operations/create_collection.js.map +1 -1
- package/lib/operations/delete.js +3 -3
- package/lib/operations/delete.js.map +1 -1
- package/lib/operations/distinct.js +3 -3
- package/lib/operations/distinct.js.map +1 -1
- package/lib/operations/drop.js +1 -1
- package/lib/operations/drop.js.map +1 -1
- package/lib/operations/estimated_document_count.js +2 -2
- package/lib/operations/estimated_document_count.js.map +1 -1
- package/lib/operations/eval.js +2 -2
- package/lib/operations/eval.js.map +1 -1
- package/lib/operations/execute_operation.js +5 -6
- package/lib/operations/execute_operation.js.map +1 -1
- package/lib/operations/find.js +5 -5
- package/lib/operations/find.js.map +1 -1
- package/lib/operations/find_and_modify.js +2 -2
- package/lib/operations/find_and_modify.js.map +1 -1
- package/lib/operations/get_more.js.map +1 -1
- package/lib/operations/indexes.js +4 -4
- package/lib/operations/indexes.js.map +1 -1
- package/lib/operations/insert.js +3 -3
- package/lib/operations/insert.js.map +1 -1
- package/lib/operations/is_capped.js +1 -1
- package/lib/operations/is_capped.js.map +1 -1
- package/lib/operations/list_collections.js +3 -3
- package/lib/operations/list_collections.js.map +1 -1
- package/lib/operations/list_databases.js +1 -1
- package/lib/operations/list_databases.js.map +1 -1
- package/lib/operations/map_reduce.js +4 -3
- package/lib/operations/map_reduce.js.map +1 -1
- package/lib/operations/operation.js +1 -1
- package/lib/operations/operation.js.map +1 -1
- package/lib/operations/options_operation.js +1 -1
- package/lib/operations/options_operation.js.map +1 -1
- package/lib/operations/profiling_level.js +1 -1
- package/lib/operations/profiling_level.js.map +1 -1
- package/lib/operations/remove_user.js +1 -1
- package/lib/operations/remove_user.js.map +1 -1
- package/lib/operations/rename.js +3 -3
- package/lib/operations/rename.js.map +1 -1
- package/lib/operations/run_command.js +1 -1
- package/lib/operations/run_command.js.map +1 -1
- package/lib/operations/set_profiling_level.js +2 -2
- package/lib/operations/set_profiling_level.js.map +1 -1
- package/lib/operations/stats.js +1 -1
- package/lib/operations/stats.js.map +1 -1
- package/lib/operations/update.js +2 -2
- package/lib/operations/update.js.map +1 -1
- package/lib/operations/validate_collection.js +1 -1
- package/lib/operations/validate_collection.js.map +1 -1
- package/lib/read_preference.js +15 -5
- package/lib/read_preference.js.map +1 -1
- package/lib/sdam/events.js +4 -4
- package/lib/sdam/monitor.js +19 -18
- package/lib/sdam/monitor.js.map +1 -1
- package/lib/sdam/server.js +24 -31
- package/lib/sdam/server.js.map +1 -1
- package/lib/sdam/server_description.js +38 -38
- package/lib/sdam/server_description.js.map +1 -1
- package/lib/sdam/server_selection.js +2 -2
- package/lib/sdam/server_selection.js.map +1 -1
- package/lib/sdam/srv_polling.js +2 -2
- package/lib/sdam/srv_polling.js.map +1 -1
- package/lib/sdam/topology.js +32 -62
- package/lib/sdam/topology.js.map +1 -1
- package/lib/sdam/topology_description.js +3 -3
- package/lib/sdam/topology_description.js.map +1 -1
- package/lib/sessions.js +13 -28
- package/lib/sessions.js.map +1 -1
- package/lib/transactions.js +1 -1
- package/lib/transactions.js.map +1 -1
- package/lib/utils.js +46 -15
- package/lib/utils.js.map +1 -1
- package/mongodb.d.ts +205 -60
- package/mongodb.ts34.d.ts +230 -59
- package/package.json +40 -37
- package/src/admin.ts +9 -9
- package/src/bson.ts +25 -17
- package/src/bulk/common.ts +22 -23
- package/src/bulk/ordered.ts +4 -4
- package/src/bulk/unordered.ts +5 -5
- package/src/change_stream.ts +29 -28
- package/src/cmap/auth/auth_provider.ts +3 -3
- package/src/cmap/auth/gssapi.ts +65 -14
- package/src/cmap/auth/mongo_credentials.ts +28 -17
- package/src/cmap/auth/mongocr.ts +3 -2
- package/src/cmap/auth/mongodb_aws.ts +10 -11
- package/src/cmap/auth/plain.ts +1 -1
- package/src/cmap/auth/providers.ts +21 -0
- package/src/cmap/auth/scram.ts +9 -9
- package/src/cmap/auth/x509.ts +3 -3
- package/src/cmap/command_monitoring_events.ts +4 -3
- package/src/cmap/commands.ts +22 -14
- package/src/cmap/connect.ts +161 -45
- package/src/cmap/connection.ts +83 -63
- package/src/cmap/connection_pool.ts +39 -39
- package/src/cmap/connection_pool_events.ts +1 -1
- package/src/cmap/message_stream.ts +9 -8
- package/src/cmap/stream_description.ts +5 -5
- package/src/cmap/wire_protocol/compression.ts +4 -3
- package/src/cmap/wire_protocol/shared.ts +10 -9
- package/src/collection.ts +116 -93
- package/src/connection_string.ts +130 -59
- package/src/constants.ts +122 -0
- package/src/cursor/abstract_cursor.ts +14 -13
- package/src/cursor/aggregation_cursor.ts +6 -6
- package/src/cursor/find_cursor.ts +12 -4
- package/src/db.ts +44 -33
- package/src/deps.ts +44 -1
- package/src/encrypter.ts +12 -3
- package/src/error.ts +52 -24
- package/src/gridfs/download.ts +10 -8
- package/src/gridfs/index.ts +11 -11
- package/src/gridfs/upload.ts +13 -10
- package/src/index.ts +205 -199
- package/src/logger.ts +2 -1
- package/src/mongo_client.ts +46 -32
- package/src/mongo_types.ts +119 -21
- package/src/operations/add_user.ts +7 -6
- package/src/operations/aggregate.ts +5 -5
- package/src/operations/bulk_write.ts +5 -5
- package/src/operations/collections.ts +2 -2
- package/src/operations/command.ts +15 -9
- package/src/operations/common_functions.ts +4 -4
- package/src/operations/connect.ts +4 -14
- package/src/operations/count.ts +4 -4
- package/src/operations/count_documents.ts +3 -3
- package/src/operations/create_collection.ts +7 -6
- package/src/operations/delete.ts +5 -5
- package/src/operations/distinct.ts +4 -4
- package/src/operations/drop.ts +4 -4
- package/src/operations/estimated_document_count.ts +5 -5
- package/src/operations/eval.ts +5 -5
- package/src/operations/execute_operation.ts +10 -11
- package/src/operations/find.ts +14 -14
- package/src/operations/find_and_modify.ts +7 -7
- package/src/operations/get_more.ts +2 -2
- package/src/operations/indexes.ts +16 -16
- package/src/operations/insert.ts +9 -9
- package/src/operations/is_capped.ts +3 -3
- package/src/operations/list_collections.ts +6 -6
- package/src/operations/list_databases.ts +4 -4
- package/src/operations/map_reduce.ts +10 -9
- package/src/operations/operation.ts +3 -3
- package/src/operations/options_operation.ts +3 -3
- package/src/operations/profiling_level.ts +4 -4
- package/src/operations/remove_user.ts +4 -4
- package/src/operations/rename.ts +6 -6
- package/src/operations/run_command.ts +3 -3
- package/src/operations/set_profiling_level.ts +6 -5
- package/src/operations/stats.ts +4 -4
- package/src/operations/update.ts +10 -10
- package/src/operations/validate_collection.ts +4 -4
- package/src/read_preference.ts +18 -7
- package/src/sdam/common.ts +2 -2
- package/src/sdam/events.ts +5 -5
- package/src/sdam/monitor.ts +29 -32
- package/src/sdam/server.ts +64 -62
- package/src/sdam/server_description.ts +41 -48
- package/src/sdam/server_selection.ts +3 -3
- package/src/sdam/srv_polling.ts +3 -2
- package/src/sdam/topology.ts +71 -89
- package/src/sdam/topology_description.ts +5 -5
- package/src/sessions.ts +31 -48
- package/src/transactions.ts +4 -4
- package/src/utils.ts +64 -28
- package/lib/cmap/auth/defaultAuthProviders.js +0 -30
- package/lib/cmap/auth/defaultAuthProviders.js.map +0 -1
- package/src/cmap/auth/defaultAuthProviders.ts +0 -32
|
@@ -1,22 +1,23 @@
|
|
|
1
1
|
// Resolves the default auth mechanism according to
|
|
2
|
-
|
|
3
2
|
import type { Document } from '../../bson';
|
|
4
3
|
import { MongoAPIError, MongoMissingCredentialsError } from '../../error';
|
|
5
|
-
import {
|
|
4
|
+
import { emitWarningOnce } from '../../utils';
|
|
5
|
+
import { GSSAPICanonicalizationValue } from './gssapi';
|
|
6
|
+
import { AUTH_MECHS_AUTH_SRC_EXTERNAL, AuthMechanism } from './providers';
|
|
6
7
|
|
|
7
8
|
// https://github.com/mongodb/specifications/blob/master/source/auth/auth.rst
|
|
8
|
-
function getDefaultAuthMechanism(
|
|
9
|
-
if (
|
|
10
|
-
// If
|
|
9
|
+
function getDefaultAuthMechanism(hello?: Document): AuthMechanism {
|
|
10
|
+
if (hello) {
|
|
11
|
+
// If hello contains saslSupportedMechs, use scram-sha-256
|
|
11
12
|
// if it is available, else scram-sha-1
|
|
12
|
-
if (Array.isArray(
|
|
13
|
-
return
|
|
13
|
+
if (Array.isArray(hello.saslSupportedMechs)) {
|
|
14
|
+
return hello.saslSupportedMechs.includes(AuthMechanism.MONGODB_SCRAM_SHA256)
|
|
14
15
|
? AuthMechanism.MONGODB_SCRAM_SHA256
|
|
15
16
|
: AuthMechanism.MONGODB_SCRAM_SHA1;
|
|
16
17
|
}
|
|
17
18
|
|
|
18
19
|
// Fallback to legacy selection method. If wire version >= 3, use scram-sha-1
|
|
19
|
-
if (
|
|
20
|
+
if (hello.maxWireVersion >= 3) {
|
|
20
21
|
return AuthMechanism.MONGODB_SCRAM_SHA1;
|
|
21
22
|
}
|
|
22
23
|
}
|
|
@@ -27,9 +28,10 @@ function getDefaultAuthMechanism(ismaster?: Document): AuthMechanism {
|
|
|
27
28
|
|
|
28
29
|
/** @public */
|
|
29
30
|
export interface AuthMechanismProperties extends Document {
|
|
31
|
+
SERVICE_HOST?: string;
|
|
30
32
|
SERVICE_NAME?: string;
|
|
31
33
|
SERVICE_REALM?: string;
|
|
32
|
-
CANONICALIZE_HOST_NAME?:
|
|
34
|
+
CANONICALIZE_HOST_NAME?: GSSAPICanonicalizationValue;
|
|
33
35
|
AWS_SESSION_TOKEN?: string;
|
|
34
36
|
}
|
|
35
37
|
|
|
@@ -89,6 +91,14 @@ export class MongoCredentials {
|
|
|
89
91
|
}
|
|
90
92
|
}
|
|
91
93
|
|
|
94
|
+
if ('gssapiCanonicalizeHostName' in this.mechanismProperties) {
|
|
95
|
+
emitWarningOnce(
|
|
96
|
+
'gssapiCanonicalizeHostName is deprecated. Please use CANONICALIZE_HOST_NAME instead.'
|
|
97
|
+
);
|
|
98
|
+
this.mechanismProperties.CANONICALIZE_HOST_NAME =
|
|
99
|
+
this.mechanismProperties.gssapiCanonicalizeHostName;
|
|
100
|
+
}
|
|
101
|
+
|
|
92
102
|
Object.freeze(this.mechanismProperties);
|
|
93
103
|
Object.freeze(this);
|
|
94
104
|
}
|
|
@@ -107,16 +117,16 @@ export class MongoCredentials {
|
|
|
107
117
|
* If the authentication mechanism is set to "default", resolves the authMechanism
|
|
108
118
|
* based on the server version and server supported sasl mechanisms.
|
|
109
119
|
*
|
|
110
|
-
* @param
|
|
120
|
+
* @param hello - A hello response from the server
|
|
111
121
|
*/
|
|
112
|
-
resolveAuthMechanism(
|
|
122
|
+
resolveAuthMechanism(hello?: Document): MongoCredentials {
|
|
113
123
|
// If the mechanism is not "default", then it does not need to be resolved
|
|
114
124
|
if (this.mechanism.match(/DEFAULT/i)) {
|
|
115
125
|
return new MongoCredentials({
|
|
116
126
|
username: this.username,
|
|
117
127
|
password: this.password,
|
|
118
128
|
source: this.source,
|
|
119
|
-
mechanism: getDefaultAuthMechanism(
|
|
129
|
+
mechanism: getDefaultAuthMechanism(hello),
|
|
120
130
|
mechanismProperties: this.mechanismProperties
|
|
121
131
|
});
|
|
122
132
|
}
|
|
@@ -136,11 +146,7 @@ export class MongoCredentials {
|
|
|
136
146
|
throw new MongoMissingCredentialsError(`Username required for mechanism '${this.mechanism}'`);
|
|
137
147
|
}
|
|
138
148
|
|
|
139
|
-
if (
|
|
140
|
-
this.mechanism === AuthMechanism.MONGODB_GSSAPI ||
|
|
141
|
-
this.mechanism === AuthMechanism.MONGODB_AWS ||
|
|
142
|
-
this.mechanism === AuthMechanism.MONGODB_X509
|
|
143
|
-
) {
|
|
149
|
+
if (AUTH_MECHS_AUTH_SRC_EXTERNAL.has(this.mechanism)) {
|
|
144
150
|
if (this.source != null && this.source !== '$external') {
|
|
145
151
|
// TODO(NODE-3485): Replace this with a MongoAuthValidationError
|
|
146
152
|
throw new MongoAPIError(
|
|
@@ -162,6 +168,11 @@ export class MongoCredentials {
|
|
|
162
168
|
// TODO(NODE-3485): Replace this with a MongoAuthValidationError
|
|
163
169
|
throw new MongoAPIError(`Password not allowed for mechanism MONGODB-X509`);
|
|
164
170
|
}
|
|
171
|
+
|
|
172
|
+
const canonicalization = this.mechanismProperties.CANONICALIZE_HOST_NAME ?? false;
|
|
173
|
+
if (!Object.values(GSSAPICanonicalizationValue).includes(canonicalization)) {
|
|
174
|
+
throw new MongoAPIError(`Invalid CANONICALIZE_HOST_NAME value: ${canonicalization}`);
|
|
175
|
+
}
|
|
165
176
|
}
|
|
166
177
|
|
|
167
178
|
static merge(
|
package/src/cmap/auth/mongocr.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import * as crypto from 'crypto';
|
|
2
|
-
|
|
3
|
-
import { Callback, ns } from '../../utils';
|
|
2
|
+
|
|
4
3
|
import { MongoMissingCredentialsError } from '../../error';
|
|
4
|
+
import { Callback, ns } from '../../utils';
|
|
5
|
+
import { AuthContext, AuthProvider } from './auth_provider';
|
|
5
6
|
|
|
6
7
|
export class MongoCR extends AuthProvider {
|
|
7
8
|
auth(authContext: AuthContext, callback: Callback): void {
|
|
@@ -1,20 +1,19 @@
|
|
|
1
|
-
import * as http from 'http';
|
|
2
1
|
import * as crypto from 'crypto';
|
|
2
|
+
import * as http from 'http';
|
|
3
3
|
import * as url from 'url';
|
|
4
|
+
|
|
5
|
+
import type { Binary, BSONSerializeOptions } from '../../bson';
|
|
4
6
|
import * as BSON from '../../bson';
|
|
5
|
-
import {
|
|
6
|
-
import { MongoCredentials } from './mongo_credentials';
|
|
7
|
+
import { aws4 } from '../../deps';
|
|
7
8
|
import {
|
|
8
|
-
|
|
9
|
+
MongoCompatibilityError,
|
|
9
10
|
MongoMissingCredentialsError,
|
|
10
|
-
|
|
11
|
+
MongoRuntimeError
|
|
11
12
|
} from '../../error';
|
|
12
|
-
import {
|
|
13
|
-
import
|
|
14
|
-
|
|
15
|
-
import {
|
|
16
|
-
import { AuthMechanism } from './defaultAuthProviders';
|
|
17
|
-
import type { Binary } from 'bson';
|
|
13
|
+
import { Callback, maxWireVersion, ns } from '../../utils';
|
|
14
|
+
import { AuthContext, AuthProvider } from './auth_provider';
|
|
15
|
+
import { MongoCredentials } from './mongo_credentials';
|
|
16
|
+
import { AuthMechanism } from './providers';
|
|
18
17
|
|
|
19
18
|
const ASCII_N = 110;
|
|
20
19
|
const AWS_RELATIVE_URI = 'http://169.254.170.2';
|
package/src/cmap/auth/plain.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Binary } from '../../bson';
|
|
2
|
-
import { AuthProvider, AuthContext } from './auth_provider';
|
|
3
2
|
import { MongoMissingCredentialsError } from '../../error';
|
|
4
3
|
import { Callback, ns } from '../../utils';
|
|
4
|
+
import { AuthContext, AuthProvider } from './auth_provider';
|
|
5
5
|
|
|
6
6
|
export class Plain extends AuthProvider {
|
|
7
7
|
auth(authContext: AuthContext, callback: Callback): void {
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/** @public */
|
|
2
|
+
export const AuthMechanism = Object.freeze({
|
|
3
|
+
MONGODB_AWS: 'MONGODB-AWS',
|
|
4
|
+
MONGODB_CR: 'MONGODB-CR',
|
|
5
|
+
MONGODB_DEFAULT: 'DEFAULT',
|
|
6
|
+
MONGODB_GSSAPI: 'GSSAPI',
|
|
7
|
+
MONGODB_PLAIN: 'PLAIN',
|
|
8
|
+
MONGODB_SCRAM_SHA1: 'SCRAM-SHA-1',
|
|
9
|
+
MONGODB_SCRAM_SHA256: 'SCRAM-SHA-256',
|
|
10
|
+
MONGODB_X509: 'MONGODB-X509'
|
|
11
|
+
} as const);
|
|
12
|
+
|
|
13
|
+
/** @public */
|
|
14
|
+
export type AuthMechanism = typeof AuthMechanism[keyof typeof AuthMechanism];
|
|
15
|
+
|
|
16
|
+
/** @internal */
|
|
17
|
+
export const AUTH_MECHS_AUTH_SRC_EXTERNAL = new Set<AuthMechanism>([
|
|
18
|
+
AuthMechanism.MONGODB_GSSAPI,
|
|
19
|
+
AuthMechanism.MONGODB_AWS,
|
|
20
|
+
AuthMechanism.MONGODB_X509
|
|
21
|
+
]);
|
package/src/cmap/auth/scram.ts
CHANGED
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
import * as crypto from 'crypto';
|
|
2
|
+
|
|
2
3
|
import { Binary, Document } from '../../bson';
|
|
4
|
+
import { saslprep } from '../../deps';
|
|
3
5
|
import {
|
|
4
6
|
AnyError,
|
|
5
|
-
MongoRuntimeError,
|
|
6
|
-
MongoServerError,
|
|
7
7
|
MongoInvalidArgumentError,
|
|
8
|
-
MongoMissingCredentialsError
|
|
8
|
+
MongoMissingCredentialsError,
|
|
9
|
+
MongoRuntimeError,
|
|
10
|
+
MongoServerError
|
|
9
11
|
} from '../../error';
|
|
10
|
-
import {
|
|
11
|
-
import { Callback, ns, emitWarning } from '../../utils';
|
|
12
|
-
import type { MongoCredentials } from './mongo_credentials';
|
|
12
|
+
import { Callback, emitWarning, ns } from '../../utils';
|
|
13
13
|
import type { HandshakeDocument } from '../connect';
|
|
14
|
-
|
|
15
|
-
import {
|
|
16
|
-
import { AuthMechanism } from './
|
|
14
|
+
import { AuthContext, AuthProvider } from './auth_provider';
|
|
15
|
+
import type { MongoCredentials } from './mongo_credentials';
|
|
16
|
+
import { AuthMechanism } from './providers';
|
|
17
17
|
|
|
18
18
|
type CryptoMethod = 'sha1' | 'sha256';
|
|
19
19
|
|
package/src/cmap/auth/x509.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { AuthProvider, AuthContext } from './auth_provider';
|
|
2
|
-
import { MongoMissingCredentialsError } from '../../error';
|
|
3
1
|
import type { Document } from '../../bson';
|
|
2
|
+
import { MongoMissingCredentialsError } from '../../error';
|
|
4
3
|
import { Callback, ns } from '../../utils';
|
|
5
|
-
import type { MongoCredentials } from './mongo_credentials';
|
|
6
4
|
import type { HandshakeDocument } from '../connect';
|
|
5
|
+
import { AuthContext, AuthProvider } from './auth_provider';
|
|
6
|
+
import type { MongoCredentials } from './mongo_credentials';
|
|
7
7
|
|
|
8
8
|
export class X509 extends AuthProvider {
|
|
9
9
|
prepare(handshakeDoc: HandshakeDocument, authContext: AuthContext, callback: Callback): void {
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { Document, ObjectId } from '../bson';
|
|
2
|
+
import { LEGACY_HELLO_COMMAND, LEGACY_HELLO_COMMAND_CAMEL_CASE } from '../constants';
|
|
2
3
|
import { calculateDurationInMs, deepCopy } from '../utils';
|
|
4
|
+
import { GetMore, KillCursor, Msg, WriteProtocolMessageType } from './commands';
|
|
3
5
|
import type { Connection } from './connection';
|
|
4
|
-
import type { Document, ObjectId } from '../bson';
|
|
5
6
|
|
|
6
7
|
/**
|
|
7
8
|
* An event indicating the start of a given
|
|
@@ -161,7 +162,7 @@ const SENSITIVE_COMMANDS = new Set([
|
|
|
161
162
|
'copydb'
|
|
162
163
|
]);
|
|
163
164
|
|
|
164
|
-
const HELLO_COMMANDS = new Set(['hello',
|
|
165
|
+
const HELLO_COMMANDS = new Set(['hello', LEGACY_HELLO_COMMAND, LEGACY_HELLO_COMMAND_CAMEL_CASE]);
|
|
165
166
|
|
|
166
167
|
// helper methods
|
|
167
168
|
const extractCommandName = (commandDoc: Document) => Object.keys(commandDoc)[0];
|
package/src/cmap/commands.ts
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { BSONSerializeOptions, Document, Long } from '../bson';
|
|
2
2
|
import * as BSON from '../bson';
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import type { Long, Document, BSONSerializeOptions } from '../bson';
|
|
3
|
+
import { MongoInvalidArgumentError, MongoRuntimeError } from '../error';
|
|
4
|
+
import { ReadPreference } from '../read_preference';
|
|
6
5
|
import type { ClientSession } from '../sessions';
|
|
6
|
+
import { databaseNamespace } from '../utils';
|
|
7
7
|
import type { CommandOptions } from './connection';
|
|
8
|
-
import {
|
|
8
|
+
import { OP_GETMORE, OP_KILL_CURSORS, OP_MSG, OP_QUERY } from './wire_protocol/constants';
|
|
9
9
|
|
|
10
10
|
// Incrementing request id
|
|
11
11
|
let _requestId = 0;
|
|
12
12
|
|
|
13
13
|
// Query flags
|
|
14
14
|
const OPTS_TAILABLE_CURSOR = 2;
|
|
15
|
-
const
|
|
15
|
+
const OPTS_SECONDARY = 4;
|
|
16
16
|
const OPTS_OPLOG_REPLAY = 8;
|
|
17
17
|
const OPTS_NO_CURSOR_TIMEOUT = 16;
|
|
18
18
|
const OPTS_AWAIT_DATA = 32;
|
|
@@ -41,7 +41,7 @@ export interface OpQueryOptions extends CommandOptions {
|
|
|
41
41
|
ignoreUndefined?: boolean;
|
|
42
42
|
maxBsonSize?: number;
|
|
43
43
|
checkKeys?: boolean;
|
|
44
|
-
|
|
44
|
+
secondaryOk?: boolean;
|
|
45
45
|
|
|
46
46
|
requestId?: number;
|
|
47
47
|
moreToCome?: boolean;
|
|
@@ -67,7 +67,7 @@ export class Query {
|
|
|
67
67
|
checkKeys: boolean;
|
|
68
68
|
batchSize: number;
|
|
69
69
|
tailable: boolean;
|
|
70
|
-
|
|
70
|
+
secondaryOk: boolean;
|
|
71
71
|
oplogReplay: boolean;
|
|
72
72
|
noCursorTimeout: boolean;
|
|
73
73
|
awaitData: boolean;
|
|
@@ -112,7 +112,7 @@ export class Query {
|
|
|
112
112
|
|
|
113
113
|
// Flags
|
|
114
114
|
this.tailable = false;
|
|
115
|
-
this.
|
|
115
|
+
this.secondaryOk = typeof options.secondaryOk === 'boolean' ? options.secondaryOk : false;
|
|
116
116
|
this.oplogReplay = false;
|
|
117
117
|
this.noCursorTimeout = false;
|
|
118
118
|
this.awaitData = false;
|
|
@@ -146,8 +146,8 @@ export class Query {
|
|
|
146
146
|
flags |= OPTS_TAILABLE_CURSOR;
|
|
147
147
|
}
|
|
148
148
|
|
|
149
|
-
if (this.
|
|
150
|
-
flags |=
|
|
149
|
+
if (this.secondaryOk) {
|
|
150
|
+
flags |= OPTS_SECONDARY;
|
|
151
151
|
}
|
|
152
152
|
|
|
153
153
|
if (this.oplogReplay) {
|
|
@@ -469,8 +469,6 @@ export interface MessageHeader {
|
|
|
469
469
|
export interface OpResponseOptions extends BSONSerializeOptions {
|
|
470
470
|
raw?: boolean;
|
|
471
471
|
documentsReturnedIn?: string | null;
|
|
472
|
-
// For now we use this internally to only prevent writeErrors from crashing the driver
|
|
473
|
-
validation?: { utf8: { writeErrors: boolean } };
|
|
474
472
|
}
|
|
475
473
|
|
|
476
474
|
/** @internal */
|
|
@@ -839,7 +837,7 @@ export class BinMsg {
|
|
|
839
837
|
const promoteValues = options.promoteValues ?? this.opts.promoteValues;
|
|
840
838
|
const promoteBuffers = options.promoteBuffers ?? this.opts.promoteBuffers;
|
|
841
839
|
const bsonRegExp = options.bsonRegExp ?? this.opts.bsonRegExp;
|
|
842
|
-
const validation = options
|
|
840
|
+
const validation = this.parseBsonSerializationOptions(options);
|
|
843
841
|
|
|
844
842
|
// Set up the options
|
|
845
843
|
const bsonOptions: BSONSerializeOptions = {
|
|
@@ -876,4 +874,14 @@ export class BinMsg {
|
|
|
876
874
|
|
|
877
875
|
this.parsed = true;
|
|
878
876
|
}
|
|
877
|
+
|
|
878
|
+
parseBsonSerializationOptions({ enableUtf8Validation }: BSONSerializeOptions): {
|
|
879
|
+
utf8: { writeErrors: false } | false;
|
|
880
|
+
} {
|
|
881
|
+
if (enableUtf8Validation === false) {
|
|
882
|
+
return { utf8: false };
|
|
883
|
+
}
|
|
884
|
+
|
|
885
|
+
return { utf8: { writeErrors: false } };
|
|
886
|
+
}
|
|
879
887
|
}
|
package/src/cmap/connect.ts
CHANGED
|
@@ -1,39 +1,60 @@
|
|
|
1
|
+
import type { Socket, SocketConnectOpts } from 'net';
|
|
1
2
|
import * as net from 'net';
|
|
3
|
+
import { SocksClient } from 'socks';
|
|
4
|
+
import type { ConnectionOptions as TLSConnectionOpts, TLSSocket } from 'tls';
|
|
2
5
|
import * as tls from 'tls';
|
|
3
|
-
|
|
6
|
+
|
|
7
|
+
import type { Document } from '../bson';
|
|
8
|
+
import { Int32 } from '../bson';
|
|
9
|
+
import { LEGACY_HELLO_COMMAND } from '../constants';
|
|
4
10
|
import {
|
|
5
|
-
MongoNetworkError,
|
|
6
|
-
MongoNetworkTimeoutError,
|
|
7
11
|
AnyError,
|
|
8
12
|
MongoCompatibilityError,
|
|
9
13
|
MongoInvalidArgumentError,
|
|
10
|
-
|
|
11
|
-
|
|
14
|
+
MongoNetworkError,
|
|
15
|
+
MongoNetworkTimeoutError,
|
|
16
|
+
MongoRuntimeError,
|
|
17
|
+
MongoServerError
|
|
12
18
|
} from '../error';
|
|
13
|
-
import { AUTH_PROVIDERS, AuthMechanism } from './auth/defaultAuthProviders';
|
|
14
|
-
import { AuthContext } from './auth/auth_provider';
|
|
15
|
-
import { makeClientMetadata, ClientMetadata, Callback, CallbackWithType, ns } from '../utils';
|
|
16
19
|
import {
|
|
17
|
-
|
|
20
|
+
Callback,
|
|
21
|
+
CallbackWithType,
|
|
22
|
+
ClientMetadata,
|
|
23
|
+
HostAddress,
|
|
24
|
+
makeClientMetadata,
|
|
25
|
+
ns
|
|
26
|
+
} from '../utils';
|
|
27
|
+
import { AuthContext, AuthProvider } from './auth/auth_provider';
|
|
28
|
+
import { GSSAPI } from './auth/gssapi';
|
|
29
|
+
import { MongoCR } from './auth/mongocr';
|
|
30
|
+
import { MongoDBAWS } from './auth/mongodb_aws';
|
|
31
|
+
import { Plain } from './auth/plain';
|
|
32
|
+
import { AuthMechanism } from './auth/providers';
|
|
33
|
+
import { ScramSHA1, ScramSHA256 } from './auth/scram';
|
|
34
|
+
import { X509 } from './auth/x509';
|
|
35
|
+
import { Connection, ConnectionOptions, CryptoConnection } from './connection';
|
|
36
|
+
import {
|
|
18
37
|
MAX_SUPPORTED_SERVER_VERSION,
|
|
19
|
-
|
|
20
|
-
MIN_SUPPORTED_SERVER_VERSION
|
|
38
|
+
MAX_SUPPORTED_WIRE_VERSION,
|
|
39
|
+
MIN_SUPPORTED_SERVER_VERSION,
|
|
40
|
+
MIN_SUPPORTED_WIRE_VERSION
|
|
21
41
|
} from './wire_protocol/constants';
|
|
22
|
-
import type { Document } from '../bson';
|
|
23
|
-
import { Int32 } from '../bson';
|
|
24
42
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
43
|
+
const AUTH_PROVIDERS = new Map<AuthMechanism | string, AuthProvider>([
|
|
44
|
+
[AuthMechanism.MONGODB_AWS, new MongoDBAWS()],
|
|
45
|
+
[AuthMechanism.MONGODB_CR, new MongoCR()],
|
|
46
|
+
[AuthMechanism.MONGODB_GSSAPI, new GSSAPI()],
|
|
47
|
+
[AuthMechanism.MONGODB_PLAIN, new Plain()],
|
|
48
|
+
[AuthMechanism.MONGODB_SCRAM_SHA1, new ScramSHA1()],
|
|
49
|
+
[AuthMechanism.MONGODB_SCRAM_SHA256, new ScramSHA256()],
|
|
50
|
+
[AuthMechanism.MONGODB_X509, new X509()]
|
|
51
|
+
]);
|
|
31
52
|
|
|
32
53
|
/** @public */
|
|
33
54
|
export type Stream = Socket | TLSSocket;
|
|
34
55
|
|
|
35
56
|
export function connect(options: ConnectionOptions, callback: Callback<Connection>): void {
|
|
36
|
-
makeConnection(options, (err, socket) => {
|
|
57
|
+
makeConnection({ ...options, existingSocket: undefined }, (err, socket) => {
|
|
37
58
|
if (err || !socket) {
|
|
38
59
|
return callback(err);
|
|
39
60
|
}
|
|
@@ -46,15 +67,15 @@ export function connect(options: ConnectionOptions, callback: Callback<Connectio
|
|
|
46
67
|
});
|
|
47
68
|
}
|
|
48
69
|
|
|
49
|
-
function checkSupportedServer(
|
|
70
|
+
function checkSupportedServer(hello: Document, options: ConnectionOptions) {
|
|
50
71
|
const serverVersionHighEnough =
|
|
51
|
-
|
|
52
|
-
(typeof
|
|
53
|
-
|
|
72
|
+
hello &&
|
|
73
|
+
(typeof hello.maxWireVersion === 'number' || hello.maxWireVersion instanceof Int32) &&
|
|
74
|
+
hello.maxWireVersion >= MIN_SUPPORTED_WIRE_VERSION;
|
|
54
75
|
const serverVersionLowEnough =
|
|
55
|
-
|
|
56
|
-
(typeof
|
|
57
|
-
|
|
76
|
+
hello &&
|
|
77
|
+
(typeof hello.minWireVersion === 'number' || hello.minWireVersion instanceof Int32) &&
|
|
78
|
+
hello.minWireVersion <= MAX_SUPPORTED_WIRE_VERSION;
|
|
58
79
|
|
|
59
80
|
if (serverVersionHighEnough) {
|
|
60
81
|
if (serverVersionLowEnough) {
|
|
@@ -62,13 +83,13 @@ function checkSupportedServer(ismaster: Document, options: ConnectionOptions) {
|
|
|
62
83
|
}
|
|
63
84
|
|
|
64
85
|
const message = `Server at ${options.hostAddress} reports minimum wire version ${JSON.stringify(
|
|
65
|
-
|
|
86
|
+
hello.minWireVersion
|
|
66
87
|
)}, but this version of the Node.js Driver requires at most ${MAX_SUPPORTED_WIRE_VERSION} (MongoDB ${MAX_SUPPORTED_SERVER_VERSION})`;
|
|
67
88
|
return new MongoCompatibilityError(message);
|
|
68
89
|
}
|
|
69
90
|
|
|
70
91
|
const message = `Server at ${options.hostAddress} reports maximum wire version ${
|
|
71
|
-
JSON.stringify(
|
|
92
|
+
JSON.stringify(hello.maxWireVersion) ?? 0
|
|
72
93
|
}, but this version of the Node.js Driver requires at least ${MIN_SUPPORTED_WIRE_VERSION} (MongoDB ${MIN_SUPPORTED_SERVER_VERSION})`;
|
|
73
94
|
return new MongoCompatibilityError(message);
|
|
74
95
|
}
|
|
@@ -122,9 +143,9 @@ function performInitialHandshake(
|
|
|
122
143
|
return;
|
|
123
144
|
}
|
|
124
145
|
|
|
125
|
-
if ('isWritablePrimary' in response) {
|
|
126
|
-
// Provide
|
|
127
|
-
response.
|
|
146
|
+
if (!('isWritablePrimary' in response)) {
|
|
147
|
+
// Provide hello-style response document.
|
|
148
|
+
response.isWritablePrimary = response[LEGACY_HELLO_COMMAND];
|
|
128
149
|
}
|
|
129
150
|
|
|
130
151
|
if (response.helloOk) {
|
|
@@ -138,10 +159,6 @@ function performInitialHandshake(
|
|
|
138
159
|
}
|
|
139
160
|
|
|
140
161
|
if (options.loadBalanced) {
|
|
141
|
-
// TODO: Durran: Remove when server support exists. (NODE-3431)
|
|
142
|
-
if (FAKE_MONGODB_SERVICE_ID) {
|
|
143
|
-
response.serviceId = response.topologyVersion.processId;
|
|
144
|
-
}
|
|
145
162
|
if (!response.serviceId) {
|
|
146
163
|
return callback(
|
|
147
164
|
new MongoCompatibilityError(
|
|
@@ -155,8 +172,8 @@ function performInitialHandshake(
|
|
|
155
172
|
// NOTE: This is metadata attached to the connection while porting away from
|
|
156
173
|
// handshake being done in the `Server` class. Likely, it should be
|
|
157
174
|
// relocated, or at very least restructured.
|
|
158
|
-
conn.
|
|
159
|
-
conn.
|
|
175
|
+
conn.hello = response;
|
|
176
|
+
conn.lastHelloMS = new Date().getTime() - start;
|
|
160
177
|
|
|
161
178
|
if (!response.arbiterOnly && credentials) {
|
|
162
179
|
// store the response on auth context
|
|
@@ -185,6 +202,9 @@ function performInitialHandshake(
|
|
|
185
202
|
}
|
|
186
203
|
|
|
187
204
|
export interface HandshakeDocument extends Document {
|
|
205
|
+
/**
|
|
206
|
+
* @deprecated Use hello instead
|
|
207
|
+
*/
|
|
188
208
|
ismaster?: boolean;
|
|
189
209
|
hello?: boolean;
|
|
190
210
|
helloOk?: boolean;
|
|
@@ -200,7 +220,7 @@ function prepareHandshakeDocument(authContext: AuthContext, callback: Callback<H
|
|
|
200
220
|
const { serverApi } = authContext.connection;
|
|
201
221
|
|
|
202
222
|
const handshakeDoc: HandshakeDocument = {
|
|
203
|
-
[serverApi?.version ? 'hello' :
|
|
223
|
+
[serverApi?.version ? 'hello' : LEGACY_HELLO_COMMAND]: true,
|
|
204
224
|
helloOk: true,
|
|
205
225
|
client: options.metadata || makeClientMetadata(options),
|
|
206
226
|
compression: compressors,
|
|
@@ -289,7 +309,9 @@ function parseConnectOptions(options: ConnectionOptions): SocketConnectOpts {
|
|
|
289
309
|
}
|
|
290
310
|
}
|
|
291
311
|
|
|
292
|
-
|
|
312
|
+
type MakeConnectionOptions = ConnectionOptions & { existingSocket?: Stream };
|
|
313
|
+
|
|
314
|
+
function parseSslOptions(options: MakeConnectionOptions): TLSConnectionOpts {
|
|
293
315
|
const result: TLSConnectionOpts = parseConnectOptions(options);
|
|
294
316
|
// Merge in valid SSL options
|
|
295
317
|
for (const name of LEGAL_TLS_SOCKET_OPTIONS) {
|
|
@@ -298,6 +320,10 @@ function parseSslOptions(options: ConnectionOptions): TLSConnectionOpts {
|
|
|
298
320
|
}
|
|
299
321
|
}
|
|
300
322
|
|
|
323
|
+
if (options.existingSocket) {
|
|
324
|
+
result.socket = options.existingSocket;
|
|
325
|
+
}
|
|
326
|
+
|
|
301
327
|
// Set default sni servername to be the same as host
|
|
302
328
|
if (result.servername == null && result.host && !net.isIP(result.host)) {
|
|
303
329
|
result.servername = result.host;
|
|
@@ -310,17 +336,21 @@ const SOCKET_ERROR_EVENT_LIST = ['error', 'close', 'timeout', 'parseError'] as c
|
|
|
310
336
|
type ErrorHandlerEventName = typeof SOCKET_ERROR_EVENT_LIST[number] | 'cancel';
|
|
311
337
|
const SOCKET_ERROR_EVENTS = new Set(SOCKET_ERROR_EVENT_LIST);
|
|
312
338
|
|
|
313
|
-
function makeConnection(
|
|
339
|
+
function makeConnection(
|
|
340
|
+
options: MakeConnectionOptions,
|
|
341
|
+
_callback: CallbackWithType<AnyError, Stream>
|
|
342
|
+
) {
|
|
314
343
|
const useTLS = options.tls ?? false;
|
|
315
344
|
const keepAlive = options.keepAlive ?? true;
|
|
316
345
|
const socketTimeoutMS = options.socketTimeoutMS ?? Reflect.get(options, 'socketTimeout') ?? 0;
|
|
317
346
|
const noDelay = options.noDelay ?? true;
|
|
318
|
-
const
|
|
347
|
+
const connectTimeoutMS = options.connectTimeoutMS ?? 30000;
|
|
319
348
|
const rejectUnauthorized = options.rejectUnauthorized ?? true;
|
|
320
349
|
const keepAliveInitialDelay =
|
|
321
350
|
((options.keepAliveInitialDelay ?? 120000) > socketTimeoutMS
|
|
322
351
|
? Math.round(socketTimeoutMS / 2)
|
|
323
352
|
: options.keepAliveInitialDelay) ?? 120000;
|
|
353
|
+
const existingSocket = options.existingSocket;
|
|
324
354
|
|
|
325
355
|
let socket: Stream;
|
|
326
356
|
const callback: Callback<Stream> = function (err, ret) {
|
|
@@ -331,18 +361,34 @@ function makeConnection(options: ConnectionOptions, _callback: CallbackWithType<
|
|
|
331
361
|
_callback(err, ret);
|
|
332
362
|
};
|
|
333
363
|
|
|
364
|
+
if (options.proxyHost != null) {
|
|
365
|
+
// Currently, only Socks5 is supported.
|
|
366
|
+
return makeSocks5Connection(
|
|
367
|
+
{
|
|
368
|
+
...options,
|
|
369
|
+
connectTimeoutMS // Should always be present for Socks5
|
|
370
|
+
},
|
|
371
|
+
callback
|
|
372
|
+
);
|
|
373
|
+
}
|
|
374
|
+
|
|
334
375
|
if (useTLS) {
|
|
335
376
|
const tlsSocket = tls.connect(parseSslOptions(options));
|
|
336
377
|
if (typeof tlsSocket.disableRenegotiation === 'function') {
|
|
337
378
|
tlsSocket.disableRenegotiation();
|
|
338
379
|
}
|
|
339
380
|
socket = tlsSocket;
|
|
381
|
+
} else if (existingSocket) {
|
|
382
|
+
// In the TLS case, parseSslOptions() sets options.socket to existingSocket,
|
|
383
|
+
// so we only need to handle the non-TLS case here (where existingSocket
|
|
384
|
+
// gives us all we need out of the box).
|
|
385
|
+
socket = existingSocket;
|
|
340
386
|
} else {
|
|
341
387
|
socket = net.createConnection(parseConnectOptions(options));
|
|
342
388
|
}
|
|
343
389
|
|
|
344
390
|
socket.setKeepAlive(keepAlive, keepAliveInitialDelay);
|
|
345
|
-
socket.setTimeout(
|
|
391
|
+
socket.setTimeout(connectTimeoutMS);
|
|
346
392
|
socket.setNoDelay(noDelay);
|
|
347
393
|
|
|
348
394
|
const connectEvent = useTLS ? 'secureConnect' : 'connect';
|
|
@@ -381,10 +427,80 @@ function makeConnection(options: ConnectionOptions, _callback: CallbackWithType<
|
|
|
381
427
|
options.cancellationToken.once('cancel', cancellationHandler);
|
|
382
428
|
}
|
|
383
429
|
|
|
384
|
-
|
|
430
|
+
if (existingSocket) {
|
|
431
|
+
process.nextTick(connectHandler);
|
|
432
|
+
} else {
|
|
433
|
+
socket.once(connectEvent, connectHandler);
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
function makeSocks5Connection(options: MakeConnectionOptions, callback: Callback<Stream>) {
|
|
438
|
+
const hostAddress = HostAddress.fromHostPort(
|
|
439
|
+
options.proxyHost ?? '', // proxyHost is guaranteed to set here
|
|
440
|
+
options.proxyPort ?? 1080
|
|
441
|
+
);
|
|
442
|
+
|
|
443
|
+
// First, connect to the proxy server itself:
|
|
444
|
+
makeConnection(
|
|
445
|
+
{
|
|
446
|
+
...options,
|
|
447
|
+
hostAddress,
|
|
448
|
+
tls: false,
|
|
449
|
+
proxyHost: undefined
|
|
450
|
+
},
|
|
451
|
+
(err, rawSocket) => {
|
|
452
|
+
if (err) {
|
|
453
|
+
return callback(err);
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
const destination = parseConnectOptions(options) as net.TcpNetConnectOpts;
|
|
457
|
+
if (typeof destination.host !== 'string' || typeof destination.port !== 'number') {
|
|
458
|
+
return callback(
|
|
459
|
+
new MongoInvalidArgumentError('Can only make Socks5 connections to TCP hosts')
|
|
460
|
+
);
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
// Then, establish the Socks5 proxy connection:
|
|
464
|
+
SocksClient.createConnection(
|
|
465
|
+
{
|
|
466
|
+
existing_socket: rawSocket,
|
|
467
|
+
timeout: options.connectTimeoutMS,
|
|
468
|
+
command: 'connect',
|
|
469
|
+
destination: {
|
|
470
|
+
host: destination.host,
|
|
471
|
+
port: destination.port
|
|
472
|
+
},
|
|
473
|
+
proxy: {
|
|
474
|
+
// host and port are ignored because we pass existing_socket
|
|
475
|
+
host: 'iLoveJavaScript',
|
|
476
|
+
port: 0,
|
|
477
|
+
type: 5,
|
|
478
|
+
userId: options.proxyUsername || undefined,
|
|
479
|
+
password: options.proxyPassword || undefined
|
|
480
|
+
}
|
|
481
|
+
},
|
|
482
|
+
(err: AnyError, info: { socket: Stream }) => {
|
|
483
|
+
if (err) {
|
|
484
|
+
return callback(connectionFailureError('error', err));
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
// Finally, now treat the resulting duplex stream as the
|
|
488
|
+
// socket over which we send and receive wire protocol messages:
|
|
489
|
+
makeConnection(
|
|
490
|
+
{
|
|
491
|
+
...options,
|
|
492
|
+
existingSocket: info.socket,
|
|
493
|
+
proxyHost: undefined
|
|
494
|
+
},
|
|
495
|
+
callback
|
|
496
|
+
);
|
|
497
|
+
}
|
|
498
|
+
);
|
|
499
|
+
}
|
|
500
|
+
);
|
|
385
501
|
}
|
|
386
502
|
|
|
387
|
-
function connectionFailureError(type:
|
|
503
|
+
function connectionFailureError(type: ErrorHandlerEventName, err: Error) {
|
|
388
504
|
switch (type) {
|
|
389
505
|
case 'error':
|
|
390
506
|
return new MongoNetworkError(err);
|