UNPKG

67.8 kBJavaScriptView Raw
1"use strict";
2
3exports.__esModule = true;
4exports["default"] = void 0;
5
6var _buffer = require("buffer");
7
8var _core = _interopRequireDefault(require("crypto-js/core"));
9
10var _libTypedarrays = _interopRequireDefault(require("crypto-js/lib-typedarrays"));
11
12var _encBase = _interopRequireDefault(require("crypto-js/enc-base64"));
13
14var _hmacSha = _interopRequireDefault(require("crypto-js/hmac-sha256"));
15
16var _BigInteger = _interopRequireDefault(require("./BigInteger"));
17
18var _AuthenticationHelper = _interopRequireDefault(require("./AuthenticationHelper"));
19
20var _CognitoAccessToken = _interopRequireDefault(require("./CognitoAccessToken"));
21
22var _CognitoIdToken = _interopRequireDefault(require("./CognitoIdToken"));
23
24var _CognitoRefreshToken = _interopRequireDefault(require("./CognitoRefreshToken"));
25
26var _CognitoUserSession = _interopRequireDefault(require("./CognitoUserSession"));
27
28var _DateHelper = _interopRequireDefault(require("./DateHelper"));
29
30var _CognitoUserAttribute = _interopRequireDefault(require("./CognitoUserAttribute"));
31
32var _StorageHelper = _interopRequireDefault(require("./StorageHelper"));
33
34function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
35
36/*!
37 * Copyright 2016 Amazon.com,
38 * Inc. or its affiliates. All Rights Reserved.
39 *
40 * Licensed under the Amazon Software License (the "License").
41 * You may not use this file except in compliance with the
42 * License. A copy of the License is located at
43 *
44 * http://aws.amazon.com/asl/
45 *
46 * or in the "license" file accompanying this file. This file is
47 * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
48 * CONDITIONS OF ANY KIND, express or implied. See the License
49 * for the specific language governing permissions and
50 * limitations under the License.
51 */
52// necessary for crypto js
53
54/**
55 * @callback nodeCallback
56 * @template T result
57 * @param {*} err The operation failure reason, or null.
58 * @param {T} result The operation result.
59 */
60
61/**
62 * @callback onFailure
63 * @param {*} err Failure reason.
64 */
65
66/**
67 * @callback onSuccess
68 * @template T result
69 * @param {T} result The operation result.
70 */
71
72/**
73 * @callback mfaRequired
74 * @param {*} details MFA challenge details.
75 */
76
77/**
78 * @callback customChallenge
79 * @param {*} details Custom challenge details.
80 */
81
82/**
83 * @callback inputVerificationCode
84 * @param {*} data Server response.
85 */
86
87/**
88 * @callback authSuccess
89 * @param {CognitoUserSession} session The new session.
90 * @param {bool=} userConfirmationNecessary User must be confirmed.
91 */
92var isBrowser = typeof navigator !== 'undefined';
93var userAgent = isBrowser ? navigator.userAgent : 'nodejs';
94/** @class */
95
96var CognitoUser = /*#__PURE__*/function () {
97 /**
98 * Constructs a new CognitoUser object
99 * @param {object} data Creation options
100 * @param {string} data.Username The user's username.
101 * @param {CognitoUserPool} data.Pool Pool containing the user.
102 * @param {object} data.Storage Optional storage object.
103 */
104 function CognitoUser(data) {
105 if (data == null || data.Username == null || data.Pool == null) {
106 throw new Error('Username and pool information are required.');
107 }
108
109 this.username = data.Username || '';
110 this.pool = data.Pool;
111 this.Session = null;
112 this.client = data.Pool.client;
113 this.signInUserSession = null;
114 this.authenticationFlowType = 'USER_SRP_AUTH';
115 this.storage = data.Storage || new _StorageHelper["default"]().getStorage();
116 this.keyPrefix = "CognitoIdentityServiceProvider." + this.pool.getClientId();
117 this.userDataKey = this.keyPrefix + "." + this.username + ".userData";
118 }
119 /**
120 * Sets the session for this user
121 * @param {CognitoUserSession} signInUserSession the session
122 * @returns {void}
123 */
124
125
126 var _proto = CognitoUser.prototype;
127
128 _proto.setSignInUserSession = function setSignInUserSession(signInUserSession) {
129 this.clearCachedUserData();
130 this.signInUserSession = signInUserSession;
131 this.cacheTokens();
132 }
133 /**
134 * @returns {CognitoUserSession} the current session for this user
135 */
136 ;
137
138 _proto.getSignInUserSession = function getSignInUserSession() {
139 return this.signInUserSession;
140 }
141 /**
142 * @returns {string} the user's username
143 */
144 ;
145
146 _proto.getUsername = function getUsername() {
147 return this.username;
148 }
149 /**
150 * @returns {String} the authentication flow type
151 */
152 ;
153
154 _proto.getAuthenticationFlowType = function getAuthenticationFlowType() {
155 return this.authenticationFlowType;
156 }
157 /**
158 * sets authentication flow type
159 * @param {string} authenticationFlowType New value.
160 * @returns {void}
161 */
162 ;
163
164 _proto.setAuthenticationFlowType = function setAuthenticationFlowType(authenticationFlowType) {
165 this.authenticationFlowType = authenticationFlowType;
166 }
167 /**
168 * This is used for authenticating the user through the custom authentication flow.
169 * @param {AuthenticationDetails} authDetails Contains the authentication data
170 * @param {object} callback Result callback map.
171 * @param {onFailure} callback.onFailure Called on any error.
172 * @param {customChallenge} callback.customChallenge Custom challenge
173 * response required to continue.
174 * @param {authSuccess} callback.onSuccess Called on success with the new session.
175 * @returns {void}
176 */
177 ;
178
179 _proto.initiateAuth = function initiateAuth(authDetails, callback) {
180 var _this = this;
181
182 var authParameters = authDetails.getAuthParameters();
183 authParameters.USERNAME = this.username;
184 var clientMetaData = Object.keys(authDetails.getValidationData()).length !== 0 ? authDetails.getValidationData() : authDetails.getClientMetadata();
185 var jsonReq = {
186 AuthFlow: 'CUSTOM_AUTH',
187 ClientId: this.pool.getClientId(),
188 AuthParameters: authParameters,
189 ClientMetadata: clientMetaData
190 };
191
192 if (this.getUserContextData()) {
193 jsonReq.UserContextData = this.getUserContextData();
194 }
195
196 this.client.request('InitiateAuth', jsonReq, function (err, data) {
197 if (err) {
198 return callback.onFailure(err);
199 }
200
201 var challengeName = data.ChallengeName;
202 var challengeParameters = data.ChallengeParameters;
203
204 if (challengeName === 'CUSTOM_CHALLENGE') {
205 _this.Session = data.Session;
206 return callback.customChallenge(challengeParameters);
207 }
208
209 _this.signInUserSession = _this.getCognitoUserSession(data.AuthenticationResult);
210
211 _this.cacheTokens();
212
213 return callback.onSuccess(_this.signInUserSession);
214 });
215 }
216 /**
217 * This is used for authenticating the user.
218 * stuff
219 * @param {AuthenticationDetails} authDetails Contains the authentication data
220 * @param {object} callback Result callback map.
221 * @param {onFailure} callback.onFailure Called on any error.
222 * @param {newPasswordRequired} callback.newPasswordRequired new
223 * password and any required attributes are required to continue
224 * @param {mfaRequired} callback.mfaRequired MFA code
225 * required to continue.
226 * @param {customChallenge} callback.customChallenge Custom challenge
227 * response required to continue.
228 * @param {authSuccess} callback.onSuccess Called on success with the new session.
229 * @returns {void}
230 */
231 ;
232
233 _proto.authenticateUser = function authenticateUser(authDetails, callback) {
234 if (this.authenticationFlowType === 'USER_PASSWORD_AUTH') {
235 return this.authenticateUserPlainUsernamePassword(authDetails, callback);
236 } else if (this.authenticationFlowType === 'USER_SRP_AUTH' || this.authenticationFlowType === 'CUSTOM_AUTH') {
237 return this.authenticateUserDefaultAuth(authDetails, callback);
238 }
239
240 return callback.onFailure(new Error('Authentication flow type is invalid.'));
241 }
242 /**
243 * PRIVATE ONLY: This is an internal only method and should not
244 * be directly called by the consumers.
245 * It calls the AuthenticationHelper for SRP related
246 * stuff
247 * @param {AuthenticationDetails} authDetails Contains the authentication data
248 * @param {object} callback Result callback map.
249 * @param {onFailure} callback.onFailure Called on any error.
250 * @param {newPasswordRequired} callback.newPasswordRequired new
251 * password and any required attributes are required to continue
252 * @param {mfaRequired} callback.mfaRequired MFA code
253 * required to continue.
254 * @param {customChallenge} callback.customChallenge Custom challenge
255 * response required to continue.
256 * @param {authSuccess} callback.onSuccess Called on success with the new session.
257 * @returns {void}
258 */
259 ;
260
261 _proto.authenticateUserDefaultAuth = function authenticateUserDefaultAuth(authDetails, callback) {
262 var _this2 = this;
263
264 var authenticationHelper = new _AuthenticationHelper["default"](this.pool.getUserPoolId().split('_')[1]);
265 var dateHelper = new _DateHelper["default"]();
266 var serverBValue;
267 var salt;
268 var authParameters = {};
269
270 if (this.deviceKey != null) {
271 authParameters.DEVICE_KEY = this.deviceKey;
272 }
273
274 authParameters.USERNAME = this.username;
275 authenticationHelper.getLargeAValue(function (errOnAValue, aValue) {
276 // getLargeAValue callback start
277 if (errOnAValue) {
278 callback.onFailure(errOnAValue);
279 }
280
281 authParameters.SRP_A = aValue.toString(16);
282
283 if (_this2.authenticationFlowType === 'CUSTOM_AUTH') {
284 authParameters.CHALLENGE_NAME = 'SRP_A';
285 }
286
287 var clientMetaData = Object.keys(authDetails.getValidationData()).length !== 0 ? authDetails.getValidationData() : authDetails.getClientMetadata();
288 var jsonReq = {
289 AuthFlow: _this2.authenticationFlowType,
290 ClientId: _this2.pool.getClientId(),
291 AuthParameters: authParameters,
292 ClientMetadata: clientMetaData
293 };
294
295 if (_this2.getUserContextData(_this2.username)) {
296 jsonReq.UserContextData = _this2.getUserContextData(_this2.username);
297 }
298
299 _this2.client.request('InitiateAuth', jsonReq, function (err, data) {
300 if (err) {
301 return callback.onFailure(err);
302 }
303
304 var challengeParameters = data.ChallengeParameters;
305 _this2.username = challengeParameters.USER_ID_FOR_SRP;
306 serverBValue = new _BigInteger["default"](challengeParameters.SRP_B, 16);
307 salt = new _BigInteger["default"](challengeParameters.SALT, 16);
308
309 _this2.getCachedDeviceKeyAndPassword();
310
311 authenticationHelper.getPasswordAuthenticationKey(_this2.username, authDetails.getPassword(), serverBValue, salt, function (errOnHkdf, hkdf) {
312 // getPasswordAuthenticationKey callback start
313 if (errOnHkdf) {
314 callback.onFailure(errOnHkdf);
315 }
316
317 var dateNow = dateHelper.getNowString();
318
319 var message = _core["default"].lib.WordArray.create(_buffer.Buffer.concat([_buffer.Buffer.from(_this2.pool.getUserPoolId().split('_')[1], 'utf8'), _buffer.Buffer.from(_this2.username, 'utf8'), _buffer.Buffer.from(challengeParameters.SECRET_BLOCK, 'base64'), _buffer.Buffer.from(dateNow, 'utf8')]));
320
321 var key = _core["default"].lib.WordArray.create(hkdf);
322
323 var signatureString = _encBase["default"].stringify((0, _hmacSha["default"])(message, key));
324
325 var challengeResponses = {};
326 challengeResponses.USERNAME = _this2.username;
327 challengeResponses.PASSWORD_CLAIM_SECRET_BLOCK = challengeParameters.SECRET_BLOCK;
328 challengeResponses.TIMESTAMP = dateNow;
329 challengeResponses.PASSWORD_CLAIM_SIGNATURE = signatureString;
330
331 if (_this2.deviceKey != null) {
332 challengeResponses.DEVICE_KEY = _this2.deviceKey;
333 }
334
335 var respondToAuthChallenge = function respondToAuthChallenge(challenge, challengeCallback) {
336 return _this2.client.request('RespondToAuthChallenge', challenge, function (errChallenge, dataChallenge) {
337 if (errChallenge && errChallenge.code === 'ResourceNotFoundException' && errChallenge.message.toLowerCase().indexOf('device') !== -1) {
338 challengeResponses.DEVICE_KEY = null;
339 _this2.deviceKey = null;
340 _this2.randomPassword = null;
341 _this2.deviceGroupKey = null;
342
343 _this2.clearCachedDeviceKeyAndPassword();
344
345 return respondToAuthChallenge(challenge, challengeCallback);
346 }
347
348 return challengeCallback(errChallenge, dataChallenge);
349 });
350 };
351
352 var jsonReqResp = {
353 ChallengeName: 'PASSWORD_VERIFIER',
354 ClientId: _this2.pool.getClientId(),
355 ChallengeResponses: challengeResponses,
356 Session: data.Session,
357 ClientMetadata: clientMetaData
358 };
359
360 if (_this2.getUserContextData()) {
361 jsonReqResp.UserContextData = _this2.getUserContextData();
362 }
363
364 respondToAuthChallenge(jsonReqResp, function (errAuthenticate, dataAuthenticate) {
365 if (errAuthenticate) {
366 return callback.onFailure(errAuthenticate);
367 }
368
369 return _this2.authenticateUserInternal(dataAuthenticate, authenticationHelper, callback);
370 });
371 return undefined; // getPasswordAuthenticationKey callback end
372 });
373 return undefined;
374 }); // getLargeAValue callback end
375
376 });
377 }
378 /**
379 * PRIVATE ONLY: This is an internal only method and should not
380 * be directly called by the consumers.
381 * @param {AuthenticationDetails} authDetails Contains the authentication data.
382 * @param {object} callback Result callback map.
383 * @param {onFailure} callback.onFailure Called on any error.
384 * @param {mfaRequired} callback.mfaRequired MFA code
385 * required to continue.
386 * @param {authSuccess} callback.onSuccess Called on success with the new session.
387 * @returns {void}
388 */
389 ;
390
391 _proto.authenticateUserPlainUsernamePassword = function authenticateUserPlainUsernamePassword(authDetails, callback) {
392 var _this3 = this;
393
394 var authParameters = {};
395 authParameters.USERNAME = this.username;
396 authParameters.PASSWORD = authDetails.getPassword();
397
398 if (!authParameters.PASSWORD) {
399 callback.onFailure(new Error('PASSWORD parameter is required'));
400 return;
401 }
402
403 var authenticationHelper = new _AuthenticationHelper["default"](this.pool.getUserPoolId().split('_')[1]);
404 this.getCachedDeviceKeyAndPassword();
405
406 if (this.deviceKey != null) {
407 authParameters.DEVICE_KEY = this.deviceKey;
408 }
409
410 var clientMetaData = Object.keys(authDetails.getValidationData()).length !== 0 ? authDetails.getValidationData() : authDetails.getClientMetadata();
411 var jsonReq = {
412 AuthFlow: 'USER_PASSWORD_AUTH',
413 ClientId: this.pool.getClientId(),
414 AuthParameters: authParameters,
415 ClientMetadata: clientMetaData
416 };
417
418 if (this.getUserContextData(this.username)) {
419 jsonReq.UserContextData = this.getUserContextData(this.username);
420 } // USER_PASSWORD_AUTH happens in a single round-trip: client sends userName and password,
421 // Cognito UserPools verifies password and returns tokens.
422
423
424 this.client.request('InitiateAuth', jsonReq, function (err, authResult) {
425 if (err) {
426 return callback.onFailure(err);
427 }
428
429 return _this3.authenticateUserInternal(authResult, authenticationHelper, callback);
430 });
431 }
432 /**
433 * PRIVATE ONLY: This is an internal only method and should not
434 * be directly called by the consumers.
435 * @param {object} dataAuthenticate authentication data
436 * @param {object} authenticationHelper helper created
437 * @param {callback} callback passed on from caller
438 * @returns {void}
439 */
440 ;
441
442 _proto.authenticateUserInternal = function authenticateUserInternal(dataAuthenticate, authenticationHelper, callback) {
443 var _this4 = this;
444
445 var challengeName = dataAuthenticate.ChallengeName;
446 var challengeParameters = dataAuthenticate.ChallengeParameters;
447
448 if (challengeName === 'SMS_MFA') {
449 this.Session = dataAuthenticate.Session;
450 return callback.mfaRequired(challengeName, challengeParameters);
451 }
452
453 if (challengeName === 'SELECT_MFA_TYPE') {
454 this.Session = dataAuthenticate.Session;
455 return callback.selectMFAType(challengeName, challengeParameters);
456 }
457
458 if (challengeName === 'MFA_SETUP') {
459 this.Session = dataAuthenticate.Session;
460 return callback.mfaSetup(challengeName, challengeParameters);
461 }
462
463 if (challengeName === 'SOFTWARE_TOKEN_MFA') {
464 this.Session = dataAuthenticate.Session;
465 return callback.totpRequired(challengeName, challengeParameters);
466 }
467
468 if (challengeName === 'CUSTOM_CHALLENGE') {
469 this.Session = dataAuthenticate.Session;
470 return callback.customChallenge(challengeParameters);
471 }
472
473 if (challengeName === 'NEW_PASSWORD_REQUIRED') {
474 this.Session = dataAuthenticate.Session;
475 var userAttributes = null;
476 var rawRequiredAttributes = null;
477 var requiredAttributes = [];
478 var userAttributesPrefix = authenticationHelper.getNewPasswordRequiredChallengeUserAttributePrefix();
479
480 if (challengeParameters) {
481 userAttributes = JSON.parse(dataAuthenticate.ChallengeParameters.userAttributes);
482 rawRequiredAttributes = JSON.parse(dataAuthenticate.ChallengeParameters.requiredAttributes);
483 }
484
485 if (rawRequiredAttributes) {
486 for (var i = 0; i < rawRequiredAttributes.length; i++) {
487 requiredAttributes[i] = rawRequiredAttributes[i].substr(userAttributesPrefix.length);
488 }
489 }
490
491 return callback.newPasswordRequired(userAttributes, requiredAttributes);
492 }
493
494 if (challengeName === 'DEVICE_SRP_AUTH') {
495 this.getDeviceResponse(callback);
496 return undefined;
497 }
498
499 this.signInUserSession = this.getCognitoUserSession(dataAuthenticate.AuthenticationResult);
500 this.challengeName = challengeName;
501 this.cacheTokens();
502 var newDeviceMetadata = dataAuthenticate.AuthenticationResult.NewDeviceMetadata;
503
504 if (newDeviceMetadata == null) {
505 return callback.onSuccess(this.signInUserSession);
506 }
507
508 authenticationHelper.generateHashDevice(dataAuthenticate.AuthenticationResult.NewDeviceMetadata.DeviceGroupKey, dataAuthenticate.AuthenticationResult.NewDeviceMetadata.DeviceKey, function (errGenHash) {
509 if (errGenHash) {
510 return callback.onFailure(errGenHash);
511 }
512
513 var deviceSecretVerifierConfig = {
514 Salt: _buffer.Buffer.from(authenticationHelper.getSaltDevices(), 'hex').toString('base64'),
515 PasswordVerifier: _buffer.Buffer.from(authenticationHelper.getVerifierDevices(), 'hex').toString('base64')
516 };
517 _this4.verifierDevices = deviceSecretVerifierConfig.PasswordVerifier;
518 _this4.deviceGroupKey = newDeviceMetadata.DeviceGroupKey;
519 _this4.randomPassword = authenticationHelper.getRandomPassword();
520
521 _this4.client.request('ConfirmDevice', {
522 DeviceKey: newDeviceMetadata.DeviceKey,
523 AccessToken: _this4.signInUserSession.getAccessToken().getJwtToken(),
524 DeviceSecretVerifierConfig: deviceSecretVerifierConfig,
525 DeviceName: userAgent
526 }, function (errConfirm, dataConfirm) {
527 if (errConfirm) {
528 return callback.onFailure(errConfirm);
529 }
530
531 _this4.deviceKey = dataAuthenticate.AuthenticationResult.NewDeviceMetadata.DeviceKey;
532
533 _this4.cacheDeviceKeyAndPassword();
534
535 if (dataConfirm.UserConfirmationNecessary === true) {
536 return callback.onSuccess(_this4.signInUserSession, dataConfirm.UserConfirmationNecessary);
537 }
538
539 return callback.onSuccess(_this4.signInUserSession);
540 });
541
542 return undefined;
543 });
544 return undefined;
545 }
546 /**
547 * This method is user to complete the NEW_PASSWORD_REQUIRED challenge.
548 * Pass the new password with any new user attributes to be updated.
549 * User attribute keys must be of format userAttributes.<attribute_name>.
550 * @param {string} newPassword new password for this user
551 * @param {object} requiredAttributeData map with values for all required attributes
552 * @param {object} callback Result callback map.
553 * @param {onFailure} callback.onFailure Called on any error.
554 * @param {mfaRequired} callback.mfaRequired MFA code required to continue.
555 * @param {customChallenge} callback.customChallenge Custom challenge
556 * response required to continue.
557 * @param {authSuccess} callback.onSuccess Called on success with the new session.
558 * @param {ClientMetadata} clientMetadata object which is passed from client to Cognito Lambda trigger
559 * @returns {void}
560 */
561 ;
562
563 _proto.completeNewPasswordChallenge = function completeNewPasswordChallenge(newPassword, requiredAttributeData, callback, clientMetadata) {
564 var _this5 = this;
565
566 if (!newPassword) {
567 return callback.onFailure(new Error('New password is required.'));
568 }
569
570 var authenticationHelper = new _AuthenticationHelper["default"](this.pool.getUserPoolId().split('_')[1]);
571 var userAttributesPrefix = authenticationHelper.getNewPasswordRequiredChallengeUserAttributePrefix();
572 var finalUserAttributes = {};
573
574 if (requiredAttributeData) {
575 Object.keys(requiredAttributeData).forEach(function (key) {
576 finalUserAttributes[userAttributesPrefix + key] = requiredAttributeData[key];
577 });
578 }
579
580 finalUserAttributes.NEW_PASSWORD = newPassword;
581 finalUserAttributes.USERNAME = this.username;
582 var jsonReq = {
583 ChallengeName: 'NEW_PASSWORD_REQUIRED',
584 ClientId: this.pool.getClientId(),
585 ChallengeResponses: finalUserAttributes,
586 Session: this.Session,
587 ClientMetadata: clientMetadata
588 };
589
590 if (this.getUserContextData()) {
591 jsonReq.UserContextData = this.getUserContextData();
592 }
593
594 this.client.request('RespondToAuthChallenge', jsonReq, function (errAuthenticate, dataAuthenticate) {
595 if (errAuthenticate) {
596 return callback.onFailure(errAuthenticate);
597 }
598
599 return _this5.authenticateUserInternal(dataAuthenticate, authenticationHelper, callback);
600 });
601 return undefined;
602 }
603 /**
604 * This is used to get a session using device authentication. It is called at the end of user
605 * authentication
606 *
607 * @param {object} callback Result callback map.
608 * @param {onFailure} callback.onFailure Called on any error.
609 * @param {authSuccess} callback.onSuccess Called on success with the new session.
610 * @param {ClientMetadata} clientMetadata object which is passed from client to Cognito Lambda trigger
611 * @returns {void}
612 * @private
613 */
614 ;
615
616 _proto.getDeviceResponse = function getDeviceResponse(callback, clientMetadata) {
617 var _this6 = this;
618
619 var authenticationHelper = new _AuthenticationHelper["default"](this.deviceGroupKey);
620 var dateHelper = new _DateHelper["default"]();
621 var authParameters = {};
622 authParameters.USERNAME = this.username;
623 authParameters.DEVICE_KEY = this.deviceKey;
624 authenticationHelper.getLargeAValue(function (errAValue, aValue) {
625 // getLargeAValue callback start
626 if (errAValue) {
627 callback.onFailure(errAValue);
628 }
629
630 authParameters.SRP_A = aValue.toString(16);
631 var jsonReq = {
632 ChallengeName: 'DEVICE_SRP_AUTH',
633 ClientId: _this6.pool.getClientId(),
634 ChallengeResponses: authParameters,
635 ClientMetadata: clientMetadata
636 };
637
638 if (_this6.getUserContextData()) {
639 jsonReq.UserContextData = _this6.getUserContextData();
640 }
641
642 _this6.client.request('RespondToAuthChallenge', jsonReq, function (err, data) {
643 if (err) {
644 return callback.onFailure(err);
645 }
646
647 var challengeParameters = data.ChallengeParameters;
648 var serverBValue = new _BigInteger["default"](challengeParameters.SRP_B, 16);
649 var salt = new _BigInteger["default"](challengeParameters.SALT, 16);
650 authenticationHelper.getPasswordAuthenticationKey(_this6.deviceKey, _this6.randomPassword, serverBValue, salt, function (errHkdf, hkdf) {
651 // getPasswordAuthenticationKey callback start
652 if (errHkdf) {
653 return callback.onFailure(errHkdf);
654 }
655
656 var dateNow = dateHelper.getNowString();
657
658 var message = _core["default"].lib.WordArray.create(_buffer.Buffer.concat([_buffer.Buffer.from(_this6.deviceGroupKey, 'utf8'), _buffer.Buffer.from(_this6.deviceKey, 'utf8'), _buffer.Buffer.from(challengeParameters.SECRET_BLOCK, 'base64'), _buffer.Buffer.from(dateNow, 'utf8')]));
659
660 var key = _core["default"].lib.WordArray.create(hkdf);
661
662 var signatureString = _encBase["default"].stringify((0, _hmacSha["default"])(message, key));
663
664 var challengeResponses = {};
665 challengeResponses.USERNAME = _this6.username;
666 challengeResponses.PASSWORD_CLAIM_SECRET_BLOCK = challengeParameters.SECRET_BLOCK;
667 challengeResponses.TIMESTAMP = dateNow;
668 challengeResponses.PASSWORD_CLAIM_SIGNATURE = signatureString;
669 challengeResponses.DEVICE_KEY = _this6.deviceKey;
670 var jsonReqResp = {
671 ChallengeName: 'DEVICE_PASSWORD_VERIFIER',
672 ClientId: _this6.pool.getClientId(),
673 ChallengeResponses: challengeResponses,
674 Session: data.Session
675 };
676
677 if (_this6.getUserContextData()) {
678 jsonReqResp.UserContextData = _this6.getUserContextData();
679 }
680
681 _this6.client.request('RespondToAuthChallenge', jsonReqResp, function (errAuthenticate, dataAuthenticate) {
682 if (errAuthenticate) {
683 return callback.onFailure(errAuthenticate);
684 }
685
686 _this6.signInUserSession = _this6.getCognitoUserSession(dataAuthenticate.AuthenticationResult);
687
688 _this6.cacheTokens();
689
690 return callback.onSuccess(_this6.signInUserSession);
691 });
692
693 return undefined; // getPasswordAuthenticationKey callback end
694 });
695 return undefined;
696 }); // getLargeAValue callback end
697
698 });
699 }
700 /**
701 * This is used for a certain user to confirm the registration by using a confirmation code
702 * @param {string} confirmationCode Code entered by user.
703 * @param {bool} forceAliasCreation Allow migrating from an existing email / phone number.
704 * @param {nodeCallback<string>} callback Called on success or error.
705 * @param {ClientMetadata} clientMetadata object which is passed from client to Cognito Lambda trigger
706 * @returns {void}
707 */
708 ;
709
710 _proto.confirmRegistration = function confirmRegistration(confirmationCode, forceAliasCreation, callback, clientMetadata) {
711 var jsonReq = {
712 ClientId: this.pool.getClientId(),
713 ConfirmationCode: confirmationCode,
714 Username: this.username,
715 ForceAliasCreation: forceAliasCreation,
716 ClientMetadata: clientMetadata
717 };
718
719 if (this.getUserContextData()) {
720 jsonReq.UserContextData = this.getUserContextData();
721 }
722
723 this.client.request('ConfirmSignUp', jsonReq, function (err) {
724 if (err) {
725 return callback(err, null);
726 }
727
728 return callback(null, 'SUCCESS');
729 });
730 }
731 /**
732 * This is used by the user once he has the responses to a custom challenge
733 * @param {string} answerChallenge The custom challenge answer.
734 * @param {object} callback Result callback map.
735 * @param {onFailure} callback.onFailure Called on any error.
736 * @param {customChallenge} callback.customChallenge
737 * Custom challenge response required to continue.
738 * @param {authSuccess} callback.onSuccess Called on success with the new session.
739 * @param {ClientMetadata} clientMetadata object which is passed from client to Cognito Lambda trigger
740 * @returns {void}
741 */
742 ;
743
744 _proto.sendCustomChallengeAnswer = function sendCustomChallengeAnswer(answerChallenge, callback, clientMetadata) {
745 var _this7 = this;
746
747 var challengeResponses = {};
748 challengeResponses.USERNAME = this.username;
749 challengeResponses.ANSWER = answerChallenge;
750 var authenticationHelper = new _AuthenticationHelper["default"](this.pool.getUserPoolId().split('_')[1]);
751 this.getCachedDeviceKeyAndPassword();
752
753 if (this.deviceKey != null) {
754 challengeResponses.DEVICE_KEY = this.deviceKey;
755 }
756
757 var jsonReq = {
758 ChallengeName: 'CUSTOM_CHALLENGE',
759 ChallengeResponses: challengeResponses,
760 ClientId: this.pool.getClientId(),
761 Session: this.Session,
762 ClientMetadata: clientMetadata
763 };
764
765 if (this.getUserContextData()) {
766 jsonReq.UserContextData = this.getUserContextData();
767 }
768
769 this.client.request('RespondToAuthChallenge', jsonReq, function (err, data) {
770 if (err) {
771 return callback.onFailure(err);
772 }
773
774 return _this7.authenticateUserInternal(data, authenticationHelper, callback);
775 });
776 }
777 /**
778 * This is used by the user once he has an MFA code
779 * @param {string} confirmationCode The MFA code entered by the user.
780 * @param {object} callback Result callback map.
781 * @param {string} mfaType The mfa we are replying to.
782 * @param {onFailure} callback.onFailure Called on any error.
783 * @param {authSuccess} callback.onSuccess Called on success with the new session.
784 * @param {ClientMetadata} clientMetadata object which is passed from client to Cognito Lambda trigger
785 * @returns {void}
786 */
787 ;
788
789 _proto.sendMFACode = function sendMFACode(confirmationCode, callback, mfaType, clientMetadata) {
790 var _this8 = this;
791
792 var challengeResponses = {};
793 challengeResponses.USERNAME = this.username;
794 challengeResponses.SMS_MFA_CODE = confirmationCode;
795 var mfaTypeSelection = mfaType || 'SMS_MFA';
796
797 if (mfaTypeSelection === 'SOFTWARE_TOKEN_MFA') {
798 challengeResponses.SOFTWARE_TOKEN_MFA_CODE = confirmationCode;
799 }
800
801 if (this.deviceKey != null) {
802 challengeResponses.DEVICE_KEY = this.deviceKey;
803 }
804
805 var jsonReq = {
806 ChallengeName: mfaTypeSelection,
807 ChallengeResponses: challengeResponses,
808 ClientId: this.pool.getClientId(),
809 Session: this.Session,
810 ClientMetadata: clientMetadata
811 };
812
813 if (this.getUserContextData()) {
814 jsonReq.UserContextData = this.getUserContextData();
815 }
816
817 this.client.request('RespondToAuthChallenge', jsonReq, function (err, dataAuthenticate) {
818 if (err) {
819 return callback.onFailure(err);
820 }
821
822 var challengeName = dataAuthenticate.ChallengeName;
823
824 if (challengeName === 'DEVICE_SRP_AUTH') {
825 _this8.getDeviceResponse(callback);
826
827 return undefined;
828 }
829
830 _this8.signInUserSession = _this8.getCognitoUserSession(dataAuthenticate.AuthenticationResult);
831
832 _this8.cacheTokens();
833
834 if (dataAuthenticate.AuthenticationResult.NewDeviceMetadata == null) {
835 return callback.onSuccess(_this8.signInUserSession);
836 }
837
838 var authenticationHelper = new _AuthenticationHelper["default"](_this8.pool.getUserPoolId().split('_')[1]);
839 authenticationHelper.generateHashDevice(dataAuthenticate.AuthenticationResult.NewDeviceMetadata.DeviceGroupKey, dataAuthenticate.AuthenticationResult.NewDeviceMetadata.DeviceKey, function (errGenHash) {
840 if (errGenHash) {
841 return callback.onFailure(errGenHash);
842 }
843
844 var deviceSecretVerifierConfig = {
845 Salt: _buffer.Buffer.from(authenticationHelper.getSaltDevices(), 'hex').toString('base64'),
846 PasswordVerifier: _buffer.Buffer.from(authenticationHelper.getVerifierDevices(), 'hex').toString('base64')
847 };
848 _this8.verifierDevices = deviceSecretVerifierConfig.PasswordVerifier;
849 _this8.deviceGroupKey = dataAuthenticate.AuthenticationResult.NewDeviceMetadata.DeviceGroupKey;
850 _this8.randomPassword = authenticationHelper.getRandomPassword();
851
852 _this8.client.request('ConfirmDevice', {
853 DeviceKey: dataAuthenticate.AuthenticationResult.NewDeviceMetadata.DeviceKey,
854 AccessToken: _this8.signInUserSession.getAccessToken().getJwtToken(),
855 DeviceSecretVerifierConfig: deviceSecretVerifierConfig,
856 DeviceName: userAgent
857 }, function (errConfirm, dataConfirm) {
858 if (errConfirm) {
859 return callback.onFailure(errConfirm);
860 }
861
862 _this8.deviceKey = dataAuthenticate.AuthenticationResult.NewDeviceMetadata.DeviceKey;
863
864 _this8.cacheDeviceKeyAndPassword();
865
866 if (dataConfirm.UserConfirmationNecessary === true) {
867 return callback.onSuccess(_this8.signInUserSession, dataConfirm.UserConfirmationNecessary);
868 }
869
870 return callback.onSuccess(_this8.signInUserSession);
871 });
872
873 return undefined;
874 });
875 return undefined;
876 });
877 }
878 /**
879 * This is used by an authenticated user to change the current password
880 * @param {string} oldUserPassword The current password.
881 * @param {string} newUserPassword The requested new password.
882 * @param {nodeCallback<string>} callback Called on success or error.
883 * @param {ClientMetadata} clientMetadata object which is passed from client to Cognito Lambda trigger
884 * @returns {void}
885 */
886 ;
887
888 _proto.changePassword = function changePassword(oldUserPassword, newUserPassword, callback, clientMetadata) {
889 if (!(this.signInUserSession != null && this.signInUserSession.isValid())) {
890 return callback(new Error('User is not authenticated'), null);
891 }
892
893 this.client.request('ChangePassword', {
894 PreviousPassword: oldUserPassword,
895 ProposedPassword: newUserPassword,
896 AccessToken: this.signInUserSession.getAccessToken().getJwtToken(),
897 ClientMetadata: clientMetadata
898 }, function (err) {
899 if (err) {
900 return callback(err, null);
901 }
902
903 return callback(null, 'SUCCESS');
904 });
905 return undefined;
906 }
907 /**
908 * This is used by an authenticated user to enable MFA for itself
909 * @deprecated
910 * @param {nodeCallback<string>} callback Called on success or error.
911 * @returns {void}
912 */
913 ;
914
915 _proto.enableMFA = function enableMFA(callback) {
916 if (this.signInUserSession == null || !this.signInUserSession.isValid()) {
917 return callback(new Error('User is not authenticated'), null);
918 }
919
920 var mfaOptions = [];
921 var mfaEnabled = {
922 DeliveryMedium: 'SMS',
923 AttributeName: 'phone_number'
924 };
925 mfaOptions.push(mfaEnabled);
926 this.client.request('SetUserSettings', {
927 MFAOptions: mfaOptions,
928 AccessToken: this.signInUserSession.getAccessToken().getJwtToken()
929 }, function (err) {
930 if (err) {
931 return callback(err, null);
932 }
933
934 return callback(null, 'SUCCESS');
935 });
936 return undefined;
937 }
938 /**
939 * This is used by an authenticated user to enable MFA for itself
940 * @param {IMfaSettings} smsMfaSettings the sms mfa settings
941 * @param {IMFASettings} softwareTokenMfaSettings the software token mfa settings
942 * @param {nodeCallback<string>} callback Called on success or error.
943 * @returns {void}
944 */
945 ;
946
947 _proto.setUserMfaPreference = function setUserMfaPreference(smsMfaSettings, softwareTokenMfaSettings, callback) {
948 if (this.signInUserSession == null || !this.signInUserSession.isValid()) {
949 return callback(new Error('User is not authenticated'), null);
950 }
951
952 this.client.request('SetUserMFAPreference', {
953 SMSMfaSettings: smsMfaSettings,
954 SoftwareTokenMfaSettings: softwareTokenMfaSettings,
955 AccessToken: this.signInUserSession.getAccessToken().getJwtToken()
956 }, function (err) {
957 if (err) {
958 return callback(err, null);
959 }
960
961 return callback(null, 'SUCCESS');
962 });
963 return undefined;
964 }
965 /**
966 * This is used by an authenticated user to disable MFA for itself
967 * @deprecated
968 * @param {nodeCallback<string>} callback Called on success or error.
969 * @returns {void}
970 */
971 ;
972
973 _proto.disableMFA = function disableMFA(callback) {
974 if (this.signInUserSession == null || !this.signInUserSession.isValid()) {
975 return callback(new Error('User is not authenticated'), null);
976 }
977
978 var mfaOptions = [];
979 this.client.request('SetUserSettings', {
980 MFAOptions: mfaOptions,
981 AccessToken: this.signInUserSession.getAccessToken().getJwtToken()
982 }, function (err) {
983 if (err) {
984 return callback(err, null);
985 }
986
987 return callback(null, 'SUCCESS');
988 });
989 return undefined;
990 }
991 /**
992 * This is used by an authenticated user to delete itself
993 * @param {nodeCallback<string>} callback Called on success or error.
994 * @param {ClientMetadata} clientMetadata object which is passed from client to Cognito Lambda trigger
995 * @returns {void}
996 */
997 ;
998
999 _proto.deleteUser = function deleteUser(callback, clientMetadata) {
1000 var _this9 = this;
1001
1002 if (this.signInUserSession == null || !this.signInUserSession.isValid()) {
1003 return callback(new Error('User is not authenticated'), null);
1004 }
1005
1006 this.client.request('DeleteUser', {
1007 AccessToken: this.signInUserSession.getAccessToken().getJwtToken(),
1008 ClientMetadata: clientMetadata
1009 }, function (err) {
1010 if (err) {
1011 return callback(err, null);
1012 }
1013
1014 _this9.clearCachedUser();
1015
1016 return callback(null, 'SUCCESS');
1017 });
1018 return undefined;
1019 }
1020 /**
1021 * @typedef {CognitoUserAttribute | { Name:string, Value:string }} AttributeArg
1022 */
1023
1024 /**
1025 * This is used by an authenticated user to change a list of attributes
1026 * @param {AttributeArg[]} attributes A list of the new user attributes.
1027 * @param {nodeCallback<string>} callback Called on success or error.
1028 * @param {ClientMetadata} clientMetadata object which is passed from client to Cognito Lambda trigger
1029 * @returns {void}
1030 */
1031 ;
1032
1033 _proto.updateAttributes = function updateAttributes(attributes, callback, clientMetadata) {
1034 if (this.signInUserSession == null || !this.signInUserSession.isValid()) {
1035 return callback(new Error('User is not authenticated'), null);
1036 }
1037
1038 this.client.request('UpdateUserAttributes', {
1039 AccessToken: this.signInUserSession.getAccessToken().getJwtToken(),
1040 UserAttributes: attributes,
1041 ClientMetadata: clientMetadata
1042 }, function (err) {
1043 if (err) {
1044 return callback(err, null);
1045 }
1046
1047 return callback(null, 'SUCCESS');
1048 });
1049 return undefined;
1050 }
1051 /**
1052 * This is used by an authenticated user to get a list of attributes
1053 * @param {nodeCallback<CognitoUserAttribute[]>} callback Called on success or error.
1054 * @returns {void}
1055 */
1056 ;
1057
1058 _proto.getUserAttributes = function getUserAttributes(callback) {
1059 if (!(this.signInUserSession != null && this.signInUserSession.isValid())) {
1060 return callback(new Error('User is not authenticated'), null);
1061 }
1062
1063 this.client.request('GetUser', {
1064 AccessToken: this.signInUserSession.getAccessToken().getJwtToken()
1065 }, function (err, userData) {
1066 if (err) {
1067 return callback(err, null);
1068 }
1069
1070 var attributeList = [];
1071
1072 for (var i = 0; i < userData.UserAttributes.length; i++) {
1073 var attribute = {
1074 Name: userData.UserAttributes[i].Name,
1075 Value: userData.UserAttributes[i].Value
1076 };
1077 var userAttribute = new _CognitoUserAttribute["default"](attribute);
1078 attributeList.push(userAttribute);
1079 }
1080
1081 return callback(null, attributeList);
1082 });
1083 return undefined;
1084 }
1085 /**
1086 * This is used by an authenticated user to get the MFAOptions
1087 * @param {nodeCallback<MFAOptions>} callback Called on success or error.
1088 * @returns {void}
1089 */
1090 ;
1091
1092 _proto.getMFAOptions = function getMFAOptions(callback) {
1093 if (!(this.signInUserSession != null && this.signInUserSession.isValid())) {
1094 return callback(new Error('User is not authenticated'), null);
1095 }
1096
1097 this.client.request('GetUser', {
1098 AccessToken: this.signInUserSession.getAccessToken().getJwtToken()
1099 }, function (err, userData) {
1100 if (err) {
1101 return callback(err, null);
1102 }
1103
1104 return callback(null, userData.MFAOptions);
1105 });
1106 return undefined;
1107 }
1108 /**
1109 * This is used by an authenticated users to get the userData
1110 * @param {nodeCallback<UserData>} callback Called on success or error.
1111 * @returns {void}
1112 */
1113 ;
1114
1115 _proto.getUserData = function getUserData(callback, params) {
1116 var _this10 = this;
1117
1118 if (!(this.signInUserSession != null && this.signInUserSession.isValid())) {
1119 this.clearCachedUserData();
1120 return callback(new Error('User is not authenticated'), null);
1121 }
1122
1123 var bypassCache = params ? params.bypassCache : false;
1124 var userData = this.storage.getItem(this.userDataKey); // get the cached user data
1125
1126 if (!userData || bypassCache) {
1127 this.client.request('GetUser', {
1128 AccessToken: this.signInUserSession.getAccessToken().getJwtToken()
1129 }, function (err, latestUserData) {
1130 if (err) {
1131 return callback(err, null);
1132 }
1133
1134 _this10.cacheUserData(latestUserData);
1135
1136 var refresh = _this10.signInUserSession.getRefreshToken();
1137
1138 if (refresh && refresh.getToken()) {
1139 _this10.refreshSession(refresh, function (refreshError, data) {
1140 if (refreshError) {
1141 return callback(refreshError, null);
1142 }
1143
1144 return callback(null, latestUserData);
1145 });
1146 } else {
1147 return callback(null, latestUserData);
1148 }
1149 });
1150 } else {
1151 try {
1152 return callback(null, JSON.parse(userData));
1153 } catch (err) {
1154 this.clearCachedUserData();
1155 return callback(err, null);
1156 }
1157 }
1158
1159 return undefined;
1160 }
1161 /**
1162 * This is used by an authenticated user to delete a list of attributes
1163 * @param {string[]} attributeList Names of the attributes to delete.
1164 * @param {nodeCallback<string>} callback Called on success or error.
1165 * @returns {void}
1166 */
1167 ;
1168
1169 _proto.deleteAttributes = function deleteAttributes(attributeList, callback) {
1170 if (!(this.signInUserSession != null && this.signInUserSession.isValid())) {
1171 return callback(new Error('User is not authenticated'), null);
1172 }
1173
1174 this.client.request('DeleteUserAttributes', {
1175 UserAttributeNames: attributeList,
1176 AccessToken: this.signInUserSession.getAccessToken().getJwtToken()
1177 }, function (err) {
1178 if (err) {
1179 return callback(err, null);
1180 }
1181
1182 return callback(null, 'SUCCESS');
1183 });
1184 return undefined;
1185 }
1186 /**
1187 * This is used by a user to resend a confirmation code
1188 * @param {nodeCallback<string>} callback Called on success or error.
1189 * @param {ClientMetadata} clientMetadata object which is passed from client to Cognito Lambda trigger
1190 * @returns {void}
1191 */
1192 ;
1193
1194 _proto.resendConfirmationCode = function resendConfirmationCode(callback, clientMetadata) {
1195 var jsonReq = {
1196 ClientId: this.pool.getClientId(),
1197 Username: this.username,
1198 ClientMetadata: clientMetadata
1199 };
1200 this.client.request('ResendConfirmationCode', jsonReq, function (err, result) {
1201 if (err) {
1202 return callback(err, null);
1203 }
1204
1205 return callback(null, result);
1206 });
1207 }
1208 /**
1209 * This is used to get a session, either from the session object
1210 * or from the local storage, or by using a refresh token
1211 *
1212 * @param {nodeCallback<CognitoUserSession>} callback Called on success or error.
1213 * @returns {void}
1214 */
1215 ;
1216
1217 _proto.getSession = function getSession(callback) {
1218 if (this.username == null) {
1219 return callback(new Error('Username is null. Cannot retrieve a new session'), null);
1220 }
1221
1222 if (this.signInUserSession != null && this.signInUserSession.isValid()) {
1223 return callback(null, this.signInUserSession);
1224 }
1225
1226 var keyPrefix = "CognitoIdentityServiceProvider." + this.pool.getClientId() + "." + this.username;
1227 var idTokenKey = keyPrefix + ".idToken";
1228 var accessTokenKey = keyPrefix + ".accessToken";
1229 var refreshTokenKey = keyPrefix + ".refreshToken";
1230 var clockDriftKey = keyPrefix + ".clockDrift";
1231
1232 if (this.storage.getItem(idTokenKey)) {
1233 var idToken = new _CognitoIdToken["default"]({
1234 IdToken: this.storage.getItem(idTokenKey)
1235 });
1236 var accessToken = new _CognitoAccessToken["default"]({
1237 AccessToken: this.storage.getItem(accessTokenKey)
1238 });
1239 var refreshToken = new _CognitoRefreshToken["default"]({
1240 RefreshToken: this.storage.getItem(refreshTokenKey)
1241 });
1242 var clockDrift = parseInt(this.storage.getItem(clockDriftKey), 0) || 0;
1243 var sessionData = {
1244 IdToken: idToken,
1245 AccessToken: accessToken,
1246 RefreshToken: refreshToken,
1247 ClockDrift: clockDrift
1248 };
1249 var cachedSession = new _CognitoUserSession["default"](sessionData);
1250
1251 if (cachedSession.isValid()) {
1252 this.signInUserSession = cachedSession;
1253 return callback(null, this.signInUserSession);
1254 }
1255
1256 if (!refreshToken.getToken()) {
1257 return callback(new Error('Cannot retrieve a new session. Please authenticate.'), null);
1258 }
1259
1260 this.refreshSession(refreshToken, callback);
1261 } else {
1262 callback(new Error('Local storage is missing an ID Token, Please authenticate'), null);
1263 }
1264
1265 return undefined;
1266 }
1267 /**
1268 * This uses the refreshToken to retrieve a new session
1269 * @param {CognitoRefreshToken} refreshToken A previous session's refresh token.
1270 * @param {nodeCallback<CognitoUserSession>} callback Called on success or error.
1271 * @param {ClientMetadata} clientMetadata object which is passed from client to Cognito Lambda trigger
1272 * @returns {void}
1273 */
1274 ;
1275
1276 _proto.refreshSession = function refreshSession(refreshToken, callback, clientMetadata) {
1277 var _this11 = this;
1278
1279 var authParameters = {};
1280 authParameters.REFRESH_TOKEN = refreshToken.getToken();
1281 var keyPrefix = "CognitoIdentityServiceProvider." + this.pool.getClientId();
1282 var lastUserKey = keyPrefix + ".LastAuthUser";
1283
1284 if (this.storage.getItem(lastUserKey)) {
1285 this.username = this.storage.getItem(lastUserKey);
1286 var deviceKeyKey = keyPrefix + "." + this.username + ".deviceKey";
1287 this.deviceKey = this.storage.getItem(deviceKeyKey);
1288 authParameters.DEVICE_KEY = this.deviceKey;
1289 }
1290
1291 var jsonReq = {
1292 ClientId: this.pool.getClientId(),
1293 AuthFlow: 'REFRESH_TOKEN_AUTH',
1294 AuthParameters: authParameters,
1295 ClientMetadata: clientMetadata
1296 };
1297
1298 if (this.getUserContextData()) {
1299 jsonReq.UserContextData = this.getUserContextData();
1300 }
1301
1302 this.client.request('InitiateAuth', jsonReq, function (err, authResult) {
1303 if (err) {
1304 if (err.code === 'NotAuthorizedException') {
1305 _this11.clearCachedUser();
1306 }
1307
1308 return callback(err, null);
1309 }
1310
1311 if (authResult) {
1312 var authenticationResult = authResult.AuthenticationResult;
1313
1314 if (!Object.prototype.hasOwnProperty.call(authenticationResult, 'RefreshToken')) {
1315 authenticationResult.RefreshToken = refreshToken.getToken();
1316 }
1317
1318 _this11.signInUserSession = _this11.getCognitoUserSession(authenticationResult);
1319
1320 _this11.cacheTokens();
1321
1322 return callback(null, _this11.signInUserSession);
1323 }
1324
1325 return undefined;
1326 });
1327 }
1328 /**
1329 * This is used to save the session tokens to local storage
1330 * @returns {void}
1331 */
1332 ;
1333
1334 _proto.cacheTokens = function cacheTokens() {
1335 var keyPrefix = "CognitoIdentityServiceProvider." + this.pool.getClientId();
1336 var idTokenKey = keyPrefix + "." + this.username + ".idToken";
1337 var accessTokenKey = keyPrefix + "." + this.username + ".accessToken";
1338 var refreshTokenKey = keyPrefix + "." + this.username + ".refreshToken";
1339 var clockDriftKey = keyPrefix + "." + this.username + ".clockDrift";
1340 var lastUserKey = keyPrefix + ".LastAuthUser";
1341 this.storage.setItem(idTokenKey, this.signInUserSession.getIdToken().getJwtToken());
1342 this.storage.setItem(accessTokenKey, this.signInUserSession.getAccessToken().getJwtToken());
1343 this.storage.setItem(refreshTokenKey, this.signInUserSession.getRefreshToken().getToken());
1344 this.storage.setItem(clockDriftKey, "" + this.signInUserSession.getClockDrift());
1345 this.storage.setItem(lastUserKey, this.username);
1346 }
1347 /**
1348 * This is to cache user data
1349 */
1350 ;
1351
1352 _proto.cacheUserData = function cacheUserData(userData) {
1353 this.storage.setItem(this.userDataKey, JSON.stringify(userData));
1354 }
1355 /**
1356 * This is to remove cached user data
1357 */
1358 ;
1359
1360 _proto.clearCachedUserData = function clearCachedUserData() {
1361 this.storage.removeItem(this.userDataKey);
1362 };
1363
1364 _proto.clearCachedUser = function clearCachedUser() {
1365 this.clearCachedTokens();
1366 this.clearCachedUserData();
1367 }
1368 /**
1369 * This is used to cache the device key and device group and device password
1370 * @returns {void}
1371 */
1372 ;
1373
1374 _proto.cacheDeviceKeyAndPassword = function cacheDeviceKeyAndPassword() {
1375 var keyPrefix = "CognitoIdentityServiceProvider." + this.pool.getClientId() + "." + this.username;
1376 var deviceKeyKey = keyPrefix + ".deviceKey";
1377 var randomPasswordKey = keyPrefix + ".randomPasswordKey";
1378 var deviceGroupKeyKey = keyPrefix + ".deviceGroupKey";
1379 this.storage.setItem(deviceKeyKey, this.deviceKey);
1380 this.storage.setItem(randomPasswordKey, this.randomPassword);
1381 this.storage.setItem(deviceGroupKeyKey, this.deviceGroupKey);
1382 }
1383 /**
1384 * This is used to get current device key and device group and device password
1385 * @returns {void}
1386 */
1387 ;
1388
1389 _proto.getCachedDeviceKeyAndPassword = function getCachedDeviceKeyAndPassword() {
1390 var keyPrefix = "CognitoIdentityServiceProvider." + this.pool.getClientId() + "." + this.username;
1391 var deviceKeyKey = keyPrefix + ".deviceKey";
1392 var randomPasswordKey = keyPrefix + ".randomPasswordKey";
1393 var deviceGroupKeyKey = keyPrefix + ".deviceGroupKey";
1394
1395 if (this.storage.getItem(deviceKeyKey)) {
1396 this.deviceKey = this.storage.getItem(deviceKeyKey);
1397 this.randomPassword = this.storage.getItem(randomPasswordKey);
1398 this.deviceGroupKey = this.storage.getItem(deviceGroupKeyKey);
1399 }
1400 }
1401 /**
1402 * This is used to clear the device key info from local storage
1403 * @returns {void}
1404 */
1405 ;
1406
1407 _proto.clearCachedDeviceKeyAndPassword = function clearCachedDeviceKeyAndPassword() {
1408 var keyPrefix = "CognitoIdentityServiceProvider." + this.pool.getClientId() + "." + this.username;
1409 var deviceKeyKey = keyPrefix + ".deviceKey";
1410 var randomPasswordKey = keyPrefix + ".randomPasswordKey";
1411 var deviceGroupKeyKey = keyPrefix + ".deviceGroupKey";
1412 this.storage.removeItem(deviceKeyKey);
1413 this.storage.removeItem(randomPasswordKey);
1414 this.storage.removeItem(deviceGroupKeyKey);
1415 }
1416 /**
1417 * This is used to clear the session tokens from local storage
1418 * @returns {void}
1419 */
1420 ;
1421
1422 _proto.clearCachedTokens = function clearCachedTokens() {
1423 var keyPrefix = "CognitoIdentityServiceProvider." + this.pool.getClientId();
1424 var idTokenKey = keyPrefix + "." + this.username + ".idToken";
1425 var accessTokenKey = keyPrefix + "." + this.username + ".accessToken";
1426 var refreshTokenKey = keyPrefix + "." + this.username + ".refreshToken";
1427 var lastUserKey = keyPrefix + ".LastAuthUser";
1428 var clockDriftKey = keyPrefix + "." + this.username + ".clockDrift";
1429 this.storage.removeItem(idTokenKey);
1430 this.storage.removeItem(accessTokenKey);
1431 this.storage.removeItem(refreshTokenKey);
1432 this.storage.removeItem(lastUserKey);
1433 this.storage.removeItem(clockDriftKey);
1434 }
1435 /**
1436 * This is used to build a user session from tokens retrieved in the authentication result
1437 * @param {object} authResult Successful auth response from server.
1438 * @returns {CognitoUserSession} The new user session.
1439 * @private
1440 */
1441 ;
1442
1443 _proto.getCognitoUserSession = function getCognitoUserSession(authResult) {
1444 var idToken = new _CognitoIdToken["default"](authResult);
1445 var accessToken = new _CognitoAccessToken["default"](authResult);
1446 var refreshToken = new _CognitoRefreshToken["default"](authResult);
1447 var sessionData = {
1448 IdToken: idToken,
1449 AccessToken: accessToken,
1450 RefreshToken: refreshToken
1451 };
1452 return new _CognitoUserSession["default"](sessionData);
1453 }
1454 /**
1455 * This is used to initiate a forgot password request
1456 * @param {object} callback Result callback map.
1457 * @param {onFailure} callback.onFailure Called on any error.
1458 * @param {inputVerificationCode?} callback.inputVerificationCode
1459 * Optional callback raised instead of onSuccess with response data.
1460 * @param {onSuccess} callback.onSuccess Called on success.
1461 * @param {ClientMetadata} clientMetadata object which is passed from client to Cognito Lambda trigger
1462 * @returns {void}
1463 */
1464 ;
1465
1466 _proto.forgotPassword = function forgotPassword(callback, clientMetadata) {
1467 var jsonReq = {
1468 ClientId: this.pool.getClientId(),
1469 Username: this.username,
1470 ClientMetadata: clientMetadata
1471 };
1472
1473 if (this.getUserContextData()) {
1474 jsonReq.UserContextData = this.getUserContextData();
1475 }
1476
1477 this.client.request('ForgotPassword', jsonReq, function (err, data) {
1478 if (err) {
1479 return callback.onFailure(err);
1480 }
1481
1482 if (typeof callback.inputVerificationCode === 'function') {
1483 return callback.inputVerificationCode(data);
1484 }
1485
1486 return callback.onSuccess(data);
1487 });
1488 }
1489 /**
1490 * This is used to confirm a new password using a confirmationCode
1491 * @param {string} confirmationCode Code entered by user.
1492 * @param {string} newPassword Confirm new password.
1493 * @param {object} callback Result callback map.
1494 * @param {onFailure} callback.onFailure Called on any error.
1495 * @param {onSuccess<void>} callback.onSuccess Called on success.
1496 * @param {ClientMetadata} clientMetadata object which is passed from client to Cognito Lambda trigger
1497 * @returns {void}
1498 */
1499 ;
1500
1501 _proto.confirmPassword = function confirmPassword(confirmationCode, newPassword, callback, clientMetadata) {
1502 var jsonReq = {
1503 ClientId: this.pool.getClientId(),
1504 Username: this.username,
1505 ConfirmationCode: confirmationCode,
1506 Password: newPassword,
1507 ClientMetadata: clientMetadata
1508 };
1509
1510 if (this.getUserContextData()) {
1511 jsonReq.UserContextData = this.getUserContextData();
1512 }
1513
1514 this.client.request('ConfirmForgotPassword', jsonReq, function (err) {
1515 if (err) {
1516 return callback.onFailure(err);
1517 }
1518
1519 return callback.onSuccess();
1520 });
1521 }
1522 /**
1523 * This is used to initiate an attribute confirmation request
1524 * @param {string} attributeName User attribute that needs confirmation.
1525 * @param {object} callback Result callback map.
1526 * @param {onFailure} callback.onFailure Called on any error.
1527 * @param {inputVerificationCode} callback.inputVerificationCode Called on success.
1528 * @param {ClientMetadata} clientMetadata object which is passed from client to Cognito Lambda trigger
1529 * @returns {void}
1530 */
1531 ;
1532
1533 _proto.getAttributeVerificationCode = function getAttributeVerificationCode(attributeName, callback, clientMetadata) {
1534 if (this.signInUserSession == null || !this.signInUserSession.isValid()) {
1535 return callback.onFailure(new Error('User is not authenticated'));
1536 }
1537
1538 this.client.request('GetUserAttributeVerificationCode', {
1539 AttributeName: attributeName,
1540 AccessToken: this.signInUserSession.getAccessToken().getJwtToken(),
1541 ClientMetadata: clientMetadata
1542 }, function (err, data) {
1543 if (err) {
1544 return callback.onFailure(err);
1545 }
1546
1547 if (typeof callback.inputVerificationCode === 'function') {
1548 return callback.inputVerificationCode(data);
1549 }
1550
1551 return callback.onSuccess();
1552 });
1553 return undefined;
1554 }
1555 /**
1556 * This is used to confirm an attribute using a confirmation code
1557 * @param {string} attributeName Attribute being confirmed.
1558 * @param {string} confirmationCode Code entered by user.
1559 * @param {object} callback Result callback map.
1560 * @param {onFailure} callback.onFailure Called on any error.
1561 * @param {onSuccess<string>} callback.onSuccess Called on success.
1562 * @returns {void}
1563 */
1564 ;
1565
1566 _proto.verifyAttribute = function verifyAttribute(attributeName, confirmationCode, callback) {
1567 if (this.signInUserSession == null || !this.signInUserSession.isValid()) {
1568 return callback.onFailure(new Error('User is not authenticated'));
1569 }
1570
1571 this.client.request('VerifyUserAttribute', {
1572 AttributeName: attributeName,
1573 Code: confirmationCode,
1574 AccessToken: this.signInUserSession.getAccessToken().getJwtToken()
1575 }, function (err) {
1576 if (err) {
1577 return callback.onFailure(err);
1578 }
1579
1580 return callback.onSuccess('SUCCESS');
1581 });
1582 return undefined;
1583 }
1584 /**
1585 * This is used to get the device information using the current device key
1586 * @param {object} callback Result callback map.
1587 * @param {onFailure} callback.onFailure Called on any error.
1588 * @param {onSuccess<*>} callback.onSuccess Called on success with device data.
1589 * @returns {void}
1590 */
1591 ;
1592
1593 _proto.getDevice = function getDevice(callback) {
1594 if (this.signInUserSession == null || !this.signInUserSession.isValid()) {
1595 return callback.onFailure(new Error('User is not authenticated'));
1596 }
1597
1598 this.client.request('GetDevice', {
1599 AccessToken: this.signInUserSession.getAccessToken().getJwtToken(),
1600 DeviceKey: this.deviceKey
1601 }, function (err, data) {
1602 if (err) {
1603 return callback.onFailure(err);
1604 }
1605
1606 return callback.onSuccess(data);
1607 });
1608 return undefined;
1609 }
1610 /**
1611 * This is used to forget a specific device
1612 * @param {string} deviceKey Device key.
1613 * @param {object} callback Result callback map.
1614 * @param {onFailure} callback.onFailure Called on any error.
1615 * @param {onSuccess<string>} callback.onSuccess Called on success.
1616 * @returns {void}
1617 */
1618 ;
1619
1620 _proto.forgetSpecificDevice = function forgetSpecificDevice(deviceKey, callback) {
1621 if (this.signInUserSession == null || !this.signInUserSession.isValid()) {
1622 return callback.onFailure(new Error('User is not authenticated'));
1623 }
1624
1625 this.client.request('ForgetDevice', {
1626 AccessToken: this.signInUserSession.getAccessToken().getJwtToken(),
1627 DeviceKey: deviceKey
1628 }, function (err) {
1629 if (err) {
1630 return callback.onFailure(err);
1631 }
1632
1633 return callback.onSuccess('SUCCESS');
1634 });
1635 return undefined;
1636 }
1637 /**
1638 * This is used to forget the current device
1639 * @param {object} callback Result callback map.
1640 * @param {onFailure} callback.onFailure Called on any error.
1641 * @param {onSuccess<string>} callback.onSuccess Called on success.
1642 * @returns {void}
1643 */
1644 ;
1645
1646 _proto.forgetDevice = function forgetDevice(callback) {
1647 var _this12 = this;
1648
1649 this.forgetSpecificDevice(this.deviceKey, {
1650 onFailure: callback.onFailure,
1651 onSuccess: function onSuccess(result) {
1652 _this12.deviceKey = null;
1653 _this12.deviceGroupKey = null;
1654 _this12.randomPassword = null;
1655
1656 _this12.clearCachedDeviceKeyAndPassword();
1657
1658 return callback.onSuccess(result);
1659 }
1660 });
1661 }
1662 /**
1663 * This is used to set the device status as remembered
1664 * @param {object} callback Result callback map.
1665 * @param {onFailure} callback.onFailure Called on any error.
1666 * @param {onSuccess<string>} callback.onSuccess Called on success.
1667 * @returns {void}
1668 */
1669 ;
1670
1671 _proto.setDeviceStatusRemembered = function setDeviceStatusRemembered(callback) {
1672 if (this.signInUserSession == null || !this.signInUserSession.isValid()) {
1673 return callback.onFailure(new Error('User is not authenticated'));
1674 }
1675
1676 this.client.request('UpdateDeviceStatus', {
1677 AccessToken: this.signInUserSession.getAccessToken().getJwtToken(),
1678 DeviceKey: this.deviceKey,
1679 DeviceRememberedStatus: 'remembered'
1680 }, function (err) {
1681 if (err) {
1682 return callback.onFailure(err);
1683 }
1684
1685 return callback.onSuccess('SUCCESS');
1686 });
1687 return undefined;
1688 }
1689 /**
1690 * This is used to set the device status as not remembered
1691 * @param {object} callback Result callback map.
1692 * @param {onFailure} callback.onFailure Called on any error.
1693 * @param {onSuccess<string>} callback.onSuccess Called on success.
1694 * @returns {void}
1695 */
1696 ;
1697
1698 _proto.setDeviceStatusNotRemembered = function setDeviceStatusNotRemembered(callback) {
1699 if (this.signInUserSession == null || !this.signInUserSession.isValid()) {
1700 return callback.onFailure(new Error('User is not authenticated'));
1701 }
1702
1703 this.client.request('UpdateDeviceStatus', {
1704 AccessToken: this.signInUserSession.getAccessToken().getJwtToken(),
1705 DeviceKey: this.deviceKey,
1706 DeviceRememberedStatus: 'not_remembered'
1707 }, function (err) {
1708 if (err) {
1709 return callback.onFailure(err);
1710 }
1711
1712 return callback.onSuccess('SUCCESS');
1713 });
1714 return undefined;
1715 }
1716 /**
1717 * This is used to list all devices for a user
1718 *
1719 * @param {int} limit the number of devices returned in a call
1720 * @param {string} paginationToken the pagination token in case any was returned before
1721 * @param {object} callback Result callback map.
1722 * @param {onFailure} callback.onFailure Called on any error.
1723 * @param {onSuccess<*>} callback.onSuccess Called on success with device list.
1724 * @returns {void}
1725 */
1726 ;
1727
1728 _proto.listDevices = function listDevices(limit, paginationToken, callback) {
1729 if (this.signInUserSession == null || !this.signInUserSession.isValid()) {
1730 return callback.onFailure(new Error('User is not authenticated'));
1731 }
1732
1733 this.client.request('ListDevices', {
1734 AccessToken: this.signInUserSession.getAccessToken().getJwtToken(),
1735 Limit: limit,
1736 PaginationToken: paginationToken
1737 }, function (err, data) {
1738 if (err) {
1739 return callback.onFailure(err);
1740 }
1741
1742 return callback.onSuccess(data);
1743 });
1744 return undefined;
1745 }
1746 /**
1747 * This is used to globally revoke all tokens issued to a user
1748 * @param {object} callback Result callback map.
1749 * @param {onFailure} callback.onFailure Called on any error.
1750 * @param {onSuccess<string>} callback.onSuccess Called on success.
1751 * @returns {void}
1752 */
1753 ;
1754
1755 _proto.globalSignOut = function globalSignOut(callback) {
1756 var _this13 = this;
1757
1758 if (this.signInUserSession == null || !this.signInUserSession.isValid()) {
1759 return callback.onFailure(new Error('User is not authenticated'));
1760 }
1761
1762 this.client.request('GlobalSignOut', {
1763 AccessToken: this.signInUserSession.getAccessToken().getJwtToken()
1764 }, function (err) {
1765 if (err) {
1766 return callback.onFailure(err);
1767 }
1768
1769 _this13.clearCachedUser();
1770
1771 return callback.onSuccess('SUCCESS');
1772 });
1773 return undefined;
1774 }
1775 /**
1776 * This is used for the user to signOut of the application and clear the cached tokens.
1777 * @returns {void}
1778 */
1779 ;
1780
1781 _proto.signOut = function signOut() {
1782 this.signInUserSession = null;
1783 this.clearCachedUser();
1784 }
1785 /**
1786 * This is used by a user trying to select a given MFA
1787 * @param {string} answerChallenge the mfa the user wants
1788 * @param {nodeCallback<string>} callback Called on success or error.
1789 * @returns {void}
1790 */
1791 ;
1792
1793 _proto.sendMFASelectionAnswer = function sendMFASelectionAnswer(answerChallenge, callback) {
1794 var _this14 = this;
1795
1796 var challengeResponses = {};
1797 challengeResponses.USERNAME = this.username;
1798 challengeResponses.ANSWER = answerChallenge;
1799 var jsonReq = {
1800 ChallengeName: 'SELECT_MFA_TYPE',
1801 ChallengeResponses: challengeResponses,
1802 ClientId: this.pool.getClientId(),
1803 Session: this.Session
1804 };
1805
1806 if (this.getUserContextData()) {
1807 jsonReq.UserContextData = this.getUserContextData();
1808 }
1809
1810 this.client.request('RespondToAuthChallenge', jsonReq, function (err, data) {
1811 if (err) {
1812 return callback.onFailure(err);
1813 }
1814
1815 _this14.Session = data.Session;
1816
1817 if (answerChallenge === 'SMS_MFA') {
1818 return callback.mfaRequired(data.challengeName, data.challengeParameters);
1819 }
1820
1821 if (answerChallenge === 'SOFTWARE_TOKEN_MFA') {
1822 return callback.totpRequired(data.challengeName, data.challengeParameters);
1823 }
1824
1825 return undefined;
1826 });
1827 }
1828 /**
1829 * This returns the user context data for advanced security feature.
1830 * @returns {void}
1831 */
1832 ;
1833
1834 _proto.getUserContextData = function getUserContextData() {
1835 var pool = this.pool;
1836 return pool.getUserContextData(this.username);
1837 }
1838 /**
1839 * This is used by an authenticated or a user trying to authenticate to associate a TOTP MFA
1840 * @param {nodeCallback<string>} callback Called on success or error.
1841 * @returns {void}
1842 */
1843 ;
1844
1845 _proto.associateSoftwareToken = function associateSoftwareToken(callback) {
1846 var _this15 = this;
1847
1848 if (!(this.signInUserSession != null && this.signInUserSession.isValid())) {
1849 this.client.request('AssociateSoftwareToken', {
1850 Session: this.Session
1851 }, function (err, data) {
1852 if (err) {
1853 return callback.onFailure(err);
1854 }
1855
1856 _this15.Session = data.Session;
1857 return callback.associateSecretCode(data.SecretCode);
1858 });
1859 } else {
1860 this.client.request('AssociateSoftwareToken', {
1861 AccessToken: this.signInUserSession.getAccessToken().getJwtToken()
1862 }, function (err, data) {
1863 if (err) {
1864 return callback.onFailure(err);
1865 }
1866
1867 return callback.associateSecretCode(data.SecretCode);
1868 });
1869 }
1870 }
1871 /**
1872 * This is used by an authenticated or a user trying to authenticate to verify a TOTP MFA
1873 * @param {string} totpCode The MFA code entered by the user.
1874 * @param {string} friendlyDeviceName The device name we are assigning to the device.
1875 * @param {nodeCallback<string>} callback Called on success or error.
1876 * @returns {void}
1877 */
1878 ;
1879
1880 _proto.verifySoftwareToken = function verifySoftwareToken(totpCode, friendlyDeviceName, callback) {
1881 var _this16 = this;
1882
1883 if (!(this.signInUserSession != null && this.signInUserSession.isValid())) {
1884 this.client.request('VerifySoftwareToken', {
1885 Session: this.Session,
1886 UserCode: totpCode,
1887 FriendlyDeviceName: friendlyDeviceName
1888 }, function (err, data) {
1889 if (err) {
1890 return callback.onFailure(err);
1891 }
1892
1893 _this16.Session = data.Session;
1894 var challengeResponses = {};
1895 challengeResponses.USERNAME = _this16.username;
1896 var jsonReq = {
1897 ChallengeName: 'MFA_SETUP',
1898 ClientId: _this16.pool.getClientId(),
1899 ChallengeResponses: challengeResponses,
1900 Session: _this16.Session
1901 };
1902
1903 if (_this16.getUserContextData()) {
1904 jsonReq.UserContextData = _this16.getUserContextData();
1905 }
1906
1907 _this16.client.request('RespondToAuthChallenge', jsonReq, function (errRespond, dataRespond) {
1908 if (errRespond) {
1909 return callback.onFailure(errRespond);
1910 }
1911
1912 _this16.signInUserSession = _this16.getCognitoUserSession(dataRespond.AuthenticationResult);
1913
1914 _this16.cacheTokens();
1915
1916 return callback.onSuccess(_this16.signInUserSession);
1917 });
1918
1919 return undefined;
1920 });
1921 } else {
1922 this.client.request('VerifySoftwareToken', {
1923 AccessToken: this.signInUserSession.getAccessToken().getJwtToken(),
1924 UserCode: totpCode,
1925 FriendlyDeviceName: friendlyDeviceName
1926 }, function (err, data) {
1927 if (err) {
1928 return callback.onFailure(err);
1929 }
1930
1931 return callback.onSuccess(data);
1932 });
1933 }
1934 };
1935
1936 return CognitoUser;
1937}();
1938
1939exports["default"] = CognitoUser;
\No newline at end of file