@vardario/cognito-client 0.1.4 → 0.1.6
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/cognito-client.d.ts +292 -0
- package/lib/cognito-client.js +409 -0
- package/lib/cognito-client.test.d.ts +1 -0
- package/lib/cognito-client.test.js +99 -0
- package/lib/error.d.ts +55 -0
- package/lib/error.js +70 -0
- package/lib/index.d.ts +3 -0
- package/lib/index.js +3 -0
- package/lib/session-storage/cookie-session-storage/cookie-session-storage.d.ts +21 -0
- package/lib/session-storage/cookie-session-storage/cookie-session-storage.js +42 -0
- package/lib/session-storage/cookie-session-storage/index.d.ts +1 -0
- package/lib/session-storage/cookie-session-storage/index.js +1 -0
- package/lib/session-storage/index.d.ts +4 -0
- package/lib/session-storage/index.js +4 -0
- package/lib/session-storage/local-storage-session-storage.d.ts +20 -0
- package/lib/session-storage/local-storage-session-storage.js +38 -0
- package/lib/session-storage/memory-session-storage.d.ts +13 -0
- package/lib/session-storage/memory-session-storage.js +18 -0
- package/lib/session-storage/session-storage.d.ts +14 -0
- package/lib/session-storage/session-storage.js +5 -0
- package/lib/session-storage/session-storage.test.d.ts +1 -0
- package/lib/session-storage/session-storage.test.js +33 -0
- package/lib/test-utils.d.ts +17 -0
- package/lib/test-utils.js +81 -0
- package/lib/utils.d.ts +20 -0
- package/lib/utils.js +111 -0
- package/package.json +8 -9
- package/dist/index.js +0 -3814
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import "isomorphic-fetch";
|
|
2
|
+
import { GenericContainer } from "testcontainers";
|
|
3
|
+
import { CognitoClient, CognitoIdentityProvider, } from "./cognito-client.js";
|
|
4
|
+
import { MemorySessionStorage } from "./session-storage/index.js";
|
|
5
|
+
import { newUser, setupCognito, user } from "./test-utils.js";
|
|
6
|
+
import { expect, test, describe, beforeAll, beforeEach, afterAll, } from "vitest";
|
|
7
|
+
describe("Cognito Client", () => {
|
|
8
|
+
let cognitoClient;
|
|
9
|
+
let container;
|
|
10
|
+
let sessionStorage = new MemorySessionStorage();
|
|
11
|
+
const oAuth2 = {
|
|
12
|
+
cognitoDomain: "http://localhost",
|
|
13
|
+
redirectUrl: "http://localhost",
|
|
14
|
+
responseType: "code",
|
|
15
|
+
scopes: ["email openid"],
|
|
16
|
+
};
|
|
17
|
+
let userPoolConfig = {
|
|
18
|
+
userPoolClientId: "",
|
|
19
|
+
userPoolId: "",
|
|
20
|
+
};
|
|
21
|
+
beforeAll(async () => {
|
|
22
|
+
const cognitoPort = 9229;
|
|
23
|
+
container = await new GenericContainer("jagregory/cognito-local")
|
|
24
|
+
.withExposedPorts(cognitoPort)
|
|
25
|
+
.start();
|
|
26
|
+
const cognitoEndpoint = `http://localhost:${container.getMappedPort(cognitoPort)}`;
|
|
27
|
+
userPoolConfig = await setupCognito(cognitoEndpoint);
|
|
28
|
+
cognitoClient = new CognitoClient({
|
|
29
|
+
userPoolId: userPoolConfig.userPoolId,
|
|
30
|
+
userPoolClientId: userPoolConfig.userPoolClientId,
|
|
31
|
+
sessionStorage: sessionStorage,
|
|
32
|
+
endpoint: cognitoEndpoint,
|
|
33
|
+
oAuth2: oAuth2,
|
|
34
|
+
});
|
|
35
|
+
});
|
|
36
|
+
beforeEach(async () => {
|
|
37
|
+
try {
|
|
38
|
+
await cognitoClient.signOut();
|
|
39
|
+
}
|
|
40
|
+
catch (error) { }
|
|
41
|
+
});
|
|
42
|
+
afterAll(async () => {
|
|
43
|
+
await container.stop();
|
|
44
|
+
});
|
|
45
|
+
test("authenticateUser", async () => {
|
|
46
|
+
const session = await cognitoClient.authenticateUser(user.email, user.password);
|
|
47
|
+
expect(session).toEqual(await cognitoClient.getSession());
|
|
48
|
+
//Simulate session expiring
|
|
49
|
+
sessionStorage.setSession({
|
|
50
|
+
...session,
|
|
51
|
+
expiresIn: 0,
|
|
52
|
+
});
|
|
53
|
+
const newSession = await cognitoClient.getSession();
|
|
54
|
+
expect(newSession).not.toEqual(session);
|
|
55
|
+
});
|
|
56
|
+
test("authenticateUserSrp: TODO", async () => {
|
|
57
|
+
// TODO: Currently SRP auth is not supported through cognito-local
|
|
58
|
+
// const session = await cognitoClient.authenticateUserSrp(user.name, user.password);
|
|
59
|
+
// expect(session).toEqual(await cognitoClient.getSession());
|
|
60
|
+
expect(true).toBe(true);
|
|
61
|
+
});
|
|
62
|
+
test("signUp", async () => {
|
|
63
|
+
const { id, confirmed } = await cognitoClient.signUp(newUser.email, newUser.password, [
|
|
64
|
+
{ Name: "givenName", Value: newUser.givenName },
|
|
65
|
+
{ Name: "familyName", Value: newUser.familyName },
|
|
66
|
+
]);
|
|
67
|
+
expect(id).toBeDefined();
|
|
68
|
+
expect(confirmed).toBe(false);
|
|
69
|
+
});
|
|
70
|
+
test("changePassword", async () => {
|
|
71
|
+
const newPassword = "newPassword";
|
|
72
|
+
expect(cognitoClient.changePassword(user.password, newPassword)).rejects.toThrow();
|
|
73
|
+
await cognitoClient.authenticateUser(user.email, user.password);
|
|
74
|
+
await cognitoClient.changePassword(user.password, newPassword);
|
|
75
|
+
await cognitoClient.signOut();
|
|
76
|
+
expect(cognitoClient.authenticateUser(user.email, user.password)).rejects.toThrow();
|
|
77
|
+
await cognitoClient.authenticateUser(user.email, "newPassword");
|
|
78
|
+
});
|
|
79
|
+
test("generateOAuthSignInUrl", () => {
|
|
80
|
+
const _test = (cb, identityProvider) => {
|
|
81
|
+
const hostedUIUrl = cognitoClient.generateOAuthSignInUrl(identityProvider);
|
|
82
|
+
const { searchParams } = new URL(hostedUIUrl);
|
|
83
|
+
expect(searchParams.get("redirect_uri")).toBe(oAuth2.redirectUrl);
|
|
84
|
+
expect(searchParams.get("response_type")).toBe(oAuth2.responseType);
|
|
85
|
+
expect(searchParams.get("client_id")).toBe(userPoolConfig.userPoolClientId);
|
|
86
|
+
expect(searchParams.get("scope")).toBe(oAuth2.scopes.join(" "));
|
|
87
|
+
expect(searchParams.get("state")).toBeDefined();
|
|
88
|
+
expect(searchParams.get("code_challenge")).toBeDefined();
|
|
89
|
+
expect(searchParams.get("code_challenge_method")).toBe("S256");
|
|
90
|
+
cb(searchParams);
|
|
91
|
+
};
|
|
92
|
+
_test((searchParams) => {
|
|
93
|
+
expect(searchParams.get("identity_provider")).toBeNull();
|
|
94
|
+
});
|
|
95
|
+
_test((searchParams) => {
|
|
96
|
+
expect(searchParams.get("identity_provider")).toBe(CognitoIdentityProvider.Apple);
|
|
97
|
+
}, CognitoIdentityProvider.Apple);
|
|
98
|
+
});
|
|
99
|
+
});
|
package/lib/error.d.ts
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Possible Authentications errors
|
|
3
|
+
*/
|
|
4
|
+
export declare enum AuthError {
|
|
5
|
+
/**
|
|
6
|
+
* User already confirmed
|
|
7
|
+
*/
|
|
8
|
+
UserConfirmedAlready = "user_confirmed_already",
|
|
9
|
+
/**
|
|
10
|
+
* User Profile does not exists.
|
|
11
|
+
*/
|
|
12
|
+
UserDoesNotExist = "user_does_not_exist",
|
|
13
|
+
/**
|
|
14
|
+
* User Profile does not exists.
|
|
15
|
+
*/
|
|
16
|
+
UserAlreadyExists = "user_already_exists",
|
|
17
|
+
/**
|
|
18
|
+
* Password was wrong.
|
|
19
|
+
*/
|
|
20
|
+
EmailOrPasswordWrong = "email_or_password_wrong",
|
|
21
|
+
/**
|
|
22
|
+
* Rate limit exceeded.
|
|
23
|
+
*/
|
|
24
|
+
LimitExceededException = "limit_exceeded_exception",
|
|
25
|
+
/**
|
|
26
|
+
* User needs to be authenticated.
|
|
27
|
+
*/
|
|
28
|
+
UserNotAuthenticated = "user_not_authenticated",
|
|
29
|
+
/**
|
|
30
|
+
* The user tried to many times wiht the wrong password
|
|
31
|
+
*/
|
|
32
|
+
PasswordAttempsExceeded = "password_attemps_exceeded",
|
|
33
|
+
/**
|
|
34
|
+
* User E-Mail needs to be verified.
|
|
35
|
+
*/
|
|
36
|
+
UserEmailNotVerified = "user_email_not_verified",
|
|
37
|
+
/**
|
|
38
|
+
* Unknown auth error happened.
|
|
39
|
+
*/
|
|
40
|
+
Unknown = "unknown"
|
|
41
|
+
}
|
|
42
|
+
export declare class AuthException extends Error {
|
|
43
|
+
readonly authError: AuthError;
|
|
44
|
+
constructor(message: string, authError: AuthError);
|
|
45
|
+
}
|
|
46
|
+
export declare enum ErrorCode {
|
|
47
|
+
UserNotFoundException = "UserNotFoundException",
|
|
48
|
+
NotAuthorizedException = "NotAuthorizedException",
|
|
49
|
+
LimitExceededException = "LimitExceededException"
|
|
50
|
+
}
|
|
51
|
+
export interface CognitoAuthErrorResponse {
|
|
52
|
+
__type: ErrorCode;
|
|
53
|
+
message: string;
|
|
54
|
+
}
|
|
55
|
+
export declare function getAuthError(errorResponse: CognitoAuthErrorResponse): AuthException;
|
package/lib/error.js
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Possible Authentications errors
|
|
3
|
+
*/
|
|
4
|
+
export var AuthError;
|
|
5
|
+
(function (AuthError) {
|
|
6
|
+
/**
|
|
7
|
+
* User already confirmed
|
|
8
|
+
*/
|
|
9
|
+
AuthError["UserConfirmedAlready"] = "user_confirmed_already";
|
|
10
|
+
/**
|
|
11
|
+
* User Profile does not exists.
|
|
12
|
+
*/
|
|
13
|
+
AuthError["UserDoesNotExist"] = "user_does_not_exist";
|
|
14
|
+
/**
|
|
15
|
+
* User Profile does not exists.
|
|
16
|
+
*/
|
|
17
|
+
AuthError["UserAlreadyExists"] = "user_already_exists";
|
|
18
|
+
/**
|
|
19
|
+
* Password was wrong.
|
|
20
|
+
*/
|
|
21
|
+
AuthError["EmailOrPasswordWrong"] = "email_or_password_wrong";
|
|
22
|
+
/**
|
|
23
|
+
* Rate limit exceeded.
|
|
24
|
+
*/
|
|
25
|
+
AuthError["LimitExceededException"] = "limit_exceeded_exception";
|
|
26
|
+
/**
|
|
27
|
+
* User needs to be authenticated.
|
|
28
|
+
*/
|
|
29
|
+
AuthError["UserNotAuthenticated"] = "user_not_authenticated";
|
|
30
|
+
/**
|
|
31
|
+
* The user tried to many times wiht the wrong password
|
|
32
|
+
*/
|
|
33
|
+
AuthError["PasswordAttempsExceeded"] = "password_attemps_exceeded";
|
|
34
|
+
/**
|
|
35
|
+
* User E-Mail needs to be verified.
|
|
36
|
+
*/
|
|
37
|
+
AuthError["UserEmailNotVerified"] = "user_email_not_verified";
|
|
38
|
+
/**
|
|
39
|
+
* Unknown auth error happened.
|
|
40
|
+
*/
|
|
41
|
+
AuthError["Unknown"] = "unknown";
|
|
42
|
+
})(AuthError || (AuthError = {}));
|
|
43
|
+
export class AuthException extends Error {
|
|
44
|
+
constructor(message, authError) {
|
|
45
|
+
super(message);
|
|
46
|
+
this.authError = authError;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
export var ErrorCode;
|
|
50
|
+
(function (ErrorCode) {
|
|
51
|
+
ErrorCode["UserNotFoundException"] = "UserNotFoundException";
|
|
52
|
+
ErrorCode["NotAuthorizedException"] = "NotAuthorizedException";
|
|
53
|
+
ErrorCode["LimitExceededException"] = "LimitExceededException";
|
|
54
|
+
})(ErrorCode || (ErrorCode = {}));
|
|
55
|
+
export function getAuthError(errorResponse) {
|
|
56
|
+
const mapping = {
|
|
57
|
+
'UserNotFoundException:User cannot be confirmed. Current status is CONFIRMED': AuthError.UserConfirmedAlready,
|
|
58
|
+
'NotAuthorizedException:Incorrect username or password.': AuthError.EmailOrPasswordWrong,
|
|
59
|
+
'LimitExceededException:Attempt limit exceeded, please try after some time.': AuthError.LimitExceededException,
|
|
60
|
+
'UserNotFoundException:Username/client id combination not found.': AuthError.UserDoesNotExist,
|
|
61
|
+
'UserNotFoundException:User does not exist.': AuthError.UserDoesNotExist,
|
|
62
|
+
'NotAuthorizedException:Password attempts exceeded': AuthError.PasswordAttempsExceeded,
|
|
63
|
+
'UsernameExistsException:An account with the given email already exists.': AuthError.UserAlreadyExists,
|
|
64
|
+
'InvalidParameterException:Cannot reset password for the user as there is no registered/verified email or phone_number': AuthError.UserEmailNotVerified,
|
|
65
|
+
'UserNotConfirmedException:User is not confirmed.': AuthError.UserEmailNotVerified,
|
|
66
|
+
};
|
|
67
|
+
const message = `${errorResponse.__type}:${errorResponse.message}`;
|
|
68
|
+
const authError = mapping[message] || AuthError.Unknown;
|
|
69
|
+
return new AuthException(message, authError);
|
|
70
|
+
}
|
package/lib/index.d.ts
ADDED
package/lib/index.js
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { CookieProps } from '@vardario/cookies';
|
|
2
|
+
import { Session } from '../../cognito-client.js';
|
|
3
|
+
import { OAuthVerificationParams, SessionStorage } from '../session-storage.js';
|
|
4
|
+
export interface CookieSessionStorageProps extends CookieProps {
|
|
5
|
+
cookieName: string;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Cookies based session storage.
|
|
9
|
+
* This session storage works also across sub domains.
|
|
10
|
+
*/
|
|
11
|
+
export declare class CookieSessionStorage extends SessionStorage {
|
|
12
|
+
private readonly props;
|
|
13
|
+
private readonly oAuthParamCookieName;
|
|
14
|
+
private readonly sessionCookieName;
|
|
15
|
+
private readonly cookies;
|
|
16
|
+
constructor(props: CookieSessionStorageProps);
|
|
17
|
+
getSession(): Session | undefined;
|
|
18
|
+
setSession(session: Session | undefined): void;
|
|
19
|
+
getOauthVerificationParams(): OAuthVerificationParams | undefined;
|
|
20
|
+
setOauthVerificationParams(oAuthParams: OAuthVerificationParams): void;
|
|
21
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { Cookies } from '@vardario/cookies';
|
|
2
|
+
import { SessionStorage } from '../session-storage.js';
|
|
3
|
+
/**
|
|
4
|
+
* Cookies based session storage.
|
|
5
|
+
* This session storage works also across sub domains.
|
|
6
|
+
*/
|
|
7
|
+
export class CookieSessionStorage extends SessionStorage {
|
|
8
|
+
constructor(props) {
|
|
9
|
+
super();
|
|
10
|
+
this.props = {
|
|
11
|
+
domain: props.domain,
|
|
12
|
+
path: props.path ?? '/',
|
|
13
|
+
expires: props.expires ?? 365,
|
|
14
|
+
secure: props.secure ?? true,
|
|
15
|
+
sameSite: props.sameSite ?? 'None',
|
|
16
|
+
cookieName: props.cookieName,
|
|
17
|
+
};
|
|
18
|
+
this.cookies = new Cookies(this.props);
|
|
19
|
+
this.sessionCookieName = `${props.cookieName}`;
|
|
20
|
+
this.oAuthParamCookieName = `${props.cookieName}_oauth`;
|
|
21
|
+
}
|
|
22
|
+
getSession() {
|
|
23
|
+
const session = this.cookies.getCookie(this.sessionCookieName);
|
|
24
|
+
if (session === undefined) {
|
|
25
|
+
return undefined;
|
|
26
|
+
}
|
|
27
|
+
return JSON.parse(session);
|
|
28
|
+
}
|
|
29
|
+
setSession(session) {
|
|
30
|
+
this.cookies.setCookie(this.sessionCookieName, JSON.stringify(session));
|
|
31
|
+
}
|
|
32
|
+
getOauthVerificationParams() {
|
|
33
|
+
const oAuthParams = this.cookies.getCookie(this.oAuthParamCookieName);
|
|
34
|
+
if (oAuthParams === undefined) {
|
|
35
|
+
return undefined;
|
|
36
|
+
}
|
|
37
|
+
return JSON.parse(oAuthParams);
|
|
38
|
+
}
|
|
39
|
+
setOauthVerificationParams(oAuthParams) {
|
|
40
|
+
this.cookies.setCookie(this.oAuthParamCookieName, JSON.stringify(oAuthParams));
|
|
41
|
+
}
|
|
42
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './cookie-session-storage.js';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './cookie-session-storage.js';
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { Session } from '../cognito-client.js';
|
|
2
|
+
import { OAuthVerificationParams, SessionStorage } from './session-storage.js';
|
|
3
|
+
export interface LocalStorageSessionStorageProps {
|
|
4
|
+
storageName: string;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* LocalStorage based session storage.
|
|
8
|
+
* This session storage works only one domain at a time.
|
|
9
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage
|
|
10
|
+
* Use @see CookieSessionStorage for a session storage, which
|
|
11
|
+
* can span across sub domains as well.
|
|
12
|
+
*/
|
|
13
|
+
export declare class LocalStorageSessionStorage extends SessionStorage {
|
|
14
|
+
private readonly props;
|
|
15
|
+
constructor(props: LocalStorageSessionStorageProps);
|
|
16
|
+
getSession(): Session | undefined;
|
|
17
|
+
setSession(session: Session | undefined): void;
|
|
18
|
+
setOauthVerificationParams(oAuthParams: OAuthVerificationParams): void;
|
|
19
|
+
getOauthVerificationParams(): OAuthVerificationParams | undefined;
|
|
20
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { SessionStorage } from './session-storage.js';
|
|
2
|
+
/**
|
|
3
|
+
* LocalStorage based session storage.
|
|
4
|
+
* This session storage works only one domain at a time.
|
|
5
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage
|
|
6
|
+
* Use @see CookieSessionStorage for a session storage, which
|
|
7
|
+
* can span across sub domains as well.
|
|
8
|
+
*/
|
|
9
|
+
export class LocalStorageSessionStorage extends SessionStorage {
|
|
10
|
+
constructor(props) {
|
|
11
|
+
super();
|
|
12
|
+
this.props = props;
|
|
13
|
+
}
|
|
14
|
+
getSession() {
|
|
15
|
+
const payload = window.localStorage.getItem(this.props.storageName);
|
|
16
|
+
if (payload === null) {
|
|
17
|
+
return undefined;
|
|
18
|
+
}
|
|
19
|
+
return JSON.parse(payload);
|
|
20
|
+
}
|
|
21
|
+
setSession(session) {
|
|
22
|
+
if (session === undefined) {
|
|
23
|
+
window.localStorage.removeItem(this.props.storageName);
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
window.localStorage.setItem(this.props.storageName, JSON.stringify(session));
|
|
27
|
+
}
|
|
28
|
+
setOauthVerificationParams(oAuthParams) {
|
|
29
|
+
window.localStorage.setItem(`${this.props.storageName}_oauth`, JSON.stringify(oAuthParams));
|
|
30
|
+
}
|
|
31
|
+
getOauthVerificationParams() {
|
|
32
|
+
const payload = window.localStorage.getItem(`${this.props.storageName}_oauth`);
|
|
33
|
+
if (payload === null) {
|
|
34
|
+
return undefined;
|
|
35
|
+
}
|
|
36
|
+
return JSON.parse(payload);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { Session } from '../cognito-client.js';
|
|
2
|
+
import { OAuthVerificationParams, SessionStorage } from './session-storage.js';
|
|
3
|
+
/**
|
|
4
|
+
* In-memory based session storage. Useful for testing.
|
|
5
|
+
*/
|
|
6
|
+
export declare class MemorySessionStorage extends SessionStorage {
|
|
7
|
+
private session?;
|
|
8
|
+
private oAuthVerificationParams?;
|
|
9
|
+
getSession(): Session | undefined;
|
|
10
|
+
setSession(session: Session | undefined): void;
|
|
11
|
+
getOauthVerificationParams(): OAuthVerificationParams | undefined;
|
|
12
|
+
setOauthVerificationParams(oAuthParams: OAuthVerificationParams): void;
|
|
13
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { SessionStorage } from './session-storage.js';
|
|
2
|
+
/**
|
|
3
|
+
* In-memory based session storage. Useful for testing.
|
|
4
|
+
*/
|
|
5
|
+
export class MemorySessionStorage extends SessionStorage {
|
|
6
|
+
getSession() {
|
|
7
|
+
return this.session;
|
|
8
|
+
}
|
|
9
|
+
setSession(session) {
|
|
10
|
+
this.session = session;
|
|
11
|
+
}
|
|
12
|
+
getOauthVerificationParams() {
|
|
13
|
+
return this.oAuthVerificationParams;
|
|
14
|
+
}
|
|
15
|
+
setOauthVerificationParams(oAuthParams) {
|
|
16
|
+
this.oAuthVerificationParams = oAuthParams;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { Session } from '../cognito-client.js';
|
|
2
|
+
export interface OAuthVerificationParams {
|
|
3
|
+
pkce: string;
|
|
4
|
+
state: string;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* Session storage interface class.
|
|
8
|
+
*/
|
|
9
|
+
export declare abstract class SessionStorage {
|
|
10
|
+
abstract getSession(): Session | undefined;
|
|
11
|
+
abstract setSession(session: Session | undefined): void;
|
|
12
|
+
abstract setOauthVerificationParams(oAuthParams: OAuthVerificationParams): void;
|
|
13
|
+
abstract getOauthVerificationParams(): OAuthVerificationParams | undefined;
|
|
14
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { randomBytes } from "crypto";
|
|
2
|
+
import { setupJsDom } from "../test-utils.js";
|
|
3
|
+
import { CookieSessionStorage } from "./cookie-session-storage/index.js";
|
|
4
|
+
import { LocalStorageSessionStorage } from "./local-storage-session-storage.js";
|
|
5
|
+
import { MemorySessionStorage } from "./memory-session-storage.js";
|
|
6
|
+
import { expect, test } from "vitest";
|
|
7
|
+
setupJsDom();
|
|
8
|
+
const sessionStorages = [
|
|
9
|
+
new MemorySessionStorage(),
|
|
10
|
+
new LocalStorageSessionStorage({ storageName: "session" }),
|
|
11
|
+
new CookieSessionStorage({
|
|
12
|
+
domain: "localhost",
|
|
13
|
+
cookieName: "session",
|
|
14
|
+
}),
|
|
15
|
+
];
|
|
16
|
+
const session = {
|
|
17
|
+
accessToken: randomBytes(128).toString("base64"),
|
|
18
|
+
expiresIn: 600,
|
|
19
|
+
idToken: randomBytes(128).toString("base64"),
|
|
20
|
+
refreshToken: randomBytes(128).toString("base64"),
|
|
21
|
+
};
|
|
22
|
+
const oAuthVerificationParams = {
|
|
23
|
+
pkce: randomBytes(128).toString("base64"),
|
|
24
|
+
state: randomBytes(128).toString("base64"),
|
|
25
|
+
};
|
|
26
|
+
test("SessionStorage", () => {
|
|
27
|
+
sessionStorages.forEach((sessionStorage) => {
|
|
28
|
+
sessionStorage.setSession(session);
|
|
29
|
+
expect(sessionStorage.getSession()).toStrictEqual(session);
|
|
30
|
+
sessionStorage.setOauthVerificationParams(oAuthVerificationParams);
|
|
31
|
+
expect(sessionStorage.getOauthVerificationParams()).toStrictEqual(oAuthVerificationParams);
|
|
32
|
+
});
|
|
33
|
+
});
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export declare const user: {
|
|
2
|
+
email: string;
|
|
3
|
+
password: string;
|
|
4
|
+
givenName: string;
|
|
5
|
+
familyName: string;
|
|
6
|
+
};
|
|
7
|
+
export declare const newUser: {
|
|
8
|
+
email: string;
|
|
9
|
+
password: string;
|
|
10
|
+
givenName: string;
|
|
11
|
+
familyName: string;
|
|
12
|
+
};
|
|
13
|
+
export declare function setupCognito(endpoint: string): Promise<{
|
|
14
|
+
userPoolId: string;
|
|
15
|
+
userPoolClientId: string;
|
|
16
|
+
}>;
|
|
17
|
+
export declare function setupJsDom(): void;
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
const { AdminCreateUserCommand, AdminSetUserPasswordCommand, AttributeDataType, CognitoIdentityProviderClient, CreateUserPoolClientCommand, CreateUserPoolCommand, } = await import("@aws-sdk/client-cognito-identity-provider");
|
|
2
|
+
import { JSDOM } from "jsdom";
|
|
3
|
+
export const user = {
|
|
4
|
+
email: "sahin@test.com",
|
|
5
|
+
password: "password",
|
|
6
|
+
givenName: "Sahin",
|
|
7
|
+
familyName: "Sahin",
|
|
8
|
+
};
|
|
9
|
+
export const newUser = {
|
|
10
|
+
email: "john@test.com",
|
|
11
|
+
password: "password",
|
|
12
|
+
givenName: "John",
|
|
13
|
+
familyName: "John",
|
|
14
|
+
};
|
|
15
|
+
export async function setupCognito(endpoint) {
|
|
16
|
+
const awsCognitoClient = new CognitoIdentityProviderClient({
|
|
17
|
+
endpoint: endpoint,
|
|
18
|
+
credentials: {
|
|
19
|
+
accessKeyId: "test",
|
|
20
|
+
secretAccessKey: "test",
|
|
21
|
+
},
|
|
22
|
+
region: "eu-central-1",
|
|
23
|
+
});
|
|
24
|
+
const createPoolResult = await awsCognitoClient.send(new CreateUserPoolCommand({
|
|
25
|
+
PoolName: "TestPool",
|
|
26
|
+
Schema: [
|
|
27
|
+
{
|
|
28
|
+
Name: "email",
|
|
29
|
+
AttributeDataType: AttributeDataType.STRING,
|
|
30
|
+
Required: true,
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
Name: "givenName",
|
|
34
|
+
AttributeDataType: AttributeDataType.STRING,
|
|
35
|
+
Required: true,
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
Name: "familyName",
|
|
39
|
+
AttributeDataType: AttributeDataType.STRING,
|
|
40
|
+
Required: true,
|
|
41
|
+
},
|
|
42
|
+
],
|
|
43
|
+
}));
|
|
44
|
+
const createUserPoolClientResult = await awsCognitoClient.send(new CreateUserPoolClientCommand({
|
|
45
|
+
ClientName: "TestClient",
|
|
46
|
+
UserPoolId: createPoolResult.UserPool?.Id,
|
|
47
|
+
}));
|
|
48
|
+
const createUserResult = await awsCognitoClient.send(new AdminCreateUserCommand({
|
|
49
|
+
UserPoolId: createPoolResult.UserPool?.Id,
|
|
50
|
+
Username: user.email,
|
|
51
|
+
MessageAction: "SUPPRESS",
|
|
52
|
+
UserAttributes: [
|
|
53
|
+
{
|
|
54
|
+
Name: "givenName",
|
|
55
|
+
Value: user.givenName,
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
Name: "familyName",
|
|
59
|
+
Value: user.familyName,
|
|
60
|
+
},
|
|
61
|
+
],
|
|
62
|
+
}));
|
|
63
|
+
const setUserPasswordResult = await awsCognitoClient.send(new AdminSetUserPasswordCommand({
|
|
64
|
+
UserPoolId: createPoolResult.UserPool?.Id,
|
|
65
|
+
Username: user.email,
|
|
66
|
+
Password: user.password,
|
|
67
|
+
Permanent: true,
|
|
68
|
+
}));
|
|
69
|
+
return {
|
|
70
|
+
userPoolId: createPoolResult.UserPool?.Id,
|
|
71
|
+
userPoolClientId: createUserPoolClientResult.UserPoolClient
|
|
72
|
+
?.ClientId,
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
export function setupJsDom() {
|
|
76
|
+
const dom = new JSDOM("", {
|
|
77
|
+
url: "http://localhost",
|
|
78
|
+
});
|
|
79
|
+
global.document = dom.window.document;
|
|
80
|
+
global.window = dom.window;
|
|
81
|
+
}
|
package/lib/utils.d.ts
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/// <reference types="node" resolution-mode="require"/>
|
|
2
|
+
import { BigInteger } from 'jsbn';
|
|
3
|
+
export declare function padHex(bigInt: BigInteger): string;
|
|
4
|
+
export declare function hashHexString(str: string): string;
|
|
5
|
+
export declare function hashBuffer(buffer: Buffer): string;
|
|
6
|
+
export declare function generateSmallA(): BigInteger;
|
|
7
|
+
export declare function generateA(smallA: BigInteger): BigInteger;
|
|
8
|
+
export declare function calculateU(A: BigInteger, B: BigInteger): BigInteger;
|
|
9
|
+
export declare function calculateS(X: BigInteger, B: BigInteger, U: BigInteger, smallA: BigInteger): BigInteger;
|
|
10
|
+
export declare function calculateHKDF(ikm: Buffer, salt: Buffer): number[];
|
|
11
|
+
export declare function getPasswordAuthenticationKey(poolName: string, username: string, password: string, B: BigInteger, U: BigInteger, smallA: BigInteger, salt: BigInteger): number[];
|
|
12
|
+
export declare function calculateSignature(poolName: string, userId: string, secretBlock: string, hkdf: number[]): {
|
|
13
|
+
signature: string;
|
|
14
|
+
timeStamp: any;
|
|
15
|
+
};
|
|
16
|
+
export declare function decodeJwt<T = unknown>(jwt: string): {
|
|
17
|
+
header: any;
|
|
18
|
+
payload: T;
|
|
19
|
+
signature: string;
|
|
20
|
+
};
|