@vardario/cognito-client 4.0.3 → 4.0.5
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/LICENSE +1 -1
- package/lib/bigint-math.d.ts +10 -0
- package/lib/bigint-math.js +67 -0
- package/lib/browser.js +1208 -0
- package/lib/cognito-client.js +18 -20
- package/lib/error.d.ts +2 -1
- package/lib/error.js +15 -14
- package/lib/utils.d.ts +19 -14
- package/lib/utils.js +83 -59
- package/package.json +7 -11
package/lib/cognito-client.js
CHANGED
|
@@ -1,8 +1,5 @@
|
|
|
1
|
-
import hashJs from 'hash.js';
|
|
2
|
-
import { BigInteger } from 'jsbn';
|
|
3
|
-
import { Buffer } from 'buffer';
|
|
4
1
|
import { ChangePasswordError, ConfirmForgotPasswordError, ConfirmSignUpError, ForgotPasswordError, GlobalSignOutError, InitAuthError, ResendConfirmationCodeError, RespondToAuthChallengeError, RevokeTokenError, SignUpError, UpdateUserAttributesError, VerifyUserAttributeError, COMMON_EXCEPTIONS, CommonError } from './error.js';
|
|
5
|
-
import { calculateSecretHash, calculateSignature, calculateU, decodeJwt, generateA, generateSmallA, getPasswordAuthenticationKey, randomBytes } from './utils.js';
|
|
2
|
+
import { calculateSecretHash, calculateSignature, calculateU, decodeJwt, digest, generateA, generateSmallA, getPasswordAuthenticationKey, randomBytes, uint8ArrayFromString, uint8ArrayToBase64String } from './utils.js';
|
|
6
3
|
/**
|
|
7
4
|
* List of used and supported Cognito API calls.
|
|
8
5
|
* @see https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_Operations.html for more details
|
|
@@ -143,16 +140,16 @@ export class CognitoClient {
|
|
|
143
140
|
AuthParameters: {
|
|
144
141
|
USERNAME: username,
|
|
145
142
|
SRP_A: A.toString(16),
|
|
146
|
-
SECRET_HASH: this.clientSecret && calculateSecretHash(this.clientSecret, this.userPoolClientId, username)
|
|
143
|
+
SECRET_HASH: this.clientSecret && (await calculateSecretHash(this.clientSecret, this.userPoolClientId, username))
|
|
147
144
|
},
|
|
148
145
|
ClientMetadata: {}
|
|
149
146
|
};
|
|
150
147
|
const challenge = (await cognitoRequest(initiateAuthPayload, ServiceTarget.InitiateAuth, this.cognitoEndpoint));
|
|
151
|
-
const B =
|
|
152
|
-
const salt =
|
|
153
|
-
const U = calculateU(A, B);
|
|
154
|
-
const hkdf = getPasswordAuthenticationKey(this.cognitoPoolName, challenge.ChallengeParameters.USER_ID_FOR_SRP, password, B, U, smallA, salt);
|
|
155
|
-
const { signature, timeStamp } = calculateSignature(this.cognitoPoolName, challenge.ChallengeParameters.USER_ID_FOR_SRP, challenge.ChallengeParameters.SECRET_BLOCK, hkdf);
|
|
148
|
+
const B = BigInt('0x' + challenge.ChallengeParameters.SRP_B);
|
|
149
|
+
const salt = BigInt('0x' + challenge.ChallengeParameters.SALT);
|
|
150
|
+
const U = await calculateU(A, B);
|
|
151
|
+
const hkdf = await getPasswordAuthenticationKey(this.cognitoPoolName, challenge.ChallengeParameters.USER_ID_FOR_SRP, password, B, U, smallA, salt);
|
|
152
|
+
const { signature, timeStamp } = await calculateSignature(this.cognitoPoolName, challenge.ChallengeParameters.USER_ID_FOR_SRP, challenge.ChallengeParameters.SECRET_BLOCK, hkdf);
|
|
156
153
|
const respondToAuthChallengeRequest = {
|
|
157
154
|
ChallengeName: 'PASSWORD_VERIFIER',
|
|
158
155
|
ClientId: this.userPoolClientId,
|
|
@@ -162,7 +159,7 @@ export class CognitoClient {
|
|
|
162
159
|
USERNAME: challenge.ChallengeParameters.USER_ID_FOR_SRP,
|
|
163
160
|
TIMESTAMP: timeStamp,
|
|
164
161
|
SECRET_HASH: this.clientSecret &&
|
|
165
|
-
calculateSecretHash(this.clientSecret, this.userPoolClientId, challenge.ChallengeParameters.USER_ID_FOR_SRP)
|
|
162
|
+
(await calculateSecretHash(this.clientSecret, this.userPoolClientId, challenge.ChallengeParameters.USER_ID_FOR_SRP))
|
|
166
163
|
},
|
|
167
164
|
ClientMetadata: {}
|
|
168
165
|
};
|
|
@@ -185,7 +182,7 @@ export class CognitoClient {
|
|
|
185
182
|
AuthParameters: {
|
|
186
183
|
USERNAME: username,
|
|
187
184
|
PASSWORD: password,
|
|
188
|
-
SECRET_HASH: this.clientSecret && calculateSecretHash(this.clientSecret, this.userPoolClientId, username)
|
|
185
|
+
SECRET_HASH: this.clientSecret && (await calculateSecretHash(this.clientSecret, this.userPoolClientId, username))
|
|
189
186
|
},
|
|
190
187
|
ClientMetadata: {}
|
|
191
188
|
};
|
|
@@ -207,7 +204,9 @@ export class CognitoClient {
|
|
|
207
204
|
ClientId: this.userPoolClientId,
|
|
208
205
|
AuthParameters: {
|
|
209
206
|
REFRESH_TOKEN: refreshToken,
|
|
210
|
-
SECRET_HASH: this.clientSecret &&
|
|
207
|
+
SECRET_HASH: this.clientSecret &&
|
|
208
|
+
username &&
|
|
209
|
+
(await calculateSecretHash(this.clientSecret, this.userPoolClientId, username))
|
|
211
210
|
},
|
|
212
211
|
ClientMetadata: {}
|
|
213
212
|
};
|
|
@@ -230,7 +229,7 @@ export class CognitoClient {
|
|
|
230
229
|
Username: username,
|
|
231
230
|
Password: password,
|
|
232
231
|
UserAttributes: userAttributes,
|
|
233
|
-
SecretHash: this.clientSecret && calculateSecretHash(this.clientSecret, this.userPoolClientId, username)
|
|
232
|
+
SecretHash: this.clientSecret && (await calculateSecretHash(this.clientSecret, this.userPoolClientId, username))
|
|
234
233
|
};
|
|
235
234
|
const data = await cognitoRequest(signUpRequest, ServiceTarget.SignUp, this.cognitoEndpoint);
|
|
236
235
|
return {
|
|
@@ -251,7 +250,7 @@ export class CognitoClient {
|
|
|
251
250
|
ClientId: this.userPoolClientId,
|
|
252
251
|
ConfirmationCode: code,
|
|
253
252
|
Username: username,
|
|
254
|
-
SecretHash: this.clientSecret && calculateSecretHash(this.clientSecret, this.userPoolClientId, username)
|
|
253
|
+
SecretHash: this.clientSecret && (await calculateSecretHash(this.clientSecret, this.userPoolClientId, username))
|
|
255
254
|
};
|
|
256
255
|
await cognitoRequest(confirmSignUpRequest, ServiceTarget.ConfirmSignUp, this.cognitoEndpoint);
|
|
257
256
|
}
|
|
@@ -327,7 +326,7 @@ export class CognitoClient {
|
|
|
327
326
|
const forgotPasswordRequest = {
|
|
328
327
|
ClientId: this.userPoolClientId,
|
|
329
328
|
Username: username,
|
|
330
|
-
SecretHash: this.clientSecret && calculateSecretHash(this.clientSecret, this.userPoolClientId, username)
|
|
329
|
+
SecretHash: this.clientSecret && (await calculateSecretHash(this.clientSecret, this.userPoolClientId, username))
|
|
331
330
|
};
|
|
332
331
|
await cognitoRequest(forgotPasswordRequest, ServiceTarget.ForgotPassword, this.cognitoEndpoint);
|
|
333
332
|
}
|
|
@@ -346,7 +345,7 @@ export class CognitoClient {
|
|
|
346
345
|
Username: username,
|
|
347
346
|
ConfirmationCode: confirmationCode,
|
|
348
347
|
Password: newPassword,
|
|
349
|
-
SecretHash: this.clientSecret && calculateSecretHash(this.clientSecret, this.userPoolClientId, username)
|
|
348
|
+
SecretHash: this.clientSecret && (await calculateSecretHash(this.clientSecret, this.userPoolClientId, username))
|
|
350
349
|
};
|
|
351
350
|
await cognitoRequest(confirmForgotPasswordRequest, ServiceTarget.ConfirmForgotPassword, this.cognitoEndpoint);
|
|
352
351
|
}
|
|
@@ -360,7 +359,7 @@ export class CognitoClient {
|
|
|
360
359
|
const resendConfirmationCodeRequest = {
|
|
361
360
|
ClientId: this.userPoolClientId,
|
|
362
361
|
Username: username,
|
|
363
|
-
SecretHash: this.clientSecret && calculateSecretHash(this.clientSecret, this.userPoolClientId, username)
|
|
362
|
+
SecretHash: this.clientSecret && (await calculateSecretHash(this.clientSecret, this.userPoolClientId, username))
|
|
364
363
|
};
|
|
365
364
|
await cognitoRequest(resendConfirmationCodeRequest, ServiceTarget.ResendConfirmationCode, this.cognitoEndpoint);
|
|
366
365
|
}
|
|
@@ -379,8 +378,7 @@ export class CognitoClient {
|
|
|
379
378
|
}
|
|
380
379
|
const state = (await randomBytes(32)).toString('hex');
|
|
381
380
|
const pkce = (await randomBytes(128)).toString('hex');
|
|
382
|
-
const code_challenge =
|
|
383
|
-
.toString('base64')
|
|
381
|
+
const code_challenge = uint8ArrayToBase64String(await digest('SHA-256', uint8ArrayFromString(pkce)))
|
|
384
382
|
.replace(/\+/g, '-')
|
|
385
383
|
.replace(/\//g, '_')
|
|
386
384
|
.replace(/=+$/, '');
|
package/lib/error.d.ts
CHANGED
|
@@ -365,7 +365,8 @@ export declare enum RevokeTokenException {
|
|
|
365
365
|
export type CognitoErrorType = 'CommonError' | 'InitAuthError' | 'RespondToAuthChallengeError' | 'SignUpError' | 'ConfirmSignUpError' | 'ChangePasswordError' | 'RevokeTokenError' | 'ForgotPasswordError' | 'ConfirmForgotPasswordError' | 'ResendConfirmationCodeError' | 'UpdateUserAttributesError' | 'VerifyUserAttributeError' | 'GlobalSignOutError';
|
|
366
366
|
export declare class CognitoError extends Error {
|
|
367
367
|
readonly errorType: CognitoErrorType;
|
|
368
|
-
|
|
368
|
+
readonly cognitoException: CommonException | InitiateAuthException | RespondToAuthChallengeException | SignUpException | ConfirmSignUpException | ChangePasswordException | RevokeTokenException | ForgotPasswordException | ConfirmForgotPasswordException | ResendConfirmationException | UpdateUserAttributesException | VerifyUserAttributeException | GlobalSignOutException;
|
|
369
|
+
constructor(message: string, errorType: CognitoErrorType, cognitoException: CommonException | InitiateAuthException | RespondToAuthChallengeException | SignUpException | ConfirmSignUpException | ChangePasswordException | RevokeTokenException | ForgotPasswordException | ConfirmForgotPasswordException | ResendConfirmationException | UpdateUserAttributesException | VerifyUserAttributeException | GlobalSignOutException);
|
|
369
370
|
}
|
|
370
371
|
export declare class CommonError extends CognitoError {
|
|
371
372
|
readonly cognitoException: CommonException;
|
package/lib/error.js
CHANGED
|
@@ -401,86 +401,87 @@ export var RevokeTokenException;
|
|
|
401
401
|
RevokeTokenException["UnsupportedTokenTypeException"] = "UnsupportedTokenTypeException";
|
|
402
402
|
})(RevokeTokenException || (RevokeTokenException = {}));
|
|
403
403
|
export class CognitoError extends Error {
|
|
404
|
-
constructor(message, errorType) {
|
|
404
|
+
constructor(message, errorType, cognitoException) {
|
|
405
405
|
super(message);
|
|
406
406
|
this.errorType = errorType;
|
|
407
|
+
this.cognitoException = cognitoException;
|
|
407
408
|
}
|
|
408
409
|
}
|
|
409
410
|
export class CommonError extends CognitoError {
|
|
410
411
|
constructor(message, cognitoException) {
|
|
411
|
-
super(message, 'CommonError');
|
|
412
|
+
super(message, 'CommonError', cognitoException);
|
|
412
413
|
this.cognitoException = cognitoException;
|
|
413
414
|
}
|
|
414
415
|
}
|
|
415
416
|
export class InitAuthError extends CognitoError {
|
|
416
417
|
constructor(message, cognitoException) {
|
|
417
|
-
super(message, 'InitAuthError');
|
|
418
|
+
super(message, 'InitAuthError', cognitoException);
|
|
418
419
|
this.cognitoException = cognitoException;
|
|
419
420
|
}
|
|
420
421
|
}
|
|
421
422
|
export class RespondToAuthChallengeError extends CognitoError {
|
|
422
423
|
constructor(message, cognitoException) {
|
|
423
|
-
super(message, 'RespondToAuthChallengeError');
|
|
424
|
+
super(message, 'RespondToAuthChallengeError', cognitoException);
|
|
424
425
|
this.cognitoException = cognitoException;
|
|
425
426
|
}
|
|
426
427
|
}
|
|
427
428
|
export class SignUpError extends CognitoError {
|
|
428
429
|
constructor(message, cognitoException) {
|
|
429
|
-
super(message, 'SignUpError');
|
|
430
|
+
super(message, 'SignUpError', cognitoException);
|
|
430
431
|
this.cognitoException = cognitoException;
|
|
431
432
|
}
|
|
432
433
|
}
|
|
433
434
|
export class ConfirmSignUpError extends CognitoError {
|
|
434
435
|
constructor(message, cognitoException) {
|
|
435
|
-
super(message, 'ConfirmSignUpError');
|
|
436
|
+
super(message, 'ConfirmSignUpError', cognitoException);
|
|
436
437
|
this.cognitoException = cognitoException;
|
|
437
438
|
}
|
|
438
439
|
}
|
|
439
440
|
export class ChangePasswordError extends CognitoError {
|
|
440
441
|
constructor(message, cognitoException) {
|
|
441
|
-
super(message, 'ChangePasswordError');
|
|
442
|
+
super(message, 'ChangePasswordError', cognitoException);
|
|
442
443
|
this.cognitoException = cognitoException;
|
|
443
444
|
}
|
|
444
445
|
}
|
|
445
446
|
export class RevokeTokenError extends CognitoError {
|
|
446
447
|
constructor(message, cognitoException) {
|
|
447
|
-
super(message, 'RevokeTokenError');
|
|
448
|
+
super(message, 'RevokeTokenError', cognitoException);
|
|
448
449
|
this.cognitoException = cognitoException;
|
|
449
450
|
}
|
|
450
451
|
}
|
|
451
452
|
export class ForgotPasswordError extends CognitoError {
|
|
452
453
|
constructor(message, cognitoException) {
|
|
453
|
-
super(message, 'ForgotPasswordError');
|
|
454
|
+
super(message, 'ForgotPasswordError', cognitoException);
|
|
454
455
|
this.cognitoException = cognitoException;
|
|
455
456
|
}
|
|
456
457
|
}
|
|
457
458
|
export class ConfirmForgotPasswordError extends CognitoError {
|
|
458
459
|
constructor(message, cognitoException) {
|
|
459
|
-
super(message, 'ConfirmForgotPasswordError');
|
|
460
|
+
super(message, 'ConfirmForgotPasswordError', cognitoException);
|
|
460
461
|
this.cognitoException = cognitoException;
|
|
461
462
|
}
|
|
462
463
|
}
|
|
463
464
|
export class ResendConfirmationCodeError extends CognitoError {
|
|
464
465
|
constructor(message, cognitoException) {
|
|
465
|
-
super(message, 'ResendConfirmationCodeError');
|
|
466
|
+
super(message, 'ResendConfirmationCodeError', cognitoException);
|
|
466
467
|
this.cognitoException = cognitoException;
|
|
467
468
|
}
|
|
468
469
|
}
|
|
469
470
|
export class UpdateUserAttributesError extends CognitoError {
|
|
470
471
|
constructor(message, cognitoException) {
|
|
471
|
-
super(message, 'UpdateUserAttributesError');
|
|
472
|
+
super(message, 'UpdateUserAttributesError', cognitoException);
|
|
472
473
|
this.cognitoException = cognitoException;
|
|
473
474
|
}
|
|
474
475
|
}
|
|
475
476
|
export class VerifyUserAttributeError extends CognitoError {
|
|
476
477
|
constructor(message, cognitoException) {
|
|
477
|
-
super(message, 'VerifyUserAttributeError');
|
|
478
|
+
super(message, 'VerifyUserAttributeError', cognitoException);
|
|
478
479
|
this.cognitoException = cognitoException;
|
|
479
480
|
}
|
|
480
481
|
}
|
|
481
482
|
export class GlobalSignOutError extends CognitoError {
|
|
482
483
|
constructor(message, cognitoException) {
|
|
483
|
-
super(message, 'GlobalSignOutError');
|
|
484
|
+
super(message, 'GlobalSignOutError', cognitoException);
|
|
484
485
|
this.cognitoException = cognitoException;
|
|
485
486
|
}
|
|
486
487
|
}
|
package/lib/utils.d.ts
CHANGED
|
@@ -1,19 +1,22 @@
|
|
|
1
1
|
/// <reference types="node" resolution-mode="require"/>
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
export declare function
|
|
5
|
-
export declare function
|
|
6
|
-
export declare function
|
|
7
|
-
export declare function
|
|
8
|
-
export declare function
|
|
9
|
-
export declare function
|
|
10
|
-
export declare function
|
|
11
|
-
export declare function
|
|
12
|
-
export declare function
|
|
13
|
-
export declare function
|
|
2
|
+
export declare function uint8ArrayFromHexString(hexString: string): Uint8Array;
|
|
3
|
+
export declare function uint8ArrayFromString(str: string): Uint8Array;
|
|
4
|
+
export declare function uint8ArrayFromBase64String(str: string): Uint8Array;
|
|
5
|
+
export declare function uint8ArrayToHexString(bytes: Uint8Array): string;
|
|
6
|
+
export declare function uint8ArrayToBase64String(bytes: Uint8Array): string;
|
|
7
|
+
export declare function padHex(bigInt: bigint): string;
|
|
8
|
+
export declare function hashHexString(str: string): Promise<string>;
|
|
9
|
+
export declare function hashBuffer(buffer: Uint8Array): Promise<string>;
|
|
10
|
+
export declare function generateSmallA(): Promise<bigint>;
|
|
11
|
+
export declare function generateA(smallA: bigint): bigint;
|
|
12
|
+
export declare function calculateU(A: bigint, B: bigint): Promise<bigint>;
|
|
13
|
+
export declare function calculateS(X: bigint, B: bigint, U: bigint, smallA: bigint): bigint;
|
|
14
|
+
export declare function calculateHKDF(ikm: Uint8Array, salt: Uint8Array): Promise<Uint8Array>;
|
|
15
|
+
export declare function getPasswordAuthenticationKey(poolName: string, username: string, password: string, B: bigint, U: bigint, smallA: bigint, salt: bigint): Promise<Uint8Array>;
|
|
16
|
+
export declare function calculateSignature(poolName: string, userId: string, secretBlock: string, hkdf: Uint8Array, date?: Date): Promise<{
|
|
14
17
|
signature: string;
|
|
15
18
|
timeStamp: string;
|
|
16
|
-
}
|
|
19
|
+
}>;
|
|
17
20
|
export declare function decodeJwt<T = unknown>(jwt: string): {
|
|
18
21
|
header: any;
|
|
19
22
|
payload: T;
|
|
@@ -21,4 +24,6 @@ export declare function decodeJwt<T = unknown>(jwt: string): {
|
|
|
21
24
|
};
|
|
22
25
|
export declare function randomBytes(num: number): Promise<Buffer>;
|
|
23
26
|
export declare function formatTimestamp(date: Date): string;
|
|
24
|
-
export declare function calculateSecretHash(clientSecret: string, userPoolClientId: string, username: string): string
|
|
27
|
+
export declare function calculateSecretHash(clientSecret: string, userPoolClientId: string, username: string): Promise<string>;
|
|
28
|
+
export declare function digest(algorithm: AlgorithmIdentifier, data: Uint8Array): Promise<Uint8Array>;
|
|
29
|
+
export declare function hmac(algorithm: AlgorithmIdentifier, key: Uint8Array, data: Uint8Array): Promise<Uint8Array>;
|
package/lib/utils.js
CHANGED
|
@@ -1,9 +1,28 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
1
|
+
import * as bigIntMath from './bigint-math.js';
|
|
2
|
+
const WEEK_DAYS = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
|
|
3
|
+
const MONTHS = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
|
|
4
|
+
export function uint8ArrayFromHexString(hexString) {
|
|
5
|
+
return Uint8Array.from(hexString.match(/.{1,2}/g).map(byte => parseInt(byte, 16)));
|
|
6
|
+
}
|
|
7
|
+
export function uint8ArrayFromString(str) {
|
|
8
|
+
const textEncoder = new TextEncoder();
|
|
9
|
+
return textEncoder.encode(str);
|
|
10
|
+
}
|
|
11
|
+
export function uint8ArrayFromBase64String(str) {
|
|
12
|
+
const binaryString = atob(str);
|
|
13
|
+
const bytes = new Uint8Array(binaryString.length);
|
|
14
|
+
for (let i = 0; i < binaryString.length; i++) {
|
|
15
|
+
bytes[i] = binaryString.charCodeAt(i);
|
|
16
|
+
}
|
|
17
|
+
return bytes;
|
|
18
|
+
}
|
|
19
|
+
export function uint8ArrayToHexString(bytes) {
|
|
20
|
+
return bytes.reduce((str, byte) => str + byte.toString(16).padStart(2, '0'), '');
|
|
21
|
+
}
|
|
22
|
+
export function uint8ArrayToBase64String(bytes) {
|
|
23
|
+
return btoa(String.fromCharCode(...bytes));
|
|
24
|
+
}
|
|
25
|
+
const N = BigInt('0xFFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1' +
|
|
7
26
|
'29024E088A67CC74020BBEA63B139B22514A08798E3404DD' +
|
|
8
27
|
'EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245' +
|
|
9
28
|
'E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED' +
|
|
@@ -18,14 +37,13 @@ const initN = 'FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1' +
|
|
|
18
37
|
'ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6B' +
|
|
19
38
|
'F12FFA06D98A0864D87602733EC86A64521F2B18177B200C' +
|
|
20
39
|
'BBE117577A615D6C770988C0BAD946E208E24FA074E5AB31' +
|
|
21
|
-
'43DB5BFCE0FD108E4B82D120A93AD2CAFFFFFFFFFFFFFFFF';
|
|
22
|
-
const
|
|
23
|
-
const
|
|
24
|
-
const k = new BigInteger(hashHexString(`${padHex(N)}${padHex(g)}`), 16);
|
|
40
|
+
'43DB5BFCE0FD108E4B82D120A93AD2CAFFFFFFFFFFFFFFFF');
|
|
41
|
+
const g = BigInt('0x2');
|
|
42
|
+
const k = BigInt('0x' + (await hashHexString(`${padHex(N)}${padHex(g)}`)));
|
|
25
43
|
export function padHex(bigInt) {
|
|
26
44
|
const HEX_MSB_REGEX = /^[89a-f]/i;
|
|
27
|
-
const isNegative = bigInt
|
|
28
|
-
let hexStr =
|
|
45
|
+
const isNegative = bigInt < 0n;
|
|
46
|
+
let hexStr = bigIntMath.abs(bigInt).toString(16);
|
|
29
47
|
hexStr = hexStr.length % 2 !== 0 ? `0${hexStr}` : hexStr;
|
|
30
48
|
hexStr = HEX_MSB_REGEX.test(hexStr) ? `00${hexStr}` : hexStr;
|
|
31
49
|
if (isNegative) {
|
|
@@ -36,7 +54,7 @@ export function padHex(bigInt) {
|
|
|
36
54
|
return '0123456789ABCDEF'.charAt(invertedNibble);
|
|
37
55
|
})
|
|
38
56
|
.join('');
|
|
39
|
-
const flippedBitsBI =
|
|
57
|
+
const flippedBitsBI = BigInt('0x' + invertedNibbles) + 1n;
|
|
40
58
|
hexStr = flippedBitsBI.toString(16);
|
|
41
59
|
if (hexStr.toUpperCase().startsWith('FF8')) {
|
|
42
60
|
hexStr = hexStr.substring(2);
|
|
@@ -44,62 +62,53 @@ export function padHex(bigInt) {
|
|
|
44
62
|
}
|
|
45
63
|
return hexStr;
|
|
46
64
|
}
|
|
47
|
-
export function hashHexString(str) {
|
|
48
|
-
return hashBuffer(
|
|
65
|
+
export async function hashHexString(str) {
|
|
66
|
+
return hashBuffer(uint8ArrayFromHexString(str));
|
|
49
67
|
}
|
|
50
|
-
export function hashBuffer(buffer) {
|
|
51
|
-
const
|
|
52
|
-
return
|
|
68
|
+
export async function hashBuffer(buffer) {
|
|
69
|
+
const hashArray = await digest('SHA-256', buffer);
|
|
70
|
+
return uint8ArrayToHexString(hashArray);
|
|
53
71
|
}
|
|
54
72
|
export async function generateSmallA() {
|
|
55
|
-
return
|
|
73
|
+
return BigInt('0x' + (await randomBytes(128)).toString('hex'));
|
|
56
74
|
}
|
|
57
75
|
export function generateA(smallA) {
|
|
58
|
-
const A =
|
|
76
|
+
const A = bigIntMath.modPow(g, smallA, N);
|
|
59
77
|
return A;
|
|
60
78
|
}
|
|
61
|
-
export function calculateU(A, B) {
|
|
62
|
-
return
|
|
79
|
+
export async function calculateU(A, B) {
|
|
80
|
+
return BigInt('0x' + (await hashHexString(padHex(A) + padHex(B))));
|
|
63
81
|
}
|
|
64
82
|
export function calculateS(X, B, U, smallA) {
|
|
65
|
-
const gModPowXN =
|
|
66
|
-
const bMinusKMult = B
|
|
67
|
-
return
|
|
68
|
-
}
|
|
69
|
-
export function calculateHKDF(ikm, salt) {
|
|
70
|
-
const infoBitsBuffer =
|
|
71
|
-
|
|
72
|
-
|
|
83
|
+
const gModPowXN = bigIntMath.modPow(g, X, N);
|
|
84
|
+
const bMinusKMult = B - k * gModPowXN;
|
|
85
|
+
return bigIntMath.modPow(bMinusKMult, smallA + U * X, N) % N;
|
|
86
|
+
}
|
|
87
|
+
export async function calculateHKDF(ikm, salt) {
|
|
88
|
+
const infoBitsBuffer = new Uint8Array([
|
|
89
|
+
...uint8ArrayFromString('Caldera Derived Key'),
|
|
90
|
+
...uint8ArrayFromString(String.fromCharCode(1))
|
|
73
91
|
]);
|
|
74
|
-
const prk =
|
|
75
|
-
|
|
76
|
-
.update(ikm)
|
|
77
|
-
.digest();
|
|
78
|
-
const hmacResult = hashJs
|
|
79
|
-
.hmac(hashJs.sha256, prk)
|
|
80
|
-
.update(infoBitsBuffer)
|
|
81
|
-
.digest();
|
|
92
|
+
const prk = await hmac('SHA-256', salt, ikm);
|
|
93
|
+
const hmacResult = await hmac('SHA-256', prk, infoBitsBuffer);
|
|
82
94
|
return hmacResult.slice(0, 16);
|
|
83
95
|
}
|
|
84
|
-
export function getPasswordAuthenticationKey(poolName, username, password, B, U, smallA, salt) {
|
|
96
|
+
export async function getPasswordAuthenticationKey(poolName, username, password, B, U, smallA, salt) {
|
|
85
97
|
const usernamePassword = `${poolName}${username}:${password}`;
|
|
86
|
-
const usernamePasswordHash = hashBuffer(
|
|
87
|
-
const X =
|
|
98
|
+
const usernamePasswordHash = await hashBuffer(uint8ArrayFromString(usernamePassword));
|
|
99
|
+
const X = BigInt('0x' + (await hashHexString(padHex(salt) + usernamePasswordHash)));
|
|
88
100
|
const S = calculateS(X, B, U, smallA);
|
|
89
|
-
return calculateHKDF(
|
|
101
|
+
return calculateHKDF(uint8ArrayFromHexString(padHex(S)), uint8ArrayFromHexString(padHex(U)));
|
|
90
102
|
}
|
|
91
|
-
export function calculateSignature(poolName, userId, secretBlock, hkdf, date = new Date()) {
|
|
103
|
+
export async function calculateSignature(poolName, userId, secretBlock, hkdf, date = new Date()) {
|
|
92
104
|
const timeStamp = formatTimestamp(date);
|
|
93
|
-
const concatBuffer =
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
105
|
+
const concatBuffer = new Uint8Array([
|
|
106
|
+
...uint8ArrayFromString(poolName),
|
|
107
|
+
...uint8ArrayFromString(userId),
|
|
108
|
+
...uint8ArrayFromBase64String(secretBlock),
|
|
109
|
+
...uint8ArrayFromString(timeStamp)
|
|
98
110
|
]);
|
|
99
|
-
const signature =
|
|
100
|
-
.hmac(hashJs.sha256, hkdf)
|
|
101
|
-
.update(concatBuffer)
|
|
102
|
-
.digest()).toString('base64');
|
|
111
|
+
const signature = uint8ArrayToBase64String(await hmac('SHA-256', hkdf, concatBuffer));
|
|
103
112
|
return {
|
|
104
113
|
signature,
|
|
105
114
|
timeStamp
|
|
@@ -114,16 +123,31 @@ export function decodeJwt(jwt) {
|
|
|
114
123
|
};
|
|
115
124
|
}
|
|
116
125
|
export async function randomBytes(num) {
|
|
117
|
-
return
|
|
126
|
+
return Buffer.from(crypto.getRandomValues(new Uint8Array(num)));
|
|
118
127
|
}
|
|
119
128
|
export function formatTimestamp(date) {
|
|
120
|
-
return
|
|
129
|
+
return `${WEEK_DAYS[date.getUTCDay()]} ${MONTHS[date.getUTCMonth()]} ${date.getUTCDate()} ${date
|
|
130
|
+
.getUTCHours()
|
|
131
|
+
.toString()
|
|
132
|
+
.padStart(2, '0')}:${date.getUTCMinutes().toString().padStart(2, '0')}:${date
|
|
133
|
+
.getUTCSeconds()
|
|
134
|
+
.toString()
|
|
135
|
+
.padStart(2, '0')} UTC ${date.getUTCFullYear()}`;
|
|
121
136
|
}
|
|
122
|
-
export function calculateSecretHash(clientSecret, userPoolClientId, username) {
|
|
137
|
+
export async function calculateSecretHash(clientSecret, userPoolClientId, username) {
|
|
123
138
|
const message = `${username}${userPoolClientId}`;
|
|
124
|
-
const hash =
|
|
125
|
-
.hmac(hashJs.sha256, clientSecret)
|
|
126
|
-
.update(message)
|
|
127
|
-
.digest()).toString('base64');
|
|
139
|
+
const hash = uint8ArrayToBase64String(await hmac('SHA-256', uint8ArrayFromString(clientSecret), uint8ArrayFromString(message)));
|
|
128
140
|
return hash;
|
|
129
141
|
}
|
|
142
|
+
export async function digest(algorithm, data) {
|
|
143
|
+
const hashBuffer = await crypto.subtle.digest(algorithm, data);
|
|
144
|
+
return new Uint8Array(hashBuffer);
|
|
145
|
+
}
|
|
146
|
+
export async function hmac(algorithm, key, data) {
|
|
147
|
+
const cryptoKey = await crypto.subtle.importKey('raw', key, {
|
|
148
|
+
name: 'HMAC',
|
|
149
|
+
hash: algorithm
|
|
150
|
+
}, false, ['sign']);
|
|
151
|
+
const signature = await crypto.subtle.sign('HMAC', cryptoKey, data);
|
|
152
|
+
return new Uint8Array(signature);
|
|
153
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vardario/cognito-client",
|
|
3
|
-
"version": "4.0.
|
|
3
|
+
"version": "4.0.5",
|
|
4
4
|
"description": "",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Sahin Vardar",
|
|
@@ -10,31 +10,26 @@
|
|
|
10
10
|
},
|
|
11
11
|
"type": "module",
|
|
12
12
|
"main": "lib/index.js",
|
|
13
|
+
"browser": "lib/browser.js",
|
|
13
14
|
"files": [
|
|
14
15
|
"lib"
|
|
15
16
|
],
|
|
16
17
|
"scripts": {
|
|
17
|
-
"build": "
|
|
18
|
+
"build": "pnpm build:lib && pnpm build:browser",
|
|
19
|
+
"build:browser": "esbuild src/index.ts --bundle --outfile=lib/browser.js --platform=neutral --external:zod",
|
|
20
|
+
"build:lib": "tsc --build",
|
|
18
21
|
"format": "prettier --plugin-search-dir . --write . && prettier-package-json --write && eslint --fix .",
|
|
19
22
|
"integration-test": "vitest run integration",
|
|
20
23
|
"prepare": "husky install",
|
|
21
24
|
"test": "vitest run unit",
|
|
22
25
|
"watch": "tsc --build --watch"
|
|
23
26
|
},
|
|
24
|
-
"dependencies": {
|
|
25
|
-
"@lukeed/csprng": "^1.1.0",
|
|
26
|
-
"buffer": "^6.0.3",
|
|
27
|
-
"date-fns-tz": "^2.0.0",
|
|
28
|
-
"hash.js": "^1.1.7",
|
|
29
|
-
"jsbn": "^1.1.0"
|
|
30
|
-
},
|
|
31
27
|
"devDependencies": {
|
|
32
28
|
"@aws-sdk/client-cognito-identity-provider": "^3.465.0",
|
|
33
|
-
"@types/jsbn": "^1.2.33",
|
|
34
29
|
"@types/jsdom": "^21.1.5",
|
|
35
|
-
"@types/randombytes": "^2.0.3",
|
|
36
30
|
"@typescript-eslint/eslint-plugin": "^6.11.0",
|
|
37
31
|
"@typescript-eslint/parser": "^6.11.0",
|
|
32
|
+
"esbuild": "^0.20.2",
|
|
38
33
|
"eslint": "^8.54.0",
|
|
39
34
|
"eslint-config-prettier": "^9.0.0",
|
|
40
35
|
"eslint-plugin-unused-imports": "^3.0.0",
|
|
@@ -46,6 +41,7 @@
|
|
|
46
41
|
"prettier-package-json": "^2.8.0",
|
|
47
42
|
"semantic-release": "^22.0.8",
|
|
48
43
|
"testcontainers": "^10.2.2",
|
|
44
|
+
"tsx": "^4.7.1",
|
|
49
45
|
"typescript": "^5.2.2",
|
|
50
46
|
"vitest": "^0.34.6",
|
|
51
47
|
"vitest-fetch-mock": "^0.2.2"
|