@vardario/cognito-client 0.1.8 → 0.2.0
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/README.md +3 -0
- package/lib/cognito-client.d.ts +30 -45
- package/lib/cognito-client.js +106 -149
- package/lib/error.d.ts +93 -31
- package/lib/error.js +96 -46
- package/lib/index.d.ts +0 -1
- package/lib/index.js +0 -1
- package/lib/utils.d.ts +3 -3
- package/lib/utils.js +60 -54
- package/package.json +37 -19
- package/lib/cognito-client.test.d.ts +0 -1
- package/lib/cognito-client.test.js +0 -99
- package/lib/session-storage/cookie-session-storage/cookie-session-storage.d.ts +0 -21
- package/lib/session-storage/cookie-session-storage/cookie-session-storage.js +0 -42
- package/lib/session-storage/cookie-session-storage/index.d.ts +0 -1
- package/lib/session-storage/cookie-session-storage/index.js +0 -1
- package/lib/session-storage/index.d.ts +0 -4
- package/lib/session-storage/index.js +0 -4
- package/lib/session-storage/local-storage-session-storage.d.ts +0 -20
- package/lib/session-storage/local-storage-session-storage.js +0 -38
- package/lib/session-storage/memory-session-storage.d.ts +0 -13
- package/lib/session-storage/memory-session-storage.js +0 -18
- package/lib/session-storage/session-storage.d.ts +0 -14
- package/lib/session-storage/session-storage.js +0 -5
- package/lib/session-storage/session-storage.test.d.ts +0 -1
- package/lib/session-storage/session-storage.test.js +0 -33
- package/lib/test-utils.d.ts +0 -17
- package/lib/test-utils.js +0 -81
package/README.md
ADDED
package/lib/cognito-client.d.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { SessionStorage } from "./session-storage/index.js";
|
|
2
1
|
export interface UserAttribute {
|
|
3
2
|
Name: string;
|
|
4
3
|
Value: string;
|
|
@@ -23,7 +22,7 @@ export interface OAuth2Props {
|
|
|
23
22
|
/**
|
|
24
23
|
* Response type.
|
|
25
24
|
*/
|
|
26
|
-
responseType:
|
|
25
|
+
responseType: 'code';
|
|
27
26
|
}
|
|
28
27
|
export interface CognitoClientProps {
|
|
29
28
|
/**
|
|
@@ -40,21 +39,6 @@ export interface CognitoClientProps {
|
|
|
40
39
|
* If not defined the endpoint will be determined by @see userPoolId .
|
|
41
40
|
*/
|
|
42
41
|
endpoint?: string;
|
|
43
|
-
/**
|
|
44
|
-
* Session storage.
|
|
45
|
-
* You can either choose on of the provided build in session
|
|
46
|
-
* storages. Or provider your own one based on @see SessionStorage .
|
|
47
|
-
*
|
|
48
|
-
* <ul>
|
|
49
|
-
* <li>
|
|
50
|
-
* @see CookieSessionStorage
|
|
51
|
-
* </li>
|
|
52
|
-
* <li>
|
|
53
|
-
* @see MemorySessionStorage
|
|
54
|
-
* </li>
|
|
55
|
-
* </ul>
|
|
56
|
-
*/
|
|
57
|
-
sessionStorage: SessionStorage;
|
|
58
42
|
/**
|
|
59
43
|
* Cognito OAuth related options. See @see OAuthProps .
|
|
60
44
|
*/
|
|
@@ -85,15 +69,15 @@ export interface Session {
|
|
|
85
69
|
* Represents the decoded values from a JWT ID token.
|
|
86
70
|
*/
|
|
87
71
|
export interface IdToken extends Record<string, string | string[] | number | boolean> {
|
|
88
|
-
|
|
89
|
-
|
|
72
|
+
'cognito:username': string;
|
|
73
|
+
'cognito:groups': string[];
|
|
90
74
|
email_verified: boolean;
|
|
91
75
|
email: string;
|
|
92
76
|
iss: string;
|
|
93
77
|
origin_jti: string;
|
|
94
78
|
aud: string;
|
|
95
79
|
event_id: string;
|
|
96
|
-
token_use:
|
|
80
|
+
token_use: 'id';
|
|
97
81
|
auth_time: number;
|
|
98
82
|
exp: number;
|
|
99
83
|
iat: number;
|
|
@@ -111,7 +95,7 @@ export interface AccessToken extends Record<string, string | string[] | number |
|
|
|
111
95
|
origin_jti: string;
|
|
112
96
|
scope: string;
|
|
113
97
|
sub: string;
|
|
114
|
-
token_use:
|
|
98
|
+
token_use: 'access';
|
|
115
99
|
username: string;
|
|
116
100
|
}
|
|
117
101
|
export interface DecodedTokens {
|
|
@@ -157,7 +141,7 @@ export interface AuthenticationResponse {
|
|
|
157
141
|
AuthenticationResult: AuthenticationResult;
|
|
158
142
|
}
|
|
159
143
|
export interface ChallengeResponse {
|
|
160
|
-
ChallengeName:
|
|
144
|
+
ChallengeName: 'PASSWORD_VERIFIER';
|
|
161
145
|
ChallengeParameters: {
|
|
162
146
|
SALT: string;
|
|
163
147
|
SECRET_BLOCK: string;
|
|
@@ -173,9 +157,8 @@ export declare class CognitoClient {
|
|
|
173
157
|
private readonly cognitoEndpoint;
|
|
174
158
|
private readonly cognitoPoolName;
|
|
175
159
|
private readonly userPoolClientId;
|
|
176
|
-
private readonly sessionStorage;
|
|
177
160
|
private readonly oAuth?;
|
|
178
|
-
constructor({ userPoolId, userPoolClientId, endpoint,
|
|
161
|
+
constructor({ userPoolId, userPoolClientId, endpoint, oAuth2: oAuth }: CognitoClientProps);
|
|
179
162
|
static getDecodedTokenFromSession(session: Session): DecodedTokens;
|
|
180
163
|
private cognitoRequest;
|
|
181
164
|
private static authResultToSession;
|
|
@@ -186,7 +169,7 @@ export declare class CognitoClient {
|
|
|
186
169
|
*
|
|
187
170
|
* @param username Username
|
|
188
171
|
* @param password Password
|
|
189
|
-
* @throws {
|
|
172
|
+
* @throws {CognitoException}
|
|
190
173
|
*/
|
|
191
174
|
authenticateUserSrp(username: string, password: string): Promise<Session>;
|
|
192
175
|
/**
|
|
@@ -196,25 +179,23 @@ export declare class CognitoClient {
|
|
|
196
179
|
*
|
|
197
180
|
* @param username Username
|
|
198
181
|
* @param password Password
|
|
199
|
-
* @throws {
|
|
182
|
+
* @throws {CognitoException}
|
|
200
183
|
*/
|
|
201
184
|
authenticateUser(username: string, password: string): Promise<Session>;
|
|
202
|
-
private refreshSession;
|
|
203
185
|
/**
|
|
204
|
-
* Returns the
|
|
205
|
-
* The auth session is only defined when we previously had a successful user authentication.
|
|
206
|
-
* This function will also take care to refresh the session with the refresh token in case
|
|
207
|
-
* the current session has expired.
|
|
186
|
+
* Returns a new session based on the given refresh token.
|
|
208
187
|
*
|
|
209
|
-
* @
|
|
188
|
+
* @param refreshToken
|
|
189
|
+
* @returns @see Session
|
|
190
|
+
* @throws {CognitoError}
|
|
210
191
|
*/
|
|
211
|
-
|
|
192
|
+
refreshSession(refreshToken: string): Promise<Session>;
|
|
212
193
|
/**
|
|
213
194
|
*
|
|
214
195
|
* @param username Username
|
|
215
196
|
* @param password Password
|
|
216
197
|
*
|
|
217
|
-
* @throws {
|
|
198
|
+
* @throws {CognitoException}
|
|
218
199
|
*/
|
|
219
200
|
signUp(username: string, password: string, userAttributes?: UserAttribute[]): Promise<{
|
|
220
201
|
id: string;
|
|
@@ -226,7 +207,7 @@ export declare class CognitoClient {
|
|
|
226
207
|
* @param username Username
|
|
227
208
|
* @param code Confirmation code the user gets through the registration E-Mail
|
|
228
209
|
*
|
|
229
|
-
* @throws {
|
|
210
|
+
* @throws {CognitoException}
|
|
230
211
|
*/
|
|
231
212
|
confirmSignUp(username: string, code: string): Promise<void>;
|
|
232
213
|
/**
|
|
@@ -234,22 +215,22 @@ export declare class CognitoClient {
|
|
|
234
215
|
* @param currentPassword Current user password.
|
|
235
216
|
* @param newPassword New user password.
|
|
236
217
|
*
|
|
237
|
-
* @throws {
|
|
218
|
+
* @throws {CognitoException}
|
|
238
219
|
*/
|
|
239
|
-
changePassword(currentPassword: string, newPassword: string): Promise<void>;
|
|
240
|
-
updateUserAttributes(userAttributes: UserAttribute[]): Promise<void>;
|
|
241
|
-
verifyUserAttribute(attributeName: string, code: string): Promise<void>;
|
|
220
|
+
changePassword(currentPassword: string, newPassword: string, accessToken: string): Promise<void>;
|
|
221
|
+
updateUserAttributes(userAttributes: UserAttribute[], accessToken: string): Promise<void>;
|
|
222
|
+
verifyUserAttribute(attributeName: string, code: string, accessToken: string): Promise<void>;
|
|
242
223
|
/**
|
|
243
224
|
* Sign out the user and remove the current user session.
|
|
244
225
|
*
|
|
245
|
-
* @throws {
|
|
226
|
+
* @throws {CognitoException}
|
|
246
227
|
*/
|
|
247
|
-
signOut(): Promise<void>;
|
|
228
|
+
signOut(refreshToken: string): Promise<void>;
|
|
248
229
|
/**
|
|
249
230
|
* Request forgot password.
|
|
250
231
|
* @param username Username
|
|
251
232
|
*
|
|
252
|
-
* @throws {
|
|
233
|
+
* @throws {CognitoException}
|
|
253
234
|
*/
|
|
254
235
|
forgotPassword(username: string): Promise<void>;
|
|
255
236
|
/**
|
|
@@ -259,7 +240,7 @@ export declare class CognitoClient {
|
|
|
259
240
|
* @param newPassword New password
|
|
260
241
|
* @param confirmationCode Confirmation code which the user got through E-mail
|
|
261
242
|
*
|
|
262
|
-
* @throws {
|
|
243
|
+
* @throws {CognitoException}
|
|
263
244
|
*/
|
|
264
245
|
confirmForgotPassword(username: string, newPassword: string, confirmationCode: string): Promise<void>;
|
|
265
246
|
/**
|
|
@@ -276,7 +257,11 @@ export declare class CognitoClient {
|
|
|
276
257
|
*
|
|
277
258
|
* @throws {Error}
|
|
278
259
|
*/
|
|
279
|
-
generateOAuthSignInUrl(identityProvider?: CognitoIdentityProvider): Promise<
|
|
260
|
+
generateOAuthSignInUrl(identityProvider?: CognitoIdentityProvider): Promise<{
|
|
261
|
+
url: string;
|
|
262
|
+
state: string;
|
|
263
|
+
pkce: string;
|
|
264
|
+
}>;
|
|
280
265
|
/**
|
|
281
266
|
*
|
|
282
267
|
* Handles Cognito`s OAuth2 code flow after redirection from Cognito`s Hosted UI.
|
|
@@ -288,5 +273,5 @@ export declare class CognitoClient {
|
|
|
288
273
|
*
|
|
289
274
|
* @throws {Error}
|
|
290
275
|
*/
|
|
291
|
-
handleCodeFlow(returnUrl: string): Promise<Session>;
|
|
276
|
+
handleCodeFlow(returnUrl: string, pkce: string): Promise<Session>;
|
|
292
277
|
}
|
package/lib/cognito-client.js
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import { calculateSignature, calculateU, decodeJwt, generateA, generateSmallA, getPasswordAuthenticationKey, randomBytes, } from "./utils.js";
|
|
1
|
+
import hashJs from 'hash.js';
|
|
2
|
+
import { BigInteger } from 'jsbn';
|
|
3
|
+
import { Buffer } from 'buffer';
|
|
4
|
+
import { CognitoError, CognitoException } from './error.js';
|
|
5
|
+
import { calculateSignature, calculateU, decodeJwt, generateA, generateSmallA, getPasswordAuthenticationKey, randomBytes } from './utils.js';
|
|
7
6
|
/**
|
|
8
7
|
* List of used and supported Cognito API calls.
|
|
9
8
|
* @see https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_Operations.html for more details
|
|
@@ -38,12 +37,11 @@ export var CognitoIdentityProvider;
|
|
|
38
37
|
* Lightweight AWS Cogito client without any AWS SDK dependencies.
|
|
39
38
|
*/
|
|
40
39
|
export class CognitoClient {
|
|
41
|
-
constructor({ userPoolId, userPoolClientId, endpoint,
|
|
42
|
-
const [cognitoPoolRegion, cognitoPoolName] = userPoolId.split(
|
|
43
|
-
this.cognitoEndpoint = (endpoint || `https://cognito-idp.${cognitoPoolRegion}.amazonaws.com`).replace(/\/$/,
|
|
40
|
+
constructor({ userPoolId, userPoolClientId, endpoint, oAuth2: oAuth }) {
|
|
41
|
+
const [cognitoPoolRegion, cognitoPoolName] = userPoolId.split('_');
|
|
42
|
+
this.cognitoEndpoint = (endpoint || `https://cognito-idp.${cognitoPoolRegion}.amazonaws.com`).replace(/\/$/, '');
|
|
44
43
|
this.cognitoPoolName = cognitoPoolName;
|
|
45
44
|
this.userPoolClientId = userPoolClientId;
|
|
46
|
-
this.sessionStorage = sessionStorage;
|
|
47
45
|
this.oAuth = oAuth;
|
|
48
46
|
}
|
|
49
47
|
static getDecodedTokenFromSession(session) {
|
|
@@ -51,31 +49,31 @@ export class CognitoClient {
|
|
|
51
49
|
const { payload: accessToken } = decodeJwt(session.accessToken);
|
|
52
50
|
return {
|
|
53
51
|
idToken,
|
|
54
|
-
accessToken
|
|
52
|
+
accessToken
|
|
55
53
|
};
|
|
56
54
|
}
|
|
57
55
|
async cognitoRequest(body, serviceTarget) {
|
|
58
|
-
const
|
|
56
|
+
const cognitoResponse = await fetch(this.cognitoEndpoint, {
|
|
59
57
|
headers: {
|
|
60
|
-
|
|
61
|
-
|
|
58
|
+
'x-amz-target': `AWSCognitoIdentityProviderService.${serviceTarget}`,
|
|
59
|
+
'content-type': 'application/x-amz-json-1.1'
|
|
62
60
|
},
|
|
63
|
-
method:
|
|
64
|
-
body: JSON.stringify(body)
|
|
61
|
+
method: 'POST',
|
|
62
|
+
body: JSON.stringify(body)
|
|
65
63
|
});
|
|
66
|
-
if (
|
|
67
|
-
|
|
68
|
-
const
|
|
69
|
-
throw
|
|
64
|
+
if (cognitoResponse.status < 200 || cognitoResponse.status > 299) {
|
|
65
|
+
const errorMessage = cognitoResponse.headers.get('X-Amzn-ErrorMessage') ?? 'Unknown';
|
|
66
|
+
const cognitoException = cognitoResponse.headers.get('X-Amzn-ErrorType') ?? CognitoException.Unknown;
|
|
67
|
+
throw new CognitoError(errorMessage, cognitoException);
|
|
70
68
|
}
|
|
71
|
-
return
|
|
69
|
+
return cognitoResponse.json();
|
|
72
70
|
}
|
|
73
71
|
static authResultToSession(authenticationResult) {
|
|
74
72
|
return {
|
|
75
73
|
accessToken: authenticationResult.AccessToken,
|
|
76
74
|
idToken: authenticationResult.IdToken,
|
|
77
|
-
expiresIn:
|
|
78
|
-
refreshToken: authenticationResult.RefreshToken
|
|
75
|
+
expiresIn: new Date().getMilliseconds() / 1000 + authenticationResult.ExpiresIn,
|
|
76
|
+
refreshToken: authenticationResult.RefreshToken
|
|
79
77
|
};
|
|
80
78
|
}
|
|
81
79
|
/**
|
|
@@ -85,19 +83,19 @@ export class CognitoClient {
|
|
|
85
83
|
*
|
|
86
84
|
* @param username Username
|
|
87
85
|
* @param password Password
|
|
88
|
-
* @throws {
|
|
86
|
+
* @throws {CognitoException}
|
|
89
87
|
*/
|
|
90
88
|
async authenticateUserSrp(username, password) {
|
|
91
89
|
const smallA = await generateSmallA();
|
|
92
90
|
const A = generateA(smallA);
|
|
93
91
|
const initiateAuthPayload = {
|
|
94
|
-
AuthFlow:
|
|
92
|
+
AuthFlow: 'USER_SRP_AUTH',
|
|
95
93
|
ClientId: this.userPoolClientId,
|
|
96
94
|
AuthParameters: {
|
|
97
95
|
USERNAME: username,
|
|
98
|
-
SRP_A: A.toString(16)
|
|
96
|
+
SRP_A: A.toString(16)
|
|
99
97
|
},
|
|
100
|
-
ClientMetadata: {}
|
|
98
|
+
ClientMetadata: {}
|
|
101
99
|
};
|
|
102
100
|
const challenge = (await this.cognitoRequest(initiateAuthPayload, CognitoServiceTarget.InitiateAuth));
|
|
103
101
|
const B = new BigInteger(challenge.ChallengeParameters.SRP_B, 16);
|
|
@@ -106,20 +104,18 @@ export class CognitoClient {
|
|
|
106
104
|
const hkdf = getPasswordAuthenticationKey(this.cognitoPoolName, challenge.ChallengeParameters.USER_ID_FOR_SRP, password, B, U, smallA, salt);
|
|
107
105
|
const { signature, timeStamp } = calculateSignature(this.cognitoPoolName, challenge.ChallengeParameters.USER_ID_FOR_SRP, challenge.ChallengeParameters.SECRET_BLOCK, hkdf);
|
|
108
106
|
const respondToAuthChallengePayload = {
|
|
109
|
-
ChallengeName:
|
|
107
|
+
ChallengeName: 'PASSWORD_VERIFIER',
|
|
110
108
|
ClientId: this.userPoolClientId,
|
|
111
109
|
ChallengeResponses: {
|
|
112
110
|
PASSWORD_CLAIM_SECRET_BLOCK: challenge.ChallengeParameters.SECRET_BLOCK,
|
|
113
111
|
PASSWORD_CLAIM_SIGNATURE: signature,
|
|
114
112
|
USERNAME: challenge.ChallengeParameters.USER_ID_FOR_SRP,
|
|
115
|
-
TIMESTAMP: timeStamp
|
|
113
|
+
TIMESTAMP: timeStamp
|
|
116
114
|
},
|
|
117
|
-
ClientMetadata: {}
|
|
115
|
+
ClientMetadata: {}
|
|
118
116
|
};
|
|
119
117
|
const { AuthenticationResult } = await this.cognitoRequest(respondToAuthChallengePayload, CognitoServiceTarget.RespondToAuthChallenge);
|
|
120
|
-
|
|
121
|
-
this.sessionStorage.setSession(session);
|
|
122
|
-
return session;
|
|
118
|
+
return CognitoClient.authResultToSession(AuthenticationResult);
|
|
123
119
|
}
|
|
124
120
|
/**
|
|
125
121
|
*
|
|
@@ -128,75 +124,62 @@ export class CognitoClient {
|
|
|
128
124
|
*
|
|
129
125
|
* @param username Username
|
|
130
126
|
* @param password Password
|
|
131
|
-
* @throws {
|
|
127
|
+
* @throws {CognitoException}
|
|
132
128
|
*/
|
|
133
129
|
async authenticateUser(username, password) {
|
|
134
130
|
const initiateAuthPayload = {
|
|
135
|
-
AuthFlow:
|
|
131
|
+
AuthFlow: 'USER_PASSWORD_AUTH',
|
|
136
132
|
ClientId: this.userPoolClientId,
|
|
137
133
|
AuthParameters: {
|
|
138
134
|
USERNAME: username,
|
|
139
|
-
PASSWORD: password
|
|
135
|
+
PASSWORD: password
|
|
140
136
|
},
|
|
141
|
-
ClientMetadata: {}
|
|
137
|
+
ClientMetadata: {}
|
|
142
138
|
};
|
|
143
139
|
const { AuthenticationResult } = (await this.cognitoRequest(initiateAuthPayload, CognitoServiceTarget.InitiateAuth));
|
|
144
140
|
const session = CognitoClient.authResultToSession(AuthenticationResult);
|
|
145
|
-
this.sessionStorage.setSession(session);
|
|
146
141
|
return session;
|
|
147
142
|
}
|
|
148
|
-
|
|
143
|
+
/**
|
|
144
|
+
* Returns a new session based on the given refresh token.
|
|
145
|
+
*
|
|
146
|
+
* @param refreshToken
|
|
147
|
+
* @returns @see Session
|
|
148
|
+
* @throws {CognitoError}
|
|
149
|
+
*/
|
|
150
|
+
async refreshSession(refreshToken) {
|
|
149
151
|
const refreshTokenPayload = {
|
|
150
|
-
AuthFlow:
|
|
152
|
+
AuthFlow: 'REFRESH_TOKEN_AUTH',
|
|
151
153
|
ClientId: this.userPoolClientId,
|
|
152
154
|
AuthParameters: {
|
|
153
|
-
REFRESH_TOKEN:
|
|
155
|
+
REFRESH_TOKEN: refreshToken
|
|
154
156
|
},
|
|
155
|
-
ClientMetadata: {}
|
|
157
|
+
ClientMetadata: {}
|
|
156
158
|
};
|
|
157
159
|
const { AuthenticationResult } = (await this.cognitoRequest(refreshTokenPayload, CognitoServiceTarget.InitiateAuth));
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
RefreshToken: session.refreshToken,
|
|
161
|
-
});
|
|
162
|
-
this.sessionStorage.setSession(newSession);
|
|
163
|
-
return newSession;
|
|
164
|
-
}
|
|
165
|
-
/**
|
|
166
|
-
* Returns the current auth session.
|
|
167
|
-
* The auth session is only defined when we previously had a successful user authentication.
|
|
168
|
-
* This function will also take care to refresh the session with the refresh token in case
|
|
169
|
-
* the current session has expired.
|
|
170
|
-
*
|
|
171
|
-
* @throws {AuthException}
|
|
172
|
-
*/
|
|
173
|
-
async getSession() {
|
|
174
|
-
const session = this.sessionStorage.getSession();
|
|
175
|
-
if (session) {
|
|
176
|
-
if (new Date().getTime() >= session.expiresIn) {
|
|
177
|
-
return this.refreshSession(session);
|
|
178
|
-
}
|
|
160
|
+
if (!AuthenticationResult.RefreshToken) {
|
|
161
|
+
AuthenticationResult.RefreshToken = refreshToken;
|
|
179
162
|
}
|
|
180
|
-
return
|
|
163
|
+
return CognitoClient.authResultToSession(AuthenticationResult);
|
|
181
164
|
}
|
|
182
165
|
/**
|
|
183
166
|
*
|
|
184
167
|
* @param username Username
|
|
185
168
|
* @param password Password
|
|
186
169
|
*
|
|
187
|
-
* @throws {
|
|
170
|
+
* @throws {CognitoException}
|
|
188
171
|
*/
|
|
189
172
|
async signUp(username, password, userAttributes) {
|
|
190
173
|
const signUpPayload = {
|
|
191
174
|
ClientId: this.userPoolClientId,
|
|
192
175
|
Username: username,
|
|
193
176
|
Password: password,
|
|
194
|
-
UserAttributes: userAttributes
|
|
177
|
+
UserAttributes: userAttributes
|
|
195
178
|
};
|
|
196
179
|
const data = await this.cognitoRequest(signUpPayload, CognitoServiceTarget.SignUp);
|
|
197
180
|
return {
|
|
198
181
|
id: data.UserSub,
|
|
199
|
-
confirmed: data.UserConfirmed
|
|
182
|
+
confirmed: data.UserConfirmed
|
|
200
183
|
};
|
|
201
184
|
}
|
|
202
185
|
/**
|
|
@@ -205,85 +188,68 @@ export class CognitoClient {
|
|
|
205
188
|
* @param username Username
|
|
206
189
|
* @param code Confirmation code the user gets through the registration E-Mail
|
|
207
190
|
*
|
|
208
|
-
* @throws {
|
|
191
|
+
* @throws {CognitoException}
|
|
209
192
|
*/
|
|
210
193
|
async confirmSignUp(username, code) {
|
|
211
194
|
const confirmSignUpPayload = {
|
|
212
195
|
ClientId: this.userPoolClientId,
|
|
213
196
|
ConfirmationCode: code,
|
|
214
|
-
Username: username
|
|
197
|
+
Username: username
|
|
215
198
|
};
|
|
216
|
-
|
|
199
|
+
await this.cognitoRequest(confirmSignUpPayload, CognitoServiceTarget.ConfirmSignUp);
|
|
217
200
|
}
|
|
218
201
|
/**
|
|
219
202
|
*
|
|
220
203
|
* @param currentPassword Current user password.
|
|
221
204
|
* @param newPassword New user password.
|
|
222
205
|
*
|
|
223
|
-
* @throws {
|
|
206
|
+
* @throws {CognitoException}
|
|
224
207
|
*/
|
|
225
|
-
async changePassword(currentPassword, newPassword) {
|
|
226
|
-
const session = await this.getSession();
|
|
227
|
-
if (session === undefined) {
|
|
228
|
-
throw new AuthException("User must be authenticated", AuthError.UserNotAuthenticated);
|
|
229
|
-
}
|
|
208
|
+
async changePassword(currentPassword, newPassword, accessToken) {
|
|
230
209
|
const changePasswordPayload = {
|
|
231
210
|
PreviousPassword: currentPassword,
|
|
232
211
|
ProposedPassword: newPassword,
|
|
233
|
-
AccessToken:
|
|
212
|
+
AccessToken: accessToken
|
|
234
213
|
};
|
|
235
|
-
|
|
214
|
+
await this.cognitoRequest(changePasswordPayload, CognitoServiceTarget.ChangePassword);
|
|
236
215
|
}
|
|
237
|
-
async updateUserAttributes(userAttributes) {
|
|
238
|
-
const session = await this.getSession();
|
|
239
|
-
if (session === undefined) {
|
|
240
|
-
throw new AuthException("User must be authenticated", AuthError.UserNotAuthenticated);
|
|
241
|
-
}
|
|
216
|
+
async updateUserAttributes(userAttributes, accessToken) {
|
|
242
217
|
const updateUserAttributesPayload = {
|
|
243
218
|
UserAttributes: userAttributes,
|
|
244
|
-
AccessToken:
|
|
219
|
+
AccessToken: accessToken
|
|
245
220
|
};
|
|
246
|
-
|
|
221
|
+
await this.cognitoRequest(updateUserAttributesPayload, CognitoServiceTarget.UpdateUserAttributes);
|
|
247
222
|
}
|
|
248
|
-
async verifyUserAttribute(attributeName, code) {
|
|
249
|
-
const session = await this.getSession();
|
|
250
|
-
if (session === undefined) {
|
|
251
|
-
throw new AuthException("User must be authenticated", AuthError.UserNotAuthenticated);
|
|
252
|
-
}
|
|
223
|
+
async verifyUserAttribute(attributeName, code, accessToken) {
|
|
253
224
|
const verifyUserAttributePayload = {
|
|
254
225
|
AttributeName: attributeName,
|
|
255
226
|
Code: code,
|
|
256
|
-
AccessToken:
|
|
227
|
+
AccessToken: accessToken
|
|
257
228
|
};
|
|
258
|
-
|
|
229
|
+
await this.cognitoRequest(verifyUserAttributePayload, CognitoServiceTarget.VerifyUserAttribute);
|
|
259
230
|
}
|
|
260
231
|
/**
|
|
261
232
|
* Sign out the user and remove the current user session.
|
|
262
233
|
*
|
|
263
|
-
* @throws {
|
|
234
|
+
* @throws {CognitoException}
|
|
264
235
|
*/
|
|
265
|
-
async signOut() {
|
|
266
|
-
const session = await this.getSession();
|
|
267
|
-
if (session === undefined) {
|
|
268
|
-
throw new AuthException("User must be authenticated", AuthError.UserNotAuthenticated);
|
|
269
|
-
}
|
|
236
|
+
async signOut(refreshToken) {
|
|
270
237
|
const revokeTokenPayload = {
|
|
271
|
-
Token:
|
|
272
|
-
ClientId: this.userPoolClientId
|
|
238
|
+
Token: refreshToken,
|
|
239
|
+
ClientId: this.userPoolClientId
|
|
273
240
|
};
|
|
274
|
-
this.sessionStorage.setSession(undefined);
|
|
275
241
|
await this.cognitoRequest(revokeTokenPayload, CognitoServiceTarget.RevokeToken);
|
|
276
242
|
}
|
|
277
243
|
/**
|
|
278
244
|
* Request forgot password.
|
|
279
245
|
* @param username Username
|
|
280
246
|
*
|
|
281
|
-
* @throws {
|
|
247
|
+
* @throws {CognitoException}
|
|
282
248
|
*/
|
|
283
249
|
async forgotPassword(username) {
|
|
284
250
|
const forgotPasswordPayload = {
|
|
285
251
|
ClientId: this.userPoolClientId,
|
|
286
|
-
Username: username
|
|
252
|
+
Username: username
|
|
287
253
|
};
|
|
288
254
|
await this.cognitoRequest(forgotPasswordPayload, CognitoServiceTarget.ForgotPassword);
|
|
289
255
|
}
|
|
@@ -294,14 +260,14 @@ export class CognitoClient {
|
|
|
294
260
|
* @param newPassword New password
|
|
295
261
|
* @param confirmationCode Confirmation code which the user got through E-mail
|
|
296
262
|
*
|
|
297
|
-
* @throws {
|
|
263
|
+
* @throws {CognitoException}
|
|
298
264
|
*/
|
|
299
265
|
async confirmForgotPassword(username, newPassword, confirmationCode) {
|
|
300
266
|
const confirmForgotPasswordPayload = {
|
|
301
267
|
ClientId: this.userPoolClientId,
|
|
302
268
|
Username: username,
|
|
303
269
|
ConfirmationCode: confirmationCode,
|
|
304
|
-
Password: newPassword
|
|
270
|
+
Password: newPassword
|
|
305
271
|
};
|
|
306
272
|
await this.cognitoRequest(confirmForgotPasswordPayload, CognitoServiceTarget.ConfirmForgotPassword);
|
|
307
273
|
}
|
|
@@ -312,7 +278,7 @@ export class CognitoClient {
|
|
|
312
278
|
async resendConfirmationCode(username) {
|
|
313
279
|
const resendConfirmationCodePayLoad = {
|
|
314
280
|
ClientId: this.userPoolClientId,
|
|
315
|
-
Username: username
|
|
281
|
+
Username: username
|
|
316
282
|
};
|
|
317
283
|
await this.cognitoRequest(resendConfirmationCodePayLoad, CognitoServiceTarget.ResendConfirmationCode);
|
|
318
284
|
}
|
|
@@ -327,30 +293,29 @@ export class CognitoClient {
|
|
|
327
293
|
*/
|
|
328
294
|
async generateOAuthSignInUrl(identityProvider) {
|
|
329
295
|
if (this.oAuth === undefined) {
|
|
330
|
-
throw Error(
|
|
296
|
+
throw Error('You have to define oAuth options to use generateFederatedSignUrl');
|
|
331
297
|
}
|
|
332
|
-
const state = (await randomBytes(32)).toString(
|
|
333
|
-
const pkce = (await randomBytes(128)).toString(
|
|
298
|
+
const state = (await randomBytes(32)).toString('hex');
|
|
299
|
+
const pkce = (await randomBytes(128)).toString('hex');
|
|
334
300
|
const code_challenge = Buffer.from(hashJs.sha256().update(pkce).digest())
|
|
335
|
-
.toString(
|
|
336
|
-
.replace(/\+/g,
|
|
337
|
-
.replace(/\//g,
|
|
338
|
-
.replace(/=+$/,
|
|
301
|
+
.toString('base64')
|
|
302
|
+
.replace(/\+/g, '-')
|
|
303
|
+
.replace(/\//g, '_')
|
|
304
|
+
.replace(/=+$/, '');
|
|
339
305
|
const queryParams = new URLSearchParams();
|
|
340
|
-
queryParams.append(
|
|
341
|
-
queryParams.append(
|
|
342
|
-
queryParams.append(
|
|
343
|
-
identityProvider &&
|
|
344
|
-
|
|
345
|
-
queryParams.append(
|
|
346
|
-
queryParams.append(
|
|
347
|
-
queryParams.append(
|
|
348
|
-
|
|
349
|
-
|
|
306
|
+
queryParams.append('redirect_uri', this.oAuth.redirectUrl);
|
|
307
|
+
queryParams.append('response_type', this.oAuth.responseType);
|
|
308
|
+
queryParams.append('client_id', this.userPoolClientId);
|
|
309
|
+
identityProvider && queryParams.append('identity_provider', identityProvider);
|
|
310
|
+
queryParams.append('scope', this.oAuth.scopes.join(' '));
|
|
311
|
+
queryParams.append('state', state);
|
|
312
|
+
queryParams.append('code_challenge', code_challenge);
|
|
313
|
+
queryParams.append('code_challenge_method', 'S256');
|
|
314
|
+
return {
|
|
315
|
+
url: `${this.oAuth.cognitoDomain}/oauth2/authorize?${queryParams.toString()}`,
|
|
350
316
|
state,
|
|
351
|
-
pkce
|
|
352
|
-
}
|
|
353
|
-
return `${this.oAuth.cognitoDomain}/oauth2/authorize?${queryParams.toString()}`;
|
|
317
|
+
pkce
|
|
318
|
+
};
|
|
354
319
|
}
|
|
355
320
|
/**
|
|
356
321
|
*
|
|
@@ -363,38 +328,31 @@ export class CognitoClient {
|
|
|
363
328
|
*
|
|
364
329
|
* @throws {Error}
|
|
365
330
|
*/
|
|
366
|
-
async handleCodeFlow(returnUrl) {
|
|
331
|
+
async handleCodeFlow(returnUrl, pkce) {
|
|
367
332
|
if (this.oAuth === undefined) {
|
|
368
|
-
throw Error(
|
|
333
|
+
throw Error('You have to define oAuth options to use handleCodeFlow');
|
|
369
334
|
}
|
|
370
335
|
const url = new URL(returnUrl);
|
|
371
|
-
const code = url.searchParams.get(
|
|
372
|
-
const state = url.searchParams.get(
|
|
336
|
+
const code = url.searchParams.get('code');
|
|
337
|
+
const state = url.searchParams.get('state');
|
|
373
338
|
if (code === null || state === null) {
|
|
374
|
-
throw Error(
|
|
375
|
-
}
|
|
376
|
-
const oAuthVerificationParams = this.sessionStorage.getOauthVerificationParams();
|
|
377
|
-
if (oAuthVerificationParams === undefined) {
|
|
378
|
-
throw new Error("OAuth verification parameters are missing, did you forgot to call generateOAuthSignInUrl ?");
|
|
379
|
-
}
|
|
380
|
-
if (oAuthVerificationParams.state !== state) {
|
|
381
|
-
throw new Error("state parameter does not match with previous value generated by previous call of generateOAuthSignInUrl .");
|
|
339
|
+
throw Error('code or state parameter is missing from return url.');
|
|
382
340
|
}
|
|
383
341
|
const urlParams = new URLSearchParams();
|
|
384
|
-
urlParams.append(
|
|
385
|
-
urlParams.append(
|
|
386
|
-
urlParams.append(
|
|
387
|
-
urlParams.append(
|
|
388
|
-
urlParams.append(
|
|
342
|
+
urlParams.append('grant_type', 'authorization_code');
|
|
343
|
+
urlParams.append('code', code);
|
|
344
|
+
urlParams.append('client_id', this.userPoolClientId);
|
|
345
|
+
urlParams.append('redirect_uri', this.oAuth.redirectUrl);
|
|
346
|
+
urlParams.append('code_verifier', pkce);
|
|
389
347
|
const tokenEndpoint = `${this.oAuth.cognitoDomain}/oauth2/token`;
|
|
390
348
|
const response = await fetch(tokenEndpoint, {
|
|
391
|
-
method:
|
|
349
|
+
method: 'POST',
|
|
392
350
|
headers: {
|
|
393
|
-
|
|
351
|
+
'Content-Type': 'application/x-www-form-urlencoded'
|
|
394
352
|
},
|
|
395
|
-
body: urlParams.toString()
|
|
353
|
+
body: urlParams.toString()
|
|
396
354
|
});
|
|
397
|
-
const { access_token, refresh_token, id_token, expires_in, token_type, error
|
|
355
|
+
const { access_token, refresh_token, id_token, expires_in, token_type, error } = await response.json();
|
|
398
356
|
if (error) {
|
|
399
357
|
throw new Error(error);
|
|
400
358
|
}
|
|
@@ -403,9 +361,8 @@ export class CognitoClient {
|
|
|
403
361
|
RefreshToken: refresh_token,
|
|
404
362
|
IdToken: id_token,
|
|
405
363
|
ExpiresIn: expires_in,
|
|
406
|
-
TokenType: token_type
|
|
364
|
+
TokenType: token_type
|
|
407
365
|
});
|
|
408
|
-
this.sessionStorage.setSession(session);
|
|
409
366
|
return session;
|
|
410
367
|
}
|
|
411
368
|
}
|