Skip to content

Commit 38bd4b1

Browse files
authored
Merge pull request #220 from CodeForBaltimore/revjtanton/issue-216
Issue 216
2 parents 03869ce + f04ec99 commit 38bd4b1

File tree

6 files changed

+179
-143
lines changed

6 files changed

+179
-143
lines changed

sequelize/data/user-role.json

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,11 @@
2525
"path": "/entity",
2626
"method": "GET"
2727
},
28+
{
29+
"role": "user",
30+
"path": "/entity/*",
31+
"method": "GET"
32+
},
2833
{
2934
"role": "user",
3035
"path": "/entity",
@@ -40,6 +45,11 @@
4045
"path": "/contact",
4146
"method": "GET"
4247
},
48+
{
49+
"role": "user",
50+
"path": "/contact/*",
51+
"method": "GET"
52+
},
4353
{
4454
"role": "user",
4555
"path": "/contact",

src/models/user.js

Lines changed: 105 additions & 101 deletions
Original file line numberDiff line numberDiff line change
@@ -3,40 +3,40 @@ import jwt from 'jsonwebtoken'
33
import utils from '../utils'
44

55
const user = (sequelize, DataTypes) => {
6-
// Defining our user table and setting User object.
7-
const User = sequelize.define('User', {
8-
id: {
9-
type: DataTypes.UUID,
10-
primaryKey: true,
11-
defaultValue: DataTypes.UUIDV4,
12-
allowNull: false,
13-
autoIncrement: false,
14-
},
15-
email: {
16-
type: DataTypes.STRING,
17-
unique: true,
18-
required: true
19-
},
20-
password: {
21-
type: DataTypes.STRING,
22-
required: true
23-
},
24-
salt: {
25-
type: DataTypes.STRING
26-
},
27-
displayName: {
28-
type: DataTypes.STRING
29-
},
30-
phone: {
31-
type: DataTypes.STRING
32-
},
33-
attributes: {
34-
type: DataTypes.JSON,
35-
}
36-
},
37-
{
38-
schema: process.env.DATABASE_SCHEMA
39-
})
6+
// Defining our user table and setting User object.
7+
const User = sequelize.define('User', {
8+
id: {
9+
type: DataTypes.UUID,
10+
primaryKey: true,
11+
defaultValue: DataTypes.UUIDV4,
12+
allowNull: false,
13+
autoIncrement: false,
14+
},
15+
email: {
16+
type: DataTypes.STRING,
17+
unique: true,
18+
required: true
19+
},
20+
password: {
21+
type: DataTypes.STRING,
22+
required: true
23+
},
24+
salt: {
25+
type: DataTypes.STRING
26+
},
27+
displayName: {
28+
type: DataTypes.STRING
29+
},
30+
phone: {
31+
type: DataTypes.STRING
32+
},
33+
attributes: {
34+
type: DataTypes.JSON,
35+
}
36+
},
37+
{
38+
schema: process.env.DATABASE_SCHEMA
39+
})
4040

4141
/**
4242
* Looks up and validates a user by email and password.
@@ -46,40 +46,44 @@ const user = (sequelize, DataTypes) => {
4646
*
4747
* @return {String} returns either the valid login token or an error message.
4848
*/
49-
User.findByLogin = async (email, password) => {
50-
const user = await User.findOne({
51-
where: {email}
52-
})
53-
if (user) {
54-
const pw = User.encryptPassword(password, user.salt)
55-
if (pw === user.password) {
56-
return await User.getToken(user.id, user.email)
57-
}
58-
}
59-
}
60-
61-
User.decodeToken = async token => {
62-
return jwt.verify(token, process.env.JWT_KEY)
63-
}
64-
65-
/** @todo deprecate this */
66-
User.getToken = async (userId, email, expiresIn = '1d') => {
67-
const token = jwt.sign(
68-
{userId, email, type: 'user'},
69-
process.env.JWT_KEY,
70-
{expiresIn}
71-
)
72-
return token
73-
}
49+
User.findByLogin = async (email, password) => {
50+
const user = await User.findOne({
51+
where: { email }
52+
})
53+
if (user) {
54+
const pw = User.encryptPassword(password, user.salt)
55+
if (pw === user.password) {
56+
57+
const e = await utils.loadCasbin()
58+
const roles = await e.getRolesForUser(user.email)
59+
60+
return await User.getToken(user.id, user.email, roles[0])
61+
}
62+
}
63+
}
64+
65+
User.decodeToken = async token => {
66+
return jwt.verify(token, process.env.JWT_KEY)
67+
}
68+
69+
/** @todo deprecate this */
70+
User.getToken = async (userId, email, type, expiresIn = '1d') => {
71+
const token = jwt.sign(
72+
{ userId, email, type },
73+
process.env.JWT_KEY,
74+
{ expiresIn }
75+
)
76+
return token
77+
}
7478

7579
/**
7680
* Generates a random salt for password security.
7781
*
7882
* @return {String} The password salt.
7983
*/
80-
User.generateSalt = () => {
81-
return crypto.randomBytes(16).toString('base64')
82-
}
84+
User.generateSalt = () => {
85+
return crypto.randomBytes(16).toString('base64')
86+
}
8387

8488
/**
8589
* Salts and hashes a password.
@@ -89,45 +93,45 @@ const user = (sequelize, DataTypes) => {
8993
*
9094
* @return {String} The secured password.
9195
*/
92-
User.encryptPassword = (plainText, salt) => {
93-
return crypto
94-
.createHash('RSA-SHA256')
95-
.update(plainText)
96-
.update(salt)
97-
.digest('hex')
98-
}
99-
100-
// Setters
101-
const setSaltAndPassword = user => {
102-
if (user.changed('password')) {
103-
user.salt = User.generateSalt()
104-
// User.password = User.encryptPassword(user.password, user.salt)
105-
user.password = utils.encryptPassword(user.password, user.salt)
106-
}
107-
}
108-
109-
// Other Helpers
110-
// const validateContactInfo = user => {
111-
// let valid = true
112-
113-
// if (!validator.isEmail(validator.normalizeEmail(user.email))) {
114-
// valid = false
115-
// }
116-
117-
// /** @todo Add more validations for all contact info. */
118-
119-
// return valid
120-
// }
121-
122-
// Create prep actions
123-
// User.beforeCreate(validateContactInfo)
124-
User.beforeCreate(setSaltAndPassword)
125-
126-
// Update prep actions
127-
// User.beforeUpdate(validateContactInfo)
128-
User.beforeUpdate(setSaltAndPassword)
129-
130-
return User
96+
User.encryptPassword = (plainText, salt) => {
97+
return crypto
98+
.createHash('RSA-SHA256')
99+
.update(plainText)
100+
.update(salt)
101+
.digest('hex')
102+
}
103+
104+
// Setters
105+
const setSaltAndPassword = user => {
106+
if (user.changed('password')) {
107+
user.salt = User.generateSalt()
108+
// User.password = User.encryptPassword(user.password, user.salt)
109+
user.password = utils.encryptPassword(user.password, user.salt)
110+
}
111+
}
112+
113+
// Other Helpers
114+
// const validateContactInfo = user => {
115+
// let valid = true
116+
117+
// if (!validator.isEmail(validator.normalizeEmail(user.email))) {
118+
// valid = false
119+
// }
120+
121+
// /** @todo Add more validations for all contact info. */
122+
123+
// return valid
124+
// }
125+
126+
// Create prep actions
127+
// User.beforeCreate(validateContactInfo)
128+
User.beforeCreate(setSaltAndPassword)
129+
130+
// Update prep actions
131+
// User.beforeUpdate(validateContactInfo)
132+
User.beforeUpdate(setSaltAndPassword)
133+
134+
return User
131135
}
132136

133137
export default user

src/routes/entity.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ router.put('/', async (req, res) => {
119119
const response = new utils.Response()
120120
try {
121121
if (validator.isUUID(req.body.id)) {
122-
let { id, name, type, address, phone, email, checkIn, contacts } = req.body
122+
let { id, name, type, address, phone, email, checkIn, contacts, attributes } = req.body
123123

124124
/** @todo validate emails */
125125
// Validating emails
@@ -140,7 +140,8 @@ router.put('/', async (req, res) => {
140140
entity.type = (type) ? type : entity.type
141141
entity.address = (address) ? address : entity.address
142142
entity.phone = (phone) ? phone : entity.phone
143-
entity.email = (email) ? email : entity.email
143+
entity.email = (email) ? email : entity.email
144+
entity.attributes = (attributes) ? attributes : entity.attributes
144145
/** @todo validate checkIn JSON */
145146
if (entity.checkIn === null && checkIn) {
146147
const checkIns = {

src/routes/user.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import utils from '../utils'
55
import email from '../email'
66

77
const router = new Router()
8-
const max = (process.env.NODE_ENV !== 'production') ? 50000 : 5
8+
const max = (process.env.NODE_ENV !== 'production') ? 50000 : 50
99
const loginLimiter = rateLimit({
1010
windowMs: 60 * 60 * 1000,
1111
max,

src/tests/entity.routes.spec.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,10 @@ const { expect } = chai
99
const entity = {
1010
name: randomWords(),
1111
type: 'Test',
12-
contacts: []
12+
contacts: [],
13+
attributes: {
14+
notes: 'test'
15+
}
1316
}
1417
const contact = {
1518
name: randomWords(),

0 commit comments

Comments
 (0)