@vardario/cognito-client 0.1.6 → 0.1.8

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