mongodb 5.1.0 → 5.3.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 +25 -22
- package/lib/admin.js +2 -0
- package/lib/admin.js.map +1 -1
- package/lib/bulk/common.js +28 -7
- package/lib/bulk/common.js.map +1 -1
- package/lib/change_stream.js +1 -1
- package/lib/cmap/auth/auth_provider.js +21 -10
- package/lib/cmap/auth/auth_provider.js.map +1 -1
- package/lib/cmap/auth/gssapi.js +71 -116
- package/lib/cmap/auth/gssapi.js.map +1 -1
- package/lib/cmap/auth/mongo_credentials.js +7 -9
- package/lib/cmap/auth/mongo_credentials.js.map +1 -1
- package/lib/cmap/auth/mongocr.js +20 -29
- package/lib/cmap/auth/mongocr.js.map +1 -1
- package/lib/cmap/auth/mongodb_aws.js +125 -140
- package/lib/cmap/auth/mongodb_aws.js.map +1 -1
- package/lib/cmap/auth/mongodb_oidc/aws_service_workflow.js +28 -0
- package/lib/cmap/auth/mongodb_oidc/aws_service_workflow.js.map +1 -0
- package/lib/cmap/auth/mongodb_oidc/callback_workflow.js +178 -0
- package/lib/cmap/auth/mongodb_oidc/callback_workflow.js.map +1 -0
- package/lib/cmap/auth/mongodb_oidc/service_workflow.js +41 -0
- package/lib/cmap/auth/mongodb_oidc/service_workflow.js.map +1 -0
- package/lib/cmap/auth/mongodb_oidc/token_entry_cache.js +115 -0
- package/lib/cmap/auth/mongodb_oidc/token_entry_cache.js.map +1 -0
- package/lib/cmap/auth/mongodb_oidc/workflow.js +3 -0
- package/lib/cmap/auth/mongodb_oidc/workflow.js.map +1 -0
- package/lib/cmap/auth/mongodb_oidc.js +59 -0
- package/lib/cmap/auth/mongodb_oidc.js.map +1 -1
- package/lib/cmap/auth/plain.js +4 -5
- package/lib/cmap/auth/plain.js.map +1 -1
- package/lib/cmap/auth/providers.js +1 -1
- package/lib/cmap/auth/providers.js.map +1 -1
- package/lib/cmap/auth/scram.js +45 -73
- package/lib/cmap/auth/scram.js.map +1 -1
- package/lib/cmap/auth/x509.js +8 -11
- package/lib/cmap/auth/x509.js.map +1 -1
- package/lib/cmap/command_monitoring_events.js +14 -5
- package/lib/cmap/command_monitoring_events.js.map +1 -1
- package/lib/cmap/commands.js +1 -1
- package/lib/cmap/commands.js.map +1 -1
- package/lib/cmap/connect.js +73 -86
- package/lib/cmap/connect.js.map +1 -1
- package/lib/cmap/connection.js +19 -23
- package/lib/cmap/connection.js.map +1 -1
- package/lib/cmap/connection_pool.js +56 -14
- package/lib/cmap/connection_pool.js.map +1 -1
- package/lib/cmap/connection_pool_events.js +28 -3
- package/lib/cmap/connection_pool_events.js.map +1 -1
- package/lib/cmap/handshake/client_metadata.js +173 -0
- package/lib/cmap/handshake/client_metadata.js.map +1 -0
- package/lib/cmap/message_stream.js.map +1 -1
- package/lib/cmap/wire_protocol/shared.js +1 -16
- package/lib/cmap/wire_protocol/shared.js.map +1 -1
- package/lib/collection.js +10 -10
- package/lib/connection_string.js +50 -69
- package/lib/connection_string.js.map +1 -1
- package/lib/constants.js +11 -0
- package/lib/constants.js.map +1 -1
- package/lib/cursor/abstract_cursor.js +2 -1
- package/lib/cursor/abstract_cursor.js.map +1 -1
- package/lib/cursor/find_cursor.js +1 -1
- package/lib/db.js +4 -2
- package/lib/db.js.map +1 -1
- package/lib/error.js +2 -1
- package/lib/error.js.map +1 -1
- package/lib/mongo_client.js +23 -2
- package/lib/mongo_client.js.map +1 -1
- package/lib/mongo_logger.js +236 -23
- package/lib/mongo_logger.js.map +1 -1
- package/lib/operations/add_user.js.map +1 -1
- package/lib/operations/execute_operation.js +8 -27
- package/lib/operations/execute_operation.js.map +1 -1
- package/lib/operations/find.js +1 -8
- package/lib/operations/find.js.map +1 -1
- package/lib/operations/update.js.map +1 -1
- package/lib/read_concern.js +1 -1
- package/lib/read_preference.js +2 -2
- package/lib/sdam/srv_polling.js +1 -15
- package/lib/sdam/srv_polling.js.map +1 -1
- package/lib/sdam/topology.js +0 -16
- package/lib/sdam/topology.js.map +1 -1
- package/lib/utils.js +33 -90
- package/lib/utils.js.map +1 -1
- package/lib/write_concern.js +1 -1
- package/mongodb.d.ts +242 -93
- package/package.json +30 -31
- package/src/admin.ts +2 -0
- package/src/bulk/common.ts +29 -8
- package/src/change_stream.ts +5 -5
- package/src/cmap/auth/auth_provider.ts +29 -16
- package/src/cmap/auth/gssapi.ts +102 -149
- package/src/cmap/auth/mongo_credentials.ts +14 -23
- package/src/cmap/auth/mongocr.ts +31 -36
- package/src/cmap/auth/mongodb_aws.ts +166 -189
- package/src/cmap/auth/mongodb_oidc/aws_service_workflow.ts +26 -0
- package/src/cmap/auth/mongodb_oidc/callback_workflow.ts +259 -0
- package/src/cmap/auth/mongodb_oidc/service_workflow.ts +47 -0
- package/src/cmap/auth/mongodb_oidc/token_entry_cache.ts +166 -0
- package/src/cmap/auth/mongodb_oidc/workflow.ts +21 -0
- package/src/cmap/auth/mongodb_oidc.ts +101 -17
- package/src/cmap/auth/plain.ts +6 -6
- package/src/cmap/auth/providers.ts +2 -2
- package/src/cmap/auth/scram.ts +56 -90
- package/src/cmap/auth/x509.ts +12 -18
- package/src/cmap/command_monitoring_events.ts +18 -3
- package/src/cmap/commands.ts +1 -1
- package/src/cmap/connect.ts +92 -114
- package/src/cmap/connection.ts +39 -25
- package/src/cmap/connection_pool.ts +89 -18
- package/src/cmap/connection_pool_events.ts +68 -6
- package/src/cmap/handshake/client_metadata.ts +272 -0
- package/src/cmap/message_stream.ts +0 -2
- package/src/cmap/wire_protocol/compression.ts +1 -1
- package/src/cmap/wire_protocol/shared.ts +1 -23
- package/src/collection.ts +13 -13
- package/src/connection_string.ts +56 -72
- package/src/constants.ts +11 -0
- package/src/cursor/abstract_cursor.ts +3 -2
- package/src/cursor/change_stream_cursor.ts +5 -5
- package/src/cursor/find_cursor.ts +1 -1
- package/src/db.ts +4 -2
- package/src/deps.ts +3 -2
- package/src/error.ts +3 -2
- package/src/index.ts +21 -3
- package/src/mongo_client.ts +60 -14
- package/src/mongo_logger.ts +341 -40
- package/src/mongo_types.ts +2 -2
- package/src/operations/add_user.ts +8 -2
- package/src/operations/aggregate.ts +1 -1
- package/src/operations/create_collection.ts +1 -1
- package/src/operations/execute_operation.ts +8 -25
- package/src/operations/find.ts +1 -11
- package/src/operations/find_and_modify.ts +4 -4
- package/src/operations/set_profiling_level.ts +1 -1
- package/src/operations/stats.ts +1 -1
- package/src/operations/update.ts +8 -4
- package/src/read_concern.ts +2 -2
- package/src/read_preference.ts +3 -3
- package/src/sdam/common.ts +2 -2
- package/src/sdam/srv_polling.ts +1 -16
- package/src/sdam/topology.ts +1 -23
- package/src/transactions.ts +1 -1
- package/src/utils.ts +37 -147
- package/src/write_concern.ts +1 -1
package/src/cmap/auth/gssapi.ts
CHANGED
|
@@ -1,15 +1,9 @@
|
|
|
1
1
|
import * as dns from 'dns';
|
|
2
2
|
|
|
3
|
-
import type { Document } from '../../bson';
|
|
4
3
|
import { Kerberos, KerberosClient } from '../../deps';
|
|
5
|
-
import {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
MongoMissingCredentialsError,
|
|
9
|
-
MongoMissingDependencyError,
|
|
10
|
-
MongoRuntimeError
|
|
11
|
-
} from '../../error';
|
|
12
|
-
import { Callback, ns } from '../../utils';
|
|
4
|
+
import { MongoInvalidArgumentError, MongoMissingCredentialsError } from '../../error';
|
|
5
|
+
import { ns } from '../../utils';
|
|
6
|
+
import type { Connection } from '../connection';
|
|
13
7
|
import { AuthContext, AuthProvider } from './auth_provider';
|
|
14
8
|
|
|
15
9
|
/** @public */
|
|
@@ -23,7 +17,7 @@ export const GSSAPICanonicalizationValue = Object.freeze({
|
|
|
23
17
|
|
|
24
18
|
/** @public */
|
|
25
19
|
export type GSSAPICanonicalizationValue =
|
|
26
|
-
typeof GSSAPICanonicalizationValue[keyof typeof GSSAPICanonicalizationValue];
|
|
20
|
+
(typeof GSSAPICanonicalizationValue)[keyof typeof GSSAPICanonicalizationValue];
|
|
27
21
|
|
|
28
22
|
type MechanismProperties = {
|
|
29
23
|
CANONICALIZE_HOST_NAME?: GSSAPICanonicalizationValue;
|
|
@@ -32,70 +26,59 @@ type MechanismProperties = {
|
|
|
32
26
|
SERVICE_REALM?: string;
|
|
33
27
|
};
|
|
34
28
|
|
|
29
|
+
async function externalCommand(
|
|
30
|
+
connection: Connection,
|
|
31
|
+
command: ReturnType<typeof saslStart> | ReturnType<typeof saslContinue>
|
|
32
|
+
): Promise<{ payload: string; conversationId: any }> {
|
|
33
|
+
return connection.commandAsync(ns('$external.$cmd'), command, undefined) as Promise<{
|
|
34
|
+
payload: string;
|
|
35
|
+
conversationId: any;
|
|
36
|
+
}>;
|
|
37
|
+
}
|
|
38
|
+
|
|
35
39
|
export class GSSAPI extends AuthProvider {
|
|
36
|
-
override auth(authContext: AuthContext
|
|
40
|
+
override async auth(authContext: AuthContext): Promise<void> {
|
|
37
41
|
const { connection, credentials } = authContext;
|
|
38
|
-
if (credentials == null)
|
|
39
|
-
|
|
40
|
-
new MongoMissingCredentialsError('Credentials required for GSSAPI authentication')
|
|
41
|
-
);
|
|
42
|
-
const { username } = credentials;
|
|
43
|
-
function externalCommand(
|
|
44
|
-
command: Document,
|
|
45
|
-
cb: Callback<{ payload: string; conversationId: any }>
|
|
46
|
-
) {
|
|
47
|
-
return connection.command(ns('$external.$cmd'), command, undefined, cb);
|
|
42
|
+
if (credentials == null) {
|
|
43
|
+
throw new MongoMissingCredentialsError('Credentials required for GSSAPI authentication');
|
|
48
44
|
}
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
payload
|
|
72
|
-
},
|
|
73
|
-
(err, result) => {
|
|
74
|
-
if (err) return callback(err);
|
|
75
|
-
|
|
76
|
-
callback(undefined, result);
|
|
77
|
-
}
|
|
78
|
-
);
|
|
79
|
-
});
|
|
80
|
-
});
|
|
81
|
-
});
|
|
82
|
-
});
|
|
83
|
-
});
|
|
45
|
+
|
|
46
|
+
const { username } = credentials;
|
|
47
|
+
|
|
48
|
+
const client = await makeKerberosClient(authContext);
|
|
49
|
+
|
|
50
|
+
const payload = await client.step('');
|
|
51
|
+
|
|
52
|
+
const saslStartResponse = await externalCommand(connection, saslStart(payload));
|
|
53
|
+
|
|
54
|
+
const negotiatedPayload = await negotiate(client, 10, saslStartResponse.payload);
|
|
55
|
+
|
|
56
|
+
const saslContinueResponse = await externalCommand(
|
|
57
|
+
connection,
|
|
58
|
+
saslContinue(negotiatedPayload, saslStartResponse.conversationId)
|
|
59
|
+
);
|
|
60
|
+
|
|
61
|
+
const finalizePayload = await finalize(client, username, saslContinueResponse.payload);
|
|
62
|
+
|
|
63
|
+
await externalCommand(connection, {
|
|
64
|
+
saslContinue: 1,
|
|
65
|
+
conversationId: saslContinueResponse.conversationId,
|
|
66
|
+
payload: finalizePayload
|
|
84
67
|
});
|
|
85
68
|
}
|
|
86
69
|
}
|
|
87
70
|
|
|
88
|
-
function makeKerberosClient(authContext: AuthContext
|
|
71
|
+
async function makeKerberosClient(authContext: AuthContext): Promise<KerberosClient> {
|
|
89
72
|
const { hostAddress } = authContext.options;
|
|
90
73
|
const { credentials } = authContext;
|
|
91
74
|
if (!hostAddress || typeof hostAddress.host !== 'string' || !credentials) {
|
|
92
|
-
|
|
93
|
-
|
|
75
|
+
throw new MongoInvalidArgumentError(
|
|
76
|
+
'Connection must have host and port and credentials defined.'
|
|
94
77
|
);
|
|
95
78
|
}
|
|
96
79
|
|
|
97
80
|
if ('kModuleError' in Kerberos) {
|
|
98
|
-
|
|
81
|
+
throw Kerberos['kModuleError'];
|
|
99
82
|
}
|
|
100
83
|
const { initializeClient } = Kerberos;
|
|
101
84
|
|
|
@@ -104,95 +87,71 @@ function makeKerberosClient(authContext: AuthContext, callback: Callback<Kerbero
|
|
|
104
87
|
|
|
105
88
|
const serviceName = mechanismProperties.SERVICE_NAME ?? 'mongodb';
|
|
106
89
|
|
|
107
|
-
performGSSAPICanonicalizeHostName(
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
initializeClient(spn, initOptions, (err: string, client: KerberosClient): void => {
|
|
125
|
-
// TODO(NODE-3483)
|
|
126
|
-
if (err) return callback(new MongoRuntimeError(err));
|
|
127
|
-
callback(undefined, client);
|
|
128
|
-
});
|
|
129
|
-
}
|
|
130
|
-
);
|
|
90
|
+
const host = await performGSSAPICanonicalizeHostName(hostAddress.host, mechanismProperties);
|
|
91
|
+
|
|
92
|
+
const initOptions = {};
|
|
93
|
+
if (password != null) {
|
|
94
|
+
// TODO(NODE-5139): These do not match the typescript options in initializeClient
|
|
95
|
+
Object.assign(initOptions, { user: username, password: password });
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
const spnHost = mechanismProperties.SERVICE_HOST ?? host;
|
|
99
|
+
let spn = `${serviceName}${process.platform === 'win32' ? '/' : '@'}${spnHost}`;
|
|
100
|
+
if ('SERVICE_REALM' in mechanismProperties) {
|
|
101
|
+
spn = `${spn}@${mechanismProperties.SERVICE_REALM}`;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
return initializeClient(spn, initOptions);
|
|
131
105
|
}
|
|
132
106
|
|
|
133
|
-
function saslStart(payload
|
|
107
|
+
function saslStart(payload: string) {
|
|
134
108
|
return {
|
|
135
109
|
saslStart: 1,
|
|
136
110
|
mechanism: 'GSSAPI',
|
|
137
111
|
payload,
|
|
138
112
|
autoAuthorize: 1
|
|
139
|
-
};
|
|
113
|
+
} as const;
|
|
140
114
|
}
|
|
141
115
|
|
|
142
|
-
function saslContinue(payload
|
|
116
|
+
function saslContinue(payload: string, conversationId: number) {
|
|
143
117
|
return {
|
|
144
118
|
saslContinue: 1,
|
|
145
119
|
conversationId,
|
|
146
120
|
payload
|
|
147
|
-
};
|
|
121
|
+
} as const;
|
|
148
122
|
}
|
|
149
123
|
|
|
150
|
-
function negotiate(
|
|
124
|
+
async function negotiate(
|
|
151
125
|
client: KerberosClient,
|
|
152
126
|
retries: number,
|
|
153
|
-
payload: string
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
127
|
+
payload: string
|
|
128
|
+
): Promise<string> {
|
|
129
|
+
try {
|
|
130
|
+
const response = await client.step(payload);
|
|
131
|
+
return response || '';
|
|
132
|
+
} catch (error) {
|
|
133
|
+
if (retries === 0) {
|
|
134
|
+
// Retries exhausted, raise error
|
|
135
|
+
throw error;
|
|
136
|
+
}
|
|
160
137
|
// Adjust number of retries and call step again
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
// Return the payload
|
|
164
|
-
callback(undefined, response || '');
|
|
165
|
-
});
|
|
138
|
+
return negotiate(client, retries - 1, payload);
|
|
139
|
+
}
|
|
166
140
|
}
|
|
167
141
|
|
|
168
|
-
function finalize(
|
|
169
|
-
client: KerberosClient,
|
|
170
|
-
user: string,
|
|
171
|
-
payload: string,
|
|
172
|
-
callback: Callback<string>
|
|
173
|
-
): void {
|
|
142
|
+
async function finalize(client: KerberosClient, user: string, payload: string): Promise<string> {
|
|
174
143
|
// GSS Client Unwrap
|
|
175
|
-
client.unwrap(payload
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
// Wrap the response
|
|
179
|
-
client.wrap(response || '', { user }, (err, wrapped) => {
|
|
180
|
-
if (err) return callback(err);
|
|
181
|
-
|
|
182
|
-
// Return the payload
|
|
183
|
-
callback(undefined, wrapped);
|
|
184
|
-
});
|
|
185
|
-
});
|
|
144
|
+
const response = await client.unwrap(payload);
|
|
145
|
+
return client.wrap(response || '', { user });
|
|
186
146
|
}
|
|
187
147
|
|
|
188
|
-
export function performGSSAPICanonicalizeHostName(
|
|
148
|
+
export async function performGSSAPICanonicalizeHostName(
|
|
189
149
|
host: string,
|
|
190
|
-
mechanismProperties: MechanismProperties
|
|
191
|
-
|
|
192
|
-
): void {
|
|
150
|
+
mechanismProperties: MechanismProperties
|
|
151
|
+
): Promise<string> {
|
|
193
152
|
const mode = mechanismProperties.CANONICALIZE_HOST_NAME;
|
|
194
153
|
if (!mode || mode === GSSAPICanonicalizationValue.none) {
|
|
195
|
-
return
|
|
154
|
+
return host;
|
|
196
155
|
}
|
|
197
156
|
|
|
198
157
|
// If forward and reverse or true
|
|
@@ -201,39 +160,33 @@ export function performGSSAPICanonicalizeHostName(
|
|
|
201
160
|
mode === GSSAPICanonicalizationValue.forwardAndReverse
|
|
202
161
|
) {
|
|
203
162
|
// Perform the lookup of the ip address.
|
|
204
|
-
dns.lookup(host
|
|
205
|
-
// No ip found, return the error.
|
|
206
|
-
if (error) return callback(error);
|
|
163
|
+
const { address } = await dns.promises.lookup(host);
|
|
207
164
|
|
|
165
|
+
try {
|
|
208
166
|
// Perform a reverse ptr lookup on the ip address.
|
|
209
|
-
dns.resolvePtr(address
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
});
|
|
219
|
-
});
|
|
167
|
+
const results = await dns.promises.resolvePtr(address);
|
|
168
|
+
// If the ptr did not error but had no results, return the host.
|
|
169
|
+
return results.length > 0 ? results[0] : host;
|
|
170
|
+
} catch (error) {
|
|
171
|
+
// This can error as ptr records may not exist for all ips. In this case
|
|
172
|
+
// fallback to a cname lookup as dns.lookup() does not return the
|
|
173
|
+
// cname.
|
|
174
|
+
return resolveCname(host);
|
|
175
|
+
}
|
|
220
176
|
} else {
|
|
221
177
|
// The case for forward is just to resolve the cname as dns.lookup()
|
|
222
178
|
// will not return it.
|
|
223
|
-
resolveCname(host
|
|
179
|
+
return resolveCname(host);
|
|
224
180
|
}
|
|
225
181
|
}
|
|
226
182
|
|
|
227
|
-
export function resolveCname(host: string
|
|
183
|
+
export async function resolveCname(host: string): Promise<string> {
|
|
228
184
|
// Attempt to resolve the host name
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
callback(undefined, host);
|
|
238
|
-
});
|
|
185
|
+
try {
|
|
186
|
+
const results = await dns.promises.resolveCname(host);
|
|
187
|
+
// Get the first resolved host id
|
|
188
|
+
return results.length > 0 ? results[0] : host;
|
|
189
|
+
} catch {
|
|
190
|
+
return host;
|
|
191
|
+
}
|
|
239
192
|
}
|
|
@@ -30,25 +30,19 @@ function getDefaultAuthMechanism(hello?: Document): AuthMechanism {
|
|
|
30
30
|
return AuthMechanism.MONGODB_CR;
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
-
/**
|
|
34
|
-
* TODO: NODE-5035: Make OIDC properties public.
|
|
35
|
-
*
|
|
36
|
-
* @public
|
|
37
|
-
* */
|
|
33
|
+
/** @public */
|
|
38
34
|
export interface AuthMechanismProperties extends Document {
|
|
39
35
|
SERVICE_HOST?: string;
|
|
40
36
|
SERVICE_NAME?: string;
|
|
41
37
|
SERVICE_REALM?: string;
|
|
42
38
|
CANONICALIZE_HOST_NAME?: GSSAPICanonicalizationValue;
|
|
43
39
|
AWS_SESSION_TOKEN?: string;
|
|
44
|
-
/** @
|
|
45
|
-
DEVICE_NAME?: 'aws' | 'azure' | 'gcp';
|
|
46
|
-
/** @internal Similar to a username, is require by OIDC when more than one IDP is configured. */
|
|
47
|
-
PRINCIPAL_NAME?: string;
|
|
48
|
-
/** @internal User provided callback to get OIDC auth credentials */
|
|
40
|
+
/** @experimental */
|
|
49
41
|
REQUEST_TOKEN_CALLBACK?: OIDCRequestFunction;
|
|
50
|
-
/** @
|
|
42
|
+
/** @experimental */
|
|
51
43
|
REFRESH_TOKEN_CALLBACK?: OIDCRefreshFunction;
|
|
44
|
+
/** @experimental */
|
|
45
|
+
PROVIDER_NAME?: 'aws';
|
|
52
46
|
}
|
|
53
47
|
|
|
54
48
|
/** @public */
|
|
@@ -155,21 +149,18 @@ export class MongoCredentials {
|
|
|
155
149
|
}
|
|
156
150
|
|
|
157
151
|
if (this.mechanism === AuthMechanism.MONGODB_OIDC) {
|
|
158
|
-
if (this.username) {
|
|
152
|
+
if (this.username && this.mechanismProperties.PROVIDER_NAME) {
|
|
159
153
|
throw new MongoInvalidArgumentError(
|
|
160
|
-
`
|
|
154
|
+
`username and PROVIDER_NAME may not be used together for mechanism '${this.mechanism}'.`
|
|
161
155
|
);
|
|
162
156
|
}
|
|
163
157
|
|
|
164
|
-
if (
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
if (this.mechanismProperties.DEVICE_NAME && this.mechanismProperties.DEVICE_NAME !== 'aws') {
|
|
158
|
+
if (
|
|
159
|
+
this.mechanismProperties.PROVIDER_NAME &&
|
|
160
|
+
this.mechanismProperties.PROVIDER_NAME !== 'aws'
|
|
161
|
+
) {
|
|
171
162
|
throw new MongoInvalidArgumentError(
|
|
172
|
-
`Currently only a
|
|
163
|
+
`Currently only a PROVIDER_NAME of 'aws' is supported for mechanism '${this.mechanism}'.`
|
|
173
164
|
);
|
|
174
165
|
}
|
|
175
166
|
|
|
@@ -183,11 +174,11 @@ export class MongoCredentials {
|
|
|
183
174
|
}
|
|
184
175
|
|
|
185
176
|
if (
|
|
186
|
-
!this.mechanismProperties.
|
|
177
|
+
!this.mechanismProperties.PROVIDER_NAME &&
|
|
187
178
|
!this.mechanismProperties.REQUEST_TOKEN_CALLBACK
|
|
188
179
|
) {
|
|
189
180
|
throw new MongoInvalidArgumentError(
|
|
190
|
-
`Either a
|
|
181
|
+
`Either a PROVIDER_NAME or a REQUEST_TOKEN_CALLBACK must be specified for mechanism '${this.mechanism}'.`
|
|
191
182
|
);
|
|
192
183
|
}
|
|
193
184
|
}
|
package/src/cmap/auth/mongocr.ts
CHANGED
|
@@ -1,47 +1,42 @@
|
|
|
1
1
|
import * as crypto from 'crypto';
|
|
2
2
|
|
|
3
3
|
import { MongoMissingCredentialsError } from '../../error';
|
|
4
|
-
import {
|
|
4
|
+
import { ns } from '../../utils';
|
|
5
5
|
import { AuthContext, AuthProvider } from './auth_provider';
|
|
6
6
|
|
|
7
7
|
export class MongoCR extends AuthProvider {
|
|
8
|
-
override auth(authContext: AuthContext
|
|
8
|
+
override async auth(authContext: AuthContext): Promise<void> {
|
|
9
9
|
const { connection, credentials } = authContext;
|
|
10
10
|
if (!credentials) {
|
|
11
|
-
|
|
11
|
+
throw new MongoMissingCredentialsError('AuthContext must provide credentials.');
|
|
12
12
|
}
|
|
13
|
-
|
|
14
|
-
const password = credentials
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
key
|
|
42
|
-
};
|
|
43
|
-
|
|
44
|
-
connection.command(ns(`${source}.$cmd`), authenticateCommand, undefined, callback);
|
|
45
|
-
});
|
|
13
|
+
|
|
14
|
+
const { username, password, source } = credentials;
|
|
15
|
+
|
|
16
|
+
const { nonce } = await connection.commandAsync(
|
|
17
|
+
ns(`${source}.$cmd`),
|
|
18
|
+
{ getnonce: 1 },
|
|
19
|
+
undefined
|
|
20
|
+
);
|
|
21
|
+
|
|
22
|
+
const hashPassword = crypto
|
|
23
|
+
.createHash('md5')
|
|
24
|
+
.update(`${username}:mongo:${password}`, 'utf8')
|
|
25
|
+
.digest('hex');
|
|
26
|
+
|
|
27
|
+
// Final key
|
|
28
|
+
const key = crypto
|
|
29
|
+
.createHash('md5')
|
|
30
|
+
.update(`${nonce}${username}${hashPassword}`, 'utf8')
|
|
31
|
+
.digest('hex');
|
|
32
|
+
|
|
33
|
+
const authenticateCommand = {
|
|
34
|
+
authenticate: 1,
|
|
35
|
+
user: username,
|
|
36
|
+
nonce,
|
|
37
|
+
key
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
await connection.commandAsync(ns(`${source}.$cmd`), authenticateCommand, undefined);
|
|
46
41
|
}
|
|
47
42
|
}
|