@vardario/cognito-client 2.0.0 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/cognito-client.d.ts +159 -2
- package/lib/cognito-client.js +36 -24
- package/lib/utils.d.ts +1 -0
- package/lib/utils.js +8 -0
- package/package.json +1 -1
package/lib/cognito-client.d.ts
CHANGED
|
@@ -1,7 +1,158 @@
|
|
|
1
|
+
export interface CognitoBaseRequest {
|
|
2
|
+
ClientId: string;
|
|
3
|
+
ClientMetadata?: Record<string, string>;
|
|
4
|
+
AnalyticsMetadata?: {
|
|
5
|
+
AnalyticsEndpointId: string;
|
|
6
|
+
};
|
|
7
|
+
UserContextData?: {
|
|
8
|
+
EncodedData?: string;
|
|
9
|
+
IpAddress?: string;
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
export interface AuthIntiUserSrpRequest extends CognitoBaseRequest {
|
|
13
|
+
AuthFlow: 'USER_SRP_AUTH';
|
|
14
|
+
AuthParameters: {
|
|
15
|
+
USERNAME: string;
|
|
16
|
+
SRP_A: string;
|
|
17
|
+
SECRET_HASH?: string;
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
export interface AuthIntiUserPasswordRequest extends CognitoBaseRequest {
|
|
21
|
+
AuthFlow: 'USER_PASSWORD_AUTH';
|
|
22
|
+
AuthParameters: {
|
|
23
|
+
USERNAME: string;
|
|
24
|
+
PASSWORD: string;
|
|
25
|
+
SECRET_HASH?: string;
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
export interface AuthIntiRefreshTokenRequest extends CognitoBaseRequest {
|
|
29
|
+
AuthFlow: 'REFRESH_TOKEN_AUTH';
|
|
30
|
+
AuthParameters: {
|
|
31
|
+
REFRESH_TOKEN: string;
|
|
32
|
+
SECRET_HASH?: string;
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
export interface AuthIntiCustomAuthRequest extends CognitoBaseRequest {
|
|
36
|
+
AuthFlow: 'CUSTOM_AUTH';
|
|
37
|
+
AuthParameters: {
|
|
38
|
+
USERNAME: string;
|
|
39
|
+
SECRET_HASH?: string;
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
export type AuthIntiRequest = AuthIntiUserSrpRequest | AuthIntiRefreshTokenRequest | AuthIntiCustomAuthRequest | AuthIntiUserPasswordRequest;
|
|
43
|
+
export interface RespondToAuthChallengeBaseRequest extends CognitoBaseRequest {
|
|
44
|
+
Session?: string;
|
|
45
|
+
}
|
|
46
|
+
export interface RespondToAuthChallengePasswordVerifierRequest extends RespondToAuthChallengeBaseRequest {
|
|
47
|
+
ChallengeName: 'PASSWORD_VERIFIER';
|
|
48
|
+
ChallengeResponses: {
|
|
49
|
+
USERNAME: string;
|
|
50
|
+
PASSWORD_CLAIM_SECRET_BLOCK: string;
|
|
51
|
+
PASSWORD_CLAIM_SIGNATURE: string;
|
|
52
|
+
TIMESTAMP: string;
|
|
53
|
+
SECRET_HASH?: string;
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
export interface RespondToAuthChallengeSmsMfaRequest extends RespondToAuthChallengeBaseRequest {
|
|
57
|
+
ChallengeName: 'SMS_MFA';
|
|
58
|
+
ChallengeResponses: {
|
|
59
|
+
USERNAME: string;
|
|
60
|
+
SMS_MFA_CODE: string;
|
|
61
|
+
SECRET_HASH?: string;
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
export interface RespondToAuthChallengeCustomChallengeNameRequest extends RespondToAuthChallengeBaseRequest {
|
|
65
|
+
ChallengeName: 'CUSTOM_CHALLENGE';
|
|
66
|
+
ChallengeResponses: {
|
|
67
|
+
USERNAME: string;
|
|
68
|
+
ANSWER: string;
|
|
69
|
+
SECRET_HASH?: string;
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
export interface RespondToAuthChallengeNewPasswordRequiredRequest extends RespondToAuthChallengeBaseRequest {
|
|
73
|
+
ChallengeName: 'NEW_PASSWORD_REQUIRED';
|
|
74
|
+
ChallengeResponses: {
|
|
75
|
+
USERNAME: string;
|
|
76
|
+
NEW_PASSWORD: string;
|
|
77
|
+
SECRET_HASH?: string;
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
export interface RespondToAuthChallengeSoftwareTokenMfaRequest extends RespondToAuthChallengeBaseRequest {
|
|
81
|
+
ChallengeName: 'SOFTWARE_TOKEN_MFA';
|
|
82
|
+
ChallengeResponses: {
|
|
83
|
+
USERNAME: string;
|
|
84
|
+
SOFTWARE_TOKEN_MFA_CODE: string;
|
|
85
|
+
SECRET_HASH?: string;
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
export interface RespondToAuthChallengeDeviceSrpAuthRequest extends RespondToAuthChallengeBaseRequest {
|
|
89
|
+
ChallengeName: 'DEVICE_SRP_AUTH';
|
|
90
|
+
ChallengeResponses: {
|
|
91
|
+
USERNAME: string;
|
|
92
|
+
SRP_A: string;
|
|
93
|
+
SECRET_HASH?: string;
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
export interface RespondToAuthChallengeDevicePasswordVerifierRequest extends RespondToAuthChallengeBaseRequest {
|
|
97
|
+
ChallengeName: 'DEVICE_PASSWORD_VERIFIER';
|
|
98
|
+
ChallengeResponses: {
|
|
99
|
+
USERNAME: string;
|
|
100
|
+
PASSWORD_CLAIM_SECRET_BLOCK: string;
|
|
101
|
+
PASSWORD_CLAIM_SIGNATURE: string;
|
|
102
|
+
TIMESTAMP: string;
|
|
103
|
+
DEVICE_KEY: string;
|
|
104
|
+
SECRET_HASH?: string;
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
export interface RespondToAuthChallengeMfaSetupRequest extends RespondToAuthChallengeBaseRequest {
|
|
108
|
+
ChallengeName: 'MFA_SETUP';
|
|
109
|
+
ChallengeResponses: {
|
|
110
|
+
USERNAME: string;
|
|
111
|
+
SMS_MFA_CODE?: string;
|
|
112
|
+
SOFTWARE_TOKEN_MFA_CODE?: string;
|
|
113
|
+
SECRET_HASH?: string;
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
export interface RespondToAuthChallengeSelectMfaTypeRequest extends RespondToAuthChallengeBaseRequest {
|
|
117
|
+
ChallengeName: 'SELECT_MFA_TYPE';
|
|
118
|
+
ChallengeResponses: {
|
|
119
|
+
USERNAME: string;
|
|
120
|
+
SOFTWARE_TOKEN_MFA_CODE?: string;
|
|
121
|
+
SECRET_HASH?: string;
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
export type RespondToAuthChallengeRequest = RespondToAuthChallengePasswordVerifierRequest | RespondToAuthChallengeSmsMfaRequest | RespondToAuthChallengeCustomChallengeNameRequest | RespondToAuthChallengeNewPasswordRequiredRequest | RespondToAuthChallengeSoftwareTokenMfaRequest | RespondToAuthChallengeDeviceSrpAuthRequest | RespondToAuthChallengeDevicePasswordVerifierRequest | RespondToAuthChallengeMfaSetupRequest | RespondToAuthChallengeSelectMfaTypeRequest;
|
|
1
125
|
export interface UserAttribute {
|
|
2
126
|
Name: string;
|
|
3
127
|
Value: string;
|
|
4
128
|
}
|
|
129
|
+
export interface ConfirmForgotPasswordRequest extends CognitoBaseRequest {
|
|
130
|
+
ConfirmationCode: string;
|
|
131
|
+
Password: string;
|
|
132
|
+
Username: string;
|
|
133
|
+
SecretHash?: string;
|
|
134
|
+
}
|
|
135
|
+
export interface ConfirmSignUpRequest extends CognitoBaseRequest {
|
|
136
|
+
ConfirmationCode: string;
|
|
137
|
+
Username: string;
|
|
138
|
+
SecretHash?: string;
|
|
139
|
+
ForceAliasCreation?: boolean;
|
|
140
|
+
}
|
|
141
|
+
export interface ForgotPasswordRequest extends CognitoBaseRequest {
|
|
142
|
+
Username: string;
|
|
143
|
+
SecretHash?: string;
|
|
144
|
+
}
|
|
145
|
+
export interface SignUpRequest extends CognitoBaseRequest {
|
|
146
|
+
Username: string;
|
|
147
|
+
Password: string;
|
|
148
|
+
SecretHash?: string;
|
|
149
|
+
UserAttributes?: UserAttribute[];
|
|
150
|
+
ValidationData?: UserAttribute[];
|
|
151
|
+
}
|
|
152
|
+
export interface ResendConfirmationCodeRequest extends CognitoBaseRequest {
|
|
153
|
+
Username: string;
|
|
154
|
+
SecretHash?: string;
|
|
155
|
+
}
|
|
5
156
|
/**
|
|
6
157
|
* Cognito related OAuth props.
|
|
7
158
|
*/
|
|
@@ -43,6 +194,10 @@ export interface CognitoClientProps {
|
|
|
43
194
|
* Cognito OAuth related options. See @see OAuthProps .
|
|
44
195
|
*/
|
|
45
196
|
oAuth2?: OAuth2Props;
|
|
197
|
+
/**
|
|
198
|
+
* Optional Cognito User Pool Client Secret.
|
|
199
|
+
*/
|
|
200
|
+
clientSecret?: string;
|
|
46
201
|
}
|
|
47
202
|
/**
|
|
48
203
|
* Cognito User Session
|
|
@@ -159,7 +314,8 @@ export declare class CognitoClient {
|
|
|
159
314
|
private readonly cognitoPoolName;
|
|
160
315
|
private readonly userPoolClientId;
|
|
161
316
|
private readonly oAuth?;
|
|
162
|
-
|
|
317
|
+
private readonly clientSecret?;
|
|
318
|
+
constructor({ userPoolId, userPoolClientId, endpoint, oAuth2: oAuth, clientSecret }: CognitoClientProps);
|
|
163
319
|
static getDecodedTokenFromSession(session: Session): DecodedTokens;
|
|
164
320
|
/**
|
|
165
321
|
*
|
|
@@ -186,10 +342,11 @@ export declare class CognitoClient {
|
|
|
186
342
|
* Returns a new session based on the given refresh token.
|
|
187
343
|
*
|
|
188
344
|
* @param refreshToken
|
|
345
|
+
* @param username
|
|
189
346
|
* @returns @see Session
|
|
190
347
|
* @throws {InitiateAuthException}
|
|
191
348
|
*/
|
|
192
|
-
refreshSession(refreshToken: string): Promise<Session>;
|
|
349
|
+
refreshSession(refreshToken: string, username?: string): Promise<Session>;
|
|
193
350
|
/**
|
|
194
351
|
*
|
|
195
352
|
* @param username Username
|
package/lib/cognito-client.js
CHANGED
|
@@ -2,7 +2,7 @@ import hashJs from 'hash.js';
|
|
|
2
2
|
import { BigInteger } from 'jsbn';
|
|
3
3
|
import { Buffer } from 'buffer';
|
|
4
4
|
import { CognitoCommonException, CognitoError } from './error.js';
|
|
5
|
-
import { calculateSignature, calculateU, decodeJwt, generateA, generateSmallA, getPasswordAuthenticationKey, randomBytes } from './utils.js';
|
|
5
|
+
import { calculateSecretHash, calculateSignature, calculateU, decodeJwt, generateA, generateSmallA, getPasswordAuthenticationKey, randomBytes } from './utils.js';
|
|
6
6
|
/**
|
|
7
7
|
* List of used and supported Cognito API calls.
|
|
8
8
|
* @see https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_Operations.html for more details
|
|
@@ -79,12 +79,13 @@ export async function cognitoRequest(body, serviceTarget, cognitoEndpoint) {
|
|
|
79
79
|
* Lightweight AWS Cogito client without any AWS SDK dependencies.
|
|
80
80
|
*/
|
|
81
81
|
export class CognitoClient {
|
|
82
|
-
constructor({ userPoolId, userPoolClientId, endpoint, oAuth2: oAuth }) {
|
|
82
|
+
constructor({ userPoolId, userPoolClientId, endpoint, oAuth2: oAuth, clientSecret }) {
|
|
83
83
|
const [cognitoPoolRegion, cognitoPoolName] = userPoolId.split('_');
|
|
84
84
|
this.cognitoEndpoint = (endpoint || `https://cognito-idp.${cognitoPoolRegion}.amazonaws.com`).replace(/\/$/, '');
|
|
85
85
|
this.cognitoPoolName = cognitoPoolName;
|
|
86
86
|
this.userPoolClientId = userPoolClientId;
|
|
87
87
|
this.oAuth = oAuth;
|
|
88
|
+
this.clientSecret = clientSecret;
|
|
88
89
|
}
|
|
89
90
|
static getDecodedTokenFromSession(session) {
|
|
90
91
|
const { payload: idToken } = decodeJwt(session.idToken);
|
|
@@ -112,7 +113,8 @@ export class CognitoClient {
|
|
|
112
113
|
ClientId: this.userPoolClientId,
|
|
113
114
|
AuthParameters: {
|
|
114
115
|
USERNAME: username,
|
|
115
|
-
SRP_A: A.toString(16)
|
|
116
|
+
SRP_A: A.toString(16),
|
|
117
|
+
SECRET_HASH: this.clientSecret && calculateSecretHash(this.clientSecret, this.userPoolClientId, username)
|
|
116
118
|
},
|
|
117
119
|
ClientMetadata: {}
|
|
118
120
|
};
|
|
@@ -122,18 +124,20 @@ export class CognitoClient {
|
|
|
122
124
|
const U = calculateU(A, B);
|
|
123
125
|
const hkdf = getPasswordAuthenticationKey(this.cognitoPoolName, challenge.ChallengeParameters.USER_ID_FOR_SRP, password, B, U, smallA, salt);
|
|
124
126
|
const { signature, timeStamp } = calculateSignature(this.cognitoPoolName, challenge.ChallengeParameters.USER_ID_FOR_SRP, challenge.ChallengeParameters.SECRET_BLOCK, hkdf);
|
|
125
|
-
const
|
|
127
|
+
const respondToAuthChallengeRequest = {
|
|
126
128
|
ChallengeName: 'PASSWORD_VERIFIER',
|
|
127
129
|
ClientId: this.userPoolClientId,
|
|
128
130
|
ChallengeResponses: {
|
|
129
131
|
PASSWORD_CLAIM_SECRET_BLOCK: challenge.ChallengeParameters.SECRET_BLOCK,
|
|
130
132
|
PASSWORD_CLAIM_SIGNATURE: signature,
|
|
131
133
|
USERNAME: challenge.ChallengeParameters.USER_ID_FOR_SRP,
|
|
132
|
-
TIMESTAMP: timeStamp
|
|
134
|
+
TIMESTAMP: timeStamp,
|
|
135
|
+
SECRET_HASH: this.clientSecret &&
|
|
136
|
+
calculateSecretHash(this.clientSecret, this.userPoolClientId, challenge.ChallengeParameters.USER_ID_FOR_SRP)
|
|
133
137
|
},
|
|
134
138
|
ClientMetadata: {}
|
|
135
139
|
};
|
|
136
|
-
const { AuthenticationResult } = await cognitoRequest(
|
|
140
|
+
const { AuthenticationResult } = await cognitoRequest(respondToAuthChallengeRequest, CognitoServiceTarget.RespondToAuthChallenge, this.cognitoEndpoint);
|
|
137
141
|
return authResultToSession(AuthenticationResult);
|
|
138
142
|
}
|
|
139
143
|
/**
|
|
@@ -151,7 +155,8 @@ export class CognitoClient {
|
|
|
151
155
|
ClientId: this.userPoolClientId,
|
|
152
156
|
AuthParameters: {
|
|
153
157
|
USERNAME: username,
|
|
154
|
-
PASSWORD: password
|
|
158
|
+
PASSWORD: password,
|
|
159
|
+
SECRET_HASH: this.clientSecret && calculateSecretHash(this.clientSecret, this.userPoolClientId, username)
|
|
155
160
|
},
|
|
156
161
|
ClientMetadata: {}
|
|
157
162
|
};
|
|
@@ -163,15 +168,17 @@ export class CognitoClient {
|
|
|
163
168
|
* Returns a new session based on the given refresh token.
|
|
164
169
|
*
|
|
165
170
|
* @param refreshToken
|
|
171
|
+
* @param username
|
|
166
172
|
* @returns @see Session
|
|
167
173
|
* @throws {InitiateAuthException}
|
|
168
174
|
*/
|
|
169
|
-
async refreshSession(refreshToken) {
|
|
175
|
+
async refreshSession(refreshToken, username) {
|
|
170
176
|
const refreshTokenPayload = {
|
|
171
177
|
AuthFlow: 'REFRESH_TOKEN_AUTH',
|
|
172
178
|
ClientId: this.userPoolClientId,
|
|
173
179
|
AuthParameters: {
|
|
174
|
-
REFRESH_TOKEN: refreshToken
|
|
180
|
+
REFRESH_TOKEN: refreshToken,
|
|
181
|
+
SECRET_HASH: this.clientSecret && username && calculateSecretHash(this.clientSecret, this.userPoolClientId, username)
|
|
175
182
|
},
|
|
176
183
|
ClientMetadata: {}
|
|
177
184
|
};
|
|
@@ -189,13 +196,14 @@ export class CognitoClient {
|
|
|
189
196
|
* @throws {SignUpException}
|
|
190
197
|
*/
|
|
191
198
|
async signUp(username, password, userAttributes) {
|
|
192
|
-
const
|
|
199
|
+
const signUpRequest = {
|
|
193
200
|
ClientId: this.userPoolClientId,
|
|
194
201
|
Username: username,
|
|
195
202
|
Password: password,
|
|
196
|
-
UserAttributes: userAttributes
|
|
203
|
+
UserAttributes: userAttributes,
|
|
204
|
+
SecretHash: this.clientSecret && calculateSecretHash(this.clientSecret, this.userPoolClientId, username)
|
|
197
205
|
};
|
|
198
|
-
const data = await cognitoRequest(
|
|
206
|
+
const data = await cognitoRequest(signUpRequest, CognitoServiceTarget.SignUp, this.cognitoEndpoint);
|
|
199
207
|
return {
|
|
200
208
|
id: data.UserSub,
|
|
201
209
|
confirmed: data.UserConfirmed
|
|
@@ -210,12 +218,13 @@ export class CognitoClient {
|
|
|
210
218
|
* @throws {ConfirmSignUpException}
|
|
211
219
|
*/
|
|
212
220
|
async confirmSignUp(username, code) {
|
|
213
|
-
const
|
|
221
|
+
const confirmSignUpRequest = {
|
|
214
222
|
ClientId: this.userPoolClientId,
|
|
215
223
|
ConfirmationCode: code,
|
|
216
|
-
Username: username
|
|
224
|
+
Username: username,
|
|
225
|
+
SecretHash: this.clientSecret && calculateSecretHash(this.clientSecret, this.userPoolClientId, username)
|
|
217
226
|
};
|
|
218
|
-
await cognitoRequest(
|
|
227
|
+
await cognitoRequest(confirmSignUpRequest, CognitoServiceTarget.ConfirmSignUp, this.cognitoEndpoint);
|
|
219
228
|
}
|
|
220
229
|
/**
|
|
221
230
|
*
|
|
@@ -283,11 +292,12 @@ export class CognitoClient {
|
|
|
283
292
|
* @throws {ForgotPasswordException}
|
|
284
293
|
*/
|
|
285
294
|
async forgotPassword(username) {
|
|
286
|
-
const
|
|
295
|
+
const forgotPasswordRequest = {
|
|
287
296
|
ClientId: this.userPoolClientId,
|
|
288
|
-
Username: username
|
|
297
|
+
Username: username,
|
|
298
|
+
SecretHash: this.clientSecret && calculateSecretHash(this.clientSecret, this.userPoolClientId, username)
|
|
289
299
|
};
|
|
290
|
-
await cognitoRequest(
|
|
300
|
+
await cognitoRequest(forgotPasswordRequest, CognitoServiceTarget.ForgotPassword, this.cognitoEndpoint);
|
|
291
301
|
}
|
|
292
302
|
/**
|
|
293
303
|
* Confirms the new password via the given code send via cognito triggered by @see forgotPassword .
|
|
@@ -299,13 +309,14 @@ export class CognitoClient {
|
|
|
299
309
|
* @throws {ConfirmForgotPasswordException}
|
|
300
310
|
*/
|
|
301
311
|
async confirmForgotPassword(username, newPassword, confirmationCode) {
|
|
302
|
-
const
|
|
312
|
+
const confirmForgotPasswordRequest = {
|
|
303
313
|
ClientId: this.userPoolClientId,
|
|
304
314
|
Username: username,
|
|
305
315
|
ConfirmationCode: confirmationCode,
|
|
306
|
-
Password: newPassword
|
|
316
|
+
Password: newPassword,
|
|
317
|
+
SecretHash: this.clientSecret && calculateSecretHash(this.clientSecret, this.userPoolClientId, username)
|
|
307
318
|
};
|
|
308
|
-
await cognitoRequest(
|
|
319
|
+
await cognitoRequest(confirmForgotPasswordRequest, CognitoServiceTarget.ConfirmForgotPassword, this.cognitoEndpoint);
|
|
309
320
|
}
|
|
310
321
|
/**
|
|
311
322
|
* Triggers cognito to resend the confirmation code
|
|
@@ -314,11 +325,12 @@ export class CognitoClient {
|
|
|
314
325
|
* @throws {ResendConfirmationCodeException}
|
|
315
326
|
*/
|
|
316
327
|
async resendConfirmationCode(username) {
|
|
317
|
-
const
|
|
328
|
+
const resendConfirmationCodeRequest = {
|
|
318
329
|
ClientId: this.userPoolClientId,
|
|
319
|
-
Username: username
|
|
330
|
+
Username: username,
|
|
331
|
+
SecretHash: this.clientSecret && calculateSecretHash(this.clientSecret, this.userPoolClientId, username)
|
|
320
332
|
};
|
|
321
|
-
await cognitoRequest(
|
|
333
|
+
await cognitoRequest(resendConfirmationCodeRequest, CognitoServiceTarget.ResendConfirmationCode, this.cognitoEndpoint);
|
|
322
334
|
}
|
|
323
335
|
/**
|
|
324
336
|
* Returns a link to Cognito`s Hosted UI for OAuth2 authentication.
|
package/lib/utils.d.ts
CHANGED
|
@@ -21,3 +21,4 @@ export declare function decodeJwt<T = unknown>(jwt: string): {
|
|
|
21
21
|
};
|
|
22
22
|
export declare function randomBytes(num: number): Promise<Buffer>;
|
|
23
23
|
export declare function formatTimestamp(date: Date): string;
|
|
24
|
+
export declare function calculateSecretHash(clientSecret: string, userPoolClientId: string, username: string): string;
|
package/lib/utils.js
CHANGED
|
@@ -123,3 +123,11 @@ export async function randomBytes(num) {
|
|
|
123
123
|
export function formatTimestamp(date) {
|
|
124
124
|
return formatInTimeZone(date, 'UTC', "EEE MMM d HH:mm:ss 'UTC' yyyy");
|
|
125
125
|
}
|
|
126
|
+
export function calculateSecretHash(clientSecret, userPoolClientId, username) {
|
|
127
|
+
const message = `${username}${userPoolClientId}`;
|
|
128
|
+
const hash = Buffer.from(hashJs
|
|
129
|
+
.hmac(hashJs.sha256, clientSecret)
|
|
130
|
+
.update(message)
|
|
131
|
+
.digest()).toString('base64');
|
|
132
|
+
return hash;
|
|
133
|
+
}
|