From 0521170292e668cbd1fcc8a1d43b776f1de9afd8 Mon Sep 17 00:00:00 2001 From: Type-Style Date: Mon, 2 Sep 2024 21:19:32 +0200 Subject: [PATCH 1/7] [CHANGE] #84, writing key check to be simpler, introduced scripts for setting up environment variables --- .eslintrc.json | 2 +- .github/workflows/main.yml | 7 +++---- init/generateKey.js | 30 ++++++++++++++++++++++++++++++ init/generatePassword.js | 29 +++++++++++++++++++++++++++++ src/models/entry.ts | 5 ++--- src/scripts/crypt.ts | 4 ++-- src/scripts/token.ts | 4 ++-- src/tests/login.test.ts | 1 - 8 files changed, 69 insertions(+), 13 deletions(-) create mode 100644 init/generateKey.js create mode 100644 init/generatePassword.js diff --git a/.eslintrc.json b/.eslintrc.json index f09bcb4..c69a5cb 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -22,6 +22,6 @@ //"@typescript-eslint/no-unused-vars": "warn" "jest/no-conditional-expect": "off" }, - "ignorePatterns": ["dist", "jest.config.js", "httpdocs", "webpack.config.js", "src/client"] + "ignorePatterns": ["dist", "jest.config.js", "httpdocs", "webpack.config.js", "src/client", "init"] } diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index e31f256..caf06d7 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -14,8 +14,7 @@ jobs: NODE_ENV: ${{ vars.NODE_ENV }} LOCALHOST: ${{ vars.LOCALHOST }} LOCALHOSTV6: ${{ vars.LOCALHOSTV6 }} - KEYA: ${{ secrets.KEYA }} - KEYB: ${{ secrets.KEYB }} + KEY: ${{ secrets.KEY }} USER_TEST: ${{ secrets.USER_TEST }} steps: @@ -30,8 +29,8 @@ jobs: - run: npm run build --if-present - name: Start server run: | - sudo NODE_ENV=$NODE_ENV LOCALHOST=$LOCALHOST LOCALHOSTV6=$LOCALHOSTV6 KEYA=$KEYA KEYB=$KEYB USER_TEST=$USER_TEST npm start & - sleep 15 # Give server some time to start + sudo NODE_ENV=$NODE_ENV LOCALHOST=$LOCALHOST LOCALHOSTV6=$LOCALHOSTV6 KEY=$KEY USER_TEST=$USER_TEST npm start & + sleep 16 # Give server some time to start - name: Check if server is running run: | curl --fail http://localhost:80 || exit 1 diff --git a/init/generateKey.js b/init/generateKey.js new file mode 100644 index 0000000..e2633f0 --- /dev/null +++ b/init/generateKey.js @@ -0,0 +1,30 @@ +/* +* Usage: open console run: node init/generateKey.js +* type desired key and hit enter +* copy output to .env add a line starting with: +* KEY= +* directly followed by your output +*/ + +// Import required modules +const readline = require('readline'); + +// set up readline to read input from the console +const rl = readline.createInterface({ + input: process.stdin, + output: process.stdout +}); + +// Prompt user for input +rl.question('Enter the string to be encoded: ', (input) => { + // encode to escape special chars + const escapedString = encodeURIComponent(input); + + // convert the escaped string to base64 + const base64String = Buffer.from(escapedString).toString('base64'); + + // print the result + console.log('Base64 Encoded String:', base64String); + + rl.close(); +}); \ No newline at end of file diff --git a/init/generatePassword.js b/init/generatePassword.js new file mode 100644 index 0000000..c3b26b0 --- /dev/null +++ b/init/generatePassword.js @@ -0,0 +1,29 @@ +/* +* This is used to setup Passwords initially +* You can create passwords using the same logic as in the environment +* Prerequisite: You need to have KEY already generated! +* Run the build command from the package.json (npm run build) +* Then call the compiled version of this script using the key as environment variable like so: +* KEY=your-key node ./init/generatePassword.js +* Enter your password +* Copy that to the Environment Variables and .env file +* USER_WHATEVER= +* followed by the output of the console +*/ + +// Import required modules +const readline = require('readline'); +const { crypt } = require('../dist/scripts/crypt'); + +// Set up readline to read input from the console +const rl = readline.createInterface({ + input: process.stdin, + output: process.stdout +}); + +// Prompt user for input +rl.question('Enter Password to be generated: ', async (input) => { + const cryptedPassword = await crypt(input); + console.log(cryptedPassword); + rl.close(); +}); \ No newline at end of file diff --git a/src/models/entry.ts b/src/models/entry.ts index 799177b..e040c77 100644 --- a/src/models/entry.ts +++ b/src/models/entry.ts @@ -1,6 +1,5 @@ import { NextFunction, Request, Response } from 'express'; import { checkExact, query } from 'express-validator'; -import { compare } from '@src/scripts/crypt'; import { create as createError } from '@src/middleware/error'; import * as file from '@src/scripts/file'; import { getTime } from '@src/scripts/time'; @@ -138,12 +137,12 @@ export function checkTime(value: string) { async function checkKey(value: string) { if (!value) { throw new Error('Key required'); } - if (!process.env.KEYB) { throw new Error('Configuration wrong'); } + if (!process.env.KEY) { throw new Error('Configuration wrong: KEY is missing in environment variables'); } if (process.env.NODE_ENV != "production" && value == "test") { return true; // dev testing convenience } - const result = await compare(decodeURIComponent(value), process.env.KEYB); + const result = Buffer.from(encodeURIComponent(value)).toString('base64') == process.env.KEY; if (!result) { throw new Error('Key does not match'); diff --git a/src/scripts/crypt.ts b/src/scripts/crypt.ts index 6bef0df..3ce03db 100644 --- a/src/scripts/crypt.ts +++ b/src/scripts/crypt.ts @@ -12,7 +12,7 @@ export const compare = async function (password: string, hash: string) { } function pepper(password: string) { - const key = process.env.KEYA; - if (!key) { throw new Error('KEYA is not defined in the environment variables'); } + const key = process.env.KEY; + if (!key) { throw new Error('KEY is not defined in the environment variables'); } return password + crypto.createHmac('sha256', key).digest("base64"); } diff --git a/src/scripts/token.ts b/src/scripts/token.ts index 9a012f2..4dc99ec 100644 --- a/src/scripts/token.ts +++ b/src/scripts/token.ts @@ -44,7 +44,7 @@ export function cleanupCSRF() { } export function validateJWT(req: Request) { - const key = process.env.KEYA; + const key = process.env.KEY; const header = req.header('Authorization'); const [type, token] = header ? header.split(' ') : ""; let payload: string | jwt.JwtPayload = ""; @@ -78,7 +78,7 @@ export function validateJWT(req: Request) { } export function createJWT(req: Request, res: Response) { - const key = process.env.KEYA; + const key = process.env.KEY; if (!key) { throw new Error('Configuration is wrong'); } const today = new Date(); const dateString = today.toLocaleDateString("de-DE", { weekday: "short", year: 'numeric', month: 'numeric', day: 'numeric', hour: '2-digit', minute: '2-digit', second: '2-digit' }); diff --git a/src/tests/login.test.ts b/src/tests/login.test.ts index e7a593e..0a934bd 100644 --- a/src/tests/login.test.ts +++ b/src/tests/login.test.ts @@ -81,7 +81,6 @@ describe('Login', () => { it('test invalid credentials to return error', async () => { try { userDataWithToken.csrfToken = csrfToken; - console.log("csrfToken %o", userDataWithToken.csrfToken); await axios.post('http://localhost:80/login', qs.stringify(userDataWithToken)); } catch (error) { const axiosError = error as AxiosError; From a5241fc864324fda6abcdc6ff7cc93af3c3d7348 Mon Sep 17 00:00:00 2001 From: Type-Style Date: Mon, 2 Sep 2024 21:20:25 +0200 Subject: [PATCH 2/7] fix: upgrade express-validator from 7.1.0 to 7.2.0 (#133) Snyk has created this PR to upgrade express-validator from 7.1.0 to 7.2.0. See this package in npm: express-validator See this project in Snyk: https://app.snyk.io/org/type-style/project/e2bcd002-cb74-409c-ba55-fb6349df1cbc?utm_source=github&utm_medium=referral&page=upgrade-pr Co-authored-by: snyk-bot --- package-lock.json | 8 ++++---- package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index 740c503..d6cac98 100644 --- a/package-lock.json +++ b/package-lock.json @@ -24,7 +24,7 @@ "express": "^4.19.2", "express-rate-limit": "^7.4.0", "express-slow-down": "^2.0.3", - "express-validator": "^7.1.0", + "express-validator": "^7.2.0", "helmet": "^7.1.0", "hpp": "^0.2.3", "jsonwebtoken": "^9.0.2", @@ -5371,9 +5371,9 @@ } }, "node_modules/express-validator": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/express-validator/-/express-validator-7.1.0.tgz", - "integrity": "sha512-ePn6NXjHRZiZkwTiU1Rl2hy6aUqmi6Cb4/s8sfUsKH7j2yYl9azSpl8xEHcOj1grzzQ+UBEoLWtE1s6FDxW++g==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/express-validator/-/express-validator-7.2.0.tgz", + "integrity": "sha512-I2ByKD8panjtr8Y05l21Wph9xk7kk64UMyvJCl/fFM/3CTJq8isXYPLeKW/aZBCdb/LYNv63PwhY8khw8VWocA==", "license": "MIT", "dependencies": { "lodash": "^4.17.21", diff --git a/package.json b/package.json index 83797bd..265196a 100644 --- a/package.json +++ b/package.json @@ -79,7 +79,7 @@ "express": "^4.19.2", "express-rate-limit": "^7.4.0", "express-slow-down": "^2.0.3", - "express-validator": "^7.1.0", + "express-validator": "^7.2.0", "helmet": "^7.1.0", "hpp": "^0.2.3", "jsonwebtoken": "^9.0.2", From 1dca5d849c31563a9b4e49b49ec04644e205ff17 Mon Sep 17 00:00:00 2001 From: Type-Style Date: Mon, 2 Sep 2024 21:20:37 +0200 Subject: [PATCH 3/7] fix: upgrade @mui/material from 5.16.6 to 5.16.7 (#132) Snyk has created this PR to upgrade @mui/material from 5.16.6 to 5.16.7. See this package in npm: @mui/material See this project in Snyk: https://app.snyk.io/org/type-style/project/e2bcd002-cb74-409c-ba55-fb6349df1cbc?utm_source=github&utm_medium=referral&page=upgrade-pr Co-authored-by: snyk-bot --- package-lock.json | 12 ++++++------ package.json | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/package-lock.json b/package-lock.json index d6cac98..81d7a12 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,7 +12,7 @@ "@emotion/react": "^11.13.0", "@emotion/styled": "^11.11.5", "@mui/icons-material": "^5.16.5", - "@mui/material": "^5.16.6", + "@mui/material": "^5.16.7", "@types/leaflet-rotatedmarker": "^0.2.5", "axios": "^1.7.4", "bcrypt": "^5.1.1", @@ -1723,14 +1723,14 @@ } }, "node_modules/@mui/material": { - "version": "5.16.6", - "resolved": "https://registry.npmjs.org/@mui/material/-/material-5.16.6.tgz", - "integrity": "sha512-0LUIKBOIjiFfzzFNxXZBRAyr9UQfmTAFzbt6ziOU2FDXhorNN2o3N9/32mNJbCA8zJo2FqFU6d3dtoqUDyIEfA==", + "version": "5.16.7", + "resolved": "https://registry.npmjs.org/@mui/material/-/material-5.16.7.tgz", + "integrity": "sha512-cwwVQxBhK60OIOqZOVLFt55t01zmarKJiJUWbk0+8s/Ix5IaUzAShqlJchxsIQ4mSrWqgcKCCXKtIlG5H+/Jmg==", "license": "MIT", "dependencies": { "@babel/runtime": "^7.23.9", - "@mui/core-downloads-tracker": "^5.16.6", - "@mui/system": "^5.16.6", + "@mui/core-downloads-tracker": "^5.16.7", + "@mui/system": "^5.16.7", "@mui/types": "^7.2.15", "@mui/utils": "^5.16.6", "@popperjs/core": "^2.11.8", diff --git a/package.json b/package.json index 265196a..eb421a2 100644 --- a/package.json +++ b/package.json @@ -67,7 +67,7 @@ "@emotion/react": "^11.13.0", "@emotion/styled": "^11.11.5", "@mui/icons-material": "^5.16.5", - "@mui/material": "^5.16.6", + "@mui/material": "^5.16.7", "@types/leaflet-rotatedmarker": "^0.2.5", "axios": "^1.7.4", "bcrypt": "^5.1.1", From 90ab078bd8b9b320733653c13b5bb012d6fe74c3 Mon Sep 17 00:00:00 2001 From: Type-Style Date: Tue, 3 Sep 2024 11:05:24 +0200 Subject: [PATCH 4/7] Create .env For easier setup, to follow readme installation guide --- .env | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 .env diff --git a/.env b/.env new file mode 100644 index 0000000..319d1c2 --- /dev/null +++ b/.env @@ -0,0 +1,7 @@ +NODE_ENV=development +ROOT=https://your-produciton-server.com +KEY= +USER_JOHNDOE= +USER_TEST= +LOCALHOST=127.0.0.1 +LOCALHOSTv6=::1 From f90b945ac0d7ae134d5e23af66dbe4f413ee7d2e Mon Sep 17 00:00:00 2001 From: Type-Style Date: Tue, 3 Sep 2024 11:49:13 +0200 Subject: [PATCH 5/7] Update README.md Installation Guide --- README.md | 91 ++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 84 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 228b1b5..f415bf9 100644 --- a/README.md +++ b/README.md @@ -4,11 +4,7 @@ Leaflet Osmand React ExpressJS Coordinates (X) > Remember an "X" marks the spot. ## Goal -**Technical:** Recieve and store coordinates via webhook and display them on a map through an interactive frontend. -**Personal:** The intend of this project is to get familiar with the listed technologies. - -## Progress -View [milestones](https://github.com/Type-Style/LOREX/milestones) and the [board](https://github.com/users/Type-Style/projects/1) to witness progression +Recieve and store coordinates via webhook and display them on a map through an interactive frontend. ## Installation ### Prerequisites @@ -20,6 +16,87 @@ Run the install command for example via npm `npm install` After completion without errors hit -`npx ts-node src/app.ts` +`npm run build` + +Once complete you can start the server using +`npm run start` + +> [!TIP] +Build and start can be combined using +`npm run dev` + +### Generating Key and Password +`Error Message: KEY is missing in environment variables` +Before you are able to login and use the webapplication, environment variables need to be setup. +Therefore you need to create a file `.env` and place it in the root of the project. +This file will be filled with secrets to protect your instance of LOREX. + +####1st. Generate Key +Usage: open console run: node init/generateKey.js +type desired key and hit enter +copy output to .env add a line starting with: +KEY= +directly followed by your output + +####2nd Generate Password(s) +Prerequisite: KEY already generated! +_(may require server restart)_ +Run the build command from the package.json (npm run build) +Then call the compiled version of this script using the key as environment variable like so: +KEY=your-key node ./init/generatePassword.js +Enter your password +Copy that to the Environment Variables and .env file +USER_WHATEVER= +followed by the output of the console + +> [!IMPORTANT] +In order to run automatic tests and create example data is is highly recommended to have a USER_TEST with the password of `test` +THe test user cannot be used in an production environment + +Once completed rebuild / restart the server and open up localhost/login +Login is now possible using the Username from the .env file in this example "WHATEVER" and the password that was created in the previous step. + +**Now the application is ready** + + +## Generating Data +### Example Data +Build and start the server for example using +`npm run dev` +Wait for the server to start and webpack to compile the assets. +Once done use a second command line to run +`npm run test:data` + +This generates 6 entries each 30s appart and calls the webserver to store this data. +The writing of data can be seen in the first console where the server is running. +Also once logged in under localhost, a map is visible showing a route westbound from the brandenburg gate. + +### Calling writing route manually +Data can be generated by calling the /write rout of the server. +Here is an example: + +`http://localhost/write?user=xx&lat=53.5000&lon=10.0×tamp=1720691648188&hdop=10.0&altitude=1000.000&speed=100.000&heading=180.0&key=test` + + +In order to pass validation use the correct key _(or `test` in development envrioment)_ and create a valid [UNIX timestamp]([url](https://currentmillis.com/)). +For example by using this javascript code: +`var a = new Date().getTime(); +copy(a); +a;` + +## Using on Production +### A note on security +This application is not developed with https built in support. +> [!WARNING] It is advised to run this application in `production` mode behind a proxy that uses https for security reasons + +### Getting data +Similar to the section Generating Data and Calling writing route manually, the application relies on data being provided using a webhook. +Well how data is collected and what data is pushed to the system is user preference. +Feel free to build you own application to do so. + +This application is designed to be used with the [OSMAND+ mobile app]([url](https://osmand.net/)). +Due to a plugin called [Triprecording]([url](https://osmand.net/docs/user/plugins/trip-recording/)) +Using the above link or by [clicking here](https://osmand.net/docs/user/plugins/trip-recording#recording-settings) more information can be found to setup webtracking or "online tracking" + -**Now the server is ready** + From a3ddc1c6fb84533bfbcd32f7b5992bbe48bf124a Mon Sep 17 00:00:00 2001 From: Type-Style Date: Tue, 3 Sep 2024 11:49:41 +0200 Subject: [PATCH 6/7] fix: upgrade @mui/icons-material from 5.16.5 to 5.16.7 (#134) Snyk has created this PR to upgrade @mui/icons-material from 5.16.5 to 5.16.7. See this package in npm: @mui/icons-material See this project in Snyk: https://app.snyk.io/org/type-style/project/e2bcd002-cb74-409c-ba55-fb6349df1cbc?utm_source=github&utm_medium=referral&page=upgrade-pr Co-authored-by: snyk-bot --- package-lock.json | 8 ++++---- package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index 81d7a12..7843c4e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,7 +11,7 @@ "@changey/react-leaflet-markercluster": "^4.0.0-rc1", "@emotion/react": "^11.13.0", "@emotion/styled": "^11.11.5", - "@mui/icons-material": "^5.16.5", + "@mui/icons-material": "^5.16.7", "@mui/material": "^5.16.7", "@types/leaflet-rotatedmarker": "^0.2.5", "axios": "^1.7.4", @@ -1697,9 +1697,9 @@ } }, "node_modules/@mui/icons-material": { - "version": "5.16.5", - "resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-5.16.5.tgz", - "integrity": "sha512-bn88xxU/J9UV0s6+eutq7o3TTOrOlbCX+KshFb8kxgIxJZZfYz3JbAXVMivvoMF4Md6jCVUzM9HEkf4Ajab4tw==", + "version": "5.16.7", + "resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-5.16.7.tgz", + "integrity": "sha512-UrGwDJCXEszbDI7yV047BYU5A28eGJ79keTCP4cc74WyncuVrnurlmIRxaHL8YK+LI1Kzq+/JM52IAkNnv4u+Q==", "license": "MIT", "dependencies": { "@babel/runtime": "^7.23.9" diff --git a/package.json b/package.json index eb421a2..02d40a3 100644 --- a/package.json +++ b/package.json @@ -66,7 +66,7 @@ "@changey/react-leaflet-markercluster": "^4.0.0-rc1", "@emotion/react": "^11.13.0", "@emotion/styled": "^11.11.5", - "@mui/icons-material": "^5.16.5", + "@mui/icons-material": "^5.16.7", "@mui/material": "^5.16.7", "@types/leaflet-rotatedmarker": "^0.2.5", "axios": "^1.7.4", From 9dd79ce8b54570a7224a2b5c73169d7c84dfa050 Mon Sep 17 00:00:00 2001 From: Type-Style Date: Tue, 3 Sep 2024 12:08:37 +0200 Subject: [PATCH 7/7] [Task] #84, remove .env --- .env | 7 ------- 1 file changed, 7 deletions(-) delete mode 100644 .env diff --git a/.env b/.env deleted file mode 100644 index 319d1c2..0000000 --- a/.env +++ /dev/null @@ -1,7 +0,0 @@ -NODE_ENV=development -ROOT=https://your-produciton-server.com -KEY= -USER_JOHNDOE= -USER_TEST= -LOCALHOST=127.0.0.1 -LOCALHOSTv6=::1