1414 */
1515
1616//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 ;
1919
2020//npm deps
21- const mqtt = require ( 'mqtt' ) ;
22- const crypto = require ( 'crypto-js' ) ;
21+ var mqtt = require ( 'mqtt' ) ;
22+ var crypto = require ( 'crypto-js' ) ;
2323
2424//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' ) ;
2830
2931//begin module
3032function makeTwoDigits ( n ) {
@@ -157,6 +159,34 @@ function prepareWebSocketUrl(options, awsAccessId, awsSecretKey, awsSTSToken) {
157159 return signUrl ( 'GET' , 'wss://' , hostName , path , queryParams ,
158160 awsAccessId , awsSecretKey , options . region , awsServiceName , '' , today , now , options . debug , awsSTSToken ) ;
159161}
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+
160190//
161191// This method is the exposed module; it validates the mqtt options,
162192// creates a secure mqtt connection via TLS, and returns the mqtt
@@ -309,7 +339,6 @@ function DeviceClient(options) {
309339 var awsAccessId ;
310340 var awsSecretKey ;
311341 var awsSTSToken ;
312-
313342 //
314343 // Validate options, set default reconnect period if not specified.
315344 //
@@ -374,11 +403,7 @@ function DeviceClient(options) {
374403 }
375404
376405 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 ) ;
382407 }
383408
384409 if ( options . protocol === 'mqtts' ) {
@@ -391,9 +416,9 @@ function DeviceClient(options) {
391416 tlsReader ( options ) ;
392417 } else if ( options . protocol === 'wss' ) {
393418 //
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
397422 if ( ! isUndefined ( options . accessKeyId ) ) {
398423 awsAccessId = options . accessKeyId ;
399424 } else {
@@ -409,10 +434,34 @@ function DeviceClient(options) {
409434 } else {
410435 awsSTSToken = process . env . AWS_SESSION_TOKEN ;
411436 }
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+ }
416465 }
417466 // AWS Access Key ID and AWS Secret Key must be defined
418467 if ( isUndefined ( awsAccessId ) || ( isUndefined ( awsSecretKey ) ) ) {
@@ -443,6 +492,13 @@ function DeviceClient(options) {
443492 protocols . mqtts = require ( './lib/tls' ) ;
444493 protocols . wss = require ( './lib/ws' ) ;
445494
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+ }
446502 function _addToSubscriptionCache ( topic , options ) {
447503 var matches = activeSubscriptions . filter ( function ( element ) {
448504 return element . topic === topic ;
@@ -521,7 +577,7 @@ function DeviceClient(options) {
521577 return protocols [ options . protocol ] ( client , options ) ;
522578 }
523579
524- const device = new mqtt . MqttClient ( _wrapper , options ) ;
580+ var device = new mqtt . MqttClient ( _wrapper , options ) ;
525581
526582 //handle events from the mqtt client
527583
@@ -730,7 +786,7 @@ function DeviceClient(options) {
730786 device . subscribe ( topics , options , callback ) ;
731787 } else {
732788 device . subscribe ( topics , options ) ;
733- }
789+ }
734790 } else {
735791 // we're offline - queue this subscription request
736792 if ( offlineSubscriptionQueue . length < offlineSubscriptionQueueMaxSize ) {
0 commit comments