@vardario/cognito-client 5.1.0 → 5.2.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
@@ -603,8 +603,47 @@ function uint8ArrayToHexString(bytes) {
603
603
  return bytes.reduce((str, byte) => str + byte.toString(16).padStart(2, "0"), "");
604
604
  }
605
605
  function uint8ArrayToBase64String(bytes) {
606
+ if (bytes instanceof ArrayBuffer) {
607
+ const byteArray = new Uint8Array(bytes);
608
+ return btoa(String.fromCharCode(...byteArray));
609
+ }
606
610
  return btoa(String.fromCharCode(...bytes));
607
611
  }
612
+ function uint8ArrayToBase64UrlString(bytes) {
613
+ if (bytes === void 0) {
614
+ return void 0;
615
+ }
616
+ const base64String = uint8ArrayToBase64String(bytes);
617
+ return base64String.replaceAll("+", "-").replaceAll("/", "_").replace(/=+$/, "");
618
+ }
619
+ function base64UrlToUint8Array(base64) {
620
+ const binary = atob(base64.replace(/-/g, "+").replace(/_/g, "/"));
621
+ const len = binary.length;
622
+ const bytes = new Uint8Array(len);
623
+ for (let i = 0; i < len; i++) {
624
+ bytes[i] = binary.charCodeAt(i);
625
+ }
626
+ return bytes;
627
+ }
628
+ function publicKeyCredentialToJSON(cred) {
629
+ return removeUndefined({
630
+ authenticatorAttachment: cred.authenticatorAttachment,
631
+ clientExtensionResults: cred.getClientExtensionResults(),
632
+ id: cred.id,
633
+ rawId: uint8ArrayToBase64UrlString(cred.rawId),
634
+ response: {
635
+ attestationObject: uint8ArrayToBase64UrlString(cred.response.attestationObject),
636
+ authenticatorData: cred.response.authenticatorData ? uint8ArrayToBase64UrlString(cred.response.authenticatorData) : void 0,
637
+ clientDataJSON: uint8ArrayToBase64UrlString(cred.response.clientDataJSON),
638
+ publicKey: cred.response.getPublicKey ? uint8ArrayToBase64UrlString(cred.response.getPublicKey()) : void 0,
639
+ publicKeyAlgorithm: cred.response.getPublicKeyAlgorithm ? cred.response.getPublicKeyAlgorithm() : void 0,
640
+ transports: cred.response.getTransports ? cred.response.getTransports() : void 0,
641
+ signature: cred.response.signature ? uint8ArrayToBase64UrlString(cred.response.signature) : void 0,
642
+ userHandle: cred.response.userHandle ? uint8ArrayToBase64UrlString(cred.response.userHandle) : void 0
643
+ },
644
+ type: cred.type
645
+ });
646
+ }
608
647
  var N = BigInt(
609
648
  "0xFFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF6955817183995497CEA956AE515D2261898FA051015728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6BF12FFA06D98A0864D87602733EC86A64521F2B18177B200CBBE117577A615D6C770988C0BAD946E208E24FA074E5AB3143DB5BFCE0FD108E4B82D120A93AD2CAFFFFFFFFFFFFFFFF"
610
649
  );
@@ -720,6 +759,24 @@ async function hmac(algorithm, key, data) {
720
759
  const signature = await crypto.subtle.sign("HMAC", cryptoKey, data);
721
760
  return new Uint8Array(signature);
722
761
  }
762
+ function removeUndefined(obj) {
763
+ if (Array.isArray(obj)) {
764
+ return obj.map((item) => removeUndefined(item)).filter((item) => item !== void 0);
765
+ }
766
+ if (obj !== null && typeof obj === "object") {
767
+ return Object.entries(obj).reduce(
768
+ (acc, [key, value]) => {
769
+ const cleaned = removeUndefined(value);
770
+ if (cleaned !== void 0) {
771
+ acc[key] = cleaned;
772
+ }
773
+ return acc;
774
+ },
775
+ {}
776
+ );
777
+ }
778
+ return obj !== void 0 ? obj : void 0;
779
+ }
723
780
 
724
781
  // src/cognito-client.ts
725
782
  var ServiceTarget = /* @__PURE__ */ ((ServiceTarget2) => {
@@ -740,16 +797,18 @@ var ServiceTarget = /* @__PURE__ */ ((ServiceTarget2) => {
740
797
  ServiceTarget2["VerifySoftwareToken"] = "VerifySoftwareToken";
741
798
  ServiceTarget2["ListDevices"] = "ListDevices";
742
799
  ServiceTarget2["SetUserMFAPreference"] = "SetUserMFAPreference";
800
+ ServiceTarget2["StartWebAuthnRegistration"] = "StartWebAuthnRegistration";
801
+ ServiceTarget2["CompleteWebAuthnRegistration"] = "CompleteWebAuthnRegistration";
802
+ ServiceTarget2["DeleteWebAuthnCredential"] = "DeleteWebAuthnCredential";
803
+ ServiceTarget2["ListWebAuthnCredentials"] = "ListWebAuthnCredentials";
743
804
  return ServiceTarget2;
744
805
  })(ServiceTarget || {});
745
- var IdentityProvider = /* @__PURE__ */ ((IdentityProvider2) => {
746
- IdentityProvider2["Cognito"] = "COGNITO";
747
- IdentityProvider2["Google"] = "Google";
748
- IdentityProvider2["Facebook"] = "Facebook";
749
- IdentityProvider2["Amazon"] = "LoginWithAmazon";
750
- IdentityProvider2["Apple"] = "SignInWithApple";
751
- return IdentityProvider2;
752
- })(IdentityProvider || {});
806
+ var IdentityProvider = {
807
+ Cognito: "COGNITO",
808
+ Google: "Google",
809
+ Facebook: "Facebook",
810
+ Apple: "SignInWithApple"
811
+ };
753
812
  function adaptExpiresIn(auth) {
754
813
  return {
755
814
  ...auth,
@@ -821,6 +880,11 @@ async function cognitoRequest(body, serviceTarget, cognitoEndpoint) {
821
880
  }
822
881
  }
823
882
  var CognitoClient = class {
883
+ cognitoEndpoint;
884
+ cognitoPoolName;
885
+ userPoolClientId;
886
+ oAuth;
887
+ clientSecret;
824
888
  constructor({ userPoolId, userPoolClientId, endpoint, oAuth2: oAuth, clientSecret }) {
825
889
  const [cognitoPoolRegion, cognitoPoolName] = userPoolId.split("_");
826
890
  this.cognitoEndpoint = (endpoint || `https://cognito-idp.${cognitoPoolRegion}.amazonaws.com`).replace(/\/$/, "");
@@ -837,6 +901,20 @@ var CognitoClient = class {
837
901
  accessToken
838
902
  };
839
903
  }
904
+ 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);
915
+ }
916
+ return cognitoResponse;
917
+ }
840
918
  /**
841
919
  *
842
920
  * Performs user authentication with username and password through ALLOW_USER_SRP_AUTH .
@@ -850,20 +928,15 @@ var CognitoClient = class {
850
928
  async authenticateUserSrp(username, password) {
851
929
  const smallA = await generateSmallA();
852
930
  const A = generateA(smallA);
853
- const initUserSrpAuthResponse = await cognitoRequest(
854
- {
855
- AuthFlow: "USER_SRP_AUTH",
856
- ClientId: this.userPoolClientId,
857
- AuthParameters: {
858
- USERNAME: username,
859
- SRP_A: A.toString(16),
860
- SECRET_HASH: this.clientSecret && await calculateSecretHash(this.clientSecret, this.userPoolClientId, username)
861
- },
862
- ClientMetadata: {}
931
+ const initUserSrpAuthResponse = await this.initiateAuth({
932
+ AuthFlow: "USER_SRP_AUTH",
933
+ AuthParameters: {
934
+ USERNAME: username,
935
+ SRP_A: A.toString(16),
936
+ SECRET_HASH: this.clientSecret && await calculateSecretHash(this.clientSecret, this.userPoolClientId, username)
863
937
  },
864
- "InitiateAuth" /* InitiateAuth */,
865
- this.cognitoEndpoint
866
- );
938
+ ClientMetadata: {}
939
+ });
867
940
  if (initUserSrpAuthResponse.ChallengeName !== "PASSWORD_VERIFIER") {
868
941
  return initUserSrpAuthResponse;
869
942
  }
@@ -919,7 +992,6 @@ var CognitoClient = class {
919
992
  async authenticateUser(username, password) {
920
993
  const initiateAuthPayload = {
921
994
  AuthFlow: "USER_PASSWORD_AUTH",
922
- ClientId: this.userPoolClientId,
923
995
  AuthParameters: {
924
996
  USERNAME: username,
925
997
  PASSWORD: password,
@@ -927,19 +999,78 @@ var CognitoClient = class {
927
999
  },
928
1000
  ClientMetadata: {}
929
1001
  };
930
- const initUserPasswordAuthResponse = await cognitoRequest(
931
- initiateAuthPayload,
932
- "InitiateAuth" /* InitiateAuth */,
933
- this.cognitoEndpoint
934
- );
1002
+ const initUserPasswordAuthResponse = await this.initiateAuth(initiateAuthPayload);
935
1003
  if (!initUserPasswordAuthResponse.AuthenticationResult) {
936
1004
  return initUserPasswordAuthResponse;
937
1005
  }
938
- initUserPasswordAuthResponse.AuthenticationResult = adaptExpiresIn(
939
- initUserPasswordAuthResponse.AuthenticationResult
940
- );
941
1006
  return initUserPasswordAuthResponse;
942
1007
  }
1008
+ /**
1009
+ * Initiates the authentication process for a user using a preferred challenge, such as WEB_AUTHN.
1010
+ */
1011
+ async authenticateWebAuthn(username) {
1012
+ const webAuthnPayload = {
1013
+ AuthFlow: "USER_AUTH",
1014
+ AuthParameters: {
1015
+ USERNAME: username,
1016
+ PREFERRED_CHALLENGE: "WEB_AUTHN"
1017
+ }
1018
+ };
1019
+ const authResponse = await this.initiateAuth(webAuthnPayload);
1020
+ if (authResponse.ChallengeName !== "WEB_AUTHN") {
1021
+ throw new InitAuthError(
1022
+ "Authentication failed, expected WEB_AUTHN challenge but received: " + authResponse.ChallengeName,
1023
+ "InternalErrorException" /* InternalErrorException */
1024
+ );
1025
+ }
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
+ const credentials = await navigator.credentials.get({
1035
+ publicKey: credentialRequestOptions
1036
+ });
1037
+ const challengeResponse = await this.respondToAuthChallenge({
1038
+ ChallengeName: "WEB_AUTHN",
1039
+ ChallengeResponses: {
1040
+ USERNAME: username,
1041
+ CREDENTIAL: JSON.stringify(publicKeyCredentialToJSON(credentials)),
1042
+ SECRET_HASH: this.clientSecret && await calculateSecretHash(this.clientSecret, this.userPoolClientId, username)
1043
+ },
1044
+ Session: authResponse.Session
1045
+ });
1046
+ if (challengeResponse.AuthenticationResult) {
1047
+ challengeResponse.AuthenticationResult = adaptExpiresIn(challengeResponse.AuthenticationResult);
1048
+ }
1049
+ return challengeResponse;
1050
+ }
1051
+ /**
1052
+ * Registers a new WebAuthn device for the current user.
1053
+ * This method initiates the WebAuthn registration process by requesting the necessary options from Cognito,
1054
+ * then creates a new public key credential using the WebAuthn API, and finally
1055
+ * completes the registration by sending the credential back to Cognito.
1056
+ *
1057
+ * @param accessToken Access token of the current user.
1058
+ */
1059
+ async registerWebAuthnDevice(accessToken) {
1060
+ const { CredentialCreationOptions } = await this.startWebAuthnRegistration({
1061
+ AccessToken: accessToken
1062
+ });
1063
+ const credentials = await navigator.credentials.create({
1064
+ publicKey: CredentialCreationOptions
1065
+ });
1066
+ if (!(credentials instanceof PublicKeyCredential)) {
1067
+ throw new Error("Invalid credentials returned from WebAuthn API");
1068
+ }
1069
+ await this.completeWebAuthnRegistration({
1070
+ AccessToken: accessToken,
1071
+ Credential: credentials
1072
+ });
1073
+ }
943
1074
  /**
944
1075
  * Returns a new session based on the given refresh token.
945
1076
  *
@@ -951,18 +1082,13 @@ var CognitoClient = class {
951
1082
  async refreshSession(refreshToken, username) {
952
1083
  const refreshTokenPayload = {
953
1084
  AuthFlow: "REFRESH_TOKEN_AUTH",
954
- ClientId: this.userPoolClientId,
955
1085
  AuthParameters: {
956
1086
  REFRESH_TOKEN: refreshToken,
957
1087
  SECRET_HASH: this.clientSecret && username && await calculateSecretHash(this.clientSecret, this.userPoolClientId, username)
958
1088
  },
959
1089
  ClientMetadata: {}
960
1090
  };
961
- const { AuthenticationResult } = await cognitoRequest(
962
- refreshTokenPayload,
963
- "InitiateAuth" /* InitiateAuth */,
964
- this.cognitoEndpoint
965
- );
1091
+ const { AuthenticationResult } = await this.initiateAuth(refreshTokenPayload);
966
1092
  if (!AuthenticationResult) {
967
1093
  throw new InitAuthError(
968
1094
  "Authentication failed, no authentication result returned",
@@ -972,7 +1098,7 @@ var CognitoClient = class {
972
1098
  if (!AuthenticationResult.RefreshToken) {
973
1099
  AuthenticationResult.RefreshToken = refreshToken;
974
1100
  }
975
- return adaptExpiresIn(AuthenticationResult);
1101
+ return AuthenticationResult;
976
1102
  }
977
1103
  /**
978
1104
  *
@@ -1027,15 +1153,40 @@ var CognitoClient = class {
1027
1153
  };
1028
1154
  await cognitoRequest(changePasswordPayload, "ChangePassword" /* ChangePassword */, this.cognitoEndpoint);
1029
1155
  }
1156
+ /**
1157
+ * Gets the user information.
1158
+ * @param accessToken Access token of the current user.
1159
+ * @returns User information.
1160
+ */
1030
1161
  async getUser(accessToken) {
1031
1162
  const getUserPayload = {
1032
1163
  AccessToken: accessToken
1033
1164
  };
1034
1165
  return cognitoRequest(getUserPayload, "GetUser" /* GetUser */, this.cognitoEndpoint);
1035
1166
  }
1167
+ /**
1168
+ * Associates a software token with the user.
1169
+ * @param params Request to associate a software token with the user.
1170
+ * @param params.AccessToken Access token of the current user.
1171
+ * @param params.Session Optional session identifier for the authentication process.
1172
+ * @param params.ClientMetadata Optional metadata to pass to the service.
1173
+ * @param params.UserContextData Optional user context data.
1174
+ * @param params.AnalyticsMetadata Optional analytics metadata.
1175
+ * @param params.FriendlyDeviceName Optional friendly name for the device.
1176
+ * @returns
1177
+ */
1036
1178
  async associateSoftwareToken(params) {
1037
1179
  return cognitoRequest(params, "AssociateSoftwareToken" /* AssociateSoftwareToken */, this.cognitoEndpoint);
1038
1180
  }
1181
+ /**
1182
+ * Verifies a software token.
1183
+ * @param params Request to verify a software token.
1184
+ * @param params.AccessToken Access token of the current user.
1185
+ * @param params.FriendlyDeviceName Optional friendly name for the device.
1186
+ * @param params.Session Optional session identifier for the authentication process.
1187
+ * @param params.UserCode The user code to verify.
1188
+ * @returns
1189
+ */
1039
1190
  async verifySoftwareToken(params) {
1040
1191
  return cognitoRequest(params, "VerifySoftwareToken" /* VerifySoftwareToken */, this.cognitoEndpoint);
1041
1192
  }
@@ -1178,6 +1329,59 @@ var CognitoClient = class {
1178
1329
  };
1179
1330
  await cognitoRequest(resendConfirmationCodeRequest, "ResendConfirmationCode" /* ResendConfirmationCode */, this.cognitoEndpoint);
1180
1331
  }
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;
1345
+ }
1346
+ /**
1347
+ * Completes registration of a passkey authenticator for the currently signed-in user.
1348
+ * @param request Request to complete WebAuthn registration.
1349
+ * @param request.AccessToken Access token of the current user.
1350
+ * @param request.Credential The credential object returned by the WebAuthn API.
1351
+ */
1352
+ async completeWebAuthnRegistration(request) {
1353
+ await cognitoRequest(
1354
+ {
1355
+ AccessToken: request.AccessToken,
1356
+ Credential: publicKeyCredentialToJSON(request.Credential)
1357
+ },
1358
+ "CompleteWebAuthnRegistration" /* CompleteWebAuthnRegistration */,
1359
+ this.cognitoEndpoint
1360
+ );
1361
+ }
1362
+ /**
1363
+ * Deletes a registered passkey, or WebAuthn, authenticator for the currently signed-in user.
1364
+ *
1365
+ * @param request Request to delete a WebAuthn credential.
1366
+ * @param request.AccessToken Access token of the current user.
1367
+ * @param request.CredentialId The ID of the credential to delete.
1368
+ */
1369
+ async deleteWebAuthnCredential(request) {
1370
+ await cognitoRequest(request, "DeleteWebAuthnCredential" /* DeleteWebAuthnCredential */, this.cognitoEndpoint);
1371
+ }
1372
+ /**
1373
+ * Lists all registered WebAuthn credentials for the currently signed-in user.
1374
+ *
1375
+ * @param request Request to list WebAuthn credentials.
1376
+ * @param request.AccessToken Access token of the current user.
1377
+ * @param request.MaxResults Maximum number of credentials to return.
1378
+ * @param request.NextToken Pagination token to continue listing credentials.
1379
+ * @returns
1380
+ */
1381
+ async listWebAuthnCredentials(request) {
1382
+ const response = await cognitoRequest(request, "ListWebAuthnCredentials" /* ListWebAuthnCredentials */, this.cognitoEndpoint);
1383
+ return response;
1384
+ }
1181
1385
  /**
1182
1386
  * Returns a link to Cognito`s Hosted UI for OAuth2 authentication.
1183
1387
  * This method works in conjunction with @see handleCodeFlow .
@@ -1319,5 +1523,30 @@ export {
1319
1523
  VerifyUserAttributeError,
1320
1524
  VerifyUserAttributeException,
1321
1525
  adaptExpiresIn,
1322
- cognitoRequest
1526
+ base64UrlToUint8Array,
1527
+ calculateHKDF,
1528
+ calculateS,
1529
+ calculateSecretHash,
1530
+ calculateSignature,
1531
+ calculateU,
1532
+ cognitoRequest,
1533
+ decodeJwt,
1534
+ digest,
1535
+ formatTimestamp,
1536
+ generateA,
1537
+ generateSmallA,
1538
+ getPasswordAuthenticationKey,
1539
+ hashBuffer,
1540
+ hashHexString,
1541
+ hmac,
1542
+ padHex,
1543
+ publicKeyCredentialToJSON,
1544
+ randomBytes,
1545
+ removeUndefined,
1546
+ uint8ArrayFromBase64String,
1547
+ uint8ArrayFromHexString,
1548
+ uint8ArrayFromString,
1549
+ uint8ArrayToBase64String,
1550
+ uint8ArrayToBase64UrlString,
1551
+ uint8ArrayToHexString
1323
1552
  };
@@ -9,7 +9,7 @@ export interface CognitoBaseRequest {
9
9
  IpAddress?: string;
10
10
  };
11
11
  }
12
- export interface InitiateAuthUserSrpAuthRequest extends CognitoBaseRequest {
12
+ export interface _InitiateAuthUserSrpAuthRequest extends CognitoBaseRequest {
13
13
  AuthFlow: 'USER_SRP_AUTH';
14
14
  AuthParameters: {
15
15
  USERNAME: string;
@@ -17,7 +17,7 @@ export interface InitiateAuthUserSrpAuthRequest extends CognitoBaseRequest {
17
17
  SECRET_HASH?: string;
18
18
  };
19
19
  }
20
- export interface InitiateAuthUserPasswordAuthRequest extends CognitoBaseRequest {
20
+ export interface _InitiateAuthUserPasswordAuthRequest extends CognitoBaseRequest {
21
21
  AuthFlow: 'USER_PASSWORD_AUTH';
22
22
  AuthParameters: {
23
23
  USERNAME: string;
@@ -25,21 +25,31 @@ export interface InitiateAuthUserPasswordAuthRequest extends CognitoBaseRequest
25
25
  SECRET_HASH?: string;
26
26
  };
27
27
  }
28
- export interface InitiateAuthRefreshTokenAuthRequest extends CognitoBaseRequest {
28
+ export interface _InitiateAuthRefreshTokenAuthRequest extends CognitoBaseRequest {
29
29
  AuthFlow: 'REFRESH_TOKEN_AUTH';
30
30
  AuthParameters: {
31
31
  REFRESH_TOKEN: string;
32
32
  SECRET_HASH?: string;
33
+ USERNAME?: never;
33
34
  };
34
35
  }
35
- export interface InitiateAuthCustomAuthRequest extends CognitoBaseRequest {
36
+ export interface _InitiateAuthCustomAuthRequest extends CognitoBaseRequest {
36
37
  AuthFlow: 'CUSTOM_AUTH';
37
38
  AuthParameters: {
38
39
  USERNAME: string;
39
40
  SECRET_HASH?: string;
40
41
  };
41
42
  }
42
- export type InitiateAuthRequest = InitiateAuthUserSrpAuthRequest | InitiateAuthRefreshTokenAuthRequest | InitiateAuthCustomAuthRequest | InitiateAuthUserPasswordAuthRequest;
43
+ export interface _InitiateAuthUserAuthRequest extends CognitoBaseRequest {
44
+ AuthFlow: 'USER_AUTH';
45
+ AuthParameters: {
46
+ USERNAME: string;
47
+ PREFERRED_CHALLENGE?: AuthChallenge;
48
+ SECRET_HASH?: string;
49
+ };
50
+ }
51
+ type _InitiateAuthRequest = _InitiateAuthUserSrpAuthRequest | _InitiateAuthUserPasswordAuthRequest | _InitiateAuthRefreshTokenAuthRequest | _InitiateAuthCustomAuthRequest | _InitiateAuthUserAuthRequest;
52
+ export type InitiateAuthRequest = Omit<_InitiateAuthUserSrpAuthRequest, 'ClientId'> | Omit<_InitiateAuthUserPasswordAuthRequest, 'ClientId'> | Omit<_InitiateAuthRefreshTokenAuthRequest, 'ClientId'> | Omit<_InitiateAuthCustomAuthRequest, 'ClientId'> | Omit<_InitiateAuthUserAuthRequest, 'ClientId'>;
43
53
  export interface RespondToAuthChallengeBaseRequest extends CognitoBaseRequest {
44
54
  Session?: string;
45
55
  }
@@ -112,6 +122,7 @@ export interface _RespondToAuthChallengeMfaSetupRequest extends RespondToAuthCha
112
122
  SOFTWARE_TOKEN_MFA_CODE?: string;
113
123
  SECRET_HASH?: string;
114
124
  };
125
+ Session?: never;
115
126
  }
116
127
  export interface _RespondToAuthChallengeSelectMfaTypeRequest extends RespondToAuthChallengeBaseRequest {
117
128
  ChallengeName: 'SELECT_MFA_TYPE';
@@ -121,8 +132,16 @@ export interface _RespondToAuthChallengeSelectMfaTypeRequest extends RespondToAu
121
132
  SECRET_HASH?: string;
122
133
  };
123
134
  }
124
- type _RespondToAuthChallengeRequest = _RespondToAuthChallengePasswordVerifierRequest | _RespondToAuthChallengeSmsMfaRequest | _RespondToAuthChallengeCustomChallengeNameRequest | _RespondToAuthChallengeNewPasswordRequiredRequest | _RespondToAuthChallengeSoftwareTokenMfaRequest | _RespondToAuthChallengeDeviceSrpAuthRequest | _RespondToAuthChallengeDevicePasswordVerifierRequest | _RespondToAuthChallengeMfaSetupRequest | _RespondToAuthChallengeSelectMfaTypeRequest;
125
- 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'>;
135
+ export interface _RespondToAuthChallengeWebAuthnRequest extends RespondToAuthChallengeBaseRequest {
136
+ ChallengeName: 'WEB_AUTHN';
137
+ ChallengeResponses: {
138
+ USERNAME: string;
139
+ CREDENTIAL: any;
140
+ SECRET_HASH?: string;
141
+ };
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'>;
126
145
  export interface UserAttribute {
127
146
  Name: string;
128
147
  Value: string;
@@ -258,7 +277,11 @@ export declare enum ServiceTarget {
258
277
  AssociateSoftwareToken = "AssociateSoftwareToken",
259
278
  VerifySoftwareToken = "VerifySoftwareToken",
260
279
  ListDevices = "ListDevices",
261
- SetUserMFAPreference = "SetUserMFAPreference"
280
+ SetUserMFAPreference = "SetUserMFAPreference",
281
+ StartWebAuthnRegistration = "StartWebAuthnRegistration",
282
+ CompleteWebAuthnRegistration = "CompleteWebAuthnRegistration",
283
+ DeleteWebAuthnCredential = "DeleteWebAuthnCredential",
284
+ ListWebAuthnCredentials = "ListWebAuthnCredentials"
262
285
  }
263
286
  export interface AssociateSoftwareTokenRequest {
264
287
  AccessToken?: string;
@@ -300,16 +323,14 @@ export interface ListDevicesResponse {
300
323
  PaginationToken?: string;
301
324
  }
302
325
  /**
303
- * Cognito supported federated identities public providers.
304
- * @see https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-identity.html for more information.
326
+ * Cognito built in identity providers.
305
327
  */
306
- export declare enum IdentityProvider {
307
- Cognito = "COGNITO",
308
- Google = "Google",
309
- Facebook = "Facebook",
310
- Amazon = "LoginWithAmazon",
311
- Apple = "SignInWithApple"
312
- }
328
+ export declare const IdentityProvider: {
329
+ Cognito: string;
330
+ Google: string;
331
+ Facebook: string;
332
+ Apple: string;
333
+ };
313
334
  export interface AuthenticationResult {
314
335
  AccessToken: string;
315
336
  ExpiresIn: number;
@@ -321,12 +342,16 @@ export interface NewDeviceMetadata {
321
342
  DeviceKey?: string;
322
343
  DeviceGroupKey?: string;
323
344
  }
324
- export interface InitiateAuthAuthenticationResponse {
345
+ export type AuthChallenge = InitiateAuthChallengeResponse['ChallengeName'];
346
+ export interface InitiateAuthBaseResponse {
347
+ AvailableChallenges: [];
348
+ Session: string;
349
+ }
350
+ export interface InitiateAuthAuthenticationResponse extends InitiateAuthBaseResponse {
325
351
  AuthenticationResult: AuthenticationResult;
326
352
  ChallengeName?: never;
327
- session?: never;
328
353
  }
329
- export interface InitiateAuthPasswordVerifierChallengeResponse {
354
+ export interface InitiateAuthPasswordVerifierChallengeResponse extends InitiateAuthBaseResponse {
330
355
  AuthenticationResult?: never;
331
356
  ChallengeName: 'PASSWORD_VERIFIER';
332
357
  ChallengeParameters: {
@@ -336,20 +361,48 @@ export interface InitiateAuthPasswordVerifierChallengeResponse {
336
361
  USERNAME: string;
337
362
  USER_ID_FOR_SRP: string;
338
363
  };
339
- session?: never;
340
364
  }
341
- export interface InitiateAuthSoftwareTokenMfaChallengeResponse {
365
+ export interface InitiateAuthSoftwareTokenMfaChallengeResponse extends InitiateAuthBaseResponse {
342
366
  AuthenticationResult?: never;
343
367
  ChallengeName: 'SOFTWARE_TOKEN_MFA';
368
+ }
369
+ export interface InitiateAuthWebAuthResponse extends InitiateAuthBaseResponse {
370
+ AuthenticationResult?: never;
371
+ ChallengeName: 'WEB_AUTHN';
344
372
  Session: string;
373
+ ChallengeParameters: {
374
+ CREDENTIAL_REQUEST_OPTIONS: string;
375
+ };
345
376
  }
346
- export interface InitiateEmailOtpChallengeResponse {
377
+ export interface InitiateEmailOtpChallengeResponse extends InitiateAuthBaseResponse {
378
+ AuthenticationResult?: never;
347
379
  ChallengeName: 'EMAIL_OTP';
348
380
  ChallengeParameters: {
349
381
  CODE_DELIVERY_DELIVERY_MEDIUM: string;
350
382
  CODE_DELIVERY_DESTINATION: string;
351
383
  };
352
- session: string;
384
+ Session: string;
385
+ }
386
+ export interface InitAuthSelectChallengeResponse extends InitiateAuthBaseResponse {
387
+ AuthenticationResult?: never;
388
+ ChallengeName: 'SELECT_CHALLENGE';
389
+ ChallengeParameters: never;
390
+ }
391
+ export interface InitAuthPasswordChallengeResponse extends InitiateAuthBaseResponse {
392
+ AuthenticationResult?: never;
393
+ ChallengeName: 'PASSWORD';
394
+ ChallengeParameters: never;
395
+ }
396
+ export interface InitAuthPasswordSRPChallengeResponse extends InitiateAuthBaseResponse {
397
+ AuthenticationResult?: never;
398
+ ChallengeName: 'PASSWORD_SRP';
399
+ ChallengeParameters: never;
400
+ }
401
+ export interface InitAuthMfaSetupChallengeResponse extends InitiateAuthBaseResponse {
402
+ AuthenticationResult?: never;
403
+ ChallengeName: 'MFA_SETUP';
404
+ ChallengeParameters: never;
405
+ MFAS_CAN_SETUP: ('SMS_MFA' | 'SOFTWARE_TOKEN_MFA')[];
353
406
  }
354
407
  export interface MfaOption {
355
408
  DeliveryMedium: 'SMS' | 'EMAIL';
@@ -377,7 +430,38 @@ export interface SetUserMFAPreferenceRequest {
377
430
  PreferredMfa?: boolean;
378
431
  };
379
432
  }
380
- export type InitiateAuthChallengeResponse = InitiateAuthPasswordVerifierChallengeResponse | InitiateAuthSoftwareTokenMfaChallengeResponse;
433
+ export interface StartWebAuthnRegistrationRequest {
434
+ AccessToken: string;
435
+ }
436
+ export interface StartWebAuthnRegistrationResponse {
437
+ CredentialCreationOptions: any;
438
+ }
439
+ export interface CompleteWebAuthnRegistrationRequest {
440
+ AccessToken: string;
441
+ Credential: PublicKeyCredential;
442
+ }
443
+ export interface DeleteWebAuthnCredentialRequest {
444
+ AccessToken: string;
445
+ CredentialId: string;
446
+ }
447
+ export interface ListWebAuthnCredentialsRequest {
448
+ AccessToken: string;
449
+ MaxResults?: number;
450
+ NextToken?: string;
451
+ }
452
+ export interface WebAuthnCredential {
453
+ AuthenticatorTransports: string[];
454
+ CreatedAt: string;
455
+ CredentialId: string;
456
+ FriendlyCredentialName: string;
457
+ RelyingPartyId: string;
458
+ AuthenticatorAttachment?: string;
459
+ }
460
+ export interface ListWebAuthnCredentialsResponse {
461
+ Credentials: WebAuthnCredential[];
462
+ NextToken?: string;
463
+ }
464
+ export type InitiateAuthChallengeResponse = InitiateAuthPasswordVerifierChallengeResponse | InitiateAuthSoftwareTokenMfaChallengeResponse | InitiateAuthWebAuthResponse | InitiateEmailOtpChallengeResponse | InitAuthSelectChallengeResponse | InitAuthPasswordChallengeResponse | InitAuthPasswordSRPChallengeResponse | InitAuthMfaSetupChallengeResponse;
381
465
  export type InitiateAuthResponse = InitiateAuthAuthenticationResponse | InitiateAuthPasswordVerifierChallengeResponse | InitiateAuthChallengeResponse;
382
466
  type CognitoResponseMap = {
383
467
  [ServiceTarget.InitiateAuth]: InitiateAuthResponse;
@@ -400,9 +484,13 @@ type CognitoResponseMap = {
400
484
  [ServiceTarget.VerifySoftwareToken]: VerifySoftwareTokenResponse;
401
485
  [ServiceTarget.ListDevices]: ListDevicesResponse;
402
486
  [ServiceTarget.SetUserMFAPreference]: void;
487
+ [ServiceTarget.StartWebAuthnRegistration]: StartWebAuthnRegistrationResponse;
488
+ [ServiceTarget.CompleteWebAuthnRegistration]: void;
489
+ [ServiceTarget.DeleteWebAuthnCredential]: void;
490
+ [ServiceTarget.ListWebAuthnCredentials]: ListWebAuthnCredentialsResponse;
403
491
  };
404
492
  type CognitoRequestMap = {
405
- [ServiceTarget.InitiateAuth]: InitiateAuthRequest;
493
+ [ServiceTarget.InitiateAuth]: _InitiateAuthRequest;
406
494
  [ServiceTarget.RespondToAuthChallenge]: _RespondToAuthChallengeRequest;
407
495
  [ServiceTarget.SignUp]: SignUpRequest;
408
496
  [ServiceTarget.ConfirmSignUp]: ConfirmSignUpRequest;
@@ -438,6 +526,10 @@ type CognitoRequestMap = {
438
526
  [ServiceTarget.VerifySoftwareToken]: VerifySoftwareTokenRequest;
439
527
  [ServiceTarget.ListDevices]: ListDevicesRequest;
440
528
  [ServiceTarget.SetUserMFAPreference]: SetUserMFAPreferenceRequest;
529
+ [ServiceTarget.StartWebAuthnRegistration]: StartWebAuthnRegistrationRequest;
530
+ [ServiceTarget.CompleteWebAuthnRegistration]: any;
531
+ [ServiceTarget.DeleteWebAuthnCredential]: DeleteWebAuthnCredentialRequest;
532
+ [ServiceTarget.ListWebAuthnCredentials]: ListWebAuthnCredentialsRequest;
441
533
  };
442
534
  export declare function adaptExpiresIn(auth: AuthenticationResult): {
443
535
  ExpiresIn: number;
@@ -458,6 +550,7 @@ export declare class CognitoClient {
458
550
  private readonly clientSecret?;
459
551
  constructor({ userPoolId, userPoolClientId, endpoint, oAuth2: oAuth, clientSecret }: CognitoClientProps);
460
552
  static getDecodedTokenFromSession(auth: AuthenticationResult): DecodedTokens;
553
+ initiateAuth(request: InitiateAuthRequest): Promise<InitiateAuthResponse>;
461
554
  /**
462
555
  *
463
556
  * Performs user authentication with username and password through ALLOW_USER_SRP_AUTH .
@@ -479,6 +572,19 @@ export declare class CognitoClient {
479
572
  * @throws {InitAuthError}
480
573
  */
481
574
  authenticateUser(username: string, password: string): Promise<InitiateAuthResponse>;
575
+ /**
576
+ * Initiates the authentication process for a user using a preferred challenge, such as WEB_AUTHN.
577
+ */
578
+ authenticateWebAuthn(username: string): Promise<InitiateAuthResponse>;
579
+ /**
580
+ * Registers a new WebAuthn device for the current user.
581
+ * This method initiates the WebAuthn registration process by requesting the necessary options from Cognito,
582
+ * then creates a new public key credential using the WebAuthn API, and finally
583
+ * completes the registration by sending the credential back to Cognito.
584
+ *
585
+ * @param accessToken Access token of the current user.
586
+ */
587
+ registerWebAuthnDevice(accessToken: string): Promise<void>;
482
588
  /**
483
589
  * Returns a new session based on the given refresh token.
484
590
  *
@@ -516,8 +622,33 @@ export declare class CognitoClient {
516
622
  * @throws {ChangePasswordError}
517
623
  */
518
624
  changePassword(currentPassword: string, newPassword: string, accessToken: string): Promise<void>;
625
+ /**
626
+ * Gets the user information.
627
+ * @param accessToken Access token of the current user.
628
+ * @returns User information.
629
+ */
519
630
  getUser(accessToken: string): Promise<GetUserResponse>;
631
+ /**
632
+ * Associates a software token with the user.
633
+ * @param params Request to associate a software token with the user.
634
+ * @param params.AccessToken Access token of the current user.
635
+ * @param params.Session Optional session identifier for the authentication process.
636
+ * @param params.ClientMetadata Optional metadata to pass to the service.
637
+ * @param params.UserContextData Optional user context data.
638
+ * @param params.AnalyticsMetadata Optional analytics metadata.
639
+ * @param params.FriendlyDeviceName Optional friendly name for the device.
640
+ * @returns
641
+ */
520
642
  associateSoftwareToken(params: AssociateSoftwareTokenRequest): Promise<AssociateSoftwareResponse>;
643
+ /**
644
+ * Verifies a software token.
645
+ * @param params Request to verify a software token.
646
+ * @param params.AccessToken Access token of the current user.
647
+ * @param params.FriendlyDeviceName Optional friendly name for the device.
648
+ * @param params.Session Optional session identifier for the authentication process.
649
+ * @param params.UserCode The user code to verify.
650
+ * @returns
651
+ */
521
652
  verifySoftwareToken(params: VerifySoftwareTokenRequest): Promise<VerifySoftwareTokenResponse>;
522
653
  /**
523
654
  * Responds to an authentication challenge.
@@ -602,6 +733,32 @@ export declare class CognitoClient {
602
733
  * @throws {ResendConfirmationCodeError}
603
734
  */
604
735
  resendConfirmationCode(username: string): Promise<void>;
736
+ startWebAuthnRegistration(request: StartWebAuthnRegistrationRequest): Promise<StartWebAuthnRegistrationResponse>;
737
+ /**
738
+ * Completes registration of a passkey authenticator for the currently signed-in user.
739
+ * @param request Request to complete WebAuthn registration.
740
+ * @param request.AccessToken Access token of the current user.
741
+ * @param request.Credential The credential object returned by the WebAuthn API.
742
+ */
743
+ completeWebAuthnRegistration(request: CompleteWebAuthnRegistrationRequest): Promise<void>;
744
+ /**
745
+ * Deletes a registered passkey, or WebAuthn, authenticator for the currently signed-in user.
746
+ *
747
+ * @param request Request to delete a WebAuthn credential.
748
+ * @param request.AccessToken Access token of the current user.
749
+ * @param request.CredentialId The ID of the credential to delete.
750
+ */
751
+ deleteWebAuthnCredential(request: DeleteWebAuthnCredentialRequest): Promise<void>;
752
+ /**
753
+ * Lists all registered WebAuthn credentials for the currently signed-in user.
754
+ *
755
+ * @param request Request to list WebAuthn credentials.
756
+ * @param request.AccessToken Access token of the current user.
757
+ * @param request.MaxResults Maximum number of credentials to return.
758
+ * @param request.NextToken Pagination token to continue listing credentials.
759
+ * @returns
760
+ */
761
+ listWebAuthnCredentials(request: ListWebAuthnCredentialsRequest): Promise<ListWebAuthnCredentialsResponse>;
605
762
  /**
606
763
  * Returns a link to Cognito`s Hosted UI for OAuth2 authentication.
607
764
  * This method works in conjunction with @see handleCodeFlow .
@@ -611,7 +768,7 @@ export declare class CognitoClient {
611
768
  *
612
769
  * @throws {Error}
613
770
  */
614
- generateOAuthSignInUrl(identityProvider?: IdentityProvider): Promise<{
771
+ generateOAuthSignInUrl(identityProvider?: string): Promise<{
615
772
  url: string;
616
773
  state: string;
617
774
  pkce: string;
@@ -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 { calculateSecretHash, calculateSignature, calculateU, decodeJwt, digest, generateA, generateSmallA, getPasswordAuthenticationKey, randomBytes, uint8ArrayFromString, uint8ArrayToBase64String } from './utils.js';
2
+ import { base64UrlToUint8Array, calculateSecretHash, calculateSignature, calculateU, 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
@@ -23,19 +23,20 @@ export var ServiceTarget;
23
23
  ServiceTarget["VerifySoftwareToken"] = "VerifySoftwareToken";
24
24
  ServiceTarget["ListDevices"] = "ListDevices";
25
25
  ServiceTarget["SetUserMFAPreference"] = "SetUserMFAPreference";
26
+ ServiceTarget["StartWebAuthnRegistration"] = "StartWebAuthnRegistration";
27
+ ServiceTarget["CompleteWebAuthnRegistration"] = "CompleteWebAuthnRegistration";
28
+ ServiceTarget["DeleteWebAuthnCredential"] = "DeleteWebAuthnCredential";
29
+ ServiceTarget["ListWebAuthnCredentials"] = "ListWebAuthnCredentials";
26
30
  })(ServiceTarget || (ServiceTarget = {}));
27
31
  /**
28
- * Cognito supported federated identities public providers.
29
- * @see https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-identity.html for more information.
32
+ * Cognito built in identity providers.
30
33
  */
31
- export var IdentityProvider;
32
- (function (IdentityProvider) {
33
- IdentityProvider["Cognito"] = "COGNITO";
34
- IdentityProvider["Google"] = "Google";
35
- IdentityProvider["Facebook"] = "Facebook";
36
- IdentityProvider["Amazon"] = "LoginWithAmazon";
37
- IdentityProvider["Apple"] = "SignInWithApple";
38
- })(IdentityProvider || (IdentityProvider = {}));
34
+ export const IdentityProvider = {
35
+ Cognito: 'COGNITO',
36
+ Google: 'Google',
37
+ Facebook: 'Facebook',
38
+ Apple: 'SignInWithApple'
39
+ };
39
40
  export function adaptExpiresIn(auth) {
40
41
  // Cognito returns expiresIn in seconds, but we want it in milliseconds from now
41
42
  return {
@@ -119,6 +120,11 @@ export async function cognitoRequest(body, serviceTarget, cognitoEndpoint) {
119
120
  * Lightweight AWS Cogito client without any AWS SDK dependencies.
120
121
  */
121
122
  export class CognitoClient {
123
+ cognitoEndpoint;
124
+ cognitoPoolName;
125
+ userPoolClientId;
126
+ oAuth;
127
+ clientSecret;
122
128
  constructor({ userPoolId, userPoolClientId, endpoint, oAuth2: oAuth, clientSecret }) {
123
129
  const [cognitoPoolRegion, cognitoPoolName] = userPoolId.split('_');
124
130
  this.cognitoEndpoint = (endpoint || `https://cognito-idp.${cognitoPoolRegion}.amazonaws.com`).replace(/\/$/, '');
@@ -135,6 +141,16 @@ export class CognitoClient {
135
141
  accessToken
136
142
  };
137
143
  }
144
+ async initiateAuth(request) {
145
+ const cognitoResponse = await cognitoRequest({
146
+ ...request,
147
+ ClientId: this.userPoolClientId
148
+ }, ServiceTarget.InitiateAuth, this.cognitoEndpoint);
149
+ if (cognitoResponse.AuthenticationResult) {
150
+ cognitoResponse.AuthenticationResult = adaptExpiresIn(cognitoResponse.AuthenticationResult);
151
+ }
152
+ return cognitoResponse;
153
+ }
138
154
  /**
139
155
  *
140
156
  * Performs user authentication with username and password through ALLOW_USER_SRP_AUTH .
@@ -148,16 +164,15 @@ export class CognitoClient {
148
164
  async authenticateUserSrp(username, password) {
149
165
  const smallA = await generateSmallA();
150
166
  const A = generateA(smallA);
151
- const initUserSrpAuthResponse = await cognitoRequest({
167
+ const initUserSrpAuthResponse = await this.initiateAuth({
152
168
  AuthFlow: 'USER_SRP_AUTH',
153
- ClientId: this.userPoolClientId,
154
169
  AuthParameters: {
155
170
  USERNAME: username,
156
171
  SRP_A: A.toString(16),
157
172
  SECRET_HASH: this.clientSecret && (await calculateSecretHash(this.clientSecret, this.userPoolClientId, username))
158
173
  },
159
174
  ClientMetadata: {}
160
- }, ServiceTarget.InitiateAuth, this.cognitoEndpoint);
175
+ });
161
176
  if (initUserSrpAuthResponse.ChallengeName !== 'PASSWORD_VERIFIER') {
162
177
  return initUserSrpAuthResponse;
163
178
  }
@@ -195,7 +210,6 @@ export class CognitoClient {
195
210
  async authenticateUser(username, password) {
196
211
  const initiateAuthPayload = {
197
212
  AuthFlow: 'USER_PASSWORD_AUTH',
198
- ClientId: this.userPoolClientId,
199
213
  AuthParameters: {
200
214
  USERNAME: username,
201
215
  PASSWORD: password,
@@ -203,13 +217,73 @@ export class CognitoClient {
203
217
  },
204
218
  ClientMetadata: {}
205
219
  };
206
- const initUserPasswordAuthResponse = await cognitoRequest(initiateAuthPayload, ServiceTarget.InitiateAuth, this.cognitoEndpoint);
220
+ const initUserPasswordAuthResponse = await this.initiateAuth(initiateAuthPayload);
207
221
  if (!initUserPasswordAuthResponse.AuthenticationResult) {
208
222
  return initUserPasswordAuthResponse;
209
223
  }
210
- initUserPasswordAuthResponse.AuthenticationResult = adaptExpiresIn(initUserPasswordAuthResponse.AuthenticationResult);
211
224
  return initUserPasswordAuthResponse;
212
225
  }
226
+ /**
227
+ * Initiates the authentication process for a user using a preferred challenge, such as WEB_AUTHN.
228
+ */
229
+ async authenticateWebAuthn(username) {
230
+ const webAuthnPayload = {
231
+ AuthFlow: 'USER_AUTH',
232
+ AuthParameters: {
233
+ USERNAME: username,
234
+ PREFERRED_CHALLENGE: 'WEB_AUTHN'
235
+ }
236
+ };
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);
240
+ }
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
+ const credentials = await navigator.credentials.get({
248
+ publicKey: credentialRequestOptions
249
+ });
250
+ const challengeResponse = await this.respondToAuthChallenge({
251
+ ChallengeName: 'WEB_AUTHN',
252
+ ChallengeResponses: {
253
+ USERNAME: username,
254
+ CREDENTIAL: JSON.stringify(publicKeyCredentialToJSON(credentials)),
255
+ SECRET_HASH: this.clientSecret && (await calculateSecretHash(this.clientSecret, this.userPoolClientId, username))
256
+ },
257
+ Session: authResponse.Session
258
+ });
259
+ if (challengeResponse.AuthenticationResult) {
260
+ challengeResponse.AuthenticationResult = adaptExpiresIn(challengeResponse.AuthenticationResult);
261
+ }
262
+ return challengeResponse;
263
+ }
264
+ /**
265
+ * Registers a new WebAuthn device for the current user.
266
+ * This method initiates the WebAuthn registration process by requesting the necessary options from Cognito,
267
+ * then creates a new public key credential using the WebAuthn API, and finally
268
+ * completes the registration by sending the credential back to Cognito.
269
+ *
270
+ * @param accessToken Access token of the current user.
271
+ */
272
+ async registerWebAuthnDevice(accessToken) {
273
+ const { CredentialCreationOptions } = await this.startWebAuthnRegistration({
274
+ AccessToken: accessToken
275
+ });
276
+ const credentials = await navigator.credentials.create({
277
+ publicKey: CredentialCreationOptions
278
+ });
279
+ if (!(credentials instanceof PublicKeyCredential)) {
280
+ throw new Error('Invalid credentials returned from WebAuthn API');
281
+ }
282
+ await this.completeWebAuthnRegistration({
283
+ AccessToken: accessToken,
284
+ Credential: credentials
285
+ });
286
+ }
213
287
  /**
214
288
  * Returns a new session based on the given refresh token.
215
289
  *
@@ -221,7 +295,6 @@ export class CognitoClient {
221
295
  async refreshSession(refreshToken, username) {
222
296
  const refreshTokenPayload = {
223
297
  AuthFlow: 'REFRESH_TOKEN_AUTH',
224
- ClientId: this.userPoolClientId,
225
298
  AuthParameters: {
226
299
  REFRESH_TOKEN: refreshToken,
227
300
  SECRET_HASH: this.clientSecret &&
@@ -230,14 +303,14 @@ export class CognitoClient {
230
303
  },
231
304
  ClientMetadata: {}
232
305
  };
233
- const { AuthenticationResult } = await cognitoRequest(refreshTokenPayload, ServiceTarget.InitiateAuth, this.cognitoEndpoint);
306
+ const { AuthenticationResult } = await this.initiateAuth(refreshTokenPayload);
234
307
  if (!AuthenticationResult) {
235
308
  throw new InitAuthError('Authentication failed, no authentication result returned', InitiateAuthException.InternalErrorException);
236
309
  }
237
310
  if (!AuthenticationResult.RefreshToken) {
238
311
  AuthenticationResult.RefreshToken = refreshToken;
239
312
  }
240
- return adaptExpiresIn(AuthenticationResult);
313
+ return AuthenticationResult;
241
314
  }
242
315
  /**
243
316
  *
@@ -292,15 +365,40 @@ export class CognitoClient {
292
365
  };
293
366
  await cognitoRequest(changePasswordPayload, ServiceTarget.ChangePassword, this.cognitoEndpoint);
294
367
  }
368
+ /**
369
+ * Gets the user information.
370
+ * @param accessToken Access token of the current user.
371
+ * @returns User information.
372
+ */
295
373
  async getUser(accessToken) {
296
374
  const getUserPayload = {
297
375
  AccessToken: accessToken
298
376
  };
299
377
  return cognitoRequest(getUserPayload, ServiceTarget.GetUser, this.cognitoEndpoint);
300
378
  }
379
+ /**
380
+ * Associates a software token with the user.
381
+ * @param params Request to associate a software token with the user.
382
+ * @param params.AccessToken Access token of the current user.
383
+ * @param params.Session Optional session identifier for the authentication process.
384
+ * @param params.ClientMetadata Optional metadata to pass to the service.
385
+ * @param params.UserContextData Optional user context data.
386
+ * @param params.AnalyticsMetadata Optional analytics metadata.
387
+ * @param params.FriendlyDeviceName Optional friendly name for the device.
388
+ * @returns
389
+ */
301
390
  async associateSoftwareToken(params) {
302
391
  return cognitoRequest(params, ServiceTarget.AssociateSoftwareToken, this.cognitoEndpoint);
303
392
  }
393
+ /**
394
+ * Verifies a software token.
395
+ * @param params Request to verify a software token.
396
+ * @param params.AccessToken Access token of the current user.
397
+ * @param params.FriendlyDeviceName Optional friendly name for the device.
398
+ * @param params.Session Optional session identifier for the authentication process.
399
+ * @param params.UserCode The user code to verify.
400
+ * @returns
401
+ */
304
402
  async verifySoftwareToken(params) {
305
403
  return cognitoRequest(params, ServiceTarget.VerifySoftwareToken, this.cognitoEndpoint);
306
404
  }
@@ -439,6 +537,51 @@ export class CognitoClient {
439
537
  };
440
538
  await cognitoRequest(resendConfirmationCodeRequest, ServiceTarget.ResendConfirmationCode, this.cognitoEndpoint);
441
539
  }
540
+ 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;
549
+ }
550
+ /**
551
+ * Completes registration of a passkey authenticator for the currently signed-in user.
552
+ * @param request Request to complete WebAuthn registration.
553
+ * @param request.AccessToken Access token of the current user.
554
+ * @param request.Credential The credential object returned by the WebAuthn API.
555
+ */
556
+ async completeWebAuthnRegistration(request) {
557
+ await cognitoRequest({
558
+ AccessToken: request.AccessToken,
559
+ Credential: publicKeyCredentialToJSON(request.Credential)
560
+ }, ServiceTarget.CompleteWebAuthnRegistration, this.cognitoEndpoint);
561
+ }
562
+ /**
563
+ * Deletes a registered passkey, or WebAuthn, authenticator for the currently signed-in user.
564
+ *
565
+ * @param request Request to delete a WebAuthn credential.
566
+ * @param request.AccessToken Access token of the current user.
567
+ * @param request.CredentialId The ID of the credential to delete.
568
+ */
569
+ async deleteWebAuthnCredential(request) {
570
+ await cognitoRequest(request, ServiceTarget.DeleteWebAuthnCredential, this.cognitoEndpoint);
571
+ }
572
+ /**
573
+ * Lists all registered WebAuthn credentials for the currently signed-in user.
574
+ *
575
+ * @param request Request to list WebAuthn credentials.
576
+ * @param request.AccessToken Access token of the current user.
577
+ * @param request.MaxResults Maximum number of credentials to return.
578
+ * @param request.NextToken Pagination token to continue listing credentials.
579
+ * @returns
580
+ */
581
+ async listWebAuthnCredentials(request) {
582
+ const response = await cognitoRequest(request, ServiceTarget.ListWebAuthnCredentials, this.cognitoEndpoint);
583
+ return response;
584
+ }
442
585
  /**
443
586
  * Returns a link to Cognito`s Hosted UI for OAuth2 authentication.
444
587
  * This method works in conjunction with @see handleCodeFlow .
package/lib/error.js CHANGED
@@ -401,6 +401,8 @@ export var RevokeTokenException;
401
401
  RevokeTokenException["UnsupportedTokenTypeException"] = "UnsupportedTokenTypeException";
402
402
  })(RevokeTokenException || (RevokeTokenException = {}));
403
403
  export class CognitoError extends Error {
404
+ errorType;
405
+ cognitoException;
404
406
  constructor(message, errorType, cognitoException) {
405
407
  super(message);
406
408
  this.errorType = errorType;
@@ -408,108 +410,126 @@ export class CognitoError extends Error {
408
410
  }
409
411
  }
410
412
  export class CommonError extends CognitoError {
413
+ cognitoException;
411
414
  constructor(message, cognitoException) {
412
415
  super(message, 'CommonError', cognitoException);
413
416
  this.cognitoException = cognitoException;
414
417
  }
415
418
  }
416
419
  export class InitAuthError extends CognitoError {
420
+ cognitoException;
417
421
  constructor(message, cognitoException) {
418
422
  super(message, 'InitAuthError', cognitoException);
419
423
  this.cognitoException = cognitoException;
420
424
  }
421
425
  }
422
426
  export class RespondToAuthChallengeError extends CognitoError {
427
+ cognitoException;
423
428
  constructor(message, cognitoException) {
424
429
  super(message, 'RespondToAuthChallengeError', cognitoException);
425
430
  this.cognitoException = cognitoException;
426
431
  }
427
432
  }
428
433
  export class SignUpError extends CognitoError {
434
+ cognitoException;
429
435
  constructor(message, cognitoException) {
430
436
  super(message, 'SignUpError', cognitoException);
431
437
  this.cognitoException = cognitoException;
432
438
  }
433
439
  }
434
440
  export class ConfirmSignUpError extends CognitoError {
441
+ cognitoException;
435
442
  constructor(message, cognitoException) {
436
443
  super(message, 'ConfirmSignUpError', cognitoException);
437
444
  this.cognitoException = cognitoException;
438
445
  }
439
446
  }
440
447
  export class ChangePasswordError extends CognitoError {
448
+ cognitoException;
441
449
  constructor(message, cognitoException) {
442
450
  super(message, 'ChangePasswordError', cognitoException);
443
451
  this.cognitoException = cognitoException;
444
452
  }
445
453
  }
446
454
  export class RevokeTokenError extends CognitoError {
455
+ cognitoException;
447
456
  constructor(message, cognitoException) {
448
457
  super(message, 'RevokeTokenError', cognitoException);
449
458
  this.cognitoException = cognitoException;
450
459
  }
451
460
  }
452
461
  export class ForgotPasswordError extends CognitoError {
462
+ cognitoException;
453
463
  constructor(message, cognitoException) {
454
464
  super(message, 'ForgotPasswordError', cognitoException);
455
465
  this.cognitoException = cognitoException;
456
466
  }
457
467
  }
458
468
  export class ConfirmForgotPasswordError extends CognitoError {
469
+ cognitoException;
459
470
  constructor(message, cognitoException) {
460
471
  super(message, 'ConfirmForgotPasswordError', cognitoException);
461
472
  this.cognitoException = cognitoException;
462
473
  }
463
474
  }
464
475
  export class ResendConfirmationCodeError extends CognitoError {
476
+ cognitoException;
465
477
  constructor(message, cognitoException) {
466
478
  super(message, 'ResendConfirmationCodeError', cognitoException);
467
479
  this.cognitoException = cognitoException;
468
480
  }
469
481
  }
470
482
  export class UpdateUserAttributesError extends CognitoError {
483
+ cognitoException;
471
484
  constructor(message, cognitoException) {
472
485
  super(message, 'UpdateUserAttributesError', cognitoException);
473
486
  this.cognitoException = cognitoException;
474
487
  }
475
488
  }
476
489
  export class VerifyUserAttributeError extends CognitoError {
490
+ cognitoException;
477
491
  constructor(message, cognitoException) {
478
492
  super(message, 'VerifyUserAttributeError', cognitoException);
479
493
  this.cognitoException = cognitoException;
480
494
  }
481
495
  }
482
496
  export class GlobalSignOutError extends CognitoError {
497
+ cognitoException;
483
498
  constructor(message, cognitoException) {
484
499
  super(message, 'GlobalSignOutError', cognitoException);
485
500
  this.cognitoException = cognitoException;
486
501
  }
487
502
  }
488
503
  export class VerifySoftwareTokenError extends CognitoError {
504
+ cognitoException;
489
505
  constructor(message, cognitoException) {
490
506
  super(message, 'VerifySoftwareTokenError', cognitoException);
491
507
  this.cognitoException = cognitoException;
492
508
  }
493
509
  }
494
510
  export class AssociateSoftwareTokenError extends CognitoError {
511
+ cognitoException;
495
512
  constructor(message, cognitoException) {
496
513
  super(message, 'AssociateSoftwareTokenError', cognitoException);
497
514
  this.cognitoException = cognitoException;
498
515
  }
499
516
  }
500
517
  export class SetUserMFAPreferenceError extends CognitoError {
518
+ cognitoException;
501
519
  constructor(message, cognitoException) {
502
520
  super(message, 'SetUserMFAPreferenceError', cognitoException);
503
521
  this.cognitoException = cognitoException;
504
522
  }
505
523
  }
506
524
  export class ListDevicesError extends CognitoError {
525
+ cognitoException;
507
526
  constructor(message, cognitoException) {
508
527
  super(message, 'ListDevicesError', cognitoException);
509
528
  this.cognitoException = cognitoException;
510
529
  }
511
530
  }
512
531
  export class GetUserError extends CognitoError {
532
+ cognitoException;
513
533
  constructor(message, cognitoException) {
514
534
  super(message, 'GetUserError', cognitoException);
515
535
  this.cognitoException = cognitoException;
package/lib/index.d.ts CHANGED
@@ -1,2 +1,3 @@
1
1
  export * from './cognito-client.js';
2
2
  export * from './error.js';
3
+ export * from './utils.js';
package/lib/index.js CHANGED
@@ -1,2 +1,3 @@
1
1
  export * from './cognito-client.js';
2
2
  export * from './error.js';
3
+ export * from './utils.js';
package/lib/utils.d.ts CHANGED
@@ -1,9 +1,13 @@
1
1
  /// <reference types="node" resolution-mode="require"/>
2
+ /// <reference types="node" resolution-mode="require"/>
2
3
  export declare function uint8ArrayFromHexString(hexString: string): Uint8Array;
3
4
  export declare function uint8ArrayFromString(str: string): Uint8Array;
4
5
  export declare function uint8ArrayFromBase64String(str: string): Uint8Array;
5
6
  export declare function uint8ArrayToHexString(bytes: Uint8Array): string;
6
- export declare function uint8ArrayToBase64String(bytes: Uint8Array): string;
7
+ export declare function uint8ArrayToBase64String(bytes: Uint8Array | ArrayBuffer): string;
8
+ export declare function uint8ArrayToBase64UrlString(bytes: Uint8Array | ArrayBuffer | undefined): string | undefined;
9
+ export declare function base64UrlToUint8Array(base64: string): Uint8Array;
10
+ export declare function publicKeyCredentialToJSON(cred: any): any;
7
11
  export declare function padHex(bigInt: bigint): string;
8
12
  export declare function hashHexString(str: string): Promise<string>;
9
13
  export declare function hashBuffer(buffer: Uint8Array): Promise<string>;
@@ -27,3 +31,4 @@ export declare function formatTimestamp(date: Date): string;
27
31
  export declare function calculateSecretHash(clientSecret: string, userPoolClientId: string, username: string): Promise<string>;
28
32
  export declare function digest(algorithm: AlgorithmIdentifier, data: Uint8Array): Promise<Uint8Array>;
29
33
  export declare function hmac(algorithm: AlgorithmIdentifier, key: Uint8Array, data: Uint8Array): Promise<Uint8Array>;
34
+ export declare function removeUndefined(obj: any): any;
package/lib/utils.js CHANGED
@@ -20,8 +20,49 @@ export function uint8ArrayToHexString(bytes) {
20
20
  return bytes.reduce((str, byte) => str + byte.toString(16).padStart(2, '0'), '');
21
21
  }
22
22
  export function uint8ArrayToBase64String(bytes) {
23
+ if (bytes instanceof ArrayBuffer) {
24
+ const byteArray = new Uint8Array(bytes);
25
+ return btoa(String.fromCharCode(...byteArray));
26
+ }
23
27
  return btoa(String.fromCharCode(...bytes));
24
28
  }
29
+ export function uint8ArrayToBase64UrlString(bytes) {
30
+ if (bytes === undefined) {
31
+ return undefined;
32
+ }
33
+ const base64String = uint8ArrayToBase64String(bytes);
34
+ return base64String.replaceAll('+', '-').replaceAll('/', '_').replace(/=+$/, '');
35
+ }
36
+ export function base64UrlToUint8Array(base64) {
37
+ const binary = atob(base64.replace(/-/g, '+').replace(/_/g, '/'));
38
+ const len = binary.length;
39
+ const bytes = new Uint8Array(len);
40
+ for (let i = 0; i < len; i++) {
41
+ bytes[i] = binary.charCodeAt(i);
42
+ }
43
+ return bytes;
44
+ }
45
+ export function publicKeyCredentialToJSON(cred) {
46
+ return removeUndefined({
47
+ authenticatorAttachment: cred.authenticatorAttachment,
48
+ clientExtensionResults: cred.getClientExtensionResults(),
49
+ id: cred.id,
50
+ rawId: uint8ArrayToBase64UrlString(cred.rawId),
51
+ response: {
52
+ attestationObject: uint8ArrayToBase64UrlString(cred.response.attestationObject),
53
+ authenticatorData: cred.response.authenticatorData
54
+ ? uint8ArrayToBase64UrlString(cred.response.authenticatorData)
55
+ : undefined,
56
+ clientDataJSON: uint8ArrayToBase64UrlString(cred.response.clientDataJSON),
57
+ publicKey: cred.response.getPublicKey ? uint8ArrayToBase64UrlString(cred.response.getPublicKey()) : undefined,
58
+ publicKeyAlgorithm: cred.response.getPublicKeyAlgorithm ? cred.response.getPublicKeyAlgorithm() : undefined,
59
+ transports: cred.response.getTransports ? cred.response.getTransports() : undefined,
60
+ signature: cred.response.signature ? uint8ArrayToBase64UrlString(cred.response.signature) : undefined,
61
+ userHandle: cred.response.userHandle ? uint8ArrayToBase64UrlString(cred.response.userHandle) : undefined
62
+ },
63
+ type: cred.type
64
+ });
65
+ }
25
66
  const N = BigInt('0xFFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1' +
26
67
  '29024E088A67CC74020BBEA63B139B22514A08798E3404DD' +
27
68
  'EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245' +
@@ -151,3 +192,18 @@ export async function hmac(algorithm, key, data) {
151
192
  const signature = await crypto.subtle.sign('HMAC', cryptoKey, data);
152
193
  return new Uint8Array(signature);
153
194
  }
195
+ export function removeUndefined(obj) {
196
+ if (Array.isArray(obj)) {
197
+ return obj.map(item => removeUndefined(item)).filter(item => item !== undefined);
198
+ }
199
+ if (obj !== null && typeof obj === 'object') {
200
+ return Object.entries(obj).reduce((acc, [key, value]) => {
201
+ const cleaned = removeUndefined(value);
202
+ if (cleaned !== undefined) {
203
+ acc[key] = cleaned;
204
+ }
205
+ return acc;
206
+ }, {});
207
+ }
208
+ return obj !== undefined ? obj : undefined;
209
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vardario/cognito-client",
3
- "version": "5.1.0",
3
+ "version": "5.2.1",
4
4
  "description": "",
5
5
  "license": "MIT",
6
6
  "author": "Sahin Vardar",
@@ -27,7 +27,7 @@
27
27
  "devDependencies": {
28
28
  "@aws-sdk/client-cognito-identity-provider": "^3.465.0",
29
29
  "@types/jsdom": "^21.1.5",
30
- "@types/node": "^20",
30
+ "@types/node": "^24",
31
31
  "@typescript-eslint/eslint-plugin": "^6.11.0",
32
32
  "@typescript-eslint/parser": "^6.11.0",
33
33
  "esbuild": "^0.25.8",
@@ -36,15 +36,15 @@
36
36
  "eslint-plugin-unused-imports": "^4.1.4",
37
37
  "husky": "^8.0.3",
38
38
  "isomorphic-fetch": "^3.0.0",
39
- "jsdom": "^22.1.0",
40
- "lint-staged": "^15.1.0",
39
+ "jsdom": "^26.1.0",
40
+ "lint-staged": "^16.1.4",
41
41
  "prettier": "^3.1.0",
42
42
  "prettier-package-json": "^2.8.0",
43
- "semantic-release": "^22.0.8",
44
- "testcontainers": "^10.2.2",
43
+ "semantic-release": "^24.2.7",
44
+ "testcontainers": "^11.5.1",
45
45
  "tsx": "^4.7.1",
46
46
  "typescript": "^5.2.2",
47
- "vitest": "^0.34.6",
47
+ "vitest": "^3.2.4",
48
48
  "vitest-fetch-mock": "^0.2.2"
49
49
  },
50
50
  "lint-staged": {