From 837aa5520d4917502c2835ab9f07e7ed6439a0d7 Mon Sep 17 00:00:00 2001 From: NeoNexus DeMortis Date: Sat, 6 Jan 2024 17:43:51 -0600 Subject: [PATCH] Minor tweaks. --- CHANGELOG.md | 6 +++--- api/controllers/admin/create-user.js | 6 +++--- api/helpers/generate-backup-tokens.js | 14 ++++++++++++-- api/models/Log.js | 2 +- api/models/OTP.js | 2 +- api/models/RequestLog.js | 4 ++-- api/models/User.js | 8 ++++---- assets/src/Admin/Login.jsx | 2 +- config/ngrok.js | 6 +++--- package.json | 2 +- 10 files changed, 31 insertions(+), 21 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7a6dc66..d19b8b0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,15 +1,15 @@ # Changelog -## [v5.1.0](https://github.com/neonexus/sails-react-bootstrap-webpack/compare/v5.0.0...v5.1.0) (2023-12-22) +## [v5.1.0](https://github.com/neonexus/sails-react-bootstrap-webpack/compare/v5.0.0...v5.1.0) (2024-01-06) ### Features -* Minor tweaks / fixes. -* Created the datastore wipe script, to reset LOCAL / DEVELOPMENT datastore. Will **not** run on PRODUCTION (or when migrate = "safe"). +* Created the datastore wipe script, to clear LOCAL / DEVELOPMENT datastore(s). It's just like `DROP`ing the database. Will **not** run on PRODUCTION (or when `migrate = 'safe'`). * Converted `.mocharc.yml` -> `.mocharc` (JSON) to be more consistent. * Made the Ngrok script capable of installing [`@ngrok/ngrok`](https://npmjs.com/package/@ngrok/ngrok) when needed. * Minor visual fix in security settings page. * Built the "reactivate user" endpoint. * Corrected "edit" and "delete" user routes to use ID in the route. +* Fixed issue in 2FA backup token generation, where it was possible to generate a pure number backup token. Now will ALWAYS have at least 1 letter. * Updated dependencies. ## [v5.0.0](https://github.com/neonexus/sails-react-bootstrap-webpack/compare/v4.3.1...v5.0.0) (2023-12-05) diff --git a/api/controllers/admin/create-user.js b/api/controllers/admin/create-user.js index c50d2ac..5a73cf0 100644 --- a/api/controllers/admin/create-user.js +++ b/api/controllers/admin/create-user.js @@ -25,7 +25,7 @@ module.exports = { type: 'string', isEmail: true, required: true, - maxLength: 191 + maxLength: 191 // Max size of an utf8mb4 varchar in MySQL. }, role: { @@ -69,7 +69,7 @@ module.exports = { isPasswordValid = true; password = sails.helpers.generateToken().substring(0, 42); - // should probably send password somehow; it will be scrubbed in the custom response (would be hashed anyway...) + // should probably send password somehow; it will be scrubbed in the response (would be hashed anyway...) } if (isPasswordValid !== true) { @@ -99,7 +99,7 @@ module.exports = { } /** - * TODO: We should probably email the new user their new account info here if the password was generated (!inputs.setPassword)... + * TODO: We should probably email the new user their new account info here if the password was generated (inputs.generatePassword)... */ return exits.created({user}); diff --git a/api/helpers/generate-backup-tokens.js b/api/helpers/generate-backup-tokens.js index 43f56b2..c52a78d 100644 --- a/api/helpers/generate-backup-tokens.js +++ b/api/helpers/generate-backup-tokens.js @@ -14,11 +14,21 @@ module.exports = { exits: {}, fn: (inputs, exits) => { - const token = sails.helpers.generateToken(); + let token = sails.helpers.generateToken(); let backupTokens = []; + let last = null; for (let i = 0; i < 10; ++i) { - backupTokens[i] = token.substring(i * 8, (i * 8) + 8); + do { + // Regenerate the token if this is our second time around in the do...while loop. + if (last === i) { + token = sails.helpers.generateToken(); + } else { + last = i; + } + + backupTokens[i] = token.substring(i * 8, (i * 8) + 8); + } while (!isNaN(backupTokens[i])); // Don't let pure number tokens through. They MUST have at least 1 letter. } return exits.success(backupTokens); diff --git a/api/models/Log.js b/api/models/Log.js index 0bbcc1e..83e4616 100644 --- a/api/models/Log.js +++ b/api/models/Log.js @@ -20,7 +20,7 @@ module.exports = { description: { type: 'string', - columnType: 'varchar(191)' // 191 is the max length to safely use the utf8mb4 charset + columnType: 'varchar(191)' // 191 is the max length to safely use the utf8mb4 varchar. }, data: { diff --git a/api/models/OTP.js b/api/models/OTP.js index 334ae9e..c65bd92 100644 --- a/api/models/OTP.js +++ b/api/models/OTP.js @@ -21,7 +21,7 @@ module.exports = { secret: { type: 'string', - columnType: 'varchar(191)', + columnType: 'varchar(191)', // 191 is the max length to safely use the utf8mb4 varchar. encrypt: true, required: true }, diff --git a/api/models/RequestLog.js b/api/models/RequestLog.js index c13d9ad..1468d0b 100644 --- a/api/models/RequestLog.js +++ b/api/models/RequestLog.js @@ -34,13 +34,13 @@ module.exports = { host: { type: 'string', required: true, - columnType: 'varchar(191)' + columnType: 'varchar(191)' // 191 is the max length to safely use the utf8mb4 varchar. }, path: { type: 'string', required: true, - columnType: 'varchar(191)' + columnType: 'varchar(191)' // 191 is the max length to safely use the utf8mb4 varchar. }, headers: { diff --git a/api/models/User.js b/api/models/User.js index c30a903..b63eaea 100644 --- a/api/models/User.js +++ b/api/models/User.js @@ -53,7 +53,7 @@ module.exports = { isEmail: true, required: true, // unique: true, // can NOT be unique, if we are using soft-deleted users; controller must deal with uniqueness - columnType: 'varchar(191)' + columnType: 'varchar(191)' // 191 is the max length to safely use the utf8mb4 varchar. }, firstName: { @@ -71,7 +71,7 @@ module.exports = { password: { type: 'string', allowNull: true, - columnType: 'varchar(191)', + columnType: 'varchar(191)', // 191 is the max length to safely use the utf8mb4 varchar. // see: https://sailsjs.com/documentation/reference/waterline-orm/queries/decrypt // You will need to "decrypt" the user object before you can check if the password is valid. // encrypt: true // currently, does not work as intended, as password is encrypted before we can hash it @@ -80,13 +80,13 @@ module.exports = { verificationKey: { // placeholder for something like email verification type: 'string', allowNull: true, - columnType: 'varchar(191)' + columnType: 'varchar(191)' // 191 is the max length to safely use the utf8mb4 varchar. }, avatar: { type: 'string', isURL: true, - columnType: 'varchar(191)' + columnType: 'varchar(191)' // 191 is the max length to safely use the utf8mb4 varchar. }, isGravatar: { diff --git a/assets/src/Admin/Login.jsx b/assets/src/Admin/Login.jsx index 5139533..d8dbe2b 100644 --- a/assets/src/Admin/Login.jsx +++ b/assets/src/Admin/Login.jsx @@ -48,7 +48,7 @@ class Login extends Component { return done(body.user); } - // This should not happen, as the error handler below should display the error from the server. + // This should not happen, as the `defaultAPIErrorHandler` should display the error from the server. alert('Unknown error. Please try again. If this error persists, please contact support.'); console.error('Something is wrong in the handleLogin API post...'); }, defaultAPIErrorHandler); diff --git a/config/ngrok.js b/config/ngrok.js index dc93160..7df003a 100644 --- a/config/ngrok.js +++ b/config/ngrok.js @@ -5,7 +5,7 @@ */ module.exports.ngrok = { - // Set an HTTP basic-auth wall for the app. + // Set an HTTP basic-auth wall for the app. Optional. auth: process.env.NGROK_BASIC || undefined, // Use a string of 'username:password' style (raw password) // Default Ngrok authtoken, to tie to your account. @@ -15,10 +15,10 @@ module.exports.ngrok = { // Whether to build assets by default or not. buildAssets: true, - // The static domain to use for the Ngrok tunnel. Something like: 'running-grey-gazelle.ngrok-free.app' + // The static domain to use for the Ngrok tunnel. Something like: 'running-grey-gazelle.ngrok-free.app'. Optional; Ngrok can generate a single-use random domain. domain: process.env.NGROK_DOMAIN || undefined, - // The default region for the Ngrok tunnel. + // The default region for the Ngrok tunnel. Optional. region: process.env.NGROK_REGION || undefined, // The default port to start Sails for the Ngrok tunnel. diff --git a/package.json b/package.json index 5c9fb18..235c4a8 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "sails-react-bootstrap-webpack", "version": "5.1.0", - "description": "An opinionated base configuration of Sails, with Webpack for React builds, and Bootstrap for styling. A start-up in a box!", + "description": "An opinionated, starter application built on Sails, React, Bootstrap and Webpack. A start-up in a box!", "keywords": [ "sails", "react",