Skip to content

Commit

Permalink
Merge branch 'develop' into renovate/webpack-5.x-lockfile
Browse files Browse the repository at this point in the history
  • Loading branch information
jennifer-shehane authored Mar 5, 2024
2 parents b14bc7d + d6f7f39 commit 9493d8f
Show file tree
Hide file tree
Showing 16 changed files with 1,366 additions and 3,069 deletions.
2 changes: 1 addition & 1 deletion .circleci/config.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
version: 2.1
orbs:
cypress: cypress-io/cypress@3.3.0
cypress: cypress-io/cypress@3.3.1
codecov: codecov/codecov@1.2.3 #

executors:
Expand Down
4 changes: 2 additions & 2 deletions .env
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,11 @@ VITE_BACKEND_PORT=3001
#VITE_OKTA_DOMAIN="dev-your-domain-id.okta.com"
#VITE_OKTA_CLIENTID="your-client-id"

# AWS Cognito #Okta Configuration to be added to .env when running "yarn dev:cognito"
# AWS Cognito Configuration to be added to .env when running "yarn dev:cognito"
# Additional config taken from aws-exports.js
#AWS_COGNITO_USERNAME="user@domain.com"
#AWS_COGNITO_PASSWORD="s3cret1234$"
#AWS_COGNITO_DOMAIN="https://YOUR_COGNITO_INSTANCE.auth.us-east-1.amazoncognito.com"
#AWS_COGNITO_DOMAIN="https://YOUR_COGNITO_USER_POOL_HOSTED_UI_DOMAIN_PREFIX.auth.us-east-1.amazoncognito.com"

# Google Auth Configuration to be added to .env when running "yarn dev:google"
# client ID should look something like <identifier>.apps.googleusercontent.com
Expand Down
21 changes: 20 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,26 @@ A [guide has been written with detail around adapting the RWA](http://on.cypress
Prerequisites include an [Amazon Cognito][cognito] account. Environment variables from [Amazon Cognito][cognito] are provided by the [AWS Amplify CLI][awsamplify].
To start the application with Cognito, replace the current **src/index.tsx** file with the **src/index.cognito.tsx** file and start the application with `yarn dev:cognito` and run Cypress with `yarn cypress:open`.
- A user pool is required (identity pool is not used here)
- The user pool must have a hosted UI domain configured, which must:
- allow callback and sign-out URLs of `http://localhost:3000/`,
- allow implicit grant Oauth grant type,
- allow these OpenID Connect scopes:
- aws.cognito.signin.user.admin
- email
- openid
- The user pool must have an app client configured, with:
- enabled auth flow `ALLOW_USER_PASSWORD_AUTH`, only for programmatic login flavor of test.
- The `cy.origin()` flavor of test only requires auth flow `ALLOW_USER_SRP_AUTH`, and does not require `ALLOW_USER_PASSWORD_AUTH`.
- The user pool must have a user corresponding to the `AWS_COGNITO` env vars mentioned below, and the user's Confirmation Status must be `Confirmed`. If it is `Force Reset Password`, then use a browser to log in once at `http://localhost:3000` while `yarn dev:cognito` is running to reset their password.
The test knobs are in a few places:
- The `.env` file has `VITE_AUTH_TOKEN_NAME` and vars beginning `AWS_COGNITO`. Be careful not to commit any secrets.
- Both `scripts/mock-aws-exports.js` and `scripts/mock-aws-exports-es5.js` must have the same data; only their export statements differ. These files can be edited manually or exported from the amplify CLI.
- `cypress.config.ts` has `cognito_programmatic_login` to control flavor of the test.
To start the application with Cognito, replace the current **src/index.tsx** file with the **src/index.cognito.tsx** file and start the application with `yarn dev:cognito` and run Cypress with `yarn cypress:open`. `yarn dev` may need to have been run once first.
The **only passing spec on this branch** will be the [cognito spec](./cypress/tests/ui-auth-providers/cognito.spec.ts); all others will fail.
Expand Down
6 changes: 4 additions & 2 deletions backend/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,12 +80,14 @@ export const verifyOktaToken = (req: Request, res: Response, next: NextFunction)

// Amazon Cognito Validate the JWT Signature
// https://docs.aws.amazon.com/cognito/latest/developerguide/amazon-cognito-user-pools-using-tokens-verifying-a-jwt.html#amazon-cognito-user-pools-using-tokens-step-2
const userPoolId = awsConfig.Auth.Cognito.userPoolId;
const region = userPoolId.split("_")[0];
const awsCognitoJwtConfig = {
secret: jwksRsa.expressJwtSecret({
jwksUri: `https://cognito-idp.${awsConfig.aws_cognito_region}.amazonaws.com/${awsConfig.aws_user_pools_id}/.well-known/jwks.json`,
jwksUri: `https://cognito-idp.${region}.amazonaws.com/${userPoolId}/.well-known/jwks.json`,
}),

issuer: `https://cognito-idp.${awsConfig.aws_cognito_region}.amazonaws.com/${awsConfig.aws_user_pools_id}`,
issuer: `https://cognito-idp.${region}.amazonaws.com/${userPoolId}`,
algorithms: ["RS256"],
};

Expand Down
58 changes: 28 additions & 30 deletions cypress/support/auth-provider-commands/cognito.ts
Original file line number Diff line number Diff line change
@@ -1,44 +1,44 @@
import { Amplify, Auth } from "aws-amplify";
import { Amplify } from "aws-amplify";
import { fetchAuthSession, signIn } from "aws-amplify/auth";

Amplify.configure(Cypress.env("awsConfig"));

const fetchJwts = async (username: string, password: string) => {
const options = { authFlowType: "USER_PASSWORD_AUTH" as const };
await signIn({ username, password, options });
const authSession = await fetchAuthSession();
const tokens = authSession.tokens!;
const accessToken = tokens.accessToken;
const accessTokenPayload = accessToken.payload;
return {
idToken: tokens.idToken!.toString(),
accessToken: accessToken.toString(),
clientId: accessTokenPayload.client_id as string,
accessTokenSub: accessTokenPayload.sub!,
};
};
type JwtResponse = Awaited<ReturnType<typeof fetchJwts>>;

// Amazon Cognito
Cypress.Commands.add("loginByCognitoApi", (username, password) => {
Cypress.Commands.add("loginByCognitoApi", (username: string, password: string) => {
const log = Cypress.log({
displayName: "COGNITO LOGIN",
message: [`🔐 Authenticating | ${username}`],
// @ts-ignore
autoEnd: false,
});

log.snapshot("before");

const signIn = Auth.signIn({ username, password });
cy.wrap(fetchJwts(username, password), { log: false }).then((unknownJwts) => {
const { idToken, accessToken, clientId, accessTokenSub } = unknownJwts as JwtResponse;

cy.wrap(signIn, { log: false }).then((cognitoResponse: any) => {
const keyPrefixWithUsername = `${cognitoResponse.keyPrefix}.${cognitoResponse.username}`;
window.localStorage.setItem(
`${keyPrefixWithUsername}.idToken`,
cognitoResponse.signInUserSession.idToken.jwtToken
);
window.localStorage.setItem(
`${keyPrefixWithUsername}.accessToken`,
cognitoResponse.signInUserSession.accessToken.jwtToken
);
window.localStorage.setItem(
`${keyPrefixWithUsername}.refreshToken`,
cognitoResponse.signInUserSession.refreshToken.token
);
window.localStorage.setItem(
`${keyPrefixWithUsername}.clockDrift`,
cognitoResponse.signInUserSession.clockDrift
);
window.localStorage.setItem(
`${cognitoResponse.keyPrefix}.LastAuthUser`,
cognitoResponse.username
);
const keyPrefix = `CognitoIdentityServiceProvider.${clientId}`;
const keyPrefixWithUsername = `${keyPrefix}.${accessTokenSub}`;

window.localStorage.setItem("amplify-authenticator-authState", "signedIn");
const ls = window.localStorage;
ls.setItem(`${keyPrefixWithUsername}.idToken`, idToken);
ls.setItem(`${keyPrefixWithUsername}.accessToken`, accessToken);
ls.setItem(`${keyPrefix}.LastAuthUser`, accessTokenSub);

log.snapshot("after");
log.end();
Expand All @@ -60,9 +60,6 @@ Cypress.Commands.add("loginByCognito", (username, password) => {
});

cy.visit("/");
cy.contains("Sign in with AWS", {
includeShadowDom: true,
}).click();

cy.origin(
Cypress.env("cognito_domain"),
Expand All @@ -73,6 +70,7 @@ Cypress.Commands.add("loginByCognito", (username, password) => {
},
},
({ username, password }) => {
cy.contains("Sign in with your email and password");
// cognito log in page has some elements of the same id but are off screen. we only want the visible elements to log in
cy.get('input[name="username"]:visible').type(username);
cy.get('input[name="password"]:visible').type(password, {
Expand Down
7 changes: 4 additions & 3 deletions cypress/tests/ui-auth-providers/cognito.spec.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
import "../../support/auth-provider-commands/cognito";
import { isMobile } from "../../support/utils";
const apiGraphQL = `${Cypress.env("apiUrl")}/graphql`;

if (Cypress.env("cognito_username")) {
// Sign in with AWS
if (Cypress.env("cognito_programmatic_login")) {
describe("AWS Cognito", function () {
describe("AWS Cognito, programmatic login (cypress.config.ts#cognito_programmatic_login: true)", function () {
beforeEach(function () {
cy.task("db:seed");

cy.intercept("POST", "/bankAccounts").as("createBankAccount");
cy.intercept("POST", apiGraphQL).as("createBankAccount");

cy.loginByCognitoApi(Cypress.env("cognito_username"), Cypress.env("cognito_password"));
});
Expand Down Expand Up @@ -49,7 +50,7 @@ if (Cypress.env("cognito_username")) {
});
});
} else {
describe("AWS Cognito", function () {
describe("AWS Cognito, cy.origin() login (cypress.config.ts#cognito_programmatic_login: false)", function () {
beforeEach(function () {
cy.task("db:seed");
cy.loginByCognito(Cypress.env("cognito_username"), Cypress.env("cognito_password"));
Expand Down
25 changes: 12 additions & 13 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,12 @@
"url": "https://github.com/cypress-io/cypress-realworld-app/issues"
},
"dependencies": {
"@auth0/auth0-react": "2.1.1",
"@aws-amplify/ui-react": "^5.0.4",
"@auth0/auth0-react": "2.2.4",
"@babel/core": "7.23.9",
"@babel/plugin-syntax-flow": "^7.14.5",
"@babel/plugin-transform-react-jsx": "^7.14.9",
"@graphql-tools/graphql-file-loader": "7.3.10",
"@graphql-tools/load": "7.5.9",
"@graphql-tools/graphql-file-loader": "7.5.17",
"@graphql-tools/load": "7.8.14",
"@material-ui/core": "4.12.4",
"@material-ui/icons": "4.11.3",
"@material-ui/lab": "4.0.0-alpha.61",
Expand All @@ -27,14 +26,14 @@
"@okta/okta-auth-js": "^7.3.0",
"@okta/okta-react": "^6.7.0",
"@types/detect-port": "^1.3.2",
"@xstate/react": "3.0.0",
"aws-amplify": "^5.3.3",
"axios": "0.26.1",
"clsx": "1.1.1",
"date-fns": "2.28.0",
"@xstate/react": "3.2.2",
"aws-amplify": "^6.0.16",
"axios": "0.28.0",
"clsx": "1.2.1",
"date-fns": "2.30.0",
"detect-port": "^1.5.1",
"dinero.js": "1.9.1",
"formik": "2.2.9",
"formik": "2.4.5",
"history": "4.10.1",
"postinstall-postinstall": "^2.1.0",
"react": "18.2.0",
Expand All @@ -47,7 +46,7 @@
"shortid": "2.2.16",
"uuid": "8.3.2",
"webpack": "5",
"xstate": "4.35.4",
"xstate": "4.38.3",
"yup": "0.32.11"
},
"devDependencies": {
Expand Down Expand Up @@ -103,7 +102,7 @@
"eslint-config-react-app": "^7.0.1",
"eslint-plugin-cypress": "2.15.1",
"eslint-plugin-prettier": "^5.0.0",
"express": "4.18.2",
"express": "4.18.3",
"express-graphql": "0.12.0",
"express-jwt": "6.1.2",
"express-paginate": "1.0.2",
Expand All @@ -114,7 +113,7 @@
"graphql-tools": "8.2.7",
"http-proxy-middleware": "0.19.1",
"husky": "7.0.4",
"istanbul-lib-coverage": "3.2.0",
"istanbul-lib-coverage": "3.2.2",
"jsdom": "^22.1.0",
"json": "11.0.0",
"jwks-rsa": "2.0.5",
Expand Down
17 changes: 15 additions & 2 deletions scripts/mock-aws-exports-es5.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,21 @@
// mock aws-exports-es5.js

const awsmobile = {
aws_cognito_region: "",
aws_user_pools_id: "",
Auth: {
Cognito: {
userPoolId: "us-east-1_abcdefghi",
userPoolClientId: "a1b2c3d4e5f6g7h8i9j0k1l2m",
loginWith: {
oauth: {
domain: "YOUR_COGNITO_USER_POOL_HOSTED_UI_DOMAIN_PREFIX.auth.us-east-1.amazoncognito.com",
scopes: ["email", "openid", "aws.cognito.signin.user.admin"],
redirectSignIn: ["http://localhost:3000/"],
redirectSignOut: ["http://localhost:3000/"],
responseType: "token",
},
},
},
},
};

exports.default = awsmobile;
17 changes: 15 additions & 2 deletions scripts/mock-aws-exports.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,21 @@
// mock aws-exports.js

const awsmobile = {
aws_cognito_region: "",
aws_user_pools_id: "",
Auth: {
Cognito: {
userPoolId: "us-east-1_abcdefghi",
userPoolClientId: "a1b2c3d4e5f6g7h8i9j0k1l2m",
loginWith: {
oauth: {
domain: "YOUR_COGNITO_USER_POOL_HOSTED_UI_DOMAIN_PREFIX.auth.us-east-1.amazoncognito.com",
scopes: ["email", "openid", "aws.cognito.signin.user.admin"],
redirectSignIn: ["http://localhost:3000/"],
redirectSignOut: ["http://localhost:3000/"],
responseType: "token",
},
},
},
},
};

export default awsmobile;
Loading

0 comments on commit 9493d8f

Please sign in to comment.