From 805d2518fd54b66bcf161e653cdae7ebebf73d31 Mon Sep 17 00:00:00 2001 From: Ulises Gascon Date: Wed, 18 Mar 2020 17:46:48 +0100 Subject: [PATCH 01/10] server-render app moved to new location apps/server-render --- .../server-render/.dockerignore | 0 .jshintrc => apps/server-render/.jshintrc | 0 Dockerfile => apps/server-render/Dockerfile | 0 .../server-render/Gruntfile.js | 0 apps/server-render/README.md | 119 ++++++++++++++++++ app.json => apps/server-render/app.json | 0 .../server-render/app}/assets/favicon.ico | Bin .../app}/assets/images/nodegoat_logo.png | Bin .../app}/assets/images/owasplogo.png | Bin .../app}/assets/js/chart/chart-data-morris.js | 0 .../app}/assets/js/tour/redirects-steps.js | 0 .../vendor/bootstrap/bootstrap-tour.css | 0 .../assets/vendor/bootstrap/bootstrap-tour.js | 0 .../assets/vendor/bootstrap/bootstrap.css | 0 .../app}/assets/vendor/bootstrap/bootstrap.js | 0 .../assets/vendor/chart/morris-0.4.3.min.js | 0 .../app}/assets/vendor/chart/raphael-min.js | 0 .../app}/assets/vendor/html5shiv.js | 0 .../app}/assets/vendor/jquery.min.js | 0 .../font-awesome/css/font-awesome.min.css | 0 .../theme/font-awesome/fonts/FontAwesome.otf | Bin .../fonts/fontawesome-webfont.eot | Bin .../fonts/fontawesome-webfont.svg | 0 .../fonts/fontawesome-webfont.ttf | Bin .../fonts/fontawesome-webfont.woff | Bin .../app}/assets/vendor/theme/sb-admin.css | 0 .../app}/data/allocations-dao.js | 0 .../server-render/app}/data/benefits-dao.js | 0 .../app}/data/contributions-dao.js | 0 .../server-render/app}/data/memos-dao.js | 0 .../server-render/app}/data/profile-dao.js | 0 .../server-render/app}/data/research-dao.js | 0 .../server-render/app}/data/user-dao.js | 0 .../server-render/app}/routes/allocations.js | 0 .../server-render/app}/routes/benefits.js | 0 .../app}/routes/contributions.js | 0 .../server-render/app}/routes/error.js | 0 .../server-render/app}/routes/index.js | 0 .../server-render/app}/routes/memos.js | 0 .../server-render/app}/routes/profile.js | 0 .../server-render/app}/routes/research.js | 0 .../server-render/app}/routes/session.js | 0 .../server-render/app}/views/allocations.html | 0 .../server-render/app}/views/benefits.html | 0 .../app}/views/contributions.html | 0 .../server-render/app}/views/dashboard.html | 0 .../app}/views/error-template.html | 0 .../server-render/app}/views/layout.html | 0 .../server-render/app}/views/login.html | 0 .../server-render/app}/views/memos.html | 0 .../server-render/app}/views/profile.html | 0 .../server-render/app}/views/research.html | 0 .../server-render/app}/views/signup.html | 0 .../server-render/app}/views/tutorial/a1.html | 0 .../app}/views/tutorial/a10.html | 0 .../server-render/app}/views/tutorial/a2.html | 0 .../server-render/app}/views/tutorial/a3.html | 0 .../server-render/app}/views/tutorial/a4.html | 0 .../server-render/app}/views/tutorial/a5.html | 0 .../server-render/app}/views/tutorial/a6.html | 0 .../server-render/app}/views/tutorial/a7.html | 0 .../server-render/app}/views/tutorial/a8.html | 0 .../server-render/app}/views/tutorial/a9.html | 0 .../app}/views/tutorial/layout.html | 0 .../app}/views/tutorial/redos.html | 0 .../app}/views/tutorial/ssrf.html | 0 .../server-render/artifacts}/cert/server.crt | 0 .../server-render/artifacts}/cert/server.key | 0 .../server-render/artifacts}/db-reset.js | 0 .../server-render/config}/config.js | 0 .../server-render/config}/env/all.js | 0 .../server-render/config}/env/development.js | 0 .../server-render/config}/env/production.js | 0 .../server-render/config}/env/test.js | 0 .../server-render/cypress.json | 0 .../server-render/docker-compose.yml | 0 .../server-render/nodemon.json | 0 .../server-render/package-lock.json | 0 .../server-render/package.json | 0 server.js => apps/server-render/server.js | 0 .../test}/e2e/fixtures/users/admin.json | 0 .../test}/e2e/fixtures/users/new_user.json | 0 .../test}/e2e/fixtures/users/user.json | 0 .../test}/e2e/integration/allocations_spec.js | 0 .../test}/e2e/integration/benefits_spec.js | 0 .../e2e/integration/contributions_spec.js | 0 .../test}/e2e/integration/dashboard_spec.js | 0 .../test}/e2e/integration/general_spec.js | 0 .../test}/e2e/integration/learn_spec.js | 0 .../test}/e2e/integration/login_spec.js | 0 .../test}/e2e/integration/logout_spec.js | 0 .../test}/e2e/integration/memos_spec.js | 0 .../test}/e2e/integration/profile_spec.js | 0 .../test}/e2e/integration/research_spec.js | 0 .../test}/e2e/integration/signup_spec.js | 0 .../test}/e2e/integration/tutorial_spec.js | 0 .../server-render/test}/e2e/plugins/index.js | 0 .../test}/e2e/support/commands.js | 0 .../server-render/test}/e2e/support/index.js | 0 .../server-render/test}/e2e/tsconfig.json | 0 .../test}/security/profile-test.js | 0 101 files changed, 119 insertions(+) rename .dockerignore => apps/server-render/.dockerignore (100%) rename .jshintrc => apps/server-render/.jshintrc (100%) rename Dockerfile => apps/server-render/Dockerfile (100%) rename Gruntfile.js => apps/server-render/Gruntfile.js (100%) create mode 100644 apps/server-render/README.md rename app.json => apps/server-render/app.json (100%) rename {app => apps/server-render/app}/assets/favicon.ico (100%) rename {app => apps/server-render/app}/assets/images/nodegoat_logo.png (100%) rename {app => apps/server-render/app}/assets/images/owasplogo.png (100%) rename {app => apps/server-render/app}/assets/js/chart/chart-data-morris.js (100%) rename {app => apps/server-render/app}/assets/js/tour/redirects-steps.js (100%) rename {app => apps/server-render/app}/assets/vendor/bootstrap/bootstrap-tour.css (100%) rename {app => apps/server-render/app}/assets/vendor/bootstrap/bootstrap-tour.js (100%) rename {app => apps/server-render/app}/assets/vendor/bootstrap/bootstrap.css (100%) rename {app => apps/server-render/app}/assets/vendor/bootstrap/bootstrap.js (100%) rename {app => apps/server-render/app}/assets/vendor/chart/morris-0.4.3.min.js (100%) rename {app => apps/server-render/app}/assets/vendor/chart/raphael-min.js (100%) rename {app => apps/server-render/app}/assets/vendor/html5shiv.js (100%) rename {app => apps/server-render/app}/assets/vendor/jquery.min.js (100%) rename {app => apps/server-render/app}/assets/vendor/theme/font-awesome/css/font-awesome.min.css (100%) rename {app => apps/server-render/app}/assets/vendor/theme/font-awesome/fonts/FontAwesome.otf (100%) rename {app => apps/server-render/app}/assets/vendor/theme/font-awesome/fonts/fontawesome-webfont.eot (100%) rename {app => apps/server-render/app}/assets/vendor/theme/font-awesome/fonts/fontawesome-webfont.svg (100%) rename {app => apps/server-render/app}/assets/vendor/theme/font-awesome/fonts/fontawesome-webfont.ttf (100%) rename {app => apps/server-render/app}/assets/vendor/theme/font-awesome/fonts/fontawesome-webfont.woff (100%) rename {app => apps/server-render/app}/assets/vendor/theme/sb-admin.css (100%) rename {app => apps/server-render/app}/data/allocations-dao.js (100%) rename {app => apps/server-render/app}/data/benefits-dao.js (100%) rename {app => apps/server-render/app}/data/contributions-dao.js (100%) rename {app => apps/server-render/app}/data/memos-dao.js (100%) rename {app => apps/server-render/app}/data/profile-dao.js (100%) rename {app => apps/server-render/app}/data/research-dao.js (100%) rename {app => apps/server-render/app}/data/user-dao.js (100%) rename {app => apps/server-render/app}/routes/allocations.js (100%) rename {app => apps/server-render/app}/routes/benefits.js (100%) rename {app => apps/server-render/app}/routes/contributions.js (100%) rename {app => apps/server-render/app}/routes/error.js (100%) rename {app => apps/server-render/app}/routes/index.js (100%) rename {app => apps/server-render/app}/routes/memos.js (100%) rename {app => apps/server-render/app}/routes/profile.js (100%) rename {app => apps/server-render/app}/routes/research.js (100%) rename {app => apps/server-render/app}/routes/session.js (100%) rename {app => apps/server-render/app}/views/allocations.html (100%) rename {app => apps/server-render/app}/views/benefits.html (100%) rename {app => apps/server-render/app}/views/contributions.html (100%) rename {app => apps/server-render/app}/views/dashboard.html (100%) rename {app => apps/server-render/app}/views/error-template.html (100%) rename {app => apps/server-render/app}/views/layout.html (100%) rename {app => apps/server-render/app}/views/login.html (100%) rename {app => apps/server-render/app}/views/memos.html (100%) rename {app => apps/server-render/app}/views/profile.html (100%) rename {app => apps/server-render/app}/views/research.html (100%) rename {app => apps/server-render/app}/views/signup.html (100%) rename {app => apps/server-render/app}/views/tutorial/a1.html (100%) rename {app => apps/server-render/app}/views/tutorial/a10.html (100%) rename {app => apps/server-render/app}/views/tutorial/a2.html (100%) rename {app => apps/server-render/app}/views/tutorial/a3.html (100%) rename {app => apps/server-render/app}/views/tutorial/a4.html (100%) rename {app => apps/server-render/app}/views/tutorial/a5.html (100%) rename {app => apps/server-render/app}/views/tutorial/a6.html (100%) rename {app => apps/server-render/app}/views/tutorial/a7.html (100%) rename {app => apps/server-render/app}/views/tutorial/a8.html (100%) rename {app => apps/server-render/app}/views/tutorial/a9.html (100%) rename {app => apps/server-render/app}/views/tutorial/layout.html (100%) rename {app => apps/server-render/app}/views/tutorial/redos.html (100%) rename {app => apps/server-render/app}/views/tutorial/ssrf.html (100%) rename {artifacts => apps/server-render/artifacts}/cert/server.crt (100%) rename {artifacts => apps/server-render/artifacts}/cert/server.key (100%) rename {artifacts => apps/server-render/artifacts}/db-reset.js (100%) rename {config => apps/server-render/config}/config.js (100%) rename {config => apps/server-render/config}/env/all.js (100%) rename {config => apps/server-render/config}/env/development.js (100%) rename {config => apps/server-render/config}/env/production.js (100%) rename {config => apps/server-render/config}/env/test.js (100%) rename cypress.json => apps/server-render/cypress.json (100%) rename docker-compose.yml => apps/server-render/docker-compose.yml (100%) rename nodemon.json => apps/server-render/nodemon.json (100%) rename package-lock.json => apps/server-render/package-lock.json (100%) rename package.json => apps/server-render/package.json (100%) rename server.js => apps/server-render/server.js (100%) rename {test => apps/server-render/test}/e2e/fixtures/users/admin.json (100%) rename {test => apps/server-render/test}/e2e/fixtures/users/new_user.json (100%) rename {test => apps/server-render/test}/e2e/fixtures/users/user.json (100%) rename {test => apps/server-render/test}/e2e/integration/allocations_spec.js (100%) rename {test => apps/server-render/test}/e2e/integration/benefits_spec.js (100%) rename {test => apps/server-render/test}/e2e/integration/contributions_spec.js (100%) rename {test => apps/server-render/test}/e2e/integration/dashboard_spec.js (100%) rename {test => apps/server-render/test}/e2e/integration/general_spec.js (100%) rename {test => apps/server-render/test}/e2e/integration/learn_spec.js (100%) rename {test => apps/server-render/test}/e2e/integration/login_spec.js (100%) rename {test => apps/server-render/test}/e2e/integration/logout_spec.js (100%) rename {test => apps/server-render/test}/e2e/integration/memos_spec.js (100%) rename {test => apps/server-render/test}/e2e/integration/profile_spec.js (100%) rename {test => apps/server-render/test}/e2e/integration/research_spec.js (100%) rename {test => apps/server-render/test}/e2e/integration/signup_spec.js (100%) rename {test => apps/server-render/test}/e2e/integration/tutorial_spec.js (100%) rename {test => apps/server-render/test}/e2e/plugins/index.js (100%) rename {test => apps/server-render/test}/e2e/support/commands.js (100%) rename {test => apps/server-render/test}/e2e/support/index.js (100%) rename {test => apps/server-render/test}/e2e/tsconfig.json (100%) rename {test => apps/server-render/test}/security/profile-test.js (100%) diff --git a/.dockerignore b/apps/server-render/.dockerignore similarity index 100% rename from .dockerignore rename to apps/server-render/.dockerignore diff --git a/.jshintrc b/apps/server-render/.jshintrc similarity index 100% rename from .jshintrc rename to apps/server-render/.jshintrc diff --git a/Dockerfile b/apps/server-render/Dockerfile similarity index 100% rename from Dockerfile rename to apps/server-render/Dockerfile diff --git a/Gruntfile.js b/apps/server-render/Gruntfile.js similarity index 100% rename from Gruntfile.js rename to apps/server-render/Gruntfile.js diff --git a/apps/server-render/README.md b/apps/server-render/README.md new file mode 100644 index 000000000..a58c67034 --- /dev/null +++ b/apps/server-render/README.md @@ -0,0 +1,119 @@ +# NodeGoat + +Being lightweight, fast, and scalable, Node.js is becoming a widely adopted platform for developing web applications. This project provides an environment to learn how OWASP Top 10 security risks apply to web applications developed using Node.js and how to effectively address them. + +## Getting Started +OWASP Top 10 for Node.js web applications: + +### Know it! +[Tutorial Guide](http://nodegoat.herokuapp.com/tutorial) explaining how each of the OWASP Top 10 vulnerabilities can manifest in Node.js web apps and how to prevent it. + +### Do it! +[A Vulnerable Node.js App for Ninjas](http://nodegoat.herokuapp.com/) to exploit, toast, and fix. You may like to [set up your own copy](#how-to-setup-your-copy-of-nodegoat) of the app to fix and test vulnerabilities. Hint: Look for comments in the source code. +##### Default user accounts +The database comes pre-populated with these user accounts created as part of the seed data - +* Admin Account - u:admin p:Admin_123 +* User Accounts (u:user1 p:User1_123), (u:user2 p:User2_123) +* New users can also be added using the sign-up page. + +## How to Setup Your Copy of NodeGoat + +### OPTION 1 - One click install on Heroku +The the quickest way to get running with NodeGoat is to click the button below to deploy it on Heroku. + +Even though it is not essential, but recommended that you fork this repository and deploy the forked repo. +This would allow you to fix vulnerabilities in your own forked version, and deploy and test it on heroku. + +[![Deploy](https://www.herokucdn.com/deploy/button.png)](https://heroku.com/deploy) + +This Heroku instance uses Free ($0/month) node server and MongoLab add-on. + +### OPTION 2 - Run NodeGoat on your machine + +If you do not wish to run NodeGoat on Heroku, please follow these steps to setup and run it locally - +* Install [Node.js](http://nodejs.org/) - NodeGoat requires Node v8 or above + +* Clone the github repository +``` +git clone https://github.com/OWASP/NodeGoat.git +``` + +*go to the directory +``` +cd NodeGoat +``` + +* Install node modules +``` +npm install +``` + +* Create Mongo DB: + You can create a remote MongoDB instance or use local mongod installation + * A. Using Remote MongoDB + * Create a sandbox mongoDB instance (free) at [mLab](https://mlab.com/plans/pricing/#plan-sandbox) + * Create a new database. + * Create a user. + * Update the `db` property in file `config/env/development.js` to reflect your DB setup. (in format: `mongodb://:@`) + * OR B.Using local MongoDB + * If using local Mongo DB instance, start [mongod](http://docs.mongodb.org/manual/reference/program/mongod/#bin.mongod). + * Update the `db` property in file `config/env/development.js` to reflect your DB setup. (in format: `mongodb://localhost:27017/`) + +* Populate MongoDB with seed data required for the app + * Run the npm-script below to populate the DB with seed data required for the application. Pass the desired environment as argument. If not passed, "development" is the default: +``` +npm run db:seed +``` +* Start server, this starts the NodeGoat application at url [http://localhost:4000/](http://localhost:4000/) +``` +npm start +``` + +* Start server with nodemon, this starts the NodeGoat application at url [http://localhost:5000/](http://localhost:5000/) +``` +npm run dev +``` + +### OPTION 3 - Run NodeGoat on Docker + +**You need to install [docker](https://docs.docker.com/installation/) and [docker compose](https://docs.docker.com/compose/install/) to be able to use this option** + +The repo includes the Dockerfile and docker-compose.yml necessary to setup the app and the db instance then connect them together. + +* Change the db config in `config/env/development.js` to point to the respective Docker container. +``` +db: "mongodb://mongo:27017/nodegoat", +``` +* Build the images: +``` +docker-compose build +``` +* Run the app: +``` +docker-compose up +``` + + +#### Customizing the Default Application Configuration +The default application settings (database url, http port, etc.) can be changed by updating the [config file] (https://github.com/OWASP/NodeGoat/blob/master/config/env/all.js). + +## Report bugs, Feedback, Comments +* Open a new [issue](https://github.com/OWASP/NodeGoat/issues) or contact team by joining chat at [Slack](https://owasp.slack.com/messages/project-nodegoat/) or [![Join the chat at https://gitter.im/OWASP/NodeGoat](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/OWASP/NodeGoat?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) + + +## Contributing + +Please Follow [the contributing guide](CONTRIBUTING.md) + +## Code Of Conduct (CoC) + +This project is bound by a [Code of Conduct](CODE_OF_CONDUCT.md). + +## Contributors +Here are the amazing [contributors](https://github.com/OWASP/NodeGoat/graphs/contributors) to the NodeGoat project. + +## Supports +- Thanks to JetBrains for providing licenses to fantastic [WebStorm IDE](https://www.jetbrains.com/webstorm/) to build this project. + +## License +Code licensed under the [Apache License v2.0.](http://www.apache.org/licenses/LICENSE-2.0) diff --git a/app.json b/apps/server-render/app.json similarity index 100% rename from app.json rename to apps/server-render/app.json diff --git a/app/assets/favicon.ico b/apps/server-render/app/assets/favicon.ico similarity index 100% rename from app/assets/favicon.ico rename to apps/server-render/app/assets/favicon.ico diff --git a/app/assets/images/nodegoat_logo.png b/apps/server-render/app/assets/images/nodegoat_logo.png similarity index 100% rename from app/assets/images/nodegoat_logo.png rename to apps/server-render/app/assets/images/nodegoat_logo.png diff --git a/app/assets/images/owasplogo.png b/apps/server-render/app/assets/images/owasplogo.png similarity index 100% rename from app/assets/images/owasplogo.png rename to apps/server-render/app/assets/images/owasplogo.png diff --git a/app/assets/js/chart/chart-data-morris.js b/apps/server-render/app/assets/js/chart/chart-data-morris.js similarity index 100% rename from app/assets/js/chart/chart-data-morris.js rename to apps/server-render/app/assets/js/chart/chart-data-morris.js diff --git a/app/assets/js/tour/redirects-steps.js b/apps/server-render/app/assets/js/tour/redirects-steps.js similarity index 100% rename from app/assets/js/tour/redirects-steps.js rename to apps/server-render/app/assets/js/tour/redirects-steps.js diff --git a/app/assets/vendor/bootstrap/bootstrap-tour.css b/apps/server-render/app/assets/vendor/bootstrap/bootstrap-tour.css similarity index 100% rename from app/assets/vendor/bootstrap/bootstrap-tour.css rename to apps/server-render/app/assets/vendor/bootstrap/bootstrap-tour.css diff --git a/app/assets/vendor/bootstrap/bootstrap-tour.js b/apps/server-render/app/assets/vendor/bootstrap/bootstrap-tour.js similarity index 100% rename from app/assets/vendor/bootstrap/bootstrap-tour.js rename to apps/server-render/app/assets/vendor/bootstrap/bootstrap-tour.js diff --git a/app/assets/vendor/bootstrap/bootstrap.css b/apps/server-render/app/assets/vendor/bootstrap/bootstrap.css similarity index 100% rename from app/assets/vendor/bootstrap/bootstrap.css rename to apps/server-render/app/assets/vendor/bootstrap/bootstrap.css diff --git a/app/assets/vendor/bootstrap/bootstrap.js b/apps/server-render/app/assets/vendor/bootstrap/bootstrap.js similarity index 100% rename from app/assets/vendor/bootstrap/bootstrap.js rename to apps/server-render/app/assets/vendor/bootstrap/bootstrap.js diff --git a/app/assets/vendor/chart/morris-0.4.3.min.js b/apps/server-render/app/assets/vendor/chart/morris-0.4.3.min.js similarity index 100% rename from app/assets/vendor/chart/morris-0.4.3.min.js rename to apps/server-render/app/assets/vendor/chart/morris-0.4.3.min.js diff --git a/app/assets/vendor/chart/raphael-min.js b/apps/server-render/app/assets/vendor/chart/raphael-min.js similarity index 100% rename from app/assets/vendor/chart/raphael-min.js rename to apps/server-render/app/assets/vendor/chart/raphael-min.js diff --git a/app/assets/vendor/html5shiv.js b/apps/server-render/app/assets/vendor/html5shiv.js similarity index 100% rename from app/assets/vendor/html5shiv.js rename to apps/server-render/app/assets/vendor/html5shiv.js diff --git a/app/assets/vendor/jquery.min.js b/apps/server-render/app/assets/vendor/jquery.min.js similarity index 100% rename from app/assets/vendor/jquery.min.js rename to apps/server-render/app/assets/vendor/jquery.min.js diff --git a/app/assets/vendor/theme/font-awesome/css/font-awesome.min.css b/apps/server-render/app/assets/vendor/theme/font-awesome/css/font-awesome.min.css similarity index 100% rename from app/assets/vendor/theme/font-awesome/css/font-awesome.min.css rename to apps/server-render/app/assets/vendor/theme/font-awesome/css/font-awesome.min.css diff --git a/app/assets/vendor/theme/font-awesome/fonts/FontAwesome.otf b/apps/server-render/app/assets/vendor/theme/font-awesome/fonts/FontAwesome.otf similarity index 100% rename from app/assets/vendor/theme/font-awesome/fonts/FontAwesome.otf rename to apps/server-render/app/assets/vendor/theme/font-awesome/fonts/FontAwesome.otf diff --git a/app/assets/vendor/theme/font-awesome/fonts/fontawesome-webfont.eot b/apps/server-render/app/assets/vendor/theme/font-awesome/fonts/fontawesome-webfont.eot similarity index 100% rename from app/assets/vendor/theme/font-awesome/fonts/fontawesome-webfont.eot rename to apps/server-render/app/assets/vendor/theme/font-awesome/fonts/fontawesome-webfont.eot diff --git a/app/assets/vendor/theme/font-awesome/fonts/fontawesome-webfont.svg b/apps/server-render/app/assets/vendor/theme/font-awesome/fonts/fontawesome-webfont.svg similarity index 100% rename from app/assets/vendor/theme/font-awesome/fonts/fontawesome-webfont.svg rename to apps/server-render/app/assets/vendor/theme/font-awesome/fonts/fontawesome-webfont.svg diff --git a/app/assets/vendor/theme/font-awesome/fonts/fontawesome-webfont.ttf b/apps/server-render/app/assets/vendor/theme/font-awesome/fonts/fontawesome-webfont.ttf similarity index 100% rename from app/assets/vendor/theme/font-awesome/fonts/fontawesome-webfont.ttf rename to apps/server-render/app/assets/vendor/theme/font-awesome/fonts/fontawesome-webfont.ttf diff --git a/app/assets/vendor/theme/font-awesome/fonts/fontawesome-webfont.woff b/apps/server-render/app/assets/vendor/theme/font-awesome/fonts/fontawesome-webfont.woff similarity index 100% rename from app/assets/vendor/theme/font-awesome/fonts/fontawesome-webfont.woff rename to apps/server-render/app/assets/vendor/theme/font-awesome/fonts/fontawesome-webfont.woff diff --git a/app/assets/vendor/theme/sb-admin.css b/apps/server-render/app/assets/vendor/theme/sb-admin.css similarity index 100% rename from app/assets/vendor/theme/sb-admin.css rename to apps/server-render/app/assets/vendor/theme/sb-admin.css diff --git a/app/data/allocations-dao.js b/apps/server-render/app/data/allocations-dao.js similarity index 100% rename from app/data/allocations-dao.js rename to apps/server-render/app/data/allocations-dao.js diff --git a/app/data/benefits-dao.js b/apps/server-render/app/data/benefits-dao.js similarity index 100% rename from app/data/benefits-dao.js rename to apps/server-render/app/data/benefits-dao.js diff --git a/app/data/contributions-dao.js b/apps/server-render/app/data/contributions-dao.js similarity index 100% rename from app/data/contributions-dao.js rename to apps/server-render/app/data/contributions-dao.js diff --git a/app/data/memos-dao.js b/apps/server-render/app/data/memos-dao.js similarity index 100% rename from app/data/memos-dao.js rename to apps/server-render/app/data/memos-dao.js diff --git a/app/data/profile-dao.js b/apps/server-render/app/data/profile-dao.js similarity index 100% rename from app/data/profile-dao.js rename to apps/server-render/app/data/profile-dao.js diff --git a/app/data/research-dao.js b/apps/server-render/app/data/research-dao.js similarity index 100% rename from app/data/research-dao.js rename to apps/server-render/app/data/research-dao.js diff --git a/app/data/user-dao.js b/apps/server-render/app/data/user-dao.js similarity index 100% rename from app/data/user-dao.js rename to apps/server-render/app/data/user-dao.js diff --git a/app/routes/allocations.js b/apps/server-render/app/routes/allocations.js similarity index 100% rename from app/routes/allocations.js rename to apps/server-render/app/routes/allocations.js diff --git a/app/routes/benefits.js b/apps/server-render/app/routes/benefits.js similarity index 100% rename from app/routes/benefits.js rename to apps/server-render/app/routes/benefits.js diff --git a/app/routes/contributions.js b/apps/server-render/app/routes/contributions.js similarity index 100% rename from app/routes/contributions.js rename to apps/server-render/app/routes/contributions.js diff --git a/app/routes/error.js b/apps/server-render/app/routes/error.js similarity index 100% rename from app/routes/error.js rename to apps/server-render/app/routes/error.js diff --git a/app/routes/index.js b/apps/server-render/app/routes/index.js similarity index 100% rename from app/routes/index.js rename to apps/server-render/app/routes/index.js diff --git a/app/routes/memos.js b/apps/server-render/app/routes/memos.js similarity index 100% rename from app/routes/memos.js rename to apps/server-render/app/routes/memos.js diff --git a/app/routes/profile.js b/apps/server-render/app/routes/profile.js similarity index 100% rename from app/routes/profile.js rename to apps/server-render/app/routes/profile.js diff --git a/app/routes/research.js b/apps/server-render/app/routes/research.js similarity index 100% rename from app/routes/research.js rename to apps/server-render/app/routes/research.js diff --git a/app/routes/session.js b/apps/server-render/app/routes/session.js similarity index 100% rename from app/routes/session.js rename to apps/server-render/app/routes/session.js diff --git a/app/views/allocations.html b/apps/server-render/app/views/allocations.html similarity index 100% rename from app/views/allocations.html rename to apps/server-render/app/views/allocations.html diff --git a/app/views/benefits.html b/apps/server-render/app/views/benefits.html similarity index 100% rename from app/views/benefits.html rename to apps/server-render/app/views/benefits.html diff --git a/app/views/contributions.html b/apps/server-render/app/views/contributions.html similarity index 100% rename from app/views/contributions.html rename to apps/server-render/app/views/contributions.html diff --git a/app/views/dashboard.html b/apps/server-render/app/views/dashboard.html similarity index 100% rename from app/views/dashboard.html rename to apps/server-render/app/views/dashboard.html diff --git a/app/views/error-template.html b/apps/server-render/app/views/error-template.html similarity index 100% rename from app/views/error-template.html rename to apps/server-render/app/views/error-template.html diff --git a/app/views/layout.html b/apps/server-render/app/views/layout.html similarity index 100% rename from app/views/layout.html rename to apps/server-render/app/views/layout.html diff --git a/app/views/login.html b/apps/server-render/app/views/login.html similarity index 100% rename from app/views/login.html rename to apps/server-render/app/views/login.html diff --git a/app/views/memos.html b/apps/server-render/app/views/memos.html similarity index 100% rename from app/views/memos.html rename to apps/server-render/app/views/memos.html diff --git a/app/views/profile.html b/apps/server-render/app/views/profile.html similarity index 100% rename from app/views/profile.html rename to apps/server-render/app/views/profile.html diff --git a/app/views/research.html b/apps/server-render/app/views/research.html similarity index 100% rename from app/views/research.html rename to apps/server-render/app/views/research.html diff --git a/app/views/signup.html b/apps/server-render/app/views/signup.html similarity index 100% rename from app/views/signup.html rename to apps/server-render/app/views/signup.html diff --git a/app/views/tutorial/a1.html b/apps/server-render/app/views/tutorial/a1.html similarity index 100% rename from app/views/tutorial/a1.html rename to apps/server-render/app/views/tutorial/a1.html diff --git a/app/views/tutorial/a10.html b/apps/server-render/app/views/tutorial/a10.html similarity index 100% rename from app/views/tutorial/a10.html rename to apps/server-render/app/views/tutorial/a10.html diff --git a/app/views/tutorial/a2.html b/apps/server-render/app/views/tutorial/a2.html similarity index 100% rename from app/views/tutorial/a2.html rename to apps/server-render/app/views/tutorial/a2.html diff --git a/app/views/tutorial/a3.html b/apps/server-render/app/views/tutorial/a3.html similarity index 100% rename from app/views/tutorial/a3.html rename to apps/server-render/app/views/tutorial/a3.html diff --git a/app/views/tutorial/a4.html b/apps/server-render/app/views/tutorial/a4.html similarity index 100% rename from app/views/tutorial/a4.html rename to apps/server-render/app/views/tutorial/a4.html diff --git a/app/views/tutorial/a5.html b/apps/server-render/app/views/tutorial/a5.html similarity index 100% rename from app/views/tutorial/a5.html rename to apps/server-render/app/views/tutorial/a5.html diff --git a/app/views/tutorial/a6.html b/apps/server-render/app/views/tutorial/a6.html similarity index 100% rename from app/views/tutorial/a6.html rename to apps/server-render/app/views/tutorial/a6.html diff --git a/app/views/tutorial/a7.html b/apps/server-render/app/views/tutorial/a7.html similarity index 100% rename from app/views/tutorial/a7.html rename to apps/server-render/app/views/tutorial/a7.html diff --git a/app/views/tutorial/a8.html b/apps/server-render/app/views/tutorial/a8.html similarity index 100% rename from app/views/tutorial/a8.html rename to apps/server-render/app/views/tutorial/a8.html diff --git a/app/views/tutorial/a9.html b/apps/server-render/app/views/tutorial/a9.html similarity index 100% rename from app/views/tutorial/a9.html rename to apps/server-render/app/views/tutorial/a9.html diff --git a/app/views/tutorial/layout.html b/apps/server-render/app/views/tutorial/layout.html similarity index 100% rename from app/views/tutorial/layout.html rename to apps/server-render/app/views/tutorial/layout.html diff --git a/app/views/tutorial/redos.html b/apps/server-render/app/views/tutorial/redos.html similarity index 100% rename from app/views/tutorial/redos.html rename to apps/server-render/app/views/tutorial/redos.html diff --git a/app/views/tutorial/ssrf.html b/apps/server-render/app/views/tutorial/ssrf.html similarity index 100% rename from app/views/tutorial/ssrf.html rename to apps/server-render/app/views/tutorial/ssrf.html diff --git a/artifacts/cert/server.crt b/apps/server-render/artifacts/cert/server.crt similarity index 100% rename from artifacts/cert/server.crt rename to apps/server-render/artifacts/cert/server.crt diff --git a/artifacts/cert/server.key b/apps/server-render/artifacts/cert/server.key similarity index 100% rename from artifacts/cert/server.key rename to apps/server-render/artifacts/cert/server.key diff --git a/artifacts/db-reset.js b/apps/server-render/artifacts/db-reset.js similarity index 100% rename from artifacts/db-reset.js rename to apps/server-render/artifacts/db-reset.js diff --git a/config/config.js b/apps/server-render/config/config.js similarity index 100% rename from config/config.js rename to apps/server-render/config/config.js diff --git a/config/env/all.js b/apps/server-render/config/env/all.js similarity index 100% rename from config/env/all.js rename to apps/server-render/config/env/all.js diff --git a/config/env/development.js b/apps/server-render/config/env/development.js similarity index 100% rename from config/env/development.js rename to apps/server-render/config/env/development.js diff --git a/config/env/production.js b/apps/server-render/config/env/production.js similarity index 100% rename from config/env/production.js rename to apps/server-render/config/env/production.js diff --git a/config/env/test.js b/apps/server-render/config/env/test.js similarity index 100% rename from config/env/test.js rename to apps/server-render/config/env/test.js diff --git a/cypress.json b/apps/server-render/cypress.json similarity index 100% rename from cypress.json rename to apps/server-render/cypress.json diff --git a/docker-compose.yml b/apps/server-render/docker-compose.yml similarity index 100% rename from docker-compose.yml rename to apps/server-render/docker-compose.yml diff --git a/nodemon.json b/apps/server-render/nodemon.json similarity index 100% rename from nodemon.json rename to apps/server-render/nodemon.json diff --git a/package-lock.json b/apps/server-render/package-lock.json similarity index 100% rename from package-lock.json rename to apps/server-render/package-lock.json diff --git a/package.json b/apps/server-render/package.json similarity index 100% rename from package.json rename to apps/server-render/package.json diff --git a/server.js b/apps/server-render/server.js similarity index 100% rename from server.js rename to apps/server-render/server.js diff --git a/test/e2e/fixtures/users/admin.json b/apps/server-render/test/e2e/fixtures/users/admin.json similarity index 100% rename from test/e2e/fixtures/users/admin.json rename to apps/server-render/test/e2e/fixtures/users/admin.json diff --git a/test/e2e/fixtures/users/new_user.json b/apps/server-render/test/e2e/fixtures/users/new_user.json similarity index 100% rename from test/e2e/fixtures/users/new_user.json rename to apps/server-render/test/e2e/fixtures/users/new_user.json diff --git a/test/e2e/fixtures/users/user.json b/apps/server-render/test/e2e/fixtures/users/user.json similarity index 100% rename from test/e2e/fixtures/users/user.json rename to apps/server-render/test/e2e/fixtures/users/user.json diff --git a/test/e2e/integration/allocations_spec.js b/apps/server-render/test/e2e/integration/allocations_spec.js similarity index 100% rename from test/e2e/integration/allocations_spec.js rename to apps/server-render/test/e2e/integration/allocations_spec.js diff --git a/test/e2e/integration/benefits_spec.js b/apps/server-render/test/e2e/integration/benefits_spec.js similarity index 100% rename from test/e2e/integration/benefits_spec.js rename to apps/server-render/test/e2e/integration/benefits_spec.js diff --git a/test/e2e/integration/contributions_spec.js b/apps/server-render/test/e2e/integration/contributions_spec.js similarity index 100% rename from test/e2e/integration/contributions_spec.js rename to apps/server-render/test/e2e/integration/contributions_spec.js diff --git a/test/e2e/integration/dashboard_spec.js b/apps/server-render/test/e2e/integration/dashboard_spec.js similarity index 100% rename from test/e2e/integration/dashboard_spec.js rename to apps/server-render/test/e2e/integration/dashboard_spec.js diff --git a/test/e2e/integration/general_spec.js b/apps/server-render/test/e2e/integration/general_spec.js similarity index 100% rename from test/e2e/integration/general_spec.js rename to apps/server-render/test/e2e/integration/general_spec.js diff --git a/test/e2e/integration/learn_spec.js b/apps/server-render/test/e2e/integration/learn_spec.js similarity index 100% rename from test/e2e/integration/learn_spec.js rename to apps/server-render/test/e2e/integration/learn_spec.js diff --git a/test/e2e/integration/login_spec.js b/apps/server-render/test/e2e/integration/login_spec.js similarity index 100% rename from test/e2e/integration/login_spec.js rename to apps/server-render/test/e2e/integration/login_spec.js diff --git a/test/e2e/integration/logout_spec.js b/apps/server-render/test/e2e/integration/logout_spec.js similarity index 100% rename from test/e2e/integration/logout_spec.js rename to apps/server-render/test/e2e/integration/logout_spec.js diff --git a/test/e2e/integration/memos_spec.js b/apps/server-render/test/e2e/integration/memos_spec.js similarity index 100% rename from test/e2e/integration/memos_spec.js rename to apps/server-render/test/e2e/integration/memos_spec.js diff --git a/test/e2e/integration/profile_spec.js b/apps/server-render/test/e2e/integration/profile_spec.js similarity index 100% rename from test/e2e/integration/profile_spec.js rename to apps/server-render/test/e2e/integration/profile_spec.js diff --git a/test/e2e/integration/research_spec.js b/apps/server-render/test/e2e/integration/research_spec.js similarity index 100% rename from test/e2e/integration/research_spec.js rename to apps/server-render/test/e2e/integration/research_spec.js diff --git a/test/e2e/integration/signup_spec.js b/apps/server-render/test/e2e/integration/signup_spec.js similarity index 100% rename from test/e2e/integration/signup_spec.js rename to apps/server-render/test/e2e/integration/signup_spec.js diff --git a/test/e2e/integration/tutorial_spec.js b/apps/server-render/test/e2e/integration/tutorial_spec.js similarity index 100% rename from test/e2e/integration/tutorial_spec.js rename to apps/server-render/test/e2e/integration/tutorial_spec.js diff --git a/test/e2e/plugins/index.js b/apps/server-render/test/e2e/plugins/index.js similarity index 100% rename from test/e2e/plugins/index.js rename to apps/server-render/test/e2e/plugins/index.js diff --git a/test/e2e/support/commands.js b/apps/server-render/test/e2e/support/commands.js similarity index 100% rename from test/e2e/support/commands.js rename to apps/server-render/test/e2e/support/commands.js diff --git a/test/e2e/support/index.js b/apps/server-render/test/e2e/support/index.js similarity index 100% rename from test/e2e/support/index.js rename to apps/server-render/test/e2e/support/index.js diff --git a/test/e2e/tsconfig.json b/apps/server-render/test/e2e/tsconfig.json similarity index 100% rename from test/e2e/tsconfig.json rename to apps/server-render/test/e2e/tsconfig.json diff --git a/test/security/profile-test.js b/apps/server-render/test/security/profile-test.js similarity index 100% rename from test/security/profile-test.js rename to apps/server-render/test/security/profile-test.js From 70316df7b5cbec1d0d1871527903f7a608c9bfa2 Mon Sep 17 00:00:00 2001 From: Ulises Gascon Date: Wed, 18 Mar 2020 17:52:39 +0100 Subject: [PATCH 02/10] Added Lerna initialization --- lerna.json | 6 ++++++ package.json | 16 ++++++++++++++++ 2 files changed, 22 insertions(+) create mode 100644 lerna.json create mode 100644 package.json diff --git a/lerna.json b/lerna.json new file mode 100644 index 000000000..8f77bbff5 --- /dev/null +++ b/lerna.json @@ -0,0 +1,6 @@ +{ + "packages": [ + "apps/*" + ], + "version": "0.0.0" +} diff --git a/package.json b/package.json new file mode 100644 index 000000000..f4f0b02a5 --- /dev/null +++ b/package.json @@ -0,0 +1,16 @@ +{ + "name": "nodegoat", + "private": true, + "version": "2.0.0", + "description": "A tool to learn OWASP Top 10 for node.js developers", + "main": "index.js", + "devDependencies": { + "lerna": "^3.20.2" + }, + "scripts": { + "test": "" + }, + "repository": "https://github.com/OWASP/NodejsGoat", + "license": "Apache 2.0", + "homepage": "https://github.com/OWASP/NodeGoat#readme" +} From 364b36bfdcfa41a2e843f8f8850423045a58f258 Mon Sep 17 00:00:00 2001 From: Ulises Gascon Date: Wed, 18 Mar 2020 18:26:31 +0100 Subject: [PATCH 03/10] update exception rules --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 51f9c0865..e4d948bc9 100644 --- a/.gitignore +++ b/.gitignore @@ -20,4 +20,4 @@ Icon? report*.html # e2e -test/e2e/screenshots/ \ No newline at end of file +**/test/e2e/screenshots/ \ No newline at end of file From 01e72afa446521b9579c13670ba6a2f8206b1562 Mon Sep 17 00:00:00 2001 From: Ulises Gascon Date: Wed, 18 Mar 2020 18:27:31 +0100 Subject: [PATCH 04/10] server-render app renamed --- apps/server-render/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/server-render/package.json b/apps/server-render/package.json index e739218c3..af0ea356b 100644 --- a/apps/server-render/package.json +++ b/apps/server-render/package.json @@ -1,5 +1,5 @@ { - "name": "owasp-nodejs-goat", + "name": "owasp-nodegoat-server-render", "private": true, "version": "1.3.0", "description": "A tool to learn OWASP Top 10 for node.js developers", From d9e8a23a4c6a5c4823e2689e36855642d8410739 Mon Sep 17 00:00:00 2001 From: Ulises Gascon Date: Wed, 18 Mar 2020 18:27:57 +0100 Subject: [PATCH 05/10] Added githooks tasks to server-render --- apps/server-render/package.json | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/apps/server-render/package.json b/apps/server-render/package.json index af0ea356b..1162a47d0 100644 --- a/apps/server-render/package.json +++ b/apps/server-render/package.json @@ -35,7 +35,10 @@ "docker-mongo": "docker run -p 27017:27017 --name mongo mongo:latest", "start-infra": "docker-compose up", "stop-infra": "docker-compose down", - "cy:verify": "cypress verify" + "cy:verify": "cypress verify", + "githook:commit-msg": "npm run precommit", + "githook:pre-push": "npm run test:ci", + "githook:post-merge": "npm install && npm install --package-lock-only" }, "devDependencies": { "async": "^2.0.0-rc.4", From 2a79334d14a5a161d2a5c3724e0fd1ebad72270a Mon Sep 17 00:00:00 2001 From: Ulises Gascon Date: Wed, 18 Mar 2020 18:28:53 +0100 Subject: [PATCH 06/10] Added main project tasks - Added Husky - Added main tasks as mirror (all:* and server-render:* patterns) --- package.json | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index f4f0b02a5..a83b9b1bb 100644 --- a/package.json +++ b/package.json @@ -5,12 +5,30 @@ "description": "A tool to learn OWASP Top 10 for node.js developers", "main": "index.js", "devDependencies": { - "lerna": "^3.20.2" + "lerna": "^3.20.2", + "husky": "^4.2.3" }, "scripts": { - "test": "" + "all:test-e2e": "lerna run --parallel test:e2e", + "all:test-ci": "lerna run --parallel test:ci", + "all:test": "lerna run --parallel test", + "all:deps-install": "lerna exec npm install && lerna exec npm install -- --package-lock-only && lerna bootstrap", + "all:deps-remove": "lerna exec -- rm -rf ./node_modules", + "all:infra-start": "lerna run --parallel start-infra", + "all:infra-stop": "lerna run --parallel stop-infra", + "server-render:docker-mongo": "lerna run --scope *-server-render docker-mongo", + "server-render:start": "lerna run --scope *-server-render start", + "server-render:dev": "lerna run --scope *-server-render dev" }, "repository": "https://github.com/OWASP/NodejsGoat", "license": "Apache 2.0", - "homepage": "https://github.com/OWASP/NodeGoat#readme" + "homepage": "https://github.com/OWASP/NodeGoat#readme", + "husky": { + "hooks": { + "commit-msg": "lerna run --parallel githook:commit-msg", + "pre-commit": "lerna run --parallel githook:pre-commit", + "pre-push": "lerna run --parallel githook:pre-push", + "post-merge": "lerna --parallel run githook:post-merge" + } + } } From f2113017ef830108b0adc697c0a810d11b09b42e Mon Sep 17 00:00:00 2001 From: Ulises Gascon Date: Wed, 18 Mar 2020 18:29:39 +0100 Subject: [PATCH 07/10] Lint execution :muscle: --- .../server-render/app/data/allocations-dao.js | 4 +- apps/server-render/app/data/benefits-dao.js | 4 +- .../app/data/contributions-dao.js | 6 +- apps/server-render/app/data/memos-dao.js | 4 +- apps/server-render/app/data/profile-dao.js | 4 +- apps/server-render/app/data/research-dao.js | 4 +- apps/server-render/app/data/user-dao.js | 6 +- apps/server-render/app/routes/allocations.js | 15 +- apps/server-render/app/routes/benefits.js | 11 +- .../server-render/app/routes/contributions.js | 10 +- apps/server-render/app/routes/error.js | 6 +- apps/server-render/app/routes/index.js | 6 +- apps/server-render/app/routes/memos.js | 6 +- apps/server-render/app/routes/profile.js | 20 ++- apps/server-render/app/routes/research.js | 20 ++- apps/server-render/app/routes/session.js | 22 ++- apps/server-render/app/views/allocations.html | 2 +- apps/server-render/app/views/layout.html | 2 +- apps/server-render/app/views/login.html | 10 +- apps/server-render/app/views/research.html | 4 +- apps/server-render/app/views/tutorial/a1.html | 70 ++++---- apps/server-render/app/views/tutorial/a2.html | 32 ++-- apps/server-render/app/views/tutorial/a3.html | 4 +- apps/server-render/app/views/tutorial/a4.html | 2 +- apps/server-render/app/views/tutorial/a5.html | 28 ++-- apps/server-render/app/views/tutorial/a7.html | 2 +- apps/server-render/app/views/tutorial/a8.html | 2 +- apps/server-render/app/views/tutorial/a9.html | 2 +- .../app/views/tutorial/ssrf.html | 2 +- apps/server-render/config/config.js | 5 +- apps/server-render/server.js | 6 +- .../test/e2e/integration/allocations_spec.js | 90 +++++----- .../test/e2e/integration/benefits_spec.js | 104 ++++++------ .../e2e/integration/contributions_spec.js | 106 ++++++------ .../test/e2e/integration/dashboard_spec.js | 56 +++---- .../test/e2e/integration/general_spec.js | 114 ++++++------- .../test/e2e/integration/learn_spec.js | 24 +-- .../test/e2e/integration/login_spec.js | 154 +++++++++--------- .../test/e2e/integration/logout_spec.js | 48 +++--- .../test/e2e/integration/memos_spec.js | 94 +++++------ .../test/e2e/integration/profile_spec.js | 112 ++++++------- .../test/e2e/integration/research_spec.js | 80 ++++----- .../test/e2e/integration/signup_spec.js | 144 ++++++++-------- .../test/e2e/integration/tutorial_spec.js | 112 ++++++------- apps/server-render/test/e2e/plugins/index.js | 4 +- .../test/e2e/support/commands.js | 39 +++-- apps/server-render/test/e2e/support/index.js | 1 - 47 files changed, 836 insertions(+), 767 deletions(-) diff --git a/apps/server-render/app/data/allocations-dao.js b/apps/server-render/app/data/allocations-dao.js index 26ecc387e..b89eefe87 100644 --- a/apps/server-render/app/data/allocations-dao.js +++ b/apps/server-render/app/data/allocations-dao.js @@ -1,7 +1,7 @@ const UserDAO = require("./user-dao").UserDAO; /* The AllocationsDAO must be constructed with a connected database object */ -const AllocationsDAO = function(db){ +const AllocationsDAO = function(db) { "use strict"; @@ -90,7 +90,7 @@ const AllocationsDAO = function(db){ let doneCounter = 0; const userAllocations = []; - allocations.forEach( alloc => { + allocations.forEach(alloc => { userDAO.getUserById(alloc.userId, (err, user) => { if (err) return callback(err, null); diff --git a/apps/server-render/app/data/benefits-dao.js b/apps/server-render/app/data/benefits-dao.js index 5e773e442..6eada694f 100644 --- a/apps/server-render/app/data/benefits-dao.js +++ b/apps/server-render/app/data/benefits-dao.js @@ -40,4 +40,6 @@ function BenefitsDAO(db) { }; } -module.exports = { BenefitsDAO }; +module.exports = { + BenefitsDAO +}; diff --git a/apps/server-render/app/data/contributions-dao.js b/apps/server-render/app/data/contributions-dao.js index 00041dac6..5863b6cf1 100644 --- a/apps/server-render/app/data/contributions-dao.js +++ b/apps/server-render/app/data/contributions-dao.js @@ -26,7 +26,7 @@ function ContributionsDAO(db) { }; contributionsDB.update({ - userId + userId }, contributions, { upsert: true @@ -83,4 +83,6 @@ function ContributionsDAO(db) { }; } -module.exports = { ContributionsDAO }; +module.exports = { + ContributionsDAO +}; diff --git a/apps/server-render/app/data/memos-dao.js b/apps/server-render/app/data/memos-dao.js index 434c935c2..c28a4c6c7 100644 --- a/apps/server-render/app/data/memos-dao.js +++ b/apps/server-render/app/data/memos-dao.js @@ -36,4 +36,6 @@ function MemosDAO(db) { } -module.exports = { MemosDAO }; +module.exports = { + MemosDAO +}; diff --git a/apps/server-render/app/data/profile-dao.js b/apps/server-render/app/data/profile-dao.js index 552e5df38..3d98bb276 100644 --- a/apps/server-render/app/data/profile-dao.js +++ b/apps/server-render/app/data/profile-dao.js @@ -110,4 +110,6 @@ function ProfileDAO(db) { }; } -module.exports = { ProfileDAO }; +module.exports = { + ProfileDAO +}; diff --git a/apps/server-render/app/data/research-dao.js b/apps/server-render/app/data/research-dao.js index 96e211fc4..1486a860c 100644 --- a/apps/server-render/app/data/research-dao.js +++ b/apps/server-render/app/data/research-dao.js @@ -24,4 +24,6 @@ function ResearchDAO(db) { } } -module.exports = { ResearchDAO }; +module.exports = { + ResearchDAO +}; diff --git a/apps/server-render/app/data/user-dao.js b/apps/server-render/app/data/user-dao.js index e88bdafb3..a39eca370 100644 --- a/apps/server-render/app/data/user-dao.js +++ b/apps/server-render/app/data/user-dao.js @@ -116,8 +116,10 @@ function UserDAO(db) { }, { new: true }, - (err, data) => err ? callback(err, null) : callback(null, data.value.seq)); + (err, data) => err ? callback(err, null) : callback(null, data.value.seq)); }; } -module.exports = { UserDAO }; +module.exports = { + UserDAO +}; diff --git a/apps/server-render/app/routes/allocations.js b/apps/server-render/app/routes/allocations.js index b45f1ab13..1f484dd67 100644 --- a/apps/server-render/app/routes/allocations.js +++ b/apps/server-render/app/routes/allocations.js @@ -1,6 +1,6 @@ const AllocationsDAO = require("../data/allocations-dao").AllocationsDAO; -function AllocationsHandler (db) { +function AllocationsHandler(db) { "use strict"; const allocationsDAO = new AllocationsDAO(db); @@ -10,12 +10,19 @@ function AllocationsHandler (db) { // Fix for A4 Insecure DOR - take user id from session instead of from URL param const { userId } = req.session; */ - const {userId} = req.params; - const { threshold } = req.query + const { + userId + } = req.params; + const { + threshold + } = req.query allocationsDAO.getByUserIdAndThreshold(userId, threshold, (err, allocations) => { if (err) return next(err); - return res.render("allocations", { userId, allocations }); + return res.render("allocations", { + userId, + allocations + }); }); }; } diff --git a/apps/server-render/app/routes/benefits.js b/apps/server-render/app/routes/benefits.js index 1e8189501..b6a541541 100644 --- a/apps/server-render/app/routes/benefits.js +++ b/apps/server-render/app/routes/benefits.js @@ -1,6 +1,8 @@ -const { BenefitsDAO } = require("../data/benefits-dao"); +const { + BenefitsDAO +} = require("../data/benefits-dao"); -function BenefitsHandler (db) { +function BenefitsHandler(db) { "use strict"; const benefitsDAO = new BenefitsDAO(db); @@ -21,7 +23,10 @@ function BenefitsHandler (db) { }; this.updateBenefits = (req, res, next) => { - const { userId, benefitStartDate } = req.body; + const { + userId, + benefitStartDate + } = req.body; benefitsDAO.updateBenefits(userId, benefitStartDate, (error) => { diff --git a/apps/server-render/app/routes/contributions.js b/apps/server-render/app/routes/contributions.js index 14327c9ed..3dbcffac9 100644 --- a/apps/server-render/app/routes/contributions.js +++ b/apps/server-render/app/routes/contributions.js @@ -1,13 +1,15 @@ const ContributionsDAO = require("../data/contributions-dao").ContributionsDAO; /* The ContributionsHandler must be constructed with a connected db */ -function ContributionsHandler (db) { +function ContributionsHandler(db) { "use strict"; const contributionsDAO = new ContributionsDAO(db); this.displayContributions = (req, res, next) => { - const { userId } = req.session; + const { + userId + } = req.session; contributionsDAO.getByUserId(userId, (error, contrib) => { if (error) return next(error); @@ -31,7 +33,9 @@ function ContributionsHandler (db) { const afterTax = parseInt(req.body.afterTax); const roth = parseInt(req.body.roth); */ - const { userId } = req.session; + const { + userId + } = req.session; //validate contributions const validations = [isNaN(preTax), isNaN(afterTax), isNaN(roth), preTax < 0, afterTax < 0, roth < 0] diff --git a/apps/server-render/app/routes/error.js b/apps/server-render/app/routes/error.js index 0df5fd867..1d56e7c9e 100644 --- a/apps/server-render/app/routes/error.js +++ b/apps/server-render/app/routes/error.js @@ -1,6 +1,6 @@ // Error handling middleware -const errorHandler = (err, req, res,next) => { +const errorHandler = (err, req, res, next) => { "use strict"; @@ -12,4 +12,6 @@ const errorHandler = (err, req, res,next) => { }); }; -module.exports = { errorHandler }; +module.exports = { + errorHandler +}; diff --git a/apps/server-render/app/routes/index.js b/apps/server-render/app/routes/index.js index 62ca639a8..361388ff2 100644 --- a/apps/server-render/app/routes/index.js +++ b/apps/server-render/app/routes/index.js @@ -76,9 +76,11 @@ const index = (app, db) => { app.get("/tutorial", (req, res) => { return res.render("tutorial/a1"); }); - + app.get("/tutorial/:page", (req, res) => { - const { page } = req.params + const { + page + } = req.params return res.render(`tutorial/${page}`); }); diff --git a/apps/server-render/app/routes/memos.js b/apps/server-render/app/routes/memos.js index c70af0beb..72e0903cd 100644 --- a/apps/server-render/app/routes/memos.js +++ b/apps/server-render/app/routes/memos.js @@ -1,6 +1,6 @@ const MemosDAO = require("../data/memos-dao").MemosDAO; -function MemosHandler (db) { +function MemosHandler(db) { "use strict"; const memosDAO = new MemosDAO(db); @@ -15,7 +15,9 @@ function MemosHandler (db) { this.displayMemos = (req, res, next) => { - const { userId } = req.session; + const { + userId + } = req.session; memosDAO.getAllMemos((err, docs) => { if (err) return next(err); diff --git a/apps/server-render/app/routes/profile.js b/apps/server-render/app/routes/profile.js index 4282d55cb..16150a9f1 100644 --- a/apps/server-render/app/routes/profile.js +++ b/apps/server-render/app/routes/profile.js @@ -2,13 +2,15 @@ const ProfileDAO = require("../data/profile-dao").ProfileDAO; const ESAPI = require('node-esapi') /* The ProfileHandler must be constructed with a connected db */ -function ProfileHandler (db) { +function ProfileHandler(db) { "use strict"; const profile = new ProfileDAO(db); this.displayProfile = (req, res, next) => { - const { userId } = req.session; + const { + userId + } = req.session; @@ -31,7 +33,15 @@ function ProfileHandler (db) { this.handleProfileUpdate = (req, res, next) => { - const {firstName, lastName, ssn, dob, address, bankAcc, bankRouting} = req.body; + const { + firstName, + lastName, + ssn, + dob, + address, + bankAcc, + bankRouting + } = req.body; // Fix for Section: ReDoS attack // The following regexPattern that is used to validate the bankRouting number is insecure and vulnerable to @@ -58,7 +68,9 @@ function ProfileHandler (db) { }); } - const { userId } = req.session; + const { + userId + } = req.session; profile.updateUser( parseInt(userId), diff --git a/apps/server-render/app/routes/research.js b/apps/server-render/app/routes/research.js index 6923256cd..4c5f4cdcb 100644 --- a/apps/server-render/app/routes/research.js +++ b/apps/server-render/app/routes/research.js @@ -1,25 +1,27 @@ const ResearchDAO = require("../data/research-dao").ResearchDAO; const needle = require('needle'); -function ResearchHandler (db) { +function ResearchHandler(db) { "use strict"; const researchDAO = new ResearchDAO(db); this.displayResearch = (req, res) => { - + if (req.query.symbol) { - const url = req.query.url+req.query.symbol; + const url = req.query.url + req.query.symbol; return needle.get(url, (error, newResponse) => { if (!error && newResponse.statusCode == 200) - res.writeHead(200, {'Content-Type': 'text/html'}); - res.write('

The following is the stock information you requested.

\n\n'); - res.write('\n\n'); - res.write(newResponse.body); - return res.end(); + res.writeHead(200, { + 'Content-Type': 'text/html' + }); + res.write('

The following is the stock information you requested.

\n\n'); + res.write('\n\n'); + res.write(newResponse.body); + return res.end(); }); } - + return res.render("research"); }; diff --git a/apps/server-render/app/routes/session.js b/apps/server-render/app/routes/session.js index 64a4e2a61..f8a2c52bb 100644 --- a/apps/server-render/app/routes/session.js +++ b/apps/server-render/app/routes/session.js @@ -2,7 +2,7 @@ const UserDAO = require("../data/user-dao").UserDAO; const AllocationsDAO = require("../data/allocations-dao").AllocationsDAO; /* The SessionHandler must be constructed with a connected db */ -function SessionHandler (db) { +function SessionHandler(db) { "use strict"; const userDAO = new UserDAO(db); @@ -22,16 +22,16 @@ function SessionHandler (db) { this.isAdminUserMiddleware = (req, res, next) => { if (req.session.userId) { return userDAO.getUserById(req.session.userId, (err, user) => user && user.isAdmin ? next() : res.redirect("/login")); - } + } console.log("redirecting to login"); return res.redirect("/login"); - + }; this.isLoggedInMiddleware = (req, res, next) => { if (req.session.userId) { return next(); - } + } console.log("redirecting to login"); return res.redirect("/login"); }; @@ -45,7 +45,10 @@ function SessionHandler (db) { }; this.handleLoginRequest = (req, res, next) => { - const { userName, password } = req.body + const { + userName, + password + } = req.body userDAO.validateLogin(userName, password, (err, user) => { const errorMessage = "Invalid username and/or password"; const invalidUserNameErrorMessage = "Invalid username"; @@ -173,7 +176,14 @@ function SessionHandler (db) { this.handleSignup = (req, res, next) => { - const { email, userName, firstName, lastName, password, verify } = req.body; + const { + email, + userName, + firstName, + lastName, + password, + verify + } = req.body; // set these up in case we have an error case const errors = { diff --git a/apps/server-render/app/views/allocations.html b/apps/server-render/app/views/allocations.html index 3b28d546f..0d85be781 100644 --- a/apps/server-render/app/views/allocations.html +++ b/apps/server-render/app/views/allocations.html @@ -50,4 +50,4 @@

-{% endblock %} +{% endblock %} \ No newline at end of file diff --git a/apps/server-render/app/views/layout.html b/apps/server-render/app/views/layout.html index 6206deb6c..c734b5221 100644 --- a/apps/server-render/app/views/layout.html +++ b/apps/server-render/app/views/layout.html @@ -128,4 +128,4 @@ - + \ No newline at end of file diff --git a/apps/server-render/app/views/login.html b/apps/server-render/app/views/login.html index b96266f1d..643af9439 100644 --- a/apps/server-render/app/views/login.html +++ b/apps/server-render/app/views/login.html @@ -87,10 +87,10 @@ RetireEasy -
+
Employee Retirement Savings Management -
-
+
+
@@ -158,9 +158,9 @@ document.cookie = "testcookie=1"; if (!document.cookie) return false; - + document.cookie = "testcookie=; expires=" + new Date(0).toUTCString(); - + } return true; diff --git a/apps/server-render/app/views/research.html b/apps/server-render/app/views/research.html index ddfc9a3eb..66e457e3a 100644 --- a/apps/server-render/app/views/research.html +++ b/apps/server-render/app/views/research.html @@ -14,7 +14,7 @@

- +

Enter Stock Symbol.

@@ -27,4 +27,4 @@

-{% endblock %} +{% endblock %} \ No newline at end of file diff --git a/apps/server-render/app/views/tutorial/a1.html b/apps/server-render/app/views/tutorial/a1.html index 2587ce97e..5e40c2b64 100644 --- a/apps/server-render/app/views/tutorial/a1.html +++ b/apps/server-render/app/views/tutorial/a1.html @@ -93,7 +93,7 @@

Attack Mechanics

File System Access -
+

@@ -221,7 +221,7 @@

1. SQL Injection

If this statement is not prepared or properly handled when constructed, an attacker may be able to supply admin' --in the username field to access the admin user's account bypassing the condition that checks for the password. The resultant SQL query would looks like:

SELECT * FROM accounts WHERE username = 'admin' -- AND password = ''
-
+
2. NoSQL Injection

The equivalent of above query for NoSQL MongoDB database is:

db.accounts.find({username: username, password: password});
@@ -270,7 +270,7 @@
$where operator

-
+
NoSQL SSJS Injection

An attacker can send the following input for the @@ -347,38 +347,38 @@

1. Log Forging (CRLF)
console.log('Error: attempt to login with invalid user: ', userName);

When user input is unsanitized and the output mechanism is an ordinary terminal stdout facility then the application will be vulnerable to CRLF injection, where an attacker can create a malicious payload as follows: -

+                            
 curl http://localhost:4000/login -X POST --data 'userName=vyva%0aError: alex moldovan failed $1,000,000 transaction&password=Admin_123&_csrf='
                         
- Where the userName parameter is encoding in the request the LF symbol which will result in a new line to begin. Resulting log output will look as follows: -
+                            Where the userName parameter is encoding in the request the LF symbol which will result in a new line to begin. Resulting log output will look as follows:
+                            
 Error: attempt to login with invalid user:  vyva
 Error: alex moldovan failed $1,000,000 transaction
                         
-
-
2. Log Injection Escalation
-

- An attacker may craft malicious input in hope of an escalated attack where the target isn't the logs themselves, but rather the actual logging system. For example, if an application has a back-office web app that manages viewing and tracking the logs, then an attacker may send an XSS payload into the log, which may not result in log forging on the log itself, but when viewed by a system administrator on the log viewing web app then it may compromise it and result in XSS injection that if the logs app is vulnerable. -

+
+
2. Log Injection Escalation
+

+ An attacker may craft malicious input in hope of an escalated attack where the target isn't the logs themselves, but rather the actual logging system. For example, if an application has a back-office web app that manages viewing and tracking the logs, then an attacker may send an XSS payload into the log, which may not result in log forging on the log itself, but when viewed by a system administrator on the log viewing web app then it may compromise it and result in XSS injection that if the logs app is vulnerable. +

-
-
-

How Do I Prevent It?

-
-
+
+
+

How Do I Prevent It?

+
+
- As always when dealing with user input: -
    -
  • - Do not allow user input into logs -
  • -
  • - Encode to proper context, or sanitize user input -
  • -
+ As always when dealing with user input: +
    +
  • + Do not allow user input into logs +
  • +
  • + Encode to proper context, or sanitize user input +
  • +
- Encoding example: -
+                                    Encoding example:
+                                    
 // Step 1: Require a module that supports encoding
 var ESAPI = require('node-esapi');
 // - Step 2: Encode the user input that will be logged in the correct context
@@ -388,15 +388,15 @@ 

How Do I Prevent It?

console.log('Error: attempt to login with invalid user: %s', ESAPI.encoder().encodeForURL(userName));
- For the above Log Injection vulnerability, example and fix can be found at - routes/session.js + For the above Log Injection vulnerability, example and fix can be found at + routes/session.js +
+
- - - + - - -{% endblock %} + + + {% endblock %} \ No newline at end of file diff --git a/apps/server-render/app/views/tutorial/a2.html b/apps/server-render/app/views/tutorial/a2.html index 9202d8649..9efaa3889 100644 --- a/apps/server-render/app/views/tutorial/a2.html +++ b/apps/server-render/app/views/tutorial/a2.html @@ -131,8 +131,8 @@

1. Protecting user credentials

callback(invalidPasswordError, null); }
Note: The bcrypt module also provides asynchronous methods for creating and comparing hash. -
-
+
+

2. Session timeout and protecting cookies in transit

The insecure demo application does not contain any provision to timeout user session. The session stays active until user explicitly logs out.

@@ -166,22 +166,22 @@

2. Session timeout and protecting cookies in transit

});
Note: The example code uses MemoryStoreto manage session data, which is not designed for production environment, as it will leak memory, and will not scale past a single process. Use database based storage MongoStore or RedisStore for production. Alternatively, sessions can be managed using popular passport module. -
-
-

3. Session hijacking

+
+
+

3. Session hijacking

-

The insecure demo application does not regenerate a new session id upon user's login, therefore rendering a vulnerability of session hijacking if an attacker is able to somehow steal the cookie with the session id and use it. +

The insecure demo application does not regenerate a new session id upon user's login, therefore rendering a vulnerability of session hijacking if an attacker is able to somehow steal the cookie with the session id and use it. -

Upon login, a security best practice with regards to cookies session management would be to regenerate the session id so that if an id was already created for a user on an insecure medium (i.e: non-HTTPS website or otherwise), or if an attacker was able to get their hands on the cookie id before the user logged-in, then the old session id will render useless as the logged-in user with new privileges holds a new session id now. -

+

Upon login, a security best practice with regards to cookies session management would be to regenerate the session id so that if an id was already created for a user on an insecure medium (i.e: non-HTTPS website or otherwise), or if an attacker was able to get their hands on the cookie id before the user logged-in, then the old session id will render useless as the logged-in user with new privileges holds a new session id now. +

-

To secure the application:

-

1. Re-generate a new session id upon login (and best practice is to keep regenerating them -upon requests or at least upon sensitive actions like a user's password reset. +

To secure the application:

+

1. Re-generate a new session id upon login (and best practice is to keep regenerating them + upon requests or at least upon sensitive actions like a user's password reset. - Re-generate a session id as follows: - By wrapping the below code as a function callback for the method req.session.regenerate() -

+                                    Re-generate a session id as follows:
+                                    By wrapping the below code as a function callback for the method req.session.regenerate()
+                                    
 req.session.regenerate(function() {
 
   req.session.userId = user._id;
@@ -194,7 +194,7 @@ 

3. Session hijacking

})
-

+

@@ -307,4 +307,4 @@

Source Code Example

-{% endblock %} +{% endblock %} \ No newline at end of file diff --git a/apps/server-render/app/views/tutorial/a3.html b/apps/server-render/app/views/tutorial/a3.html index b1dd5a04b..03900bba6 100644 --- a/apps/server-render/app/views/tutorial/a3.html +++ b/apps/server-render/app/views/tutorial/a3.html @@ -85,7 +85,7 @@

How Do I Prevent It?

UNTRUSTED DATA"> Except for alphanumeric characters, escape all characters with the HTML Entity &#xHH; format, including spaces. (HH = Hex Value) -
+
@@ -94,7 +94,7 @@

How Do I Prevent It?

UNTRUSTED DATA">clickme</a> Except for alphanumeric characters, escape all characters with ASCII values less than 256 with the HTML Entity &#xHH; format, including spaces. (HH = Hex Value) -
+
diff --git a/apps/server-render/app/views/tutorial/a4.html b/apps/server-render/app/views/tutorial/a4.html index 81292aeba..13b1ac4f6 100644 --- a/apps/server-render/app/views/tutorial/a4.html +++ b/apps/server-render/app/views/tutorial/a4.html @@ -78,4 +78,4 @@

Source Code Example

-{% endblock %} +{% endblock %} \ No newline at end of file diff --git a/apps/server-render/app/views/tutorial/a5.html b/apps/server-render/app/views/tutorial/a5.html index 1bf72b5a2..a7f29f604 100644 --- a/apps/server-render/app/views/tutorial/a5.html +++ b/apps/server-render/app/views/tutorial/a5.html @@ -62,18 +62,18 @@

How Do I Prevent It?

Limit HTTP Request Body size by setting sensible size limits on each content type specific middleware ( urlencoded, json, multipart) instead of using aggregate limitmiddleware. Include only required middleware. For example if application doesn't need to support file uploads, do not include multipart middleware. -
  • - If using multipart middleware, have a strategy to clean up temporary files generated by it. These files are not garbage collected by default, and an attacker can fill disk with such temporary files -
  • -
  • - Vet npm packages used by the application -
  • -
  • - Lock versions of all npm packages used, for example using shrinkwarp, to have full control over when to install a new version of the package. -
  • -
  • - Set security specific HTTP headers -
  • +
  • + If using multipart middleware, have a strategy to clean up temporary files generated by it. These files are not garbage collected by default, and an attacker can fill disk with such temporary files +
  • +
  • + Vet npm packages used by the application +
  • +
  • + Lock versions of all npm packages used, for example using shrinkwarp, to have full control over when to install a new version of the package. +
  • +
  • + Set security specific HTTP headers +
  • @@ -87,7 +87,7 @@

    Source Code Example

    The default HTTP header x-powered-by can reveal implementation details to an attacker. It can be taken out by including this code in server.js -

       
    +                    
             app.disable("x-powered-by"); 
         

    @@ -129,4 +129,4 @@

    Source Code Example

    -{% endblock %} +{% endblock %} \ No newline at end of file diff --git a/apps/server-render/app/views/tutorial/a7.html b/apps/server-render/app/views/tutorial/a7.html index 124d42950..e211d3009 100644 --- a/apps/server-render/app/views/tutorial/a7.html +++ b/apps/server-render/app/views/tutorial/a7.html @@ -61,7 +61,7 @@

    Source Code Examples

    To implement isAdminmiddleware, check if isAdmin flag is set for the logged in user in database. -
    For example, here is middleware function that can be added to +
    For example, here is middleware function that can be added to routes\session.js:

    diff --git a/apps/server-render/app/views/tutorial/a8.html b/apps/server-render/app/views/tutorial/a8.html
    index ae1883bdf..2b56d669d 100644
    --- a/apps/server-render/app/views/tutorial/a8.html
    +++ b/apps/server-render/app/views/tutorial/a8.html
    @@ -100,4 +100,4 @@ 

    Source Code Example

    -{% endblock %} +{% endblock %} \ No newline at end of file diff --git a/apps/server-render/app/views/tutorial/a9.html b/apps/server-render/app/views/tutorial/a9.html index dceaf36da..7bb72e955 100644 --- a/apps/server-render/app/views/tutorial/a9.html +++ b/apps/server-render/app/views/tutorial/a9.html @@ -158,4 +158,4 @@

    Attack Mechanics

    -{% endblock %} +{% endblock %} \ No newline at end of file diff --git a/apps/server-render/app/views/tutorial/ssrf.html b/apps/server-render/app/views/tutorial/ssrf.html index 11caba305..b9db9322a 100644 --- a/apps/server-render/app/views/tutorial/ssrf.html +++ b/apps/server-render/app/views/tutorial/ssrf.html @@ -47,4 +47,4 @@

    How Do I Prevent It?

    -{% endblock %} +{% endblock %} \ No newline at end of file diff --git a/apps/server-render/config/config.js b/apps/server-render/config/config.js index 5b1d511d6..8701b80ed 100644 --- a/apps/server-render/config/config.js +++ b/apps/server-render/config/config.js @@ -6,7 +6,10 @@ const finalEnv = process.env.NODE_ENV || "development"; const allConf = require(path.resolve(__dirname + "/../config/env/all.js")) const envConf = require(path.resolve(__dirname + "/../config/env/" + finalEnv.toLowerCase() + ".js")) || {} -const config = { ...allConf, ...envConf } +const config = { + ...allConf, + ...envConf +} console.log(`Current Config: ${config}`) diff --git a/apps/server-render/server.js b/apps/server-render/server.js index a0147579f..cb141ec26 100644 --- a/apps/server-render/server.js +++ b/apps/server-render/server.js @@ -14,7 +14,11 @@ const marked = require("marked"); //const nosniff = require('dont-sniff-mimetype'); const app = express(); // Web framework to handle routing requests const routes = require("./app/routes"); -const { port, db, cookieSecret } = require("./config/config"); // Application config properties +const { + port, + db, + cookieSecret +} = require("./config/config"); // Application config properties /* // Fix for A6-Sensitive Data Exposure // Load keys for establishing secure HTTPS connection diff --git a/apps/server-render/test/e2e/integration/allocations_spec.js b/apps/server-render/test/e2e/integration/allocations_spec.js index 225d2c6f2..73ab5e078 100644 --- a/apps/server-render/test/e2e/integration/allocations_spec.js +++ b/apps/server-render/test/e2e/integration/allocations_spec.js @@ -1,50 +1,50 @@ /// describe('/allocations behaviour', () => { - before(() => { - cy.dbReset() - }) - - after(() => { - cy.dbReset() - }) - - afterEach(() => { - cy.visitPage('/logout') - }) - - it('Should redirect if the user has not logged in', () => { - cy.visitPage('/allocations/1') - cy.url().should('include', 'login') - }) - - it('Should be accesible for a logged user', () => { - cy.userSignIn() - cy.visitPage('/allocations/1') - cy.url().should('include', 'allocations') - }) - - it('Should be an input', () => { - cy.userSignIn() - cy.visitPage('/allocations/1') - cy.get('input[name="threshold"]') - }) - - it('Should redirect the user', () => { - const threshold = 2 - cy.userSignIn() - cy.visitPage('/allocations/1') - - cy.get('input[name="threshold"]') - .clear() - .type(threshold) - - cy.get('button[type="submit"]') - .click() - - cy.location().should((loc) => { - expect(loc.search).to.eq(`?threshold=${threshold}`) - expect(loc.pathname).to.eq('/allocations/1') + before(() => { + cy.dbReset() + }) + + after(() => { + cy.dbReset() + }) + + afterEach(() => { + cy.visitPage('/logout') + }) + + it('Should redirect if the user has not logged in', () => { + cy.visitPage('/allocations/1') + cy.url().should('include', 'login') + }) + + it('Should be accesible for a logged user', () => { + cy.userSignIn() + cy.visitPage('/allocations/1') + cy.url().should('include', 'allocations') + }) + + it('Should be an input', () => { + cy.userSignIn() + cy.visitPage('/allocations/1') + cy.get('input[name="threshold"]') + }) + + it('Should redirect the user', () => { + const threshold = 2 + cy.userSignIn() + cy.visitPage('/allocations/1') + + cy.get('input[name="threshold"]') + .clear() + .type(threshold) + + cy.get('button[type="submit"]') + .click() + + cy.location().should((loc) => { + expect(loc.search).to.eq(`?threshold=${threshold}`) + expect(loc.pathname).to.eq('/allocations/1') + }) }) - }) }) diff --git a/apps/server-render/test/e2e/integration/benefits_spec.js b/apps/server-render/test/e2e/integration/benefits_spec.js index b28f0d968..4ede56420 100644 --- a/apps/server-render/test/e2e/integration/benefits_spec.js +++ b/apps/server-render/test/e2e/integration/benefits_spec.js @@ -1,56 +1,56 @@ /// describe('/login behaviour', () => { - before(() => { - cy.dbReset() - }) - - after(() => { - cy.dbReset() - }) - - afterEach(() => { - cy.visitPage('/logout') - }) - - it('Should redirect if the user has not logged in', () => { - cy.visitPage('/benefits') - cy.url().should('include', 'login') - }) - - it('Should be accesible by default if the user is an admin', () => { - cy.adminSignIn() - cy.visitPage('/benefits') - cy.url().should('include', 'benefits') - }) - - it('Should be accesible if the user is not an admin', () => { - cy.userSignIn() - cy.visitPage('/benefits') - cy.url().should('include', 'benefits') - }) - - it('Should be a table with rows', () => { - cy.adminSignIn() - cy.visitPage('/benefits') - cy.get('table tr') - }) - - it('Should data in the table be modified', () => { - cy.adminSignIn() - cy.visitPage('/benefits') - cy.get('input[name="benefitStartDate"') - .first() - .type('2099-01-10') - - cy.get('button[type="submit"]') - .first() - .click() - - cy.url().should('include', 'benefits') - cy.get('input[name="benefitStartDate"') - .first() - .invoke('val') - .should('eq', '2099-01-10') - }) + before(() => { + cy.dbReset() + }) + + after(() => { + cy.dbReset() + }) + + afterEach(() => { + cy.visitPage('/logout') + }) + + it('Should redirect if the user has not logged in', () => { + cy.visitPage('/benefits') + cy.url().should('include', 'login') + }) + + it('Should be accesible by default if the user is an admin', () => { + cy.adminSignIn() + cy.visitPage('/benefits') + cy.url().should('include', 'benefits') + }) + + it('Should be accesible if the user is not an admin', () => { + cy.userSignIn() + cy.visitPage('/benefits') + cy.url().should('include', 'benefits') + }) + + it('Should be a table with rows', () => { + cy.adminSignIn() + cy.visitPage('/benefits') + cy.get('table tr') + }) + + it('Should data in the table be modified', () => { + cy.adminSignIn() + cy.visitPage('/benefits') + cy.get('input[name="benefitStartDate"') + .first() + .type('2099-01-10') + + cy.get('button[type="submit"]') + .first() + .click() + + cy.url().should('include', 'benefits') + cy.get('input[name="benefitStartDate"') + .first() + .invoke('val') + .should('eq', '2099-01-10') + }) }) diff --git a/apps/server-render/test/e2e/integration/contributions_spec.js b/apps/server-render/test/e2e/integration/contributions_spec.js index c00af2f87..e846b8847 100644 --- a/apps/server-render/test/e2e/integration/contributions_spec.js +++ b/apps/server-render/test/e2e/integration/contributions_spec.js @@ -1,57 +1,57 @@ /// describe('/contributions behaviour', () => { - before(() => { - cy.dbReset() - }) - - after(() => { - cy.dbReset() - }) - - afterEach(() => { - cy.visitPage('/logout') - }) - - it('Should redirect if the user has not logged in', () => { - cy.visitPage('/contributions') - cy.url().should('include', 'login') - }) - - it('Should be accesible for a logged user', () => { - cy.userSignIn() - cy.visitPage('/contributions') - cy.url().should('include', 'contributions') - }) - - it('Should be a table with several inputs', () => { - cy.userSignIn() - cy.visitPage('/contributions') - cy.get('table') - .find('input') - .should('have.length', 3) - }) - - it('Should input be modified', () => { - const value = '12' - cy.userSignIn() - cy.visitPage('/contributions') - cy.get('table') - .find('input') - .first() - .clear() - .type(value) - - cy.get('button[type="submit"]') - .click() - - cy.get('tbody > tr > td') - .eq(1) - .contains(`${value} %`) - - cy.get('.alert-success') - .should('be.visible') - - cy.url().should('include', 'contributions') - }) + before(() => { + cy.dbReset() + }) + + after(() => { + cy.dbReset() + }) + + afterEach(() => { + cy.visitPage('/logout') + }) + + it('Should redirect if the user has not logged in', () => { + cy.visitPage('/contributions') + cy.url().should('include', 'login') + }) + + it('Should be accesible for a logged user', () => { + cy.userSignIn() + cy.visitPage('/contributions') + cy.url().should('include', 'contributions') + }) + + it('Should be a table with several inputs', () => { + cy.userSignIn() + cy.visitPage('/contributions') + cy.get('table') + .find('input') + .should('have.length', 3) + }) + + it('Should input be modified', () => { + const value = '12' + cy.userSignIn() + cy.visitPage('/contributions') + cy.get('table') + .find('input') + .first() + .clear() + .type(value) + + cy.get('button[type="submit"]') + .click() + + cy.get('tbody > tr > td') + .eq(1) + .contains(`${value} %`) + + cy.get('.alert-success') + .should('be.visible') + + cy.url().should('include', 'contributions') + }) }) diff --git a/apps/server-render/test/e2e/integration/dashboard_spec.js b/apps/server-render/test/e2e/integration/dashboard_spec.js index 737aacf6e..ad6c6e762 100644 --- a/apps/server-render/test/e2e/integration/dashboard_spec.js +++ b/apps/server-render/test/e2e/integration/dashboard_spec.js @@ -1,36 +1,36 @@ /// describe('/dashboard behaviour', () => { - afterEach(() => { - cy.visitPage('/logout') - }) + afterEach(() => { + cy.visitPage('/logout') + }) - it('Should redirect if the user has not logged in', () => { - cy.visitPage('/dashboard') - cy.url().should('include', 'login') - }) + it('Should redirect if the user has not logged in', () => { + cy.visitPage('/dashboard') + cy.url().should('include', 'login') + }) - it('Should be accesible for a logged user', () => { - cy.userSignIn() - cy.visitPage('/dashboard') - cy.url().should('include', 'dashboard') - }) + it('Should be accesible for a logged user', () => { + cy.userSignIn() + cy.visitPage('/dashboard') + cy.url().should('include', 'dashboard') + }) - it('Should display information', () => { - cy.userSignIn() - cy.visitPage('/dashboard') - cy.url().should('include', 'dashboard') - cy.get('.panel') - .should('be.visible') - .should('have.length', 5) - }) + it('Should display information', () => { + cy.userSignIn() + cy.visitPage('/dashboard') + cy.url().should('include', 'dashboard') + cy.get('.panel') + .should('be.visible') + .should('have.length', 5) + }) - it('Should have a link to /contributions', () => { - cy.userSignIn() - cy.visitPage('/dashboard') - cy.url().should('include', 'dashboard') - cy.get('.panel a') - .first() - .should('have.attr', 'href', '/contributions') - }) + it('Should have a link to /contributions', () => { + cy.userSignIn() + cy.visitPage('/dashboard') + cy.url().should('include', 'dashboard') + cy.get('.panel a') + .first() + .should('have.attr', 'href', '/contributions') + }) }) diff --git a/apps/server-render/test/e2e/integration/general_spec.js b/apps/server-render/test/e2e/integration/general_spec.js index d211a90ce..7b7e872ec 100644 --- a/apps/server-render/test/e2e/integration/general_spec.js +++ b/apps/server-render/test/e2e/integration/general_spec.js @@ -1,73 +1,75 @@ /// describe('General behaviour', () => { - beforeEach(() => { - cy.adminSignIn() - cy.visitPage('/') - }) + beforeEach(() => { + cy.adminSignIn() + cy.visitPage('/') + }) - afterEach(() => { - cy.visitPage('/logout') - }) + afterEach(() => { + cy.visitPage('/logout') + }) - it('should have all the links in the side menu', () => { - cy.get('#dashboard-menu-link') - .should('be.visible') - .should('have.attr', 'href', '/') + it('should have all the links in the side menu', () => { + cy.get('#dashboard-menu-link') + .should('be.visible') + .should('have.attr', 'href', '/') - cy.get('#contributions-menu-link') - .should('be.visible') - .should('have.attr', 'href', '/contributions') + cy.get('#contributions-menu-link') + .should('be.visible') + .should('have.attr', 'href', '/contributions') - cy.get('#allocations-menu-link') - .should('be.visible') - .should('have.attr', 'href', '/allocations/1') + cy.get('#allocations-menu-link') + .should('be.visible') + .should('have.attr', 'href', '/allocations/1') - cy.get('#memos-menu-link') - .should('be.visible') - .should('have.attr', 'href', '/memos') + cy.get('#memos-menu-link') + .should('be.visible') + .should('have.attr', 'href', '/memos') - cy.get('#profile-menu-link') - .should('be.visible') - .should('have.attr', 'href', '/profile') + cy.get('#profile-menu-link') + .should('be.visible') + .should('have.attr', 'href', '/profile') - cy.get('#learn-menu-link') - .should('be.visible') - .should('have.attr', 'target', '_blank') - .should('have.attr', 'href', '/learn?url=https://www.khanacademy.org/economics-finance-domain/core-finance/investment-vehicles-tutorial/ira-401ks/v/traditional-iras') + cy.get('#learn-menu-link') + .should('be.visible') + .should('have.attr', 'target', '_blank') + .should('have.attr', 'href', '/learn?url=https://www.khanacademy.org/economics-finance-domain/core-finance/investment-vehicles-tutorial/ira-401ks/v/traditional-iras') - cy.get('#research-menu-link') - .should('be.visible') - .should('have.attr', 'href', '/research') + cy.get('#research-menu-link') + .should('be.visible') + .should('have.attr', 'href', '/research') - cy.get('#logout-menu-link') - .should('be.visible') - .should('have.attr', 'href', '/logout') - }) + cy.get('#logout-menu-link') + .should('be.visible') + .should('have.attr', 'href', '/logout') + }) - it('should have a profile menu', () => { - cy.get('.user-dropdown a') - .eq(0) - .invoke('text') - .should('eq', ' Node Goat Admin ') + it('should have a profile menu', () => { + cy.get('.user-dropdown a') + .eq(0) + .invoke('text') + .should('eq', ' Node Goat Admin ') - cy.get('.user-dropdown a') - .eq(1) - .should('have.attr', 'href', '/profile') - .invoke('text') - .should('eq', ' Profile') + cy.get('.user-dropdown a') + .eq(1) + .should('have.attr', 'href', '/profile') + .invoke('text') + .should('eq', ' Profile') - cy.get('.user-dropdown a') - .eq(2) - .should('have.attr', 'href', '/logout') - .invoke('text') - .should('eq', ' Log Out') - }) + cy.get('.user-dropdown a') + .eq(2) + .should('have.attr', 'href', '/logout') + .invoke('text') + .should('eq', ' Log Out') + }) - it('should manage 404', () => { - cy.visitPage('/invented', { failOnStatusCode: false }) - cy.get('body') - .invoke('text') - .should('eq', '\nCannot GET /invented\n\n\n') - }) + it('should manage 404', () => { + cy.visitPage('/invented', { + failOnStatusCode: false + }) + cy.get('body') + .invoke('text') + .should('eq', '\nCannot GET /invented\n\n\n') + }) }) diff --git a/apps/server-render/test/e2e/integration/learn_spec.js b/apps/server-render/test/e2e/integration/learn_spec.js index 3e15f6454..177fd3555 100644 --- a/apps/server-render/test/e2e/integration/learn_spec.js +++ b/apps/server-render/test/e2e/integration/learn_spec.js @@ -1,18 +1,18 @@ /// describe('/learn behaviour', () => { - afterEach(() => { - cy.visitPage('/logout') - }) + afterEach(() => { + cy.visitPage('/logout') + }) - it('Should redirect if the user has not logged in', () => { - cy.visitPage('/learn?url=/dashboard') - cy.url().should('include', 'login') - }) + it('Should redirect if the user has not logged in', () => { + cy.visitPage('/learn?url=/dashboard') + cy.url().should('include', 'login') + }) - it('Should be accesible for a logged user', () => { - cy.userSignIn() - cy.visitPage('/learn?url=/dashboard') - cy.url().should('include', 'dashboard') - }) + it('Should be accesible for a logged user', () => { + cy.userSignIn() + cy.visitPage('/learn?url=/dashboard') + cy.url().should('include', 'dashboard') + }) }) diff --git a/apps/server-render/test/e2e/integration/login_spec.js b/apps/server-render/test/e2e/integration/login_spec.js index 458525379..70353eeef 100644 --- a/apps/server-render/test/e2e/integration/login_spec.js +++ b/apps/server-render/test/e2e/integration/login_spec.js @@ -1,94 +1,94 @@ /// describe('/login behaviour', () => { - before(() => { - cy.dbReset() - }) - - after(() => { - cy.dbReset() - }) - - afterEach(() => { - cy.visitPage('/logout') - }) - - beforeEach(() => { - cy.visitPage('/login') - }) - - it('should have tutorial Guide link', () => { - cy.get("a[href='/tutorial']") - .should('have.attr', 'target', '_blank') - .and('be.visible') - }) - - it('Should open the tutorial in another tab', () => { - cy.get("a[href='/tutorial']").then(function ($a) { - const href = - $a.prop('href') - cy.visit(href) - cy.url().should('include', 'tutorial') + before(() => { + cy.dbReset() }) - }) - - it('should have admin user able to login', () => { - cy.fixture('users/admin.json').as('admin') - cy.get('@admin').then(admin => { - cy.get('#userName').type(admin.user) - cy.get('#password').type(admin.pass) - cy.get('[type="submit"]').click() - cy.url().should('include', 'benefits') + + after(() => { + cy.dbReset() + }) + + afterEach(() => { + cy.visitPage('/logout') + }) + + beforeEach(() => { + cy.visitPage('/login') + }) + + it('should have tutorial Guide link', () => { + cy.get("a[href='/tutorial']") + .should('have.attr', 'target', '_blank') + .and('be.visible') }) - }) - - it('should have non-admin user able to login', () => { - cy.fixture('users/user.json').as('user') - cy.get('@user').then(user => { - cy.get('#userName').type(user.user) - cy.get('#password').type(user.pass) - cy.get('[type="submit"]').click() - cy.url().should('include', 'dashboard') + + it('Should open the tutorial in another tab', () => { + cy.get("a[href='/tutorial']").then(function($a) { + const href = + $a.prop('href') + cy.visit(href) + cy.url().should('include', 'tutorial') + }) + }) + + it('should have admin user able to login', () => { + cy.fixture('users/admin.json').as('admin') + cy.get('@admin').then(admin => { + cy.get('#userName').type(admin.user) + cy.get('#password').type(admin.pass) + cy.get('[type="submit"]').click() + cy.url().should('include', 'benefits') + }) }) - }) - it('should reject wrong password', () => { - cy.fixture('users/user.json').as('user') - cy.get('@user').then(user => { - cy.get('#userName').type(user.user) - cy.get('#password').type('TO BE REJECTED') - cy.get('[type="submit"]').click() + it('should have non-admin user able to login', () => { + cy.fixture('users/user.json').as('user') + cy.get('@user').then(user => { + cy.get('#userName').type(user.user) + cy.get('#password').type(user.pass) + cy.get('[type="submit"]').click() + cy.url().should('include', 'dashboard') + }) + }) - cy.url().should('include', 'login') + it('should reject wrong password', () => { + cy.fixture('users/user.json').as('user') + cy.get('@user').then(user => { + cy.get('#userName').type(user.user) + cy.get('#password').type('TO BE REJECTED') + cy.get('[type="submit"]').click() - cy.get('.alert-danger') - .contains('Invalid password') - .and('be.visible') + cy.url().should('include', 'login') + + cy.get('.alert-danger') + .contains('Invalid password') + .and('be.visible') + }) }) - }) - it('should reject wrong username', () => { - cy.fixture('users/user.json').as('user') - cy.get('@user').then(user => { - cy.get('#userName').type('INVENTED') - cy.get('#password').type(user.pass) - cy.get('[type="submit"]').click() + it('should reject wrong username', () => { + cy.fixture('users/user.json').as('user') + cy.get('@user').then(user => { + cy.get('#userName').type('INVENTED') + cy.get('#password').type(user.pass) + cy.get('[type="submit"]').click() - cy.url().should('include', 'login') + cy.url().should('include', 'login') - cy.get('.alert-danger') - .contains('Invalid username') - .and('be.visible') + cy.get('.alert-danger') + .contains('Invalid username') + .and('be.visible') + }) }) - }) - it('should have new user/ sign up link', () => { - cy.get("a[href='/signup']") - .and('be.visible') - }) + it('should have new user/ sign up link', () => { + cy.get("a[href='/signup']") + .and('be.visible') + }) - it('Should redirect to the signup', () => { - cy.get("a[href='/signup']").click() - cy.url().should('include', 'signup') - }) + it('Should redirect to the signup', () => { + cy.get("a[href='/signup']").click() + cy.url().should('include', 'signup') + }) }) diff --git a/apps/server-render/test/e2e/integration/logout_spec.js b/apps/server-render/test/e2e/integration/logout_spec.js index b56bc9142..53c1f3755 100644 --- a/apps/server-render/test/e2e/integration/logout_spec.js +++ b/apps/server-render/test/e2e/integration/logout_spec.js @@ -1,32 +1,32 @@ /// describe('/logout behaviour', () => { - before(() => { - cy.dbReset() - }) + before(() => { + cy.dbReset() + }) - after(() => { - cy.dbReset() - }) + after(() => { + cy.dbReset() + }) - it('Should redirect if the user has not logged in', () => { - cy.visitPage('/logout') - cy.url().should('include', 'login') - }) + it('Should redirect if the user has not logged in', () => { + cy.visitPage('/logout') + cy.url().should('include', 'login') + }) - it('Should be working if the user is an admin', () => { - cy.adminSignIn() - cy.visitPage('/logout') - cy.url().should('include', 'login') - cy.visitPage('/dashboard') - cy.url().should('include', 'login') - }) + it('Should be working if the user is an admin', () => { + cy.adminSignIn() + cy.visitPage('/logout') + cy.url().should('include', 'login') + cy.visitPage('/dashboard') + cy.url().should('include', 'login') + }) - it('Should be working if the user is not an admin', () => { - cy.userSignIn() - cy.visitPage('/logout') - cy.url().should('include', 'login') - cy.visitPage('/dashboard') - cy.url().should('include', 'login') - }) + it('Should be working if the user is not an admin', () => { + cy.userSignIn() + cy.visitPage('/logout') + cy.url().should('include', 'login') + cy.visitPage('/dashboard') + cy.url().should('include', 'login') + }) }) diff --git a/apps/server-render/test/e2e/integration/memos_spec.js b/apps/server-render/test/e2e/integration/memos_spec.js index 0928d3d56..834343ece 100644 --- a/apps/server-render/test/e2e/integration/memos_spec.js +++ b/apps/server-render/test/e2e/integration/memos_spec.js @@ -1,51 +1,51 @@ /// describe('/memos behaviour', () => { - before(() => { - cy.dbReset() - }) - - after(() => { - cy.dbReset() - }) - - afterEach(() => { - cy.visitPage('/logout') - }) - - it('Should redirect if the user has not logged in', () => { - cy.visitPage('/memos') - cy.url().should('include', 'login') - }) - - it('Should be accesible for a logged user', () => { - cy.userSignIn() - cy.visitPage('/memos') - cy.url().should('include', 'memos') - }) - - it('Should exists a textarea', () => { - cy.userSignIn() - cy.visitPage('/memos') - cy.get('textarea[name="memo"]') - }) - - it('Should memo be generated', () => { - const text = 'Hello World!' - - cy.userSignIn() - cy.visitPage('/memos') - cy.get('textarea[name="memo"]') - .clear() - .type(text) - - cy.get('button[type="submit"]') - .click() - - cy.url().should('include', 'memos') - - cy.get('.panel-body > p') - .should('be.visible') - .contains(text) - }) + before(() => { + cy.dbReset() + }) + + after(() => { + cy.dbReset() + }) + + afterEach(() => { + cy.visitPage('/logout') + }) + + it('Should redirect if the user has not logged in', () => { + cy.visitPage('/memos') + cy.url().should('include', 'login') + }) + + it('Should be accesible for a logged user', () => { + cy.userSignIn() + cy.visitPage('/memos') + cy.url().should('include', 'memos') + }) + + it('Should exists a textarea', () => { + cy.userSignIn() + cy.visitPage('/memos') + cy.get('textarea[name="memo"]') + }) + + it('Should memo be generated', () => { + const text = 'Hello World!' + + cy.userSignIn() + cy.visitPage('/memos') + cy.get('textarea[name="memo"]') + .clear() + .type(text) + + cy.get('button[type="submit"]') + .click() + + cy.url().should('include', 'memos') + + cy.get('.panel-body > p') + .should('be.visible') + .contains(text) + }) }) diff --git a/apps/server-render/test/e2e/integration/profile_spec.js b/apps/server-render/test/e2e/integration/profile_spec.js index 42d0198f3..38c9099d2 100644 --- a/apps/server-render/test/e2e/integration/profile_spec.js +++ b/apps/server-render/test/e2e/integration/profile_spec.js @@ -1,72 +1,72 @@ /// describe('/profile behaviour', () => { - before(() => { - cy.dbReset() - }) + before(() => { + cy.dbReset() + }) - after(() => { - cy.dbReset() - }) + after(() => { + cy.dbReset() + }) - afterEach(() => { - cy.visitPage('/logout') - }) + afterEach(() => { + cy.visitPage('/logout') + }) - it('Should redirect if the user has not logged in', () => { - cy.visitPage('/profile') - cy.url().should('include', 'login') - }) + it('Should redirect if the user has not logged in', () => { + cy.visitPage('/profile') + cy.url().should('include', 'login') + }) - it('Should be accesible for logged user', () => { - cy.userSignIn() - cy.visitPage('/profile') - cy.url().should('include', 'profile') - }) + it('Should be accesible for logged user', () => { + cy.userSignIn() + cy.visitPage('/profile') + cy.url().should('include', 'profile') + }) - it('Should be a form with inputs', () => { - cy.userSignIn() - cy.visitPage('/profile') - cy.get('form[role="form"]') - .find('input') - .should('have.length', 8) - }) + it('Should be a form with inputs', () => { + cy.userSignIn() + cy.visitPage('/profile') + cy.get('form[role="form"]') + .find('input') + .should('have.length', 8) + }) - it('Should first name be modified', () => { - const newName = 'My new name!' - const bankRouting = '0198212#' - cy.userSignIn() - cy.visitPage('/profile') - cy.get('#firstName') - .clear() - .type(newName) + it('Should first name be modified', () => { + const newName = 'My new name!' + const bankRouting = '0198212#' + cy.userSignIn() + cy.visitPage('/profile') + cy.get('#firstName') + .clear() + .type(newName) - cy.get('#bankRouting') - .clear() - .type(bankRouting) + cy.get('#bankRouting') + .clear() + .type(bankRouting) - cy.get('button[type="submit"]') - .first() - .click() + cy.get('button[type="submit"]') + .first() + .click() - cy.url().should('include', 'profile') + cy.url().should('include', 'profile') - cy.get('.alert-success') - .should('be.visible') - // @TODO: Just commented for CI, this MUST be improved - /* - cy.get('#firstName') - .invoke('val') - .should('eq', newName) - */ - }) + cy.get('.alert-success') + .should('be.visible') + // @TODO: Just commented for CI, this MUST be improved + /* + cy.get('#firstName') + .invoke('val') + .should('eq', newName) + */ + }) - it('Google search this profile by name', () => { - cy.userSignIn() - cy.visitPage('/profile') + it('Google search this profile by name', () => { + cy.userSignIn() + cy.visitPage('/profile') - cy.get('form[role="form"] a') - .should('be.visible') - .should('have.attr', 'href') - }) + cy.get('form[role="form"] a') + .should('be.visible') + .should('have.attr', 'href') + }) }) diff --git a/apps/server-render/test/e2e/integration/research_spec.js b/apps/server-render/test/e2e/integration/research_spec.js index 841da0860..ef1d3c8a6 100644 --- a/apps/server-render/test/e2e/integration/research_spec.js +++ b/apps/server-render/test/e2e/integration/research_spec.js @@ -1,44 +1,44 @@ /// describe('/research behaviour', () => { - afterEach(() => { - cy.visitPage('/logout') - }) - - it('Should redirect if the user has not logged in', () => { - cy.visitPage('/research') - cy.url().should('include', 'login') - }) - - it('Should be accesible for a logged user', () => { - cy.userSignIn() - cy.visitPage('/research') - cy.url().should('include', 'research') - }) - - it('Should be a form with an input', () => { - cy.userSignIn() - cy.visitPage('/research') - cy.get('form[role="search"]') - .find('input') - }) - - it('Should have an input text as a valid stock symbol', () => { - const stockSymbol = 'AAPL' - cy.userSignIn() - cy.visitPage('/research') - cy.get('.form-control') - .clear() - .type(stockSymbol) - - cy.get('form') - .should('have.attr', 'action', '/research') - .invoke('attr', 'action', '/skip') - - cy.get('button[type="submit"]') - .first() - .click() - - cy.url().should('include', 'https%3A%2F%2Ffinance.yahoo.com%2Fquote%2F&symbol=AAPL') - }) + afterEach(() => { + cy.visitPage('/logout') + }) + + it('Should redirect if the user has not logged in', () => { + cy.visitPage('/research') + cy.url().should('include', 'login') + }) + + it('Should be accesible for a logged user', () => { + cy.userSignIn() + cy.visitPage('/research') + cy.url().should('include', 'research') + }) + + it('Should be a form with an input', () => { + cy.userSignIn() + cy.visitPage('/research') + cy.get('form[role="search"]') + .find('input') + }) + + it('Should have an input text as a valid stock symbol', () => { + const stockSymbol = 'AAPL' + cy.userSignIn() + cy.visitPage('/research') + cy.get('.form-control') + .clear() + .type(stockSymbol) + + cy.get('form') + .should('have.attr', 'action', '/research') + .invoke('attr', 'action', '/skip') + + cy.get('button[type="submit"]') + .first() + .click() + + cy.url().should('include', 'https%3A%2F%2Ffinance.yahoo.com%2Fquote%2F&symbol=AAPL') + }) }) diff --git a/apps/server-render/test/e2e/integration/signup_spec.js b/apps/server-render/test/e2e/integration/signup_spec.js index 1bbc1920a..4a9f7d291 100644 --- a/apps/server-render/test/e2e/integration/signup_spec.js +++ b/apps/server-render/test/e2e/integration/signup_spec.js @@ -1,78 +1,78 @@ /// describe('/signup behaviour', () => { - before(() => { - cy.dbReset() - }) - - after(() => { - cy.dbReset() - }) - - afterEach(() => { - cy.visitPage('/logout') - }) - - it('Should not redirect if the user has not logged in', () => { - cy.visitPage('/signup') - cy.url().should('include', 'signup') - }) - - it('Should not redirect if the user has logged in', () => { - cy.visitPage('/signup') - cy.url().should('include', 'signup') - }) - - it('Should be a form with inputs', () => { - cy.visitPage('/signup') - cy.get('form[role="form"]') - .find('input') - .should('have.length', 7) - }) - - it('Should new user be added to the system', () => { - cy.fixture('users/new_user.json').as('newUser') - cy.get('@newUser').then(newUser => { - cy.visitPage('/signup') - - cy.get('#userName') - .clear() - .type(newUser.user) - - cy.get('#firstName') - .clear() - .type(newUser.firstName) - - cy.get('#lastName') - .clear() - .type(newUser.lastName) - - cy.get('#password') - .clear() - .type(newUser.pass) - - cy.get('#verify') - .clear() - .type(newUser.pass) - - cy.get('button[type="submit"]') - .first() - .click() - - cy.get('.alert-danger').should('not.be.visible') - - cy.get('.breadcrumb > li') - .invoke('text') - .should('eq', ' Dashboard') + before(() => { + cy.dbReset() }) - }) - - it('Should new user be able to login in the system', () => { - cy.fixture('users/new_user.json').as('newUser') - cy.get('@newUser').then(newUser => { - cy.signIn(newUser.user, newUser.pass) - cy.visitPage('/dashboard') - cy.url().should('include', 'dashboard') + + after(() => { + cy.dbReset() + }) + + afterEach(() => { + cy.visitPage('/logout') + }) + + it('Should not redirect if the user has not logged in', () => { + cy.visitPage('/signup') + cy.url().should('include', 'signup') + }) + + it('Should not redirect if the user has logged in', () => { + cy.visitPage('/signup') + cy.url().should('include', 'signup') + }) + + it('Should be a form with inputs', () => { + cy.visitPage('/signup') + cy.get('form[role="form"]') + .find('input') + .should('have.length', 7) + }) + + it('Should new user be added to the system', () => { + cy.fixture('users/new_user.json').as('newUser') + cy.get('@newUser').then(newUser => { + cy.visitPage('/signup') + + cy.get('#userName') + .clear() + .type(newUser.user) + + cy.get('#firstName') + .clear() + .type(newUser.firstName) + + cy.get('#lastName') + .clear() + .type(newUser.lastName) + + cy.get('#password') + .clear() + .type(newUser.pass) + + cy.get('#verify') + .clear() + .type(newUser.pass) + + cy.get('button[type="submit"]') + .first() + .click() + + cy.get('.alert-danger').should('not.be.visible') + + cy.get('.breadcrumb > li') + .invoke('text') + .should('eq', ' Dashboard') + }) + }) + + it('Should new user be able to login in the system', () => { + cy.fixture('users/new_user.json').as('newUser') + cy.get('@newUser').then(newUser => { + cy.signIn(newUser.user, newUser.pass) + cy.visitPage('/dashboard') + cy.url().should('include', 'dashboard') + }) }) - }) }) diff --git a/apps/server-render/test/e2e/integration/tutorial_spec.js b/apps/server-render/test/e2e/integration/tutorial_spec.js index eac8f5c28..e0e0b77eb 100644 --- a/apps/server-render/test/e2e/integration/tutorial_spec.js +++ b/apps/server-render/test/e2e/integration/tutorial_spec.js @@ -1,71 +1,71 @@ /// describe('/tutorial behaviour', () => { - it('Should have all the links in the side nav', () => { - cy.visitPage('/tutorial') - cy.url().should('include', 'tutorial') - cy.get('.side-nav') - .should('be.visible') - .find('a') - .should('have.length', 12) - }) + it('Should have all the links in the side nav', () => { + cy.visitPage('/tutorial') + cy.url().should('include', 'tutorial') + cy.get('.side-nav') + .should('be.visible') + .find('a') + .should('have.length', 12) + }) - it('Should exists /tutorial/a1', () => { - cy.visitPage('/tutorial/a1') - cy.url().should('include', 'a1') - }) + it('Should exists /tutorial/a1', () => { + cy.visitPage('/tutorial/a1') + cy.url().should('include', 'a1') + }) - it('Should exists /tutorial/a2', () => { - cy.visitPage('/tutorial/a2') - cy.url().should('include', 'a2') - }) + it('Should exists /tutorial/a2', () => { + cy.visitPage('/tutorial/a2') + cy.url().should('include', 'a2') + }) - it('Should exists /tutorial/a3', () => { - cy.visitPage('/tutorial/a3') - cy.url().should('include', 'a3') - }) - it('Should exists /tutorial/a4', () => { - cy.visitPage('/tutorial/a4') - cy.url().should('include', 'a4') - }) + it('Should exists /tutorial/a3', () => { + cy.visitPage('/tutorial/a3') + cy.url().should('include', 'a3') + }) + it('Should exists /tutorial/a4', () => { + cy.visitPage('/tutorial/a4') + cy.url().should('include', 'a4') + }) - it('Should exists /tutorial/a5', () => { - cy.visitPage('/tutorial/a5') - cy.url().should('include', 'a5') - }) + it('Should exists /tutorial/a5', () => { + cy.visitPage('/tutorial/a5') + cy.url().should('include', 'a5') + }) - it('Should exists /tutorial/a6', () => { - cy.visitPage('/tutorial/a6') - cy.url().should('include', 'a6') - }) + it('Should exists /tutorial/a6', () => { + cy.visitPage('/tutorial/a6') + cy.url().should('include', 'a6') + }) - it('Should exists /tutorial/a7', () => { - cy.visitPage('/tutorial/a7') - cy.url().should('include', 'a7') - }) + it('Should exists /tutorial/a7', () => { + cy.visitPage('/tutorial/a7') + cy.url().should('include', 'a7') + }) - it('Should exists /tutorial/a8', () => { - cy.visitPage('/tutorial/a8') - cy.url().should('include', 'a8') - }) + it('Should exists /tutorial/a8', () => { + cy.visitPage('/tutorial/a8') + cy.url().should('include', 'a8') + }) - it('Should exists /tutorial/a9', () => { - cy.visitPage('/tutorial/a9') - cy.url().should('include', 'a9') - }) + it('Should exists /tutorial/a9', () => { + cy.visitPage('/tutorial/a9') + cy.url().should('include', 'a9') + }) - it('Should exists /tutorial/a10', () => { - cy.visitPage('/tutorial/a10') - cy.url().should('include', 'a10') - }) + it('Should exists /tutorial/a10', () => { + cy.visitPage('/tutorial/a10') + cy.url().should('include', 'a10') + }) - it('Should exists /tutorial/redos', () => { - cy.visitPage('/tutorial/redos') - cy.url().should('include', 'redos') - }) + it('Should exists /tutorial/redos', () => { + cy.visitPage('/tutorial/redos') + cy.url().should('include', 'redos') + }) - it('Should exists /tutorial/ssrf', () => { - cy.visitPage('/tutorial/ssrf') - cy.url().should('include', 'ssrf') - }) + it('Should exists /tutorial/ssrf', () => { + cy.visitPage('/tutorial/ssrf') + cy.url().should('include', 'ssrf') + }) }) diff --git a/apps/server-render/test/e2e/plugins/index.js b/apps/server-render/test/e2e/plugins/index.js index fd170fba6..19b9052ba 100644 --- a/apps/server-render/test/e2e/plugins/index.js +++ b/apps/server-render/test/e2e/plugins/index.js @@ -12,6 +12,6 @@ // the project's config changing) module.exports = (on, config) => { - // `on` is used to hook into various events Cypress emits - // `config` is the resolved Cypress config + // `on` is used to hook into various events Cypress emits + // `config` is the resolved Cypress config } diff --git a/apps/server-render/test/e2e/support/commands.js b/apps/server-render/test/e2e/support/commands.js index 42278a9f0..25e02dabd 100644 --- a/apps/server-render/test/e2e/support/commands.js +++ b/apps/server-render/test/e2e/support/commands.js @@ -1,33 +1,36 @@ -const { port, hostName } = require('../../../config/env/all') +const { + port, + hostName +} = require('../../../config/env/all') Cypress.Commands.add('signIn', (usr, pw) => { - cy.visit(`http://${hostName}:${port}/login`) - cy.get('#userName').type(usr) - cy.get('#password').type(pw) - cy.get('[type="submit"]').click() + cy.visit(`http://${hostName}:${port}/login`) + cy.get('#userName').type(usr) + cy.get('#password').type(pw) + cy.get('[type="submit"]').click() }) Cypress.Commands.add('adminSignIn', () => { - cy.fixture('users/admin.json').as('admin') - cy.get('@admin').then(admin => { - cy.signIn(admin.user, admin.pass) - }) + cy.fixture('users/admin.json').as('admin') + cy.get('@admin').then(admin => { + cy.signIn(admin.user, admin.pass) + }) }) Cypress.Commands.add('userSignIn', () => { - cy.fixture('users/user.json').as('user') - cy.get('@user').then(user => { - cy.signIn(user.user, user.pass) - }) + cy.fixture('users/user.json').as('user') + cy.get('@user').then(user => { + cy.signIn(user.user, user.pass) + }) }) Cypress.Commands.add('visitPage', (path = '/', config = {}) => { - cy.visit(`http://${hostName}:${port}${path}`, config) + cy.visit(`http://${hostName}:${port}${path}`, config) }) Cypress.Commands.add('dbReset', () => { - cy.exec('npm run db:seed', { - timeout: 6000, - failOnNonZeroExit: false - }) + cy.exec('npm run db:seed', { + timeout: 6000, + failOnNonZeroExit: false + }) }) diff --git a/apps/server-render/test/e2e/support/index.js b/apps/server-render/test/e2e/support/index.js index 292b920bb..d6189ff90 100644 --- a/apps/server-render/test/e2e/support/index.js +++ b/apps/server-render/test/e2e/support/index.js @@ -1,2 +1 @@ - require('./commands.js') From fd4f30e57eb928e5e82e134dc19f841aebb062f9 Mon Sep 17 00:00:00 2001 From: Ulises Gascon Date: Wed, 18 Mar 2020 18:39:21 +0100 Subject: [PATCH 08/10] CI extended to work with Lerna --- .travis.yml | 12 ++++++------ package.json | 1 + 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/.travis.yml b/.travis.yml index 250349ee5..c9254120c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -24,17 +24,17 @@ cache: override: # use the new "ci" command for fastest installs on CI - - npm ci - - npm run cy:verify + - npm install + - npm run all:deps-ci + - npm run all:cy:verify before_script: ## we use the '&' ampersand which tells ## travis to run this process in the background ## else it would block execution and hang travis - - docker run -d -p 27017:27017 mongo:4.0 - - docker ps -a - - NODE_ENV=test npm start -- --silent & + - npm run all:deps-ci + - NODE_ENV=test npm run all:infra-start -- --silent & script: - - npm run test:ci + - npm run all:test-ci diff --git a/package.json b/package.json index a83b9b1bb..dfd6c82eb 100644 --- a/package.json +++ b/package.json @@ -12,6 +12,7 @@ "all:test-e2e": "lerna run --parallel test:e2e", "all:test-ci": "lerna run --parallel test:ci", "all:test": "lerna run --parallel test", + "all:deps-ci": "lerna exec npm ci", "all:deps-install": "lerna exec npm install && lerna exec npm install -- --package-lock-only && lerna bootstrap", "all:deps-remove": "lerna exec -- rm -rf ./node_modules", "all:infra-start": "lerna run --parallel start-infra", From de13e15d2a48b12afdee2d579dec43f120dec6d4 Mon Sep 17 00:00:00 2001 From: Ulises Gascon Date: Wed, 18 Mar 2020 18:56:14 +0100 Subject: [PATCH 09/10] CI improvements --- .travis.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index c9254120c..058265e4f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -25,14 +25,13 @@ cache: override: # use the new "ci" command for fastest installs on CI - npm install - - npm run all:deps-ci - npm run all:cy:verify before_script: ## we use the '&' ampersand which tells ## travis to run this process in the background ## else it would block execution and hang travis - - npm run all:deps-ci + - npm run all:deps-install - NODE_ENV=test npm run all:infra-start -- --silent & script: From 52af9e8878d022e5126cd4853c4621aff93d0c8c Mon Sep 17 00:00:00 2001 From: Ulises Gascon Date: Wed, 18 Mar 2020 19:01:58 +0100 Subject: [PATCH 10/10] WIP.CI improvements --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 058265e4f..27ee9e093 100644 --- a/.travis.yml +++ b/.travis.yml @@ -31,7 +31,7 @@ before_script: ## we use the '&' ampersand which tells ## travis to run this process in the background ## else it would block execution and hang travis - - npm run all:deps-install + - npm run all:deps-ci - NODE_ENV=test npm run all:infra-start -- --silent & script: