Skip to content

Commit b937f3b

Browse files
authored
Merge pull request #64 from neonexus/master
Started build out of workable user management...
2 parents 930ea07 + bc391e5 commit b937f3b

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

74 files changed

+1394
-315
lines changed

CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,12 @@
11
# Changelog
22

3+
## [v3.1.0](https://github.com/neonexus/sails-react-bootstrap-webpack/compare/v3.0.3...v3.1.0) (2022-09-05)
4+
5+
### Features
6+
7+
* Built start of new user management page, mostly for proof-of-concept purposes.
8+
* Built "semi-smart" pagination front-end components. More tweaks are required.
9+
310
## [v3.0.3](https://github.com/neonexus/sails-react-bootstrap-webpack/compare/v3.0.2...v3.0.3) (2022-08-18)
411

512
### Features

Dockerfile

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ RUN apt-get install -y curl ntp nano
66
RUN mkdir /var/www && mkdir /var/www/myapp
77
WORKDIR /var/www/myapp
88

9+
# If you change the exposed port, you need to also change the environment variable PORT below to the same port, or nothing will work
910
EXPOSE 1337
1011
# REMEMBER! NEVER STORE SECRETS, DEK's, PASSWORDS, OR ANYTHING OF A SENSITIVE NATURE IN SOURCE CONTROL (INCLUDING THIS FILE)! USE ENVIRONMENT VARIABLES!
1112
ENV PORT=1337 DB_HOSTNAME=dockerdb DB_USERNAME=dockeruser DB_PASSWORD=dockerpass DB_NAME=docker DB_PORT=3306 DB_SSL=true DATA_ENCRYPTION_KEY=1234abcd4321asdf0987lkjh SESSION_SECRET=0987poiuqwer1234zxcvmnbv
@@ -14,9 +15,16 @@ ENV PORT=1337 DB_HOSTNAME=dockerdb DB_USERNAME=dockeruser DB_PASSWORD=dockerpass
1415
COPY package.json /var/www/myapp/package.json
1516
RUN npm install
1617

17-
COPY . /var/www/myapp/
18+
# More caching help
19+
COPY ./* /var/www/myapp/
20+
COPY config /var/www/myapp/config
21+
COPY assets /var/www/myapp/assets
22+
COPY webpack /var/www/myapp/webpack
1823
RUN npm run build
1924

25+
# Copy the reset of the app
26+
COPY . /var/www/myapp/
27+
2028
# Expose the compiled public assets, so Nginx can route to them, instead of using Sails to do the file serving.
2129
VOLUME /var/www/myapp/.tmp/public
2230

api/controllers/admin/create-user.js

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ module.exports = {
1818

1919
password: {
2020
type: 'string',
21-
required: true,
2221
maxLength: 70
2322
},
2423

@@ -36,6 +35,11 @@ module.exports = {
3635
'user',
3736
'admin'
3837
]
38+
},
39+
40+
setPassword: {
41+
type: 'boolean',
42+
defaultsTo: true
3943
}
4044
},
4145

@@ -52,10 +56,18 @@ module.exports = {
5256
},
5357

5458
fn: async (inputs, exits) => {
55-
const isPasswordValid = sails.helpers.isPasswordValid.with({
56-
password: inputs.password,
57-
user: {firstName: inputs.firstName, lastName: inputs.lastName, email: inputs.email}
58-
});
59+
let password = inputs.password;
60+
let isPasswordValid;
61+
62+
if (inputs.setPassword) {
63+
isPasswordValid = sails.helpers.isPasswordValid.with({
64+
password: inputs.password,
65+
user: {firstName: inputs.firstName, lastName: inputs.lastName, email: inputs.email}
66+
});
67+
} else {
68+
isPasswordValid = true;
69+
password = sails.helpers.generateToken();
70+
}
5971

6072
if (isPasswordValid !== true) {
6173
return exits.badRequest(isPasswordValid);
@@ -71,7 +83,7 @@ module.exports = {
7183
id: 'c', // required, but auto-generated
7284
firstName: inputs.firstName,
7385
lastName: inputs.lastName,
74-
password: inputs.password,
86+
password,
7587
role: inputs.role,
7688
email: inputs.email
7789
}).meta({fetch: true}).exec((err, newUser) => {
@@ -81,6 +93,10 @@ module.exports = {
8193
return exits.serverError(err);
8294
}
8395

96+
/**
97+
* We should probably email the new user their new account info here if the password was generated (!inputs.setPassword)...
98+
*/
99+
84100
return exits.ok({user: newUser});
85101
});
86102
}

api/controllers/admin/get-users.js

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
module.exports = {
2+
friendlyName: 'Get Users',
3+
4+
description: 'Get paginated list of users',
5+
6+
inputs: {
7+
page: {
8+
description: 'The page number to return',
9+
type: 'number',
10+
defaultsTo: 1,
11+
min: 1
12+
},
13+
14+
limit: {
15+
description: 'The amount of users to return',
16+
type: 'number',
17+
defaultsTo: 25,
18+
min: 10,
19+
max: 500
20+
}
21+
},
22+
23+
exits: {
24+
ok: {
25+
responseType: 'ok'
26+
},
27+
badRequest: {
28+
responseType: 'badRequest'
29+
},
30+
serverError: {
31+
responseType: 'serverError'
32+
}
33+
},
34+
35+
fn: async (inputs, exits) => {
36+
const pagination = sails.helpers.paginateForQuery.with({
37+
limit: inputs.limit,
38+
page: inputs.page
39+
});
40+
41+
const users = await sails.models.user.find(_.omit(pagination, ['page']));
42+
43+
let out = await sails.helpers.paginateForJson.with({
44+
model: sails.models.user,
45+
query: pagination,
46+
objToWrap: {users: []}
47+
});
48+
49+
// We assign the users to the object afterward, so we can run our safety checks.
50+
// Otherwise, if we were to put the users object into "objToWrap", they would be transformed, and the "customToJSON" feature would no longer work, and hashed passwords would leak.
51+
out.users = users;
52+
53+
return exits.ok(out);
54+
}
55+
};

api/helpers/create-log.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,9 @@ module.exports = {
3030

3131
const newLog = {
3232
data: inputs.data,
33-
user: user,
34-
account: account,
35-
request: request,
33+
user,
34+
account,
35+
request,
3636
description: inputs.description
3737
};
3838

api/helpers/generate-token.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ module.exports = {
2323
crypto.createHmac('sha256', sails.config.session.secret).update(
2424
crypto.randomBytes(21) // cryptographically-secure random characters
2525
+ moment(new Date()).format() // throw in the current time stamp
26-
+ 'I am a tea pot' // the best HTTP status code
26+
+ 'I\'m a tea pot' // the best HTTP status code
2727
+ inputs.extra // an optional way to add a bit more randomness to the mix
2828
+ crypto.randomBytes(21)
2929
).digest('hex')

api/helpers/is-password-valid.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ module.exports = {
2626

2727
if (inputs.password.length > 70) {
2828
// this 70-character limit is not arbitrary, it is the max size of MySQL utf8mb4 encoding
29-
// (71 characters balloons past the 191 character limit of utf8mb4 varchar columns after hashing)
29+
// (71 characters balloons past the 191-character limit of utf8mb4 varchar columns after hashing)
3030
errors.push('WOW. Password length is TOO good. Max is 70 characters. Sorry.');
3131
}
3232

api/models/User.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ module.exports = {
5050
type: 'string',
5151
isEmail: true,
5252
required: true,
53-
unique: true,
53+
// unique: true, // can NOT be unique, if we are using soft-deleted users; controller must deal with uniqueness
5454
columnType: 'varchar(191)'
5555
},
5656

api/responses/badRequest.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ module.exports = async function badRequest(msg) {
99
const out = {
1010
success: false,
1111
errors: await sails.helpers.simplifyErrors(msg),
12-
errorMessages: await sails.helpers.getErrorMessages(msg)
12+
errorMessages: await sails.helpers.getErrorMessages(msg),
13+
raw: msg
1314
};
1415

1516
res.status(400).json(out);

api/responses/created.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ module.exports = async function created(data) {
1111
}
1212

1313
data = sails.helpers.keepModelsSafe(data);
14-
data = sails.helpers.setCookies(data, res);
14+
data = sails.helpers.setOrRemoveCookies(data, res);
1515
data = await sails.helpers.updateCsrf(data, req);
1616

1717
const out = _.merge({success: true}, data);

0 commit comments

Comments
 (0)