Skip to content

Commit ccc3ddf

Browse files
committed
Added way to soft-delete users. Added minor improvements to CSRF.
1 parent 5c566e7 commit ccc3ddf

File tree

11 files changed

+97
-6
lines changed

11 files changed

+97
-6
lines changed

README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@
55
This is an opinionated base [Sails v1](https://sailsjs.com) application, using Webpack to handle Bootstrap (SASS) and React.
66

77
# Branch Warning
8-
The `master` branch is experimental, and the [release branch](https://github.com/neonexus/sails-react-bootstrap-webpack/tree/release) (or the [`releases section`](https://github.com/neonexus/sails-react-bootstrap-webpack/releases)) is where one should base their use of this template. `master` is **volatile**, likely to change at any time, for any reason; this includes `git push --force` updates.
8+
The `master` branch is experimental, and the [release branch](https://github.com/neonexus/sails-react-bootstrap-webpack/tree/release) (or the [`releases section`](https://github.com/neonexus/sails-react-bootstrap-webpack/releases)) is where one should base their use of this template.
9+
10+
`master` is **volatile**, likely to change at any time, for any reason; this includes `git push --force` updates.
911

1012
**FINAL WARNING: DO NOT RELY ON THE MASTER BRANCH!**
1113

api/controllers/admin/create-user.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ module.exports = {
5252
return exits.badRequest(isPasswordValid);
5353
}
5454

55-
const foundUser = await User.findOne({email: inputs.email});
55+
const foundUser = await User.findOne({email: inputs.email, deletedAt: null});
5656

5757
if (foundUser) {
5858
return exits.badRequest('Email is already in-use.');

api/controllers/admin/delete-user.js

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
const moment = require('moment-timezone');
2+
3+
module.exports = {
4+
friendlyName: 'Delete User',
5+
6+
description: 'Delete a user, give its ID',
7+
8+
inputs: {
9+
id: {
10+
type: 'string',
11+
required: true,
12+
isUUID: true
13+
}
14+
},
15+
16+
exits: {
17+
ok: {
18+
responseType: 'ok'
19+
},
20+
badRequest: {
21+
responseType: 'badRequest'
22+
},
23+
serverError: {
24+
responseType: 'serverError'
25+
}
26+
},
27+
28+
fn: async (inputs, exits, env) => {
29+
const foundUser = await User.findOne({id: inputs.id, deletedAt: null});
30+
31+
if (!foundUser) {
32+
return exits.badRequest('User does not exist');
33+
}
34+
35+
await Session.destroy({user: foundUser.id}); // force logout any active sessions user might have
36+
37+
await User.update({id: foundUser.id}).set(_.merge({}, foundUser, {
38+
deletedAt: moment.tz(sails.config.datastores.default.timezone).toDate(),
39+
deletedBy: env.req.session.user.id
40+
}));
41+
42+
return exits.ok();
43+
}
44+
};

api/controllers/admin/login.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ module.exports = {
3636
}
3737

3838
const badEmailPass = 'Bad email / password combination.';
39-
const foundUser = await User.findOne({email: inputs.email});
39+
const foundUser = await User.findOne({email: inputs.email, deletedAt: null});
4040

4141
if (!foundUser) {
4242
return exits.badRequest(badEmailPass);
@@ -70,6 +70,7 @@ module.exports = {
7070
isSession: true
7171
}
7272
],
73+
user: foundUser,
7374
_csrf: csrf.token
7475
});
7576
}

api/helpers/set-cookies.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ module.exports = {
4141
return inputs.res.clearCookie(cookie.name, defaultCookie);
4242
}
4343

44-
const newCookie = (cookie.isSession)
44+
const newCookie = (!cookie.isSession) // if we don't want to use the default "session" to expire the cookie, we use the maxAge
4545
? _.merge({}, defaultCookie, {maxAge: sails.config.session.cookie.maxAge})
4646
: defaultCookie;
4747

api/helpers/update-csrf.js

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
module.exports = {
2+
friendlyName: 'Update CSRF',
3+
4+
description: 'Update the CSRF secret, and append the token to the res.',
5+
6+
inputs: {
7+
data: {
8+
type: 'ref',
9+
required: true
10+
},
11+
12+
req: {
13+
type: 'ref',
14+
required: true
15+
}
16+
},
17+
18+
exits: {},
19+
20+
fn: async (inputs, exits) => {
21+
if (inputs.req.method === 'GET' || !inputs.req.session || !inputs.req.session.user || !inputs.req.session.id) {
22+
return exits.success(inputs.data);
23+
}
24+
25+
const foundSession = await Session.findOne({id: inputs.req.session.id});
26+
27+
const csrf = sails.helpers.generateCsrfToken();
28+
const newData = _.merge({}, foundSession.data, {_csrfSecret: csrf.secret});
29+
30+
Session.update({id: inputs.req.session.id}).set({
31+
data: newData
32+
}).exec((err) => {
33+
if (err) {
34+
throw new Error(err);
35+
}
36+
37+
return exits.success(_.merge({}, inputs.data, {_csrf: csrf.token}));
38+
});
39+
}
40+
};

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,
5454
columnType: 'varchar(191)'
5555
},
5656

api/responses/created.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ module.exports = async function created(data) {
1212

1313
data = sails.helpers.keepModelsSafe(data);
1414
data = sails.helpers.setCookies(data, res);
15+
data = await sails.helpers.updateCsrf(data, req);
1516

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

api/responses/ok.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ module.exports = async function sendOK(data) {
1212

1313
data = sails.helpers.keepModelsSafe(data);
1414
data = sails.helpers.setCookies(data, res);
15+
data = await sails.helpers.updateCsrf(data, req);
1516

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

config/policies.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ module.exports.policies = {
1414
AdminController: {
1515
'*': 'isLoggedIn',
1616
'login': true,
17-
'create-user': ['isLoggedIn', 'isAdmin']
17+
'create-user': ['isLoggedIn', 'isAdmin'],
18+
'delete-user': ['isLoggedIn', 'isAdmin']
1819
}
1920
};

0 commit comments

Comments
 (0)