@vardario/cognito-client 0.1.5 → 0.1.7

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,4 +1,4 @@
1
- import { SessionStorage } from './session-storage/index.js';
1
+ import { SessionStorage } from "./session-storage/index.js";
2
2
  export interface UserAttribute {
3
3
  Name: string;
4
4
  Value: string;
@@ -23,7 +23,7 @@ export interface OAuth2Props {
23
23
  /**
24
24
  * Response type.
25
25
  */
26
- responseType: 'code';
26
+ responseType: "code";
27
27
  }
28
28
  export interface CognitoClientProps {
29
29
  /**
@@ -85,15 +85,15 @@ export interface Session {
85
85
  * Represents the decoded values from a JWT ID token.
86
86
  */
87
87
  export interface IdToken extends Record<string, string | string[] | number | boolean> {
88
- 'cognito:username': string;
89
- 'cognito:groups': string[];
88
+ "cognito:username": string;
89
+ "cognito:groups": string[];
90
90
  email_verified: boolean;
91
91
  email: string;
92
92
  iss: string;
93
93
  origin_jti: string;
94
94
  aud: string;
95
95
  event_id: string;
96
- token_use: 'id';
96
+ token_use: "id";
97
97
  auth_time: number;
98
98
  exp: number;
99
99
  iat: number;
@@ -111,7 +111,7 @@ export interface AccessToken extends Record<string, string | string[] | number |
111
111
  origin_jti: string;
112
112
  scope: string;
113
113
  sub: string;
114
- token_use: 'access';
114
+ token_use: "access";
115
115
  username: string;
116
116
  }
117
117
  export interface DecodedTokens {
@@ -157,7 +157,7 @@ export interface AuthenticationResponse {
157
157
  AuthenticationResult: AuthenticationResult;
158
158
  }
159
159
  export interface ChallengeResponse {
160
- ChallengeName: 'PASSWORD_VERIFIER';
160
+ ChallengeName: "PASSWORD_VERIFIER";
161
161
  ChallengeParameters: {
162
162
  SALT: string;
163
163
  SECRET_BLOCK: string;
@@ -175,7 +175,7 @@ export declare class CognitoClient {
175
175
  private readonly userPoolClientId;
176
176
  private readonly sessionStorage;
177
177
  private readonly oAuth?;
178
- constructor({ userPoolId, userPoolClientId, endpoint, sessionStorage, oAuth2: oAuth }: CognitoClientProps);
178
+ constructor({ userPoolId, userPoolClientId, endpoint, sessionStorage, oAuth2: oAuth, }: CognitoClientProps);
179
179
  static getDecodedTokenFromSession(session: Session): DecodedTokens;
180
180
  private cognitoRequest;
181
181
  private static authResultToSession;
@@ -276,7 +276,7 @@ export declare class CognitoClient {
276
276
  *
277
277
  * @throws {Error}
278
278
  */
279
- generateOAuthSignInUrl(identityProvider?: CognitoIdentityProvider): string;
279
+ generateOAuthSignInUrl(identityProvider?: CognitoIdentityProvider): Promise<string>;
280
280
  /**
281
281
  *
282
282
  * Handles Cognito`s OAuth2 code flow after redirection from Cognito`s Hosted UI.
@@ -1,9 +1,8 @@
1
- import addSeconds from 'date-fns/addSeconds';
2
- import { sha256 } from 'hash.js';
3
- import { BigInteger } from 'jsbn';
4
- import randomBytes from 'randombytes';
5
- import { AuthError, AuthException, getAuthError } from './error.js';
6
- import { calculateSignature, calculateU, decodeJwt, generateA, generateSmallA, getPasswordAuthenticationKey, } from './utils.js';
1
+ import { addSeconds } from "date-fns";
2
+ import hashJs from "hash.js";
3
+ import { BigInteger } from "jsbn";
4
+ import { AuthError, AuthException, getAuthError, } from "./error.js";
5
+ import { calculateSignature, calculateU, decodeJwt, generateA, generateSmallA, getPasswordAuthenticationKey, randomBytes, } from "./utils.js";
7
6
  /**
8
7
  * List of used and supported Cognito API calls.
9
8
  * @see https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_Operations.html for more details
@@ -38,9 +37,9 @@ export var CognitoIdentityProvider;
38
37
  * Lightweight AWS Cogito client without any AWS SDK dependencies.
39
38
  */
40
39
  export class CognitoClient {
41
- constructor({ userPoolId, userPoolClientId, endpoint, sessionStorage, oAuth2: oAuth }) {
42
- const [cognitoPoolRegion, cognitoPoolName] = userPoolId.split('_');
43
- this.cognitoEndpoint = (endpoint || `https://cognito-idp.${cognitoPoolRegion}.amazonaws.com`).replace(/\/$/, '');
40
+ constructor({ userPoolId, userPoolClientId, endpoint, sessionStorage, oAuth2: oAuth, }) {
41
+ const [cognitoPoolRegion, cognitoPoolName] = userPoolId.split("_");
42
+ this.cognitoEndpoint = (endpoint || `https://cognito-idp.${cognitoPoolRegion}.amazonaws.com`).replace(/\/$/, "");
44
43
  this.cognitoPoolName = cognitoPoolName;
45
44
  this.userPoolClientId = userPoolClientId;
46
45
  this.sessionStorage = sessionStorage;
@@ -57,13 +56,14 @@ export class CognitoClient {
57
56
  async cognitoRequest(body, serviceTarget) {
58
57
  const respondToAuthChallenge = await fetch(this.cognitoEndpoint, {
59
58
  headers: {
60
- 'x-amz-target': `AWSCognitoIdentityProviderService.${serviceTarget}`,
61
- 'content-type': 'application/x-amz-json-1.1',
59
+ "x-amz-target": `AWSCognitoIdentityProviderService.${serviceTarget}`,
60
+ "content-type": "application/x-amz-json-1.1",
62
61
  },
63
- method: 'POST',
62
+ method: "POST",
64
63
  body: JSON.stringify(body),
65
64
  });
66
- if (respondToAuthChallenge.status < 200 || respondToAuthChallenge.status > 299) {
65
+ if (respondToAuthChallenge.status < 200 ||
66
+ respondToAuthChallenge.status > 299) {
67
67
  const errorMessage = (await respondToAuthChallenge.json());
68
68
  throw getAuthError(errorMessage);
69
69
  }
@@ -87,10 +87,10 @@ export class CognitoClient {
87
87
  * @throws {AuthException}
88
88
  */
89
89
  async authenticateUserSrp(username, password) {
90
- const smallA = generateSmallA();
90
+ const smallA = await generateSmallA();
91
91
  const A = generateA(smallA);
92
92
  const initiateAuthPayload = {
93
- AuthFlow: 'USER_SRP_AUTH',
93
+ AuthFlow: "USER_SRP_AUTH",
94
94
  ClientId: this.userPoolClientId,
95
95
  AuthParameters: {
96
96
  USERNAME: username,
@@ -105,7 +105,7 @@ export class CognitoClient {
105
105
  const hkdf = getPasswordAuthenticationKey(this.cognitoPoolName, challenge.ChallengeParameters.USER_ID_FOR_SRP, password, B, U, smallA, salt);
106
106
  const { signature, timeStamp } = calculateSignature(this.cognitoPoolName, challenge.ChallengeParameters.USER_ID_FOR_SRP, challenge.ChallengeParameters.SECRET_BLOCK, hkdf);
107
107
  const respondToAuthChallengePayload = {
108
- ChallengeName: 'PASSWORD_VERIFIER',
108
+ ChallengeName: "PASSWORD_VERIFIER",
109
109
  ClientId: this.userPoolClientId,
110
110
  ChallengeResponses: {
111
111
  PASSWORD_CLAIM_SECRET_BLOCK: challenge.ChallengeParameters.SECRET_BLOCK,
@@ -131,7 +131,7 @@ export class CognitoClient {
131
131
  */
132
132
  async authenticateUser(username, password) {
133
133
  const initiateAuthPayload = {
134
- AuthFlow: 'USER_PASSWORD_AUTH',
134
+ AuthFlow: "USER_PASSWORD_AUTH",
135
135
  ClientId: this.userPoolClientId,
136
136
  AuthParameters: {
137
137
  USERNAME: username,
@@ -146,7 +146,7 @@ export class CognitoClient {
146
146
  }
147
147
  async refreshSession(session) {
148
148
  const refreshTokenPayload = {
149
- AuthFlow: 'REFRESH_TOKEN_AUTH',
149
+ AuthFlow: "REFRESH_TOKEN_AUTH",
150
150
  ClientId: this.userPoolClientId,
151
151
  AuthParameters: {
152
152
  REFRESH_TOKEN: session.refreshToken,
@@ -224,7 +224,7 @@ export class CognitoClient {
224
224
  async changePassword(currentPassword, newPassword) {
225
225
  const session = await this.getSession();
226
226
  if (session === undefined) {
227
- throw new AuthException('User must be authenticated', AuthError.UserNotAuthenticated);
227
+ throw new AuthException("User must be authenticated", AuthError.UserNotAuthenticated);
228
228
  }
229
229
  const changePasswordPayload = {
230
230
  PreviousPassword: currentPassword,
@@ -236,7 +236,7 @@ export class CognitoClient {
236
236
  async updateUserAttributes(userAttributes) {
237
237
  const session = await this.getSession();
238
238
  if (session === undefined) {
239
- throw new AuthException('User must be authenticated', AuthError.UserNotAuthenticated);
239
+ throw new AuthException("User must be authenticated", AuthError.UserNotAuthenticated);
240
240
  }
241
241
  const updateUserAttributesPayload = {
242
242
  UserAttributes: userAttributes,
@@ -247,7 +247,7 @@ export class CognitoClient {
247
247
  async verifyUserAttribute(attributeName, code) {
248
248
  const session = await this.getSession();
249
249
  if (session === undefined) {
250
- throw new AuthException('User must be authenticated', AuthError.UserNotAuthenticated);
250
+ throw new AuthException("User must be authenticated", AuthError.UserNotAuthenticated);
251
251
  }
252
252
  const verifyUserAttributePayload = {
253
253
  AttributeName: attributeName,
@@ -264,7 +264,7 @@ export class CognitoClient {
264
264
  async signOut() {
265
265
  const session = await this.getSession();
266
266
  if (session === undefined) {
267
- throw new AuthException('User must be authenticated', AuthError.UserNotAuthenticated);
267
+ throw new AuthException("User must be authenticated", AuthError.UserNotAuthenticated);
268
268
  }
269
269
  const revokeTokenPayload = {
270
270
  Token: session.refreshToken,
@@ -324,26 +324,27 @@ export class CognitoClient {
324
324
  *
325
325
  * @throws {Error}
326
326
  */
327
- generateOAuthSignInUrl(identityProvider) {
327
+ async generateOAuthSignInUrl(identityProvider) {
328
328
  if (this.oAuth === undefined) {
329
- throw Error('You have to define oAuth options to use generateFederatedSignUrl');
329
+ throw Error("You have to define oAuth options to use generateFederatedSignUrl");
330
330
  }
331
- const state = randomBytes(32).toString('hex');
332
- const pkce = randomBytes(128).toString('hex');
333
- const code_challenge = Buffer.from(sha256().update(pkce).digest())
334
- .toString('base64')
335
- .replace(/\+/g, '-')
336
- .replace(/\//g, '_')
337
- .replace(/=+$/, '');
331
+ const state = (await randomBytes(32)).toString("hex");
332
+ const pkce = (await randomBytes(128)).toString("hex");
333
+ const code_challenge = Buffer.from(hashJs.sha256().update(pkce).digest())
334
+ .toString("base64")
335
+ .replace(/\+/g, "-")
336
+ .replace(/\//g, "_")
337
+ .replace(/=+$/, "");
338
338
  const queryParams = new URLSearchParams();
339
- queryParams.append('redirect_uri', this.oAuth.redirectUrl);
340
- queryParams.append('response_type', this.oAuth.responseType);
341
- queryParams.append('client_id', this.userPoolClientId);
342
- identityProvider && queryParams.append('identity_provider', identityProvider);
343
- queryParams.append('scope', this.oAuth.scopes.join(' '));
344
- queryParams.append('state', state);
345
- queryParams.append('code_challenge', code_challenge);
346
- queryParams.append('code_challenge_method', 'S256');
339
+ queryParams.append("redirect_uri", this.oAuth.redirectUrl);
340
+ queryParams.append("response_type", this.oAuth.responseType);
341
+ queryParams.append("client_id", this.userPoolClientId);
342
+ identityProvider &&
343
+ queryParams.append("identity_provider", identityProvider);
344
+ queryParams.append("scope", this.oAuth.scopes.join(" "));
345
+ queryParams.append("state", state);
346
+ queryParams.append("code_challenge", code_challenge);
347
+ queryParams.append("code_challenge_method", "S256");
347
348
  this.sessionStorage.setOauthVerificationParams({
348
349
  state,
349
350
  pkce,
@@ -363,36 +364,36 @@ export class CognitoClient {
363
364
  */
364
365
  async handleCodeFlow(returnUrl) {
365
366
  if (this.oAuth === undefined) {
366
- throw Error('You have to define oAuth options to use handleCodeFlow');
367
+ throw Error("You have to define oAuth options to use handleCodeFlow");
367
368
  }
368
369
  const url = new URL(returnUrl);
369
- const code = url.searchParams.get('code');
370
- const state = url.searchParams.get('state');
370
+ const code = url.searchParams.get("code");
371
+ const state = url.searchParams.get("state");
371
372
  if (code === null || state === null) {
372
- throw Error('code or state parameter is missing from return url.');
373
+ throw Error("code or state parameter is missing from return url.");
373
374
  }
374
375
  const oAuthVerificationParams = this.sessionStorage.getOauthVerificationParams();
375
376
  if (oAuthVerificationParams === undefined) {
376
- throw new Error('OAuth verification parameters are missing, did you forgot to call generateOAuthSignInUrl ?');
377
+ throw new Error("OAuth verification parameters are missing, did you forgot to call generateOAuthSignInUrl ?");
377
378
  }
378
379
  if (oAuthVerificationParams.state !== state) {
379
- throw new Error('state parameter does not match with previous value generated by previous call of generateOAuthSignInUrl .');
380
+ throw new Error("state parameter does not match with previous value generated by previous call of generateOAuthSignInUrl .");
380
381
  }
381
382
  const urlParams = new URLSearchParams();
382
- urlParams.append('grant_type', 'authorization_code');
383
- urlParams.append('code', code);
384
- urlParams.append('client_id', this.userPoolClientId);
385
- urlParams.append('redirect_uri', this.oAuth.redirectUrl);
386
- urlParams.append('code_verifier', oAuthVerificationParams.pkce);
383
+ urlParams.append("grant_type", "authorization_code");
384
+ urlParams.append("code", code);
385
+ urlParams.append("client_id", this.userPoolClientId);
386
+ urlParams.append("redirect_uri", this.oAuth.redirectUrl);
387
+ urlParams.append("code_verifier", oAuthVerificationParams.pkce);
387
388
  const tokenEndpoint = `${this.oAuth.cognitoDomain}/oauth2/token`;
388
389
  const response = await fetch(tokenEndpoint, {
389
- method: 'POST',
390
+ method: "POST",
390
391
  headers: {
391
- 'Content-Type': 'application/x-www-form-urlencoded',
392
+ "Content-Type": "application/x-www-form-urlencoded",
392
393
  },
393
394
  body: urlParams.toString(),
394
395
  });
395
- const { access_token, refresh_token, id_token, expires_in, token_type, error } = await response.json();
396
+ const { access_token, refresh_token, id_token, expires_in, token_type, error, } = await response.json();
396
397
  if (error) {
397
398
  throw new Error(error);
398
399
  }
@@ -76,9 +76,9 @@ describe("Cognito Client", () => {
76
76
  expect(cognitoClient.authenticateUser(user.email, user.password)).rejects.toThrow();
77
77
  await cognitoClient.authenticateUser(user.email, "newPassword");
78
78
  });
79
- test("generateOAuthSignInUrl", () => {
80
- const _test = (cb, identityProvider) => {
81
- const hostedUIUrl = cognitoClient.generateOAuthSignInUrl(identityProvider);
79
+ test("generateOAuthSignInUrl", async () => {
80
+ const _test = async (cb, identityProvider) => {
81
+ const hostedUIUrl = await cognitoClient.generateOAuthSignInUrl(identityProvider);
82
82
  const { searchParams } = new URL(hostedUIUrl);
83
83
  expect(searchParams.get("redirect_uri")).toBe(oAuth2.redirectUrl);
84
84
  expect(searchParams.get("response_type")).toBe(oAuth2.responseType);
@@ -89,10 +89,10 @@ describe("Cognito Client", () => {
89
89
  expect(searchParams.get("code_challenge_method")).toBe("S256");
90
90
  cb(searchParams);
91
91
  };
92
- _test((searchParams) => {
92
+ await _test((searchParams) => {
93
93
  expect(searchParams.get("identity_provider")).toBeNull();
94
94
  });
95
- _test((searchParams) => {
95
+ await _test((searchParams) => {
96
96
  expect(searchParams.get("identity_provider")).toBe(CognitoIdentityProvider.Apple);
97
97
  }, CognitoIdentityProvider.Apple);
98
98
  });
package/lib/utils.d.ts CHANGED
@@ -1,9 +1,9 @@
1
1
  /// <reference types="node" resolution-mode="require"/>
2
- import { BigInteger } from 'jsbn';
2
+ import { BigInteger } from "jsbn";
3
3
  export declare function padHex(bigInt: BigInteger): string;
4
4
  export declare function hashHexString(str: string): string;
5
5
  export declare function hashBuffer(buffer: Buffer): string;
6
- export declare function generateSmallA(): BigInteger;
6
+ export declare function generateSmallA(): Promise<BigInteger>;
7
7
  export declare function generateA(smallA: BigInteger): BigInteger;
8
8
  export declare function calculateU(A: BigInteger, B: BigInteger): BigInteger;
9
9
  export declare function calculateS(X: BigInteger, B: BigInteger, U: BigInteger, smallA: BigInteger): BigInteger;
@@ -18,3 +18,4 @@ export declare function decodeJwt<T = unknown>(jwt: string): {
18
18
  payload: T;
19
19
  signature: string;
20
20
  };
21
+ export declare function randomBytes(num: number): Promise<Buffer>;
package/lib/utils.js CHANGED
@@ -1,25 +1,24 @@
1
- import formatInTimeZone from 'date-fns-tz/formatInTimeZone';
2
- import { hmac, sha256 } from 'hash.js';
3
- import { BigInteger } from 'jsbn';
4
- import randomBytes from 'randombytes';
5
- const initN = 'FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1' +
6
- '29024E088A67CC74020BBEA63B139B22514A08798E3404DD' +
7
- 'EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245' +
8
- 'E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED' +
9
- 'EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D' +
10
- 'C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F' +
11
- '83655D23DCA3AD961C62F356208552BB9ED529077096966D' +
12
- '670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B' +
13
- 'E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9' +
14
- 'DE2BCBF6955817183995497CEA956AE515D2261898FA0510' +
15
- '15728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64' +
16
- 'ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7' +
17
- 'ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6B' +
18
- 'F12FFA06D98A0864D87602733EC86A64521F2B18177B200C' +
19
- 'BBE117577A615D6C770988C0BAD946E208E24FA074E5AB31' +
20
- '43DB5BFCE0FD108E4B82D120A93AD2CAFFFFFFFFFFFFFFFF';
1
+ import formatInTimeZone from "date-fns-tz/formatInTimeZone";
2
+ import hashJs from "hash.js";
3
+ import { BigInteger } from "jsbn";
4
+ const initN = "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" +
5
+ "29024E088A67CC74020BBEA63B139B22514A08798E3404DD" +
6
+ "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" +
7
+ "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" +
8
+ "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D" +
9
+ "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F" +
10
+ "83655D23DCA3AD961C62F356208552BB9ED529077096966D" +
11
+ "670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B" +
12
+ "E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9" +
13
+ "DE2BCBF6955817183995497CEA956AE515D2261898FA0510" +
14
+ "15728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64" +
15
+ "ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7" +
16
+ "ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6B" +
17
+ "F12FFA06D98A0864D87602733EC86A64521F2B18177B200C" +
18
+ "BBE117577A615D6C770988C0BAD946E208E24FA074E5AB31" +
19
+ "43DB5BFCE0FD108E4B82D120A93AD2CAFFFFFFFFFFFFFFFF";
21
20
  const N = new BigInteger(initN, 16);
22
- const g = new BigInteger('2', 16);
21
+ const g = new BigInteger("2", 16);
23
22
  const k = new BigInteger(hashHexString(`${padHex(N)}${padHex(g)}`), 16);
24
23
  export function padHex(bigInt) {
25
24
  const HEX_MSB_REGEX = /^[89a-f]/i;
@@ -29,29 +28,29 @@ export function padHex(bigInt) {
29
28
  hexStr = HEX_MSB_REGEX.test(hexStr) ? `00${hexStr}` : hexStr;
30
29
  if (isNegative) {
31
30
  const invertedNibbles = hexStr
32
- .split('')
31
+ .split("")
33
32
  .map((x) => {
34
33
  const invertedNibble = ~parseInt(x, 16) & 0xf;
35
- return '0123456789ABCDEF'.charAt(invertedNibble);
34
+ return "0123456789ABCDEF".charAt(invertedNibble);
36
35
  })
37
- .join('');
36
+ .join("");
38
37
  const flippedBitsBI = new BigInteger(invertedNibbles, 16).add(BigInteger.ONE);
39
38
  hexStr = flippedBitsBI.toString(16);
40
- if (hexStr.toUpperCase().startsWith('FF8')) {
39
+ if (hexStr.toUpperCase().startsWith("FF8")) {
41
40
  hexStr = hexStr.substring(2);
42
41
  }
43
42
  }
44
43
  return hexStr;
45
44
  }
46
45
  export function hashHexString(str) {
47
- return hashBuffer(Buffer.from(str, 'hex'));
46
+ return hashBuffer(Buffer.from(str, "hex"));
48
47
  }
49
48
  export function hashBuffer(buffer) {
50
- const hash = sha256().update(buffer).digest('hex');
51
- return new Array(64 - hash.length).join('0') + hash;
49
+ const hash = hashJs.sha256().update(buffer).digest("hex");
50
+ return new Array(64 - hash.length).join("0") + hash;
52
51
  }
53
- export function generateSmallA() {
54
- return new BigInteger(randomBytes(128).toString('hex'), 16);
52
+ export async function generateSmallA() {
53
+ return new BigInteger((await randomBytes(128)).toString("hex"), 16);
55
54
  }
56
55
  export function generateA(smallA) {
57
56
  const A = g.modPow(smallA, N);
@@ -67,45 +66,59 @@ export function calculateS(X, B, U, smallA) {
67
66
  }
68
67
  export function calculateHKDF(ikm, salt) {
69
68
  const infoBitsBuffer = Buffer.concat([
70
- Buffer.from('Caldera Derived Key', 'utf8'),
71
- Buffer.from(String.fromCharCode(1), 'utf8'),
69
+ Buffer.from("Caldera Derived Key", "utf8"),
70
+ Buffer.from(String.fromCharCode(1), "utf8"),
72
71
  ]);
73
- const prk = hmac(sha256, salt)
72
+ const prk = hashJs
73
+ .hmac(hashJs.sha256, salt)
74
74
  .update(ikm)
75
75
  .digest();
76
- const hmacResult = hmac(sha256, prk)
76
+ const hmacResult = hashJs
77
+ .hmac(hashJs.sha256, prk)
77
78
  .update(infoBitsBuffer)
78
79
  .digest();
79
80
  return hmacResult.slice(0, 16);
80
81
  }
81
82
  export function getPasswordAuthenticationKey(poolName, username, password, B, U, smallA, salt) {
82
83
  const usernamePassword = `${poolName}${username}:${password}`;
83
- const usernamePasswordHash = hashBuffer(Buffer.from(usernamePassword, 'utf-8'));
84
+ const usernamePasswordHash = hashBuffer(Buffer.from(usernamePassword, "utf-8"));
84
85
  const X = new BigInteger(hashHexString(padHex(salt) + usernamePasswordHash), 16);
85
86
  const S = calculateS(X, B, U, smallA);
86
- return calculateHKDF(Buffer.from(padHex(S), 'hex'), Buffer.from(padHex(U), 'hex'));
87
+ return calculateHKDF(Buffer.from(padHex(S), "hex"), Buffer.from(padHex(U), "hex"));
87
88
  }
88
89
  export function calculateSignature(poolName, userId, secretBlock, hkdf) {
89
- const timeStamp = formatInTimeZone(new Date(), 'UTC', "EEE MMM d HH:mm:ss 'UTC' yyyy");
90
+ const timeStamp = formatInTimeZone(new Date(), "UTC", "EEE MMM d HH:mm:ss 'UTC' yyyy");
90
91
  const concatBuffer = Buffer.concat([
91
- Buffer.from(poolName, 'utf8'),
92
- Buffer.from(userId, 'utf8'),
93
- Buffer.from(secretBlock, 'base64'),
94
- Buffer.from(timeStamp, 'utf8'),
92
+ Buffer.from(poolName, "utf8"),
93
+ Buffer.from(userId, "utf8"),
94
+ Buffer.from(secretBlock, "base64"),
95
+ Buffer.from(timeStamp, "utf8"),
95
96
  ]);
96
- const signature = Buffer.from(hmac(sha256, hkdf)
97
+ const signature = Buffer.from(hashJs
98
+ .hmac(hashJs.sha256, hkdf)
97
99
  .update(concatBuffer)
98
- .digest()).toString('base64');
100
+ .digest()).toString("base64");
99
101
  return {
100
102
  signature,
101
103
  timeStamp,
102
104
  };
103
105
  }
104
106
  export function decodeJwt(jwt) {
105
- const [header, payload, signature] = jwt.split('.');
107
+ const [header, payload, signature] = jwt.split(".");
106
108
  return {
107
- header: JSON.parse(Buffer.from(header, 'base64').toString('utf-8')),
108
- payload: JSON.parse(Buffer.from(payload, 'base64').toString('utf-8')),
109
+ header: JSON.parse(Buffer.from(header, "base64").toString("utf-8")),
110
+ payload: JSON.parse(Buffer.from(payload, "base64").toString("utf-8")),
109
111
  signature: signature,
110
112
  };
111
113
  }
114
+ export async function randomBytes(num) {
115
+ if (globalThis.window) {
116
+ const bytes = new Uint8Array(num);
117
+ window.crypto.getRandomValues(bytes);
118
+ return Buffer.from(bytes);
119
+ }
120
+ else {
121
+ const { randomBytes } = await import("node:crypto");
122
+ return randomBytes(num);
123
+ }
124
+ }
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "@vardario/cognito-client",
3
- "version": "0.1.5",
3
+ "version": "0.1.7",
4
4
  "description": "",
5
- "main": "dist/index.js",
5
+ "main": "lib/index.js",
6
6
  "type": "module",
7
7
  "files": [
8
8
  "/lib"
@@ -14,14 +14,12 @@
14
14
  "date-fns": "^2.29.3",
15
15
  "date-fns-tz": "^1.3.7",
16
16
  "jsbn": "^1.1.0",
17
- "randombytes": "^2.1.0",
18
17
  "hash.js": "^1.1.7"
19
18
  },
20
19
  "devDependencies": {
21
20
  "@aws-sdk/client-cognito-identity-provider": "^3.209.0",
22
21
  "@types/jsbn": "^1.2.30",
23
22
  "@types/jsdom": "^20.0.1",
24
- "@types/randombytes": "^2.0.0",
25
23
  "isomorphic-fetch": "^3.0.0",
26
24
  "jsdom": "^20.0.2",
27
25
  "testcontainers": "^9.0.0",