14
14
*/
15
15
16
16
//node.js deps
17
- const events = require ( 'events' ) ;
18
- const inherits = require ( 'util' ) . inherits ;
17
+ var events = require ( 'events' ) ;
18
+ var inherits = require ( 'util' ) . inherits ;
19
19
20
20
//npm deps
21
- const mqtt = require ( 'mqtt' ) ;
22
- const crypto = require ( 'crypto-js' ) ;
21
+ var mqtt = require ( 'mqtt' ) ;
22
+ var crypto = require ( 'crypto-js' ) ;
23
23
24
24
//app deps
25
- const exceptions = require ( './lib/exceptions' ) ,
26
- isUndefined = require ( '../common/lib/is-undefined' ) ,
27
- tlsReader = require ( '../common/lib/tls-reader' ) ;
25
+ var exceptions = require ( './lib/exceptions' ) ;
26
+ var isUndefined = require ( '../common/lib/is-undefined' ) ;
27
+ var tlsReader = require ( '../common/lib/tls-reader' ) ;
28
+ var path = require ( 'path' ) ;
29
+ var fs = require ( 'fs' ) ;
28
30
29
31
//begin module
30
32
function makeTwoDigits ( n ) {
@@ -157,6 +159,34 @@ function prepareWebSocketUrl(options, awsAccessId, awsSecretKey, awsSTSToken) {
157
159
return signUrl ( 'GET' , 'wss://' , hostName , path , queryParams ,
158
160
awsAccessId , awsSecretKey , options . region , awsServiceName , '' , today , now , options . debug , awsSTSToken ) ;
159
161
}
162
+
163
+ function arrayEach ( array , iterFunction ) {
164
+ for ( var idx in array ) {
165
+ if ( Object . prototype . hasOwnProperty . call ( array , idx ) ) {
166
+ iterFunction . call ( this , array [ idx ] , parseInt ( idx , 10 ) ) ;
167
+ }
168
+ }
169
+ }
170
+ function getCredentials ( ini ) {
171
+ //Get shared credential function from AWS SDK.
172
+ var map = { } ;
173
+ var currentSection = { } ;
174
+ arrayEach ( ini . split ( / \r ? \n / ) , function ( line ) {
175
+ line = line . split ( / ( ^ | \s ) [ ; # ] / ) [ 0 ] ; // remove comments
176
+ var section = line . match ( / ^ \s * \[ ( [ ^ \[ \] ] + ) \] \s * $ / ) ;
177
+ if ( section ) {
178
+ currentSection = section [ 1 ] ;
179
+ } else if ( currentSection ) {
180
+ var item = line . match ( / ^ \s * ( .+ ?) \s * = \s * ( .+ ?) \s * $ / ) ;
181
+ if ( item ) {
182
+ map [ currentSection ] = map [ currentSection ] || { } ;
183
+ map [ currentSection ] [ item [ 1 ] ] = item [ 2 ] ;
184
+ }
185
+ }
186
+ } ) ;
187
+ return map ;
188
+ }
189
+
160
190
//
161
191
// This method is the exposed module; it validates the mqtt options,
162
192
// creates a secure mqtt connection via TLS, and returns the mqtt
@@ -309,7 +339,6 @@ function DeviceClient(options) {
309
339
var awsAccessId ;
310
340
var awsSecretKey ;
311
341
var awsSTSToken ;
312
-
313
342
//
314
343
// Validate options, set default reconnect period if not specified.
315
344
//
@@ -374,11 +403,7 @@ function DeviceClient(options) {
374
403
}
375
404
376
405
if ( isUndefined ( options . host ) ) {
377
- if ( ! ( isUndefined ( options . region ) ) ) {
378
- options . host = 'data.iot.' + options . region + '.amazonaws.com' ;
379
- } else {
380
- throw new Error ( exceptions . INVALID_CONNECT_OPTIONS ) ;
381
- }
406
+ throw new Error ( exceptions . INVALID_CONNECT_OPTIONS ) ;
382
407
}
383
408
384
409
if ( options . protocol === 'mqtts' ) {
@@ -391,9 +416,9 @@ function DeviceClient(options) {
391
416
tlsReader ( options ) ;
392
417
} else if ( options . protocol === 'wss' ) {
393
418
//
394
- // AWS access id and secret key must be available as either
395
- // options or in the environment.
396
- //
419
+ // AWS access id and secret key
420
+ // It first check Input options and Environment variables
421
+ // If that not available, it will try to load credentials from default credential file
397
422
if ( ! isUndefined ( options . accessKeyId ) ) {
398
423
awsAccessId = options . accessKeyId ;
399
424
} else {
@@ -409,10 +434,34 @@ function DeviceClient(options) {
409
434
} else {
410
435
awsSTSToken = process . env . AWS_SESSION_TOKEN ;
411
436
}
412
- // AWS region must be defined when connecting via WebSocket/SigV4
413
- if ( isUndefined ( options . region ) ) {
414
- console . log ( 'AWS region must be defined when connecting via WebSocket/SigV4; see README.md' ) ;
415
- throw new Error ( exceptions . INVALID_CONNECT_OPTIONS ) ;
437
+ if ( isUndefined ( awsAccessId ) || isUndefined ( awsSecretKey ) ) {
438
+ var filename ;
439
+ try {
440
+ if ( ! isUndefined ( options . filename ) ) {
441
+ filename = options . filename ;
442
+ } else {
443
+ filename = _loadDefaultFilename ( ) ;
444
+ }
445
+ var user_profile = options . profile || process . env . AWS_PROFILE || 'default' ;
446
+ var creds = getCredentials ( fs . readFileSync ( filename , 'utf-8' ) ) ;
447
+ var profile = creds [ user_profile ] ;
448
+ awsAccessId = profile . aws_access_key_id ;
449
+ awsSecretKey = profile . aws_secret_access_key ;
450
+ awsSTSToken = profile . aws_session_token ;
451
+ } catch ( e ) {
452
+ console . log ( e ) ;
453
+ console . log ( "Failed to read credentials from " + filename ) ;
454
+ }
455
+ }
456
+ if ( ! isUndefined ( options . host ) ) {
457
+ var pattern = / [ a - z A - Z 0 - 9 ] + \. i o t \. ( [ a - z ] + - [ a - z ] + - [ 0 - 9 ] + ) \. a m a z o n a w s \. c o m / ;
458
+ var region = pattern . exec ( options . host ) ;
459
+ if ( region === null ) {
460
+ console . log ( 'Host endpoint is not valid' ) ;
461
+ throw new Error ( exceptions . INVALID_CONNECT_OPTIONS ) ;
462
+ } else {
463
+ options . region = region [ 1 ] ;
464
+ }
416
465
}
417
466
// AWS Access Key ID and AWS Secret Key must be defined
418
467
if ( isUndefined ( awsAccessId ) || ( isUndefined ( awsSecretKey ) ) ) {
@@ -443,6 +492,13 @@ function DeviceClient(options) {
443
492
protocols . mqtts = require ( './lib/tls' ) ;
444
493
protocols . wss = require ( './lib/ws' ) ;
445
494
495
+ function _loadDefaultFilename ( ) {
496
+ var home = process . env . HOME ||
497
+ process . env . USERPROFILE ||
498
+ ( process . env . HOMEPATH ? ( ( process . env . HOMEDRIVE || 'C:/' ) + process . env . HOMEPATH ) : null ) ;
499
+ return path . join ( home , '.aws' , 'credentials' ) ;
500
+
501
+ }
446
502
function _addToSubscriptionCache ( topic , options ) {
447
503
var matches = activeSubscriptions . filter ( function ( element ) {
448
504
return element . topic === topic ;
@@ -521,7 +577,7 @@ function DeviceClient(options) {
521
577
return protocols [ options . protocol ] ( client , options ) ;
522
578
}
523
579
524
- const device = new mqtt . MqttClient ( _wrapper , options ) ;
580
+ var device = new mqtt . MqttClient ( _wrapper , options ) ;
525
581
526
582
//handle events from the mqtt client
527
583
@@ -730,7 +786,7 @@ function DeviceClient(options) {
730
786
device . subscribe ( topics , options , callback ) ;
731
787
} else {
732
788
device . subscribe ( topics , options ) ;
733
- }
789
+ }
734
790
} else {
735
791
// we're offline - queue this subscription request
736
792
if ( offlineSubscriptionQueue . length < offlineSubscriptionQueueMaxSize ) {
0 commit comments