From d25fd1749ccf20dba3a61a48da3e05605dfedd17 Mon Sep 17 00:00:00 2001 From: NeoNexus DeMortis Date: Sat, 6 Jan 2024 02:34:47 -0600 Subject: [PATCH 1/2] Converted `mocaharc.yml` -> `.mocharc` for better consistency. Made Ngrok script capable of installing @ngrok/ngrok. Built the datastore wipe. Updated dependencies. --- .editorconfig | 14 +- .idea/runConfigurations/Run_Tests.xml | 2 +- .mocharc | 25 + .mocharc.yml | 20 - CHANGELOG.md | 16 +- README.md | 15 +- api/controllers/admin/edit-user.js | 4 +- api/controllers/admin/reactivate-user.js | 47 + api/models/User.js | 14 +- assets/src/Admin/AdminRouter.jsx | 7 +- assets/src/Admin/NavBar.jsx | 18 +- assets/src/Admin/Settings/SecuritySection.jsx | 10 +- assets/src/Admin/Users/Users.jsx | 3 +- config/autoreload.js | 36 +- config/local.js.sample | 2 +- config/models.js | 11 +- config/policies.js | 7 +- config/routes.js | 4 +- config/security.js | 2 +- ngrok.js | 374 ++--- package-lock.json | 1235 +++++++++-------- package.json | 41 +- scripts/datastore-wipe.js | 157 +++ setup.js | 15 + test/fixtures/User.js | 15 +- test/integration/admin/delete-user.test.js | 14 +- test/integration/admin/edit-user.test.js | 128 ++ test/utilities.js | 8 +- views/README.md | 4 +- 29 files changed, 1380 insertions(+), 868 deletions(-) create mode 100644 .mocharc delete mode 100644 .mocharc.yml create mode 100644 api/controllers/admin/reactivate-user.js create mode 100644 scripts/datastore-wipe.js create mode 100644 test/integration/admin/edit-user.test.js diff --git a/.editorconfig b/.editorconfig index 37f9649..2eeb032 100644 --- a/.editorconfig +++ b/.editorconfig @@ -3,18 +3,16 @@ # ║╣ ║║║ ║ ║ ║╠╦╝│ │ ││││├┤ ││ ┬ # o╚═╝═╩╝╩ ╩ ╚═╝╩╚═└─┘└─┘┘└┘└ ┴└─┘ # -# > Formatting conventions for your Sails app. +# > Formatting conventions for your app. # # This file (`.editorconfig`) exists to help # maintain consistent formatting throughout the -# files in your Sails app. +# files in your app. # -# For the sake of convention, the Sails team's -# preferred settings are included here out of the -# box. You can also change this file to fit your -# team's preferences (for example, if all of the -# developers on your team have a strong preference -# for tabs over spaces), +# These defaults have proven to be effective +# though many teams / years / projects. 4 spaces +# is much easier to see block separations than +# with just 2 (as is the Sails default). # # To review what each of these options mean, see: # http://editorconfig.org/ diff --git a/.idea/runConfigurations/Run_Tests.xml b/.idea/runConfigurations/Run_Tests.xml index da0bd92..9f3d15b 100644 --- a/.idea/runConfigurations/Run_Tests.xml +++ b/.idea/runConfigurations/Run_Tests.xml @@ -9,7 +9,7 @@ bdd - + --config .mocharc TEST_FILE $PROJECT_DIR$/test/startTests.js diff --git a/.mocharc b/.mocharc new file mode 100644 index 0000000..6145a77 --- /dev/null +++ b/.mocharc @@ -0,0 +1,25 @@ +{ + "bail": false, + "async-only": true, + "require": [ + "test/startTests.js" + ], + "spec": [ + "test/unit/index.js", + "test/integration/index.js" + ], + "timeout": 60000, + "checkLeaks": true, + "global": [ + "_", + "sails", + "__core-js_shared__", + "Archive", + "User", + "Session", + "RequestLog", + "Log", + "__coverage__", + "match" + ] +} \ No newline at end of file diff --git a/.mocharc.yml b/.mocharc.yml deleted file mode 100644 index af5f0f7..0000000 --- a/.mocharc.yml +++ /dev/null @@ -1,20 +0,0 @@ -bail: false #stop on first error -async-only: true # require use of "done" cb or an async function (a Promise) -require: - - 'test/startTests.js' # starting point for tests -spec: - - 'test/unit/index.js' - - 'test/integration/index.js' -timeout: 60000 # Give Sails some breathing room... We are building schemas / data fixtures. -checkLeaks: true -global: - - '_' # Lodash global - - 'sails' - - '__core-js_shared__' - - 'Archive' # Sails' built-in archive - - 'User' - - 'Session' - - 'RequestLog' - - 'Log' - - '__coverage__' # NYC coverage global - - 'match' diff --git a/CHANGELOG.md b/CHANGELOG.md index e4370f0..7a6dc66 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,17 @@ # Changelog +## [v5.1.0](https://github.com/neonexus/sails-react-bootstrap-webpack/compare/v5.0.0...v5.1.0) (2023-12-22) +### Features + +* Minor tweaks / fixes. +* Created the datastore wipe script, to reset LOCAL / DEVELOPMENT datastore. 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. +* Updated dependencies. + ## [v5.0.0](https://github.com/neonexus/sails-react-bootstrap-webpack/compare/v4.3.1...v5.0.0) (2023-12-05) ### Features @@ -277,4 +289,6 @@ * Fixed webpack config. * Made `isLoggedIn` policy clear cookie if not logged in. -This changelog is incomplete, as it was not started until **v2** (and rehashing that far back in the past is a lot of work for very little gain, the commits are there). I've gone as far back as this template became "popular" (people other than me began to clone it). +

+ +#### This changelog is incomplete, as it was not started until **v2** (and rehashing that far back in the past is a lot of work for very little gain, the commits are there). I've gone as far back as this template became "popular" (people other than me began to clone it). diff --git a/README.md b/README.md index dd9201b..8ce0258 100644 --- a/README.md +++ b/README.md @@ -2,17 +2,14 @@ [![Travis CI status](https://img.shields.io/travis/com/neonexus/sails-react-bootstrap-webpack.svg?branch=release&logo=travis)](https://app.travis-ci.com/github/neonexus/sails-react-bootstrap-webpack) [![Codecov](https://img.shields.io/codecov/c/github/neonexus/sails-react-bootstrap-webpack?logo=codecov)](https://codecov.io/gh/neonexus/sails-react-bootstrap-webpack) -[![Sails version](https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fraw.githubusercontent.com%2Fneonexus%2Fsails-react-bootstrap-webpack%2Fv5.0.0%2Fpackage.json&query=%24.dependencies.sails&label=Sails&logo=sailsdotjs)](https://sailsjs.com) -[![React version](https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fraw.githubusercontent.com%2Fneonexus%2Fsails-react-bootstrap-webpack%2Fv5.0.0%2Fpackage.json&query=%24.devDependencies.react&label=React&logo=react)](https://react.dev) -[![Bootstrap version](https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fraw.githubusercontent.com%2Fneonexus%2Fsails-react-bootstrap-webpack%2Fv5.0.0%2Fpackage.json&query=%24.devDependencies.bootstrap&label=Bootstrap&logo=bootstrap&logoColor=white)](https://getbootstrap.com) -[![Webpack version](https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fraw.githubusercontent.com%2Fneonexus%2Fsails-react-bootstrap-webpack%2Fv5.0.0%2Fpackage.json&query=%24.devDependencies.webpack&label=Webpack&logo=webpack)](https://webpack.js.org) +[![Sails version](https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fraw.githubusercontent.com%2Fneonexus%2Fsails-react-bootstrap-webpack%2Fv5.1.0%2Fpackage.json&query=%24.dependencies.sails&label=Sails&logo=sailsdotjs)](https://sailsjs.com) +[![React version](https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fraw.githubusercontent.com%2Fneonexus%2Fsails-react-bootstrap-webpack%2Fv5.1.0%2Fpackage.json&query=%24.devDependencies.react&label=React&logo=react)](https://react.dev) +[![Bootstrap version](https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fraw.githubusercontent.com%2Fneonexus%2Fsails-react-bootstrap-webpack%2Fv5.1.0%2Fpackage.json&query=%24.devDependencies.bootstrap&label=Bootstrap&logo=bootstrap&logoColor=white)](https://getbootstrap.com) +[![Webpack version](https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fraw.githubusercontent.com%2Fneonexus%2Fsails-react-bootstrap-webpack%2Fv5.1.0%2Fpackage.json&query=%24.devDependencies.webpack&label=Webpack&logo=webpack)](https://webpack.js.org) [![Discord Server](https://img.shields.io/badge/Discord_server-silver?logo=discord)](http://discord.gg/Y5K73E84Tc) -This is an easily-modifiable, opinionated, [Sails v1](https://sailsjs.com) base application, using [Webpack](https://webpack.js.org) to handle [Bootstrap](https://getbootstrap.com) -(using [SASS](https://sass-lang.com)) and [React](https://react.dev) builds. It is designed such that, one can build multiple React frontends (an admin panel, and a customer site maybe), that use the -same API backend. This allows developers to easily share React components across different frontends / applications. Also, because the backend and frontend are in the same repo (and the frontend is -compiled before it is handed to the end user), they can share [NPM](http://npmjs.com) libraries, like [Moment.js](https://momentjs.com) +Kick-start your project with this startup in a box. ## Table of Contents @@ -449,7 +446,7 @@ It may also be a good idea to consider using something like [Nginx](https://ngin ## Schema Validation and Enforcement -This repo is set up for `MySQL` (can LIKELY be used with most if not all other SQL-based datastores [I have not tried]). If you plan to use a different datastore, you will likely want to disable this +This feature is designed for `MySQL` (can LIKELY be used with most if not all other SQL-based datastores [I have not tried]). If you plan to use a different datastore, you will likely want to disable this feature. Inside [`config/bootstrap.js`](config/bootstrap.js) is a bit of logic (**HEAVILY ROOTED IN NATIVE `MySQL` QUERIES**), which validates column types in the `PRODUCTION` database ( diff --git a/api/controllers/admin/edit-user.js b/api/controllers/admin/edit-user.js index f7fa261..6ce7080 100644 --- a/api/controllers/admin/edit-user.js +++ b/api/controllers/admin/edit-user.js @@ -45,13 +45,13 @@ module.exports = { setPassword: { type: 'boolean', - defaultsTo: true + defaultsTo: false } }, exits: { ok: { - responseType: 'created' + responseType: 'ok' }, badRequest: { responseType: 'badRequest' diff --git a/api/controllers/admin/reactivate-user.js b/api/controllers/admin/reactivate-user.js new file mode 100644 index 0000000..95da10c --- /dev/null +++ b/api/controllers/admin/reactivate-user.js @@ -0,0 +1,47 @@ +module.exports = { + friendlyName: 'Reactivate User', + + description: 'Reactivate a soft-deleted user.', + + inputs: { + id: { + type: 'string', + required: true, + isUUID: true + } + }, + + exits: { + ok: { + responseType: 'ok' + }, + badRequest: { + responseType: 'badRequest' + }, + serverError: { + responseType: 'serverError' + } + }, + + fn: async (inputs, exits) => { + const foundUser = await sails.models.user.findOne({id: inputs.id}); + + if (!foundUser) { + return exits.badRequest('There is no user with that ID.'); + } + + if (!foundUser.deletedAt) { + return exits.badRequest('User is already active.'); + } + + const activeUser = await sails.models.user.findOne({email: foundUser.email, deletedAt: null}); + + if (activeUser) { + return exits.badRequest('There is already an active user with the email address ' + activeUser.email); + } + + await sails.models.user.update({id: inputs.id}).set({deletedAt: null}); + + return exits.ok(); + } +}; diff --git a/api/models/User.js b/api/models/User.js index cc7e427..c30a903 100644 --- a/api/models/User.js +++ b/api/models/User.js @@ -166,23 +166,23 @@ module.exports = { }, beforeUpdate: async function(user, next) { - if (user.email && user.email !== '') { + if (user.email && user.email.trim().length) { const email = user.email.toLowerCase().trim(); user.email = email; user.avatar = getGravatarUrl(email); } - if (user.firstName && user.firstName !== '') { - user.firstName = forceUppercaseOnFirst(user.firstName); + if (user.firstName && user.firstName.trim().length) { + user.firstName = forceUppercaseOnFirst(user.firstName.trim()); } - if (user.lastName && user.lastName !== '') { - user.lastName = forceUppercaseOnFirst(user.lastName); + if (user.lastName && user.lastName.trim().length) { + user.lastName = forceUppercaseOnFirst(user.lastName.trim()); } - if (user.password && user.password !== '') { - user.password = await updatePassword(user.password); + if (user.password && user.password !== '' && user.password.length > 7) { + user.password = await updatePassword(user.password.trim()); } return next(); diff --git a/assets/src/Admin/AdminRouter.jsx b/assets/src/Admin/AdminRouter.jsx index a844c9d..2799681 100644 --- a/assets/src/Admin/AdminRouter.jsx +++ b/assets/src/Admin/AdminRouter.jsx @@ -1,4 +1,4 @@ -import { Component, StrictMode, Suspense, lazy } from 'react'; +import {Component, StrictMode, Suspense, lazy} from 'react'; import PropTypes from 'prop-types'; import '../../styles/admin/admin.scss'; import { @@ -27,7 +27,10 @@ function RenderOrLogin(props) { if (props.api) { return ( - + <> + alert('logout')} /> + + ); } diff --git a/assets/src/Admin/NavBar.jsx b/assets/src/Admin/NavBar.jsx index bae7026..2bd09c3 100644 --- a/assets/src/Admin/NavBar.jsx +++ b/assets/src/Admin/NavBar.jsx @@ -93,11 +93,17 @@ function NavBar(props) { ? Users : null } - 404 Page - - Profile - Security - + { + (user.isLoggedIn) + ? <> + 404 Page + + Profile + Security + + + : null + } { @@ -109,7 +115,7 @@ function NavBar(props) { : null } - } id="light-or-dark-toggle" className="ms-3 right-align-menu"> + } id="light-or-dark-toggle" className="ms-3 right-align-menu"> Light Dark Auto diff --git a/assets/src/Admin/Settings/SecuritySection.jsx b/assets/src/Admin/Settings/SecuritySection.jsx index 1b39086..0cbaaaa 100644 --- a/assets/src/Admin/Settings/SecuritySection.jsx +++ b/assets/src/Admin/Settings/SecuritySection.jsx @@ -27,16 +27,16 @@ function SecuritySection(props) {

Security Settings

-

Change Password

+

Change Password

Always a good idea to rotate your passwords.

- +
-

+

2-Factor Authentication { (user.info._isOTPEnabled) @@ -46,7 +46,7 @@ function SecuritySection(props) {

{ (user.info._isOTPEnabled) - ?

Nice! Your account security is even stronger, because 2FA is enabled.

+ ?

Nice! Your account security is even stronger, because 2FA is enabled.

:

It is highly recommended to enable 2FA to increase security with your account.

} @@ -56,7 +56,7 @@ function SecuritySection(props) { // : null } - + { (user.info._isOTPEnabled) ? diff --git a/assets/src/Admin/Users/Users.jsx b/assets/src/Admin/Users/Users.jsx index 6ab6ebb..4465775 100644 --- a/assets/src/Admin/Users/Users.jsx +++ b/assets/src/Admin/Users/Users.jsx @@ -95,8 +95,7 @@ class Users extends Component { handleDeleteUser(after) { this.props.api.del({ - url: '/user', - body: {id: this.state.currentDeleteUser.id} + url: '/user/' + this.state.currentDeleteUser.id, }, (resp) => { this.setState({showDeleteModal: false}, () => { this.getUsers(this.state.currentPage); diff --git a/config/autoreload.js b/config/autoreload.js index c114c4a..89c055b 100644 --- a/config/autoreload.js +++ b/config/autoreload.js @@ -7,28 +7,22 @@ * For more info, see: https://www.npmjs.com/package/sails-hook-autoreload */ -module.exports = { - autoreload: { - active: true, +module.exports.autoreload = { + active: true, - dirs: [ - 'api/controllers', - 'api/helpers', - 'api/hooks', - 'api/models', - 'api/policies', - 'api/responses', - 'config' - ], + dirs: [ + 'api/controllers', + 'api/helpers', + 'api/hooks', + 'api/models', + 'api/policies', + 'api/responses', + 'config' + ], - ignored: [ - '**.md' - ], + ignored: [ + '**.md' + ], - overrideMigrateSetting: false - }, - - models: { - archiveModelIdentity: false - } + overrideMigrateSetting: false }; diff --git a/config/local.js.sample b/config/local.js.sample index 935031e..0eccbb2 100644 --- a/config/local.js.sample +++ b/config/local.js.sample @@ -3,7 +3,7 @@ * * DON'T DELETE ME!!! * The setup.js script requires a `local.js.sample` file to work. - * Additionally, if you change values here, the setup script will need to be modified to match. + * Additionally, if you change anything here, the setup script will likely need to be modified to match. */ diff --git a/config/models.js b/config/models.js index 4bbeb0e..04b3d95 100644 --- a/config/models.js +++ b/config/models.js @@ -92,7 +92,7 @@ module.exports.models = { ******************************************************************************/ dataEncryptionKeys: { - // Run this to generate a new key: `npm run generate:dek` + // Run this to generate a new key: `npm run generate:dek` OR `npm run setup` default: '{{DEK here}}' // NEVER STORE THIS FOR PRODUCTION PURPOSES!!! }, @@ -143,4 +143,13 @@ module.exports.models = { *********************************************************************************/ enforceForeignKeys: true, + + /********************************************************************************* + * * + * Disable Sails' built-in archive system by default. It tends to mess with * + * other things, like `sails-hook-autoreload`. * + * * + *********************************************************************************/ + + archiveModelIdentity: false }; diff --git a/config/policies.js b/config/policies.js index f1bf895..2fb1580 100644 --- a/config/policies.js +++ b/config/policies.js @@ -9,14 +9,17 @@ */ module.exports.policies = { + // Default to "allow" if not defined below. '*': true, + // ALl the functions found in /controllers/admin/* AdminController: { '*': ['isLoggedIn', 'isAdmin'] }, + // The functions in /controllers/common/* CommonController: { - '*': 'isLoggedIn', - 'login': true, + '*': 'isLoggedIn', // Default require the user is authenticated + 'login': true, // Allow non-authenticated users access. } }; diff --git a/config/routes.js b/config/routes.js index 0175a81..df09063 100644 --- a/config/routes.js +++ b/config/routes.js @@ -57,7 +57,9 @@ module.exports.routes = { 'GET /api/v1/users': 'admin/get-users', 'GET /api/v1/users/deleted': 'admin/get-deleted-users', 'POST /api/v1/user': 'admin/create-user', - 'DELETE /api/v1/user': 'admin/delete-user', + 'PUT /api/v1/user/:id': 'admin/edit-user', + 'DELETE /api/v1/user/:id': 'admin/delete-user', + 'PUT /api/v1/user/:id/reactivate': 'admin/reactivate-user', 'POST /api/v1/token': 'admin/create-api-token', 'POST /api/v1/login': 'common/login', diff --git a/config/security.js b/config/security.js index f93e52a..b68149f 100644 --- a/config/security.js +++ b/config/security.js @@ -64,7 +64,7 @@ module.exports.security = { * * * When enabled, sails.helpers.isPasswordValid() will check with the * * PwnedPasswords.com API (v3), using a k-Anonymity model, preventing * - * third parties, including the PwnedPasswords.com API from knowing * + * third parties, including the PwnedPasswords.com API, from knowing * * which password we are searching for. * * * * See this for more details: * diff --git a/ngrok.js b/ngrok.js index b1c0702..66555d1 100755 --- a/ngrok.js +++ b/ngrok.js @@ -10,197 +10,237 @@ let ngrok; try { ngrok = require('@ngrok/ngrok'); + + return afterChecks(); } catch { - console.log(''); - console.log('In order to run this script, you must install `Ngrok`:'); - console.log(''); - console.log('npm i @ngrok/ngrok --save-dev'); - console.log(''); + try { + const prompts = require('prompts'); + const { spawn } = require('child_process'); + + (async function() { + const answer = await prompts({ + type: 'confirm', + name: 'installNgrok', + message: 'Ngrok is NOT installed. Would you like to install now?', + initial: false + }); - return process.exit(1); -} + if (answer.installNgrok) { + function installNgrok() { + return new Promise((resolve, reject) => { + const ngrokInstall = spawn('npm', ['install', '@ngrok/ngrok@v0.9.1', '--save-dev', '--save-exact'], {cwd: __dirname, stdio: 'inherit'}); -const sails = require('sails'); -const rc = require('sails/accessible/rc'); -const {spawn} = require('child_process'); -const path = require('path'); -const moduleLoader = require('sails/lib/hooks/moduleloader'); -const merge = require('lodash/merge'); - -// Load configuration the way Sails would. -moduleLoader({ - config: { - environment: process.env.NODE_ENV || 'development', - paths: { - config: path.join(__dirname, 'config') - } - } -}).loadUserConfig((err, config) => { - if (err) { - console.error(''); - console.error('There was an issue loading user configuration:'); - console.error(''); - console.error(err); - console.error(''); + ngrokInstall.on('error', (err) => { + return reject(err); + }); + + ngrokInstall.on('close', (code) => { + if (code === 0) { + return resolve(); + } + + return reject('npm install failed with code: ' + code); + }); + }); + } + + await installNgrok(); + + ngrok = require('@ngrok/ngrok'); + + return afterChecks(); + } + })(); + } catch { + console.error('Looks like you need to `npm install`'); return process.exit(1); } +} - // Set Ngrok defaults. These can be overwritten in `config/ngrok.js` or `config/local.js`. - // Basically, this is just a safety net, should one delete the `config/ngrok.js` file. - config = merge({ - ngrok: { - auth: process.env.NGROK_BASIC || undefined, - token: process.env.NGROK_AUTHTOKEN || process.env.NGROK_TOKEN || undefined, - buildAssets: true, - domain: process.env.NGROK_DOMAIN || undefined, - region: process.env.NGROK_REGION || undefined, - port: process.env.PORT || 4242 - }, - ...config - }); +function afterChecks() { + const sails = require('sails'); + const rc = require('sails/accessible/rc'); + const {spawn} = require('child_process'); + const path = require('path'); + const moduleLoader = require('sails/lib/hooks/moduleloader'); + const merge = require('lodash/merge'); + + // Load configuration the way Sails would. + moduleLoader({ + config: { + environment: process.env.NODE_ENV || 'development', + paths: { + config: path.join(__dirname, 'config') + } + } + }).loadUserConfig((err, config) => { + if (err) { + console.error(''); + console.error('There was an issue loading user configuration:'); + console.error(''); + console.error(err); + console.error(''); - // Boolean coercion - switch (config.ngrok.buildAssets) { - case true: - case 'true': - case '1': - case 1: - config.ngrok.buildAssets = true; - break; - case false: - case 'false': - case '0': - case 0: - config.ngrok.buildAssets = false; - break; - default: - console.error('Invalid value set for `buildAssets`. Expected boolean-like, got: ' + config.ngrok.buildAssets); return process.exit(1); - } - - // Read our console config flags. - for (let i = 2; i < process.argv.length; ++i) { - const thisFlag = process.argv[i].toLowerCase(); - - if (thisFlag === 'nobuild') { - config.ngrok.buildAssets = false; - } else if (thisFlag === 'build') { - config.ngrok.buildAssets = true; - } else if (thisFlag.startsWith('auth=')) { - config.ngrok.auth = process.argv[i].substring(5); // this.flag is lower cased; have to use the raw input - } else if (thisFlag.startsWith('domain=')) { - config.ngrok.domain = thisFlag.substring(7); - } else if (thisFlag.startsWith('port=')) { - config.ngrok.port = thisFlag.substring(5); - } else if (thisFlag.startsWith('region=')) { - config.ngrok.region = thisFlag.substring(7); - } else if (thisFlag.startsWith('token=')) { - config.ngrok.token = process.argv[i].substring(6); // this.flag is lower cased; have to use the raw input } - } - ngrok.forward({ - addr: config.ngrok.port, // This is actually the port to we'll use for Sails. Ngrok will handle its own ports. - authtoken: config.ngrok.token, - basic_auth: config.ngrok.auth, // eslint-disable-line - domain: config.ngrok.domain, - region: config.ngrok.region, - schemes: ['HTTPS'] - }).then((listener) => { - let origins; - const ngrokUrl = listener.url(); - - // Smaller helper function, to output the Ngrok URLs. - function sendUrls() { - console.log(''); - console.log('Ngrok URL: ' + ngrokUrl); - // console.log('Ngrok Dashboard: https://dashboard.ngrok.com'); - console.log(''); + // Set Ngrok defaults. These can be overwritten in `config/ngrok.js` or `config/local.js`. + // Basically, this is just a safety net, should one delete the `config/ngrok.js` file. + config = merge({ + ngrok: { + auth: process.env.NGROK_BASIC || undefined, + token: process.env.NGROK_AUTHTOKEN || process.env.NGROK_TOKEN || undefined, + buildAssets: true, + domain: process.env.NGROK_DOMAIN || undefined, + region: process.env.NGROK_REGION || undefined, + port: process.env.PORT || 4242 + }, + ...config + }); + + // Boolean coercion + switch (config.ngrok.buildAssets) { + case true: + case 'true': + case '1': + case 1: + config.ngrok.buildAssets = true; + break; + case false: + case 'false': + case '0': + case 0: + config.ngrok.buildAssets = false; + break; + default: + console.error('Invalid value set for `buildAssets`. Expected boolean-like, got: ' + config.ngrok.buildAssets); + return process.exit(1); } - // Build our assets in the background. - if (config.ngrok.buildAssets) { - const assetBuilderProcess = spawn('npm', ['run', 'build'], {env: {...process.env, BASE_URL: ngrokUrl}}); + // Read our console config flags. + for (let i = 2; i < process.argv.length; ++i) { + const thisFlag = process.argv[i].toLowerCase(); + + if (thisFlag === 'nobuild') { + config.ngrok.buildAssets = false; + } else if (thisFlag === 'build') { + config.ngrok.buildAssets = true; + } else if (thisFlag.startsWith('auth=')) { + config.ngrok.auth = process.argv[i].substring(5); // this.flag is lower cased; have to use the raw input + } else if (thisFlag.startsWith('domain=')) { + config.ngrok.domain = thisFlag.substring(7); + } else if (thisFlag.startsWith('port=')) { + config.ngrok.port = thisFlag.substring(5); + } else if (thisFlag.startsWith('region=')) { + config.ngrok.region = thisFlag.substring(7); + } else if (thisFlag.startsWith('token=')) { + config.ngrok.token = process.argv[i].substring(6); // this.flag is lower cased; have to use the raw input + } + } - assetBuilderProcess.stderr.on('data', (data) => { - console.log('Error:'); - console.error(data); - }); + ngrok.forward({ + addr: config.ngrok.port, // This is actually the port we'll use for Sails. Ngrok will handle its own ports. + authtoken: config.ngrok.token, + basic_auth: config.ngrok.auth, // eslint-disable-line + domain: config.ngrok.domain, + region: config.ngrok.region, + schemes: ['HTTPS'] + }).then((listener) => { + let origins; + const ngrokUrl = listener.url(); + + // Smaller helper function, to output the Ngrok URLs. + function sendUrls() { + console.log(''); + console.log('Ngrok URL: ' + ngrokUrl); + // console.log('Ngrok Dashboard: https://dashboard.ngrok.com'); + console.log(''); + } - assetBuilderProcess.on('exit', (code, signal) => { - if (code === 0) { - console.log('Assets successfully built!'); - sendUrls(); - } else { - console.error('An error occurred while trying to build assets. Signal: ' + signal); + // Build our assets in the background. + if (config.ngrok.buildAssets) { + const assetBuilderProcess = spawn('npm', ['run', 'build'], {env: {...process.env, BASE_URL: ngrokUrl}}); - process.exit(1); - } - }); + assetBuilderProcess.stderr.on('data', (data) => { + console.log('Error:'); + console.error(data); + }); - console.log(''); - console.log('Assets are being built. Starting API...'); - console.log(''); - } + assetBuilderProcess.on('exit', (code, signal) => { + if (code === 0) { + console.log('Assets successfully built!'); + sendUrls(); + } else { + console.error('An error occurred while trying to build assets. Signal: ' + signal); - // Add the Ngrok URL to our allowed origins. - if (config.security && config.security.cors && config.security.cors.allowOrigins) { - origins = [...config.security.cors.allowOrigins]; + process.exit(1); + } + }); - if (!config.security.cors.allowOrigins.includes(ngrokUrl)) { - origins.push(ngrokUrl); + console.log(''); + console.log('Assets are being built. Starting API...'); + console.log(''); } - } else { - origins = [ngrokUrl]; - } - // Small safety trigger, to help prevent use of `sails lift`, as that circumvents our custom error handlers / configuration overrides. - process.env.NOT_FROM_SAILS_LIFT = 'true'; // Can't use booleans with environment variables. That's just silly! - - // Start Sails. - sails.lift({ - ...rc('sails'), - baseUrl: ngrokUrl, - port: config.ngrok.port, - security: { - cors: { - allowOrigins: origins + // Add the Ngrok URL to our allowed origins. + if (config.security && config.security.cors && config.security.cors.allowOrigins) { + origins = [...config.security.cors.allowOrigins]; + + if (!config.security.cors.allowOrigins.includes(ngrokUrl)) { + origins.push(ngrokUrl); } + } else { + origins = [ngrokUrl]; } - }, (err) => { - if (err) { - switch (err.code) { - case 'E_INVALID_DATA_ENCRYPTION_KEYS': - console.error( - '\nSails is complaining about bad DEK\'s (Data Encryption Keys).' - + '\nThis is likely caused by running on PRODUCTION without a DATA_ENCRYPTION_KEY environment variable set.' - + '\n\nThe DEK ID that is being reported as invalid: ' + err.dekId - + '\n\nTo generate a new DEK: npm run generate:dek\n' - ); - break; - default: - console.error(err); - break; - } - return process.exit(1); - } + // Small safety trigger, to help prevent use of `sails lift`, as that circumvents our custom error handlers / configuration overrides. + process.env.NOT_FROM_SAILS_LIFT = 'true'; // Can't use booleans with environment variables. That's just silly! + + // Start Sails. + sails.lift({ + ...rc('sails'), + baseUrl: ngrokUrl, + port: config.ngrok.port, + security: { + cors: { + allowOrigins: origins + } + } + }, (err) => { + if (err) { + switch (err.code) { + case 'E_INVALID_DATA_ENCRYPTION_KEYS': + console.error( + '\nSails is complaining about bad DEK\'s (Data Encryption Keys).' + + '\nThis is likely caused by running on PRODUCTION without a DATA_ENCRYPTION_KEY environment variable set.' + + '\n\nThe DEK ID that is being reported as invalid: ' + err.dekId + + '\n\nTo generate a new DEK: npm run generate:dek\n' + ); + break; + default: + console.error(err); + break; + } + + return process.exit(1); + } - // Sails tends to be faster at startup than asset building... - // Assume we are still waiting for assets (which will output URLs when finished)... - if (config.ngrok.buildAssets) { - console.log(''); - console.log('Please wait for assets...'); - } else { - sendUrls(); - } + // Sails tends to be faster at startup than asset building... + // Assume we are still waiting for assets (which will output URLs when finished)... + if (config.ngrok.buildAssets) { + console.log(''); + console.log('Please wait for assets...'); + } else { + sendUrls(); + } + }); + }).catch((e) => { + console.log(''); + console.log('There was an error starting the Ngrok tunnel. Here is the error:'); + console.log(''); + console.log(e.message); + console.log(''); }); - }).catch((e) => { - console.log(''); - console.log('There was an error starting the Ngrok tunnel. Here is the error:'); - console.log(''); - console.log(e.message); - console.log(''); }); -}); +} diff --git a/package-lock.json b/package-lock.json index 80079fa..fb19804 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "sails-react-bootstrap-webpack", - "version": "5.0.0", + "version": "5.1.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "sails-react-bootstrap-webpack", - "version": "5.0.0", + "version": "5.1.0", "funding": [ { "type": "github", @@ -18,10 +18,10 @@ "csrf": "3.1.0", "json-stringify-safe": "5.0.1", "lodash": "4.17.21", - "moment-timezone": "0.5.43", + "moment-timezone": "0.5.44", "otplib": "12.0.1", "qrcode": "1.5.3", - "sails": "1.5.8", + "sails": "1.5.9", "sails-hook-orm": "4.0.2", "sails-hook-sockets": "3.0.0", "sails-mysql": "3.0.1", @@ -29,28 +29,28 @@ "superagent": "8.1.2" }, "devDependencies": { - "@babel/core": "7.23.5", + "@babel/core": "7.23.7", "@babel/eslint-parser": "7.23.3", - "@babel/preset-env": "7.23.5", + "@babel/preset-env": "7.23.7", "@babel/preset-react": "7.23.3", "@popperjs/core": "2.11.8", "babel-loader": "9.1.3", "bootstrap": "5.3.2", - "bootstrap-icons": "1.11.2", + "bootstrap-icons": "1.11.3", "chai": "4.3.10", "chai-spies": "1.1.0", "chai-uuid": "1.0.6", - "codecov": "^3.8.3", + "codecov": "3.8.3", "copy-webpack-plugin": "11.0.0", - "core-js": "3.33.3", + "core-js": "3.35.0", "css-loader": "6.8.1", - "eslint": "8.55.0", + "eslint": "8.56.0", "eslint-plugin-react": "7.33.2", - "favicons": "7.1.4", + "favicons": "7.1.5", "favicons-webpack-plugin": "6.0.1", "file-loader": "6.2.0", - "fixted": "4.2.3", - "html-webpack-plugin": "5.5.3", + "fixted": "4.2.4", + "html-webpack-plugin": "5.6.0", "mini-css-extract-plugin": "2.7.6", "mocha": "10.2.0", "npm-run-all": "4.1.5", @@ -58,12 +58,12 @@ "prompts": "2.4.2", "prop-types": "15.8.1", "react": "18.2.0", - "react-bootstrap": "v2.9.1", + "react-bootstrap": "2.9.2", "react-dom": "18.2.0", - "react-router-dom": "6.20.1", + "react-router-dom": "6.21.1", "readline-sync": "1.4.10", - "sass": "1.69.5", - "sass-loader": "13.3.2", + "sass": "1.69.7", + "sass-loader": "13.3.3", "style-loader": "3.3.3", "supertest": "6.3.3", "webpack": "5.89.0", @@ -120,21 +120,21 @@ } }, "node_modules/@babel/core": { - "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.23.5.tgz", - "integrity": "sha512-Cwc2XjUrG4ilcfOw4wBAK+enbdgwAcAJCfGUItPBKR7Mjw4aEfAFYrLxeRp4jWgtNIKn3n2AlBOfwwafl+42/g==", + "version": "7.23.7", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.23.7.tgz", + "integrity": "sha512-+UpDgowcmqe36d4NwqvKsyPMlOLNGMsfMmQ5WGCu+siCe3t3dfe9njrzGfdN4qq+bcNUt0+Vw6haRxBOycs4dw==", "dev": true, "dependencies": { "@ampproject/remapping": "^2.2.0", "@babel/code-frame": "^7.23.5", - "@babel/generator": "^7.23.5", - "@babel/helper-compilation-targets": "^7.22.15", + "@babel/generator": "^7.23.6", + "@babel/helper-compilation-targets": "^7.23.6", "@babel/helper-module-transforms": "^7.23.3", - "@babel/helpers": "^7.23.5", - "@babel/parser": "^7.23.5", + "@babel/helpers": "^7.23.7", + "@babel/parser": "^7.23.6", "@babel/template": "^7.22.15", - "@babel/traverse": "^7.23.5", - "@babel/types": "^7.23.5", + "@babel/traverse": "^7.23.7", + "@babel/types": "^7.23.6", "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", @@ -174,12 +174,12 @@ } }, "node_modules/@babel/generator": { - "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.5.tgz", - "integrity": "sha512-BPssCHrBD+0YrxviOa3QzpqwhNIXKEtOa2jQrm4FlmkC2apYgRnQcmPWiGZDlGxiNtltnUFolMe8497Esry+jA==", + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.6.tgz", + "integrity": "sha512-qrSfCYxYQB5owCmGLbl8XRpX1ytXlpueOb0N0UmQwA073KZxejgQTzAmJezxvpwQD9uGtK2shHdi55QT+MbjIw==", "dev": true, "dependencies": { - "@babel/types": "^7.23.5", + "@babel/types": "^7.23.6", "@jridgewell/gen-mapping": "^0.3.2", "@jridgewell/trace-mapping": "^0.3.17", "jsesc": "^2.5.1" @@ -227,14 +227,14 @@ } }, "node_modules/@babel/helper-compilation-targets": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.15.tgz", - "integrity": "sha512-y6EEzULok0Qvz8yyLkCvVX+02ic+By2UdOhylwUOvOn9dvYc9mKICJuuU1n1XBI02YWsNsnrY1kc6DVbjcXbtw==", + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.23.6.tgz", + "integrity": "sha512-9JB548GZoQVmzrFgp8o7KxdgkTGm6xs9DW0o/Pim72UDjzr5ObUQ6ZzYPqA+g9OTS2bBQoctLJrky0RDCAWRgQ==", "dev": true, "dependencies": { - "@babel/compat-data": "^7.22.9", - "@babel/helper-validator-option": "^7.22.15", - "browserslist": "^4.21.9", + "@babel/compat-data": "^7.23.5", + "@babel/helper-validator-option": "^7.23.5", + "browserslist": "^4.22.2", "lru-cache": "^5.1.1", "semver": "^6.3.1" }, @@ -283,9 +283,9 @@ } }, "node_modules/@babel/helper-define-polyfill-provider": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.4.3.tgz", - "integrity": "sha512-WBrLmuPP47n7PNwsZ57pqam6G/RGo1vw/87b0Blc53tZNGZ4x7YvZ6HgQe2vo1W/FR20OgjeZuGXzudPiXHFug==", + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.4.4.tgz", + "integrity": "sha512-QcJMILQCu2jm5TFPGA3lCpJJTeEP+mqeXooG/NZbg/h5FTFi6V0+99ahlRsW8/kRLyb24LZVCCiclDedhLKcBA==", "dev": true, "dependencies": { "@babel/helper-compilation-targets": "^7.22.6", @@ -508,14 +508,14 @@ } }, "node_modules/@babel/helpers": { - "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.23.5.tgz", - "integrity": "sha512-oO7us8FzTEsG3U6ag9MfdF1iA/7Z6dz+MtFhifZk8C8o453rGJFFWUP1t+ULM9TUIAzC9uxXEiXjOiVMyd7QPg==", + "version": "7.23.7", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.23.7.tgz", + "integrity": "sha512-6AMnjCoC8wjqBzDHkuqpa7jAKwvMo4dC+lr/TFBz+ucfulO1XMpDnwWPGBNwClOKZ8h6xn5N81W/R5OrcKtCbQ==", "dev": true, "dependencies": { "@babel/template": "^7.22.15", - "@babel/traverse": "^7.23.5", - "@babel/types": "^7.23.5" + "@babel/traverse": "^7.23.7", + "@babel/types": "^7.23.6" }, "engines": { "node": ">=6.9.0" @@ -536,9 +536,9 @@ } }, "node_modules/@babel/parser": { - "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.5.tgz", - "integrity": "sha512-hOOqoiNXrmGdFbhgCzu6GiURxUgM27Xwd/aPuu8RfHEZPBzL1Z54okAHAQjXfcQNwvrlkAmAp4SlRTZ45vlthQ==", + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.6.tgz", + "integrity": "sha512-Z2uID7YJ7oNvAI20O9X0bblw7Qqs8Q2hFy0R9tAfnfLkp5MW0UH9eUvnDSnFwKZ0AvgS1ucqR4KzvVHgnke1VQ==", "dev": true, "bin": { "parser": "bin/babel-parser.js" @@ -580,9 +580,9 @@ } }, "node_modules/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.23.3.tgz", - "integrity": "sha512-XaJak1qcityzrX0/IU5nKHb34VaibwP3saKqG6a/tppelgllOH13LUann4ZCIBcVOeE6H18K4Vx9QKkVww3z/w==", + "version": "7.23.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.23.7.tgz", + "integrity": "sha512-LlRT7HgaifEpQA1ZgLVOIJZZFVPWN5iReq/7/JixwBtwcoeVGDBD53ZV28rrsLYOZs1Y/EHhA8N/Z6aazHR8cw==", "dev": true, "dependencies": { "@babel/helper-environment-visitor": "^7.22.20", @@ -873,9 +873,9 @@ } }, "node_modules/@babel/plugin-transform-async-generator-functions": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.23.4.tgz", - "integrity": "sha512-efdkfPhHYTtn0G6n2ddrESE91fgXxjlqLsnUtPWnJs4a4mZIbUaK7ffqKIIUKXSHwcDvaCVX6GXkaJJFqtX7jw==", + "version": "7.23.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.23.7.tgz", + "integrity": "sha512-PdxEpL71bJp1byMG0va5gwQcXHxuEYC/BgI/e88mGTtohbZN28O5Yit0Plkkm/dBzCF/BxmbNcses1RH1T+urA==", "dev": true, "dependencies": { "@babel/helper-environment-visitor": "^7.22.20", @@ -1104,12 +1104,13 @@ } }, "node_modules/@babel/plugin-transform-for-of": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.23.3.tgz", - "integrity": "sha512-X8jSm8X1CMwxmK878qsUGJRmbysKNbdpTv/O1/v0LuY/ZkZrng5WYiekYSdg9m09OTmDDUWeEDsTE+17WYbAZw==", + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.23.6.tgz", + "integrity": "sha512-aYH4ytZ0qSuBbpfhuofbg/e96oQ7U2w1Aw/UQmKT+1l39uEhUPoFS3fHevDc1G0OvewyDudfMKY1OulczHzWIw==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5" }, "engines": { "node": ">=6.9.0" @@ -1695,18 +1696,18 @@ } }, "node_modules/@babel/preset-env": { - "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.23.5.tgz", - "integrity": "sha512-0d/uxVD6tFGWXGDSfyMD1p2otoaKmu6+GD+NfAx0tMaH+dxORnp7T9TaVQ6mKyya7iBtCIVxHjWT7MuzzM9z+A==", + "version": "7.23.7", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.23.7.tgz", + "integrity": "sha512-SY27X/GtTz/L4UryMNJ6p4fH4nsgWbz84y9FE0bQeWJP6O5BhgVCt53CotQKHCOeXJel8VyhlhujhlltKms/CA==", "dev": true, "dependencies": { "@babel/compat-data": "^7.23.5", - "@babel/helper-compilation-targets": "^7.22.15", + "@babel/helper-compilation-targets": "^7.23.6", "@babel/helper-plugin-utils": "^7.22.5", "@babel/helper-validator-option": "^7.23.5", "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.23.3", "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.23.3", - "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.23.3", + "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.23.7", "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2", "@babel/plugin-syntax-async-generators": "^7.8.4", "@babel/plugin-syntax-class-properties": "^7.12.13", @@ -1727,7 +1728,7 @@ "@babel/plugin-syntax-top-level-await": "^7.14.5", "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6", "@babel/plugin-transform-arrow-functions": "^7.23.3", - "@babel/plugin-transform-async-generator-functions": "^7.23.4", + "@babel/plugin-transform-async-generator-functions": "^7.23.7", "@babel/plugin-transform-async-to-generator": "^7.23.3", "@babel/plugin-transform-block-scoped-functions": "^7.23.3", "@babel/plugin-transform-block-scoping": "^7.23.4", @@ -1741,7 +1742,7 @@ "@babel/plugin-transform-dynamic-import": "^7.23.4", "@babel/plugin-transform-exponentiation-operator": "^7.23.3", "@babel/plugin-transform-export-namespace-from": "^7.23.4", - "@babel/plugin-transform-for-of": "^7.23.3", + "@babel/plugin-transform-for-of": "^7.23.6", "@babel/plugin-transform-function-name": "^7.23.3", "@babel/plugin-transform-json-strings": "^7.23.4", "@babel/plugin-transform-literals": "^7.23.3", @@ -1775,9 +1776,9 @@ "@babel/plugin-transform-unicode-regex": "^7.23.3", "@babel/plugin-transform-unicode-sets-regex": "^7.23.3", "@babel/preset-modules": "0.1.6-no-external-plugins", - "babel-plugin-polyfill-corejs2": "^0.4.6", - "babel-plugin-polyfill-corejs3": "^0.8.5", - "babel-plugin-polyfill-regenerator": "^0.5.3", + "babel-plugin-polyfill-corejs2": "^0.4.7", + "babel-plugin-polyfill-corejs3": "^0.8.7", + "babel-plugin-polyfill-regenerator": "^0.5.4", "core-js-compat": "^3.31.0", "semver": "^6.3.1" }, @@ -1855,20 +1856,20 @@ } }, "node_modules/@babel/traverse": { - "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.5.tgz", - "integrity": "sha512-czx7Xy5a6sapWWRx61m1Ke1Ra4vczu1mCTtJam5zRTBOonfdJ+S/B6HYmGYu3fJtr8GGET3si6IhgWVBhJ/m8w==", + "version": "7.23.7", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.7.tgz", + "integrity": "sha512-tY3mM8rH9jM0YHFGyfC0/xf+SB5eKUu7HPj7/k3fpi9dAlsMc5YbQvDi0Sh2QTPXqMhyaAtzAr807TIyfQrmyg==", "dev": true, "dependencies": { "@babel/code-frame": "^7.23.5", - "@babel/generator": "^7.23.5", + "@babel/generator": "^7.23.6", "@babel/helper-environment-visitor": "^7.22.20", "@babel/helper-function-name": "^7.23.0", "@babel/helper-hoist-variables": "^7.22.5", "@babel/helper-split-export-declaration": "^7.22.6", - "@babel/parser": "^7.23.5", - "@babel/types": "^7.23.5", - "debug": "^4.1.0", + "@babel/parser": "^7.23.6", + "@babel/types": "^7.23.6", + "debug": "^4.3.1", "globals": "^11.1.0" }, "engines": { @@ -1876,9 +1877,9 @@ } }, "node_modules/@babel/types": { - "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.5.tgz", - "integrity": "sha512-ON5kSOJwVO6xXVRTvOI0eOnWe7VdUcIpsovGo9U/Br4Ie4UVFQTboO2cYnDhAGU6Fp+UxSiT+pMft0SMHfuq6w==", + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.6.tgz", + "integrity": "sha512-+uarb83brBzPKN38NX1MkB6vb6+mwvR6amUulqAE7ccQw1pEl+bCia9TbdG1lsnFP7lZySvUn37CHyXQdfTwzg==", "dev": true, "dependencies": { "@babel/helper-string-parser": "^7.23.4", @@ -1898,6 +1899,16 @@ "node": ">=10.0.0" } }, + "node_modules/@emnapi/runtime": { + "version": "0.44.0", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-0.44.0.tgz", + "integrity": "sha512-ZX/etZEZw8DR7zAB1eVQT40lNo0jeqpb6dCgOvctB6FIQ5PoXfMuNY8+ayQfu8tNQbAB8gQWSSJupR8NxeiZXw==", + "dev": true, + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, "node_modules/@eslint-community/eslint-utils": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.2.0.tgz", @@ -1982,9 +1993,9 @@ } }, "node_modules/@eslint/js": { - "version": "8.55.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.55.0.tgz", - "integrity": "sha512-qQfo2mxH5yVom1kacMtZZJFVdW+E70mqHMJvVg6WTLo+VBuQJ4TojZlfWBjK0ve5BdEeNAVxOsl/nvNMpJOaJA==", + "version": "8.56.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.56.0.tgz", + "integrity": "sha512-gMsVel9D7f2HLkBma9VbtzZRehRogVRfbr++f06nL2vnCGCNlzOD+/MUov/F4p8myyAHspEhVobgjpX64q5m6A==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -2023,6 +2034,456 @@ "integrity": "sha512-dvuCeX5fC9dXgJn9t+X5atfmgQAzUOWqS1254Gh0m6i8wKd10ebXkfNKiRK+1GWi/yTvvLDHpoxLr0xxxeslWw==", "dev": true }, + "node_modules/@img/sharp-darwin-arm64": { + "version": "0.33.1", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.33.1.tgz", + "integrity": "sha512-esr2BZ1x0bo+wl7Gx2hjssYhjrhUsD88VQulI0FrG8/otRQUOxLWHMBd1Y1qo2Gfg2KUvXNpT0ASnV9BzJCexw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "glibc": ">=2.26", + "node": "^18.17.0 || ^20.3.0 || >=21.0.0", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-darwin-arm64": "1.0.0" + } + }, + "node_modules/@img/sharp-darwin-x64": { + "version": "0.33.1", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.33.1.tgz", + "integrity": "sha512-YrnuB3bXuWdG+hJlXtq7C73lF8ampkhU3tMxg5Hh+E7ikxbUVOU9nlNtVTloDXz6pRHt2y2oKJq7DY/yt+UXYw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "glibc": ">=2.26", + "node": "^18.17.0 || ^20.3.0 || >=21.0.0", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-darwin-x64": "1.0.0" + } + }, + "node_modules/@img/sharp-libvips-darwin-arm64": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.0.0.tgz", + "integrity": "sha512-VzYd6OwnUR81sInf3alj1wiokY50DjsHz5bvfnsFpxs5tqQxESoHtJO6xyksDs3RIkyhMWq2FufXo6GNSU9BMw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "macos": ">=11", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-darwin-x64": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.0.0.tgz", + "integrity": "sha512-dD9OznTlHD6aovRswaPNEy8dKtSAmNo4++tO7uuR4o5VxbVAOoEQ1uSmN4iFAdQneTHws1lkTZeiXPrcCkh6IA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "macos": ">=10.13", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-arm": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.0.0.tgz", + "integrity": "sha512-VwgD2eEikDJUk09Mn9Dzi1OW2OJFRQK+XlBTkUNmAWPrtj8Ly0yq05DFgu1VCMx2/DqCGQVi5A1dM9hTmxf3uw==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "glibc": ">=2.28", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-arm64": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.0.0.tgz", + "integrity": "sha512-xTYThiqEZEZc0PRU90yVtM3KE7lw1bKdnDQ9kCTHWbqWyHOe4NpPOtMGy27YnN51q0J5dqRrvicfPbALIOeAZA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "glibc": ">=2.26", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-s390x": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.0.0.tgz", + "integrity": "sha512-o9E46WWBC6JsBlwU4QyU9578G77HBDT1NInd+aERfxeOPbk0qBZHgoDsQmA2v9TbqJRWzoBPx1aLOhprBMgPjw==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "glibc": ">=2.28", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-x64": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.0.0.tgz", + "integrity": "sha512-naldaJy4hSVhWBgEjfdBY85CAa4UO+W1nx6a1sWStHZ7EUfNiuBTTN2KUYT5dH1+p/xij1t2QSXfCiFJoC5S/Q==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "glibc": ">=2.26", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linuxmusl-arm64": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.0.0.tgz", + "integrity": "sha512-OdorplCyvmSAPsoJLldtLh3nLxRrkAAAOHsGWGDYfN0kh730gifK+UZb3dWORRa6EusNqCTjfXV4GxvgJ/nPDQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "musl": ">=1.2.2", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linuxmusl-x64": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.0.0.tgz", + "integrity": "sha512-FW8iK6rJrg+X2jKD0Ajhjv6y74lToIBEvkZhl42nZt563FfxkCYacrXZtd+q/sRQDypQLzY5WdLkVTbJoPyqNg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "musl": ">=1.2.2", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-linux-arm": { + "version": "0.33.1", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.33.1.tgz", + "integrity": "sha512-Ii4X1vnzzI4j0+cucsrYA5ctrzU9ciXERfJR633S2r39CiD8npqH2GMj63uFZRCFt3E687IenAdbwIpQOJ5BNA==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "glibc": ">=2.28", + "node": "^18.17.0 || ^20.3.0 || >=21.0.0", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-arm": "1.0.0" + } + }, + "node_modules/@img/sharp-linux-arm64": { + "version": "0.33.1", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.33.1.tgz", + "integrity": "sha512-59B5GRO2d5N3tIfeGHAbJps7cLpuWEQv/8ySd9109ohQ3kzyCACENkFVAnGPX00HwPTQcaBNF7HQYEfZyZUFfw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "glibc": ">=2.26", + "node": "^18.17.0 || ^20.3.0 || >=21.0.0", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-arm64": "1.0.0" + } + }, + "node_modules/@img/sharp-linux-s390x": { + "version": "0.33.1", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.33.1.tgz", + "integrity": "sha512-tRGrb2pHnFUXpOAj84orYNxHADBDIr0J7rrjwQrTNMQMWA4zy3StKmMvwsI7u3dEZcgwuMMooIIGWEWOjnmG8A==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "glibc": ">=2.28", + "node": "^18.17.0 || ^20.3.0 || >=21.0.0", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-s390x": "1.0.0" + } + }, + "node_modules/@img/sharp-linux-x64": { + "version": "0.33.1", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.33.1.tgz", + "integrity": "sha512-4y8osC0cAc1TRpy02yn5omBeloZZwS62fPZ0WUAYQiLhSFSpWJfY/gMrzKzLcHB9ulUV6ExFiu2elMaixKDbeg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "glibc": ">=2.26", + "node": "^18.17.0 || ^20.3.0 || >=21.0.0", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-x64": "1.0.0" + } + }, + "node_modules/@img/sharp-linuxmusl-arm64": { + "version": "0.33.1", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.33.1.tgz", + "integrity": "sha512-D3lV6clkqIKUizNS8K6pkuCKNGmWoKlBGh5p0sLO2jQERzbakhu4bVX1Gz+RS4vTZBprKlWaf+/Rdp3ni2jLfA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "musl": ">=1.2.2", + "node": "^18.17.0 || ^20.3.0 || >=21.0.0", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linuxmusl-arm64": "1.0.0" + } + }, + "node_modules/@img/sharp-linuxmusl-x64": { + "version": "0.33.1", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.33.1.tgz", + "integrity": "sha512-LOGKNu5w8uu1evVqUAUKTix2sQu1XDRIYbsi5Q0c/SrXhvJ4QyOx+GaajxmOg5PZSsSnCYPSmhjHHsRBx06/wQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "musl": ">=1.2.2", + "node": "^18.17.0 || ^20.3.0 || >=21.0.0", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linuxmusl-x64": "1.0.0" + } + }, + "node_modules/@img/sharp-wasm32": { + "version": "0.33.1", + "resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.33.1.tgz", + "integrity": "sha512-vWI/sA+0p+92DLkpAMb5T6I8dg4z2vzCUnp8yvxHlwBpzN8CIcO3xlSXrLltSvK6iMsVMNswAv+ub77rsf25lA==", + "cpu": [ + "wasm32" + ], + "dev": true, + "optional": true, + "dependencies": { + "@emnapi/runtime": "^0.44.0" + }, + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-ia32": { + "version": "0.33.1", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.33.1.tgz", + "integrity": "sha512-/xhYkylsKL05R+NXGJc9xr2Tuw6WIVl2lubFJaFYfW4/MQ4J+dgjIo/T4qjNRizrqs/szF/lC9a5+updmY9jaQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-x64": { + "version": "0.33.1", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.33.1.tgz", + "integrity": "sha512-XaM69X0n6kTEsp9tVYYLhXdg7Qj32vYJlAKRutxUsm1UlgQNx6BOhHwZPwukCGXBU2+tH87ip2eV1I/E8MQnZg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, "node_modules/@istanbuljs/load-nyc-config": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", @@ -2326,9 +2787,9 @@ } }, "node_modules/@remix-run/router": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.13.1.tgz", - "integrity": "sha512-so+DHzZKsoOcoXrILB4rqDkMDy7NLMErRdOxvzvOKb507YINKUP4Di+shbTZDhSE/pBZ+vr7XGIpcOO0VLSA+Q==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.14.1.tgz", + "integrity": "sha512-Qg4DMQsfPNAs88rb2xkdk03N3bjK4jgX5fR24eHCTR9q6PrhZQZ4UJBPzCHJkIpTRN1UKxx2DzjZmnC+7Lj0Ow==", "dev": true, "engines": { "node": ">=14.0.0" @@ -3193,9 +3654,9 @@ } }, "node_modules/async": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/async/-/async-3.2.4.tgz", - "integrity": "sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==" + "version": "3.2.5", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.5.tgz", + "integrity": "sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg==" }, "node_modules/asynciterator.prototype": { "version": "1.0.0", @@ -3232,12 +3693,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/b4a": { - "version": "1.6.4", - "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.6.4.tgz", - "integrity": "sha512-fpWrvyVHEKyeEvbKZTVOeZF3VSKKWtJxFIxX/jaVPf+cLbGUSitjb49pHLqPV2BUNNZ0LcoeEGfE/YCpyDYHIw==", - "dev": true - }, "node_modules/babel-loader": { "version": "9.1.3", "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-9.1.3.tgz", @@ -3369,13 +3824,13 @@ } }, "node_modules/babel-plugin-polyfill-corejs2": { - "version": "0.4.6", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.6.tgz", - "integrity": "sha512-jhHiWVZIlnPbEUKSSNb9YoWcQGdlTLq7z1GHL4AjFxaoOUMuuEVJ+Y4pAaQUGOGk93YsVCKPbqbfw3m0SM6H8Q==", + "version": "0.4.7", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.7.tgz", + "integrity": "sha512-LidDk/tEGDfuHW2DWh/Hgo4rmnw3cduK6ZkOI1NPFceSK3n/yAGeOsNT7FLnSGHkXj3RHGSEVkN3FsCTY6w2CQ==", "dev": true, "dependencies": { "@babel/compat-data": "^7.22.6", - "@babel/helper-define-polyfill-provider": "^0.4.3", + "@babel/helper-define-polyfill-provider": "^0.4.4", "semver": "^6.3.1" }, "peerDependencies": { @@ -3383,25 +3838,25 @@ } }, "node_modules/babel-plugin-polyfill-corejs3": { - "version": "0.8.5", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.8.5.tgz", - "integrity": "sha512-Q6CdATeAvbScWPNLB8lzSO7fgUVBkQt6zLgNlfyeCr/EQaEQR+bWiBYYPYAFyE528BMjRhL+1QBMOI4jc/c5TA==", + "version": "0.8.7", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.8.7.tgz", + "integrity": "sha512-KyDvZYxAzkC0Aj2dAPyDzi2Ym15e5JKZSK+maI7NAwSqofvuFglbSsxE7wUOvTg9oFVnHMzVzBKcqEb4PJgtOA==", "dev": true, "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.4.3", - "core-js-compat": "^3.32.2" + "@babel/helper-define-polyfill-provider": "^0.4.4", + "core-js-compat": "^3.33.1" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, "node_modules/babel-plugin-polyfill-regenerator": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.5.3.tgz", - "integrity": "sha512-8sHeDOmXC8csczMrYEOf0UTNa4yE2SxV5JGeT/LP1n0OYVDUUFPxG9vdk2AlDlIit4t+Kf0xCtpgXPBwnn/9pw==", + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.5.4.tgz", + "integrity": "sha512-S/x2iOCvDaCASLYsOOgWOq4bCfKYVqvO/uxjkaYyZ3rVsVE3CeAI/c84NpyuBBymEgNvHgjEot3a9/Z/kXvqsg==", "dev": true, "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.4.3" + "@babel/helper-define-polyfill-provider": "^0.4.4" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" @@ -3412,26 +3867,6 @@ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" }, - "node_modules/base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, "node_modules/base64id": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/base64id/-/base64id-2.0.0.tgz", @@ -3472,31 +3907,6 @@ "node": ">=8" } }, - "node_modules/bl": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", - "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", - "dev": true, - "dependencies": { - "buffer": "^5.5.0", - "inherits": "^2.0.4", - "readable-stream": "^3.4.0" - } - }, - "node_modules/bl/node_modules/readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "dev": true, - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, "node_modules/bluebird": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.2.1.tgz", @@ -3615,9 +4025,9 @@ } }, "node_modules/bootstrap-icons": { - "version": "1.11.2", - "resolved": "https://registry.npmjs.org/bootstrap-icons/-/bootstrap-icons-1.11.2.tgz", - "integrity": "sha512-TgdiPv+IM9tgDb+dsxrnGIyocsk85d2M7T0qIgkvPedZeoZfyeG/j+yiAE4uHCEayKef2RP05ahQ0/e9Sv75Wg==", + "version": "1.11.3", + "resolved": "https://registry.npmjs.org/bootstrap-icons/-/bootstrap-icons-1.11.3.tgz", + "integrity": "sha512-+3lpHrCw/it2/7lBL15VR0HEumaBss0+f/Lb6ZvHISn1mlK83jjFpooTLsMWbIjJMDjDjOExMsTxnXSIT4k4ww==", "dev": true, "funding": [ { @@ -3658,9 +4068,9 @@ "dev": true }, "node_modules/browserslist": { - "version": "4.22.1", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.22.1.tgz", - "integrity": "sha512-FEVc202+2iuClEhZhrWy6ZiAcRLvNMyYcxZ8raemul1DYVOVdFsbqckWLdsixQZCpJlwe77Z3UTalE7jsjnKfQ==", + "version": "4.22.2", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.22.2.tgz", + "integrity": "sha512-0UgcrvQmBDvZHFGdYUehrCNIazki7/lUP3kkoi/r3YB2amZbFM9J43ZRkJTXBUZK4gmx56+Sqk9+Vs9mwZx9+A==", "dev": true, "funding": [ { @@ -3677,9 +4087,9 @@ } ], "dependencies": { - "caniuse-lite": "^1.0.30001541", - "electron-to-chromium": "^1.4.535", - "node-releases": "^2.0.13", + "caniuse-lite": "^1.0.30001565", + "electron-to-chromium": "^1.4.601", + "node-releases": "^2.0.14", "update-browserslist-db": "^1.0.13" }, "bin": { @@ -3689,30 +4099,6 @@ "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" } }, - "node_modules/buffer": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" - } - }, "node_modules/buffer-from": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", @@ -3782,9 +4168,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001549", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001549.tgz", - "integrity": "sha512-qRp48dPYSCYaP+KurZLhDYdVE+yEyht/3NlmcJgVQ2VMGt6JL36ndQ/7rgspdZsJuxDPFIo/OzBT2+GmIJ53BA==", + "version": "1.0.30001570", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001570.tgz", + "integrity": "sha512-+3e0ASu4sw1SWaoCtvPeyXp+5PsjigkSt8OXZbF9StH5pQWbxEjLAZE3n8Aup5udop1uRiKA7a4utUk/uoSpUw==", "dev": true, "funding": [ { @@ -3993,12 +4379,6 @@ "node": ">= 6" } }, - "node_modules/chownr": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", - "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", - "dev": true - }, "node_modules/chrome-trace-event": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz", @@ -4414,9 +4794,9 @@ } }, "node_modules/core-js": { - "version": "3.33.3", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.33.3.tgz", - "integrity": "sha512-lo0kOocUlLKmm6kv/FswQL8zbkH7mVsLJ/FULClOhv8WRVmKLVcs6XPNQAzstfeJTCHMyButEwG+z1kHxHoDZw==", + "version": "3.35.0", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.35.0.tgz", + "integrity": "sha512-ntakECeqg81KqMueeGJ79Q5ZgQNR+6eaE8sxGCx62zMbAIj65q+uYvatToew3m6eAGdU4gNZwpZ34NMe4GYswg==", "dev": true, "hasInstallScript": true, "funding": { @@ -4425,12 +4805,12 @@ } }, "node_modules/core-js-compat": { - "version": "3.33.0", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.33.0.tgz", - "integrity": "sha512-0w4LcLXsVEuNkIqwjjf9rjCoPhK8uqA4tMRh4Ge26vfLtUutshn+aRJU21I9LCJlh2QQHfisNToLjw1XEJLTWw==", + "version": "3.35.0", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.35.0.tgz", + "integrity": "sha512-5blwFAddknKeNgsjBzilkdQ0+YK8L1PfqPYq40NOYMYFSS38qj+hpTcLLWwpIwA2A5bje/x5jmVn2tzUMg9IVw==", "dev": true, "dependencies": { - "browserslist": "^4.22.1" + "browserslist": "^4.22.2" }, "funding": { "type": "opencollective", @@ -4645,21 +5025,6 @@ "node": ">=0.10.0" } }, - "node_modules/decompress-response": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", - "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", - "dev": true, - "dependencies": { - "mimic-response": "^3.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/deep-eql": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.3.tgz", @@ -4974,9 +5339,9 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.4.556", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.556.tgz", - "integrity": "sha512-6RPN0hHfzDU8D56E72YkDvnLw5Cj2NMXZGg3UkgyoHxjVhG99KZpsKgBWMmTy0Ei89xwan+rbRsVB9yzATmYzQ==", + "version": "1.4.614", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.614.tgz", + "integrity": "sha512-X4ze/9Sc3QWs6h92yerwqv7aB/uU8vCjZcrMjA8N9R1pjMFRe44dLsck5FzLilOYvcXuDn93B+bpGYyufc70gQ==", "dev": true }, "node_modules/emoji-regex": { @@ -5017,15 +5382,6 @@ "node": ">=6.0" } }, - "node_modules/end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "dev": true, - "dependencies": { - "once": "^1.4.0" - } - }, "node_modules/engine.io": { "version": "6.5.4", "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.5.4.tgz", @@ -5257,15 +5613,15 @@ } }, "node_modules/eslint": { - "version": "8.55.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.55.0.tgz", - "integrity": "sha512-iyUUAM0PCKj5QpwGfmCAG9XXbZCWsqP/eWAWrG/W0umvjuLRBECwSFdt+rCntju0xEH7teIABPwXpahftIaTdA==", + "version": "8.56.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.56.0.tgz", + "integrity": "sha512-Go19xM6T9puCOWntie1/P997aXxFsOi37JIHRWI514Hc6ZnaHGKY9xFhrU65RT6CcBEzZoGG1e6Nq+DT04ZtZQ==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.6.1", "@eslint/eslintrc": "^2.1.4", - "@eslint/js": "8.55.0", + "@eslint/js": "8.56.0", "@humanwhocodes/config-array": "^0.11.13", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", @@ -5676,15 +6032,6 @@ "url": "https://github.com/sindresorhus/execa?sponsor=1" } }, - "node_modules/expand-template": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz", - "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==", - "dev": true, - "engines": { - "node": ">=6" - } - }, "node_modules/express": { "version": "4.17.3", "resolved": "https://registry.npmjs.org/express/-/express-4.17.3.tgz", @@ -5890,12 +6237,6 @@ "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", "dev": true }, - "node_modules/fast-fifo": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.3.2.tgz", - "integrity": "sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==", - "dev": true - }, "node_modules/fast-glob": { "version": "3.2.12", "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz", @@ -5975,13 +6316,13 @@ } }, "node_modules/favicons": { - "version": "7.1.4", - "resolved": "https://registry.npmjs.org/favicons/-/favicons-7.1.4.tgz", - "integrity": "sha512-lnZpVgT7Fzz+DUjioKF1dMwLYlpqWCaB4gIksIfIKwtlhHO1Q7w23hERwHQjEsec+43iENwbTAPRDW3XvpLhbg==", + "version": "7.1.5", + "resolved": "https://registry.npmjs.org/favicons/-/favicons-7.1.5.tgz", + "integrity": "sha512-OVqWHqVnxGmvcQdXGmA9wGkfiZTrgaaVNvoeemzrV1YHP/boAyGJVRFGwib5NxLm+sQmJrf2MuRaJX33sJkMVw==", "dev": true, "dependencies": { "escape-html": "^1.0.3", - "sharp": "^0.32.4", + "sharp": "^0.33.1", "xml2js": "^0.6.1" }, "engines": { @@ -6196,9 +6537,9 @@ } }, "node_modules/fixted": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/fixted/-/fixted-4.2.3.tgz", - "integrity": "sha512-ELr2gPrLWrkXKwwncUF/ZhmQd+qTjjrO1uKNUhJobpRDILfZY9FPAqs5wRLYF70AA8Ms/KefQ2N7mWrj24u/Ig==", + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/fixted/-/fixted-4.2.4.tgz", + "integrity": "sha512-+ubwM3GPrDSARKC+rrX6bY5Ha0sWMz5VjLWNAJPdwP91uF2vSYWAKGsqEVLoaMNG6VeCzRBpbPMupV/TPbcEFg==", "dev": true, "funding": [ { @@ -6207,11 +6548,11 @@ } ], "dependencies": { - "async": "~3.2.4", + "async": "~3.2.5", "lodash": "~4.17.21" }, "engines": { - "node": ">=20.9" + "node": ">=20.10" }, "peerDependencies": { "sails": "1.x" @@ -6387,12 +6728,6 @@ } ] }, - "node_modules/fs-constants": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", - "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", - "dev": true - }, "node_modules/fs-extra": { "version": "0.30.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.30.0.tgz", @@ -6530,12 +6865,6 @@ "resolved": "https://registry.npmjs.org/getopts/-/getopts-2.3.0.tgz", "integrity": "sha512-5eDf9fuSXwxBL6q5HX+dhDj+dslFGWzU5thZ9kNKUkcPtaPdatmUFKwHFrLb/uf/WpA4BHET+AX3Scl56cAjpA==" }, - "node_modules/github-from-package": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", - "integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==", - "dev": true - }, "node_modules/glob": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", @@ -6832,9 +7161,9 @@ } }, "node_modules/html-webpack-plugin": { - "version": "5.5.3", - "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-5.5.3.tgz", - "integrity": "sha512-6YrDKTuqaP/TquFH7h4srYWsZx+x6k6+FbsTm0ziCwGHDP78Unr1r9F/H4+sGmMbX08GQcJ+K64x55b+7VM/jg==", + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-5.6.0.tgz", + "integrity": "sha512-iwaY4wzbe48AfKLZ/Cc8k0L+FKG6oSNRaZ8x5A/T/IVDGyXcbHncM9TdDa93wn0FsSm82FhTKW7f3vS61thXAw==", "dev": true, "dependencies": { "@types/html-minifier-terser": "^6.0.0", @@ -6851,7 +7180,16 @@ "url": "https://opencollective.com/html-webpack-plugin" }, "peerDependencies": { + "@rspack/core": "0.x || 1.x", "webpack": "^5.20.0" + }, + "peerDependenciesMeta": { + "@rspack/core": { + "optional": true + }, + "webpack": { + "optional": true + } } }, "node_modules/htmlparser2": { @@ -7026,26 +7364,6 @@ "postcss": "^8.1.0" } }, - "node_modules/ieee754": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, "node_modules/ignore": { "version": "5.2.4", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", @@ -8529,18 +8847,6 @@ "node": ">=6" } }, - "node_modules/mimic-response": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", - "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/mini-css-extract-plugin": { "version": "2.7.6", "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.7.6.tgz", @@ -8593,12 +8899,6 @@ "mkdirp": "bin/cmd.js" } }, - "node_modules/mkdirp-classic": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", - "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==", - "dev": true - }, "node_modules/mocha": { "version": "10.2.0", "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.2.0.tgz", @@ -8720,9 +9020,9 @@ } }, "node_modules/moment-timezone": { - "version": "0.5.43", - "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.43.tgz", - "integrity": "sha512-72j3aNyuIsDxdF1i7CEgV2FfxM1r6aaqJyLB2vwb33mXYyoyLly+F1zbWqhA3/bVIoJ4szlUoMbUnVdid32NUQ==", + "version": "0.5.44", + "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.44.tgz", + "integrity": "sha512-nv3YpzI/8lkQn0U6RkLd+f0W/zy/JnoR5/EyPz/dNkPTBjA2jNLCVxaiQ8QpeLymhSZvX0wCL5s27NQWdOPwAw==", "dependencies": { "moment": "^2.29.4" }, @@ -8795,12 +9095,6 @@ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" } }, - "node_modules/napi-build-utils": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.2.tgz", - "integrity": "sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==", - "dev": true - }, "node_modules/natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", @@ -8837,57 +9131,6 @@ "tslib": "^2.0.3" } }, - "node_modules/node-abi": { - "version": "3.47.0", - "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.47.0.tgz", - "integrity": "sha512-2s6B2CWZM//kPgwnuI0KrYwNjfdByE25zvAaEpq9IH4zcNsarH8Ihu/UuX6XMPEogDAxkuUFeZn60pXNHAqn3A==", - "dev": true, - "dependencies": { - "semver": "^7.3.5" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/node-abi/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/node-abi/node_modules/semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", - "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/node-abi/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, - "node_modules/node-addon-api": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-6.1.0.tgz", - "integrity": "sha512-+eawOlIgy680F0kBzPUNFhMZGtJ1YmqM6l4+Crf4IkImjYrO/mqPwRMh352g23uIaQKFItcQ64I7KMaJxHgAVA==", - "dev": true - }, "node_modules/node-fetch": { "version": "2.7.0", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", @@ -8930,9 +9173,9 @@ } }, "node_modules/node-releases": { - "version": "2.0.13", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.13.tgz", - "integrity": "sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ==", + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", + "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==", "dev": true }, "node_modules/normalize-package-data": { @@ -9992,74 +10235,6 @@ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" } }, - "node_modules/prebuild-install": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.1.tgz", - "integrity": "sha512-jAXscXWMcCK8GgCoHOfIr0ODh5ai8mj63L2nWrjuAgXE6tDyYGnx4/8o/rCgU+B4JSyZBKbeZqzhtwtC3ovxjw==", - "dev": true, - "dependencies": { - "detect-libc": "^2.0.0", - "expand-template": "^2.0.3", - "github-from-package": "0.0.0", - "minimist": "^1.2.3", - "mkdirp-classic": "^0.5.3", - "napi-build-utils": "^1.0.1", - "node-abi": "^3.3.0", - "pump": "^3.0.0", - "rc": "^1.2.7", - "simple-get": "^4.0.0", - "tar-fs": "^2.0.0", - "tunnel-agent": "^0.6.0" - }, - "bin": { - "prebuild-install": "bin.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/prebuild-install/node_modules/readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "dev": true, - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/prebuild-install/node_modules/tar-fs": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz", - "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==", - "dev": true, - "dependencies": { - "chownr": "^1.1.1", - "mkdirp-classic": "^0.5.2", - "pump": "^3.0.0", - "tar-stream": "^2.1.4" - } - }, - "node_modules/prebuild-install/node_modules/tar-stream": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", - "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", - "dev": true, - "dependencies": { - "bl": "^4.0.3", - "end-of-stream": "^1.4.1", - "fs-constants": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^3.1.1" - }, - "engines": { - "node": ">=6" - } - }, "node_modules/prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", @@ -10178,16 +10353,6 @@ "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", "integrity": "sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==" }, - "node_modules/pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "dev": true, - "dependencies": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, "node_modules/punycode": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", @@ -10384,12 +10549,6 @@ } ] }, - "node_modules/queue-tick": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/queue-tick/-/queue-tick-1.0.1.tgz", - "integrity": "sha512-kJt5qhMxoszgU/62PLP1CJytzd2NKetjSRnyuj31fDd3Rlcz3fzlFdFLD1SItunPwyqEOkca6GbV612BWfaBag==", - "dev": true - }, "node_modules/random-bytes": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/random-bytes/-/random-bytes-1.0.0.tgz", @@ -10500,9 +10659,9 @@ } }, "node_modules/react-bootstrap": { - "version": "2.9.1", - "resolved": "https://registry.npmjs.org/react-bootstrap/-/react-bootstrap-2.9.1.tgz", - "integrity": "sha512-ezgmh/ARCYp18LbZEqPp0ppvy+ytCmycDORqc8vXSKYV3cer4VH7OReV8uMOoKXmYzivJTxgzGHalGrHamryHA==", + "version": "2.9.2", + "resolved": "https://registry.npmjs.org/react-bootstrap/-/react-bootstrap-2.9.2.tgz", + "integrity": "sha512-a36B+EHsAI/aH+ZhXNILBFnqscE3zr10dWmjBmfhIb2QR7KSXJiGzYd6Faf/25G8G7/CP9TCL2B0WhUBOD2UBQ==", "dev": true, "dependencies": { "@babel/runtime": "^7.22.5", @@ -10555,12 +10714,12 @@ "dev": true }, "node_modules/react-router": { - "version": "6.20.1", - "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.20.1.tgz", - "integrity": "sha512-ccvLrB4QeT5DlaxSFFYi/KR8UMQ4fcD8zBcR71Zp1kaYTC5oJKYAp1cbavzGrogwxca+ubjkd7XjFZKBW8CxPA==", + "version": "6.21.1", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.21.1.tgz", + "integrity": "sha512-W0l13YlMTm1YrpVIOpjCADJqEUpz1vm+CMo47RuFX4Ftegwm6KOYsL5G3eiE52jnJpKvzm6uB/vTKTPKM8dmkA==", "dev": true, "dependencies": { - "@remix-run/router": "1.13.1" + "@remix-run/router": "1.14.1" }, "engines": { "node": ">=14.0.0" @@ -10570,13 +10729,13 @@ } }, "node_modules/react-router-dom": { - "version": "6.20.1", - "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.20.1.tgz", - "integrity": "sha512-npzfPWcxfQN35psS7rJgi/EW0Gx6EsNjfdJSAk73U/HqMEJZ2k/8puxfwHFgDQhBGmS3+sjnGbMdMSV45axPQw==", + "version": "6.21.1", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.21.1.tgz", + "integrity": "sha512-QCNrtjtDPwHDO+AO21MJd7yIcr41UetYt5jzaB9Y1UYaPTCnVuJq6S748g1dE11OQlCFIQg+RtAA1SEZIyiBeA==", "dev": true, "dependencies": { - "@remix-run/router": "1.13.1", - "react-router": "6.20.1" + "@remix-run/router": "1.14.1", + "react-router": "6.21.1" }, "engines": { "node": ">=14.0.0" @@ -11129,9 +11288,9 @@ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, "node_modules/sails": { - "version": "1.5.8", - "resolved": "https://registry.npmjs.org/sails/-/sails-1.5.8.tgz", - "integrity": "sha512-S1omXwRYsnJzQtnDG0pDOmLUT8WssFV3KMIE15grYo6gtOwUwPhITs8dSw1rzTCyV8TIt5vQzVbeL82vvfwINA==", + "version": "1.5.9", + "resolved": "https://registry.npmjs.org/sails/-/sails-1.5.9.tgz", + "integrity": "sha512-oji4Nxo7IxBTaL+ITc4Q24q64uVU9eABwKnKEoDLuIcH6kW5n0LOjxZBzMVZukqJOxwKVa/iGiS9H7/0SipDVA==", "dependencies": { "@sailshq/lodash": "^3.10.2", "async": "2.6.4", @@ -11688,9 +11847,9 @@ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" }, "node_modules/sass": { - "version": "1.69.5", - "resolved": "https://registry.npmjs.org/sass/-/sass-1.69.5.tgz", - "integrity": "sha512-qg2+UCJibLr2LCVOt3OlPhr/dqVHWOa9XtZf2OjbLs/T4VPSJ00udtgJxH3neXZm+QqX8B+3cU7RaLqp1iVfcQ==", + "version": "1.69.7", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.69.7.tgz", + "integrity": "sha512-rzj2soDeZ8wtE2egyLXgOOHQvaC2iosZrkF6v3EUG+tBwEvhqUCzm0VP3k9gHF9LXbSrRhT5SksoI56Iw8NPnQ==", "dev": true, "dependencies": { "chokidar": ">=3.0.0 <4.0.0", @@ -11705,9 +11864,9 @@ } }, "node_modules/sass-loader": { - "version": "13.3.2", - "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-13.3.2.tgz", - "integrity": "sha512-CQbKl57kdEv+KDLquhC+gE3pXt74LEAzm+tzywcA0/aHZuub8wTErbjAoNI57rPUWRYRNC5WUnNl8eGJNbDdwg==", + "version": "13.3.3", + "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-13.3.3.tgz", + "integrity": "sha512-mt5YN2F1MOZr3d/wBRcZxeFgwgkH44wVc2zohO2YF6JiOMkiXe4BYRZpSu2sO1g71mo/j16txzUhsKZlqjVGzA==", "dev": true, "dependencies": { "neo-async": "^2.6.2" @@ -12165,26 +12324,43 @@ } }, "node_modules/sharp": { - "version": "0.32.6", - "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.32.6.tgz", - "integrity": "sha512-KyLTWwgcR9Oe4d9HwCwNM2l7+J0dUQwn/yf7S0EnTtb0eVS4RxO0eUSvxPtzT4F3SY+C4K6fqdv/DO27sJ/v/w==", + "version": "0.33.1", + "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.33.1.tgz", + "integrity": "sha512-iAYUnOdTqqZDb3QjMneBKINTllCJDZ3em6WaWy7NPECM4aHncvqHRm0v0bN9nqJxMiwamv5KIdauJ6lUzKDpTQ==", "dev": true, "hasInstallScript": true, "dependencies": { "color": "^4.2.3", "detect-libc": "^2.0.2", - "node-addon-api": "^6.1.0", - "prebuild-install": "^7.1.1", - "semver": "^7.5.4", - "simple-get": "^4.0.1", - "tar-fs": "^3.0.4", - "tunnel-agent": "^0.6.0" + "semver": "^7.5.4" }, "engines": { - "node": ">=14.15.0" + "libvips": ">=8.15.0", + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" }, "funding": { "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-darwin-arm64": "0.33.1", + "@img/sharp-darwin-x64": "0.33.1", + "@img/sharp-libvips-darwin-arm64": "1.0.0", + "@img/sharp-libvips-darwin-x64": "1.0.0", + "@img/sharp-libvips-linux-arm": "1.0.0", + "@img/sharp-libvips-linux-arm64": "1.0.0", + "@img/sharp-libvips-linux-s390x": "1.0.0", + "@img/sharp-libvips-linux-x64": "1.0.0", + "@img/sharp-libvips-linuxmusl-arm64": "1.0.0", + "@img/sharp-libvips-linuxmusl-x64": "1.0.0", + "@img/sharp-linux-arm": "0.33.1", + "@img/sharp-linux-arm64": "0.33.1", + "@img/sharp-linux-s390x": "0.33.1", + "@img/sharp-linux-x64": "0.33.1", + "@img/sharp-linuxmusl-arm64": "0.33.1", + "@img/sharp-linuxmusl-x64": "0.33.1", + "@img/sharp-wasm32": "0.33.1", + "@img/sharp-win32-ia32": "0.33.1", + "@img/sharp-win32-x64": "0.33.1" } }, "node_modules/sharp/node_modules/lru-cache": { @@ -12269,51 +12445,6 @@ "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", "dev": true }, - "node_modules/simple-concat": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", - "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/simple-get": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.1.tgz", - "integrity": "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "decompress-response": "^6.0.0", - "once": "^1.3.1", - "simple-concat": "^1.0.0" - } - }, "node_modules/simple-swizzle": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", @@ -12691,16 +12822,6 @@ "node": ">=0.10" } }, - "node_modules/streamx": { - "version": "2.15.1", - "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.15.1.tgz", - "integrity": "sha512-fQMzy2O/Q47rgwErk/eGeLu/roaFWV0jVsogDmrszM9uIw8L5OA+t+V93MgYlufNptfjmYR1tOMWhei/Eh7TQA==", - "dev": true, - "dependencies": { - "fast-fifo": "^1.1.0", - "queue-tick": "^1.0.1" - } - }, "node_modules/string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", @@ -12994,28 +13115,6 @@ "node": ">=6" } }, - "node_modules/tar-fs": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.0.4.tgz", - "integrity": "sha512-5AFQU8b9qLfZCX9zp2duONhPmZv0hGYiBPJsyUdqMjzq/mqVpy/rEUSeHk1+YitmxugaptgBh5oDGU3VsAJq4w==", - "dev": true, - "dependencies": { - "mkdirp-classic": "^0.5.2", - "pump": "^3.0.0", - "tar-stream": "^3.1.5" - } - }, - "node_modules/tar-stream": { - "version": "3.1.6", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.1.6.tgz", - "integrity": "sha512-B/UyjYwPpMBv+PaFSWAmtYjwdrlEaZQEhMIBFNC5oEG8lpiW8XjcSdmEaClj28ArfKScKHs2nshz3k2le6crsg==", - "dev": true, - "dependencies": { - "b4a": "^1.6.4", - "fast-fifo": "^1.2.0", - "streamx": "^2.15.0" - } - }, "node_modules/tarn": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/tarn/-/tarn-3.0.2.tgz", @@ -13212,18 +13311,6 @@ "node": ">=0.6.x" } }, - "node_modules/tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", - "dev": true, - "dependencies": { - "safe-buffer": "^5.0.1" - }, - "engines": { - "node": "*" - } - }, "node_modules/type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", diff --git a/package.json b/package.json index dcdf016..5c9fb18 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "sails-react-bootstrap-webpack", - "version": "5.0.0", - "description": "An opinionated base configuration of Sails, with Webpack for React support, and Bootstrap for styling. A start-up in a box!", + "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!", "keywords": [ "sails", "react", @@ -16,10 +16,10 @@ "csrf": "3.1.0", "json-stringify-safe": "5.0.1", "lodash": "4.17.21", - "moment-timezone": "0.5.43", + "moment-timezone": "0.5.44", "otplib": "12.0.1", "qrcode": "1.5.3", - "sails": "1.5.8", + "sails": "1.5.9", "sails-hook-orm": "4.0.2", "sails-hook-sockets": "3.0.0", "sails-mysql": "3.0.1", @@ -27,28 +27,28 @@ "superagent": "8.1.2" }, "devDependencies": { - "@babel/core": "7.23.5", + "@babel/core": "7.23.7", "@babel/eslint-parser": "7.23.3", - "@babel/preset-env": "7.23.5", + "@babel/preset-env": "7.23.7", "@babel/preset-react": "7.23.3", "@popperjs/core": "2.11.8", "babel-loader": "9.1.3", "bootstrap": "5.3.2", - "bootstrap-icons": "1.11.2", + "bootstrap-icons": "1.11.3", "chai": "4.3.10", "chai-spies": "1.1.0", "chai-uuid": "1.0.6", - "codecov": "^3.8.3", + "codecov": "3.8.3", "copy-webpack-plugin": "11.0.0", - "core-js": "3.33.3", + "core-js": "3.35.0", "css-loader": "6.8.1", - "eslint": "8.55.0", + "eslint": "8.56.0", "eslint-plugin-react": "7.33.2", - "favicons": "7.1.4", + "favicons": "7.1.5", "favicons-webpack-plugin": "6.0.1", "file-loader": "6.2.0", - "fixted": "4.2.3", - "html-webpack-plugin": "5.5.3", + "fixted": "4.2.4", + "html-webpack-plugin": "5.6.0", "mini-css-extract-plugin": "2.7.6", "mocha": "10.2.0", "npm-run-all": "4.1.5", @@ -56,12 +56,12 @@ "prompts": "2.4.2", "prop-types": "15.8.1", "react": "18.2.0", - "react-bootstrap": "v2.9.1", + "react-bootstrap": "2.9.2", "react-dom": "18.2.0", - "react-router-dom": "6.20.1", + "react-router-dom": "6.21.1", "readline-sync": "1.4.10", - "sass": "1.69.5", - "sass-loader": "13.3.2", + "sass": "1.69.7", + "sass-loader": "13.3.3", "style-loader": "3.3.3", "supertest": "6.3.3", "webpack": "5.89.0", @@ -76,9 +76,11 @@ "build:prod": "NODE_ENV=production webpack --mode production --config webpack/prod.config.js", "clean": "rm -rf .tmp && mkdir -p .tmp/public", "codecov": "npm run lint && NODE_ENV=testing nyc --reporter=lcovonly mocha && codecov --file=test/coverage/lcov.info --disable=gcov", - "coverage": "npm run lint && NODE_ENV=testing nyc --reporter=html mocha", + "coverage": "npm run lint && NODE_ENV=testing nyc --reporter=html npm run custom-mocha", "create:admin": "sails run create-admin", - "custom-tests": "NODE_ENV=testing mocha", + "custom-mocha": "mocha --config .mocharc", + "custom-tests": "NODE_ENV=testing npm run custom-mocha", + "db:wipe": "sails run datastore-wipe", "debug": "node --inspect app.js", "generate:dek": "node -p \"require('crypto').randomBytes(32).toString('base64')\"", "generate:token": "node -p \"const crypto = require('crypto'); crypto.createHmac('sha512', crypto.randomBytes(42)).update(crypto.randomBytes(42) + new Date()).digest('hex');\"", @@ -87,6 +89,7 @@ "lift:prod": "NODE_ENV=production node app.js", "lines": "git ls-files --exclude-standard -- ':!:**/*.[pjs][npv]g' ':!:test/*' ':!:**/*.ai' ':!:.*' ':!:**/.*' ':!:**/*.md' ':!:*.md' ':!:assets/styles' ':!:assets/dependencies' ':!:package.json' ':!:package-lock.json' ':!:config' ':!:LICENSE' | xargs wc -l", "lint": "eslint . --max-warnings=0 --report-unused-disable-directives && echo '✔ Your .js files look good.'", + "ngrok": "node ngrok.js", "setup": "node setup.js", "start": "run-p webpack lift", "start:debug": "npm-run-all --parallel webpack debug", diff --git a/scripts/datastore-wipe.js b/scripts/datastore-wipe.js new file mode 100644 index 0000000..f43c91d --- /dev/null +++ b/scripts/datastore-wipe.js @@ -0,0 +1,157 @@ +const prompts = require('prompts'); + +module.exports = { + friendlyName: 'Datastore Wipe', + + description: 'Wipe all data on all the datastores. WILL NOT run on PRODUCTION. VERY DANGEROUS!!!', + + inputs: {}, + + exits: { + canceled: { + description: 'Datastore wipe was canceled.' + }, + success: { + description: 'Success! THIS DATASTORE IS CLEAN.' + }, + production: { + description: 'You CAN NOT run this program on a PRODUCTION environment.' + } + }, + + fn: async (inputs, exits) => { + if ((process.env.NODE_ENV && process.env.NODE_ENV.toUpperCase() === 'PRODUCTION') || sails.config.models.migrate.toLowerCase() === 'safe') { + return exits.production(); + } + + // A word for every letter. + const randomWords = [ + 'Vanilla', + 'Fluffy', + 'Ultimate', + 'Longitude', + 'Zenith', + 'Inquisitive', + 'Dimple', + 'Spectrum', + 'Gargoyle', + 'Bobcat', + 'Official', + 'Winning', + 'Ephemeral', + 'Young', + 'Train', + 'Mingle', + 'Joint', + 'Cascade', + 'Rabbit', + 'Prelude', + 'Quiet', + 'Halo', + 'Nickel', + 'Kilometer', + 'Xenon', + 'Apple', + ]; + + const chosenOne = Math.floor(Math.random() * randomWords.length); + + let notChosenOne; + do { + notChosenOne = Math.floor(Math.random() * randomWords.length); + } while (notChosenOne === chosenOne); + + const answers = await prompts([ + { + message: 'Do you wish to wipe all of the data from the connected datastore(s)?', + name: 'sureConfirm', + type: 'confirm', + initial: false + }, { + message: 'ARE YOU ABSOLUTELY SURE? THIS CAN NOT BE UNDONE! YOU WILL LOSE EVERYTHING! ALL DATA WILL BE ERASED!', + name: 'sureToggle', + type: (prev) => { + if (prev) { + console.log(''); + + return 'toggle'; + } + + return null; + }, + initial: false, + inactive: 'NO, CANCEL', + active: 'YES, I\'M SURE' + }, { + message: 'FINAL FAILSAFE VERIFICATION. In order to erase everything, you must select the word "' + randomWords[chosenOne] + '":', + name: 'sureSelect', + type: (prev) => { + if (prev) { + console.log(''); + + return 'select'; + } + + return null; + }, + initial: notChosenOne, + choices: randomWords + } + ]); + + if (!answers.sureConfirm || !answers.sureToggle || answers.sureSelect !== chosenOne) { + console.log(''); + + return exits.canceled(); + } + + // It's a bit more than 10 seconds... + console.log('\nYOU NOW HAVE 10 SECONDS TO CHANGE YOUR MIND, BEFORE ALL DATA IS DESTROYED...\n'); + await sleep(2500); + console.log('10'); + await sleep(); + console.log('9'); + await sleep(); + console.log('8'); + await sleep(); + console.log('7'); + await sleep(); + console.log('6'); + await sleep(); + console.log('\nI REALLY HOPE YOU KNOW WHAT YOU ARE DOING!!!\n'); + await sleep(2500); + console.log('5'); + await sleep(); + console.log('4'); + await sleep(); + console.log('3'); + await sleep(); + console.log('2'); + await sleep(); + console.log('1'); + await sleep(); + + console.log('\nNO GOING BACK NOW!!!'); + await sleep(); + console.log('ALL DATA IS BEING ERASED!!!\n'); + await sleep(); + + const modelsToDestroy = []; + + _.forEach(sails.models, (model, modelName) => { + modelsToDestroy.push(modelName); + modelsToDestroy.push(model.destroy({})); + }); + + for(let i = 0; i < modelsToDestroy.length; i = i + 2) { + console.log(modelsToDestroy[i]); + await modelsToDestroy[i + 1]; + } + + return exits.success('\nThe datastore(s) are clean.\n'); + } +}; + +async function sleep(napTime = 1000) { + await new Promise(resolve => setTimeout(resolve, napTime)); +} diff --git a/setup.js b/setup.js index 25a62c3..f42c9f4 100755 --- a/setup.js +++ b/setup.js @@ -1,5 +1,17 @@ #!/usr/bin/env node +/** + * + * WELCOME TO THE SETUP FILE! + * + * This file requires a template `config/local.js.sample` file in order to work. + * It is meant to create a `config/local.js` file, which is a "master" file, if you will; dictating any configuration overrides. + * + * While `config/env/DEVELOPMENT.js` (or `config/env/PRODUCTION.js`) override the general configuration files, + * `config/local.js` takes precedence over all other files, including the `config/env` files. + * + */ + const crypto = require('crypto'); const fs = require('fs'); const path = require('path'); @@ -381,7 +393,10 @@ function runPrompts(defaults = { // fs.writeFileSync(modelsConfigPath, modelsConfigContent); // } + console.log(''); console.log('Setup complete!'); + console.log('`config/local.js.sample` copied to -> `config/local.js`'); + console.log(''); return process.exit(0); }); diff --git a/test/fixtures/User.js b/test/fixtures/User.js index 20932cf..6ab42d4 100644 --- a/test/fixtures/User.js +++ b/test/fixtures/User.js @@ -1,27 +1,36 @@ module.exports = [ { id: 'c', // auto-generated, but still string required + role: 'admin', firstName: 'NeoNexus', lastName: 'DeMortis', - role: 'admin', email: 'admin@testing.com', password: 'Some really long passphrase is better than a password.', verificationKey: 'rmWFXL/4wePcEqrojD6IGgzGnlQfGlaZUIoe7mWYbTQ=' }, { id: 'c', // auto-generated, but still string required + role: 'manager', firstName: 'Manager', lastName: 'Bot', - role: 'manager', email: 'manager@testing.com', password: `Passphrases are great, aren't they?`, verificationKey: 'iQXYf9NeNbzlB6qeIOqtiGNRyPdM7y/AyDf1rHYRi78=' }, { id: 'c', // auto-generated, but still string required + role: 'user', firstName: 'User', lastName: 'Bot', - role: 'user', email: 'user@testing.com', password: `Who doesn't love a good passphrase?`, verificationKey: 'O+mATUT1soiuaqAfS9XJcWkQscs/xI/IaYq37KLCIrw=' + }, { + id: 'c', // auto-generated, but still string required + role: 'user', + firstName: 'Deleted', + lastName: 'Softly', + email: 'softly@deleted.com', + password: `Mmmmmmmmmmmmmmm, tasty passphrase...`, + verificationKey: 'zxJQsKi85AcpN+CmSisE9fJuDApd61mgNKptUj5sfsE=', + deletedAt: new Date() } ]; diff --git a/test/integration/admin/delete-user.test.js b/test/integration/admin/delete-user.test.js index 93910c1..bdf79b7 100644 --- a/test/integration/admin/delete-user.test.js +++ b/test/integration/admin/delete-user.test.js @@ -27,7 +27,7 @@ describe('Delete User Controller', function() { it('should require an admin be logged in', function(done) { testUtils.deleteAsAnonymous({ - route: '/user', + route: '/user/' + userId, expectedStatus: 403, end: (err) => { if (err) { @@ -35,7 +35,7 @@ describe('Delete User Controller', function() { } testUtils.deleteAsUser({ - route: '/user', + route: '/user/' + userId, expectedStatus: 403, end: done }); @@ -45,21 +45,15 @@ describe('Delete User Controller', function() { it('should not allow one to delete one self', function(done) { testUtils.deleteAsAdmin({ - route: '/user', + route: '/user/' + testUtils.fixtures.user[0].id, expectedStatus: 400, - data: { - id: testUtils.fixtures.user[0].id - }, end: done }); }); it('should SOFT DELETE the user', function(done) { testUtils.deleteAsAdmin({ - route: '/user', - data: { - id: userId - }, + route: '/user/' + userId, end: done }); }); diff --git a/test/integration/admin/edit-user.test.js b/test/integration/admin/edit-user.test.js new file mode 100644 index 0000000..0ef42ee --- /dev/null +++ b/test/integration/admin/edit-user.test.js @@ -0,0 +1,128 @@ +describe('Edit User', function() { + it('should be denied for a non-authenticated user', function(done) { + testUtils.putAsAnonymous({ + route: '/user/some-user-uuid', + data: { + firstName: 'Updated', + lastName: 'User', + email: 'newly.updated@user.com', + password: 'A super awesome passphrase, to appease the password gods.' + }, + expectedStatus: 403, // forbidden + end: async (err, res) => { + if (err) { + console.debug(res.body); + + return done(err); + } + + return done(); + } + }); + }); + + it('should be denied for a non-admin user', function(done) { + testUtils.putAsUser({ + route: '/user/some-user-uuid', + data: { + firstName: 'Updated', + lastName: 'User', + email: 'newly.updated@user.com', + password: 'A super awesome passphrase, to appease the password gods.' + }, + expectedStatus: 403, // forbidden + end: async (err, res) => { + if (err) { + console.debug(res.body); + + return done(err); + } + + return done(); + } + }); + }); + + it('should update a user correctly', function(done) { + const firstName = 'Updated'; + const lastName = 'User'; + const email = 'newly.updated@user.com'; + const role = 'admin'; + + testUtils.putAsAdmin({ + route: '/user/' + testUtils.fixtures.user[2].id, + data: { + firstName, + lastName, + email, + role + }, + expectedStatus: 200, // ok + end: (err, res) => { + if (err) { + console.debug(res.body); + + return done(err); + } + + should.exist(res.body.user); + res.body.user.id.should.eq(testUtils.fixtures.user[2].id); + res.body.user.firstName.should.not.eq(testUtils.fixtures.user[2].firstName); + res.body.user.lastName.should.not.eq(testUtils.fixtures.user[2].lastName); + res.body.user.email.should.not.eq(testUtils.fixtures.user[2].email); + res.body.user.role.should.not.eq(testUtils.fixtures.user[2].role); + + res.body.user.firstName.should.eq(firstName); + res.body.user.lastName.should.eq(lastName); + res.body.user.email.should.eq(email); + res.body.user.role.should.eq(role); + + // Reset the data + testUtils.putAsAdmin({ + route: '/user/' + testUtils.fixtures.user[2].id, + data: { + firstName: testUtils.fixtures.user[2].firstName, + lastName: testUtils.fixtures.user[2].lastName, + email: testUtils.fixtures.user[2].email, + role: testUtils.fixtures.user[2].role + }, + expectedStatus: 200, // ok + end: (err2, res2) => { + if (err2) { + console.debug(res2.body); + + return done(err2); + } + + return done(); + } + }); + } + }); + }); + + it('should not allow edits to soft-deleted users', (done) => { + testUtils.putAsAdmin({ + route: '/user/' + testUtils.fixtures.user[3].id, + data: { + firstName: 'Bob', + lastName: 'Lobla', + email: 'no@pe.come' + }, + expectedStatus: 400, // bad request + end: (err, res) => { + if (err) { + console.debug(res.body); + + return done(err); + } + + res.body.should.haveOwnProperty('errorMessages'); + res.body.errorMessages.length.should.eq(1); + res.body.errorMessages[0].should.eq('This user has been deleted, and can not be edited until reactivated.'); + + return done(); + } + }); + }); +}); diff --git a/test/utilities.js b/test/utilities.js index c19249c..34c333f 100644 --- a/test/utilities.js +++ b/test/utilities.js @@ -3,10 +3,10 @@ const st = require('supertest'); const apiPrefix = '/api/v1'; module.exports = function(sails) { - // Login handling is dealt with in startTests.js. - const sendRequestAsAnon = st(sails.hooks.http.app); // anon browser - const sendRequestAsUser = st.agent(sails.hooks.http.app); // browser with cookies - const sendRequestAsAdmin = st.agent(sails.hooks.http.app); + // Logins are handled in startTests.js. + const sendRequestAsAnon = st(sails.hooks.http.app); // Anon browser. Not authenticated. + const sendRequestAsUser = st.agent(sails.hooks.http.app); // Browser with cookies; will be logged-in as user. + const sendRequestAsAdmin = st.agent(sails.hooks.http.app); // Different browser with cookies; will be logged-in as admin. sendRequestAsUser._csrf = 'none'; sendRequestAsAdmin._csrf = 'none'; diff --git a/views/README.md b/views/README.md index 75b8a7a..342f6b8 100644 --- a/views/README.md +++ b/views/README.md @@ -1,7 +1,9 @@ # Sails.js Views -Generally speaking, you do not want to modify files in this folder. You likely want [`../assets/src`](../assets/src) folder, where the React source files live. +Generally speaking, you do not want to modify files in this folder. You likely want [`../assets/src`](../assets/src) folder, where the [React](https://react.dev) source files live. The error pages are still in-use, when appropriate, and you will likely want to modify those. Sails is still setup to use EJS, to help make crafting emails easier. + +See: https://sailsjs.com/documentation/concepts/views From bf2c560f2af3ad4aac4978833eb0edadcd972085 Mon Sep 17 00:00:00 2001 From: NeoNexus DeMortis Date: Sat, 6 Jan 2024 17:43:51 -0600 Subject: [PATCH 2/2] Minor tweaks. --- CHANGELOG.md | 6 +- README.md | 14 +- 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-lock.json | 412 -------------------------- package.json | 2 +- 12 files changed, 43 insertions(+), 435 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/README.md b/README.md index 8ce0258..544b182 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,17 @@ [![Discord Server](https://img.shields.io/badge/Discord_server-silver?logo=discord)](http://discord.gg/Y5K73E84Tc) -Kick-start your project with this startup in a box. +This is a starter application, built on [Sails v1](https://sailsjs.com), [React](https://react.dev), [Bootstrap](https://getbootstrap.com), and [Webpack](https://webpack.js.org). It is designed +so that multiple front-ends (a customer front-end, and an admin panel perhaps; more if need be) can live side-by-side, and use the same API. It even has built-in [Ngrok support](#working-with-ngrok). +A virtual start-up in a box! + +## Quick Install + +```shell +npx drfg neonexus/sails-react-bootstrap-webpack my-new-site +npm run setup +npm run start OR npm run ngrok +``` ## Table of Contents @@ -53,7 +63,7 @@ Kick-start your project with this startup in a box. * Automatic (incoming) request logging (manual outgoing), via Sails models / hooks. * Setup for Webpack auto-reload dev server. Build; save; auto-reload. * Setup so Sails will serve Webpack-built bundles as separate apps (so, a marketing site, and an admin site can live side-by-side). -* More than a few custom [helper functions](api/helpers) to make life a little easier. +* More than a few custom [API helper functions](api/helpers) to make life a little easier. * Includes [react-bootstrap](https://www.npmjs.com/package/react-bootstrap) to make using Bootstrap styles / features with React easier. * Schema validation and enforcement for `PRODUCTION`. See [schema validation and enforcement](#schema-validation-and-enforcement). * New passwords will be checked against the [PwnedPasswords API](https://haveibeenpwned.com/API/v3#PwnedPasswords). If there is a single hit for the password, an error will be given, and the user will 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-lock.json b/package-lock.json index fb19804..39b4345 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1899,16 +1899,6 @@ "node": ">=10.0.0" } }, - "node_modules/@emnapi/runtime": { - "version": "0.44.0", - "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-0.44.0.tgz", - "integrity": "sha512-ZX/etZEZw8DR7zAB1eVQT40lNo0jeqpb6dCgOvctB6FIQ5PoXfMuNY8+ayQfu8tNQbAB8gQWSSJupR8NxeiZXw==", - "dev": true, - "optional": true, - "dependencies": { - "tslib": "^2.4.0" - } - }, "node_modules/@eslint-community/eslint-utils": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.2.0.tgz", @@ -2034,32 +2024,6 @@ "integrity": "sha512-dvuCeX5fC9dXgJn9t+X5atfmgQAzUOWqS1254Gh0m6i8wKd10ebXkfNKiRK+1GWi/yTvvLDHpoxLr0xxxeslWw==", "dev": true }, - "node_modules/@img/sharp-darwin-arm64": { - "version": "0.33.1", - "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.33.1.tgz", - "integrity": "sha512-esr2BZ1x0bo+wl7Gx2hjssYhjrhUsD88VQulI0FrG8/otRQUOxLWHMBd1Y1qo2Gfg2KUvXNpT0ASnV9BzJCexw==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "glibc": ">=2.26", - "node": "^18.17.0 || ^20.3.0 || >=21.0.0", - "npm": ">=9.6.5", - "pnpm": ">=7.1.0", - "yarn": ">=3.2.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-darwin-arm64": "1.0.0" - } - }, "node_modules/@img/sharp-darwin-x64": { "version": "0.33.1", "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.33.1.tgz", @@ -2086,28 +2050,6 @@ "@img/sharp-libvips-darwin-x64": "1.0.0" } }, - "node_modules/@img/sharp-libvips-darwin-arm64": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.0.0.tgz", - "integrity": "sha512-VzYd6OwnUR81sInf3alj1wiokY50DjsHz5bvfnsFpxs5tqQxESoHtJO6xyksDs3RIkyhMWq2FufXo6GNSU9BMw==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "macos": ">=11", - "npm": ">=9.6.5", - "pnpm": ">=7.1.0", - "yarn": ">=3.2.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - } - }, "node_modules/@img/sharp-libvips-darwin-x64": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.0.0.tgz", @@ -2130,360 +2072,6 @@ "url": "https://opencollective.com/libvips" } }, - "node_modules/@img/sharp-libvips-linux-arm": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.0.0.tgz", - "integrity": "sha512-VwgD2eEikDJUk09Mn9Dzi1OW2OJFRQK+XlBTkUNmAWPrtj8Ly0yq05DFgu1VCMx2/DqCGQVi5A1dM9hTmxf3uw==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "glibc": ">=2.28", - "npm": ">=9.6.5", - "pnpm": ">=7.1.0", - "yarn": ">=3.2.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-libvips-linux-arm64": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.0.0.tgz", - "integrity": "sha512-xTYThiqEZEZc0PRU90yVtM3KE7lw1bKdnDQ9kCTHWbqWyHOe4NpPOtMGy27YnN51q0J5dqRrvicfPbALIOeAZA==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "glibc": ">=2.26", - "npm": ">=9.6.5", - "pnpm": ">=7.1.0", - "yarn": ">=3.2.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-libvips-linux-s390x": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.0.0.tgz", - "integrity": "sha512-o9E46WWBC6JsBlwU4QyU9578G77HBDT1NInd+aERfxeOPbk0qBZHgoDsQmA2v9TbqJRWzoBPx1aLOhprBMgPjw==", - "cpu": [ - "s390x" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "glibc": ">=2.28", - "npm": ">=9.6.5", - "pnpm": ">=7.1.0", - "yarn": ">=3.2.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-libvips-linux-x64": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.0.0.tgz", - "integrity": "sha512-naldaJy4hSVhWBgEjfdBY85CAa4UO+W1nx6a1sWStHZ7EUfNiuBTTN2KUYT5dH1+p/xij1t2QSXfCiFJoC5S/Q==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "glibc": ">=2.26", - "npm": ">=9.6.5", - "pnpm": ">=7.1.0", - "yarn": ">=3.2.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-libvips-linuxmusl-arm64": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.0.0.tgz", - "integrity": "sha512-OdorplCyvmSAPsoJLldtLh3nLxRrkAAAOHsGWGDYfN0kh730gifK+UZb3dWORRa6EusNqCTjfXV4GxvgJ/nPDQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "musl": ">=1.2.2", - "npm": ">=9.6.5", - "pnpm": ">=7.1.0", - "yarn": ">=3.2.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-libvips-linuxmusl-x64": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.0.0.tgz", - "integrity": "sha512-FW8iK6rJrg+X2jKD0Ajhjv6y74lToIBEvkZhl42nZt563FfxkCYacrXZtd+q/sRQDypQLzY5WdLkVTbJoPyqNg==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "musl": ">=1.2.2", - "npm": ">=9.6.5", - "pnpm": ">=7.1.0", - "yarn": ">=3.2.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-linux-arm": { - "version": "0.33.1", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.33.1.tgz", - "integrity": "sha512-Ii4X1vnzzI4j0+cucsrYA5ctrzU9ciXERfJR633S2r39CiD8npqH2GMj63uFZRCFt3E687IenAdbwIpQOJ5BNA==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "glibc": ">=2.28", - "node": "^18.17.0 || ^20.3.0 || >=21.0.0", - "npm": ">=9.6.5", - "pnpm": ">=7.1.0", - "yarn": ">=3.2.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-linux-arm": "1.0.0" - } - }, - "node_modules/@img/sharp-linux-arm64": { - "version": "0.33.1", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.33.1.tgz", - "integrity": "sha512-59B5GRO2d5N3tIfeGHAbJps7cLpuWEQv/8ySd9109ohQ3kzyCACENkFVAnGPX00HwPTQcaBNF7HQYEfZyZUFfw==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "glibc": ">=2.26", - "node": "^18.17.0 || ^20.3.0 || >=21.0.0", - "npm": ">=9.6.5", - "pnpm": ">=7.1.0", - "yarn": ">=3.2.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-linux-arm64": "1.0.0" - } - }, - "node_modules/@img/sharp-linux-s390x": { - "version": "0.33.1", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.33.1.tgz", - "integrity": "sha512-tRGrb2pHnFUXpOAj84orYNxHADBDIr0J7rrjwQrTNMQMWA4zy3StKmMvwsI7u3dEZcgwuMMooIIGWEWOjnmG8A==", - "cpu": [ - "s390x" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "glibc": ">=2.28", - "node": "^18.17.0 || ^20.3.0 || >=21.0.0", - "npm": ">=9.6.5", - "pnpm": ">=7.1.0", - "yarn": ">=3.2.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-linux-s390x": "1.0.0" - } - }, - "node_modules/@img/sharp-linux-x64": { - "version": "0.33.1", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.33.1.tgz", - "integrity": "sha512-4y8osC0cAc1TRpy02yn5omBeloZZwS62fPZ0WUAYQiLhSFSpWJfY/gMrzKzLcHB9ulUV6ExFiu2elMaixKDbeg==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "glibc": ">=2.26", - "node": "^18.17.0 || ^20.3.0 || >=21.0.0", - "npm": ">=9.6.5", - "pnpm": ">=7.1.0", - "yarn": ">=3.2.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-linux-x64": "1.0.0" - } - }, - "node_modules/@img/sharp-linuxmusl-arm64": { - "version": "0.33.1", - "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.33.1.tgz", - "integrity": "sha512-D3lV6clkqIKUizNS8K6pkuCKNGmWoKlBGh5p0sLO2jQERzbakhu4bVX1Gz+RS4vTZBprKlWaf+/Rdp3ni2jLfA==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "musl": ">=1.2.2", - "node": "^18.17.0 || ^20.3.0 || >=21.0.0", - "npm": ">=9.6.5", - "pnpm": ">=7.1.0", - "yarn": ">=3.2.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-linuxmusl-arm64": "1.0.0" - } - }, - "node_modules/@img/sharp-linuxmusl-x64": { - "version": "0.33.1", - "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.33.1.tgz", - "integrity": "sha512-LOGKNu5w8uu1evVqUAUKTix2sQu1XDRIYbsi5Q0c/SrXhvJ4QyOx+GaajxmOg5PZSsSnCYPSmhjHHsRBx06/wQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "musl": ">=1.2.2", - "node": "^18.17.0 || ^20.3.0 || >=21.0.0", - "npm": ">=9.6.5", - "pnpm": ">=7.1.0", - "yarn": ">=3.2.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-linuxmusl-x64": "1.0.0" - } - }, - "node_modules/@img/sharp-wasm32": { - "version": "0.33.1", - "resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.33.1.tgz", - "integrity": "sha512-vWI/sA+0p+92DLkpAMb5T6I8dg4z2vzCUnp8yvxHlwBpzN8CIcO3xlSXrLltSvK6iMsVMNswAv+ub77rsf25lA==", - "cpu": [ - "wasm32" - ], - "dev": true, - "optional": true, - "dependencies": { - "@emnapi/runtime": "^0.44.0" - }, - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0", - "npm": ">=9.6.5", - "pnpm": ">=7.1.0", - "yarn": ">=3.2.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-win32-ia32": { - "version": "0.33.1", - "resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.33.1.tgz", - "integrity": "sha512-/xhYkylsKL05R+NXGJc9xr2Tuw6WIVl2lubFJaFYfW4/MQ4J+dgjIo/T4qjNRizrqs/szF/lC9a5+updmY9jaQ==", - "cpu": [ - "ia32" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0", - "npm": ">=9.6.5", - "pnpm": ">=7.1.0", - "yarn": ">=3.2.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-win32-x64": { - "version": "0.33.1", - "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.33.1.tgz", - "integrity": "sha512-XaM69X0n6kTEsp9tVYYLhXdg7Qj32vYJlAKRutxUsm1UlgQNx6BOhHwZPwukCGXBU2+tH87ip2eV1I/E8MQnZg==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0", - "npm": ">=9.6.5", - "pnpm": ">=7.1.0", - "yarn": ">=3.2.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - } - }, "node_modules/@istanbuljs/load-nyc-config": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", 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",