@@ -14,6 +14,7 @@ import type { BSONSerializeOptions } from '../../bson';
14
14
15
15
import { aws4 } from '../../deps' ;
16
16
import { AuthMechanism } from './defaultAuthProviders' ;
17
+ import type { Binary } from 'bson' ;
17
18
18
19
const ASCII_N = 110 ;
19
20
const AWS_RELATIVE_URI = 'http://169.254.170.2' ;
@@ -64,10 +65,19 @@ export class MongoDBAWS extends AuthProvider {
64
65
return ;
65
66
}
66
67
67
- const username = credentials . username ;
68
- const password = credentials . password ;
68
+ const accessKeyId = credentials . username ;
69
+ const secretAccessKey = credentials . password ;
70
+ const sessionToken = credentials . mechanismProperties . AWS_SESSION_TOKEN ;
71
+
72
+ // If all three defined, include sessionToken, else include username and pass, else no credentials
73
+ const awsCredentials =
74
+ accessKeyId && secretAccessKey && sessionToken
75
+ ? { accessKeyId, secretAccessKey, sessionToken }
76
+ : accessKeyId && secretAccessKey
77
+ ? { accessKeyId, secretAccessKey }
78
+ : undefined ;
79
+
69
80
const db = credentials . source ;
70
- const token = credentials . mechanismProperties . AWS_SESSION_TOKEN ;
71
81
crypto . randomBytes ( 32 , ( err , nonce ) => {
72
82
if ( err ) {
73
83
callback ( err ) ;
@@ -83,7 +93,10 @@ export class MongoDBAWS extends AuthProvider {
83
93
connection . command ( ns ( `${ db } .$cmd` ) , saslStart , undefined , ( err , res ) => {
84
94
if ( err ) return callback ( err ) ;
85
95
86
- const serverResponse = BSON . deserialize ( res . payload . buffer , bsonOptions ) ;
96
+ const serverResponse = BSON . deserialize ( res . payload . buffer , bsonOptions ) as {
97
+ s : Binary ;
98
+ h : string ;
99
+ } ;
87
100
const host = serverResponse . h ;
88
101
const serverNonce = serverResponse . s . buffer ;
89
102
if ( serverNonce . length !== 64 ) {
@@ -123,18 +136,15 @@ export class MongoDBAWS extends AuthProvider {
123
136
path : '/' ,
124
137
body
125
138
} ,
126
- {
127
- accessKeyId : username ,
128
- secretAccessKey : password ,
129
- token
130
- }
139
+ awsCredentials
131
140
) ;
132
141
133
- const authorization = options . headers . Authorization ;
134
- const date = options . headers [ 'X-Amz-Date' ] ;
135
- const payload : AWSSaslContinuePayload = { a : authorization , d : date } ;
136
- if ( token ) {
137
- payload . t = token ;
142
+ const payload : AWSSaslContinuePayload = {
143
+ a : options . headers . Authorization ,
144
+ d : options . headers [ 'X-Amz-Date' ]
145
+ } ;
146
+ if ( sessionToken ) {
147
+ payload . t = sessionToken ;
138
148
}
139
149
140
150
const saslContinue = {
@@ -149,14 +159,16 @@ export class MongoDBAWS extends AuthProvider {
149
159
}
150
160
}
151
161
152
- interface AWSCredentials {
162
+ interface AWSTempCredentials {
153
163
AccessKeyId ?: string ;
154
164
SecretAccessKey ?: string ;
155
165
Token ?: string ;
166
+ RoleArn ?: string ;
167
+ Expiration ?: Date ;
156
168
}
157
169
158
170
function makeTempCredentials ( credentials : MongoCredentials , callback : Callback < MongoCredentials > ) {
159
- function done ( creds : AWSCredentials ) {
171
+ function done ( creds : AWSTempCredentials ) {
160
172
if ( ! creds . AccessKeyId || ! creds . SecretAccessKey || ! creds . Token ) {
161
173
callback (
162
174
new MongoMissingCredentialsError ( 'Could not obtain temporary MONGODB-AWS credentials' )
@@ -183,6 +195,7 @@ function makeTempCredentials(credentials: MongoCredentials, callback: Callback<M
183
195
if ( process . env . AWS_CONTAINER_CREDENTIALS_RELATIVE_URI ) {
184
196
request (
185
197
`${ AWS_RELATIVE_URI } ${ process . env . AWS_CONTAINER_CREDENTIALS_RELATIVE_URI } ` ,
198
+ undefined ,
186
199
( err , res ) => {
187
200
if ( err ) return callback ( err ) ;
188
201
done ( res ) ;
@@ -239,27 +252,15 @@ interface RequestOptions {
239
252
headers ?: http . OutgoingHttpHeaders ;
240
253
}
241
254
242
- function request ( uri : string , callback : Callback ) : void ;
243
- function request ( uri : string , options : RequestOptions , callback : Callback ) : void ;
244
- function request ( uri : string , _options : RequestOptions | Callback , _callback ?: Callback ) {
245
- let options = _options as RequestOptions ;
246
- if ( 'function' === typeof _options ) {
247
- options = { } ;
248
- }
249
-
250
- let callback : Callback = _options as Callback ;
251
- if ( _callback ) {
252
- callback = _callback ;
253
- }
254
-
255
- options = Object . assign (
255
+ function request ( uri : string , _options : RequestOptions | undefined , callback : Callback ) {
256
+ const options = Object . assign (
256
257
{
257
258
method : 'GET' ,
258
259
timeout : 10000 ,
259
260
json : true
260
261
} ,
261
262
url . parse ( uri ) ,
262
- options
263
+ _options
263
264
) ;
264
265
265
266
const req = http . request ( options , res => {
0 commit comments