@vardario/cognito-client 5.2.1 → 5.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/browser.js CHANGED
@@ -644,6 +644,28 @@ function publicKeyCredentialToJSON(cred) {
644
644
  type: cred.type
645
645
  });
646
646
  }
647
+ function credentialCreateOptionsToPublicKey(credentialCreateOptions) {
648
+ credentialCreateOptions.challenge = base64UrlToUint8Array(credentialCreateOptions.challenge);
649
+ credentialCreateOptions.user.id = base64UrlToUint8Array(credentialCreateOptions.user.id);
650
+ credentialCreateOptions.excludeCredentials = (credentialCreateOptions.excludeCredentials || []).map(
651
+ (excludeCred) => ({
652
+ ...excludeCred,
653
+ id: base64UrlToUint8Array(excludeCred.id)
654
+ })
655
+ );
656
+ return credentialCreateOptions;
657
+ }
658
+ function createCredentialFromInitWebAuthResponse(reposne) {
659
+ const credentialRequestOptions = JSON.parse(reposne.ChallengeParameters.CREDENTIAL_REQUEST_OPTIONS);
660
+ credentialRequestOptions.challenge = base64UrlToUint8Array(credentialRequestOptions.challenge);
661
+ credentialRequestOptions.allowCredentials = (credentialRequestOptions.allowCredentials || []).map(
662
+ (allowCred) => ({
663
+ ...allowCred,
664
+ id: base64UrlToUint8Array(allowCred.id)
665
+ })
666
+ );
667
+ return credentialRequestOptions;
668
+ }
647
669
  var N = BigInt(
648
670
  "0xFFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF6955817183995497CEA956AE515D2261898FA051015728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6BF12FFA06D98A0864D87602733EC86A64521F2B18177B200CBBE117577A615D6C770988C0BAD946E208E24FA074E5AB3143DB5BFCE0FD108E4B82D120A93AD2CAFFFFFFFFFFFFFFFF"
649
671
  );
@@ -809,12 +831,6 @@ var IdentityProvider = {
809
831
  Facebook: "Facebook",
810
832
  Apple: "SignInWithApple"
811
833
  };
812
- function adaptExpiresIn(auth) {
813
- return {
814
- ...auth,
815
- ExpiresIn: (/* @__PURE__ */ new Date()).getTime() + auth.ExpiresIn * 1e3
816
- };
817
- }
818
834
  async function cognitoRequest(body, serviceTarget, cognitoEndpoint) {
819
835
  const cognitoResponse = await fetch(cognitoEndpoint, {
820
836
  headers: {
@@ -902,17 +918,18 @@ var CognitoClient = class {
902
918
  };
903
919
  }
904
920
  async initiateAuth(request) {
905
- const cognitoResponse = await cognitoRequest(
906
- {
907
- ...request,
908
- ClientId: this.userPoolClientId
909
- },
910
- "InitiateAuth" /* InitiateAuth */,
911
- this.cognitoEndpoint
912
- );
913
- if (cognitoResponse.AuthenticationResult) {
914
- cognitoResponse.AuthenticationResult = adaptExpiresIn(cognitoResponse.AuthenticationResult);
921
+ const _request = {
922
+ ...request,
923
+ ClientId: this.userPoolClientId
924
+ };
925
+ if (this.clientSecret && request.AuthParameters.USERNAME) {
926
+ _request.AuthParameters.SECRET_HASH = await calculateSecretHash(
927
+ this.clientSecret,
928
+ this.userPoolClientId,
929
+ request.AuthParameters.USERNAME
930
+ );
915
931
  }
932
+ const cognitoResponse = await cognitoRequest(_request, "InitiateAuth" /* InitiateAuth */, this.cognitoEndpoint);
916
933
  return cognitoResponse;
917
934
  }
918
935
  /**
@@ -932,8 +949,7 @@ var CognitoClient = class {
932
949
  AuthFlow: "USER_SRP_AUTH",
933
950
  AuthParameters: {
934
951
  USERNAME: username,
935
- SRP_A: A.toString(16),
936
- SECRET_HASH: this.clientSecret && await calculateSecretHash(this.clientSecret, this.userPoolClientId, username)
952
+ SRP_A: A.toString(16)
937
953
  },
938
954
  ClientMetadata: {}
939
955
  });
@@ -964,20 +980,10 @@ var CognitoClient = class {
964
980
  PASSWORD_CLAIM_SECRET_BLOCK: initUserSrpAuthResponse.ChallengeParameters.SECRET_BLOCK,
965
981
  PASSWORD_CLAIM_SIGNATURE: signature,
966
982
  USERNAME: initUserSrpAuthResponse.ChallengeParameters.USER_ID_FOR_SRP,
967
- TIMESTAMP: timeStamp,
968
- SECRET_HASH: this.clientSecret && await calculateSecretHash(
969
- this.clientSecret,
970
- this.userPoolClientId,
971
- initUserSrpAuthResponse.ChallengeParameters.USER_ID_FOR_SRP
972
- )
983
+ TIMESTAMP: timeStamp
973
984
  },
974
985
  ClientMetadata: {}
975
986
  });
976
- if (passwordAuthChallengeResponse.AuthenticationResult) {
977
- passwordAuthChallengeResponse.AuthenticationResult = adaptExpiresIn(
978
- passwordAuthChallengeResponse.AuthenticationResult
979
- );
980
- }
981
987
  return passwordAuthChallengeResponse;
982
988
  }
983
989
  /**
@@ -994,8 +1000,7 @@ var CognitoClient = class {
994
1000
  AuthFlow: "USER_PASSWORD_AUTH",
995
1001
  AuthParameters: {
996
1002
  USERNAME: username,
997
- PASSWORD: password,
998
- SECRET_HASH: this.clientSecret && await calculateSecretHash(this.clientSecret, this.userPoolClientId, username)
1003
+ PASSWORD: password
999
1004
  },
1000
1005
  ClientMetadata: {}
1001
1006
  };
@@ -1016,36 +1021,24 @@ var CognitoClient = class {
1016
1021
  PREFERRED_CHALLENGE: "WEB_AUTHN"
1017
1022
  }
1018
1023
  };
1019
- const authResponse = await this.initiateAuth(webAuthnPayload);
1020
- if (authResponse.ChallengeName !== "WEB_AUTHN") {
1024
+ const initWebAuthnReponse = await this.initiateAuth(webAuthnPayload);
1025
+ if (initWebAuthnReponse.ChallengeName !== "WEB_AUTHN") {
1021
1026
  throw new InitAuthError(
1022
- "Authentication failed, expected WEB_AUTHN challenge but received: " + authResponse.ChallengeName,
1027
+ "Authentication failed, expected WEB_AUTHN challenge but received: " + initWebAuthnReponse.ChallengeName,
1023
1028
  "InternalErrorException" /* InternalErrorException */
1024
1029
  );
1025
1030
  }
1026
- const credentialRequestOptions = JSON.parse(authResponse.ChallengeParameters.CREDENTIAL_REQUEST_OPTIONS);
1027
- credentialRequestOptions.challenge = base64UrlToUint8Array(credentialRequestOptions.challenge);
1028
- credentialRequestOptions.allowCredentials = (credentialRequestOptions.allowCredentials || []).map(
1029
- (allowCred) => ({
1030
- ...allowCred,
1031
- id: base64UrlToUint8Array(allowCred.id)
1032
- })
1033
- );
1034
1031
  const credentials = await navigator.credentials.get({
1035
- publicKey: credentialRequestOptions
1032
+ publicKey: createCredentialFromInitWebAuthResponse(initWebAuthnReponse)
1036
1033
  });
1037
1034
  const challengeResponse = await this.respondToAuthChallenge({
1038
1035
  ChallengeName: "WEB_AUTHN",
1039
1036
  ChallengeResponses: {
1040
1037
  USERNAME: username,
1041
- CREDENTIAL: JSON.stringify(publicKeyCredentialToJSON(credentials)),
1042
- SECRET_HASH: this.clientSecret && await calculateSecretHash(this.clientSecret, this.userPoolClientId, username)
1038
+ CREDENTIAL: JSON.stringify(publicKeyCredentialToJSON(credentials))
1043
1039
  },
1044
- Session: authResponse.Session
1040
+ Session: initWebAuthnReponse.Session
1045
1041
  });
1046
- if (challengeResponse.AuthenticationResult) {
1047
- challengeResponse.AuthenticationResult = adaptExpiresIn(challengeResponse.AuthenticationResult);
1048
- }
1049
1042
  return challengeResponse;
1050
1043
  }
1051
1044
  /**
@@ -1061,14 +1054,14 @@ var CognitoClient = class {
1061
1054
  AccessToken: accessToken
1062
1055
  });
1063
1056
  const credentials = await navigator.credentials.create({
1064
- publicKey: CredentialCreationOptions
1057
+ publicKey: credentialCreateOptionsToPublicKey(CredentialCreationOptions)
1065
1058
  });
1066
1059
  if (!(credentials instanceof PublicKeyCredential)) {
1067
1060
  throw new Error("Invalid credentials returned from WebAuthn API");
1068
1061
  }
1069
1062
  await this.completeWebAuthnRegistration({
1070
1063
  AccessToken: accessToken,
1071
- Credential: credentials
1064
+ Credential: publicKeyCredentialToJSON(credentials)
1072
1065
  });
1073
1066
  }
1074
1067
  /**
@@ -1202,6 +1195,13 @@ var CognitoClient = class {
1202
1195
  * @returns
1203
1196
  */
1204
1197
  async respondToAuthChallenge(params) {
1198
+ if (this.clientSecret) {
1199
+ params.ChallengeResponses.SECRET_HASH = await calculateSecretHash(
1200
+ this.clientSecret,
1201
+ this.userPoolClientId,
1202
+ params.ChallengeResponses.USERNAME
1203
+ );
1204
+ }
1205
1205
  return cognitoRequest(
1206
1206
  {
1207
1207
  ...params,
@@ -1330,30 +1330,19 @@ var CognitoClient = class {
1330
1330
  await cognitoRequest(resendConfirmationCodeRequest, "ResendConfirmationCode" /* ResendConfirmationCode */, this.cognitoEndpoint);
1331
1331
  }
1332
1332
  async startWebAuthnRegistration(request) {
1333
- const response = await cognitoRequest(request, "StartWebAuthnRegistration" /* StartWebAuthnRegistration */, this.cognitoEndpoint);
1334
- response.CredentialCreationOptions.challenge = base64UrlToUint8Array(
1335
- response.CredentialCreationOptions.challenge
1336
- );
1337
- response.CredentialCreationOptions.user.id = base64UrlToUint8Array(
1338
- response.CredentialCreationOptions.user.id
1339
- );
1340
- response.CredentialCreationOptions.excludeCredentials = (response.CredentialCreationOptions.excludeCredentials || []).map((excludeCred) => ({
1341
- ...excludeCred,
1342
- id: base64UrlToUint8Array(excludeCred.id)
1343
- }));
1344
- return response;
1333
+ return cognitoRequest(request, "StartWebAuthnRegistration" /* StartWebAuthnRegistration */, this.cognitoEndpoint);
1345
1334
  }
1346
1335
  /**
1347
1336
  * Completes registration of a passkey authenticator for the currently signed-in user.
1348
1337
  * @param request Request to complete WebAuthn registration.
1349
1338
  * @param request.AccessToken Access token of the current user.
1350
- * @param request.Credential The credential object returned by the WebAuthn API.
1339
+ * @param request.Credential The credential object returned by the WebAuthn API. You have to use publicKeyCredentialToJSON to convert the credential to a JSON object before sending it to Cognito.
1351
1340
  */
1352
1341
  async completeWebAuthnRegistration(request) {
1353
1342
  await cognitoRequest(
1354
1343
  {
1355
1344
  AccessToken: request.AccessToken,
1356
- Credential: publicKeyCredentialToJSON(request.Credential)
1345
+ Credential: request.Credential
1357
1346
  },
1358
1347
  "CompleteWebAuthnRegistration" /* CompleteWebAuthnRegistration */,
1359
1348
  this.cognitoEndpoint
@@ -1454,12 +1443,12 @@ var CognitoClient = class {
1454
1443
  if (error) {
1455
1444
  throw new Error(error);
1456
1445
  }
1457
- return adaptExpiresIn({
1446
+ return {
1458
1447
  AccessToken: access_token,
1459
1448
  RefreshToken: refresh_token,
1460
1449
  IdToken: id_token,
1461
1450
  ExpiresIn: expires_in
1462
- });
1451
+ };
1463
1452
  }
1464
1453
  /**
1465
1454
  * Invalidates the identity, access, and refresh tokens that Amazon Cognito issued to a user. Call this operation when your user signs out of your app. This results in the following behavior.
@@ -1522,7 +1511,6 @@ export {
1522
1511
  VerifySoftwareTokenException,
1523
1512
  VerifyUserAttributeError,
1524
1513
  VerifyUserAttributeException,
1525
- adaptExpiresIn,
1526
1514
  base64UrlToUint8Array,
1527
1515
  calculateHKDF,
1528
1516
  calculateS,
@@ -1530,6 +1518,8 @@ export {
1530
1518
  calculateSignature,
1531
1519
  calculateU,
1532
1520
  cognitoRequest,
1521
+ createCredentialFromInitWebAuthResponse,
1522
+ credentialCreateOptionsToPublicKey,
1533
1523
  decodeJwt,
1534
1524
  digest,
1535
1525
  formatTimestamp,
@@ -140,8 +140,16 @@ export interface _RespondToAuthChallengeWebAuthnRequest extends RespondToAuthCha
140
140
  SECRET_HASH?: string;
141
141
  };
142
142
  }
143
- type _RespondToAuthChallengeRequest = _RespondToAuthChallengePasswordVerifierRequest | _RespondToAuthChallengeSmsMfaRequest | _RespondToAuthChallengeCustomChallengeNameRequest | _RespondToAuthChallengeNewPasswordRequiredRequest | _RespondToAuthChallengeSoftwareTokenMfaRequest | _RespondToAuthChallengeDeviceSrpAuthRequest | _RespondToAuthChallengeDevicePasswordVerifierRequest | _RespondToAuthChallengeMfaSetupRequest | _RespondToAuthChallengeSelectMfaTypeRequest | _RespondToAuthChallengeWebAuthnRequest;
144
- export type RespondToAuthChallengeRequest = Omit<_RespondToAuthChallengePasswordVerifierRequest, 'ClientId'> | Omit<_RespondToAuthChallengeSmsMfaRequest, 'ClientId'> | Omit<_RespondToAuthChallengeCustomChallengeNameRequest, 'ClientId'> | Omit<_RespondToAuthChallengeNewPasswordRequiredRequest, 'ClientId'> | Omit<_RespondToAuthChallengeSoftwareTokenMfaRequest, 'ClientId'> | Omit<_RespondToAuthChallengeDeviceSrpAuthRequest, 'ClientId'> | Omit<_RespondToAuthChallengeDevicePasswordVerifierRequest, 'ClientId'> | Omit<_RespondToAuthChallengeMfaSetupRequest, 'ClientId'> | Omit<_RespondToAuthChallengeSelectMfaTypeRequest, 'ClientId'> | Omit<_RespondToAuthChallengeWebAuthnRequest, 'ClientId'>;
143
+ export interface _RespondToAuthChallengeEmailOtpRequest extends RespondToAuthChallengeBaseRequest {
144
+ ChallengeName: 'EMAIL_OTP';
145
+ ChallengeResponses: {
146
+ SECRET_HASH?: string;
147
+ EMAIL_OTP_CODE: string;
148
+ USERNAME: string;
149
+ };
150
+ }
151
+ type _RespondToAuthChallengeRequest = _RespondToAuthChallengePasswordVerifierRequest | _RespondToAuthChallengeSmsMfaRequest | _RespondToAuthChallengeCustomChallengeNameRequest | _RespondToAuthChallengeNewPasswordRequiredRequest | _RespondToAuthChallengeSoftwareTokenMfaRequest | _RespondToAuthChallengeDeviceSrpAuthRequest | _RespondToAuthChallengeDevicePasswordVerifierRequest | _RespondToAuthChallengeMfaSetupRequest | _RespondToAuthChallengeSelectMfaTypeRequest | _RespondToAuthChallengeWebAuthnRequest | _RespondToAuthChallengeEmailOtpRequest;
152
+ export type RespondToAuthChallengeRequest = Omit<_RespondToAuthChallengePasswordVerifierRequest, 'ClientId'> | Omit<_RespondToAuthChallengeSmsMfaRequest, 'ClientId'> | Omit<_RespondToAuthChallengeCustomChallengeNameRequest, 'ClientId'> | Omit<_RespondToAuthChallengeNewPasswordRequiredRequest, 'ClientId'> | Omit<_RespondToAuthChallengeSoftwareTokenMfaRequest, 'ClientId'> | Omit<_RespondToAuthChallengeDeviceSrpAuthRequest, 'ClientId'> | Omit<_RespondToAuthChallengeDevicePasswordVerifierRequest, 'ClientId'> | Omit<_RespondToAuthChallengeMfaSetupRequest, 'ClientId'> | Omit<_RespondToAuthChallengeSelectMfaTypeRequest, 'ClientId'> | Omit<_RespondToAuthChallengeWebAuthnRequest, 'ClientId'> | Omit<_RespondToAuthChallengeEmailOtpRequest, 'ClientId'>;
145
153
  export interface UserAttribute {
146
154
  Name: string;
147
155
  Value: string;
@@ -404,6 +412,15 @@ export interface InitAuthMfaSetupChallengeResponse extends InitiateAuthBaseRespo
404
412
  ChallengeParameters: never;
405
413
  MFAS_CAN_SETUP: ('SMS_MFA' | 'SOFTWARE_TOKEN_MFA')[];
406
414
  }
415
+ export interface InitAuthEmailOtpChallengeResponse extends InitiateAuthBaseResponse {
416
+ AuthenticationResult?: never;
417
+ ChallengeName: 'EMAIL_OTP';
418
+ ChallengeParameters: {
419
+ CODE_DELIVERY_DELIVERY_MEDIUM: string;
420
+ CODE_DELIVERY_DESTINATION: string;
421
+ };
422
+ Session: string;
423
+ }
407
424
  export interface MfaOption {
408
425
  DeliveryMedium: 'SMS' | 'EMAIL';
409
426
  AttributeName: string;
@@ -438,7 +455,7 @@ export interface StartWebAuthnRegistrationResponse {
438
455
  }
439
456
  export interface CompleteWebAuthnRegistrationRequest {
440
457
  AccessToken: string;
441
- Credential: PublicKeyCredential;
458
+ Credential: any;
442
459
  }
443
460
  export interface DeleteWebAuthnCredentialRequest {
444
461
  AccessToken: string;
@@ -451,7 +468,7 @@ export interface ListWebAuthnCredentialsRequest {
451
468
  }
452
469
  export interface WebAuthnCredential {
453
470
  AuthenticatorTransports: string[];
454
- CreatedAt: string;
471
+ CreatedAt: number;
455
472
  CredentialId: string;
456
473
  FriendlyCredentialName: string;
457
474
  RelyingPartyId: string;
@@ -461,7 +478,7 @@ export interface ListWebAuthnCredentialsResponse {
461
478
  Credentials: WebAuthnCredential[];
462
479
  NextToken?: string;
463
480
  }
464
- export type InitiateAuthChallengeResponse = InitiateAuthPasswordVerifierChallengeResponse | InitiateAuthSoftwareTokenMfaChallengeResponse | InitiateAuthWebAuthResponse | InitiateEmailOtpChallengeResponse | InitAuthSelectChallengeResponse | InitAuthPasswordChallengeResponse | InitAuthPasswordSRPChallengeResponse | InitAuthMfaSetupChallengeResponse;
481
+ export type InitiateAuthChallengeResponse = InitiateAuthPasswordVerifierChallengeResponse | InitiateAuthSoftwareTokenMfaChallengeResponse | InitiateAuthWebAuthResponse | InitiateEmailOtpChallengeResponse | InitAuthSelectChallengeResponse | InitAuthPasswordChallengeResponse | InitAuthPasswordSRPChallengeResponse | InitAuthMfaSetupChallengeResponse | InitAuthEmailOtpChallengeResponse;
465
482
  export type InitiateAuthResponse = InitiateAuthAuthenticationResponse | InitiateAuthPasswordVerifierChallengeResponse | InitiateAuthChallengeResponse;
466
483
  type CognitoResponseMap = {
467
484
  [ServiceTarget.InitiateAuth]: InitiateAuthResponse;
@@ -531,13 +548,6 @@ type CognitoRequestMap = {
531
548
  [ServiceTarget.DeleteWebAuthnCredential]: DeleteWebAuthnCredentialRequest;
532
549
  [ServiceTarget.ListWebAuthnCredentials]: ListWebAuthnCredentialsRequest;
533
550
  };
534
- export declare function adaptExpiresIn(auth: AuthenticationResult): {
535
- ExpiresIn: number;
536
- AccessToken: string;
537
- IdToken: string;
538
- RefreshToken: string;
539
- NewDeviceMetadata?: NewDeviceMetadata | undefined;
540
- };
541
551
  export declare function cognitoRequest<T extends ServiceTarget>(body: CognitoRequestMap[T], serviceTarget: T, cognitoEndpoint: string): Promise<CognitoResponseMap[T]>;
542
552
  /**
543
553
  * Lightweight AWS Cogito client without any AWS SDK dependencies.
@@ -738,7 +748,7 @@ export declare class CognitoClient {
738
748
  * Completes registration of a passkey authenticator for the currently signed-in user.
739
749
  * @param request Request to complete WebAuthn registration.
740
750
  * @param request.AccessToken Access token of the current user.
741
- * @param request.Credential The credential object returned by the WebAuthn API.
751
+ * @param request.Credential The credential object returned by the WebAuthn API. You have to use publicKeyCredentialToJSON to convert the credential to a JSON object before sending it to Cognito.
742
752
  */
743
753
  completeWebAuthnRegistration(request: CompleteWebAuthnRegistrationRequest): Promise<void>;
744
754
  /**
@@ -1,5 +1,5 @@
1
1
  import { ChangePasswordError, ConfirmForgotPasswordError, ConfirmSignUpError, ForgotPasswordError, GlobalSignOutError, InitAuthError, ResendConfirmationCodeError, RespondToAuthChallengeError, RevokeTokenError, SignUpError, UpdateUserAttributesError, VerifyUserAttributeError, InitiateAuthException, COMMON_EXCEPTIONS, CommonError, VerifySoftwareTokenError, AssociateSoftwareTokenError, SetUserMFAPreferenceError, ListDevicesError, GetUserError } from './error.js';
2
- import { base64UrlToUint8Array, calculateSecretHash, calculateSignature, calculateU, decodeJwt, digest, generateA, generateSmallA, getPasswordAuthenticationKey, publicKeyCredentialToJSON, randomBytes, uint8ArrayFromString, uint8ArrayToBase64String } from './utils.js';
2
+ import { calculateSecretHash, calculateSignature, calculateU, createCredentialFromInitWebAuthResponse, credentialCreateOptionsToPublicKey, decodeJwt, digest, generateA, generateSmallA, getPasswordAuthenticationKey, publicKeyCredentialToJSON, randomBytes, uint8ArrayFromString, uint8ArrayToBase64String } from './utils.js';
3
3
  /**
4
4
  * List of used and supported Cognito API calls.
5
5
  * @see https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_Operations.html for more details
@@ -37,13 +37,6 @@ export const IdentityProvider = {
37
37
  Facebook: 'Facebook',
38
38
  Apple: 'SignInWithApple'
39
39
  };
40
- export function adaptExpiresIn(auth) {
41
- // Cognito returns expiresIn in seconds, but we want it in milliseconds from now
42
- return {
43
- ...auth,
44
- ExpiresIn: new Date().getTime() + auth.ExpiresIn * 1000
45
- };
46
- }
47
40
  export async function cognitoRequest(body, serviceTarget, cognitoEndpoint) {
48
41
  const cognitoResponse = await fetch(cognitoEndpoint, {
49
42
  headers: {
@@ -142,13 +135,14 @@ export class CognitoClient {
142
135
  };
143
136
  }
144
137
  async initiateAuth(request) {
145
- const cognitoResponse = await cognitoRequest({
138
+ const _request = {
146
139
  ...request,
147
140
  ClientId: this.userPoolClientId
148
- }, ServiceTarget.InitiateAuth, this.cognitoEndpoint);
149
- if (cognitoResponse.AuthenticationResult) {
150
- cognitoResponse.AuthenticationResult = adaptExpiresIn(cognitoResponse.AuthenticationResult);
141
+ };
142
+ if (this.clientSecret && request.AuthParameters.USERNAME) {
143
+ _request.AuthParameters.SECRET_HASH = await calculateSecretHash(this.clientSecret, this.userPoolClientId, request.AuthParameters.USERNAME);
151
144
  }
145
+ const cognitoResponse = await cognitoRequest(_request, ServiceTarget.InitiateAuth, this.cognitoEndpoint);
152
146
  return cognitoResponse;
153
147
  }
154
148
  /**
@@ -168,8 +162,7 @@ export class CognitoClient {
168
162
  AuthFlow: 'USER_SRP_AUTH',
169
163
  AuthParameters: {
170
164
  USERNAME: username,
171
- SRP_A: A.toString(16),
172
- SECRET_HASH: this.clientSecret && (await calculateSecretHash(this.clientSecret, this.userPoolClientId, username))
165
+ SRP_A: A.toString(16)
173
166
  },
174
167
  ClientMetadata: {}
175
168
  });
@@ -187,15 +180,10 @@ export class CognitoClient {
187
180
  PASSWORD_CLAIM_SECRET_BLOCK: initUserSrpAuthResponse.ChallengeParameters.SECRET_BLOCK,
188
181
  PASSWORD_CLAIM_SIGNATURE: signature,
189
182
  USERNAME: initUserSrpAuthResponse.ChallengeParameters.USER_ID_FOR_SRP,
190
- TIMESTAMP: timeStamp,
191
- SECRET_HASH: this.clientSecret &&
192
- (await calculateSecretHash(this.clientSecret, this.userPoolClientId, initUserSrpAuthResponse.ChallengeParameters.USER_ID_FOR_SRP))
183
+ TIMESTAMP: timeStamp
193
184
  },
194
185
  ClientMetadata: {}
195
186
  });
196
- if (passwordAuthChallengeResponse.AuthenticationResult) {
197
- passwordAuthChallengeResponse.AuthenticationResult = adaptExpiresIn(passwordAuthChallengeResponse.AuthenticationResult);
198
- }
199
187
  return passwordAuthChallengeResponse;
200
188
  }
201
189
  /**
@@ -212,8 +200,7 @@ export class CognitoClient {
212
200
  AuthFlow: 'USER_PASSWORD_AUTH',
213
201
  AuthParameters: {
214
202
  USERNAME: username,
215
- PASSWORD: password,
216
- SECRET_HASH: this.clientSecret && (await calculateSecretHash(this.clientSecret, this.userPoolClientId, username))
203
+ PASSWORD: password
217
204
  },
218
205
  ClientMetadata: {}
219
206
  };
@@ -234,31 +221,21 @@ export class CognitoClient {
234
221
  PREFERRED_CHALLENGE: 'WEB_AUTHN'
235
222
  }
236
223
  };
237
- const authResponse = await this.initiateAuth(webAuthnPayload);
238
- if (authResponse.ChallengeName !== 'WEB_AUTHN') {
239
- throw new InitAuthError('Authentication failed, expected WEB_AUTHN challenge but received: ' + authResponse.ChallengeName, InitiateAuthException.InternalErrorException);
224
+ const initWebAuthnReponse = await this.initiateAuth(webAuthnPayload);
225
+ if (initWebAuthnReponse.ChallengeName !== 'WEB_AUTHN') {
226
+ throw new InitAuthError('Authentication failed, expected WEB_AUTHN challenge but received: ' + initWebAuthnReponse.ChallengeName, InitiateAuthException.InternalErrorException);
240
227
  }
241
- const credentialRequestOptions = JSON.parse(authResponse.ChallengeParameters.CREDENTIAL_REQUEST_OPTIONS);
242
- credentialRequestOptions.challenge = base64UrlToUint8Array(credentialRequestOptions.challenge);
243
- credentialRequestOptions.allowCredentials = (credentialRequestOptions.allowCredentials || []).map((allowCred) => ({
244
- ...allowCred,
245
- id: base64UrlToUint8Array(allowCred.id)
246
- }));
247
228
  const credentials = await navigator.credentials.get({
248
- publicKey: credentialRequestOptions
229
+ publicKey: createCredentialFromInitWebAuthResponse(initWebAuthnReponse)
249
230
  });
250
231
  const challengeResponse = await this.respondToAuthChallenge({
251
232
  ChallengeName: 'WEB_AUTHN',
252
233
  ChallengeResponses: {
253
234
  USERNAME: username,
254
- CREDENTIAL: JSON.stringify(publicKeyCredentialToJSON(credentials)),
255
- SECRET_HASH: this.clientSecret && (await calculateSecretHash(this.clientSecret, this.userPoolClientId, username))
235
+ CREDENTIAL: JSON.stringify(publicKeyCredentialToJSON(credentials))
256
236
  },
257
- Session: authResponse.Session
237
+ Session: initWebAuthnReponse.Session
258
238
  });
259
- if (challengeResponse.AuthenticationResult) {
260
- challengeResponse.AuthenticationResult = adaptExpiresIn(challengeResponse.AuthenticationResult);
261
- }
262
239
  return challengeResponse;
263
240
  }
264
241
  /**
@@ -274,14 +251,14 @@ export class CognitoClient {
274
251
  AccessToken: accessToken
275
252
  });
276
253
  const credentials = await navigator.credentials.create({
277
- publicKey: CredentialCreationOptions
254
+ publicKey: credentialCreateOptionsToPublicKey(CredentialCreationOptions)
278
255
  });
279
256
  if (!(credentials instanceof PublicKeyCredential)) {
280
257
  throw new Error('Invalid credentials returned from WebAuthn API');
281
258
  }
282
259
  await this.completeWebAuthnRegistration({
283
260
  AccessToken: accessToken,
284
- Credential: credentials
261
+ Credential: publicKeyCredentialToJSON(credentials)
285
262
  });
286
263
  }
287
264
  /**
@@ -414,6 +391,9 @@ export class CognitoClient {
414
391
  * @returns
415
392
  */
416
393
  async respondToAuthChallenge(params) {
394
+ if (this.clientSecret) {
395
+ params.ChallengeResponses.SECRET_HASH = await calculateSecretHash(this.clientSecret, this.userPoolClientId, params.ChallengeResponses.USERNAME);
396
+ }
417
397
  return cognitoRequest({
418
398
  ...params,
419
399
  ClientId: this.userPoolClientId
@@ -538,25 +518,18 @@ export class CognitoClient {
538
518
  await cognitoRequest(resendConfirmationCodeRequest, ServiceTarget.ResendConfirmationCode, this.cognitoEndpoint);
539
519
  }
540
520
  async startWebAuthnRegistration(request) {
541
- const response = await cognitoRequest(request, ServiceTarget.StartWebAuthnRegistration, this.cognitoEndpoint);
542
- response.CredentialCreationOptions.challenge = base64UrlToUint8Array(response.CredentialCreationOptions.challenge);
543
- response.CredentialCreationOptions.user.id = base64UrlToUint8Array(response.CredentialCreationOptions.user.id);
544
- response.CredentialCreationOptions.excludeCredentials = (response.CredentialCreationOptions.excludeCredentials || []).map((excludeCred) => ({
545
- ...excludeCred,
546
- id: base64UrlToUint8Array(excludeCred.id)
547
- }));
548
- return response;
521
+ return cognitoRequest(request, ServiceTarget.StartWebAuthnRegistration, this.cognitoEndpoint);
549
522
  }
550
523
  /**
551
524
  * Completes registration of a passkey authenticator for the currently signed-in user.
552
525
  * @param request Request to complete WebAuthn registration.
553
526
  * @param request.AccessToken Access token of the current user.
554
- * @param request.Credential The credential object returned by the WebAuthn API.
527
+ * @param request.Credential The credential object returned by the WebAuthn API. You have to use publicKeyCredentialToJSON to convert the credential to a JSON object before sending it to Cognito.
555
528
  */
556
529
  async completeWebAuthnRegistration(request) {
557
530
  await cognitoRequest({
558
531
  AccessToken: request.AccessToken,
559
- Credential: publicKeyCredentialToJSON(request.Credential)
532
+ Credential: request.Credential
560
533
  }, ServiceTarget.CompleteWebAuthnRegistration, this.cognitoEndpoint);
561
534
  }
562
535
  /**
@@ -657,12 +630,12 @@ export class CognitoClient {
657
630
  if (error) {
658
631
  throw new Error(error);
659
632
  }
660
- return adaptExpiresIn({
633
+ return {
661
634
  AccessToken: access_token,
662
635
  RefreshToken: refresh_token,
663
636
  IdToken: id_token,
664
637
  ExpiresIn: expires_in
665
- });
638
+ };
666
639
  }
667
640
  /**
668
641
  * Invalidates the identity, access, and refresh tokens that Amazon Cognito issued to a user. Call this operation when your user signs out of your app. This results in the following behavior.
package/lib/utils.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  /// <reference types="node" resolution-mode="require"/>
2
2
  /// <reference types="node" resolution-mode="require"/>
3
+ import { InitiateAuthWebAuthResponse } from './cognito-client.js';
3
4
  export declare function uint8ArrayFromHexString(hexString: string): Uint8Array;
4
5
  export declare function uint8ArrayFromString(str: string): Uint8Array;
5
6
  export declare function uint8ArrayFromBase64String(str: string): Uint8Array;
@@ -8,6 +9,8 @@ export declare function uint8ArrayToBase64String(bytes: Uint8Array | ArrayBuffer
8
9
  export declare function uint8ArrayToBase64UrlString(bytes: Uint8Array | ArrayBuffer | undefined): string | undefined;
9
10
  export declare function base64UrlToUint8Array(base64: string): Uint8Array;
10
11
  export declare function publicKeyCredentialToJSON(cred: any): any;
12
+ export declare function credentialCreateOptionsToPublicKey(credentialCreateOptions: any): PublicKeyCredentialCreationOptions;
13
+ export declare function createCredentialFromInitWebAuthResponse(reposne: InitiateAuthWebAuthResponse): PublicKeyCredentialCreationOptions;
11
14
  export declare function padHex(bigInt: bigint): string;
12
15
  export declare function hashHexString(str: string): Promise<string>;
13
16
  export declare function hashBuffer(buffer: Uint8Array): Promise<string>;
package/lib/utils.js CHANGED
@@ -63,6 +63,24 @@ export function publicKeyCredentialToJSON(cred) {
63
63
  type: cred.type
64
64
  });
65
65
  }
66
+ export function credentialCreateOptionsToPublicKey(credentialCreateOptions) {
67
+ credentialCreateOptions.challenge = base64UrlToUint8Array(credentialCreateOptions.challenge);
68
+ credentialCreateOptions.user.id = base64UrlToUint8Array(credentialCreateOptions.user.id);
69
+ credentialCreateOptions.excludeCredentials = (credentialCreateOptions.excludeCredentials || []).map((excludeCred) => ({
70
+ ...excludeCred,
71
+ id: base64UrlToUint8Array(excludeCred.id)
72
+ }));
73
+ return credentialCreateOptions;
74
+ }
75
+ export function createCredentialFromInitWebAuthResponse(reposne) {
76
+ const credentialRequestOptions = JSON.parse(reposne.ChallengeParameters.CREDENTIAL_REQUEST_OPTIONS);
77
+ credentialRequestOptions.challenge = base64UrlToUint8Array(credentialRequestOptions.challenge);
78
+ credentialRequestOptions.allowCredentials = (credentialRequestOptions.allowCredentials || []).map((allowCred) => ({
79
+ ...allowCred,
80
+ id: base64UrlToUint8Array(allowCred.id)
81
+ }));
82
+ return credentialRequestOptions;
83
+ }
66
84
  const N = BigInt('0xFFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1' +
67
85
  '29024E088A67CC74020BBEA63B139B22514A08798E3404DD' +
68
86
  'EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245' +
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vardario/cognito-client",
3
- "version": "5.2.1",
3
+ "version": "5.3.1",
4
4
  "description": "",
5
5
  "license": "MIT",
6
6
  "author": "Sahin Vardar",
@@ -40,7 +40,7 @@
40
40
  "lint-staged": "^16.1.4",
41
41
  "prettier": "^3.1.0",
42
42
  "prettier-package-json": "^2.8.0",
43
- "semantic-release": "^24.2.7",
43
+ "semantic-release": "^25.0.3",
44
44
  "testcontainers": "^11.5.1",
45
45
  "tsx": "^4.7.1",
46
46
  "typescript": "^5.2.2",
@@ -54,7 +54,7 @@
54
54
  ],
55
55
  "package.json": "prettier-package-json --write"
56
56
  },
57
- "packageManager": "pnpm@8.10.5",
57
+ "packageManager": "pnpm@9.1.0",
58
58
  "release": {
59
59
  "branches": [
60
60
  "release"