Skip to content

Commit d25fd17

Browse files
committed
Converted mocaharc.yml -> .mocharc for better consistency. Made Ngrok script capable of installing @ngrok/ngrok. Built the datastore wipe. Updated dependencies.
1 parent 82ab95f commit d25fd17

29 files changed

+1380
-868
lines changed

.editorconfig

+6-8
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,16 @@
33
# ║╣ ║║║ ║ ║ ║╠╦╝│ │ ││││├┤ ││ ┬
44
# o╚═╝═╩╝╩ ╩ ╚═╝╩╚═└─┘└─┘┘└┘└ ┴└─┘
55
#
6-
# > Formatting conventions for your Sails app.
6+
# > Formatting conventions for your app.
77
#
88
# This file (`.editorconfig`) exists to help
99
# maintain consistent formatting throughout the
10-
# files in your Sails app.
10+
# files in your app.
1111
#
12-
# For the sake of convention, the Sails team's
13-
# preferred settings are included here out of the
14-
# box. You can also change this file to fit your
15-
# team's preferences (for example, if all of the
16-
# developers on your team have a strong preference
17-
# for tabs over spaces),
12+
# These defaults have proven to be effective
13+
# though many teams / years / projects. 4 spaces
14+
# is much easier to see block separations than
15+
# with just 2 (as is the Sails default).
1816
#
1917
# To review what each of these options mean, see:
2018
# http://editorconfig.org/

.idea/runConfigurations/Run_Tests.xml

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.mocharc

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
{
2+
"bail": false,
3+
"async-only": true,
4+
"require": [
5+
"test/startTests.js"
6+
],
7+
"spec": [
8+
"test/unit/index.js",
9+
"test/integration/index.js"
10+
],
11+
"timeout": 60000,
12+
"checkLeaks": true,
13+
"global": [
14+
"_",
15+
"sails",
16+
"__core-js_shared__",
17+
"Archive",
18+
"User",
19+
"Session",
20+
"RequestLog",
21+
"Log",
22+
"__coverage__",
23+
"match"
24+
]
25+
}

.mocharc.yml

-20
This file was deleted.

CHANGELOG.md

+15-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,17 @@
11
# Changelog
22

3+
## [v5.1.0](https://github.com/neonexus/sails-react-bootstrap-webpack/compare/v5.0.0...v5.1.0) (2023-12-22)
4+
### Features
5+
6+
* Minor tweaks / fixes.
7+
* Created the datastore wipe script, to reset LOCAL / DEVELOPMENT datastore. Will **not** run on PRODUCTION (or when migrate = "safe").
8+
* Converted `.mocharc.yml` -> `.mocharc` (JSON) to be more consistent.
9+
* Made the Ngrok script capable of installing [`@ngrok/ngrok`](https://npmjs.com/package/@ngrok/ngrok) when needed.
10+
* Minor visual fix in security settings page.
11+
* Built the "reactivate user" endpoint.
12+
* Corrected "edit" and "delete" user routes to use ID in the route.
13+
* Updated dependencies.
14+
315
## [v5.0.0](https://github.com/neonexus/sails-react-bootstrap-webpack/compare/v4.3.1...v5.0.0) (2023-12-05)
416
### Features
517

@@ -277,4 +289,6 @@
277289
* Fixed webpack config.
278290
* Made `isLoggedIn` policy clear cookie if not logged in.
279291

280-
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).
292+
<br/><br/>
293+
294+
#### 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).

README.md

+6-9
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,14 @@
22

33
[![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)
44
[![Codecov](https://img.shields.io/codecov/c/github/neonexus/sails-react-bootstrap-webpack?logo=codecov)](https://codecov.io/gh/neonexus/sails-react-bootstrap-webpack)
5-
[![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)
6-
[![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)
7-
[![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)
8-
[![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)
5+
[![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)
6+
[![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)
7+
[![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)
8+
[![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)
99

1010
[![Discord Server](https://img.shields.io/badge/Discord_server-silver?logo=discord)](http://discord.gg/Y5K73E84Tc)
1111

12-
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)
13-
(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
14-
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
15-
compiled before it is handed to the end user), they can share [NPM](http://npmjs.com) libraries, like [Moment.js](https://momentjs.com)
12+
Kick-start your project with this startup in a box.
1613

1714
## Table of Contents
1815

@@ -449,7 +446,7 @@ It may also be a good idea to consider using something like [Nginx](https://ngin
449446

450447
## Schema Validation and Enforcement
451448

452-
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
449+
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
453450
feature.
454451

455452
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 (

api/controllers/admin/edit-user.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -45,13 +45,13 @@ module.exports = {
4545

4646
setPassword: {
4747
type: 'boolean',
48-
defaultsTo: true
48+
defaultsTo: false
4949
}
5050
},
5151

5252
exits: {
5353
ok: {
54-
responseType: 'created'
54+
responseType: 'ok'
5555
},
5656
badRequest: {
5757
responseType: 'badRequest'
+47
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
module.exports = {
2+
friendlyName: 'Reactivate User',
3+
4+
description: 'Reactivate a soft-deleted user.',
5+
6+
inputs: {
7+
id: {
8+
type: 'string',
9+
required: true,
10+
isUUID: true
11+
}
12+
},
13+
14+
exits: {
15+
ok: {
16+
responseType: 'ok'
17+
},
18+
badRequest: {
19+
responseType: 'badRequest'
20+
},
21+
serverError: {
22+
responseType: 'serverError'
23+
}
24+
},
25+
26+
fn: async (inputs, exits) => {
27+
const foundUser = await sails.models.user.findOne({id: inputs.id});
28+
29+
if (!foundUser) {
30+
return exits.badRequest('There is no user with that ID.');
31+
}
32+
33+
if (!foundUser.deletedAt) {
34+
return exits.badRequest('User is already active.');
35+
}
36+
37+
const activeUser = await sails.models.user.findOne({email: foundUser.email, deletedAt: null});
38+
39+
if (activeUser) {
40+
return exits.badRequest('There is already an active user with the email address ' + activeUser.email);
41+
}
42+
43+
await sails.models.user.update({id: inputs.id}).set({deletedAt: null});
44+
45+
return exits.ok();
46+
}
47+
};

api/models/User.js

+7-7
Original file line numberDiff line numberDiff line change
@@ -166,23 +166,23 @@ module.exports = {
166166
},
167167

168168
beforeUpdate: async function(user, next) {
169-
if (user.email && user.email !== '') {
169+
if (user.email && user.email.trim().length) {
170170
const email = user.email.toLowerCase().trim();
171171

172172
user.email = email;
173173
user.avatar = getGravatarUrl(email);
174174
}
175175

176-
if (user.firstName && user.firstName !== '') {
177-
user.firstName = forceUppercaseOnFirst(user.firstName);
176+
if (user.firstName && user.firstName.trim().length) {
177+
user.firstName = forceUppercaseOnFirst(user.firstName.trim());
178178
}
179179

180-
if (user.lastName && user.lastName !== '') {
181-
user.lastName = forceUppercaseOnFirst(user.lastName);
180+
if (user.lastName && user.lastName.trim().length) {
181+
user.lastName = forceUppercaseOnFirst(user.lastName.trim());
182182
}
183183

184-
if (user.password && user.password !== '') {
185-
user.password = await updatePassword(user.password);
184+
if (user.password && user.password !== '' && user.password.length > 7) {
185+
user.password = await updatePassword(user.password.trim());
186186
}
187187

188188
return next();

assets/src/Admin/AdminRouter.jsx

+5-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Component, StrictMode, Suspense, lazy } from 'react';
1+
import {Component, StrictMode, Suspense, lazy} from 'react';
22
import PropTypes from 'prop-types';
33
import '../../styles/admin/admin.scss';
44
import {
@@ -27,7 +27,10 @@ function RenderOrLogin(props) {
2727

2828
if (props.api) {
2929
return (
30-
<Login api={props.api} />
30+
<>
31+
<NavBar handleLogout={() => alert('logout')} />
32+
<Login api={props.api} />
33+
</>
3134
);
3235
}
3336

assets/src/Admin/NavBar.jsx

+12-6
Original file line numberDiff line numberDiff line change
@@ -93,11 +93,17 @@ function NavBar(props) {
9393
? <Nav.Link as={ReactNavLink} to="/admin/users" onClick={closeNavbar}>Users</Nav.Link>
9494
: null
9595
}
96-
<Nav.Link as={ReactNavLink} to="/admin/404" onClick={closeNavbar}>404 Page</Nav.Link>
97-
<NavDropdown title="Settings" id="basic-nav-dropdown">
98-
<NavDropdown.Item className="ps-3 pe-3" as={ReactNavLink} to="/admin/settings/profile" onClick={closeNavbar}><i className="bi bi-person-fill" /> Profile</NavDropdown.Item>
99-
<NavDropdown.Item className="ps-3 pe-3" as={ReactNavLink} to="/admin/settings/security" onClick={closeNavbar}><i className="bi bi-shield-lock-fill" /> Security</NavDropdown.Item>
100-
</NavDropdown>
96+
{
97+
(user.isLoggedIn)
98+
? <>
99+
<Nav.Link as={ReactNavLink} to="/admin/404" onClick={closeNavbar}>404 Page</Nav.Link>
100+
<NavDropdown title="Settings" id="basic-nav-dropdown">
101+
<NavDropdown.Item className="ps-3 pe-3" as={ReactNavLink} to="/admin/settings/profile" onClick={closeNavbar}><i className="bi bi-person-fill" /> Profile</NavDropdown.Item>
102+
<NavDropdown.Item className="ps-3 pe-3" as={ReactNavLink} to="/admin/settings/security" onClick={closeNavbar}><i className="bi bi-shield-lock-fill" /> Security</NavDropdown.Item>
103+
</NavDropdown>
104+
</>
105+
: null
106+
}
101107
</Nav>
102108

103109
{
@@ -109,7 +115,7 @@ function NavBar(props) {
109115
: null
110116
}
111117

112-
<NavDropdown title={<i className={'bi ' + lightDarkAutoClass}/>} id="light-or-dark-toggle" className="ms-3 right-align-menu">
118+
<NavDropdown title={<i className={'bi ' + lightDarkAutoClass} />} id="light-or-dark-toggle" className="ms-3 right-align-menu">
113119
<NavDropdown.Item className="bi bi-sun-fill" active={lightOrDark === 'light'} data-theme-set="light" onClick={switchTheme}>Light</NavDropdown.Item>
114120
<NavDropdown.Item className="bi bi-moon-fill" active={lightOrDark === 'dark'} data-theme-set="dark" onClick={switchTheme}>Dark</NavDropdown.Item>
115121
<NavDropdown.Item className="bi bi-circle-half" active={lightOrDark !== 'light' && lightOrDark !== 'dark'} data-theme-set="auto" onClick={switchTheme}>Auto</NavDropdown.Item>

assets/src/Admin/Settings/SecuritySection.jsx

+5-5
Original file line numberDiff line numberDiff line change
@@ -27,16 +27,16 @@ function SecuritySection(props) {
2727
<h2 className="mb-4 text-center">Security Settings</h2>
2828
<Row className="m-0 pt-2" style={{border: '1px solid #ddd', borderWidth: '1px 0 0 0'}}>
2929
<Col>
30-
<h3>Change Password</h3>
30+
<h3 className="pt-2">Change Password</h3>
3131
<p>Always a good idea to rotate your passwords.</p>
3232
</Col>
33-
<Col className="pt-3">
33+
<Col className="pt-4">
3434
<Button variant="secondary" className="float-end" onClick={() => setShowChangePassword(true)}>Change Password</Button>
3535
</Col>
3636
</Row>
3737
<Row className="m-0 pt-2" style={{border: '1px solid #ddd', borderWidth: '1px 0 1px 0'}}>
3838
<Col>
39-
<h3>
39+
<h3 className="pt-2">
4040
2-Factor Authentication
4141
{
4242
(user.info._isOTPEnabled)
@@ -46,7 +46,7 @@ function SecuritySection(props) {
4646
</h3>
4747
{
4848
(user.info._isOTPEnabled)
49-
? <p className="m-0">Nice! Your account security is even stronger, because 2FA is enabled.</p>
49+
? <p className="m-0 pb-3">Nice! Your account security is even stronger, because 2FA is enabled.</p>
5050
: <p>It is highly recommended to enable 2FA to increase security with your account.</p>
5151
}
5252

@@ -56,7 +56,7 @@ function SecuritySection(props) {
5656
// : null
5757
}
5858
</Col>
59-
<Col className="pt-3">
59+
<Col className="pt-4">
6060
{
6161
(user.info._isOTPEnabled)
6262
? <Button variant="danger" className="float-end" onClick={() => setShowDisableOTP(true)}>Disable 2FA</Button>

assets/src/Admin/Users/Users.jsx

+1-2
Original file line numberDiff line numberDiff line change
@@ -95,8 +95,7 @@ class Users extends Component {
9595

9696
handleDeleteUser(after) {
9797
this.props.api.del({
98-
url: '/user',
99-
body: {id: this.state.currentDeleteUser.id}
98+
url: '/user/' + this.state.currentDeleteUser.id,
10099
}, (resp) => {
101100
this.setState({showDeleteModal: false}, () => {
102101
this.getUsers(this.state.currentPage);

config/autoreload.js

+15-21
Original file line numberDiff line numberDiff line change
@@ -7,28 +7,22 @@
77
* For more info, see: https://www.npmjs.com/package/sails-hook-autoreload
88
*/
99

10-
module.exports = {
11-
autoreload: {
12-
active: true,
10+
module.exports.autoreload = {
11+
active: true,
1312

14-
dirs: [
15-
'api/controllers',
16-
'api/helpers',
17-
'api/hooks',
18-
'api/models',
19-
'api/policies',
20-
'api/responses',
21-
'config'
22-
],
13+
dirs: [
14+
'api/controllers',
15+
'api/helpers',
16+
'api/hooks',
17+
'api/models',
18+
'api/policies',
19+
'api/responses',
20+
'config'
21+
],
2322

24-
ignored: [
25-
'**.md'
26-
],
23+
ignored: [
24+
'**.md'
25+
],
2726

28-
overrideMigrateSetting: false
29-
},
30-
31-
models: {
32-
archiveModelIdentity: false
33-
}
27+
overrideMigrateSetting: false
3428
};

config/local.js.sample

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
*
44
* DON'T DELETE ME!!!
55
* The setup.js script requires a `local.js.sample` file to work.
6-
* Additionally, if you change values here, the setup script will need to be modified to match.
6+
* Additionally, if you change anything here, the setup script will likely need to be modified to match.
77
*/
88

99

0 commit comments

Comments
 (0)