@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 +58 -68
- package/lib/cognito-client.d.ts +23 -13
- package/lib/cognito-client.js +25 -52
- package/lib/utils.d.ts +3 -0
- package/lib/utils.js +18 -0
- package/package.json +3 -3
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
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
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
|
|
1020
|
-
if (
|
|
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: " +
|
|
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:
|
|
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:
|
|
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
|
-
|
|
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:
|
|
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
|
|
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,
|
package/lib/cognito-client.d.ts
CHANGED
|
@@ -140,8 +140,16 @@ export interface _RespondToAuthChallengeWebAuthnRequest extends RespondToAuthCha
|
|
|
140
140
|
SECRET_HASH?: string;
|
|
141
141
|
};
|
|
142
142
|
}
|
|
143
|
-
|
|
144
|
-
|
|
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:
|
|
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:
|
|
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
|
/**
|
package/lib/cognito-client.js
CHANGED
|
@@ -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 {
|
|
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
|
|
138
|
+
const _request = {
|
|
146
139
|
...request,
|
|
147
140
|
ClientId: this.userPoolClientId
|
|
148
|
-
}
|
|
149
|
-
if (
|
|
150
|
-
|
|
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
|
|
238
|
-
if (
|
|
239
|
-
throw new InitAuthError('Authentication failed, expected WEB_AUTHN challenge but received: ' +
|
|
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:
|
|
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:
|
|
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
|
-
|
|
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:
|
|
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
|
|
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.
|
|
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": "^
|
|
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@
|
|
57
|
+
"packageManager": "pnpm@9.1.0",
|
|
58
58
|
"release": {
|
|
59
59
|
"branches": [
|
|
60
60
|
"release"
|