diff --git a/.gitignore b/.gitignore index a6b66c431..752b0635c 100644 --- a/.gitignore +++ b/.gitignore @@ -13,3 +13,8 @@ nodedata/ deb-package/dist/** +.env + +dela/ +bin/ +nodes/ diff --git a/scripts/run_local.sh b/scripts/run_local.sh new file mode 100755 index 000000000..3b9f63be2 --- /dev/null +++ b/scripts/run_local.sh @@ -0,0 +1,190 @@ +#!/bin/bash -e +# This puts all the different steps of initializing a Dela d-voting network into one shell script. +# This can be used for development by calling the script and then testing the result locally. +# The script must be called from the root of the github tree, else it returns an error. +# If the script is called with `./scripts/run_local.sh clean`, it stops all services. +# For development, the calls to the different parts can be adjusted, e.g., comment all but +# `start_backend` to only restart the backend. + +if [[ $(git rev-parse --show-toplevel) != $(pwd) ]]; then + echo "ERROR: This script must be started from the root of the git repo" + exit 1 +fi + +asdf_shell() { + if ! asdf list "$1" | grep -wq "$2"; then + asdf install "$1" "$2" + fi + asdf local "$1" "$2" +} +asdf_shell nodejs 16.20.2 +asdf_shell golang 1.21.0 +mkdir -p nodes + +function build_dela() { + echo "Building dela-node" + if ! [[ -d dela/ ]]; then + git clone -b fix-bbolt https://github.com/dedis/dela.git + fi + export GOBIN=$(pwd)/bin + PATH="$PATH":"$GOBIN" + if ! [[ -f $GOBIN/crypto ]]; then + (cd dela/cli/crypto && go install) + fi + if ! [[ -f $GOBIN/dvoting ]]; then + go install ./cli/dvoting + fi + + echo "Installing node directories" + for d in backend frontend; do + DIR=web/$d + if ! [[ -d $DIR/node_modules ]]; then + (cd $DIR && npm ci) + fi + done +} + +function keypair() { + if ! [[ "$PUBLIC_KEY" ]]; then + if ! [[ -f nodes/keypair ]]; then + echo "Getting keypair" + (cd web/backend && npm run keygen) | tail -n 2 >nodes/keypair + fi + . nodes/keypair + export PUBLIC_KEY PRIVATE_KEY + fi +} + +function kill_nodes() { + pkill dvoting || true + rm -rf nodes/node* +} + +function init_nodes() { + kill_nodes + keypair + + echo "Starting nodes" + for n in $(seq 4); do + NODEPORT=$((2000 + n * 2)) + PROXYPORT=$((2001 + n * 2)) + NODEDIR=./nodes/node-$n + mkdir -p $NODEDIR + rm -f $NODEDIR/node.log + dvoting --config $NODEDIR start --postinstall --proxyaddr :$PROXYPORT --proxykey $PUBLIC_KEY \ + --listen tcp://0.0.0.0:$NODEPORT --public http://localhost:$NODEPORT --routing tree --noTLS | + ts "Node-$n: " | tee $NODEDIR/node.log & + done + + echo "Waiting for nodes to start up" + for n in $(seq 4); do + NODEDIR=./nodes/node-$n + while ! [[ -S $NODEDIR/daemon.sock && -f $NODEDIR/node.log && $(cat $NODEDIR/node.log | wc -l) -ge 2 ]]; do + sleep .2 + done + done +} + +function init_dela() { + echo "Initializing dela" + echo " Share the certificate" + for n in $(seq 2 4); do + TOKEN_ARGS=$(dvoting --config ./nodes/node-1 minogrpc token) + NODEDIR=./nodes/node-$n + dvoting --config $NODEDIR minogrpc join --address //localhost:2002 $TOKEN_ARGS + done + + echo " Create a new chain with the nodes" + for n in $(seq 4); do + NODEDIR=./nodes/node-$n + # add node to the chain + MEMBERS="$MEMBERS --member $(dvoting --config $NODEDIR ordering export)" + done + dvoting --config ./nodes/node-1 ordering setup $MEMBERS + + echo " Authorize the signer to handle the access contract on each node" + for s in $(seq 4); do + NODEDIR=./nodes/node-$s + IDENTITY=$(crypto bls signer read --path $NODEDIR/private.key --format BASE64_PUBKEY) + for n in $(seq 4); do + NODEDIR=./nodes/node-$n + dvoting --config $NODEDIR access add --identity "$IDENTITY" + done + done + + echo " Update the access contract" + for n in $(seq 4); do + NODEDIR=./nodes/node-$n + IDENTITY=$(crypto bls signer read --path $NODEDIR/private.key --format BASE64_PUBKEY) + dvoting --config ./nodes/node-1 pool add --key ./nodes/node-1/private.key --args go.dedis.ch/dela.ContractArg \ + --args go.dedis.ch/dela.Access --args access:grant_id \ + --args 0300000000000000000000000000000000000000000000000000000000000000 --args access:grant_contract \ + --args go.dedis.ch/dela.Evoting --args access:grant_command --args all --args access:identity --args $IDENTITY \ + --args access:command --args GRANT + done +} + +function kill_db() { + docker rm -f postgres_dvoting || true +} + +function init_db() { + kill_db + + echo "Starting postgres database" + docker run -d -v "$(pwd)/web/backend/src/migration.sql:/docker-entrypoint-initdb.d/init.sql" \ + -e POSTGRES_PASSWORD=$DATABASE_PASSWORD -e POSTGRES_USER=$DATABASE_USERNAME \ + --name postgres_dvoting -p 5432:5432 postgres:15 >/dev/null + + echo "Adding SCIPER to admin" + (cd web/backend && npx ts-node src/cli.ts addAdmin --sciper $SCIPER_ADMIN | grep -v Executing) +} + +function kill_backend() { + pkill -f "web/backend" || true +} + +function start_backend() { + kill_backend + keypair + + echo "Running backend" + (cd web/backend && npm run start-dev | ts "Backend: " &) +} + +function kill_frontend() { + pkill -f "web/frontend" || true +} + +function start_frontend() { + kill_frontend + keypair + + echo "Running frontend" + (cd web/frontend && npm run start-dev | ts "Frontend: " &) +} + +export SCIPER_ADMIN=100100 +export DATABASE_USERNAME=dvoting +export DATABASE_PASSWORD=postgres +export FRONT_END_URL="http://localhost:3000" +export DELA_NODE_URL="http://localhost:2003" +export BACKEND_HOST="localhost" +export BACKEND_PORT="6000" +export SESSION_SECRET="session secret" +export REACT_APP_NOMOCK=on + +if [[ "$1" == "clean" ]]; then + kill_frontend + kill_nodes + kill_backend + kill_db + exit +fi + +build_dela +init_nodes +init_dela +init_db +start_backend +start_frontend diff --git a/web/backend/package.json b/web/backend/package.json index abafc84ed..861cb4aa0 100644 --- a/web/backend/package.json +++ b/web/backend/package.json @@ -6,6 +6,7 @@ "type": "commonjs", "scripts": { "start": "ts-node -r dotenv/config src/Server.ts dotenv_config_path=config.env", + "start-dev": "NODE_ENV=development ts-node -r dotenv/config src/Server.ts dotenv_config_path=config.env", "dev": "./node_modules/.bin/nodemon", "eslint": "./node_modules/.bin/eslint .", "eslint-fix": "./node_modules/.bin/eslint . --fix", diff --git a/web/backend/src/authManager.ts b/web/backend/src/authManager.ts index aaceb9b7b..5885d707b 100644 --- a/web/backend/src/authManager.ts +++ b/web/backend/src/authManager.ts @@ -21,6 +21,7 @@ export const PERMISSIONS = { }; let authEnforcer: Enforcer; + /* We use the postgres adapter to store the Casbin policies we initialize the adapter with the connection string and the migrate option @@ -83,3 +84,13 @@ export function setMapAuthorization(list: string[][]): Map } return userRights; } + +// Reads a SCIPER from a string and returns the number. If the SCIPER is not in +// the range between 100000 and 999999, an error is thrown. +export function readSCIPER(s: string): number { + const n = parseInt(s, 10); + if (n < 100000 || n > 999999) { + throw new Error(`SCIPER is out of range. ${n} is not between 100000 and 999999`); + } + return n; +} diff --git a/web/backend/src/cli.ts b/web/backend/src/cli.ts index 3a37593e4..e8a740174 100755 --- a/web/backend/src/cli.ts +++ b/web/backend/src/cli.ts @@ -12,7 +12,7 @@ import { SequelizeAdapter } from 'casbin-sequelize-adapter'; import { newEnforcer } from 'casbin'; import { curve } from '@dedis/kyber'; import * as fs from 'fs'; -import { PERMISSIONS } from './authManager'; +import { PERMISSIONS, readSCIPER } from './authManager'; const program = new Command(); @@ -95,16 +95,13 @@ program const scipers: Array = data.split('\n'); const policies = []; for (let i = 0; i < scipers.length; i += 1) { - const sciper: number = Number(scipers[i]); - if (Number.isNaN(sciper)) { - throw new InvalidArgumentError(`SCIPER '${sciper}' on line ${i + 1} is not a number`); - } - if (sciper > 999999 || sciper < 100000) { + try { + policies[i] = [readSCIPER(scipers[i]), electionId, PERMISSIONS.ACTIONS.VOTE]; + } catch (e) { throw new InvalidArgumentError( - `SCIPER '${sciper}' on line ${i + 1} is outside acceptable range (100000..999999)` + `SCIPER '${scipers[i]}' on line ${i + 1} is not a valid sciper: ${e}` ); } - policies[i] = [scipers[i], electionId, PERMISSIONS.ACTIONS.VOTE]; } const enforcer = await initEnforcer(); await enforcer.addPolicies(policies); diff --git a/web/backend/src/controllers/authentication.ts b/web/backend/src/controllers/authentication.ts index fa224605d..2a731391c 100644 --- a/web/backend/src/controllers/authentication.ts +++ b/web/backend/src/controllers/authentication.ts @@ -1,10 +1,41 @@ import express from 'express'; import axios, { AxiosError } from 'axios'; import { sciper2sess } from '../session'; -import { getUserPermissions, setMapAuthorization } from '../authManager'; +import { getUserPermissions, readSCIPER, setMapAuthorization } from '../authManager'; export const authenticationRouter = express.Router(); +authenticationRouter.get('/get_dev_login', (req, res) => { + if (process.env.NODE_ENV !== 'development') { + const err = `/get_dev_login can only be called in development: ${process.env.NODE_ENV}`; + console.error(err); + res.status(500).send(err); + return; + } + if (process.env.SCIPER_ADMIN === undefined) { + const err = 'Please set SCIPER_ADMIN for /get/dev/login endpoint'; + console.error(err); + res.status(500).send(err); + return; + } + try { + req.session.userId = readSCIPER(process.env.SCIPER_ADMIN); + req.session.lastName = 'develo'; + req.session.firstName = 'pment'; + } catch (e) { + const err = `Invalid SCIPER_ADMIN: ${e}`; + console.error(err); + res.status(500).send(err); + return; + } + + const sciperSessions = sciper2sess.get(req.session.userId) || new Set(); + sciperSessions.add(req.sessionID); + sciper2sess.set(req.session.userId, sciperSessions); + + res.redirect('/logged'); +}); + // This is via this endpoint that the client request the tequila key, this key // will then be used for redirection on the tequila server authenticationRouter.get('/get_teq_key', (req, res) => { diff --git a/web/backend/src/controllers/users.ts b/web/backend/src/controllers/users.ts index 723848b58..48922afe5 100644 --- a/web/backend/src/controllers/users.ts +++ b/web/backend/src/controllers/users.ts @@ -1,6 +1,6 @@ import express from 'express'; -import { isAuthorized, PERMISSIONS } from '../authManager'; +import { isAuthorized, PERMISSIONS, readSCIPER } from '../authManager'; export const usersRouter = express.Router(); @@ -26,13 +26,13 @@ usersRouter.post('/add_role', (req, res, next) => { return; } - const { sciper } = req.body; - - // The sciper has to contain 6 numbers - if (sciper > 999999 || sciper < 100000) { + try { + readSCIPER(req.body.sciper); + } catch (e) { res.status(400).send('Sciper length is incorrect'); return; } + next(); // Call https://search-api.epfl.ch/api/ldap?q=228271, if the answer is // empty then sciper unknown, otherwise add it in userDB diff --git a/web/backend/yarn.lock b/web/backend/yarn.lock index a1b7c8d97..2c194d20e 100644 --- a/web/backend/yarn.lock +++ b/web/backend/yarn.lock @@ -69,14 +69,14 @@ "@jridgewell/resolve-uri" "^3.0.3" "@jridgewell/sourcemap-codec" "^1.4.10" -"@lmdb/lmdb-linux-x64@2.4.5": - "integrity" "sha512-p2jWhERu6Mdrm7HmPwucbvrVYNCo+NZNz9YRFGc/91zuslqCr12jzNYpXy9j+ZtxqEC/dbZUkta29FESzO3FZA==" - "resolved" "https://registry.npmjs.org/@lmdb/lmdb-linux-x64/-/lmdb-linux-x64-2.4.5.tgz" +"@lmdb/lmdb-darwin-arm64@2.4.5": + "integrity" "sha512-JlYSjhyPUQI2dyH497WkZ+AqPQZZ0v3xyAmjMpKrucgnoPGoNbSYg/LNvfVx9WE2iQunZ7vUkofunFZxuQLDcQ==" + "resolved" "https://registry.npmjs.org/@lmdb/lmdb-darwin-arm64/-/lmdb-darwin-arm64-2.4.5.tgz" "version" "2.4.5" -"@msgpackr-extract/msgpackr-extract-linux-x64@2.0.2": - "integrity" "sha512-zrBHaePwcv4cQXxzYgNj0+A8I1uVN97E7/3LmkRocYZ+rMwUsnPpp4RuTAHSRoKlTQV3nSdCQW4Qdt4MXw/iHw==" - "resolved" "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-x64/-/msgpackr-extract-linux-x64-2.0.2.tgz" +"@msgpackr-extract/msgpackr-extract-darwin-arm64@2.0.2": + "integrity" "sha512-FMX5i7a+ojIguHpWbzh5MCsCouJkwf4z4ejdUY/fsgB9Vkdak4ZnoIEskOyOUMMB4lctiZFGszFQJXUeFL8tRg==" + "resolved" "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-darwin-arm64/-/msgpackr-extract-darwin-arm64-2.0.2.tgz" "version" "2.0.2" "@nodelib/fs.scandir@2.1.5": @@ -678,6 +678,11 @@ "readable-stream" "^3.6.0" "safe-buffer" "^5.2.0" +"buffer-writer@2.0.0": + "integrity" "sha512-a7ZpuTZU1TRtnwyCNW3I5dc0wWNC3VR9S++Ewyk2HHZdrO3CQJqSpd+95Us590V6AL7JqUAH2IwZ/398PmNFgw==" + "resolved" "https://registry.npmjs.org/buffer-writer/-/buffer-writer-2.0.0.tgz" + "version" "2.0.0" + "buffer-xor@^1.0.3": "integrity" "sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ==" "resolved" "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz" @@ -805,6 +810,11 @@ dependencies: "delayed-stream" "~1.0.0" +"commander@^11.0.0": + "integrity" "sha512-9HMlXtt/BNoYr8ooyjjNRdIilOTkVJXB+GhxMTtOKwk0R4j4lS4NpjuqmRxroBfnfTSHQIHQB7wryHhXarNjmQ==" + "resolved" "https://registry.npmjs.org/commander/-/commander-11.0.0.tgz" + "version" "11.0.0" + "commander@^2.20.3": "integrity" "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" "resolved" "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz" @@ -1565,6 +1575,11 @@ "resolved" "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz" "version" "1.0.0" +"fsevents@~2.3.2": + "integrity" "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==" + "resolved" "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz" + "version" "2.3.2" + "function-bind@^1.1.1": "integrity" "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" "resolved" "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz" @@ -2518,6 +2533,11 @@ "registry-url" "^5.0.0" "semver" "^6.2.0" +"packet-reader@1.0.0": + "integrity" "sha512-HAKu/fG3HpHFO0AA8WE8q2g+gBJaZ9MG7fcKk+IJPLTGAD6Psw4443l+9DGRbOIh3/aXr7Phy0TjilYivJo5XQ==" + "resolved" "https://registry.npmjs.org/packet-reader/-/packet-reader-1.0.0.tgz" + "version" "1.0.0" + "parent-module@^1.0.0": "integrity" "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==" "resolved" "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz" @@ -2582,16 +2602,91 @@ "safe-buffer" "^5.0.1" "sha.js" "^2.4.8" -"pg-connection-string@^2.5.0": - "integrity" "sha512-r5o/V/ORTA6TmUnyWZR9nCj1klXCO2CEKNRlVuJptZe85QuhFayC7WeMic7ndayT5IRIR0S0xFxFi2ousartlQ==" - "resolved" "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.5.0.tgz" - "version" "2.5.0" +"pg-cloudflare@^1.1.1": + "integrity" "sha512-xWPagP/4B6BgFO+EKz3JONXv3YDgvkbVrGw2mTo3D6tVDQRh1e7cqVGvyR3BE+eQgAvx1XhW/iEASj4/jCWl3Q==" + "resolved" "https://registry.npmjs.org/pg-cloudflare/-/pg-cloudflare-1.1.1.tgz" + "version" "1.1.1" + +"pg-connection-string@^2.5.0", "pg-connection-string@^2.6.2": + "integrity" "sha512-ch6OwaeaPYcova4kKZ15sbJ2hKb/VP48ZD2gE7i1J+L4MspCtBMAx8nMgz7bksc7IojCIIWuEhHibSMFH8m8oA==" + "resolved" "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.6.2.tgz" + "version" "2.6.2" + +"pg-int8@1.0.1": + "integrity" "sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==" + "resolved" "https://registry.npmjs.org/pg-int8/-/pg-int8-1.0.1.tgz" + "version" "1.0.1" + +"pg-pool@^3.6.1": + "integrity" "sha512-jizsIzhkIitxCGfPRzJn1ZdcosIt3pz9Sh3V01fm1vZnbnCMgmGl5wvGGdNN2EL9Rmb0EcFoCkixH4Pu+sP9Og==" + "resolved" "https://registry.npmjs.org/pg-pool/-/pg-pool-3.6.1.tgz" + "version" "3.6.1" + +"pg-protocol@^1.6.0": + "integrity" "sha512-M+PDm637OY5WM307051+bsDia5Xej6d9IR4GwJse1qA1DIhiKlksvrneZOYQq42OM+spubpcNYEo2FcKQrDk+Q==" + "resolved" "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.6.0.tgz" + "version" "1.6.0" + +"pg-types@^2.1.0": + "integrity" "sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==" + "resolved" "https://registry.npmjs.org/pg-types/-/pg-types-2.2.0.tgz" + "version" "2.2.0" + dependencies: + "pg-int8" "1.0.1" + "postgres-array" "~2.0.0" + "postgres-bytea" "~1.0.0" + "postgres-date" "~1.0.4" + "postgres-interval" "^1.1.0" + +"pg@^8.11.1", "pg@>=8.0": + "integrity" "sha512-l4rmVeV8qTIrrPrIR3kZQqBgSN93331s9i6wiUiLOSk0Q7PmUxZD/m1rQI622l3NfqBby9Ar5PABfS/SulfieQ==" + "resolved" "https://registry.npmjs.org/pg/-/pg-8.11.2.tgz" + "version" "8.11.2" + dependencies: + "buffer-writer" "2.0.0" + "packet-reader" "1.0.0" + "pg-connection-string" "^2.6.2" + "pg-pool" "^3.6.1" + "pg-protocol" "^1.6.0" + "pg-types" "^2.1.0" + "pgpass" "1.x" + optionalDependencies: + "pg-cloudflare" "^1.1.1" + +"pgpass@1.x": + "integrity" "sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug==" + "resolved" "https://registry.npmjs.org/pgpass/-/pgpass-1.0.5.tgz" + "version" "1.0.5" + dependencies: + "split2" "^4.1.0" "picomatch@^2.0.4", "picomatch@^2.2.1", "picomatch@^2.2.3", "picomatch@^2.3.1": "integrity" "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==" "resolved" "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz" "version" "2.3.1" +"postgres-array@~2.0.0": + "integrity" "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==" + "resolved" "https://registry.npmjs.org/postgres-array/-/postgres-array-2.0.0.tgz" + "version" "2.0.0" + +"postgres-bytea@~1.0.0": + "integrity" "sha512-xy3pmLuQqRBZBXDULy7KbaitYqLcmxigw14Q5sj8QBVLqEwXfeybIKVWiqAXTlcvdvb0+xkOtDbfQMOf4lST1w==" + "resolved" "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-1.0.0.tgz" + "version" "1.0.0" + +"postgres-date@~1.0.4": + "integrity" "sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==" + "resolved" "https://registry.npmjs.org/postgres-date/-/postgres-date-1.0.7.tgz" + "version" "1.0.7" + +"postgres-interval@^1.1.0": + "integrity" "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==" + "resolved" "https://registry.npmjs.org/postgres-interval/-/postgres-interval-1.2.0.tgz" + "version" "1.2.0" + dependencies: + "xtend" "^4.0.0" + "prelude-ls@^1.2.1": "integrity" "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==" "resolved" "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz" @@ -2993,6 +3088,11 @@ "resolved" "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz" "version" "3.0.0" +"split2@^4.1.0": + "integrity" "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==" + "resolved" "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz" + "version" "4.2.0" + "statuses@2.0.1": "integrity" "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==" "resolved" "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz" @@ -3362,6 +3462,11 @@ "commander" "^2.20.3" "cssfilter" "0.0.10" +"xtend@^4.0.0": + "integrity" "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==" + "resolved" "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz" + "version" "4.0.2" + "yallist@^2.1.2": "integrity" "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=" "resolved" "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz" diff --git a/web/frontend/package.json b/web/frontend/package.json index 9475b197b..949c866b7 100644 --- a/web/frontend/package.json +++ b/web/frontend/package.json @@ -4,6 +4,7 @@ "private": true, "scripts": { "start": "HTTPS=true react-scripts start", + "start-dev": "react-scripts start", "build": "HTTPS=true react-scripts build", "test": "react-scripts test", "eject": "react-scripts eject", diff --git a/web/frontend/src/components/utils/Endpoints.tsx b/web/frontend/src/components/utils/Endpoints.tsx index 93b8b4216..070589c4b 100644 --- a/web/frontend/src/components/utils/Endpoints.tsx +++ b/web/frontend/src/components/utils/Endpoints.tsx @@ -1,5 +1,6 @@ // information accessed through the middleware export const ENDPOINT_GET_TEQ_KEY = '/api/get_teq_key'; +export const ENDPOINT_DEV_LOGIN = '/api/get_dev_login'; export const ENDPOINT_PERSONAL_INFO = '/api/personal_info'; export const ENDPOINT_LOGOUT = '/api/logout'; export const ENDPOINT_USER_RIGHTS = '/api/user_rights'; diff --git a/web/frontend/src/pages/session/HandleLogin.tsx b/web/frontend/src/pages/session/HandleLogin.tsx index a204facdf..88d5326b1 100644 --- a/web/frontend/src/pages/session/HandleLogin.tsx +++ b/web/frontend/src/pages/session/HandleLogin.tsx @@ -1,11 +1,18 @@ -import { ENDPOINT_GET_TEQ_KEY } from 'components/utils/Endpoints'; +import { ENDPOINT_DEV_LOGIN, ENDPOINT_GET_TEQ_KEY } from 'components/utils/Endpoints'; import { FlashLevel, FlashState } from 'index'; // The backend will provide the client the URL to make a Tequila authentication. // We therefore redirect to this address. const handleLogin = async (fctx: FlashState) => { try { - const res = await fetch(ENDPOINT_GET_TEQ_KEY); + let res; + if (process.env.NODE_ENV === 'development') { + await fetch(ENDPOINT_DEV_LOGIN); + window.location.reload(); + return; + } else { + res = await fetch(ENDPOINT_GET_TEQ_KEY); + } const d = new Date(); d.setTime(d.getTime() + 120000);