mongodb 6.6.2 → 6.7.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/lib/client-side-encryption/providers/azure.js +21 -6
- package/lib/client-side-encryption/providers/azure.js.map +1 -1
- package/lib/cmap/auth/mongo_credentials.js +24 -16
- package/lib/cmap/auth/mongo_credentials.js.map +1 -1
- package/lib/cmap/auth/mongodb_oidc/automated_callback_workflow.js +78 -0
- package/lib/cmap/auth/mongodb_oidc/automated_callback_workflow.js.map +1 -0
- package/lib/cmap/auth/mongodb_oidc/azure_machine_workflow.js +74 -0
- package/lib/cmap/auth/mongodb_oidc/azure_machine_workflow.js.map +1 -0
- package/lib/cmap/auth/mongodb_oidc/callback_workflow.js +74 -135
- package/lib/cmap/auth/mongodb_oidc/callback_workflow.js.map +1 -1
- package/lib/cmap/auth/mongodb_oidc/command_builders.js +45 -0
- package/lib/cmap/auth/mongodb_oidc/command_builders.js.map +1 -0
- package/lib/cmap/auth/mongodb_oidc/gcp_machine_workflow.js +46 -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/machine_workflow.js +107 -0
- package/lib/cmap/auth/mongodb_oidc/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 +34 -0
- package/lib/cmap/auth/mongodb_oidc/token_machine_workflow.js.map +1 -0
- package/lib/cmap/auth/mongodb_oidc.js +26 -24
- package/lib/cmap/auth/mongodb_oidc.js.map +1 -1
- package/lib/cmap/auth/providers.js +0 -1
- package/lib/cmap/auth/providers.js.map +1 -1
- package/lib/cmap/connect.js +4 -4
- package/lib/cmap/connect.js.map +1 -1
- package/lib/cmap/connection.js.map +1 -1
- package/lib/cmap/connection_pool.js +1 -1
- package/lib/cmap/connection_pool.js.map +1 -1
- package/lib/connection_string.js +3 -0
- package/lib/connection_string.js.map +1 -1
- package/lib/error.js +57 -2
- package/lib/error.js.map +1 -1
- package/lib/index.js +5 -3
- package/lib/index.js.map +1 -1
- package/lib/mongo_client.js +1 -1
- package/lib/mongo_client.js.map +1 -1
- package/lib/mongo_client_auth_providers.js +34 -4
- package/lib/mongo_client_auth_providers.js.map +1 -1
- package/lib/sdam/server_description.js +10 -4
- package/lib/sdam/server_description.js.map +1 -1
- package/lib/sessions.js +10 -0
- package/lib/sessions.js.map +1 -1
- package/lib/utils.js +32 -2
- package/lib/utils.js.map +1 -1
- package/mongodb.d.ts +115 -25
- package/package.json +5 -4
- package/src/client-side-encryption/providers/azure.ts +21 -10
- package/src/cmap/auth/mongo_credentials.ts +41 -34
- package/src/cmap/auth/mongodb_oidc/automated_callback_workflow.ts +82 -0
- package/src/cmap/auth/mongodb_oidc/azure_machine_workflow.ts +85 -0
- package/src/cmap/auth/mongodb_oidc/callback_workflow.ts +96 -204
- package/src/cmap/auth/mongodb_oidc/command_builders.ts +54 -0
- package/src/cmap/auth/mongodb_oidc/gcp_machine_workflow.ts +53 -0
- package/src/cmap/auth/mongodb_oidc/human_callback_workflow.ts +142 -0
- package/src/cmap/auth/mongodb_oidc/machine_workflow.ts +137 -0
- package/src/cmap/auth/mongodb_oidc/token_cache.ts +62 -0
- package/src/cmap/auth/mongodb_oidc/token_machine_workflow.ts +34 -0
- package/src/cmap/auth/mongodb_oidc.ts +79 -49
- package/src/cmap/auth/providers.ts +0 -1
- package/src/cmap/connect.ts +14 -4
- package/src/cmap/connection.ts +1 -0
- package/src/cmap/connection_pool.ts +2 -1
- package/src/connection_string.ts +3 -0
- package/src/error.ts +58 -1
- package/src/index.ts +8 -4
- package/src/mongo_client.ts +4 -1
- package/src/mongo_client_auth_providers.ts +44 -6
- package/src/sdam/server_description.ts +13 -4
- package/src/sessions.ts +10 -0
- package/src/utils.ts +33 -0
- package/lib/client-side-encryption/providers/utils.js +0 -35
- package/lib/client-side-encryption/providers/utils.js.map +0 -1
- package/lib/cmap/auth/mongodb_oidc/aws_service_workflow.js +0 -30
- package/lib/cmap/auth/mongodb_oidc/aws_service_workflow.js.map +0 -1
- package/lib/cmap/auth/mongodb_oidc/azure_service_workflow.js +0 -73
- package/lib/cmap/auth/mongodb_oidc/azure_service_workflow.js.map +0 -1
- package/lib/cmap/auth/mongodb_oidc/azure_token_cache.js +0 -49
- package/lib/cmap/auth/mongodb_oidc/azure_token_cache.js.map +0 -1
- package/lib/cmap/auth/mongodb_oidc/cache.js +0 -55
- package/lib/cmap/auth/mongodb_oidc/cache.js.map +0 -1
- package/lib/cmap/auth/mongodb_oidc/callback_lock_cache.js +0 -90
- package/lib/cmap/auth/mongodb_oidc/callback_lock_cache.js.map +0 -1
- package/lib/cmap/auth/mongodb_oidc/service_workflow.js +0 -43
- package/lib/cmap/auth/mongodb_oidc/service_workflow.js.map +0 -1
- package/lib/cmap/auth/mongodb_oidc/token_entry_cache.js +0 -62
- package/lib/cmap/auth/mongodb_oidc/token_entry_cache.js.map +0 -1
- package/src/client-side-encryption/providers/utils.ts +0 -37
- package/src/cmap/auth/mongodb_oidc/aws_service_workflow.ts +0 -29
- package/src/cmap/auth/mongodb_oidc/azure_service_workflow.ts +0 -86
- package/src/cmap/auth/mongodb_oidc/azure_token_cache.ts +0 -51
- package/src/cmap/auth/mongodb_oidc/cache.ts +0 -63
- package/src/cmap/auth/mongodb_oidc/callback_lock_cache.ts +0 -115
- package/src/cmap/auth/mongodb_oidc/service_workflow.ts +0 -49
- package/src/cmap/auth/mongodb_oidc/token_entry_cache.ts +0 -77
package/mongodb.d.ts
CHANGED
|
@@ -502,7 +502,6 @@ export declare const AuthMechanism: Readonly<{
|
|
|
502
502
|
readonly MONGODB_SCRAM_SHA1: "SCRAM-SHA-1";
|
|
503
503
|
readonly MONGODB_SCRAM_SHA256: "SCRAM-SHA-256";
|
|
504
504
|
readonly MONGODB_X509: "MONGODB-X509";
|
|
505
|
-
/** @experimental */
|
|
506
505
|
readonly MONGODB_OIDC: "MONGODB-OIDC";
|
|
507
506
|
}>;
|
|
508
507
|
|
|
@@ -516,16 +515,16 @@ export declare interface AuthMechanismProperties extends Document {
|
|
|
516
515
|
SERVICE_REALM?: string;
|
|
517
516
|
CANONICALIZE_HOST_NAME?: GSSAPICanonicalizationValue;
|
|
518
517
|
AWS_SESSION_TOKEN?: string;
|
|
519
|
-
/**
|
|
520
|
-
|
|
521
|
-
/**
|
|
522
|
-
|
|
523
|
-
/**
|
|
524
|
-
|
|
525
|
-
/**
|
|
518
|
+
/** A user provided OIDC machine callback function. */
|
|
519
|
+
OIDC_CALLBACK?: OIDCCallbackFunction;
|
|
520
|
+
/** A user provided OIDC human interacted callback function. */
|
|
521
|
+
OIDC_HUMAN_CALLBACK?: OIDCCallbackFunction;
|
|
522
|
+
/** The OIDC environment. Note that 'test' is for internal use only. */
|
|
523
|
+
ENVIRONMENT?: 'test' | 'azure' | 'gcp';
|
|
524
|
+
/** Allowed hosts that OIDC auth can connect to. */
|
|
526
525
|
ALLOWED_HOSTS?: string[];
|
|
527
|
-
/**
|
|
528
|
-
|
|
526
|
+
/** The resource token for OIDC auth in Azure and GCP. */
|
|
527
|
+
TOKEN_RESOURCE?: string;
|
|
529
528
|
}
|
|
530
529
|
|
|
531
530
|
/* Excluded from this release type: AuthProvider */
|
|
@@ -2010,6 +2009,11 @@ export declare class ClientSession extends TypedEventEmitter<ClientSessionEvents
|
|
|
2010
2009
|
/**
|
|
2011
2010
|
* Starts a new transaction with the given options.
|
|
2012
2011
|
*
|
|
2012
|
+
* @remarks
|
|
2013
|
+
* **IMPORTANT**: Running operations in parallel is not supported during a transaction. The use of `Promise.all`,
|
|
2014
|
+
* `Promise.allSettled`, `Promise.race`, etc to parallelize operations inside a transaction is
|
|
2015
|
+
* undefined behaviour.
|
|
2016
|
+
*
|
|
2013
2017
|
* @param options - Options for the transaction
|
|
2014
2018
|
*/
|
|
2015
2019
|
startTransaction(options?: TransactionOptions): void;
|
|
@@ -2030,6 +2034,11 @@ export declare class ClientSession extends TypedEventEmitter<ClientSessionEvents
|
|
|
2030
2034
|
*
|
|
2031
2035
|
* **IMPORTANT:** This method requires the function passed in to return a Promise. That promise must be made by `await`-ing all operations in such a way that rejections are propagated to the returned promise.
|
|
2032
2036
|
*
|
|
2037
|
+
* **IMPORTANT:** Running operations in parallel is not supported during a transaction. The use of `Promise.all`,
|
|
2038
|
+
* `Promise.allSettled`, `Promise.race`, etc to parallelize operations inside a transaction is
|
|
2039
|
+
* undefined behaviour.
|
|
2040
|
+
*
|
|
2041
|
+
*
|
|
2033
2042
|
* @remarks
|
|
2034
2043
|
* - If all operations successfully complete and the `commitTransaction` operation is successful, then the provided function will return the result of the provided function.
|
|
2035
2044
|
* - If the transaction is unable to complete or an error is thrown from within the provided function, then the provided function will throw an error.
|
|
@@ -4281,22 +4290,33 @@ export declare class HostAddress {
|
|
|
4281
4290
|
}
|
|
4282
4291
|
|
|
4283
4292
|
/**
|
|
4293
|
+
* The information returned by the server on the IDP server.
|
|
4284
4294
|
* @public
|
|
4285
|
-
* @experimental
|
|
4286
4295
|
*/
|
|
4287
|
-
export declare interface
|
|
4296
|
+
export declare interface IdPInfo {
|
|
4297
|
+
/**
|
|
4298
|
+
* A URL which describes the Authentication Server. This identifier should
|
|
4299
|
+
* be the iss of provided access tokens, and be viable for RFC8414 metadata
|
|
4300
|
+
* discovery and RFC9207 identification.
|
|
4301
|
+
*/
|
|
4288
4302
|
issuer: string;
|
|
4303
|
+
/** A unique client ID for this OIDC client. */
|
|
4289
4304
|
clientId: string;
|
|
4305
|
+
/** A list of additional scopes to request from IdP. */
|
|
4290
4306
|
requestScopes?: string[];
|
|
4291
4307
|
}
|
|
4292
4308
|
|
|
4293
4309
|
/**
|
|
4310
|
+
* The response from the IdP server with the access token and
|
|
4311
|
+
* optional expiration time and refresh token.
|
|
4294
4312
|
* @public
|
|
4295
|
-
* @experimental
|
|
4296
4313
|
*/
|
|
4297
4314
|
export declare interface IdPServerResponse {
|
|
4315
|
+
/** The OIDC access token. */
|
|
4298
4316
|
accessToken: string;
|
|
4317
|
+
/** The time when the access token expires. For future use. */
|
|
4299
4318
|
expiresInSeconds?: number;
|
|
4319
|
+
/** The refresh token, if applicable, to be used by the callback to request a new token from the issuer. */
|
|
4300
4320
|
refreshToken?: string;
|
|
4301
4321
|
}
|
|
4302
4322
|
|
|
@@ -4793,7 +4813,7 @@ export declare class MongoAWSError extends MongoRuntimeError {
|
|
|
4793
4813
|
* @public
|
|
4794
4814
|
* @category Error
|
|
4795
4815
|
*/
|
|
4796
|
-
export declare class MongoAzureError extends
|
|
4816
|
+
export declare class MongoAzureError extends MongoOIDCError {
|
|
4797
4817
|
/**
|
|
4798
4818
|
* **Do not use this constructor!**
|
|
4799
4819
|
*
|
|
@@ -5564,6 +5584,29 @@ export declare class MongoExpiredSessionError extends MongoAPIError {
|
|
|
5564
5584
|
get name(): string;
|
|
5565
5585
|
}
|
|
5566
5586
|
|
|
5587
|
+
/**
|
|
5588
|
+
* A error generated when the user attempts to authenticate
|
|
5589
|
+
* via GCP, but fails.
|
|
5590
|
+
*
|
|
5591
|
+
* @public
|
|
5592
|
+
* @category Error
|
|
5593
|
+
*/
|
|
5594
|
+
export declare class MongoGCPError extends MongoOIDCError {
|
|
5595
|
+
/**
|
|
5596
|
+
* **Do not use this constructor!**
|
|
5597
|
+
*
|
|
5598
|
+
* Meant for internal use only.
|
|
5599
|
+
*
|
|
5600
|
+
* @remarks
|
|
5601
|
+
* This class is only meant to be constructed within the driver. This constructor is
|
|
5602
|
+
* not subject to semantic versioning compatibility guarantees and may change at any time.
|
|
5603
|
+
*
|
|
5604
|
+
* @public
|
|
5605
|
+
**/
|
|
5606
|
+
constructor(message: string);
|
|
5607
|
+
get name(): string;
|
|
5608
|
+
}
|
|
5609
|
+
|
|
5567
5610
|
/**
|
|
5568
5611
|
* An error generated when a malformed or invalid chunk is
|
|
5569
5612
|
* encountered when reading from a GridFSStream.
|
|
@@ -5793,6 +5836,29 @@ export declare class MongoNotConnectedError extends MongoAPIError {
|
|
|
5793
5836
|
get name(): string;
|
|
5794
5837
|
}
|
|
5795
5838
|
|
|
5839
|
+
/**
|
|
5840
|
+
* A error generated when the user attempts to authenticate
|
|
5841
|
+
* via OIDC callbacks, but fails.
|
|
5842
|
+
*
|
|
5843
|
+
* @public
|
|
5844
|
+
* @category Error
|
|
5845
|
+
*/
|
|
5846
|
+
export declare class MongoOIDCError extends MongoRuntimeError {
|
|
5847
|
+
/**
|
|
5848
|
+
* **Do not use this constructor!**
|
|
5849
|
+
*
|
|
5850
|
+
* Meant for internal use only.
|
|
5851
|
+
*
|
|
5852
|
+
* @remarks
|
|
5853
|
+
* This class is only meant to be constructed within the driver. This constructor is
|
|
5854
|
+
* not subject to semantic versioning compatibility guarantees and may change at any time.
|
|
5855
|
+
*
|
|
5856
|
+
* @public
|
|
5857
|
+
**/
|
|
5858
|
+
constructor(message: string);
|
|
5859
|
+
get name(): string;
|
|
5860
|
+
}
|
|
5861
|
+
|
|
5796
5862
|
/**
|
|
5797
5863
|
* Parsed Mongo Client Options.
|
|
5798
5864
|
*
|
|
@@ -5828,6 +5894,7 @@ export declare interface MongoOptions extends Required<Pick<MongoClientOptions,
|
|
|
5828
5894
|
metadata: ClientMetadata;
|
|
5829
5895
|
/* Excluded from this release type: extendedMetadata */
|
|
5830
5896
|
/* Excluded from this release type: autoEncrypter */
|
|
5897
|
+
/* Excluded from this release type: tokenCache */
|
|
5831
5898
|
proxyHost?: string;
|
|
5832
5899
|
proxyPort?: number;
|
|
5833
5900
|
proxyUsername?: string;
|
|
@@ -6230,27 +6297,46 @@ export declare type NumericType = IntegerType | Decimal128 | Double;
|
|
|
6230
6297
|
export { ObjectId }
|
|
6231
6298
|
|
|
6232
6299
|
/**
|
|
6300
|
+
* The signature of the human or machine callback functions.
|
|
6233
6301
|
* @public
|
|
6234
|
-
* @experimental
|
|
6235
6302
|
*/
|
|
6236
|
-
export declare
|
|
6237
|
-
refreshToken?: string;
|
|
6238
|
-
timeoutSeconds?: number;
|
|
6239
|
-
timeoutContext?: AbortSignal;
|
|
6240
|
-
version: number;
|
|
6241
|
-
}
|
|
6303
|
+
export declare type OIDCCallbackFunction = (params: OIDCCallbackParams) => Promise<OIDCResponse>;
|
|
6242
6304
|
|
|
6243
6305
|
/**
|
|
6306
|
+
* The parameters that the driver provides to the user supplied
|
|
6307
|
+
* human or machine callback.
|
|
6308
|
+
*
|
|
6309
|
+
* The version number is used to communicate callback API changes that are not breaking but that
|
|
6310
|
+
* users may want to know about and review their implementation. Users may wish to check the version
|
|
6311
|
+
* number and throw an error if their expected version number and the one provided do not match.
|
|
6244
6312
|
* @public
|
|
6245
|
-
* @experimental
|
|
6246
6313
|
*/
|
|
6247
|
-
export declare
|
|
6314
|
+
export declare interface OIDCCallbackParams {
|
|
6315
|
+
/** Optional username. */
|
|
6316
|
+
username?: string;
|
|
6317
|
+
/** The context in which to timeout the OIDC callback. */
|
|
6318
|
+
timeoutContext: AbortSignal;
|
|
6319
|
+
/** The current OIDC API version. */
|
|
6320
|
+
version: 1;
|
|
6321
|
+
/** The IdP information returned from the server. */
|
|
6322
|
+
idpInfo?: IdPInfo;
|
|
6323
|
+
/** The refresh token, if applicable, to be used by the callback to request a new token from the issuer. */
|
|
6324
|
+
refreshToken?: string;
|
|
6325
|
+
}
|
|
6248
6326
|
|
|
6249
6327
|
/**
|
|
6328
|
+
* The response required to be returned from the machine or
|
|
6329
|
+
* human callback workflows' callback.
|
|
6250
6330
|
* @public
|
|
6251
|
-
* @experimental
|
|
6252
6331
|
*/
|
|
6253
|
-
export declare
|
|
6332
|
+
export declare interface OIDCResponse {
|
|
6333
|
+
/** The OIDC access token. */
|
|
6334
|
+
accessToken: string;
|
|
6335
|
+
/** The time when the access token expires. For future use. */
|
|
6336
|
+
expiresInSeconds?: number;
|
|
6337
|
+
/** The refresh token, if applicable, to be used by the callback to request a new token from the issuer. */
|
|
6338
|
+
refreshToken?: string;
|
|
6339
|
+
}
|
|
6254
6340
|
|
|
6255
6341
|
/* Excluded from this release type: OnDemandDocument */
|
|
6256
6342
|
|
|
@@ -7159,6 +7245,8 @@ export declare interface TimeSeriesCollectionOptions extends Document {
|
|
|
7159
7245
|
|
|
7160
7246
|
export { Timestamp }
|
|
7161
7247
|
|
|
7248
|
+
/* Excluded from this release type: TokenCache */
|
|
7249
|
+
|
|
7162
7250
|
/* Excluded from this release type: Topology */
|
|
7163
7251
|
|
|
7164
7252
|
/* Excluded from this release type: TOPOLOGY_CLOSED */
|
|
@@ -7587,6 +7675,8 @@ export declare type WithSessionCallback<T = unknown> = (session: ClientSession)
|
|
|
7587
7675
|
/** @public */
|
|
7588
7676
|
export declare type WithTransactionCallback<T = any> = (session: ClientSession) => Promise<T>;
|
|
7589
7677
|
|
|
7678
|
+
/* Excluded from this release type: Workflow */
|
|
7679
|
+
|
|
7590
7680
|
/**
|
|
7591
7681
|
* A MongoDB WriteConcern, which describes the level of acknowledgement
|
|
7592
7682
|
* requested from MongoDB for write operations.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mongodb",
|
|
3
|
-
"version": "6.
|
|
3
|
+
"version": "6.7.0",
|
|
4
4
|
"description": "The official MongoDB driver for Node.js",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"files": [
|
|
@@ -68,7 +68,6 @@
|
|
|
68
68
|
"@microsoft/api-extractor": "^7.43.1",
|
|
69
69
|
"@microsoft/tsdoc-config": "^0.16.2",
|
|
70
70
|
"@mongodb-js/zstd": "^1.2.0",
|
|
71
|
-
"@octokit/core": "^6.1.2",
|
|
72
71
|
"@types/chai": "^4.3.14",
|
|
73
72
|
"@types/chai-subset": "^1.3.5",
|
|
74
73
|
"@types/express": "^4.17.21",
|
|
@@ -149,8 +148,10 @@
|
|
|
149
148
|
"check:drivers-atlas-testing": "mocha --config test/mocha_mongodb.json test/atlas/drivers_atlas_testing.test.ts",
|
|
150
149
|
"check:adl": "mocha --config test/mocha_mongodb.json test/manual/atlas-data-lake-testing",
|
|
151
150
|
"check:aws": "nyc mocha --config test/mocha_mongodb.json test/integration/auth/mongodb_aws.test.ts",
|
|
152
|
-
"check:oidc": "mocha --config test/mocha_mongodb.json test/
|
|
153
|
-
"check:oidc-
|
|
151
|
+
"check:oidc-auth": "mocha --config test/mocha_mongodb.json test/integration/auth/auth.spec.test.ts",
|
|
152
|
+
"check:oidc-test": "mocha --config test/mocha_mongodb.json test/integration/auth/mongodb_oidc.prose.test.ts",
|
|
153
|
+
"check:oidc-azure": "mocha --config test/mocha_mongodb.json test/integration/auth/mongodb_oidc_azure.prose.05.test.ts",
|
|
154
|
+
"check:oidc-gcp": "mocha --config test/mocha_mongodb.json test/integration/auth/mongodb_oidc_gcp.prose.06.test.ts",
|
|
154
155
|
"check:ocsp": "mocha --config test/manual/mocharc.json test/manual/ocsp_support.test.js",
|
|
155
156
|
"check:kerberos": "nyc mocha --config test/manual/mocharc.json test/manual/kerberos.test.ts",
|
|
156
157
|
"check:tls": "mocha --config test/manual/mocharc.json test/manual/tls_support.test.ts",
|
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
import { type Document } from '../../bson';
|
|
2
|
-
import {
|
|
2
|
+
import { MongoNetworkTimeoutError } from '../../error';
|
|
3
|
+
import { get } from '../../utils';
|
|
4
|
+
import { MongoCryptAzureKMSRequestError } from '../errors';
|
|
3
5
|
import { type KMSProviders } from './index';
|
|
4
|
-
import { get } from './utils';
|
|
5
6
|
|
|
6
7
|
const MINIMUM_TOKEN_REFRESH_IN_MILLISECONDS = 6000;
|
|
8
|
+
/** Base URL for getting Azure tokens. */
|
|
9
|
+
export const AZURE_BASE_URL = 'http://169.254.169.254/metadata/identity/oauth2/token?';
|
|
7
10
|
|
|
8
11
|
/**
|
|
9
12
|
* The access token that libmongocrypt expects for Azure kms.
|
|
@@ -113,6 +116,19 @@ export interface AzureKMSRequestOptions {
|
|
|
113
116
|
url?: URL | string;
|
|
114
117
|
}
|
|
115
118
|
|
|
119
|
+
/**
|
|
120
|
+
* @internal
|
|
121
|
+
* Get the Azure endpoint URL.
|
|
122
|
+
*/
|
|
123
|
+
export function addAzureParams(url: URL, resource: string, username?: string): URL {
|
|
124
|
+
url.searchParams.append('api-version', '2018-02-01');
|
|
125
|
+
url.searchParams.append('resource', resource);
|
|
126
|
+
if (username) {
|
|
127
|
+
url.searchParams.append('client_id', username);
|
|
128
|
+
}
|
|
129
|
+
return url;
|
|
130
|
+
}
|
|
131
|
+
|
|
116
132
|
/**
|
|
117
133
|
* @internal
|
|
118
134
|
*
|
|
@@ -123,13 +139,8 @@ export function prepareRequest(options: AzureKMSRequestOptions): {
|
|
|
123
139
|
headers: Document;
|
|
124
140
|
url: URL;
|
|
125
141
|
} {
|
|
126
|
-
const url = new URL(
|
|
127
|
-
|
|
128
|
-
);
|
|
129
|
-
|
|
130
|
-
url.searchParams.append('api-version', '2018-02-01');
|
|
131
|
-
url.searchParams.append('resource', 'https://vault.azure.net');
|
|
132
|
-
|
|
142
|
+
const url = new URL(options.url?.toString() ?? AZURE_BASE_URL);
|
|
143
|
+
addAzureParams(url, 'https://vault.azure.net');
|
|
133
144
|
const headers = { ...options.headers, 'Content-Type': 'application/json', Metadata: true };
|
|
134
145
|
return { headers, url };
|
|
135
146
|
}
|
|
@@ -152,7 +163,7 @@ export async function fetchAzureKMSToken(
|
|
|
152
163
|
const response = await get(url, { headers });
|
|
153
164
|
return await parseResponse(response);
|
|
154
165
|
} catch (error) {
|
|
155
|
-
if (error instanceof
|
|
166
|
+
if (error instanceof MongoNetworkTimeoutError) {
|
|
156
167
|
throw new MongoCryptAzureKMSRequestError(`[Azure KMS] ${error.message}`);
|
|
157
168
|
}
|
|
158
169
|
throw error;
|
|
@@ -3,12 +3,11 @@
|
|
|
3
3
|
import type { Document } from '../../bson';
|
|
4
4
|
import {
|
|
5
5
|
MongoAPIError,
|
|
6
|
-
MongoAzureError,
|
|
7
6
|
MongoInvalidArgumentError,
|
|
8
7
|
MongoMissingCredentialsError
|
|
9
8
|
} from '../../error';
|
|
10
9
|
import { GSSAPICanonicalizationValue } from './gssapi';
|
|
11
|
-
import type {
|
|
10
|
+
import type { OIDCCallbackFunction } from './mongodb_oidc';
|
|
12
11
|
import { AUTH_MECHS_AUTH_SRC_EXTERNAL, AuthMechanism } from './providers';
|
|
13
12
|
|
|
14
13
|
// https://github.com/mongodb/specifications/blob/master/source/auth/auth.rst
|
|
@@ -32,12 +31,17 @@ function getDefaultAuthMechanism(hello: Document | null): AuthMechanism {
|
|
|
32
31
|
return AuthMechanism.MONGODB_CR;
|
|
33
32
|
}
|
|
34
33
|
|
|
35
|
-
const
|
|
34
|
+
const ALLOWED_ENVIRONMENT_NAMES: AuthMechanismProperties['ENVIRONMENT'][] = [
|
|
35
|
+
'test',
|
|
36
|
+
'azure',
|
|
37
|
+
'gcp'
|
|
38
|
+
];
|
|
36
39
|
const ALLOWED_HOSTS_ERROR = 'Auth mechanism property ALLOWED_HOSTS must be an array of strings.';
|
|
37
40
|
|
|
38
41
|
/** @internal */
|
|
39
42
|
export const DEFAULT_ALLOWED_HOSTS = [
|
|
40
43
|
'*.mongodb.net',
|
|
44
|
+
'*.mongodb-qa.net',
|
|
41
45
|
'*.mongodb-dev.net',
|
|
42
46
|
'*.mongodbgov.net',
|
|
43
47
|
'localhost',
|
|
@@ -46,8 +50,8 @@ export const DEFAULT_ALLOWED_HOSTS = [
|
|
|
46
50
|
];
|
|
47
51
|
|
|
48
52
|
/** Error for when the token audience is missing in the environment. */
|
|
49
|
-
const
|
|
50
|
-
'
|
|
53
|
+
const TOKEN_RESOURCE_MISSING_ERROR =
|
|
54
|
+
'TOKEN_RESOURCE must be set in the auth mechanism properties when ENVIRONMENT is azure or gcp.';
|
|
51
55
|
|
|
52
56
|
/** @public */
|
|
53
57
|
export interface AuthMechanismProperties extends Document {
|
|
@@ -56,16 +60,16 @@ export interface AuthMechanismProperties extends Document {
|
|
|
56
60
|
SERVICE_REALM?: string;
|
|
57
61
|
CANONICALIZE_HOST_NAME?: GSSAPICanonicalizationValue;
|
|
58
62
|
AWS_SESSION_TOKEN?: string;
|
|
59
|
-
/**
|
|
60
|
-
|
|
61
|
-
/**
|
|
62
|
-
|
|
63
|
-
/**
|
|
64
|
-
|
|
65
|
-
/**
|
|
63
|
+
/** A user provided OIDC machine callback function. */
|
|
64
|
+
OIDC_CALLBACK?: OIDCCallbackFunction;
|
|
65
|
+
/** A user provided OIDC human interacted callback function. */
|
|
66
|
+
OIDC_HUMAN_CALLBACK?: OIDCCallbackFunction;
|
|
67
|
+
/** The OIDC environment. Note that 'test' is for internal use only. */
|
|
68
|
+
ENVIRONMENT?: 'test' | 'azure' | 'gcp';
|
|
69
|
+
/** Allowed hosts that OIDC auth can connect to. */
|
|
66
70
|
ALLOWED_HOSTS?: string[];
|
|
67
|
-
/**
|
|
68
|
-
|
|
71
|
+
/** The resource token for OIDC auth in Azure and GCP. */
|
|
72
|
+
TOKEN_RESOURCE?: string;
|
|
69
73
|
}
|
|
70
74
|
|
|
71
75
|
/** @public */
|
|
@@ -179,45 +183,48 @@ export class MongoCredentials {
|
|
|
179
183
|
}
|
|
180
184
|
|
|
181
185
|
if (this.mechanism === AuthMechanism.MONGODB_OIDC) {
|
|
182
|
-
if (
|
|
186
|
+
if (
|
|
187
|
+
this.username &&
|
|
188
|
+
this.mechanismProperties.ENVIRONMENT &&
|
|
189
|
+
this.mechanismProperties.ENVIRONMENT !== 'azure'
|
|
190
|
+
) {
|
|
183
191
|
throw new MongoInvalidArgumentError(
|
|
184
|
-
`username and
|
|
192
|
+
`username and ENVIRONMENT '${this.mechanismProperties.ENVIRONMENT}' may not be used together for mechanism '${this.mechanism}'.`
|
|
185
193
|
);
|
|
186
194
|
}
|
|
187
195
|
|
|
188
|
-
if (
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
throw new MongoAzureError(TOKEN_AUDIENCE_MISSING_ERROR);
|
|
196
|
+
if (this.username && this.password) {
|
|
197
|
+
throw new MongoInvalidArgumentError(
|
|
198
|
+
`No password is allowed in ENVIRONMENT '${this.mechanismProperties.ENVIRONMENT}' for '${this.mechanism}'.`
|
|
199
|
+
);
|
|
193
200
|
}
|
|
194
201
|
|
|
195
202
|
if (
|
|
196
|
-
this.mechanismProperties.
|
|
197
|
-
|
|
203
|
+
(this.mechanismProperties.ENVIRONMENT === 'azure' ||
|
|
204
|
+
this.mechanismProperties.ENVIRONMENT === 'gcp') &&
|
|
205
|
+
!this.mechanismProperties.TOKEN_RESOURCE
|
|
198
206
|
) {
|
|
199
|
-
throw new MongoInvalidArgumentError(
|
|
200
|
-
`Currently only a PROVIDER_NAME in ${ALLOWED_PROVIDER_NAMES.join(
|
|
201
|
-
','
|
|
202
|
-
)} is supported for mechanism '${this.mechanism}'.`
|
|
203
|
-
);
|
|
207
|
+
throw new MongoInvalidArgumentError(TOKEN_RESOURCE_MISSING_ERROR);
|
|
204
208
|
}
|
|
205
209
|
|
|
206
210
|
if (
|
|
207
|
-
this.mechanismProperties.
|
|
208
|
-
!this.mechanismProperties.
|
|
211
|
+
this.mechanismProperties.ENVIRONMENT &&
|
|
212
|
+
!ALLOWED_ENVIRONMENT_NAMES.includes(this.mechanismProperties.ENVIRONMENT)
|
|
209
213
|
) {
|
|
210
214
|
throw new MongoInvalidArgumentError(
|
|
211
|
-
`
|
|
215
|
+
`Currently only a ENVIRONMENT in ${ALLOWED_ENVIRONMENT_NAMES.join(
|
|
216
|
+
','
|
|
217
|
+
)} is supported for mechanism '${this.mechanism}'.`
|
|
212
218
|
);
|
|
213
219
|
}
|
|
214
220
|
|
|
215
221
|
if (
|
|
216
|
-
!this.mechanismProperties.
|
|
217
|
-
!this.mechanismProperties.
|
|
222
|
+
!this.mechanismProperties.ENVIRONMENT &&
|
|
223
|
+
!this.mechanismProperties.OIDC_CALLBACK &&
|
|
224
|
+
!this.mechanismProperties.OIDC_HUMAN_CALLBACK
|
|
218
225
|
) {
|
|
219
226
|
throw new MongoInvalidArgumentError(
|
|
220
|
-
`Either a
|
|
227
|
+
`Either a ENVIRONMENT, OIDC_CALLBACK, or OIDC_HUMAN_CALLBACK must be specified for mechanism '${this.mechanism}'.`
|
|
221
228
|
);
|
|
222
229
|
}
|
|
223
230
|
|
|
@@ -0,0 +1,82 @@
|
|
|
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
|
+
try {
|
|
38
|
+
return await this.finishAuthentication(connection, credentials, token);
|
|
39
|
+
} catch (error) {
|
|
40
|
+
if (
|
|
41
|
+
error instanceof MongoError &&
|
|
42
|
+
error.code === MONGODB_ERROR_CODES.AuthenticationFailed
|
|
43
|
+
) {
|
|
44
|
+
this.cache.removeAccessToken();
|
|
45
|
+
return await this.execute(connection, credentials);
|
|
46
|
+
} else {
|
|
47
|
+
throw error;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
const response = await this.fetchAccessToken(credentials);
|
|
52
|
+
this.cache.put(response);
|
|
53
|
+
connection.accessToken = response.accessToken;
|
|
54
|
+
await this.finishAuthentication(connection, credentials, response.accessToken);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Fetches the access token using the callback.
|
|
59
|
+
*/
|
|
60
|
+
protected async fetchAccessToken(credentials: MongoCredentials): Promise<OIDCResponse> {
|
|
61
|
+
const controller = new AbortController();
|
|
62
|
+
const params: OIDCCallbackParams = {
|
|
63
|
+
timeoutContext: controller.signal,
|
|
64
|
+
version: OIDC_VERSION
|
|
65
|
+
};
|
|
66
|
+
if (credentials.username) {
|
|
67
|
+
params.username = credentials.username;
|
|
68
|
+
}
|
|
69
|
+
const timeout = Timeout.expires(AUTOMATED_TIMEOUT_MS);
|
|
70
|
+
try {
|
|
71
|
+
return await Promise.race([this.executeAndValidateCallback(params), timeout]);
|
|
72
|
+
} catch (error) {
|
|
73
|
+
if (TimeoutError.is(error)) {
|
|
74
|
+
controller.abort();
|
|
75
|
+
throw new MongoOIDCError(`OIDC callback timed out after ${AUTOMATED_TIMEOUT_MS}ms.`);
|
|
76
|
+
}
|
|
77
|
+
throw error;
|
|
78
|
+
} finally {
|
|
79
|
+
timeout.clear();
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
@@ -0,0 +1,85 @@
|
|
|
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 { MongoCredentials } from '../mongo_credentials';
|
|
5
|
+
import { type AccessToken, MachineWorkflow } from './machine_workflow';
|
|
6
|
+
import { type TokenCache } from './token_cache';
|
|
7
|
+
|
|
8
|
+
/** Azure request headers. */
|
|
9
|
+
const AZURE_HEADERS = Object.freeze({ Metadata: 'true', Accept: 'application/json' });
|
|
10
|
+
|
|
11
|
+
/** Invalid endpoint result error. */
|
|
12
|
+
const ENDPOINT_RESULT_ERROR =
|
|
13
|
+
'Azure endpoint did not return a value with only access_token and expires_in properties';
|
|
14
|
+
|
|
15
|
+
/** Error for when the token audience is missing in the environment. */
|
|
16
|
+
const TOKEN_RESOURCE_MISSING_ERROR =
|
|
17
|
+
'TOKEN_RESOURCE must be set in the auth mechanism properties when ENVIRONMENT is azure.';
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Device workflow implementation for Azure.
|
|
21
|
+
*
|
|
22
|
+
* @internal
|
|
23
|
+
*/
|
|
24
|
+
export class AzureMachineWorkflow extends MachineWorkflow {
|
|
25
|
+
/**
|
|
26
|
+
* Instantiate the machine workflow.
|
|
27
|
+
*/
|
|
28
|
+
constructor(cache: TokenCache) {
|
|
29
|
+
super(cache);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Get the token from the environment.
|
|
34
|
+
*/
|
|
35
|
+
async getToken(credentials?: MongoCredentials): Promise<AccessToken> {
|
|
36
|
+
const tokenAudience = credentials?.mechanismProperties.TOKEN_RESOURCE;
|
|
37
|
+
const username = credentials?.username;
|
|
38
|
+
if (!tokenAudience) {
|
|
39
|
+
throw new MongoAzureError(TOKEN_RESOURCE_MISSING_ERROR);
|
|
40
|
+
}
|
|
41
|
+
const response = await getAzureTokenData(tokenAudience, username);
|
|
42
|
+
if (!isEndpointResultValid(response)) {
|
|
43
|
+
throw new MongoAzureError(ENDPOINT_RESULT_ERROR);
|
|
44
|
+
}
|
|
45
|
+
return response;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Hit the Azure endpoint to get the token data.
|
|
51
|
+
*/
|
|
52
|
+
async function getAzureTokenData(tokenAudience: string, username?: string): Promise<AccessToken> {
|
|
53
|
+
const url = new URL(AZURE_BASE_URL);
|
|
54
|
+
addAzureParams(url, tokenAudience, username);
|
|
55
|
+
const response = await get(url, {
|
|
56
|
+
headers: AZURE_HEADERS
|
|
57
|
+
});
|
|
58
|
+
if (response.status !== 200) {
|
|
59
|
+
throw new MongoAzureError(
|
|
60
|
+
`Status code ${response.status} returned from the Azure endpoint. Response body: ${response.body}`
|
|
61
|
+
);
|
|
62
|
+
}
|
|
63
|
+
const result = JSON.parse(response.body);
|
|
64
|
+
return {
|
|
65
|
+
access_token: result.access_token,
|
|
66
|
+
expires_in: Number(result.expires_in)
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Determines if a result returned from the endpoint is valid.
|
|
72
|
+
* This means the result is not nullish, contains the access_token required field
|
|
73
|
+
* and the expires_in required field.
|
|
74
|
+
*/
|
|
75
|
+
function isEndpointResultValid(
|
|
76
|
+
token: unknown
|
|
77
|
+
): token is { access_token: unknown; expires_in: unknown } {
|
|
78
|
+
if (token == null || typeof token !== 'object') return false;
|
|
79
|
+
return (
|
|
80
|
+
'access_token' in token &&
|
|
81
|
+
typeof token.access_token === 'string' &&
|
|
82
|
+
'expires_in' in token &&
|
|
83
|
+
typeof token.expires_in === 'number'
|
|
84
|
+
);
|
|
85
|
+
}
|