@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.
@@ -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 = new BigInteger(challenge.ChallengeParameters.SRP_B, 16);
152
- const salt = new BigInteger(challenge.ChallengeParameters.SALT, 16);
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 && username && calculateSecretHash(this.clientSecret, this.userPoolClientId, username)
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 = Buffer.from(hashJs.sha256().update(pkce).digest())
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
- constructor(message: string, errorType: CognitoErrorType);
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
- import { BigInteger } from 'jsbn';
3
- import { Buffer } from 'buffer';
4
- export declare function padHex(bigInt: BigInteger): string;
5
- export declare function hashHexString(str: string): string;
6
- export declare function hashBuffer(buffer: Buffer): string;
7
- export declare function generateSmallA(): Promise<BigInteger>;
8
- export declare function generateA(smallA: BigInteger): BigInteger;
9
- export declare function calculateU(A: BigInteger, B: BigInteger): BigInteger;
10
- export declare function calculateS(X: BigInteger, B: BigInteger, U: BigInteger, smallA: BigInteger): BigInteger;
11
- export declare function calculateHKDF(ikm: Buffer, salt: Buffer): number[];
12
- export declare function getPasswordAuthenticationKey(poolName: string, username: string, password: string, B: BigInteger, U: BigInteger, smallA: BigInteger, salt: BigInteger): number[];
13
- export declare function calculateSignature(poolName: string, userId: string, secretBlock: string, hkdf: number[], date?: Date): {
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 hashJs from 'hash.js';
2
- import { BigInteger } from 'jsbn';
3
- import { Buffer } from 'buffer';
4
- import formatInTimeZone from 'date-fns-tz/formatInTimeZone';
5
- import { random } from '@lukeed/csprng';
6
- const initN = 'FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1' +
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 N = new BigInteger(initN, 16);
23
- const g = new BigInteger('2', 16);
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.compareTo(BigInteger.ZERO) < 0;
28
- let hexStr = bigInt.abs().toString(16);
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 = new BigInteger(invertedNibbles, 16).add(BigInteger.ONE);
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(Buffer.from(str, 'hex'));
65
+ export async function hashHexString(str) {
66
+ return hashBuffer(uint8ArrayFromHexString(str));
49
67
  }
50
- export function hashBuffer(buffer) {
51
- const hash = hashJs.sha256().update(buffer).digest('hex');
52
- return new Array(64 - hash.length).join('0') + hash;
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 new BigInteger((await randomBytes(128)).toString('hex'), 16);
73
+ return BigInt('0x' + (await randomBytes(128)).toString('hex'));
56
74
  }
57
75
  export function generateA(smallA) {
58
- const A = g.modPow(smallA, N);
76
+ const A = bigIntMath.modPow(g, smallA, N);
59
77
  return A;
60
78
  }
61
- export function calculateU(A, B) {
62
- return new BigInteger(hashHexString(padHex(A) + padHex(B)), 16);
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 = g.modPow(X, N);
66
- const bMinusKMult = B.subtract(k.multiply(gModPowXN));
67
- return bMinusKMult.modPow(smallA.add(U.multiply(X)), N).mod(N);
68
- }
69
- export function calculateHKDF(ikm, salt) {
70
- const infoBitsBuffer = Buffer.concat([
71
- Buffer.from('Caldera Derived Key', 'utf8'),
72
- Buffer.from(String.fromCharCode(1), 'utf8')
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 = hashJs
75
- .hmac(hashJs.sha256, salt)
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(Buffer.from(usernamePassword, 'utf-8'));
87
- const X = new BigInteger(hashHexString(padHex(salt) + usernamePasswordHash), 16);
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(Buffer.from(padHex(S), 'hex'), Buffer.from(padHex(U), 'hex'));
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 = Buffer.concat([
94
- Buffer.from(poolName, 'utf8'),
95
- Buffer.from(userId, 'utf8'),
96
- Buffer.from(secretBlock, 'base64'),
97
- Buffer.from(timeStamp, 'utf8')
105
+ const concatBuffer = new Uint8Array([
106
+ ...uint8ArrayFromString(poolName),
107
+ ...uint8ArrayFromString(userId),
108
+ ...uint8ArrayFromBase64String(secretBlock),
109
+ ...uint8ArrayFromString(timeStamp)
98
110
  ]);
99
- const signature = Buffer.from(hashJs
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 random(num);
126
+ return Buffer.from(crypto.getRandomValues(new Uint8Array(num)));
118
127
  }
119
128
  export function formatTimestamp(date) {
120
- return formatInTimeZone(date, 'UTC', "EEE MMM d HH:mm:ss 'UTC' yyyy");
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 = Buffer.from(hashJs
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",
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": "tsc --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"