1 | import redis from 'redis' |
||
2 | import Limiter from 'ratelimiter' |
||
3 | import owasp from 'owasp-password-strength-test' |
||
4 | import bcrypt from 'bcrypt-nodejs' |
||
5 | import Cookies from 'cookies' |
||
6 | import jwt from 'jwt-simple' |
||
7 | |||
8 | import { |
||
9 | User |
||
10 | ,config |
||
11 | ,coreUtils |
||
12 | } from '../../cli' |
||
13 | |||
14 | export function checkSameEmail(data) { |
||
15 | var emailAlreadyUsed = false |
||
16 | var bdd = User.manager.instance.get() |
||
17 | for (var i = 0, len = bdd.length; i < len; i++) { |
||
18 | var user = bdd[i] |
||
19 | if (user.email === data.email && parseInt(user.id) !== parseInt(data.id)) { |
||
20 | emailAlreadyUsed = true |
||
21 | } |
||
22 | } |
||
23 | |||
24 | if (emailAlreadyUsed === true) { |
||
25 | return { |
||
26 | success:0, |
||
27 | message: 'Email adress already exist' |
||
28 | } |
||
29 | }else { |
||
30 | return { |
||
31 | success:1 |
||
32 | } |
||
33 | } |
||
34 | } |
||
35 | |||
36 | export function getRole(data) { |
||
37 | var roles = config.users.roles |
||
38 | Array.prototype.forEach.call(roles, (role) => { |
||
39 | if(role.name === data.role) { |
||
40 | data.role = role |
||
41 | } |
||
42 | }) |
||
43 | |||
44 | return data |
||
45 | } |
||
46 | |||
47 | export function commonPassword(data) { |
||
48 | var owaspConfig = config.users.owasp |
||
49 | owasp.config(owaspConfig) |
||
50 | var sameAsUser = (typeof owaspConfig.sameAsUser !== 'undefined' && owaspConfig.sameAsUser !== null) ? owaspConfig.sameAsUser : true |
||
51 | var mostCommon = (typeof owaspConfig.mostCommon !== 'undefined' && owaspConfig.mostCommon !== null) ? owaspConfig.mostCommon : true |
||
52 | var mostCommonPassword = config.users.mostCommonPassword |
||
53 | owasp.tests.required.push(function(password) { |
||
54 | if (mostCommon && coreUtils.array.contains(mostCommonPassword, password.toLowerCase())) { |
||
0 ignored issues
–
show
|
|||
55 | return 'the password used is too common.' |
||
56 | } |
||
57 | }) |
||
58 | |||
59 | var currentUserName = data.username |
||
60 | owasp.tests.required.push(function(password) { |
||
61 | var username = currentUserName |
||
62 | var shouldTest = sameAsUser |
||
63 | |||
64 | if(shouldTest) { |
||
0 ignored issues
–
show
There is no return statement if
shouldTest is false . Are you sure this is correct? If so, consider adding return; explicitly.
This check looks for functions where a Consider this little piece of code function isBig(a) {
if (a > 5000) {
return "yes";
}
}
console.log(isBig(5001)); //returns yes
console.log(isBig(42)); //returns undefined
The function This behaviour may not be what you had intended. In any case, you can add a
![]() |
|||
65 | if (password.toLowerCase() === username.toLowerCase()) { |
||
66 | return 'username and password must be different.' |
||
67 | } |
||
68 | if (password.toLowerCase() === username.toLowerCase().split('').reverse().join('')) { |
||
0 ignored issues
–
show
There is no return statement if
password.toLowerCase() =...("").reverse().join("") is false . Are you sure this is correct? If so, consider adding return; explicitly.
This check looks for functions where a Consider this little piece of code function isBig(a) {
if (a > 5000) {
return "yes";
}
}
console.log(isBig(5001)); //returns yes
console.log(isBig(42)); //returns undefined
The function This behaviour may not be what you had intended. In any case, you can add a
![]() |
|||
69 | return 'username and password must be different, not just inverted.' |
||
70 | } |
||
71 | } |
||
72 | }) |
||
73 | |||
74 | var res = owasp.test(data.password) |
||
75 | |||
76 | if(typeof res.errors !== 'undefined' && res.errors !== null |
||
77 | && res.errors.length > 0) { |
||
78 | var message = '' |
||
79 | Array.prototype.forEach.call(res.errors, (error) => { |
||
80 | message += error + '<br />' |
||
81 | }) |
||
82 | return { |
||
83 | success:0, |
||
84 | message: message |
||
85 | } |
||
86 | }else { |
||
87 | return { |
||
88 | success:1 |
||
89 | } |
||
90 | } |
||
91 | } |
||
92 | |||
93 | export function encryptPassword(numb, password) { |
||
94 | var salt = bcrypt.genSaltSync(numb) |
||
95 | return bcrypt.hashSync(password, salt) |
||
96 | } |
||
97 | |||
98 | export function getUserRoutes(workflow) { |
||
99 | var routes = config.users.routes |
||
100 | var userRoles = [] |
||
101 | Array.prototype.forEach.call(Object.keys(routes), (role) => { |
||
102 | if(role === workflow) { |
||
103 | userRoles = routes[role] |
||
104 | } |
||
105 | }) |
||
106 | |||
107 | return userRoles |
||
108 | } |
||
109 | |||
110 | |||
111 | export function findSync(id) { |
||
112 | var bdd = User.manager.instance.get() |
||
113 | for (var i = 0, len = bdd.length; i < len; i++) { |
||
114 | var user = bdd[i] |
||
115 | if (parseInt(user.id) === parseInt(id)) { |
||
116 | return user |
||
117 | } |
||
118 | } |
||
119 | return null |
||
120 | } |
||
121 | |||
122 | export function find(id, done) { |
||
123 | var bdd = User.manager.instance.get() |
||
124 | for (var i = 0, len = bdd.length; i < len; i++) { |
||
125 | var user = bdd[i] |
||
126 | if (parseInt(user.id) === parseInt(id)) { |
||
127 | return done(null, user) |
||
128 | } |
||
129 | } |
||
130 | return done(null, null) |
||
131 | } |
||
132 | |||
133 | export function findByUsername(username, done) { |
||
134 | var bdd = User.manager.instance.get() |
||
135 | for (var i = 0, len = bdd.length; i < len; i++) { |
||
136 | var user = bdd[i] |
||
137 | if (user.username === username) { |
||
138 | return done(null, user) |
||
139 | } |
||
140 | } |
||
141 | return done(null, null) |
||
142 | } |
||
143 | |||
144 | export function findByEmail(email, done) { |
||
145 | var bdd = User.manager.instance.get() |
||
146 | for (var i = 0, len = bdd.length; i < len; i++) { |
||
147 | var user = bdd[i] |
||
148 | if (user.email === email) { |
||
149 | return done(null, user) |
||
150 | } |
||
151 | } |
||
152 | return done(null, null) |
||
153 | } |
||
154 | |||
155 | export function findByResetPasswordToken(resetPasswordToken, done) { |
||
156 | var bdd = User.manager.instance.get() |
||
157 | for (var i = 0, len = bdd.length; i < len; i++) { |
||
158 | var user = bdd[i] |
||
159 | if (user.resetPasswordToken === resetPasswordToken) { |
||
160 | return done(null, user) |
||
161 | } |
||
162 | } |
||
163 | return done(null, null) |
||
164 | } |
||
165 | |||
166 | export function isValid(user, password) { |
||
167 | if(user.actif === 1) { |
||
168 | if(bcrypt.compareSync(password, user.password)) { |
||
169 | return true |
||
170 | } |
||
171 | } |
||
172 | return false |
||
173 | } |
||
174 | |||
175 | export function decodeUser(req, res) { |
||
176 | var decoded = {} |
||
177 | var token = User.utils.getTokenFromCookies(req, res) |
||
178 | if(typeof token !== 'undefined' && token !== null && token !== '') { |
||
179 | try { |
||
180 | var secret = config.users.secret |
||
181 | decoded = jwt.decode(token, secret) |
||
182 | } catch (err) {} |
||
0 ignored issues
–
show
Coding Style
Comprehensibility
Best Practice
introduced
by
|
|||
183 | } |
||
184 | |||
185 | return decoded |
||
186 | } |
||
187 | |||
188 | export function getTokenFromCookies(req, res) { |
||
189 | var cookies = new Cookies(req, res, { |
||
190 | secure: config.cookie.secure |
||
191 | }) |
||
192 | return cookies.get('x-access-token') |
||
193 | } |
||
194 | |||
195 | export function isAbeRestrictedUrl(currentRoute) { |
||
196 | if( currentRoute.indexOf('/abe/users/forgot') > -1 |
||
197 | || currentRoute.indexOf('/abe/users/login') > -1 |
||
198 | || currentRoute.indexOf('/abe/users/reset') > -1 |
||
199 | || !/^\/abe\//.test(currentRoute)) { |
||
200 | return false |
||
201 | } |
||
202 | |||
203 | return true |
||
204 | } |
||
205 | |||
206 | export function isUserAllowedOnRoute(workflow, currentRoute) { |
||
207 | var isAllowed = false |
||
208 | |||
209 | if (config.users.enable) { |
||
210 | if( currentRoute.indexOf('/abe/users/forgot') > -1 || currentRoute.indexOf('/abe/users/login') > -1 || !/^\/abe/.test(currentRoute)) { |
||
211 | return true |
||
212 | } |
||
213 | |||
214 | if (currentRoute.indexOf('abe/') === -1) { |
||
215 | isAllowed = true |
||
216 | } |
||
217 | |||
218 | if (workflow != null) { |
||
219 | var routes = config.users.routes |
||
220 | if(typeof routes[workflow] !== 'undefined' && routes[workflow] !== null) { |
||
221 | Array.prototype.forEach.call(routes[workflow], (route) => { |
||
222 | var reg = new RegExp(route) |
||
223 | if(reg.test(currentRoute)) { |
||
224 | isAllowed = true |
||
225 | } |
||
226 | }) |
||
227 | } |
||
228 | } |
||
229 | }else { |
||
230 | isAllowed = true |
||
231 | } |
||
232 | |||
233 | return isAllowed |
||
234 | } |
||
235 | |||
236 | export function getAll() { |
||
237 | return User.manager.instance.get() |
||
238 | } |
||
239 | |||
240 | export function getUserWorkflow(status) { |
||
241 | var flows = [] |
||
242 | |||
243 | function addFlow (flow, type, action) { |
||
244 | type = (type != null) ? type : flow |
||
245 | return { |
||
246 | status: flow, |
||
247 | url: `/abe/operations/${action}/${type}` |
||
248 | } |
||
249 | } |
||
250 | |||
251 | if (config.users.enable) { |
||
252 | var found = null |
||
253 | Array.prototype.forEach.call(config.users.workflow, (flow) => { |
||
254 | |||
255 | if (found != null) { |
||
256 | flows.push(addFlow(flow, flow, 'submit')) |
||
257 | found = null |
||
258 | } |
||
259 | |||
260 | if (status == flow) { |
||
261 | found = flow |
||
262 | if (flow != 'draft' && flow != 'publish') { |
||
263 | flows.push(addFlow('reject', flow, 'reject')) |
||
264 | } |
||
265 | if (flow == 'publish') { |
||
266 | flows.push(addFlow('edit', 'draft', 'edit')) |
||
267 | }else { |
||
268 | flows.push(addFlow('save', flow, 'edit')) |
||
269 | } |
||
270 | } |
||
271 | }) |
||
272 | if (found != null) { |
||
273 | flows.push(addFlow('save', 'publish', 'submit')) |
||
274 | } |
||
275 | }else { |
||
276 | flows = [addFlow('draft', 'draft', 'submit'), addFlow('publish', 'publish', 'submit')] |
||
277 | } |
||
278 | return flows |
||
279 | } |
||
280 | |||
281 | export function loginLimitTry(username) { |
||
282 | var p = new Promise((resolve) => { |
||
283 | var isNexted = false |
||
284 | try { |
||
285 | var limiterConfig = config.users.limiter |
||
286 | |||
287 | var client = redis.createClient() |
||
288 | client.on('error', function() { |
||
289 | if (!isNexted) { |
||
290 | isNexted = true |
||
291 | resolve() |
||
292 | } |
||
293 | }) |
||
294 | |||
295 | var limit = new Limiter({ |
||
296 | id: username, |
||
297 | db: client, |
||
298 | duration: limiterConfig.duration, |
||
299 | max: limiterConfig.max |
||
300 | }) |
||
301 | |||
302 | limit.get(function(err, limit) { |
||
303 | if (err) { |
||
304 | resolve() |
||
305 | }else { |
||
306 | resolve(limit) |
||
307 | } |
||
308 | }) |
||
309 | }catch(e) { |
||
310 | resolve() |
||
311 | } |
||
312 | }) |
||
313 | |||
314 | return p |
||
315 | } |
This check looks for functions where a
return
statement is found in some execution paths, but not in all.Consider this little piece of code
The function
isBig
will only return a specific value when its parameter is bigger than 5000. In any other case, it will implicitly returnundefined
.This behaviour may not be what you had intended. In any case, you can add a
return undefined
to the other execution path to make the return value explicit.