Commit a21b1159e7323213cd125287e97f279730021600
1 parent
971384b244
Exists in
master
Manajemen user
Showing 6 changed files with 289 additions and 0 deletions Side-by-side Diff
index.js
... | ... | @@ -3,6 +3,7 @@ var nunjucks = require('nunjucks'); |
3 | 3 | var session = require('express-session'); |
4 | 4 | var MongoStore = require('connect-mongo/es5')(session); |
5 | 5 | var bodyParser = require('body-parser'); |
6 | +var mongoObjectID = require('mongodb').ObjectID; | |
6 | 7 | var mongoClient = require('mongodb').MongoClient; |
7 | 8 | var crypto = require('crypto'); |
8 | 9 | var strftime = require('strftime'); |
... | ... | @@ -179,6 +180,7 @@ function pageHome(req, res, next) { |
179 | 180 | res.render('index.html', { |
180 | 181 | title: 'Transactions', |
181 | 182 | config: config, |
183 | + session: req.session, | |
182 | 184 | conditions: conditions, |
183 | 185 | trxcount: count, |
184 | 186 | pagecount: pagecount, |
... | ... | @@ -234,10 +236,15 @@ function pageSigninPost(req, res, next) { |
234 | 236 | } |
235 | 237 | |
236 | 238 | req.session.username = req.body.username; |
239 | + | |
237 | 240 | if (doc.roles) { |
241 | + | |
238 | 242 | req.session.roles = doc.roles; |
243 | + req.session.isAdmin = (doc.roles.indexOf('admin') >= 0); | |
244 | + | |
239 | 245 | } else { |
240 | 246 | req.session.roles = []; |
247 | + req.session.isAdmin = 0; | |
241 | 248 | } |
242 | 249 | |
243 | 250 | res.redirect('/'); |
... | ... | @@ -245,6 +252,119 @@ function pageSigninPost(req, res, next) { |
245 | 252 | }); |
246 | 253 | } |
247 | 254 | |
255 | +function pageUsersIndex(req, res, next) { | |
256 | + mongodb.collection('users').find({}).toArray(function(err, docs) { | |
257 | + if (err) { | |
258 | + res.end('Gagal ambil list user'); | |
259 | + return; | |
260 | + } | |
261 | + | |
262 | + /* | |
263 | + console.log(JSON.stringify(docs)); | |
264 | + res.send(JSON.stringify(docs)); | |
265 | + return; | |
266 | + */ | |
267 | + | |
268 | + res.render('users.index.html', { | |
269 | + title: 'Users', | |
270 | + config: config, | |
271 | + session: req.session, | |
272 | + qs: req.query, | |
273 | + url: req.url, | |
274 | + path: req.path, | |
275 | + users: docs, | |
276 | + }); | |
277 | + }); | |
278 | + | |
279 | +} | |
280 | + | |
281 | +function pageUsersView(req, res, next) { | |
282 | + | |
283 | + mongodb.collection('users').find({_id: new mongoObjectID(req.params.id)}).limit(1).next(function(err, doc) { | |
284 | + if (err) { | |
285 | + res.send("Error retrieving data"); | |
286 | + return; | |
287 | + } | |
288 | + | |
289 | + res.render( | |
290 | + 'users.view.html', | |
291 | + { | |
292 | + title: doc.email, | |
293 | + session: req.session, | |
294 | + user: doc | |
295 | + } | |
296 | + ); | |
297 | + | |
298 | + }); | |
299 | + | |
300 | +} | |
301 | + | |
302 | +function pageUsersAdd(req, res, next) { | |
303 | + res.render( | |
304 | + 'users.add.html', | |
305 | + { | |
306 | + title: 'Add a new user', | |
307 | + session: req.session | |
308 | + } | |
309 | + ); | |
310 | +} | |
311 | + | |
312 | +function pageUsersAddPost(req, res, next) { | |
313 | + if (req.body.password1 != req.body.password2) { | |
314 | + res.redirect("/users/add"); | |
315 | + return; | |
316 | + } | |
317 | + | |
318 | + var passwordHash = crypto.createHash('sha256').update(req.body.password1).digest().toString('hex'); | |
319 | + var roles = req.body.roles.replace(" ", "").split(","); | |
320 | + var suppliers = req.body.suppliers.replace(" ", "").split(","); | |
321 | + | |
322 | + var user = { | |
323 | + email: req.body.email, | |
324 | + password: passwordHash, | |
325 | + roles: roles, | |
326 | + suppliers: suppliers | |
327 | + } | |
328 | + | |
329 | + mongodb.collection('users').insertOne(user, function(err, r) { | |
330 | + res.redirect('/users'); | |
331 | + }); | |
332 | + | |
333 | +} | |
334 | + | |
335 | +function pageUsersChangePassword(req, res, next) { | |
336 | + mongodb.collection('users').find({_id: new mongoObjectID(req.params.id)}).limit(1).next(function(err, doc) { | |
337 | + if (err) { | |
338 | + res.send("Error retrieving data"); | |
339 | + return; | |
340 | + } | |
341 | + | |
342 | + res.render( | |
343 | + 'users.change-password.html', | |
344 | + { | |
345 | + title: 'Change Password', | |
346 | + session: req.session, | |
347 | + user: doc | |
348 | + } | |
349 | + ); | |
350 | + }); | |
351 | +} | |
352 | + | |
353 | +function pageUsersChangePasswordPost(req, res, next) { | |
354 | + if (req.body.passwod1 && (req.body.password1 != req.body.password2)) { | |
355 | + res.redirect("/users/change-password/" + req.body._id); | |
356 | + return; | |
357 | + } | |
358 | + | |
359 | + var _id = new mongoObjectID(req.body._id); | |
360 | + var passwordHash = crypto.createHash('sha256').update(req.body.password1).digest().toString('hex'); | |
361 | + | |
362 | + mongodb.collection('users').updateOne({_id: _id}, {$set: {password: passwordHash}}, function(err, r) { | |
363 | + res.redirect("/users/view/" + req.body._id); | |
364 | + return; | |
365 | + }); | |
366 | +} | |
367 | + | |
248 | 368 | function logout(req, res, next) { |
249 | 369 | req.session.username = null; |
250 | 370 | res.redirect('/signin'); |
... | ... | @@ -257,6 +377,13 @@ app.get('/logout', logout); |
257 | 377 | |
258 | 378 | app.get('/trx/view/:id', authNeeded, pageTrxView); |
259 | 379 | |
380 | +app.get('/users', authNeeded, pageUsersIndex); | |
381 | +app.get('/users/view/:id', authNeeded, pageUsersView); | |
382 | +app.get('/users/add', authNeeded, pageUsersAdd); | |
383 | +app.post('/users/add', authNeeded, pageUsersAddPost); | |
384 | +app.get('/users/change-password/:id', authNeeded, pageUsersChangePassword); | |
385 | +app.post('/users/change-password/:id', authNeeded, pageUsersChangePasswordPost); | |
386 | + | |
260 | 387 | app.listen(config.listen_port, function () { |
261 | 388 | console.log('Example app listening on port ' + config.listen_port); |
262 | 389 | }); |
views/starter-template.html
... | ... | @@ -48,6 +48,16 @@ |
48 | 48 | <div id="navbar" class="collapse navbar-collapse"> |
49 | 49 | <ul class="nav navbar-nav"> |
50 | 50 | <li><a href="/">Home</a></li> |
51 | + {% if session.isAdmin %} | |
52 | + <li class="dropdown"> | |
53 | + <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false"> | |
54 | + Admin <span class="caret"></span> | |
55 | + </a> | |
56 | + <ul class="dropdown-menu"> | |
57 | + <li><a href="/users">Users</a></li> | |
58 | + </ul> | |
59 | + </li> | |
60 | + {% endif %} | |
51 | 61 | <li><a href="/logout">Logout</a></li> |
52 | 62 | </ul> |
53 | 63 | </div><!--/.nav-collapse --> |
views/users.add.html
... | ... | @@ -0,0 +1,42 @@ |
1 | +{% extends "starter-template.html" %} | |
2 | +{% block content %} | |
3 | + | |
4 | +<form class="form-horizontal" method="POST"> | |
5 | + | |
6 | + <div class="form-group"> | |
7 | + <label for="inputEmail" class="col-sm-2 control-label">Email</label> | |
8 | + <div class="col-sm-10"> | |
9 | + <input name="email" type="text" class="form-control" id="inputEmail"> | |
10 | + </div> | |
11 | + </div> | |
12 | + | |
13 | + <div class="form-group"> | |
14 | + <label for="inputSuppliers" class="col-sm-2 control-label">Suppliers</label> | |
15 | + <div class="col-sm-10"> | |
16 | + <input name="suppliers" type="text" class="form-control" id="inputSuppliers"> | |
17 | + </div> | |
18 | + </div> | |
19 | + | |
20 | + <div class="form-group"> | |
21 | + <label for="inputRoles" class="col-sm-2 control-label">Roles</label> | |
22 | + <div class="col-sm-10"> | |
23 | + <input name="roles" type="text" class="form-control" id="inputRoles"> | |
24 | + </div> | |
25 | + </div> | |
26 | + | |
27 | + <div class="form-group"> | |
28 | + <label for="inputPassword" class="col-sm-2 control-label">Password</label> | |
29 | + <div class="col-sm-10"> | |
30 | + <input name="password1" type="password" class="form-control" id="inputPassword1" placeholder="Password"> | |
31 | + <input name="password2" type="password" class="form-control" id="inputPassword2" placeholder="Retype password"> | |
32 | + </div> | |
33 | + </div> | |
34 | + | |
35 | + <div class="form-group"> | |
36 | + <div class="col-sm-offset-2 col-sm-10"> | |
37 | + <input type="submit" class="btn btn-primary"> | |
38 | + </div> | |
39 | + </div> | |
40 | + | |
41 | +</form> | |
42 | +{% endblock %} |
views/users.change-password.html
... | ... | @@ -0,0 +1,32 @@ |
1 | +{% extends "starter-template.html" %} | |
2 | +{% block content %} | |
3 | + | |
4 | +<form class="form-horizontal" method="POST"> | |
5 | + | |
6 | + <input name="_id" type="hidden" value="{{ user._id }}"> | |
7 | + | |
8 | + <div class="form-group"> | |
9 | + <label for="inputEmail" class="col-sm-2 control-label">Email</label> | |
10 | + <div class="col-sm-10"> | |
11 | + <input name="email" type="text" class="form-control" id="inputEmail" value="{{ user.email }}" readonly> | |
12 | + </div> | |
13 | + </div> | |
14 | + | |
15 | + <div class="form-group"> | |
16 | + <label for="inputPassword" class="col-sm-2 control-label">Password</label> | |
17 | + <div class="col-sm-10"> | |
18 | + <input name="password1" type="password" class="form-control" id="inputPassword1" placeholder="Password"> | |
19 | + <input name="password2" type="password" class="form-control" id="inputPassword2" placeholder="Retype password"> | |
20 | + </div> | |
21 | + </div> | |
22 | + | |
23 | + <div class="form-group"> | |
24 | + <div class="col-sm-offset-2 col-sm-10"> | |
25 | + <input type="submit" class="btn btn-primary"> | |
26 | + <a href="/users" class="btn btn-default" role="button">Cancel</a> | |
27 | + </div> | |
28 | + </div> | |
29 | + | |
30 | +</form> | |
31 | + | |
32 | +{% endblock %} |
views/users.index.html
... | ... | @@ -0,0 +1,45 @@ |
1 | +{% extends "starter-template.html" %} | |
2 | +{% block content %} | |
3 | + | |
4 | +<table class="table table-striped table-hover"> | |
5 | + <tr> | |
6 | + <th>Email</th> | |
7 | + <th>Suppliers</th> | |
8 | + <th>Roles</th> | |
9 | + <th> </th> | |
10 | + </tr> | |
11 | + | |
12 | + {% for user in users %} | |
13 | + <tr> | |
14 | + | |
15 | + <td class="user-email"> | |
16 | + <a href="/users/view/{{ user._id }}"> | |
17 | + {{ user.email }} | |
18 | + </a> | |
19 | + </td> | |
20 | + | |
21 | + <td class="user-suppliers"> | |
22 | + {% for supplier in user.suppliers %} | |
23 | + <span class="label label-default">{{ supplier }}</span> | |
24 | + {% endfor %} | |
25 | + </td> | |
26 | + | |
27 | + <td class="user-roles"> | |
28 | + {% for role in user.roles %} | |
29 | + <span class="label label-default">{{ role }}</span> | |
30 | + {% endfor %} | |
31 | + </td> | |
32 | + | |
33 | + <td class="user-action"> | |
34 | + <a href="/users/change-password/{{ user._id }}" class="btn btn-primary" role="button"> | |
35 | + Change Password | |
36 | + </a> | |
37 | + </td> | |
38 | + | |
39 | + </tr> | |
40 | + {% endfor %} | |
41 | +</table> | |
42 | + | |
43 | +<a href="/users/add" class="btn btn-primary" role="button">Add</a> | |
44 | + | |
45 | +{% endblock %} |
views/users.view.html
... | ... | @@ -0,0 +1,33 @@ |
1 | +{% extends "starter-template.html" %} | |
2 | +{% block content %} | |
3 | + | |
4 | +<form class="form-horizontal"> | |
5 | + | |
6 | + <div class="form-group"> | |
7 | + <label for="inputEmail" class="col-sm-2 control-label">Email</label> | |
8 | + <div class="col-sm-10"> | |
9 | + <input type="text" class="form-control" id="inputEmail" value="{{ user.email }}" readonly> | |
10 | + </div> | |
11 | + </div> | |
12 | + | |
13 | + <div class="form-group"> | |
14 | + <label for="inputSuppliers" class="col-sm-2 control-label">Suppliers</label> | |
15 | + <div class="col-sm-10"> | |
16 | + {% for supplier in user.suppliers %} | |
17 | + <span class="label label-default">{{ supplier }}</span> | |
18 | + {% endfor %} | |
19 | + </div> | |
20 | + </div> | |
21 | + | |
22 | + <div class="form-group"> | |
23 | + <label for="inputRoles" class="col-sm-2 control-label">Roles</label> | |
24 | + <div class="col-sm-10"> | |
25 | + {% for role in user.roles %} | |
26 | + <span class="label label-default">{{ role }}</span> | |
27 | + {% endfor %} | |
28 | + </div> | |
29 | + </div> | |
30 | + | |
31 | +</form> | |
32 | + | |
33 | +{% endblock %} |