Skip to content

Commit cb0e465

Browse files
committed
feat(NODE-6161): allow custom aws sdk config
1 parent 907aac1 commit cb0e465

File tree

5 files changed

+40
-5
lines changed

5 files changed

+40
-5
lines changed

src/cmap/auth/aws_temporary_credentials.ts

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ export interface AWSTempCredentials {
2121
Expiration?: Date;
2222
}
2323

24+
/** @internal */
25+
export type AWSCredentialProvider = () => Promise<AWSCredentials>;
26+
2427
/**
2528
* @internal
2629
*
@@ -41,7 +44,20 @@ export abstract class AWSTemporaryCredentialProvider {
4144

4245
/** @internal */
4346
export class AWSSDKCredentialProvider extends AWSTemporaryCredentialProvider {
44-
private _provider?: () => Promise<AWSCredentials>;
47+
private _provider?: AWSCredentialProvider;
48+
49+
/**
50+
* Create the SDK credentials provider.
51+
* @param credentialsProvider - The credentials provider.
52+
*/
53+
constructor(credentialsProvider?: AWSCredentialProvider) {
54+
super();
55+
56+
if (credentialsProvider) {
57+
this._provider = credentialsProvider;
58+
}
59+
}
60+
4561
/**
4662
* The AWS SDK caches credentials automatically and handles refresh when the credentials have expired.
4763
* To ensure this occurs, we need to cache the `provider` returned by the AWS sdk and re-use it when fetching credentials.

src/cmap/auth/mongodb_aws.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import {
99
import { ByteUtils, maxWireVersion, ns, randomBytes } from '../../utils';
1010
import { type AuthContext, AuthProvider } from './auth_provider';
1111
import {
12+
type AWSCredentialProvider,
1213
AWSSDKCredentialProvider,
1314
type AWSTempCredentials,
1415
AWSTemporaryCredentialProvider,
@@ -34,11 +35,11 @@ interface AWSSaslContinuePayload {
3435

3536
export class MongoDBAWS extends AuthProvider {
3637
private credentialFetcher: AWSTemporaryCredentialProvider;
37-
constructor() {
38+
constructor(credentialProvider?: AWSCredentialProvider) {
3839
super();
3940

4041
this.credentialFetcher = AWSTemporaryCredentialProvider.isAWSSDKInstalled
41-
? new AWSSDKCredentialProvider()
42+
? new AWSSDKCredentialProvider(credentialProvider)
4243
: new LegacyAWSTemporaryCredentialProvider();
4344
}
4445

src/connection_string.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import ConnectionString from 'mongodb-connection-string-url';
33
import { URLSearchParams } from 'url';
44

55
import type { Document } from './bson';
6+
import { type AWSCredentialProvider } from './cmap/auth/aws_temporary_credentials';
67
import { MongoCredentials } from './cmap/auth/mongo_credentials';
78
import { AUTH_MECHS_AUTH_SRC_EXTERNAL, AuthMechanism } from './cmap/auth/providers';
89
import { addContainerMetadata, makeClientMetadata } from './cmap/handshake/client_metadata';
@@ -751,6 +752,14 @@ export const OPTIONS = {
751752
autoSelectFamilyAttemptTimeout: {
752753
type: 'uint'
753754
},
755+
awsCredentialsProvider: {
756+
transform({ values: [value] }): AWSCredentialProvider {
757+
if (typeof value === 'function') {
758+
return value as AWSCredentialProvider;
759+
}
760+
throw new MongoParseError(`Option awsCredentialProvider must be a function, got ${value}`);
761+
}
762+
},
754763
bsonRegExp: {
755764
type: 'boolean'
756765
},

src/mongo_client.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import type { ConnectionOptions as TLSConnectionOptions, TLSSocketOptions } from
55
import { type BSONSerializeOptions, type Document, resolveBSONOptions } from './bson';
66
import { ChangeStream, type ChangeStreamDocument, type ChangeStreamOptions } from './change_stream';
77
import type { AutoEncrypter, AutoEncryptionOptions } from './client-side-encryption/auto_encrypter';
8+
import { type AWSCredentialProvider } from './cmap/auth/aws_temporary_credentials';
89
import {
910
type AuthMechanismProperties,
1011
DEFAULT_ALLOWED_HOSTS,
@@ -299,6 +300,10 @@ export interface MongoClientOptions extends BSONSerializeOptions, SupportedNodeC
299300
* TODO: NODE-5671 - remove internal flag
300301
*/
301302
mongodbLogMaxDocumentLength?: number;
303+
/**
304+
* A custom AWS SDK credentials provider to use instead of the default.
305+
*/
306+
awsCredentialsProvider?: AWSCredentialProvider;
302307

303308
/** @internal */
304309
__skipPingOnConnect?: boolean;

src/mongo_client_auth_providers.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { type AuthProvider } from './cmap/auth/auth_provider';
2+
import { type AWSCredentialProvider } from './cmap/auth/aws_temporary_credentials';
23
import { GSSAPI } from './cmap/auth/gssapi';
34
import { type AuthMechanismProperties } from './cmap/auth/mongo_credentials';
45
import { MongoDBAWS } from './cmap/auth/mongodb_aws';
@@ -13,8 +14,11 @@ import { X509 } from './cmap/auth/x509';
1314
import { MongoInvalidArgumentError } from './error';
1415

1516
/** @internal */
16-
const AUTH_PROVIDERS = new Map<AuthMechanism | string, (workflow?: Workflow) => AuthProvider>([
17-
[AuthMechanism.MONGODB_AWS, () => new MongoDBAWS()],
17+
const AUTH_PROVIDERS = new Map<AuthMechanism | string, (param?: any) => AuthProvider>([
18+
[
19+
AuthMechanism.MONGODB_AWS,
20+
(credentialProvider?: AWSCredentialProvider) => new MongoDBAWS(credentialProvider)
21+
],
1822
[
1923
AuthMechanism.MONGODB_CR,
2024
() => {

0 commit comments

Comments
 (0)