From 0f4c70f9df2df5812f69ce064500de02aefc0310 Mon Sep 17 00:00:00 2001 From: Tatenda Date: Sat, 30 Apr 2022 01:24:55 +0200 Subject: [PATCH 01/12] WIP user registration --- models/user.js | 38 ++++++++++++- routes/api_v1.js | 3 - routes/auth.js | 109 ++++++++++++++++++++++++++++++++++++- server.js | 19 ++++++- src/css/custom.css | 8 ++- views/dblogin.ejs | 63 +++++++++++++++++++++ views/login.ejs | 21 ++++--- views/register.ejs | 87 +++++++++++++++++++---------- views/register_options.ejs | 72 ++++++++++++++++++++++++ 9 files changed, 371 insertions(+), 49 deletions(-) create mode 100644 views/dblogin.ejs create mode 100644 views/register_options.ejs diff --git a/models/user.js b/models/user.js index 9796dd3c..9da9b5e6 100644 --- a/models/user.js +++ b/models/user.js @@ -9,6 +9,14 @@ module.exports = function (sequelize, DataTypes) { allowNull: false, primaryKey: true, }, + user_uuid: { + type: DataTypes.STRING(255), + allowNull: true, + }, + userId: { + type: DataTypes.STRING(255), + allowNull: true, + }, firstName: { type: DataTypes.STRING(255), allowNull: true, @@ -39,10 +47,21 @@ module.exports = function (sequelize, DataTypes) { type: DataTypes.STRING(255), allowNull: true, }, - createdAt: { - type: DataTypes.DATE, + farmName: { + type: DataTypes.STRING(255), + allowNull: true, + }, + organisationName: { + type: DataTypes.STRING(255), + allowNull: true, + }, + organisationType: { + type: DataTypes.STRING(255), + allowNull: true, + }, + city: { + type: DataTypes.STRING(255), allowNull: true, - defaultValue: Sequelize.Sequelize.literal('CURRENT_TIMESTAMP'), }, registrationChannel: { type: DataTypes.STRING(255), @@ -52,6 +71,19 @@ module.exports = function (sequelize, DataTypes) { type: DataTypes.BLOB, allowNull: true, }, + emailVerificationToken: { + type: DataTypes.STRING, + allowNull: true, + }, + isEmailVerified: { + type: DataTypes.BOOLEAN, + defaultValue: false, + }, + createdAt: { + type: DataTypes.DATE, + allowNull: true, + defaultValue: Sequelize.Sequelize.literal('CURRENT_TIMESTAMP'), + }, }, { sequelize, diff --git a/routes/api_v1.js b/routes/api_v1.js index 95f6c77f..24f2af79 100644 --- a/routes/api_v1.js +++ b/routes/api_v1.js @@ -12,7 +12,6 @@ let models = initModels(sequelise); const { Sequelize } = require('sequelize'); let passport = require('passport'); - /** * @swagger * components: @@ -952,7 +951,6 @@ router.post('/harvest/whatsapp', function (req, res, next) { } }); - /** * @swagger * /app/api/v1/storage: @@ -1712,7 +1710,6 @@ router.post('/storage/whatsapp', function (req, res, next) { } }); - /** * @swagger * /app/api/v1/qrcount/scans/{startDate}: diff --git a/routes/auth.js b/routes/auth.js index 655188f8..97a09b12 100644 --- a/routes/auth.js +++ b/routes/auth.js @@ -2,7 +2,12 @@ var express = require('express'); var router = express.Router(); var passport = require('passport'); const fetch = (...args) => import('node-fetch').then(({ default: fetch }) => fetch(...args)); +var fs = require('fs'); +const multer = require('multer'); //middleware for handling multipart/form-data, which is primarily used for uploading files +const upload = multer({ dest: './static/images/produce_images/' }); //path.join(__dirname, 'static/images/produce_images/) +var crypto = require('crypto'); +const uuidv4 = require('uuid/v4'); var initModels = require('../models/init-models'); var sequelise = require('../config/db/db_sequelise'); @@ -29,6 +34,19 @@ router.post( }) //instruct Passport to flash an error message using the message given by the strategy's verify callback, if any ); +/* Render DB Login page. */ +router.get('/dblogin', function (req, res) { + if (req.user) { + res.redirect('/'); + } else { + res.render('dblogin', { + title: 'FoodPrint - User Login', + user: req.user, + page_name: 'login', + }); + } +}); + /* Process Login form submission (DB Based Auth). */ /* TODO add a user not found message */ router.post( @@ -49,6 +67,9 @@ router.get('/logout', function (req, res) { /* Render Register page. */ router.get('/register/:message?', function (req, res) { + // choice + let choice = req.query.choice; + choice = typeof choice === 'undefined' ? '' : choice; req.params.message ? res.render('message', { title: 'FoodPrint - User Registration', @@ -61,13 +82,97 @@ router.get('/register/:message?', function (req, res) { title: 'FoodPrint - User Registration', user: req.user, page_name: 'register', + choice: choice, }); + // console.log(req.query) +}); + +/*Render register_options */ +router.get('/register_options', function (req, res) { + res.render('register_options', { + title: 'FoodPrint - User Registration', + user: req.user, + page_name: 'register', + }); }); /* Process register form submission . */ -router.post('/register', function (req, res) { +router.post('/register', upload.single('registerIDPhoto'), async function (req, res) { //TODO - Log registration to table and send email to FoodPrint Admin - res.redirect('/app/auth/register/message'); + + //res.redirect('/app/auth/register/message'); + try { + let user = { + user_uuid: uuidv4(), + userId: `${req.body.role.charAt(0).toUpperCase()}-${crypto + .createHash('md5') + .update(req.body.registerEmail) + .digest('hex')}`, + firstName: req.body.registerName, + middleName: '', + lastName: req.body.registerSurname, + phoneNumber: req.body.registerPhoneNumber, + email: req.body.registerEmail, + role: req.body.role, + password: req.body.password, + ...(req.body.role === 'farmer' && { farmName: req.body.farmName }), + ...(req.body.role === 'intermediary' && { organisationName: req.body.registerOrgName }), + ...(req.body.role === 'intermediary' && { organisationType: req.body.registerOrgType }), + ...(req.body.role === 'agent' && { city: req.body.city }), + registrationChannel: 'web', + }; + + const img = req.file; + if (user.role === 'agent') { + fs.readFile(img.path, function (err, img_datadata) { + user['nationalIdPhotoHash'] = img_datadata; + }); + } + + models.User.create(user) + .then(_ => { + models.User.findAll({ + attributes: [ + 'ID', + 'firstName', + 'middleName', + 'lastName', + 'phoneNumber', + 'email', + 'role', + 'createdAt', + 'farmName', + 'registrationChannel', + 'nationalIdPhotoHash', + 'organisationName', + 'organisationType', + 'city', + ], + where: { + email: req.body.registerEmail, + }, + }) + .then(users => { + if (users.length === 0) { + res.status(404).send({ message: 'user not found' }); + } else { + // res.status(201).send(users[0]); + res.redirect('/app/auth/register/message'); + } + }) + .catch(err => { + console.log(err); + res.status(400).send({ message: err.message }); + }); + }) + .catch(err => { + console.log(err); + res.status(400).send({ message: err.message }); + }); + } catch (e) { + console.log(e); + res.status(500).send({ error: e, message: 'Unexpected error occurred 😤' }); + } }); /* Process register for WhatsApp*/ diff --git a/server.js b/server.js index 6241d9e5..1ed4cbc5 100644 --- a/server.js +++ b/server.js @@ -60,9 +60,10 @@ var configRouter = require('./routes/config'); var harvestRouter = require('./routes/harvest'); var storageRouter = require('./routes/storage'); var authRouter = require('./routes/auth'); -var blockchainRouter = require('./routes/blockchain'); +// var blockchainRouter = require('./routes/blockchain'); var dashboardsRouter = require('./routes/dashboards'); var qrCodeRouter = require('./routes/qrcode'); +var umsRouter = require('./routes/usermanagement'); var testRouter = require('./routes/test'); var searchRouter = require('./routes/search'); @@ -140,9 +141,10 @@ app.use('/docs', swaggerUi.serve, swaggerUi.setup(swaggerSpecs)); // Mount routers app.use('/', router); -app.use('/', blockchainRouter); +// app.use('/', blockchainRouter); app.use('/app/config', configRouter); app.use('/app/auth', authRouter); +app.use('/app/usermanagement', umsRouter); app.use('/app/harvest', harvestRouter); app.use('/app/storage', storageRouter); app.use('/app/produce', produceRouter); @@ -236,6 +238,19 @@ passport.deserializeUser(function (id, cb) { } cb(null, user); }); + //Models currently giving error upon login + /*models.User.findUserById(id, function (err, user) { + if (err) { + return cb(err); + } + cb(null, user); + }); + models.User.findByUsername(id, function (err, user) { + if (err) { + return cb(err); + } + cb(null, user); + });*/ }); // catch 404 and forward to error handler diff --git a/src/css/custom.css b/src/css/custom.css index 04999238..c46b086a 100644 --- a/src/css/custom.css +++ b/src/css/custom.css @@ -5,10 +5,14 @@ overflow: hidden; } +.register-option { + padding: 10px; +} + /* spinner CSS */ @keyframes spinner-border { to { transform: rotate(360deg); } - } + } .spinner-border{ display: inline-block; width: 1rem; @@ -23,4 +27,4 @@ .spinner-border-sm{ height: 1rem; border-width: .2em; - } \ No newline at end of file + } diff --git a/views/dblogin.ejs b/views/dblogin.ejs new file mode 100644 index 00000000..9c285fc9 --- /dev/null +++ b/views/dblogin.ejs @@ -0,0 +1,63 @@ + + + + <% include ./partials/head %> + + + + +
+ + + + + +
+
+ +
+

USER LOGIN

+ <% include ./partials/notificationbar %> +
+
+

Enter Your Details

+ +
+
+ + +
+ +
+ + +
+ +
+ +
+ +
+ Don't have a FoodPrint account yet? Sign up now. +
+ + + +
+
+ +
+
+ + +<% include ./partials/footer %> + + + + + + + + diff --git a/views/login.ejs b/views/login.ejs index b1b8bb35..91cfd542 100644 --- a/views/login.ejs +++ b/views/login.ejs @@ -1,7 +1,7 @@ - <% include ./partials/head %> + <% include ./partials/head %> @@ -12,8 +12,8 @@ <% include ./partials/header %> - - + +
@@ -29,20 +29,23 @@
- +
- +
- -
+ + +
+ Don't have a FoodPrint account yet? Sign up now.
- + @@ -54,7 +57,7 @@ <% include ./partials/footer %> - + diff --git a/views/register.ejs b/views/register.ejs index c79ef4ad..47859839 100644 --- a/views/register.ejs +++ b/views/register.ejs @@ -1,7 +1,12 @@ - <% include ./partials/head %> + <% include ./partials/head %> + @@ -12,11 +17,11 @@ <% include ./partials/header %> - - + +
- +

USER REGISTRATION

<% include ./partials/notificationbar %> @@ -24,7 +29,7 @@

Enter Your Details

-
+
@@ -35,9 +40,14 @@
+
+ + +
+
- +
@@ -45,28 +55,49 @@
-
- - -
+ + + + <%if(choice && choice.length > 0 && choice === 'agent'){%> +
+ + +
+ +
+ + +
+ <%}%> + + + + <%if(choice && choice.length > 0 && choice === 'intermediary'){%> +
+ + +
+ +
+ + +
+ <%}%> + + + + <%if(choice && choice.length > 0 && choice === 'farmer'){%> +
+ + +
+ <%}%> + -
- - -
-
- +
By signing up, you are indicating that you have read and agree to the Terms of Use and Privacy Policy.
@@ -74,21 +105,21 @@
Already have a FoodPrint account? Sign in now.
- +
- +
<% include ./partials/footer %> - + - + diff --git a/views/register_options.ejs b/views/register_options.ejs new file mode 100644 index 00000000..6cc05458 --- /dev/null +++ b/views/register_options.ejs @@ -0,0 +1,72 @@ + + + + <% include ./partials/head %> + + + + +
+ + + + + +
+
+ +
+ +

USER REGISTRATION

+ <% include ./partials/notificationbar %> +
+
+

What interests you about joining the FoodPrint initiative

+ +
+ + +
+ + +
+ +
+ + +
+ +
+ + +
+ + +
+ +
+ +
+ Already have a FoodPrint account? Sign in now. +
+ + +
+
+ +
+
+ + +<% include ./partials/footer %> + + + + + + + + From fea87d224441584e11a8594b8295b0e9b52c49a7 Mon Sep 17 00:00:00 2001 From: Tatenda Date: Tue, 28 Jun 2022 22:16:26 +0200 Subject: [PATCH 02/12] WIP user registration --- .../20220429215904-add_new_user_columns.js | 30 + .../20220604131504-remove-primary-index.js | 44 +- package-lock.json | 915 +++++++++++++++++- package.json | 2 + routes/auth.js | 86 +- routes/usermanagement.js | 13 + server.js | 86 +- views/register.ejs | 14 +- views/user_management.ejs | 35 + 9 files changed, 1171 insertions(+), 54 deletions(-) create mode 100644 migrations/20220429215904-add_new_user_columns.js create mode 100644 routes/usermanagement.js create mode 100644 views/user_management.ejs diff --git a/migrations/20220429215904-add_new_user_columns.js b/migrations/20220429215904-add_new_user_columns.js new file mode 100644 index 00000000..1c83614e --- /dev/null +++ b/migrations/20220429215904-add_new_user_columns.js @@ -0,0 +1,30 @@ +'use strict'; + +module.exports = { + up: async (queryInterface, Sequelize) => { + /** + * Add altering commands here. + * + * Example: + * await queryInterface.createTable('users', { id: Sequelize.INTEGER }); + */ + await queryInterface.addColumn('user', 'userId', { + type: Sequelize.STRING(255), + }); + await queryInterface.addColumn('user', 'user_uuid', { + type: Sequelize.STRING(255), + }); + }, + + down: async (queryInterface, Sequelize) => { + /** + * Add reverting commands here. + * + * Example: + * await queryInterface.dropTable('users'); + */ + + await queryInterface.removeColumn('user', 'userId'); + await queryInterface.removeColumn('user', 'user_uuid'); + }, +}; diff --git a/migrations/20220604131504-remove-primary-index.js b/migrations/20220604131504-remove-primary-index.js index e983b54d..a5359cbb 100644 --- a/migrations/20220604131504-remove-primary-index.js +++ b/migrations/20220604131504-remove-primary-index.js @@ -7,29 +7,31 @@ $npm run build-dev module.exports = { up: async (queryInterface, Sequelize) => { // logic for transforming into the new state - await queryInterface.removeIndex('foodprint_config', 'PRIMARY') - .then(queryInterface.removeIndex('foodprint_harvest', 'PRIMARY')) - .then(queryInterface.removeIndex('foodprint_produce', 'PRIMARY')) - .then(queryInterface.removeIndex('foodprint_produce_price', 'PRIMARY')) - .then(queryInterface.removeIndex('foodprint_qrcount', 'PRIMARY')) - .then(queryInterface.removeIndex('foodprint_storage', 'PRIMARY')) - .then(queryInterface.removeIndex('foodprint_subscription', 'PRIMARY')) - .then(queryInterface.removeIndex('foodprint_weeklyview', 'PRIMARY')) - .then(queryInterface.removeIndex('market_subscription', 'PRIMARY')) - .then(queryInterface.removeIndex('user', 'PRIMARY')); + await queryInterface + .removeIndex('foodprint_config', 'PRIMARY') + .then(queryInterface.removeIndex('foodprint_harvest', 'PRIMARY')) + .then(queryInterface.removeIndex('foodprint_produce', 'PRIMARY')) + .then(queryInterface.removeIndex('foodprint_produce_price', 'PRIMARY')) + .then(queryInterface.removeIndex('foodprint_qrcount', 'PRIMARY')) + .then(queryInterface.removeIndex('foodprint_storage', 'PRIMARY')) + .then(queryInterface.removeIndex('foodprint_subscription', 'PRIMARY')) + .then(queryInterface.removeIndex('foodprint_weeklyview', 'PRIMARY')) + .then(queryInterface.removeIndex('market_subscription', 'PRIMARY')) + .then(queryInterface.removeIndex('user', 'PRIMARY')); }, down: async (queryInterface, Sequelize) => { // logic for reverting the changes - await queryInterface.addIndex('foodprint_config', 'PRIMARY') - .then(queryInterface.addIndex('foodprint_harvest', 'PRIMARY')) - .then(queryInterface.addIndex('foodprint_produce', 'PRIMARY')) - .then(queryInterface.addIndex('foodprint_produce_price', 'PRIMARY')) - .then(queryInterface.addIndex('foodprint_qrcount', 'PRIMARY')) - .then(queryInterface.addIndex('foodprint_storage', 'PRIMARY')) - .then(queryInterface.addIndex('foodprint_subscription', 'PRIMARY')) - .then(queryInterface.addIndex('foodprint_weeklyview', 'PRIMARY')) - .then(queryInterface.addIndex('market_subscription', 'PRIMARY')) - .then(queryInterface.addIndex('user', 'PRIMARY')); - } + await queryInterface + .addIndex('foodprint_config', 'PRIMARY') + .then(queryInterface.addIndex('foodprint_harvest', 'PRIMARY')) + .then(queryInterface.addIndex('foodprint_produce', 'PRIMARY')) + .then(queryInterface.addIndex('foodprint_produce_price', 'PRIMARY')) + .then(queryInterface.addIndex('foodprint_qrcount', 'PRIMARY')) + .then(queryInterface.addIndex('foodprint_storage', 'PRIMARY')) + .then(queryInterface.addIndex('foodprint_subscription', 'PRIMARY')) + .then(queryInterface.addIndex('foodprint_weeklyview', 'PRIMARY')) + .then(queryInterface.addIndex('market_subscription', 'PRIMARY')) + .then(queryInterface.addIndex('user', 'PRIMARY')); + }, }; diff --git a/package-lock.json b/package-lock.json index 527b970d..2cac1fe7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,6 +12,7 @@ "dependencies": { "algosdk": "^1.12.0", "axios": "^0.26.1", + "bcrypt": "^5.0.1", "body-parser": "^1.19.0", "browserify": "^16.3.0", "connect-ensure-login": "^0.1.1", @@ -27,6 +28,7 @@ "fs": "0.0.1-security", "heroku-ssl-redirect": "0.0.4", "jimp": "^0.6.4", + "jsonwebtoken": "^8.5.1", "method-override": "^3.0.0", "moment": "^2.27.0", "morgan": "^1.9.1", @@ -562,6 +564,80 @@ "resolved": "https://registry.npmjs.org/@jsdevtools/ono/-/ono-7.1.3.tgz", "integrity": "sha512-4JQNk+3mVzK3xh2rqd6RB4J46qUR19azEHBneZyTZM+c456qOrbbM/5xcR8huNCCcbVt7+UmizG6GuUvPvKUYg==" }, + "node_modules/@mapbox/node-pre-gyp": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.9.tgz", + "integrity": "sha512-aDF3S3rK9Q2gey/WAttUlISduDItz5BU3306M9Eyv6/oS40aMprnopshtlKTykxRNIBEZuRMaZAnbrQ4QtKGyw==", + "dependencies": { + "detect-libc": "^2.0.0", + "https-proxy-agent": "^5.0.0", + "make-dir": "^3.1.0", + "node-fetch": "^2.6.7", + "nopt": "^5.0.0", + "npmlog": "^5.0.1", + "rimraf": "^3.0.2", + "semver": "^7.3.5", + "tar": "^6.1.11" + }, + "bin": { + "node-pre-gyp": "bin/node-pre-gyp" + } + }, + "node_modules/@mapbox/node-pre-gyp/node_modules/make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dependencies": { + "semver": "^6.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@mapbox/node-pre-gyp/node_modules/make-dir/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@mapbox/node-pre-gyp/node_modules/node-fetch": { + "version": "2.6.7", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", + "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/@mapbox/node-pre-gyp/node_modules/nopt": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz", + "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==", + "dependencies": { + "abbrev": "1" + }, + "bin": { + "nopt": "bin/nopt.js" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/@socket.io/base64-arraybuffer": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/@socket.io/base64-arraybuffer/-/base64-arraybuffer-1.0.2.tgz", @@ -649,8 +725,7 @@ "node_modules/abbrev": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", - "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", - "dev": true + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" }, "node_modules/accepts": { "version": "1.3.7", @@ -705,6 +780,38 @@ "node": ">=0.4.0" } }, + "node_modules/agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/agent-base/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/agent-base/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, "node_modules/algo-msgpack-with-bigint": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/algo-msgpack-with-bigint/-/algo-msgpack-with-bigint-2.1.1.tgz", @@ -900,12 +1007,42 @@ "resolved": "https://registry.npmjs.org/append-field/-/append-field-1.0.0.tgz", "integrity": "sha1-HjRA6RXwsSA9I3SOeO3XubW0PlY=" }, + "node_modules/aproba": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz", + "integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==" + }, "node_modules/archy": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", "integrity": "sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=", "dev": true }, + "node_modules/are-we-there-yet": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-2.0.0.tgz", + "integrity": "sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw==", + "dependencies": { + "delegates": "^1.0.0", + "readable-stream": "^3.6.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/are-we-there-yet/node_modules/readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", @@ -1345,6 +1482,19 @@ "integrity": "sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY=", "dev": true }, + "node_modules/bcrypt": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/bcrypt/-/bcrypt-5.0.1.tgz", + "integrity": "sha512-9BTgmrhZM2t1bNuDtrtIMVSmmxZBrJ71n8Wg+YgdjHuIWYF7SjjmCPZFB+/5i/o/PIeRpwVJR3P+NrpIItUjqw==", + "hasInstallScript": true, + "dependencies": { + "@mapbox/node-pre-gyp": "^1.0.0", + "node-addon-api": "^3.1.0" + }, + "engines": { + "node": ">= 10.0.0" + } + }, "node_modules/beeper": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/beeper/-/beeper-1.1.1.tgz", @@ -1945,6 +2095,11 @@ "node": ">=0.4.0" } }, + "node_modules/buffer-equal-constant-time": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", + "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==" + }, "node_modules/buffer-from": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", @@ -2240,6 +2395,14 @@ "fsevents": "~2.3.2" } }, + "node_modules/chownr": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", + "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", + "engines": { + "node": ">=10" + } + }, "node_modules/ci-info": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-1.6.0.tgz", @@ -2530,7 +2693,6 @@ "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==", - "dev": true, "bin": { "color-support": "bin.js" } @@ -2677,6 +2839,11 @@ "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz", "integrity": "sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==" }, + "node_modules/console-control-strings": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", + "integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==" + }, "node_modules/constants-browserify": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", @@ -3087,6 +3254,11 @@ "node": ">=0.4.0" } }, + "node_modules/delegates": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", + "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==" + }, "node_modules/denque": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/denque/-/denque-2.0.1.tgz", @@ -3140,6 +3312,14 @@ "node": ">=0.10.0" } }, + "node_modules/detect-libc": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.1.tgz", + "integrity": "sha512-463v3ZeIrcWtdgIg6vI6XUncguvr2TnGl4SzDXinkt9mSLpBJKXT3mW6xT3VQdDN11+WVs29pgvivTc4Lp8v+w==", + "engines": { + "node": ">=8" + } + }, "node_modules/detect-newline": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-2.1.0.tgz", @@ -3367,6 +3547,14 @@ "node": ">= 0.8.0" } }, + "node_modules/ecdsa-sig-formatter": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", + "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", + "dependencies": { + "safe-buffer": "^5.0.1" + } + }, "node_modules/editorconfig": { "version": "0.15.3", "resolved": "https://registry.npmjs.org/editorconfig/-/editorconfig-0.15.3.tgz", @@ -4563,6 +4751,17 @@ "universalify": "^0.1.0" } }, + "node_modules/fs-minipass": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", + "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, "node_modules/fs-mkdirp-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs-mkdirp-stream/-/fs-mkdirp-stream-1.0.0.tgz", @@ -4600,6 +4799,65 @@ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" }, + "node_modules/gauge": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-3.0.2.tgz", + "integrity": "sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q==", + "dependencies": { + "aproba": "^1.0.3 || ^2.0.0", + "color-support": "^1.1.2", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.1", + "object-assign": "^4.1.1", + "signal-exit": "^3.0.0", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1", + "wide-align": "^1.1.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/gauge/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/gauge/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "engines": { + "node": ">=8" + } + }, + "node_modules/gauge/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/gauge/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/generate-function": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.3.1.tgz", @@ -5918,6 +6176,11 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/has-unicode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", + "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==" + }, "node_modules/has-value": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", @@ -6110,6 +6373,39 @@ "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=" }, + "node_modules/https-proxy-agent": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "dependencies": { + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/https-proxy-agent/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/https-proxy-agent/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, "node_modules/iconv-lite": { "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", @@ -6449,7 +6745,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true, "engines": { "node": ">=4" } @@ -6831,12 +7126,65 @@ "node": "*" } }, + "node_modules/jsonwebtoken": { + "version": "8.5.1", + "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz", + "integrity": "sha512-XjwVfRS6jTMsqYs0EsuJ4LGxXV14zQybNd4L2r0UvbVnSF9Af8x7p5MzbJ90Ioz/9TI41/hTCvznF/loiSzn8w==", + "dependencies": { + "jws": "^3.2.2", + "lodash.includes": "^4.3.0", + "lodash.isboolean": "^3.0.3", + "lodash.isinteger": "^4.0.4", + "lodash.isnumber": "^3.0.3", + "lodash.isplainobject": "^4.0.6", + "lodash.isstring": "^4.0.1", + "lodash.once": "^4.0.0", + "ms": "^2.1.1", + "semver": "^5.6.0" + }, + "engines": { + "node": ">=4", + "npm": ">=1.4.28" + } + }, + "node_modules/jsonwebtoken/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, + "node_modules/jsonwebtoken/node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "bin": { + "semver": "bin/semver" + } + }, "node_modules/just-debounce": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/just-debounce/-/just-debounce-1.1.0.tgz", "integrity": "sha512-qpcRocdkUmf+UTNBYx5w6dexX5J31AKK1OmPwH630a83DdVVUIngk55RSAiIGpQyoH0dlr872VHfPjnQnK1qDQ==", "dev": true }, + "node_modules/jwa": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", + "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==", + "dependencies": { + "buffer-equal-constant-time": "1.0.1", + "ecdsa-sig-formatter": "1.0.11", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/jws": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", + "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", + "dependencies": { + "jwa": "^1.4.1", + "safe-buffer": "^5.0.1" + } + }, "node_modules/kind-of": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", @@ -7272,6 +7620,11 @@ "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=" }, + "node_modules/lodash.includes": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz", + "integrity": "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==" + }, "node_modules/lodash.isarguments": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz", @@ -7284,6 +7637,11 @@ "integrity": "sha1-eeTriMNqgSKvhvhEqpvNhRtfu1U=", "dev": true }, + "node_modules/lodash.isboolean": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz", + "integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==" + }, "node_modules/lodash.isequal": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", @@ -7295,6 +7653,26 @@ "integrity": "sha1-+4m2WpqAKBgz8LdHizpRBPiY67M=", "dev": true }, + "node_modules/lodash.isinteger": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz", + "integrity": "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==" + }, + "node_modules/lodash.isnumber": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz", + "integrity": "sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==" + }, + "node_modules/lodash.isplainobject": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", + "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==" + }, + "node_modules/lodash.isstring": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", + "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==" + }, "node_modules/lodash.keys": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-3.1.2.tgz", @@ -7316,6 +7694,11 @@ "resolved": "https://registry.npmjs.org/lodash.mergewith/-/lodash.mergewith-4.6.2.tgz", "integrity": "sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ==" }, + "node_modules/lodash.once": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", + "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==" + }, "node_modules/lodash.restparam": { "version": "3.6.1", "resolved": "https://registry.npmjs.org/lodash.restparam/-/lodash.restparam-3.6.1.tgz", @@ -7883,6 +8266,29 @@ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" }, + "node_modules/minipass": { + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.6.tgz", + "integrity": "sha512-rty5kpw9/z8SX9dmxblFA6edItUmwJgMeYDZRrwlIVN27i8gysGbznJwUggw2V/FVqFSDdWy040ZPS811DYAqQ==", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minizlib": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", + "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", + "dependencies": { + "minipass": "^3.0.0", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">= 8" + } + }, "node_modules/mitt": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/mitt/-/mitt-1.2.0.tgz", @@ -8479,6 +8885,11 @@ "integrity": "sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==", "dev": true }, + "node_modules/node-addon-api": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-3.2.1.tgz", + "integrity": "sha512-mmcei9JghVNDYydghQmeDX8KoAm0FAiYyIcUt/N4nhyAipB17pllZQDOJD2fotxABnt4Mdz+dKTO7eftLg4d0A==" + }, "node_modules/node-domexception": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz", @@ -8963,6 +9374,17 @@ "node": ">=4" } }, + "node_modules/npmlog": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-5.0.1.tgz", + "integrity": "sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw==", + "dependencies": { + "are-we-there-yet": "^2.0.0", + "console-control-strings": "^1.1.0", + "gauge": "^3.0.0", + "set-blocking": "^2.0.0" + } + }, "node_modules/number-is-nan": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", @@ -10420,6 +10842,20 @@ "resolved": "https://registry.npmjs.org/retry-as-promised/-/retry-as-promised-5.0.0.tgz", "integrity": "sha512-6S+5LvtTl2ggBumk04hBo/4Uf6fRJUwIgunGZ7CYEBCeufGFW1Pu6ucUf/UskHeWOIsUcLOGLFXPig5tR5V1nA==" }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/ripemd160": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", @@ -11148,8 +11584,7 @@ "node_modules/signal-exit": { "version": "3.0.5", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.5.tgz", - "integrity": "sha512-KWcOiKeQj6ZyXx7zq4YxSMgHRlod4czeBQZrPb8OKcohcqAXShm7E20kEMle9WBt26hFcAf0qLOcp5zmY7kOqQ==", - "dev": true + "integrity": "sha512-KWcOiKeQj6ZyXx7zq4YxSMgHRlod4czeBQZrPb8OKcohcqAXShm7E20kEMle9WBt26hFcAf0qLOcp5zmY7kOqQ==" }, "node_modules/simple-concat": { "version": "1.0.1", @@ -11788,7 +12223,6 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, "dependencies": { "is-fullwidth-code-point": "^2.0.0", "strip-ansi": "^4.0.0" @@ -11801,7 +12235,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true, "engines": { "node": ">=4" } @@ -11810,7 +12243,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, "dependencies": { "ansi-regex": "^3.0.0" }, @@ -12082,6 +12514,33 @@ "acorn-node": "^1.2.0" } }, + "node_modules/tar": { + "version": "6.1.11", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.11.tgz", + "integrity": "sha512-an/KZQzQUkZCkuoAA64hM92X0Urb6VpRhAFllDzz44U2mcD5scmT3zBc4VgVpkugF580+DQn8eAFSyoQt0tznA==", + "dependencies": { + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "minipass": "^3.0.0", + "minizlib": "^2.1.1", + "mkdirp": "^1.0.3", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/tar/node_modules/mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/term-size": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/term-size/-/term-size-1.2.0.tgz", @@ -12281,6 +12740,11 @@ "nodetouch": "bin/nodetouch.js" } }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" + }, "node_modules/transfob": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/transfob/-/transfob-1.0.0.tgz", @@ -13189,6 +13653,20 @@ "node": ">= 8" } }, + "node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" + }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -13209,6 +13687,14 @@ "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=" }, + "node_modules/wide-align": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz", + "integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==", + "dependencies": { + "string-width": "^1.0.2 || 2 || 3 || 4" + } + }, "node_modules/widest-line": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-2.0.1.tgz", @@ -14036,6 +14522,55 @@ "resolved": "https://registry.npmjs.org/@jsdevtools/ono/-/ono-7.1.3.tgz", "integrity": "sha512-4JQNk+3mVzK3xh2rqd6RB4J46qUR19azEHBneZyTZM+c456qOrbbM/5xcR8huNCCcbVt7+UmizG6GuUvPvKUYg==" }, + "@mapbox/node-pre-gyp": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.9.tgz", + "integrity": "sha512-aDF3S3rK9Q2gey/WAttUlISduDItz5BU3306M9Eyv6/oS40aMprnopshtlKTykxRNIBEZuRMaZAnbrQ4QtKGyw==", + "requires": { + "detect-libc": "^2.0.0", + "https-proxy-agent": "^5.0.0", + "make-dir": "^3.1.0", + "node-fetch": "^2.6.7", + "nopt": "^5.0.0", + "npmlog": "^5.0.1", + "rimraf": "^3.0.2", + "semver": "^7.3.5", + "tar": "^6.1.11" + }, + "dependencies": { + "make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "requires": { + "semver": "^6.0.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + } + } + }, + "node-fetch": { + "version": "2.6.7", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", + "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", + "requires": { + "whatwg-url": "^5.0.0" + } + }, + "nopt": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz", + "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==", + "requires": { + "abbrev": "1" + } + } + } + }, "@socket.io/base64-arraybuffer": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/@socket.io/base64-arraybuffer/-/base64-arraybuffer-1.0.2.tgz", @@ -14120,8 +14655,7 @@ "abbrev": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", - "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", - "dev": true + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" }, "accepts": { "version": "1.3.7", @@ -14160,6 +14694,29 @@ "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz", "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==" }, + "agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "requires": { + "debug": "4" + }, + "dependencies": { + "debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "requires": { + "ms": "2.1.2" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + } + } + }, "algo-msgpack-with-bigint": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/algo-msgpack-with-bigint/-/algo-msgpack-with-bigint-2.1.1.tgz", @@ -14309,12 +14866,38 @@ "resolved": "https://registry.npmjs.org/append-field/-/append-field-1.0.0.tgz", "integrity": "sha1-HjRA6RXwsSA9I3SOeO3XubW0PlY=" }, + "aproba": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz", + "integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==" + }, "archy": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", "integrity": "sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=", "dev": true }, + "are-we-there-yet": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-2.0.0.tgz", + "integrity": "sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw==", + "requires": { + "delegates": "^1.0.0", + "readable-stream": "^3.6.0" + }, + "dependencies": { + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + } + } + }, "argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", @@ -14655,6 +15238,15 @@ "integrity": "sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY=", "dev": true }, + "bcrypt": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/bcrypt/-/bcrypt-5.0.1.tgz", + "integrity": "sha512-9BTgmrhZM2t1bNuDtrtIMVSmmxZBrJ71n8Wg+YgdjHuIWYF7SjjmCPZFB+/5i/o/PIeRpwVJR3P+NrpIItUjqw==", + "requires": { + "@mapbox/node-pre-gyp": "^1.0.0", + "node-addon-api": "^3.1.0" + } + }, "beeper": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/beeper/-/beeper-1.1.1.tgz", @@ -15161,6 +15753,11 @@ "resolved": "https://registry.npmjs.org/buffer-equal/-/buffer-equal-0.0.1.tgz", "integrity": "sha1-kbx0sR6kBbyRa8aqkI+q+ltKrEs=" }, + "buffer-equal-constant-time": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", + "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==" + }, "buffer-from": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", @@ -15407,6 +16004,11 @@ "readdirp": "~3.6.0" } }, + "chownr": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", + "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==" + }, "ci-info": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-1.6.0.tgz", @@ -15646,8 +16248,7 @@ "color-support": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", - "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==", - "dev": true + "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==" }, "combine-source-map": { "version": "0.8.0", @@ -15769,6 +16370,11 @@ "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz", "integrity": "sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==" }, + "console-control-strings": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", + "integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==" + }, "constants-browserify": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", @@ -16121,6 +16727,11 @@ "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" }, + "delegates": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", + "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==" + }, "denque": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/denque/-/denque-2.0.1.tgz", @@ -16162,6 +16773,11 @@ "integrity": "sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc=", "dev": true }, + "detect-libc": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.1.tgz", + "integrity": "sha512-463v3ZeIrcWtdgIg6vI6XUncguvr2TnGl4SzDXinkt9mSLpBJKXT3mW6xT3VQdDN11+WVs29pgvivTc4Lp8v+w==" + }, "detect-newline": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-2.1.0.tgz", @@ -16352,6 +16968,14 @@ "tfunk": "^4.0.0" } }, + "ecdsa-sig-formatter": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", + "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", + "requires": { + "safe-buffer": "^5.0.1" + } + }, "editorconfig": { "version": "0.15.3", "resolved": "https://registry.npmjs.org/editorconfig/-/editorconfig-0.15.3.tgz", @@ -17331,6 +17955,14 @@ "universalify": "^0.1.0" } }, + "fs-minipass": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", + "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", + "requires": { + "minipass": "^3.0.0" + } + }, "fs-mkdirp-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs-mkdirp-stream/-/fs-mkdirp-stream-1.0.0.tgz", @@ -17358,6 +17990,52 @@ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" }, + "gauge": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-3.0.2.tgz", + "integrity": "sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q==", + "requires": { + "aproba": "^1.0.3 || ^2.0.0", + "color-support": "^1.1.2", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.1", + "object-assign": "^4.1.1", + "signal-exit": "^3.0.0", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1", + "wide-align": "^1.1.2" + }, + "dependencies": { + "ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==" + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" + }, + "string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + } + }, + "strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "requires": { + "ansi-regex": "^5.0.1" + } + } + } + }, "generate-function": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.3.1.tgz", @@ -18438,6 +19116,11 @@ "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==" }, + "has-unicode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", + "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==" + }, "has-value": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", @@ -18602,6 +19285,30 @@ "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=" }, + "https-proxy-agent": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "requires": { + "agent-base": "6", + "debug": "4" + }, + "dependencies": { + "debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "requires": { + "ms": "2.1.2" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + } + } + }, "iconv-lite": { "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", @@ -18853,8 +19560,7 @@ "is-fullwidth-code-point": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" }, "is-function": { "version": "1.0.2", @@ -19143,12 +19849,60 @@ "through": ">=2.2.7 <3" } }, + "jsonwebtoken": { + "version": "8.5.1", + "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz", + "integrity": "sha512-XjwVfRS6jTMsqYs0EsuJ4LGxXV14zQybNd4L2r0UvbVnSF9Af8x7p5MzbJ90Ioz/9TI41/hTCvznF/loiSzn8w==", + "requires": { + "jws": "^3.2.2", + "lodash.includes": "^4.3.0", + "lodash.isboolean": "^3.0.3", + "lodash.isinteger": "^4.0.4", + "lodash.isnumber": "^3.0.3", + "lodash.isplainobject": "^4.0.6", + "lodash.isstring": "^4.0.1", + "lodash.once": "^4.0.0", + "ms": "^2.1.1", + "semver": "^5.6.0" + }, + "dependencies": { + "ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" + } + } + }, "just-debounce": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/just-debounce/-/just-debounce-1.1.0.tgz", "integrity": "sha512-qpcRocdkUmf+UTNBYx5w6dexX5J31AKK1OmPwH630a83DdVVUIngk55RSAiIGpQyoH0dlr872VHfPjnQnK1qDQ==", "dev": true }, + "jwa": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", + "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==", + "requires": { + "buffer-equal-constant-time": "1.0.1", + "ecdsa-sig-formatter": "1.0.11", + "safe-buffer": "^5.0.1" + } + }, + "jws": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", + "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", + "requires": { + "jwa": "^1.4.1", + "safe-buffer": "^5.0.1" + } + }, "kind-of": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", @@ -19504,6 +20258,11 @@ "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=" }, + "lodash.includes": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz", + "integrity": "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==" + }, "lodash.isarguments": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz", @@ -19516,6 +20275,11 @@ "integrity": "sha1-eeTriMNqgSKvhvhEqpvNhRtfu1U=", "dev": true }, + "lodash.isboolean": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz", + "integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==" + }, "lodash.isequal": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", @@ -19527,6 +20291,26 @@ "integrity": "sha1-+4m2WpqAKBgz8LdHizpRBPiY67M=", "dev": true }, + "lodash.isinteger": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz", + "integrity": "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==" + }, + "lodash.isnumber": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz", + "integrity": "sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==" + }, + "lodash.isplainobject": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", + "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==" + }, + "lodash.isstring": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", + "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==" + }, "lodash.keys": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-3.1.2.tgz", @@ -19548,6 +20332,11 @@ "resolved": "https://registry.npmjs.org/lodash.mergewith/-/lodash.mergewith-4.6.2.tgz", "integrity": "sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ==" }, + "lodash.once": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", + "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==" + }, "lodash.restparam": { "version": "3.6.1", "resolved": "https://registry.npmjs.org/lodash.restparam/-/lodash.restparam-3.6.1.tgz", @@ -20014,6 +20803,23 @@ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" }, + "minipass": { + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.6.tgz", + "integrity": "sha512-rty5kpw9/z8SX9dmxblFA6edItUmwJgMeYDZRrwlIVN27i8gysGbznJwUggw2V/FVqFSDdWy040ZPS811DYAqQ==", + "requires": { + "yallist": "^4.0.0" + } + }, + "minizlib": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", + "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", + "requires": { + "minipass": "^3.0.0", + "yallist": "^4.0.0" + } + }, "mitt": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/mitt/-/mitt-1.2.0.tgz", @@ -20488,6 +21294,11 @@ "integrity": "sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==", "dev": true }, + "node-addon-api": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-3.2.1.tgz", + "integrity": "sha512-mmcei9JghVNDYydghQmeDX8KoAm0FAiYyIcUt/N4nhyAipB17pllZQDOJD2fotxABnt4Mdz+dKTO7eftLg4d0A==" + }, "node-domexception": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz", @@ -20869,6 +21680,17 @@ "path-key": "^2.0.0" } }, + "npmlog": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-5.0.1.tgz", + "integrity": "sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw==", + "requires": { + "are-we-there-yet": "^2.0.0", + "console-control-strings": "^1.1.0", + "gauge": "^3.0.0", + "set-blocking": "^2.0.0" + } + }, "number-is-nan": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", @@ -22018,6 +22840,14 @@ "resolved": "https://registry.npmjs.org/retry-as-promised/-/retry-as-promised-5.0.0.tgz", "integrity": "sha512-6S+5LvtTl2ggBumk04hBo/4Uf6fRJUwIgunGZ7CYEBCeufGFW1Pu6ucUf/UskHeWOIsUcLOGLFXPig5tR5V1nA==" }, + "rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "requires": { + "glob": "^7.1.3" + } + }, "ripemd160": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", @@ -22568,8 +23398,7 @@ "signal-exit": { "version": "3.0.5", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.5.tgz", - "integrity": "sha512-KWcOiKeQj6ZyXx7zq4YxSMgHRlod4czeBQZrPb8OKcohcqAXShm7E20kEMle9WBt26hFcAf0qLOcp5zmY7kOqQ==", - "dev": true + "integrity": "sha512-KWcOiKeQj6ZyXx7zq4YxSMgHRlod4czeBQZrPb8OKcohcqAXShm7E20kEMle9WBt26hFcAf0qLOcp5zmY7kOqQ==" }, "simple-concat": { "version": "1.0.1", @@ -23086,7 +23915,6 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, "requires": { "is-fullwidth-code-point": "^2.0.0", "strip-ansi": "^4.0.0" @@ -23095,14 +23923,12 @@ "ansi-regex": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=" }, "strip-ansi": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, "requires": { "ansi-regex": "^3.0.0" } @@ -23303,6 +24129,26 @@ "acorn-node": "^1.2.0" } }, + "tar": { + "version": "6.1.11", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.11.tgz", + "integrity": "sha512-an/KZQzQUkZCkuoAA64hM92X0Urb6VpRhAFllDzz44U2mcD5scmT3zBc4VgVpkugF580+DQn8eAFSyoQt0tznA==", + "requires": { + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "minipass": "^3.0.0", + "minizlib": "^2.1.1", + "mkdirp": "^1.0.3", + "yallist": "^4.0.0" + }, + "dependencies": { + "mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==" + } + } + }, "term-size": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/term-size/-/term-size-1.2.0.tgz", @@ -23465,6 +24311,11 @@ "nopt": "~1.0.10" } }, + "tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" + }, "transfob": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/transfob/-/transfob-1.0.0.tgz", @@ -24206,6 +25057,20 @@ "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.2.0.tgz", "integrity": "sha512-EqPmREeOzttaLRm5HS7io98goBgZ7IVz79aDvqjD0kYXLtFZTc0T/U6wHTPKyIjb+MdN7DFIIX6hgdBEpWmfPA==" }, + "webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" + }, + "whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "requires": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, "which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -24220,6 +25085,14 @@ "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=" }, + "wide-align": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz", + "integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==", + "requires": { + "string-width": "^1.0.2 || 2 || 3 || 4" + } + }, "widest-line": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-2.0.1.tgz", diff --git a/package.json b/package.json index c2024476..bd225189 100644 --- a/package.json +++ b/package.json @@ -48,6 +48,7 @@ "dependencies": { "algosdk": "^1.12.0", "axios": "^0.26.1", + "bcrypt": "^5.0.1", "body-parser": "^1.19.0", "browserify": "^16.3.0", "connect-ensure-login": "^0.1.1", @@ -63,6 +64,7 @@ "fs": "0.0.1-security", "heroku-ssl-redirect": "0.0.4", "jimp": "^0.6.4", + "jsonwebtoken": "^8.5.1", "method-override": "^3.0.0", "moment": "^2.27.0", "morgan": "^1.9.1", diff --git a/routes/auth.js b/routes/auth.js index 97a09b12..3cdeec15 100644 --- a/routes/auth.js +++ b/routes/auth.js @@ -13,6 +13,10 @@ var sequelise = require('../config/db/db_sequelise'); var models = initModels(sequelise); +const bcrypt = require('bcrypt'); +var jwt = require('jsonwebtoken'); +const nodemailer = require('nodemailer'); + /* Render Login page. */ router.get('/login', function (req, res) { if (req.user) { @@ -53,7 +57,7 @@ router.post( '/dblogin', passport.authenticate('db-local', { successReturnToOrRedirect: '/', - failureRedirect: '/app/auth/login', + failureRedirect: '/app/auth/dblogin', failureFlash: true, }) //instruct Passport to flash an error message using the message given by the strategy's verify callback, if any ); @@ -76,7 +80,7 @@ router.get('/register/:message?', function (req, res) { user: req.user, page_name: 'message', message: - 'Your registration has been submitted and is currently under review by the FoodPrint Team! You will be notified of status updates via the email you provided.', + 'Your registration has been submitted. Please check you email to verify your email address.', }) : res.render('register', { title: 'FoodPrint - User Registration', @@ -99,6 +103,10 @@ router.get('/register_options', function (req, res) { /* Process register form submission . */ router.post('/register', upload.single('registerIDPhoto'), async function (req, res) { //TODO - Log registration to table and send email to FoodPrint Admin + const salt = await bcrypt.genSalt(10); + const hashedPassword = await bcrypt.hash(req.body.password, salt); + + const confirmationCode = jwt.sign({ email: req.body.registerEmail }, process.env.TOKEN_SIGN); //res.redirect('/app/auth/register/message'); try { @@ -114,12 +122,14 @@ router.post('/register', upload.single('registerIDPhoto'), async function (req, phoneNumber: req.body.registerPhoneNumber, email: req.body.registerEmail, role: req.body.role, - password: req.body.password, + password: hashedPassword, ...(req.body.role === 'farmer' && { farmName: req.body.farmName }), ...(req.body.role === 'intermediary' && { organisationName: req.body.registerOrgName }), ...(req.body.role === 'intermediary' && { organisationType: req.body.registerOrgType }), ...(req.body.role === 'agent' && { city: req.body.city }), registrationChannel: 'web', + emailVerificationToken: confirmationCode, + isEmailVerified: false, }; const img = req.file; @@ -157,6 +167,38 @@ router.post('/register', upload.single('registerIDPhoto'), async function (req, res.status(404).send({ message: 'user not found' }); } else { // res.status(201).send(users[0]); + + // TODO change to use gmail + let transport = nodemailer.createTransport({ + host: process.env.EMAIL_HOST, + port: process.env.EMAIL_PORT, + auth: { + user: process.env.EMAIL_ADDRESS, + pass: process.env.EMAIL_PASSWORD, + }, + }); + + transport.sendMail( + { + from: process.env.EMAIL_ADDRESS, + to: req.body.registerEmail, + subject: 'Foodprint registration confirmation email', + html: `

Hi ${req.body.registerName} ${req.body.registerSurname}

+

Thank you for joining FoodPrint.

+

Please confirm your email by clicking on the following link

+ Click here +
`, + }, + (err, info) => { + if (err) { + console.log('Error occurred. ' + err.message); + // return process.exit(1); + } + + console.log('Message sent: %s', info.messageId); + console.log('Preview URL: %s', nodemailer.getTestMessageUrl(info)); + } + ); res.redirect('/app/auth/register/message'); } }) @@ -175,6 +217,44 @@ router.post('/register', upload.single('registerIDPhoto'), async function (req, } }); +router.get('/confirm/:confirmationCode', async function (req, res) { + models.User.findOne({ + where: { + emailVerificationToken: req.params.confirmationCode, + }, + }) + .then(user => { + if (user) { + models.User.update( + { isEmailVerified: true }, + { + where: { + emailVerificationToken: req.params.confirmationCode, + }, + } + ); + + res.render('message', { + title: 'FoodPrint - User Confirmation', + user: req.user, + page_name: 'message', + message: 'Verification successful', + }); + } else { + res.render('message', { + title: 'FoodPrint - User Confirmation', + user: req.user, + page_name: 'message', + message: 'User not found', + }); + } + }) + .catch(err => { + console.log(err); + res.status(500).send({ error: err, message: 'Unexpected error occurred 😤' }); + }); +}); + /* Process register for WhatsApp*/ router.post('/register/whatsapp', async function (req, res) { try { diff --git a/routes/usermanagement.js b/routes/usermanagement.js new file mode 100644 index 00000000..a33b8204 --- /dev/null +++ b/routes/usermanagement.js @@ -0,0 +1,13 @@ +var express = require('express'); +var router = express.Router(); + +/*Render user_management */ +router.get('/user_management', function (req, res) { + res.render('user_management', { + title: 'FoodPrint - User management', + user: req.user, + page_name: 'UMS', + }); +}); + +module.exports = router; diff --git a/server.js b/server.js index bbe3af8d..74bbaf11 100644 --- a/server.js +++ b/server.js @@ -14,6 +14,9 @@ var LocalStrategy = require('passport-local').Strategy; var fs = require('fs'); var sequelise = require('./config/db/db_sequelise'); +const bcrypt = require('bcrypt'); +var initModels = require('./models/init-models'); +var models = initModels(sequelise); const swaggerJSDoc = require('swagger-jsdoc'); const swaggerUi = require('swagger-ui-express'); @@ -208,7 +211,49 @@ passport.use( passwordField: 'loginPassword', //useful for custom id's on your credentials fields }, function (username, password, cb) { - db.users.findByUsername(username, function (err, user) { + models.User.findOne({ + attributes: [ + 'ID', + 'firstName', + 'middleName', + 'lastName', + 'email', + 'password', + 'isEmailVerified', + ], + where: { + email: username, + }, + }) + .then(async data => { + let user = { + id: data.ID, + username: 'adminjack', + password: data.password, + displayName: `${data.firstName} ${data.lastName}`, + prefs: [{ value: data.email }], + email: data.email, + role: 'Admin', + }; + if (!data) { + return cb(null, false, { message: 'Incorrect login details.' }); + } + + const match = await bcrypt.compare(password, user.password); + if (!match) { + return cb(null, false, { message: 'Incorrect login details.' }); + } + + if (!data.isEmailVerified) { + return cb(null, false, { message: 'Please verify your email first.' }); + } + // console.log(user); + return cb(null, user); + }) + .catch(err => { + return cb(err); + }); + /*db.users.findByUsername(username, function (err, user) { if (err) { return cb(err); } @@ -221,7 +266,7 @@ passport.use( // If the credentials are valid, the verify callback invokes done to // supply Passport with the user that authenticated. return cb(null, user); - }); + });*/ } ) ); @@ -238,12 +283,39 @@ passport.serializeUser(function (user, cb) { }); passport.deserializeUser(function (id, cb) { - db.users.findById(id, function (err, user) { - if (err) { + // db.users.findById(id, function(err, user) { + // if (err) { + // return cb(err); + // } + // cb(null, user); + // }); + + models.User.findOne({ + attributes: ['ID', 'firstName', 'middleName', 'lastName', 'email', 'password'], + where: { + ID: id, + }, + }) + .then(data => { + let user = { + id: data.ID, + username: data.email, + password: data.password, + displayName: `${data.firstName} ${data.lastName}`, + prefs: [{ value: data.email }], + email: data.email, + role: 'Admin', + }; + if (!data) { + return cb(err); + } + + // console.log(user); + return cb(null, user); + }) + .catch(err => { return cb(err); - } - cb(null, user); - }); + }); //Models currently giving error upon login /*models.User.findUserById(id, function (err, user) { if (err) { diff --git a/views/register.ejs b/views/register.ejs index 47859839..8e826d45 100644 --- a/views/register.ejs +++ b/views/register.ejs @@ -50,10 +50,20 @@ -
+ + +
+ + +
+ + diff --git a/views/user_management.ejs b/views/user_management.ejs new file mode 100644 index 00000000..285bca28 --- /dev/null +++ b/views/user_management.ejs @@ -0,0 +1,35 @@ + + + + <% include ./partials/head %> + + + + +
+ + + + + +
+
+ + + + +
+
+ + +<% include ./partials/footer %> + + + + + + + + From 33d8f84891c654997330c85de0e0fcf70683e835 Mon Sep 17 00:00:00 2001 From: Tatenda Date: Mon, 4 Jul 2022 14:34:26 +0200 Subject: [PATCH 03/12] WIP user registration --- .../20220429215904-add_new_user_columns.js | 4 ++++ models/user.js | 4 ++++ routes/auth.js | 14 +++++++---- server.js | 16 +++++++++---- utils/roles.js | 2 ++ views/dblogin.ejs | 4 ++-- views/register.ejs | 23 ++++++++++++++----- views/register_options.ejs | 6 ++--- 8 files changed, 53 insertions(+), 20 deletions(-) diff --git a/migrations/20220429215904-add_new_user_columns.js b/migrations/20220429215904-add_new_user_columns.js index 1c83614e..3e7a4e9d 100644 --- a/migrations/20220429215904-add_new_user_columns.js +++ b/migrations/20220429215904-add_new_user_columns.js @@ -14,6 +14,9 @@ module.exports = { await queryInterface.addColumn('user', 'user_uuid', { type: Sequelize.STRING(255), }); + await queryInterface.addColumn('user', 'isAdminVerified', { + type: Sequelize.BOOLEAN, + }); }, down: async (queryInterface, Sequelize) => { @@ -26,5 +29,6 @@ module.exports = { await queryInterface.removeColumn('user', 'userId'); await queryInterface.removeColumn('user', 'user_uuid'); + await queryInterface.removeColumn('user', 'isAdminVerified'); }, }; diff --git a/models/user.js b/models/user.js index 137f791a..59b8a30e 100644 --- a/models/user.js +++ b/models/user.js @@ -79,6 +79,10 @@ module.exports = function (sequelize, DataTypes) { type: DataTypes.BOOLEAN, defaultValue: false, }, + isAdminVerified: { + type: DataTypes.BOOLEAN, + defaultValue: false, + }, createdAt: { type: DataTypes.DATE, allowNull: true, diff --git a/routes/auth.js b/routes/auth.js index 3cdeec15..037afa5a 100644 --- a/routes/auth.js +++ b/routes/auth.js @@ -10,6 +10,7 @@ var crypto = require('crypto'); const uuidv4 = require('uuid/v4'); var initModels = require('../models/init-models'); var sequelise = require('../config/db/db_sequelise'); +var ROLES = require('../utils/roles'); var models = initModels(sequelise); @@ -123,17 +124,20 @@ router.post('/register', upload.single('registerIDPhoto'), async function (req, email: req.body.registerEmail, role: req.body.role, password: hashedPassword, - ...(req.body.role === 'farmer' && { farmName: req.body.farmName }), - ...(req.body.role === 'intermediary' && { organisationName: req.body.registerOrgName }), - ...(req.body.role === 'intermediary' && { organisationType: req.body.registerOrgType }), - ...(req.body.role === 'agent' && { city: req.body.city }), + ...(req.body.role === ROLES.Farmer && { farmName: req.body.farmName, isAdminVerified: true }), + ...(req.body.role === ROLES.Intermediary && { + organisationName: req.body.registerOrgName, + organisationType: req.body.registerOrgType, + isAdminVerified: true, + }), + ...(req.body.role === ROLES.Agent && { city: req.body.city, isAdminVerified: false }), registrationChannel: 'web', emailVerificationToken: confirmationCode, isEmailVerified: false, }; const img = req.file; - if (user.role === 'agent') { + if (user.role === ROLES.Agent || user.role === ROLES.Farmer) { fs.readFile(img.path, function (err, img_datadata) { user['nationalIdPhotoHash'] = img_datadata; }); diff --git a/server.js b/server.js index 74bbaf11..44c5c12b 100644 --- a/server.js +++ b/server.js @@ -219,7 +219,9 @@ passport.use( 'lastName', 'email', 'password', + 'role', 'isEmailVerified', + 'isAdminVerified', ], where: { email: username, @@ -228,12 +230,12 @@ passport.use( .then(async data => { let user = { id: data.ID, - username: 'adminjack', + username: '', password: data.password, displayName: `${data.firstName} ${data.lastName}`, prefs: [{ value: data.email }], email: data.email, - role: 'Admin', + role: data.role, }; if (!data) { return cb(null, false, { message: 'Incorrect login details.' }); @@ -247,6 +249,12 @@ passport.use( if (!data.isEmailVerified) { return cb(null, false, { message: 'Please verify your email first.' }); } + + if (!data.isAdminVerified) { + return cb(null, false, { + message: 'Your profile is being reviewed by the Foodprint team.', + }); + } // console.log(user); return cb(null, user); }) @@ -291,7 +299,7 @@ passport.deserializeUser(function (id, cb) { // }); models.User.findOne({ - attributes: ['ID', 'firstName', 'middleName', 'lastName', 'email', 'password'], + attributes: ['ID', 'firstName', 'middleName', 'lastName', 'email', 'password', 'role'], where: { ID: id, }, @@ -304,7 +312,7 @@ passport.deserializeUser(function (id, cb) { displayName: `${data.firstName} ${data.lastName}`, prefs: [{ value: data.email }], email: data.email, - role: 'Admin', + role: data.role, // TODO roles have title case in enum }; if (!data) { return cb(err); diff --git a/utils/roles.js b/utils/roles.js index f1c7de01..a45b78d7 100644 --- a/utils/roles.js +++ b/utils/roles.js @@ -6,6 +6,8 @@ const ROLES = { Superuser: 'Superuser', Buyer: 'Buyer', Seller: 'Seller', + Intermediary: 'Intermediary', + Agent: 'Agent' }; module.exports = ROLES; diff --git a/views/dblogin.ejs b/views/dblogin.ejs index 9c285fc9..192ab5b8 100644 --- a/views/dblogin.ejs +++ b/views/dblogin.ejs @@ -26,8 +26,8 @@
- - + +
diff --git a/views/register.ejs b/views/register.ejs index 8e826d45..22a7a890 100644 --- a/views/register.ejs +++ b/views/register.ejs @@ -57,7 +57,7 @@
- +
- <%if(choice && choice.length > 0 && choice === 'agent'){%> + <%if(choice && choice.length > 0 && (choice === 'Agent' || choice === 'Farmer' )){%>
+ <%}%> + + + + <%if(choice && choice.length > 0 && choice === 'Agent'){%>
@@ -82,21 +86,28 @@ - <%if(choice && choice.length > 0 && choice === 'intermediary'){%> + <%if(choice && choice.length > 0 && choice === 'Intermediary'){%>
+
- +
<%}%> - <%if(choice && choice.length > 0 && choice === 'farmer'){%> + <%if(choice && choice.length > 0 && choice === 'Farmer'){%>
diff --git a/views/register_options.ejs b/views/register_options.ejs index 6cc05458..882b181c 100644 --- a/views/register_options.ejs +++ b/views/register_options.ejs @@ -30,17 +30,17 @@
- +
- +
- +
From 20dfa157e782d5900cd1d69d812694104b6d70bc Mon Sep 17 00:00:00 2001 From: Tatenda Date: Mon, 4 Jul 2022 15:25:32 +0200 Subject: [PATCH 04/12] fix id upload --- routes/auth.js | 8 ++++---- utils/roles.js | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/routes/auth.js b/routes/auth.js index 037afa5a..412a3dad 100644 --- a/routes/auth.js +++ b/routes/auth.js @@ -2,7 +2,7 @@ var express = require('express'); var router = express.Router(); var passport = require('passport'); const fetch = (...args) => import('node-fetch').then(({ default: fetch }) => fetch(...args)); -var fs = require('fs'); +var fs = require('fs').promises; const multer = require('multer'); //middleware for handling multipart/form-data, which is primarily used for uploading files const upload = multer({ dest: './static/images/produce_images/' }); //path.join(__dirname, 'static/images/produce_images/) @@ -138,9 +138,9 @@ router.post('/register', upload.single('registerIDPhoto'), async function (req, const img = req.file; if (user.role === ROLES.Agent || user.role === ROLES.Farmer) { - fs.readFile(img.path, function (err, img_datadata) { - user['nationalIdPhotoHash'] = img_datadata; - }); + user['nationalIdPhotoHash'] = await fs + .readFile(img.path) + .catch(err => console.log('Failed to read file', err)); } models.User.create(user) diff --git a/utils/roles.js b/utils/roles.js index a45b78d7..402b67fa 100644 --- a/utils/roles.js +++ b/utils/roles.js @@ -7,7 +7,7 @@ const ROLES = { Buyer: 'Buyer', Seller: 'Seller', Intermediary: 'Intermediary', - Agent: 'Agent' + Agent: 'Agent', }; module.exports = ROLES; From 2420b1c947b85cb2f626eb671ace814f9941cc70 Mon Sep 17 00:00:00 2001 From: Tatenda Date: Thu, 7 Jul 2022 14:19:49 +0200 Subject: [PATCH 05/12] WIP user management --- package-lock.json | 895 +++++++++++++++++++++++++++++++++++++- routes/auth.js | 56 +-- routes/usermanagement.js | 13 - routes/users.js | 62 +++ server.js | 80 ++-- utils/enums.js | 2 + views/index.ejs | 26 +- views/login.ejs | 2 +- views/partials/header.ejs | 12 +- views/user_management.ejs | 62 ++- 10 files changed, 1071 insertions(+), 139 deletions(-) delete mode 100644 routes/usermanagement.js create mode 100644 routes/users.js diff --git a/package-lock.json b/package-lock.json index 893ac271..46050a42 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,6 +13,7 @@ "algosdk": "^1.12.0", "aws-sdk": "^2.1167.0", "axios": "^0.26.1", + "bcrypt": "^5.0.1", "body-parser": "^1.19.0", "browserify": "^16.3.0", "connect-ensure-login": "^0.1.1", @@ -28,6 +29,7 @@ "fs": "0.0.1-security", "heroku-ssl-redirect": "0.0.4", "jimp": "^0.6.4", + "jsonwebtoken": "^8.5.1", "method-override": "^3.0.0", "moment": "^2.27.0", "morgan": "^1.9.1", @@ -587,6 +589,66 @@ "resolved": "https://registry.npmjs.org/@jsdevtools/ono/-/ono-7.1.3.tgz", "integrity": "sha512-4JQNk+3mVzK3xh2rqd6RB4J46qUR19azEHBneZyTZM+c456qOrbbM/5xcR8huNCCcbVt7+UmizG6GuUvPvKUYg==" }, + "node_modules/@mapbox/node-pre-gyp": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.9.tgz", + "integrity": "sha512-aDF3S3rK9Q2gey/WAttUlISduDItz5BU3306M9Eyv6/oS40aMprnopshtlKTykxRNIBEZuRMaZAnbrQ4QtKGyw==", + "dependencies": { + "detect-libc": "^2.0.0", + "https-proxy-agent": "^5.0.0", + "make-dir": "^3.1.0", + "node-fetch": "^2.6.7", + "nopt": "^5.0.0", + "npmlog": "^5.0.1", + "rimraf": "^3.0.2", + "semver": "^7.3.5", + "tar": "^6.1.11" + }, + "bin": { + "node-pre-gyp": "bin/node-pre-gyp" + } + }, + "node_modules/@mapbox/node-pre-gyp/node_modules/make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dependencies": { + "semver": "^6.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@mapbox/node-pre-gyp/node_modules/make-dir/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@mapbox/node-pre-gyp/node_modules/node-fetch": { + "version": "2.6.7", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", + "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, "node_modules/@socket.io/component-emitter": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.0.tgz", @@ -678,8 +740,7 @@ "node_modules/abbrev": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", - "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", - "dev": true + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" }, "node_modules/accepts": { "version": "1.3.8", @@ -734,6 +795,38 @@ "node": ">=0.4.0" } }, + "node_modules/agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/agent-base/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/agent-base/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, "node_modules/algo-msgpack-with-bigint": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/algo-msgpack-with-bigint/-/algo-msgpack-with-bigint-2.1.1.tgz", @@ -896,12 +989,42 @@ "resolved": "https://registry.npmjs.org/append-field/-/append-field-1.0.0.tgz", "integrity": "sha512-klpgFSWLW1ZEs8svjfb7g4qWY0YS5imI82dTg+QahUvJ8YqAY0P10Uk8tTyh9ZGuYEZEMaeJYCF5BFuX552hsw==" }, + "node_modules/aproba": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz", + "integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==" + }, "node_modules/archy": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", "integrity": "sha512-Xg+9RwCg/0p32teKdGMPTPnVXKD0w3DfHnFTficozsAgsvq2XenPJq/MYpzzQ/v8zrOyJn6Ds39VA4JIDwFfqw==", "dev": true }, + "node_modules/are-we-there-yet": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-2.0.0.tgz", + "integrity": "sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw==", + "dependencies": { + "delegates": "^1.0.0", + "readable-stream": "^3.6.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/are-we-there-yet/node_modules/readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", @@ -1446,6 +1569,19 @@ "integrity": "sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==", "dev": true }, + "node_modules/bcrypt": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/bcrypt/-/bcrypt-5.0.1.tgz", + "integrity": "sha512-9BTgmrhZM2t1bNuDtrtIMVSmmxZBrJ71n8Wg+YgdjHuIWYF7SjjmCPZFB+/5i/o/PIeRpwVJR3P+NrpIItUjqw==", + "hasInstallScript": true, + "dependencies": { + "@mapbox/node-pre-gyp": "^1.0.0", + "node-addon-api": "^3.1.0" + }, + "engines": { + "node": ">= 10.0.0" + } + }, "node_modules/beeper": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/beeper/-/beeper-1.1.1.tgz", @@ -1945,6 +2081,11 @@ "node": ">=0.4.0" } }, + "node_modules/buffer-equal-constant-time": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", + "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==" + }, "node_modules/buffer-from": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", @@ -2260,6 +2401,14 @@ "fsevents": "~2.3.2" } }, + "node_modules/chownr": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", + "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", + "engines": { + "node": ">=10" + } + }, "node_modules/ci-info": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-1.6.0.tgz", @@ -2554,7 +2703,6 @@ "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==", - "dev": true, "bin": { "color-support": "bin.js" } @@ -2701,6 +2849,11 @@ "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz", "integrity": "sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==" }, + "node_modules/console-control-strings": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", + "integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==" + }, "node_modules/constants-browserify": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", @@ -3143,6 +3296,11 @@ "node": ">=0.4.0" } }, + "node_modules/delegates": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", + "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==" + }, "node_modules/denque": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/denque/-/denque-2.0.1.tgz", @@ -3200,6 +3358,14 @@ "node": ">=0.10.0" } }, + "node_modules/detect-libc": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.1.tgz", + "integrity": "sha512-463v3ZeIrcWtdgIg6vI6XUncguvr2TnGl4SzDXinkt9mSLpBJKXT3mW6xT3VQdDN11+WVs29pgvivTc4Lp8v+w==", + "engines": { + "node": ">=8" + } + }, "node_modules/detect-newline": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-2.1.0.tgz", @@ -3432,6 +3598,14 @@ "node": ">= 0.8.0" } }, + "node_modules/ecdsa-sig-formatter": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", + "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", + "dependencies": { + "safe-buffer": "^5.0.1" + } + }, "node_modules/editorconfig": { "version": "0.15.3", "resolved": "https://registry.npmjs.org/editorconfig/-/editorconfig-0.15.3.tgz", @@ -4711,6 +4885,17 @@ "universalify": "^0.1.0" } }, + "node_modules/fs-minipass": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", + "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, "node_modules/fs-mkdirp-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs-mkdirp-stream/-/fs-mkdirp-stream-1.0.0.tgz", @@ -4773,6 +4958,65 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/gauge": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-3.0.2.tgz", + "integrity": "sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q==", + "dependencies": { + "aproba": "^1.0.3 || ^2.0.0", + "color-support": "^1.1.2", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.1", + "object-assign": "^4.1.1", + "signal-exit": "^3.0.0", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1", + "wide-align": "^1.1.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/gauge/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/gauge/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "engines": { + "node": ">=8" + } + }, + "node_modules/gauge/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/gauge/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/generate-function": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.3.1.tgz", @@ -6059,6 +6303,11 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/has-unicode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", + "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==" + }, "node_modules/has-value": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", @@ -6246,6 +6495,39 @@ "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", "integrity": "sha512-J+FkSdyD+0mA0N+81tMotaRMfSL9SGi+xpD3T6YApKsc3bGSXJlfXri3VyFOeYkfLRQisDk1W+jIFFKBeUBbBg==" }, + "node_modules/https-proxy-agent": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "dependencies": { + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/https-proxy-agent/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/https-proxy-agent/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, "node_modules/iconv-lite": { "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", @@ -6664,7 +6946,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", - "dev": true, "engines": { "node": ">=4" } @@ -7193,12 +7474,65 @@ "node": "*" } }, + "node_modules/jsonwebtoken": { + "version": "8.5.1", + "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz", + "integrity": "sha512-XjwVfRS6jTMsqYs0EsuJ4LGxXV14zQybNd4L2r0UvbVnSF9Af8x7p5MzbJ90Ioz/9TI41/hTCvznF/loiSzn8w==", + "dependencies": { + "jws": "^3.2.2", + "lodash.includes": "^4.3.0", + "lodash.isboolean": "^3.0.3", + "lodash.isinteger": "^4.0.4", + "lodash.isnumber": "^3.0.3", + "lodash.isplainobject": "^4.0.6", + "lodash.isstring": "^4.0.1", + "lodash.once": "^4.0.0", + "ms": "^2.1.1", + "semver": "^5.6.0" + }, + "engines": { + "node": ">=4", + "npm": ">=1.4.28" + } + }, + "node_modules/jsonwebtoken/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, + "node_modules/jsonwebtoken/node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "bin": { + "semver": "bin/semver" + } + }, "node_modules/just-debounce": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/just-debounce/-/just-debounce-1.1.0.tgz", "integrity": "sha512-qpcRocdkUmf+UTNBYx5w6dexX5J31AKK1OmPwH630a83DdVVUIngk55RSAiIGpQyoH0dlr872VHfPjnQnK1qDQ==", "dev": true }, + "node_modules/jwa": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", + "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==", + "dependencies": { + "buffer-equal-constant-time": "1.0.1", + "ecdsa-sig-formatter": "1.0.11", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/jws": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", + "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", + "dependencies": { + "jwa": "^1.4.1", + "safe-buffer": "^5.0.1" + } + }, "node_modules/kind-of": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", @@ -7578,6 +7912,11 @@ "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", "integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==" }, + "node_modules/lodash.includes": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz", + "integrity": "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==" + }, "node_modules/lodash.isarguments": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz", @@ -7590,6 +7929,11 @@ "integrity": "sha512-JwObCrNJuT0Nnbuecmqr5DgtuBppuCvGD9lxjFpAzwnVtdGoDQ1zig+5W8k5/6Gcn0gZ3936HDAlGd28i7sOGQ==", "dev": true }, + "node_modules/lodash.isboolean": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz", + "integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==" + }, "node_modules/lodash.isequal": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", @@ -7601,6 +7945,26 @@ "integrity": "sha512-7FGG40uhC8Mm633uKW1r58aElFlBlxCrg9JfSi3P6aYiWmfiWF0PgMd86ZUsxE5GwWPdHoS2+48bwTh2VPkIQA==", "dev": true }, + "node_modules/lodash.isinteger": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz", + "integrity": "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==" + }, + "node_modules/lodash.isnumber": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz", + "integrity": "sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==" + }, + "node_modules/lodash.isplainobject": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", + "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==" + }, + "node_modules/lodash.isstring": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", + "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==" + }, "node_modules/lodash.keys": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-3.1.2.tgz", @@ -7622,6 +7986,11 @@ "resolved": "https://registry.npmjs.org/lodash.mergewith/-/lodash.mergewith-4.6.2.tgz", "integrity": "sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ==" }, + "node_modules/lodash.once": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", + "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==" + }, "node_modules/lodash.restparam": { "version": "3.6.1", "resolved": "https://registry.npmjs.org/lodash.restparam/-/lodash.restparam-3.6.1.tgz", @@ -8189,6 +8558,29 @@ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==" }, + "node_modules/minipass": { + "version": "3.3.4", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.4.tgz", + "integrity": "sha512-I9WPbWHCGu8W+6k1ZiGpPu0GkoKBeorkfKNuAFBNS1HNFJvke82sxvI5bzcCNpWPorkOO5QQ+zomzzwRxejXiw==", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minizlib": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", + "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", + "dependencies": { + "minipass": "^3.0.0", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">= 8" + } + }, "node_modules/mitt": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/mitt/-/mitt-1.2.0.tgz", @@ -8730,6 +9122,11 @@ "integrity": "sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==", "dev": true }, + "node_modules/node-addon-api": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-3.2.1.tgz", + "integrity": "sha512-mmcei9JghVNDYydghQmeDX8KoAm0FAiYyIcUt/N4nhyAipB17pllZQDOJD2fotxABnt4Mdz+dKTO7eftLg4d0A==" + }, "node_modules/node-domexception": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz", @@ -9140,7 +9537,6 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz", "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==", - "dev": true, "dependencies": { "abbrev": "1" }, @@ -9214,6 +9610,17 @@ "node": ">=4" } }, + "node_modules/npmlog": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-5.0.1.tgz", + "integrity": "sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw==", + "dependencies": { + "are-we-there-yet": "^2.0.0", + "console-control-strings": "^1.1.0", + "gauge": "^3.0.0", + "set-blocking": "^2.0.0" + } + }, "node_modules/number-is-nan": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", @@ -10960,6 +11367,20 @@ "resolved": "https://registry.npmjs.org/retry-as-promised/-/retry-as-promised-5.0.0.tgz", "integrity": "sha512-6S+5LvtTl2ggBumk04hBo/4Uf6fRJUwIgunGZ7CYEBCeufGFW1Pu6ucUf/UskHeWOIsUcLOGLFXPig5tR5V1nA==" }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/ripemd160": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", @@ -11717,8 +12138,7 @@ "node_modules/signal-exit": { "version": "3.0.7", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "dev": true + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==" }, "node_modules/simple-concat": { "version": "1.0.1", @@ -12358,7 +12778,6 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, "dependencies": { "is-fullwidth-code-point": "^2.0.0", "strip-ansi": "^4.0.0" @@ -12371,7 +12790,6 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz", "integrity": "sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==", - "dev": true, "engines": { "node": ">=4" } @@ -12380,7 +12798,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", "integrity": "sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==", - "dev": true, "dependencies": { "ansi-regex": "^3.0.0" }, @@ -12666,6 +13083,33 @@ "acorn-node": "^1.2.0" } }, + "node_modules/tar": { + "version": "6.1.11", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.11.tgz", + "integrity": "sha512-an/KZQzQUkZCkuoAA64hM92X0Urb6VpRhAFllDzz44U2mcD5scmT3zBc4VgVpkugF580+DQn8eAFSyoQt0tznA==", + "dependencies": { + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "minipass": "^3.0.0", + "minizlib": "^2.1.1", + "mkdirp": "^1.0.3", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/tar/node_modules/mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/term-size": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/term-size/-/term-size-1.2.0.tgz", @@ -12885,6 +13329,11 @@ "node": "*" } }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" + }, "node_modules/tslib": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", @@ -13873,6 +14322,20 @@ "node": ">= 8" } }, + "node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" + }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -13942,6 +14405,14 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/wide-align": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz", + "integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==", + "dependencies": { + "string-width": "^1.0.2 || 2 || 3 || 4" + } + }, "node_modules/widest-line": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-2.0.1.tgz", @@ -14720,6 +15191,47 @@ "resolved": "https://registry.npmjs.org/@jsdevtools/ono/-/ono-7.1.3.tgz", "integrity": "sha512-4JQNk+3mVzK3xh2rqd6RB4J46qUR19azEHBneZyTZM+c456qOrbbM/5xcR8huNCCcbVt7+UmizG6GuUvPvKUYg==" }, + "@mapbox/node-pre-gyp": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.9.tgz", + "integrity": "sha512-aDF3S3rK9Q2gey/WAttUlISduDItz5BU3306M9Eyv6/oS40aMprnopshtlKTykxRNIBEZuRMaZAnbrQ4QtKGyw==", + "requires": { + "detect-libc": "^2.0.0", + "https-proxy-agent": "^5.0.0", + "make-dir": "^3.1.0", + "node-fetch": "^2.6.7", + "nopt": "^5.0.0", + "npmlog": "^5.0.1", + "rimraf": "^3.0.2", + "semver": "^7.3.5", + "tar": "^6.1.11" + }, + "dependencies": { + "make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "requires": { + "semver": "^6.0.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + } + } + }, + "node-fetch": { + "version": "2.6.7", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", + "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", + "requires": { + "whatwg-url": "^5.0.0" + } + } + } + }, "@socket.io/component-emitter": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.0.tgz", @@ -14811,8 +15323,7 @@ "abbrev": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", - "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", - "dev": true + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" }, "accepts": { "version": "1.3.8", @@ -14851,6 +15362,29 @@ "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz", "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==" }, + "agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "requires": { + "debug": "4" + }, + "dependencies": { + "debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "requires": { + "ms": "2.1.2" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + } + } + }, "algo-msgpack-with-bigint": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/algo-msgpack-with-bigint/-/algo-msgpack-with-bigint-2.1.1.tgz", @@ -14979,12 +15513,38 @@ "resolved": "https://registry.npmjs.org/append-field/-/append-field-1.0.0.tgz", "integrity": "sha512-klpgFSWLW1ZEs8svjfb7g4qWY0YS5imI82dTg+QahUvJ8YqAY0P10Uk8tTyh9ZGuYEZEMaeJYCF5BFuX552hsw==" }, + "aproba": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz", + "integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==" + }, "archy": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", "integrity": "sha512-Xg+9RwCg/0p32teKdGMPTPnVXKD0w3DfHnFTficozsAgsvq2XenPJq/MYpzzQ/v8zrOyJn6Ds39VA4JIDwFfqw==", "dev": true }, + "are-we-there-yet": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-2.0.0.tgz", + "integrity": "sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw==", + "requires": { + "delegates": "^1.0.0", + "readable-stream": "^3.6.0" + }, + "dependencies": { + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + } + } + }, "argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", @@ -15408,6 +15968,15 @@ "integrity": "sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==", "dev": true }, + "bcrypt": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/bcrypt/-/bcrypt-5.0.1.tgz", + "integrity": "sha512-9BTgmrhZM2t1bNuDtrtIMVSmmxZBrJ71n8Wg+YgdjHuIWYF7SjjmCPZFB+/5i/o/PIeRpwVJR3P+NrpIItUjqw==", + "requires": { + "@mapbox/node-pre-gyp": "^1.0.0", + "node-addon-api": "^3.1.0" + } + }, "beeper": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/beeper/-/beeper-1.1.1.tgz", @@ -15830,6 +16399,11 @@ "resolved": "https://registry.npmjs.org/buffer-equal/-/buffer-equal-0.0.1.tgz", "integrity": "sha512-RgSV6InVQ9ODPdLWJ5UAqBqJBOg370Nz6ZQtRzpt6nUjc8v0St97uJ4PYC6NztqIScrAXafKM3mZPMygSe1ggA==" }, + "buffer-equal-constant-time": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", + "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==" + }, "buffer-from": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", @@ -16087,6 +16661,11 @@ "readdirp": "~3.6.0" } }, + "chownr": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", + "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==" + }, "ci-info": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-1.6.0.tgz", @@ -16330,8 +16909,7 @@ "color-support": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", - "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==", - "dev": true + "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==" }, "combine-source-map": { "version": "0.8.0", @@ -16453,6 +17031,11 @@ "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz", "integrity": "sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==" }, + "console-control-strings": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", + "integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==" + }, "constants-browserify": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", @@ -16826,6 +17409,11 @@ "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==" }, + "delegates": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", + "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==" + }, "denque": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/denque/-/denque-2.0.1.tgz", @@ -16867,6 +17455,11 @@ "integrity": "sha512-DtCOLG98P007x7wiiOmfI0fi3eIKyWiLTGJ2MDnVi/E04lWGbf+JzrRHMm0rgIIZJGtHpKpbVgLWHrv8xXpc3Q==", "dev": true }, + "detect-libc": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.1.tgz", + "integrity": "sha512-463v3ZeIrcWtdgIg6vI6XUncguvr2TnGl4SzDXinkt9mSLpBJKXT3mW6xT3VQdDN11+WVs29pgvivTc4Lp8v+w==" + }, "detect-newline": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-2.1.0.tgz", @@ -17062,6 +17655,14 @@ "tfunk": "^4.0.0" } }, + "ecdsa-sig-formatter": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", + "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", + "requires": { + "safe-buffer": "^5.0.1" + } + }, "editorconfig": { "version": "0.15.3", "resolved": "https://registry.npmjs.org/editorconfig/-/editorconfig-0.15.3.tgz", @@ -18103,6 +18704,14 @@ "universalify": "^0.1.0" } }, + "fs-minipass": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", + "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", + "requires": { + "minipass": "^3.0.0" + } + }, "fs-mkdirp-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs-mkdirp-stream/-/fs-mkdirp-stream-1.0.0.tgz", @@ -18146,6 +18755,52 @@ "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==" }, + "gauge": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-3.0.2.tgz", + "integrity": "sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q==", + "requires": { + "aproba": "^1.0.3 || ^2.0.0", + "color-support": "^1.1.2", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.1", + "object-assign": "^4.1.1", + "signal-exit": "^3.0.0", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1", + "wide-align": "^1.1.2" + }, + "dependencies": { + "ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==" + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" + }, + "string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + } + }, + "strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "requires": { + "ansi-regex": "^5.0.1" + } + } + } + }, "generate-function": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.3.1.tgz", @@ -19194,6 +19849,11 @@ "has-symbols": "^1.0.2" } }, + "has-unicode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", + "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==" + }, "has-value": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", @@ -19351,6 +20011,30 @@ "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", "integrity": "sha512-J+FkSdyD+0mA0N+81tMotaRMfSL9SGi+xpD3T6YApKsc3bGSXJlfXri3VyFOeYkfLRQisDk1W+jIFFKBeUBbBg==" }, + "https-proxy-agent": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "requires": { + "agent-base": "6", + "debug": "4" + }, + "dependencies": { + "debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "requires": { + "ms": "2.1.2" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + } + } + }, "iconv-lite": { "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", @@ -19651,8 +20335,7 @@ "is-fullwidth-code-point": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", - "dev": true + "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==" }, "is-function": { "version": "1.0.2", @@ -20035,12 +20718,60 @@ "through": ">=2.2.7 <3" } }, + "jsonwebtoken": { + "version": "8.5.1", + "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz", + "integrity": "sha512-XjwVfRS6jTMsqYs0EsuJ4LGxXV14zQybNd4L2r0UvbVnSF9Af8x7p5MzbJ90Ioz/9TI41/hTCvznF/loiSzn8w==", + "requires": { + "jws": "^3.2.2", + "lodash.includes": "^4.3.0", + "lodash.isboolean": "^3.0.3", + "lodash.isinteger": "^4.0.4", + "lodash.isnumber": "^3.0.3", + "lodash.isplainobject": "^4.0.6", + "lodash.isstring": "^4.0.1", + "lodash.once": "^4.0.0", + "ms": "^2.1.1", + "semver": "^5.6.0" + }, + "dependencies": { + "ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" + } + } + }, "just-debounce": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/just-debounce/-/just-debounce-1.1.0.tgz", "integrity": "sha512-qpcRocdkUmf+UTNBYx5w6dexX5J31AKK1OmPwH630a83DdVVUIngk55RSAiIGpQyoH0dlr872VHfPjnQnK1qDQ==", "dev": true }, + "jwa": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", + "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==", + "requires": { + "buffer-equal-constant-time": "1.0.1", + "ecdsa-sig-formatter": "1.0.11", + "safe-buffer": "^5.0.1" + } + }, + "jws": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", + "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", + "requires": { + "jwa": "^1.4.1", + "safe-buffer": "^5.0.1" + } + }, "kind-of": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", @@ -20360,6 +21091,11 @@ "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", "integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==" }, + "lodash.includes": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz", + "integrity": "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==" + }, "lodash.isarguments": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz", @@ -20372,6 +21108,11 @@ "integrity": "sha512-JwObCrNJuT0Nnbuecmqr5DgtuBppuCvGD9lxjFpAzwnVtdGoDQ1zig+5W8k5/6Gcn0gZ3936HDAlGd28i7sOGQ==", "dev": true }, + "lodash.isboolean": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz", + "integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==" + }, "lodash.isequal": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", @@ -20383,6 +21124,26 @@ "integrity": "sha512-7FGG40uhC8Mm633uKW1r58aElFlBlxCrg9JfSi3P6aYiWmfiWF0PgMd86ZUsxE5GwWPdHoS2+48bwTh2VPkIQA==", "dev": true }, + "lodash.isinteger": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz", + "integrity": "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==" + }, + "lodash.isnumber": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz", + "integrity": "sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==" + }, + "lodash.isplainobject": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", + "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==" + }, + "lodash.isstring": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", + "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==" + }, "lodash.keys": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-3.1.2.tgz", @@ -20404,6 +21165,11 @@ "resolved": "https://registry.npmjs.org/lodash.mergewith/-/lodash.mergewith-4.6.2.tgz", "integrity": "sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ==" }, + "lodash.once": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", + "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==" + }, "lodash.restparam": { "version": "3.6.1", "resolved": "https://registry.npmjs.org/lodash.restparam/-/lodash.restparam-3.6.1.tgz", @@ -20870,6 +21636,23 @@ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==" }, + "minipass": { + "version": "3.3.4", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.4.tgz", + "integrity": "sha512-I9WPbWHCGu8W+6k1ZiGpPu0GkoKBeorkfKNuAFBNS1HNFJvke82sxvI5bzcCNpWPorkOO5QQ+zomzzwRxejXiw==", + "requires": { + "yallist": "^4.0.0" + } + }, + "minizlib": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", + "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", + "requires": { + "minipass": "^3.0.0", + "yallist": "^4.0.0" + } + }, "mitt": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/mitt/-/mitt-1.2.0.tgz", @@ -21308,6 +22091,11 @@ "integrity": "sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==", "dev": true }, + "node-addon-api": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-3.2.1.tgz", + "integrity": "sha512-mmcei9JghVNDYydghQmeDX8KoAm0FAiYyIcUt/N4nhyAipB17pllZQDOJD2fotxABnt4Mdz+dKTO7eftLg4d0A==" + }, "node-domexception": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz", @@ -21634,7 +22422,6 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz", "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==", - "dev": true, "requires": { "abbrev": "1" } @@ -21689,6 +22476,17 @@ "path-key": "^2.0.0" } }, + "npmlog": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-5.0.1.tgz", + "integrity": "sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw==", + "requires": { + "are-we-there-yet": "^2.0.0", + "console-control-strings": "^1.1.0", + "gauge": "^3.0.0", + "set-blocking": "^2.0.0" + } + }, "number-is-nan": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", @@ -23044,6 +23842,14 @@ "resolved": "https://registry.npmjs.org/retry-as-promised/-/retry-as-promised-5.0.0.tgz", "integrity": "sha512-6S+5LvtTl2ggBumk04hBo/4Uf6fRJUwIgunGZ7CYEBCeufGFW1Pu6ucUf/UskHeWOIsUcLOGLFXPig5tR5V1nA==" }, + "rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "requires": { + "glob": "^7.1.3" + } + }, "ripemd160": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", @@ -23617,8 +24423,7 @@ "signal-exit": { "version": "3.0.7", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "dev": true + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==" }, "simple-concat": { "version": "1.0.1", @@ -24133,7 +24938,6 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, "requires": { "is-fullwidth-code-point": "^2.0.0", "strip-ansi": "^4.0.0" @@ -24142,14 +24946,12 @@ "ansi-regex": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz", - "integrity": "sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==", - "dev": true + "integrity": "sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==" }, "strip-ansi": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", "integrity": "sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==", - "dev": true, "requires": { "ansi-regex": "^3.0.0" } @@ -24357,6 +25159,26 @@ "acorn-node": "^1.2.0" } }, + "tar": { + "version": "6.1.11", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.11.tgz", + "integrity": "sha512-an/KZQzQUkZCkuoAA64hM92X0Urb6VpRhAFllDzz44U2mcD5scmT3zBc4VgVpkugF580+DQn8eAFSyoQt0tznA==", + "requires": { + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "minipass": "^3.0.0", + "minizlib": "^2.1.1", + "mkdirp": "^1.0.3", + "yallist": "^4.0.0" + }, + "dependencies": { + "mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==" + } + } + }, "term-size": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/term-size/-/term-size-1.2.0.tgz", @@ -24535,6 +25357,11 @@ } } }, + "tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" + }, "tslib": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", @@ -25332,6 +26159,20 @@ "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.2.1.tgz", "integrity": "sha512-e0MO3wdXWKrLbL0DgGnUV7WHVuw9OUvL4hjgnPkIeEvESk74gAITi5G606JtZPp39cd8HA9VQzCIvA49LpPN5Q==" }, + "webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" + }, + "whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "requires": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, "which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -25383,6 +26224,14 @@ "is-typed-array": "^1.1.9" } }, + "wide-align": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz", + "integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==", + "requires": { + "string-width": "^1.0.2 || 2 || 3 || 4" + } + }, "widest-line": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-2.0.1.tgz", diff --git a/routes/auth.js b/routes/auth.js index 412a3dad..17b1230a 100644 --- a/routes/auth.js +++ b/routes/auth.js @@ -16,7 +16,8 @@ var models = initModels(sequelise); const bcrypt = require('bcrypt'); var jwt = require('jsonwebtoken'); -const nodemailer = require('nodemailer'); +// const nodemailer = require('nodemailer'); +const customSendEmail = require('../config/email/email'); /* Render Login page. */ router.get('/login', function (req, res) { @@ -29,9 +30,8 @@ router.get('/login', function (req, res) { /* Process Login form submission (File Based Auth). */ /* TODO add a user not found message */ -router.post( - '/login', - passport.authenticate('file-local', { +router.post('/login', + passport.authenticate(process.env.AUTH_STATEGY? process.env.AUTH_STATEGY:'db-local' , { successReturnToOrRedirect: '/', successFlash: 'You are now logged in.', failureRedirect: '/app/auth/login', @@ -111,6 +111,7 @@ router.post('/register', upload.single('registerIDPhoto'), async function (req, //res.redirect('/app/auth/register/message'); try { + // TODO make user id short let user = { user_uuid: uuidv4(), userId: `${req.body.role.charAt(0).toUpperCase()}-${crypto @@ -171,39 +172,24 @@ router.post('/register', upload.single('registerIDPhoto'), async function (req, res.status(404).send({ message: 'user not found' }); } else { // res.status(201).send(users[0]); - - // TODO change to use gmail - let transport = nodemailer.createTransport({ - host: process.env.EMAIL_HOST, - port: process.env.EMAIL_PORT, - auth: { - user: process.env.EMAIL_ADDRESS, - pass: process.env.EMAIL_PASSWORD, - }, - }); - - transport.sendMail( - { - from: process.env.EMAIL_ADDRESS, - to: req.body.registerEmail, - subject: 'Foodprint registration confirmation email', - html: `

Hi ${req.body.registerName} ${req.body.registerSurname}

-

Thank you for joining FoodPrint.

+ let mailOptions = { + to: process.env.TEST_EMAIL_ADDRESS, + subject: 'Foodprint registration confirmation email', + html: `

Thank you for joining FoodPrint.

Please confirm your email by clicking on the following link

- Click here -
`, - }, - (err, info) => { - if (err) { - console.log('Error occurred. ' + err.message); - // return process.exit(1); - } + Click here +

Regards

+

Foodprint Team

+ `, + }; + try { + customSendEmail(mailOptions.to, mailOptions.subject, mailOptions.html); + res.redirect('/app/auth/register/message'); + console.log('Email successfully sent'); + } catch (e) { + console.log('Error sending email - ', e); + } - console.log('Message sent: %s', info.messageId); - console.log('Preview URL: %s', nodemailer.getTestMessageUrl(info)); - } - ); - res.redirect('/app/auth/register/message'); } }) .catch(err => { diff --git a/routes/usermanagement.js b/routes/usermanagement.js deleted file mode 100644 index a33b8204..00000000 --- a/routes/usermanagement.js +++ /dev/null @@ -1,13 +0,0 @@ -var express = require('express'); -var router = express.Router(); - -/*Render user_management */ -router.get('/user_management', function (req, res) { - res.render('user_management', { - title: 'FoodPrint - User management', - user: req.user, - page_name: 'UMS', - }); -}); - -module.exports = router; diff --git a/routes/users.js b/routes/users.js new file mode 100644 index 00000000..ecabd710 --- /dev/null +++ b/routes/users.js @@ -0,0 +1,62 @@ +var express = require('express'); +const ROLES = require('../utils/roles'); +var router = express.Router(); + +const { Op, Sequelize } = require('sequelize'); +var initModels = require('../models/init-models'); +var sequelise = require('../config/db/db_sequelise'); + +var models = initModels(sequelise); + +/*Render user_management */ +router.get('/management', + require('connect-ensure-login').ensureLoggedIn({ redirectTo: '/app/auth/login' }), + function (req, res) { + + if ( + req.user.role === ROLES.Admin || + req.user.role === ROLES.Superuser + ) { + + models.User.findAll({ + attributes: [ + 'firstName', + 'lastName', + 'email', + 'phoneNumber', + 'role', + 'isEmailVerified', + 'isAdminVerified' + ], + where: { + role: {[Op.notIn]:[ROLES.Admin, ROLES.Superuser]} + } + }).then( user_rows => { + res.render('user_management', { + title: 'FoodPrint - User management', + user: req.user, + data: user_rows, + page_name: 'UMS', + }); + }).catch(err => { + console.log('All users err:' + err); + req.flash('error', err); + res.render('user_management', { + title: 'FoodPrint - User management', + user: req.user, + data: '', + page_name: 'UMS', + }); + }) + + } else { + res.render('error', { + message: 'You are not authorised to view this resource.', + title: 'Error', + user: req.user, + page_name: 'error', + }); + } +}); + +module.exports = router; diff --git a/server.js b/server.js index 51b954f3..058623e2 100644 --- a/server.js +++ b/server.js @@ -66,7 +66,7 @@ var authRouter = require('./routes/auth'); // var blockchainRouter = require('./routes/blockchain'); var dashboardsRouter = require('./routes/dashboards'); var qrCodeRouter = require('./routes/qrcode'); -var umsRouter = require('./routes/usermanagement'); +var umsRouter = require('./routes/users'); var testRouter = require('./routes/test'); var searchRouter = require('./routes/search'); @@ -150,7 +150,7 @@ app.use('/', router); // app.use('/', blockchainRouter); app.use('/app/config', configRouter); app.use('/app/auth', authRouter); -app.use('/app/usermanagement', umsRouter); +app.use('/app/user', umsRouter); app.use('/app/harvest', harvestRouter); app.use('/app/storage', storageRouter); app.use('/app/produce', produceRouter); @@ -291,52 +291,44 @@ passport.serializeUser(function (user, cb) { }); passport.deserializeUser(function (id, cb) { - // db.users.findById(id, function(err, user) { - // if (err) { - // return cb(err); - // } - // cb(null, user); - // }); - - models.User.findOne({ - attributes: ['ID', 'firstName', 'middleName', 'lastName', 'email', 'password', 'role'], - where: { - ID: id, - }, - }) - .then(data => { - let user = { - id: data.ID, - username: data.email, - password: data.password, - displayName: `${data.firstName} ${data.lastName}`, - prefs: [{ value: data.email }], - email: data.email, - role: data.role, // TODO roles have title case in enum - }; - if (!data) { + const strategy = process.env.AUTH_STATEGY ? process.env.AUTH_STATEGY: CUSTOM_ENUMS.DB_STRATEGY + if (strategy === CUSTOM_ENUMS.FILE_STRATEGY ) { + db.users.findById(id, function(err, user) { + if (err) { return cb(err); } + cb(null, user); + }); - // console.log(user); - return cb(null, user); + } else { + models.User.findOne({ + attributes: ['ID', 'firstName', 'middleName', 'lastName', 'email', 'password', 'role'], + where: { + ID: id, + }, }) - .catch(err => { - return cb(err); - }); - //Models currently giving error upon login - /*models.User.findUserById(id, function (err, user) { - if (err) { - return cb(err); - } - cb(null, user); - }); - models.User.findByUsername(id, function (err, user) { - if (err) { - return cb(err); - } - cb(null, user); - });*/ + .then(data => { + let user = { + id: data.ID, + username: data.email, + password: data.password, + displayName: `${data.firstName} ${data.lastName}`, + prefs: [{ value: data.email }], + email: data.email, + role: data.role, // TODO roles have title case in enum + }; + if (!data) { + return cb(err); + } + + // console.log(user); + return cb(null, user); + }) + .catch(err => { + return cb(err); + }); + } + }); // catch 404 and forward to error handler diff --git a/utils/enums.js b/utils/enums.js index 5d782796..3cccd8b4 100644 --- a/utils/enums.js +++ b/utils/enums.js @@ -6,5 +6,7 @@ const CUSTOM_ENUMS = { OTHER: 'other', DEVELOPMENT: 'development', OZCF: 'ozcf', + FILE_STRATEGY: 'file-local', + DB_STRATEGY: 'db-local' }; module.exports = CUSTOM_ENUMS; diff --git a/views/index.ejs b/views/index.ejs index 433d08f9..26799243 100644 --- a/views/index.ejs +++ b/views/index.ejs @@ -1,7 +1,7 @@ - <% include ./partials/head %> + <% include ./partials/head %> @@ -12,9 +12,9 @@ <% include ./partials/header %> - - - + + +
@@ -22,7 +22,7 @@

HOME

<% include ./partials/notificationbar %>
-

Track & Trace

@@ -36,7 +36,7 @@
-

Wholesale Marketplace

@@ -54,7 +54,7 @@
-

Reporting & Dashboards

@@ -72,7 +72,7 @@
-

Configuration

@@ -80,15 +80,15 @@
- -

Support

@@ -97,13 +97,13 @@
-

Other

diff --git a/views/login.ejs b/views/login.ejs index 8f0dc72c..3754c149 100644 --- a/views/login.ejs +++ b/views/login.ejs @@ -39,7 +39,7 @@
- Don't have a FoodPrint account yet? Sign up now. + Don't have a FoodPrint account yet? Sign up now.
diff --git a/views/partials/header.ejs b/views/partials/header.ejs index 82971e74..ad8d4f1c 100644 --- a/views/partials/header.ejs +++ b/views/partials/header.ejs @@ -12,7 +12,7 @@
- +
- + - +
  • class="active" <% } %> > <% if (user) { %> Log out (<%=user.username%>) @@ -102,4 +102,4 @@
  • - \ No newline at end of file + diff --git a/views/user_management.ejs b/views/user_management.ejs index 285bca28..57881b19 100644 --- a/views/user_management.ejs +++ b/views/user_management.ejs @@ -15,12 +15,66 @@
    -
    - +

    Users

    + <% include ./partials/notificationbar %> + +
    + + + + + + + + + + + + + + + + <% if(data.length){ + for(var i = 0; i < data.length; i++) { %> + + + + + + + + + + + + <% } + }else{ %> + + + + <% } %> + +
    #NameemailPhone NumberRoleEmail VerifiedProfile ActiveAction
    <%= (i + 1) ;%><%= data[i].firstName ;%> <%= data[i].lastName ;%> <%= data[i].email ;%> <%= data[i].phoneNumber ;%> <%= data[i].role ;%> <%= data[i].isEmailVerified ;%> <%= data[i].isAdminVerified ;%> +
    + + View + + + Edit + + <% if (data[i].isAdminVerified) { %> + + Disable + <% }else{ %> + + + Enable + <% } %> + +
    +
    No Data
    - -
    From 2403e183a0b8fb7128a4e25216b9e0837dca8a37 Mon Sep 17 00:00:00 2001 From: Tatenda Date: Wed, 13 Jul 2022 00:49:45 +0200 Subject: [PATCH 06/12] User management --- .gitignore | 1 + package-lock.json | 36 ++-- routes/auth.js | 51 +++--- routes/users.js | 259 +++++++++++++++++++++++++---- server.js | 21 +-- utils/enums.js | 2 +- views/user_management.ejs | 334 ++++++++++++++++++++++++++++++++++++-- 7 files changed, 595 insertions(+), 109 deletions(-) diff --git a/.gitignore b/.gitignore index 333bc114..d98f086f 100644 --- a/.gitignore +++ b/.gitignore @@ -63,4 +63,5 @@ src/js/_DS_Store #User uploaded produce_images images static/images/produce_images +static/images/id_images diff --git a/package-lock.json b/package-lock.json index 46050a42..754069f0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8786,6 +8786,18 @@ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "dev": true }, + "node_modules/mocha/node_modules/nanoid": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.1.tgz", + "integrity": "sha512-n6Vs/3KGyxPQd6uO0eH4Bv0ojGSUvuLlIHtC3Y0kEO23YRge8H9x1GCzLn28YX0H66pMkxuaeESFq4tKISKwdw==", + "dev": true, + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, "node_modules/mocha/node_modules/string-width": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", @@ -9065,18 +9077,6 @@ "dev": true, "optional": true }, - "node_modules/nanoid": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.1.tgz", - "integrity": "sha512-n6Vs/3KGyxPQd6uO0eH4Bv0ojGSUvuLlIHtC3Y0kEO23YRge8H9x1GCzLn28YX0H66pMkxuaeESFq4tKISKwdw==", - "dev": true, - "bin": { - "nanoid": "bin/nanoid.cjs" - }, - "engines": { - "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" - } - }, "node_modules/nanomatch": { "version": "1.2.13", "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", @@ -21808,6 +21808,12 @@ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "dev": true }, + "nanoid": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.1.tgz", + "integrity": "sha512-n6Vs/3KGyxPQd6uO0eH4Bv0ojGSUvuLlIHtC3Y0kEO23YRge8H9x1GCzLn28YX0H66pMkxuaeESFq4tKISKwdw==", + "dev": true + }, "string-width": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", @@ -22047,12 +22053,6 @@ "dev": true, "optional": true }, - "nanoid": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.1.tgz", - "integrity": "sha512-n6Vs/3KGyxPQd6uO0eH4Bv0ojGSUvuLlIHtC3Y0kEO23YRge8H9x1GCzLn28YX0H66pMkxuaeESFq4tKISKwdw==", - "dev": true - }, "nanomatch": { "version": "1.2.13", "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", diff --git a/routes/auth.js b/routes/auth.js index 17b1230a..82e17739 100644 --- a/routes/auth.js +++ b/routes/auth.js @@ -4,9 +4,8 @@ var passport = require('passport'); const fetch = (...args) => import('node-fetch').then(({ default: fetch }) => fetch(...args)); var fs = require('fs').promises; const multer = require('multer'); //middleware for handling multipart/form-data, which is primarily used for uploading files -const upload = multer({ dest: './static/images/produce_images/' }); //path.join(__dirname, 'static/images/produce_images/) +const upload = multer({ dest: './static/images/id_images/' }); //path.join(__dirname, 'static/images/produce_images/) -var crypto = require('crypto'); const uuidv4 = require('uuid/v4'); var initModels = require('../models/init-models'); var sequelise = require('../config/db/db_sequelise'); @@ -16,7 +15,6 @@ var models = initModels(sequelise); const bcrypt = require('bcrypt'); var jwt = require('jsonwebtoken'); -// const nodemailer = require('nodemailer'); const customSendEmail = require('../config/email/email'); /* Render Login page. */ @@ -30,8 +28,9 @@ router.get('/login', function (req, res) { /* Process Login form submission (File Based Auth). */ /* TODO add a user not found message */ -router.post('/login', - passport.authenticate(process.env.AUTH_STATEGY? process.env.AUTH_STATEGY:'db-local' , { +router.post( + '/login', + passport.authenticate(process.env.AUTH_STATEGY ? process.env.AUTH_STATEGY : 'db-local', { successReturnToOrRedirect: '/', successFlash: 'You are now logged in.', failureRedirect: '/app/auth/login', @@ -103,21 +102,19 @@ router.get('/register_options', function (req, res) { /* Process register form submission . */ router.post('/register', upload.single('registerIDPhoto'), async function (req, res) { - //TODO - Log registration to table and send email to FoodPrint Admin const salt = await bcrypt.genSalt(10); const hashedPassword = await bcrypt.hash(req.body.password, salt); - const confirmationCode = jwt.sign({ email: req.body.registerEmail }, process.env.TOKEN_SIGN); + const latestUser = await models.User.findOne({ + attributes: [ 'ID'], + order: [[ 'ID', 'DESC' ]], + }); + const user_uuid = uuidv4(); - //res.redirect('/app/auth/register/message'); try { - // TODO make user id short let user = { - user_uuid: uuidv4(), - userId: `${req.body.role.charAt(0).toUpperCase()}-${crypto - .createHash('md5') - .update(req.body.registerEmail) - .digest('hex')}`, + user_uuid: user_uuid, + userId: `${req.body.role.charAt(0).toUpperCase()}${user_uuid.substring(0,6)}${latestUser?latestUser.ID + 1:0}`, firstName: req.body.registerName, middleName: '', lastName: req.body.registerSurname, @@ -146,33 +143,21 @@ router.post('/register', upload.single('registerIDPhoto'), async function (req, models.User.create(user) .then(_ => { - models.User.findAll({ + models.User.findOne({ attributes: [ 'ID', 'firstName', - 'middleName', 'lastName', - 'phoneNumber', 'email', - 'role', - 'createdAt', - 'farmName', - 'registrationChannel', - 'nationalIdPhotoHash', - 'organisationName', - 'organisationType', - 'city', ], where: { + user_uuid: user_uuid, email: req.body.registerEmail, }, }) - .then(users => { - if (users.length === 0) { - res.status(404).send({ message: 'user not found' }); - } else { - // res.status(201).send(users[0]); - let mailOptions = { + .then(user => { + if (user) { + const mailOptions = { to: process.env.TEST_EMAIL_ADDRESS, subject: 'Foodprint registration confirmation email', html: `

    Thank you for joining FoodPrint.

    @@ -189,7 +174,9 @@ router.post('/register', upload.single('registerIDPhoto'), async function (req, } catch (e) { console.log('Error sending email - ', e); } - + } + else { + res.status(404).send({ message: 'user not found' }); } }) .catch(err => { diff --git a/routes/users.js b/routes/users.js index ecabd710..f3efbe1f 100644 --- a/routes/users.js +++ b/routes/users.js @@ -2,53 +2,57 @@ var express = require('express'); const ROLES = require('../utils/roles'); var router = express.Router(); -const { Op, Sequelize } = require('sequelize'); +// const { Op, Sequelize } = require('sequelize'); var initModels = require('../models/init-models'); var sequelise = require('../config/db/db_sequelise'); +const { check, validationResult } = require('express-validator'); +const multer = require('multer'); +const bcrypt = require('bcrypt'); +const jwt = require('jsonwebtoken'); +const uuidv4 = require('uuid/v4'); +const upload = multer({ dest: './static/images/id_images/' }); var models = initModels(sequelise); /*Render user_management */ -router.get('/management', +router.get( + '/management', require('connect-ensure-login').ensureLoggedIn({ redirectTo: '/app/auth/login' }), function (req, res) { - - if ( - req.user.role === ROLES.Admin || - req.user.role === ROLES.Superuser - ) { - + if (req.user.role === ROLES.Admin || req.user.role === ROLES.Superuser) { models.User.findAll({ attributes: [ + 'user_uuid', 'firstName', 'lastName', 'email', 'phoneNumber', 'role', 'isEmailVerified', - 'isAdminVerified' + 'isAdminVerified', ], - where: { - role: {[Op.notIn]:[ROLES.Admin, ROLES.Superuser]} - } - }).then( user_rows => { - res.render('user_management', { - title: 'FoodPrint - User management', - user: req.user, - data: user_rows, - page_name: 'UMS', - }); - }).catch(err => { - console.log('All users err:' + err); - req.flash('error', err); - res.render('user_management', { - title: 'FoodPrint - User management', - user: req.user, - data: '', - page_name: 'UMS', - }); + /*where: { + role: { [Op.notIn]: [ROLES.Admin, ROLES.Superuser] }, + },*/ }) - + .then(user_rows => { + res.render('user_management', { + title: 'FoodPrint - User management', + user: req.user, + data: user_rows, + page_name: 'UMS', + }); + }) + .catch(err => { + console.log('All users err:' + err); + req.flash('error', err); + res.render('user_management', { + title: 'FoodPrint - User management', + user: req.user, + data: '', + page_name: 'UMS', + }); + }); } else { res.render('error', { message: 'You are not authorised to view this resource.', @@ -57,6 +61,201 @@ router.get('/management', page_name: 'error', }); } -}); + } +); + +router.post( + '/update', + upload.none(), + [ + check('viewmodal_user_firstName', 'User FirstName value is not valid') + .not() + .isEmpty() + .trim() + .escape(), + check('viewmodal_user_lastName', 'User Lastname value is not valid') + .not() + .isEmpty() + .trim() + .escape(), + check('viewmodal_user_email', 'User email value is not valid').not().isEmpty().trim().escape(), + check('viewmodal_user_phoneNumber', 'User phone number value is not valid') + .not() + .isEmpty() + .trim() + .escape(), + check('viewmodal_user_role', 'User role value is not valid').not().isEmpty().trim().escape(), + ], + function (req, res) { + const result = validationResult(req); + const errors = result.errors; + for (let key in errors) { + console.log('Validation error - ' + errors[key].msg); + } + + if (!result.isEmpty()) { + req.flash('error', errors); + res.redirect('/app/user/management'); + } else { + let data = { + firstName: req.body.viewmodal_user_firstName, + lastName: req.body.viewmodal_user_lastName, + email: req.body.viewmodal_user_email, + phoneNumber: req.body.viewmodal_user_phoneNumber, + role: req.body.viewmodal_user_role, + isAdminVerified: req.body.viewmodal_user_profile, + }; + + try { + models.User.update(data, { + where: { + user_uuid: req.body.viewmodal_user_uuid, + }, + }) + .then(_ => { + req.flash( + 'success', + 'User entry updated successfully! User UUID = ' + req.body.viewmodal_user_uuid + ); + res.redirect('/app/user/management'); + }) + .catch(err => { + console.log('Error - Update User failed'); + console.log(err); + req.flash('error', err.message); + res.redirect('/app/user/management'); + }); + } catch (e) { + next(e); + res.redirect('/app/user/management'); + } + } + } +); + + +router.post( + '/save', + upload.none(), + [ + check('viewmodal_user_firstName', 'User FirstName value is not valid') + .not() + .isEmpty() + .trim() + .escape(), + check('viewmodal_user_lastName', 'User Lastname value is not valid') + .not() + .isEmpty() + .trim() + .escape(), + check('viewmodal_user_email', 'User email value is not valid').not().isEmpty().trim().escape(), + check('viewmodal_user_phoneNumber', 'User phone number value is not valid') + .not() + .isEmpty() + .trim() + .escape(), + check('viewmodal_user_password', 'User phone number value is not valid') + .not() + .isEmpty() + .trim() + .escape(), + check('viewmodal_user_role', 'User role value is not valid').not().isEmpty().trim().escape(), + ], + async function (req, res) { + const result = validationResult(req); + const errors = result.errors; + for (let key in errors) { + console.log('Validation error - ' + errors[key].msg); + } + + if (!result.isEmpty()) { + req.flash('error', errors); + res.redirect('/app/user/management'); + } else { + + const salt = await bcrypt.genSalt(10); + const hashedPassword = await bcrypt.hash(req.body.viewmodal_user_password, salt); + const confirmationCode = jwt.sign({ email: req.body.viewmodal_user_email }, process.env.TOKEN_SIGN); + const latestUser = await models.User.findOne({ + attributes: [ 'ID'], + order: [[ 'ID', 'DESC' ]], + }); + const user_uuid = uuidv4(); + const data = { + user_uuid: user_uuid, + userId: `${req.body.viewmodal_user_role.charAt(0).toUpperCase()}${user_uuid.substring(0,6)}${latestUser?latestUser.ID + 1:0}`, + firstName: req.body.viewmodal_user_firstName, + lastName: req.body.viewmodal_user_lastName, + email: req.body.viewmodal_user_email, + phoneNumber: req.body.viewmodal_user_phoneNumber, + role: req.body.viewmodal_user_role, + isAdminVerified: req.body.viewmodal_user_profile, + isEmailVerified: true, + password: hashedPassword, + emailVerificationToken: confirmationCode + }; + + try { + models.User.create(data) + .then(_ => { + req.flash( + 'success', + 'User entry added successfully' + ); + res.redirect('/app/user/management'); + }) + .catch(err => { + console.log('Error - Add User failed'); + console.log(err); + req.flash('error', err.message); + res.redirect('/app/user/management'); + }); + } catch (e) { + next(e); + res.redirect('/app/user/management'); + } + } + } +); + +router.post( + '/delete', + upload.none(), + [ + check('viewmodal_user_uuid', 'User ID value is not valid') + .not() + .isEmpty() + .trim() + .escape(), + ], + function (req, res) { + if (req.user.role === ROLES.Admin || req.user.role === ROLES.Superuser) { + models.User.destroy({ + where: { + user_uuid: req.body.viewmodal_user_uuid, + }, + }) + .then(_ => { + req.flash( + 'success', + 'User entry deleted successfully! User ID = ' + req.body.viewmodal_user_uuid + ); + res.redirect('/app/user/management'); + }) + .catch(err => { + req.flash('error', err.message); + res.redirect('/app/user/management'); + }); + } + else { + req.flash( + 'error', + 'Not authorised' + ); + res.redirect('/app/user/management'); + } + } +); + module.exports = router; diff --git a/server.js b/server.js index 058623e2..38c7b070 100644 --- a/server.js +++ b/server.js @@ -63,7 +63,7 @@ var configRouter = require('./routes/config'); var harvestRouter = require('./routes/harvest'); var storageRouter = require('./routes/storage'); var authRouter = require('./routes/auth'); -// var blockchainRouter = require('./routes/blockchain'); +var blockchainRouter = require('./routes/blockchain'); var dashboardsRouter = require('./routes/dashboards'); var qrCodeRouter = require('./routes/qrcode'); var umsRouter = require('./routes/users'); @@ -147,7 +147,7 @@ app.use('/docs', swaggerUi.serve, swaggerUi.setup(swaggerSpecs)); // Mount routers app.use('/', router); -// app.use('/', blockchainRouter); +app.use('/', blockchainRouter); app.use('/app/config', configRouter); app.use('/app/auth', authRouter); app.use('/app/user', umsRouter); @@ -192,7 +192,7 @@ passport.use( if (!user) { return cb(null, false, { message: 'Incorrect username.' }); } - if (user.password != password) { + if (user.password !== password) { return cb(null, false, { message: 'Incorrect password.' }); } // If the credentials are valid, the verify callback invokes done to supply @@ -291,44 +291,41 @@ passport.serializeUser(function (user, cb) { }); passport.deserializeUser(function (id, cb) { - const strategy = process.env.AUTH_STATEGY ? process.env.AUTH_STATEGY: CUSTOM_ENUMS.DB_STRATEGY - if (strategy === CUSTOM_ENUMS.FILE_STRATEGY ) { - db.users.findById(id, function(err, user) { + const strategy = process.env.AUTH_STATEGY ? process.env.AUTH_STATEGY : CUSTOM_ENUMS.DB_STRATEGY; + if (strategy === CUSTOM_ENUMS.FILE_STRATEGY) { + db.users.findById(id, function (err, user) { if (err) { return cb(err); } cb(null, user); }); - } else { models.User.findOne({ - attributes: ['ID', 'firstName', 'middleName', 'lastName', 'email', 'password', 'role'], + attributes: ['ID', 'firstName', 'lastName', 'email', 'password', 'role'], where: { ID: id, }, }) .then(data => { - let user = { + const user = { id: data.ID, username: data.email, password: data.password, displayName: `${data.firstName} ${data.lastName}`, prefs: [{ value: data.email }], email: data.email, - role: data.role, // TODO roles have title case in enum + role: data.role, }; if (!data) { return cb(err); } - // console.log(user); return cb(null, user); }) .catch(err => { return cb(err); }); } - }); // catch 404 and forward to error handler diff --git a/utils/enums.js b/utils/enums.js index 3cccd8b4..80fb8b2d 100644 --- a/utils/enums.js +++ b/utils/enums.js @@ -7,6 +7,6 @@ const CUSTOM_ENUMS = { DEVELOPMENT: 'development', OZCF: 'ozcf', FILE_STRATEGY: 'file-local', - DB_STRATEGY: 'db-local' + DB_STRATEGY: 'db-local', }; module.exports = CUSTOM_ENUMS; diff --git a/views/user_management.ejs b/views/user_management.ejs index 57881b19..e16451a3 100644 --- a/views/user_management.ejs +++ b/views/user_management.ejs @@ -17,6 +17,10 @@ +
    + +
    + + <% include ./partials/footer %> @@ -85,5 +212,180 @@ + + From 45b913fa6d1d842d9db8e69e1576400a3b429a8a Mon Sep 17 00:00:00 2001 From: Tatenda Date: Wed, 13 Jul 2022 01:06:09 +0200 Subject: [PATCH 07/12] update migration file --- README.md | 3 ++ .../20220429215904-add_new_user_columns.js | 24 +++++++++++ models/user.js | 2 +- routes/auth.js | 20 ++++----- routes/users.js | 42 +++++++------------ 5 files changed, 52 insertions(+), 39 deletions(-) diff --git a/README.md b/README.md index a714cab6..90fc247a 100644 --- a/README.md +++ b/README.md @@ -129,6 +129,9 @@ DO_BUCKET_NAME=REPLACE_ME DO_KEY_ID=REPLACE_ME DO_SECRET=REPLACE_ME DO_ENDPOINT=REPLACE_ME +TOKEN_SIGN=REPLACE_ME +AUTH_STATEGY=REPLACE_ME +CONFIRM_URL=REPLACE_ME ``` You can then access the variables in your code using process.env e.g. diff --git a/migrations/20220429215904-add_new_user_columns.js b/migrations/20220429215904-add_new_user_columns.js index 3e7a4e9d..1bccdded 100644 --- a/migrations/20220429215904-add_new_user_columns.js +++ b/migrations/20220429215904-add_new_user_columns.js @@ -14,6 +14,24 @@ module.exports = { await queryInterface.addColumn('user', 'user_uuid', { type: Sequelize.STRING(255), }); + await queryInterface.addColumn('user', 'farmName', { + type: Sequelize.STRING(255), + }); + await queryInterface.addColumn('user', 'organisationName', { + type: Sequelize.STRING(255), + }); + await queryInterface.addColumn('user', 'organisationType', { + type: Sequelize.STRING(255), + }); + await queryInterface.addColumn('user', 'city', { + type: Sequelize.STRING(255), + }); + await queryInterface.addColumn('user', 'emailVerificationToken', { + type: Sequelize.STRING(255), + }); + await queryInterface.addColumn('user', 'isEmailVerified', { + type: Sequelize.BOOLEAN, + }); await queryInterface.addColumn('user', 'isAdminVerified', { type: Sequelize.BOOLEAN, }); @@ -29,6 +47,12 @@ module.exports = { await queryInterface.removeColumn('user', 'userId'); await queryInterface.removeColumn('user', 'user_uuid'); + await queryInterface.removeColumn('user', 'farmName'); + await queryInterface.removeColumn('user', 'organisationName'); + await queryInterface.removeColumn('user', 'organisationType'); + await queryInterface.removeColumn('user', 'city'); + await queryInterface.removeColumn('user', 'emailVerificationToken'); + await queryInterface.removeColumn('user', 'isEmailVerified'); await queryInterface.removeColumn('user', 'isAdminVerified'); }, }; diff --git a/models/user.js b/models/user.js index 59b8a30e..63b2823b 100644 --- a/models/user.js +++ b/models/user.js @@ -72,7 +72,7 @@ module.exports = function (sequelize, DataTypes) { allowNull: true, }, emailVerificationToken: { - type: DataTypes.STRING, + type: DataTypes.STRING(255), allowNull: true, }, isEmailVerified: { diff --git a/routes/auth.js b/routes/auth.js index 82e17739..d92c0c8a 100644 --- a/routes/auth.js +++ b/routes/auth.js @@ -105,16 +105,18 @@ router.post('/register', upload.single('registerIDPhoto'), async function (req, const salt = await bcrypt.genSalt(10); const hashedPassword = await bcrypt.hash(req.body.password, salt); const confirmationCode = jwt.sign({ email: req.body.registerEmail }, process.env.TOKEN_SIGN); - const latestUser = await models.User.findOne({ - attributes: [ 'ID'], - order: [[ 'ID', 'DESC' ]], + const latestUser = await models.User.findOne({ + attributes: ['ID'], + order: [['ID', 'DESC']], }); const user_uuid = uuidv4(); try { let user = { user_uuid: user_uuid, - userId: `${req.body.role.charAt(0).toUpperCase()}${user_uuid.substring(0,6)}${latestUser?latestUser.ID + 1:0}`, + userId: `${req.body.role.charAt(0).toUpperCase()}${user_uuid.substring(0, 6)}${ + latestUser ? latestUser.ID + 1 : 0 + }`, firstName: req.body.registerName, middleName: '', lastName: req.body.registerSurname, @@ -144,12 +146,7 @@ router.post('/register', upload.single('registerIDPhoto'), async function (req, models.User.create(user) .then(_ => { models.User.findOne({ - attributes: [ - 'ID', - 'firstName', - 'lastName', - 'email', - ], + attributes: ['ID', 'firstName', 'lastName', 'email'], where: { user_uuid: user_uuid, email: req.body.registerEmail, @@ -174,8 +171,7 @@ router.post('/register', upload.single('registerIDPhoto'), async function (req, } catch (e) { console.log('Error sending email - ', e); } - } - else { + } else { res.status(404).send({ message: 'user not found' }); } }) diff --git a/routes/users.js b/routes/users.js index f3efbe1f..0a7bf8b4 100644 --- a/routes/users.js +++ b/routes/users.js @@ -133,7 +133,6 @@ router.post( } ); - router.post( '/save', upload.none(), @@ -172,18 +171,23 @@ router.post( req.flash('error', errors); res.redirect('/app/user/management'); } else { - const salt = await bcrypt.genSalt(10); const hashedPassword = await bcrypt.hash(req.body.viewmodal_user_password, salt); - const confirmationCode = jwt.sign({ email: req.body.viewmodal_user_email }, process.env.TOKEN_SIGN); - const latestUser = await models.User.findOne({ - attributes: [ 'ID'], - order: [[ 'ID', 'DESC' ]], + const confirmationCode = jwt.sign( + { email: req.body.viewmodal_user_email }, + process.env.TOKEN_SIGN + ); + const latestUser = await models.User.findOne({ + attributes: ['ID'], + order: [['ID', 'DESC']], }); const user_uuid = uuidv4(); const data = { user_uuid: user_uuid, - userId: `${req.body.viewmodal_user_role.charAt(0).toUpperCase()}${user_uuid.substring(0,6)}${latestUser?latestUser.ID + 1:0}`, + userId: `${req.body.viewmodal_user_role.charAt(0).toUpperCase()}${user_uuid.substring( + 0, + 6 + )}${latestUser ? latestUser.ID + 1 : 0}`, firstName: req.body.viewmodal_user_firstName, lastName: req.body.viewmodal_user_lastName, email: req.body.viewmodal_user_email, @@ -192,16 +196,13 @@ router.post( isAdminVerified: req.body.viewmodal_user_profile, isEmailVerified: true, password: hashedPassword, - emailVerificationToken: confirmationCode + emailVerificationToken: confirmationCode, }; try { models.User.create(data) .then(_ => { - req.flash( - 'success', - 'User entry added successfully' - ); + req.flash('success', 'User entry added successfully'); res.redirect('/app/user/management'); }) .catch(err => { @@ -221,13 +222,7 @@ router.post( router.post( '/delete', upload.none(), - [ - check('viewmodal_user_uuid', 'User ID value is not valid') - .not() - .isEmpty() - .trim() - .escape(), - ], + [check('viewmodal_user_uuid', 'User ID value is not valid').not().isEmpty().trim().escape()], function (req, res) { if (req.user.role === ROLES.Admin || req.user.role === ROLES.Superuser) { models.User.destroy({ @@ -246,16 +241,11 @@ router.post( req.flash('error', err.message); res.redirect('/app/user/management'); }); - } - else { - req.flash( - 'error', - 'Not authorised' - ); + } else { + req.flash('error', 'Not authorised'); res.redirect('/app/user/management'); } } ); - module.exports = router; From 8b827d04853c3042e68d23fa6abf2e62e536aacf Mon Sep 17 00:00:00 2001 From: Tatenda Date: Wed, 13 Jul 2022 01:14:55 +0200 Subject: [PATCH 08/12] update migration file --- routes/auth.js | 4 ++-- server.js | 14 -------------- views/register.ejs | 15 +-------------- 3 files changed, 3 insertions(+), 30 deletions(-) diff --git a/routes/auth.js b/routes/auth.js index d92c0c8a..fe7b3061 100644 --- a/routes/auth.js +++ b/routes/auth.js @@ -3,8 +3,8 @@ var router = express.Router(); var passport = require('passport'); const fetch = (...args) => import('node-fetch').then(({ default: fetch }) => fetch(...args)); var fs = require('fs').promises; -const multer = require('multer'); //middleware for handling multipart/form-data, which is primarily used for uploading files -const upload = multer({ dest: './static/images/id_images/' }); //path.join(__dirname, 'static/images/produce_images/) +const multer = require('multer'); +const upload = multer({ dest: './static/images/id_images/' }); const uuidv4 = require('uuid/v4'); var initModels = require('../models/init-models'); diff --git a/server.js b/server.js index 38c7b070..065183e6 100644 --- a/server.js +++ b/server.js @@ -261,20 +261,6 @@ passport.use( .catch(err => { return cb(err); }); - /*db.users.findByUsername(username, function (err, user) { - if (err) { - return cb(err); - } - if (!user) { - return cb(null, false, { message: 'Incorrect username.' }); - } - if (user.password != password) { - return cb(null, false, { message: 'Incorrect password.' }); - } - // If the credentials are valid, the verify callback invokes done to - // supply Passport with the user that authenticated. - return cb(null, user); - });*/ } ) ); diff --git a/views/register.ejs b/views/register.ejs index 22a7a890..a3190215 100644 --- a/views/register.ejs +++ b/views/register.ejs @@ -2,11 +2,6 @@ <% include ./partials/head %> - @@ -50,20 +45,12 @@
    -
    - @@ -106,7 +93,7 @@ <%}%> - + <%if(choice && choice.length > 0 && choice === 'Farmer'){%>
    From 3fc14f6638bd76c8b23d12d6f45d9edb7f3e3ba6 Mon Sep 17 00:00:00 2001 From: Tatenda Date: Sat, 16 Jul 2022 00:11:07 +0200 Subject: [PATCH 09/12] update user management --- routes/users.js | 22 +++++ views/user_management.ejs | 176 +++++++++++++++++++++++++++++++++++++- 2 files changed, 195 insertions(+), 3 deletions(-) diff --git a/routes/users.js b/routes/users.js index 0a7bf8b4..94dfe14f 100644 --- a/routes/users.js +++ b/routes/users.js @@ -30,12 +30,26 @@ router.get( 'role', 'isEmailVerified', 'isAdminVerified', + 'farmName', + 'organisationName', + 'organisationType', + 'city', + 'nationalIdPhotoHash' ], /*where: { role: { [Op.notIn]: [ROLES.Admin, ROLES.Superuser] }, },*/ }) .then(user_rows => { + for (let i = 0; i < user_rows.length; i++) { + if (user_rows[i].nationalIdPhotoHash === null) { + user_rows[i].nationalIdPhotoHash = ''; + } else { + user_rows[i].nationalIdPhotoHash = + 'data:image/png;base64,' + + Buffer.from(user_rows[i].nationalIdPhotoHash, 'binary').toString('base64'); + } + } res.render('user_management', { title: 'FoodPrint - User management', user: req.user, @@ -104,6 +118,14 @@ router.post( phoneNumber: req.body.viewmodal_user_phoneNumber, role: req.body.viewmodal_user_role, isAdminVerified: req.body.viewmodal_user_profile, + ...(req.body.viewmodal_user_role === ROLES.Farmer && { + farmName: req.body.viewmodal_user_farmname }), + ...(req.body.viewmodal_user_role === ROLES.Intermediary && { + organisationName: req.body.viewmodal_user_orgname, + organisationType: req.body.viewmodal_user_orgtype, + }), + ...(req.body.viewmodal_user_role === ROLES.Agent && { + city: req.body.viewmodal_user_city }), }; try { diff --git a/views/user_management.ejs b/views/user_management.ejs index e16451a3..d0e85f46 100644 --- a/views/user_management.ejs +++ b/views/user_management.ejs @@ -60,6 +60,11 @@ data-phonenumber="<%=data[i].phoneNumber%>" data-role="<%=data[i].role%>" data-profilestatus="<%=data[i].isAdminVerified%>" + data-farmname="<%=data[i].farmName%>" + data-organisationname="<%=data[i].organisationName%>" + data-organisationtype="<%=data[i].organisationType%>" + data-city="<%=data[i].city%>" + data-nationalidphotohash="<%=data[i].nationalIdPhotoHash%>" >View Edit Delete
    @@ -184,6 +199,58 @@
    +
    + + +
    + +
    + + +
    + + +
    + + +
    + +
    + + +
    + +
    + + +
    + User ID +
    +
    +
    @@ -251,6 +318,11 @@ const user_phoneNumber = $(obj_identifier).data('phonenumber'); const user_role = $(obj_identifier).data('role'); const user_profilestatus = $(obj_identifier).data('profilestatus'); + const user_farmname = $(obj_identifier).data('farmname'); + const user_organisationname = $(obj_identifier).data('organisationname'); + const user_organisationtype = $(obj_identifier).data('organisationtype'); + const user_city = $(obj_identifier).data('city'); + const user_idphoto = $(obj_identifier).data('nationalidphotohash'); // console.log(obj_identifier); @@ -270,7 +342,18 @@ $('#viewmodal_user_lastName').val(user_lastName); $('#viewmodal_user_email').val(user_email); $('#viewmodal_user_phoneNumber').val(user_phoneNumber); + $('#viewmodal_user_farmname').val(user_farmname); + $('#viewmodal_user_orgname').val(user_organisationname); + $(`#viewmodal_user_orgtype option[value='${user_organisationtype}']`).prop('selected', true); + $('#viewmodal_user_city').val(user_city); + $('#viewmodal_user_idimage').attr("src", user_idphoto); + $('#password_div').hide(); + $('#farmname_div').hide(); + $('#orgname_div').hide(); + $('#orgtype_div').hide(); + $('#city_div').hide(); + $('#idphoto_div').hide(); $(`#viewmodal_user_profile option[value='${user_profilestatus}']`).prop('selected', true); @@ -286,12 +369,32 @@ $("#viewmodal_user_role").append(""); $("#viewmodal_user_role").append(""); - $("#viewmodal_user_role").append(""); + $("#viewmodal_user_role").append(""); $("#viewmodal_user_role").append(""); $("#viewmodal_user_role").append(""); $(`#viewmodal_user_role option[value='${user_role}']`).prop('selected', true); + if(user_role === 'Farmer'){ + $('#farmname_div').show(); + $('#orgname_div').hide(); + $('#orgtype_div').hide(); + $('#city_div').hide(); + $('#idphoto_div').show(); + } else if (user_role === 'Agent') { + $('#farmname_div').hide(); + $('#orgname_div').hide(); + $('#orgtype_div').hide(); + $('#city_div').show(); + $('#idphoto_div').show(); + } else if (user_role === 'Intermediary') { + $('#farmname_div').hide(); + $('#orgname_div').show(); + $('#orgtype_div').show(); + $('#city_div').hide(); + $('#idphoto_div').hide(); + } + $("#userCheckDiv").hide(); $("#userDeleteDiv").hide(); $("#modalFooter").append(closeButton); @@ -308,12 +411,40 @@ $("#viewmodal_user_role").append(""); $("#viewmodal_user_role").append(""); - $("#viewmodal_user_role").append(""); + $("#viewmodal_user_role").append(""); $("#viewmodal_user_role").append(""); $("#viewmodal_user_role").append(""); $(`#viewmodal_user_role option[value='${user_role}']`).prop('selected', true); + if(user_role === 'Farmer'){ + $('#farmname_div').show(); + $('#orgname_div').hide(); + $('#orgtype_div').hide(); + $('#city_div').hide(); + $('#idphoto_div').show(); + $("#viewmodal_user_orgname").attr("required", false); + $("#viewmodal_user_orgtype").attr("required", false); + $("#viewmodal_user_city").attr("required", false); + } else if (user_role === 'Agent') { + $('#farmname_div').hide(); + $('#orgname_div').hide(); + $('#orgtype_div').hide(); + $('#city_div').show(); + $('#idphoto_div').show(); + $("#viewmodal_user_orgname").attr("required", false); + $("#viewmodal_user_orgtype").attr("required", false); + $("#viewmodal_user_farmname").attr("required", false); + } else if (user_role === 'Intermediary') { + $('#farmname_div').hide(); + $('#orgname_div').show(); + $('#orgtype_div').show(); + $('#city_div').hide(); + $('#idphoto_div').hide(); + $("#viewmodal_user_city").attr("required", false); + $("#viewmodal_user_farmname").attr("required", false); + } + $("#viewmodal_user_uuid").attr('readonly', true); $("#viewmodal_user_password").attr("required", false); @@ -345,6 +476,17 @@ $('#viewmodal_user_profile').show(); $('#password_div').show(); + $('#farmname_div').hide(); + $('#orgname_div').hide(); + $('#orgtype_div').hide(); + $('#city_div').hide(); + $('#idphoto_div').hide(); + $("#viewmodal_user_orgname").attr("required", false); + $("#viewmodal_user_orgtype").attr("required", false); + $("#viewmodal_user_city").attr("required", false); + $("#viewmodal_user_farmname").attr("required", false); + + $("#userCheckDiv").show(); $("#userDeleteDiv").hide(); $("#userDelete").attr("required", false); @@ -362,12 +504,40 @@ $("#viewmodal_user_role").append(""); $("#viewmodal_user_role").append(""); - $("#viewmodal_user_role").append(""); + $("#viewmodal_user_role").append(""); $("#viewmodal_user_role").append(""); $("#viewmodal_user_role").append(""); $(`#viewmodal_user_role option[value='${user_role}']`).prop('selected', true); + if(user_role === 'Farmer'){ + $('#farmname_div').show(); + $('#orgname_div').hide(); + $('#orgtype_div').hide(); + $('#city_div').hide(); + $('#idphoto_div').show(); + $("#viewmodal_user_orgname").attr("required", false); + $("#viewmodal_user_orgtype").attr("required", false); + $("#viewmodal_user_city").attr("required", false); + } else if (user_role === 'Agent') { + $('#farmname_div').hide(); + $('#orgname_div').hide(); + $('#orgtype_div').hide(); + $('#city_div').show(); + $('#idphoto_div').show(); + $("#viewmodal_user_orgname").attr("required", false); + $("#viewmodal_user_orgtype").attr("required", false); + $("#viewmodal_user_farmname").attr("required", false); + } else if (user_role === 'Intermediary') { + $('#farmname_div').hide(); + $('#orgname_div').show(); + $('#orgtype_div').show(); + $('#city_div').hide(); + $('#idphoto_div').hide(); + $("#viewmodal_user_city").attr("required", false); + $("#viewmodal_user_farmname").attr("required", false); + } + $("#userDeleteDiv").show(); $("#userDelete").attr("required", true); From 0223a32383962a5baffc4395439eb76f20c4b5c3 Mon Sep 17 00:00:00 2001 From: Tatenda Date: Sun, 7 Aug 2022 02:52:52 +0200 Subject: [PATCH 10/12] fix email to option --- routes/auth.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/routes/auth.js b/routes/auth.js index fe7b3061..bf4ff879 100644 --- a/routes/auth.js +++ b/routes/auth.js @@ -155,7 +155,7 @@ router.post('/register', upload.single('registerIDPhoto'), async function (req, .then(user => { if (user) { const mailOptions = { - to: process.env.TEST_EMAIL_ADDRESS, + to: req.body.registerEmail, subject: 'Foodprint registration confirmation email', html: `

    Thank you for joining FoodPrint.

    Please confirm your email by clicking on the following link

    From 9fc36f3f5f01ae4f53a3121687f59e5497f887fa Mon Sep 17 00:00:00 2001 From: nkululekombhele Date: Tue, 23 May 2023 22:45:33 +0200 Subject: [PATCH 11/12] remove duplicate name --- views/register.ejs | 162 +++++++++++++++++++++------------------------ 1 file changed, 75 insertions(+), 87 deletions(-) diff --git a/views/register.ejs b/views/register.ejs index 289ef1a1..b1c8a45f 100644 --- a/views/register.ejs +++ b/views/register.ejs @@ -31,102 +31,90 @@
    -
    -
    - - -
    - -
    - - -
    - -
    - - -
    -
    - - -
    - -
    - - -
    -
    - - -
    - -
    - - -
    - -
    - - -
    - - - - - <%if(choice && choice.length > 0 && (choice === 'Agent' || choice === 'Farmer' )){%> -
    - - -
    - - <%}%> +
    + + +
    + +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    + +
    + + +
    + + + + + <%if(choice && choice.length > 0 && (choice === 'Agent' || choice === 'Farmer' )){%> +
    + + +
    + + <%}%> <%if(choice && choice.length > 0 && choice === 'Agent'){%> -
    - - -
    - <%}%> +
    + + +
    + <%}%> <%if(choice && choice.length > 0 && choice === 'Intermediary'){%> -
    - - -
    +
    + + +
    -
    - - -
    - <%}%> +
    + + +
    + <%}%> <%if(choice && choice.length > 0 && choice === 'Farmer'){%> -
    - - -
    - <%}%> +
    + + +
    + <%}%>
    @@ -151,12 +139,12 @@ <%- include('partials/footer'); %> - + - - - - + + + + \ No newline at end of file From 8b7b9d38cac2c748a679d024c6dd1eb8be477e48 Mon Sep 17 00:00:00 2001 From: nkululekombhele Date: Mon, 5 Jun 2023 22:10:40 +0200 Subject: [PATCH 12/12] Update test_config UI --- src/css/custom.css | 60 ++++++++ views/test_config.ejs | 331 +++++++++++++++++++++++------------------- 2 files changed, 239 insertions(+), 152 deletions(-) diff --git a/src/css/custom.css b/src/css/custom.css index a1b8728c..0ccab03a 100644 --- a/src/css/custom.css +++ b/src/css/custom.css @@ -1710,3 +1710,63 @@ body { } /* ---------------- Global Style ------------ */ + +/* ----------------------- Test Config Styles -------------------- */ + +#test-config-wrapper { + padding: 0 5vw; + display: flex; + justify-content: center; + flex-direction: column; + align-items: center; +} +#test-config-wrapper .test-btns-container { + display: flex; + flex-direction: column; +} + +#test-config-wrapper .test-btns-container .btn { + width: 30vw; +} + +@media only screen and (min-width: 396px) and (max-width: 720px) { + #test-config-wrapper .table { + width: 80vw; + } + #test-config-wrapper { + padding: 0 2vw; + display: flex; + justify-content: center; + flex-direction: column; + align-items: center; + } + #test-config-wrapper .test-btns-container { + display: flex; + flex-direction: column; + } + + #test-config-wrapper .test-btns-container .btn { + width: 70vw; + } +} + +@media only screen and (max-width: 396px) { + #test-config-wrapper .table { + width: 80vw; + } + #test-config-wrapper { + padding: 0 2vw; + display: flex; + justify-content: center; + flex-direction: column; + align-items: center; + } + #test-config-wrapper .test-btns-container { + display: flex; + flex-direction: column; + } + + #test-config-wrapper .test-btns-container .btn { + width: 90vw; + } +} diff --git a/views/test_config.ejs b/views/test_config.ejs index a12784ba..69cc1e51 100644 --- a/views/test_config.ejs +++ b/views/test_config.ejs @@ -1,176 +1,203 @@ + Farmers - - - + <%- include('partials/head'); %> + + +
    + +
    - Home + +
    + -<% if (messages.success) { %> -

    <%- messages.success %>

    -<% } %> -
    - - - - - - - - - - - - <% if(data.length){ + <% if (messages.success) { %> +

    <%- messages.success %>

    + <% } %> +
    + +
    +
    +

    Testing

    +
    + + <%# Data %> +
    #IDFarmer NameProduce Name
    + + + + + + + + + + + <% if(data.length){ for(var i = 0; i< data.length; i++) {%> - - - - - - - - <% } + + <% } }else{ %> - + - - <% } %> - -
    #IDFarmer NameProduce Name
    <%= (i+1) %><%= data[i].harvest_logid%><%= data[i].harvest_farmerName%><%= data[i].harvest_produceName%>
    No data
    - - -
    -

    Test Email

    -

    - -
      -
      -
      -

      Test QR Code

      -

      -

      - -
        -
        - - - + + + + - + + \ No newline at end of file