usersController.js 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. /*
  2. ztncui - ZeroTier network controller UI
  3. Copyright (C) 2017 Key Networks (https://key-networks.com)
  4. Licensed under GPLv3 - see LICENSE for details.
  5. */
  6. const fs = require('fs');
  7. const argon2 = require('argon2');
  8. const util = require('util');
  9. const passwd_file = 'etc/passwd';
  10. const min_pass_len = 10;
  11. const readFile = util.promisify(fs.readFile);
  12. const writeFile = util.promisify(fs.writeFile);
  13. const chmod = util.promisify(fs.chmod);
  14. let _users = null;
  15. get_users = async function() {
  16. if (_users) {
  17. return _users;
  18. } else {
  19. try {
  20. _users = JSON.parse(await readFile(passwd_file, 'utf8'));
  21. return _users;
  22. } catch(err) {
  23. throw(err);
  24. }
  25. }
  26. }
  27. exports.get_users = get_users;
  28. update_users = async function(users) {
  29. try {
  30. await writeFile(passwd_file, JSON.stringify(users), 'utf8');
  31. await chmod(passwd_file, 0600);
  32. } catch (err) {
  33. throw err;
  34. }
  35. _users = null;
  36. return await get_users();
  37. }
  38. exports.users_list = async function(req, res) {
  39. const page = 'users';
  40. try {
  41. const users = await get_users();
  42. res.render('users', { title: 'Admin users', page: page, message: 'List of users with admin priviledges', users: users });
  43. } catch (err) {
  44. res.render('users', { title: 'Admin users', page: page, message: 'Error', users: null, error: 'Error returning list of users: ' + err });
  45. }
  46. }
  47. exports.password_get = async function(req, res) {
  48. const page = 'users';
  49. const user =
  50. {
  51. name: req.params.name,
  52. password1: null,
  53. password2: null
  54. };
  55. res.render('password', { title: 'Set password', page: page, user: user, readonly: true, message: '' });
  56. }
  57. exports.password_post = async function(req, res) {
  58. const page = 'users';
  59. req.checkBody('username', 'Username required').notEmpty();
  60. req.sanitize('username').escape();
  61. req.sanitize('username').trim();
  62. req.checkBody('password1', 'Password required').notEmpty();
  63. req.checkBody('password1', 'Minimum password length is ' + min_pass_len + ' characters').isLength({ min: min_pass_len, max: 160 });
  64. req.checkBody('password2', 'Please re-enter password').notEmpty();
  65. req.checkBody('password2', 'Minimum password length is ' + min_pass_len + ' characters').isLength({ min: min_pass_len, max: 160 });
  66. req.checkBody('password2', 'Passwords are not the same').equals(req.body.password1);
  67. const errors = req.validationErrors();
  68. if (errors) {
  69. const user =
  70. {
  71. name: req.body.username,
  72. password1: req.body.password1,
  73. password2: req.body.password2
  74. };
  75. const message = 'Please check errors below';
  76. res.render('password', { title: 'Set password', page: page, user: user, readonly: true, message: message, errors: errors });
  77. } else {
  78. let pass_set = true;
  79. if (req.body.pass_set === 'check') pass_set = false;
  80. const hash = await argon2.hash(req.body.password1);
  81. const user =
  82. {
  83. name: req.body.username,
  84. pass_set: pass_set,
  85. hash: hash
  86. };
  87. const passwd_user =
  88. {
  89. [req.body.username]: user
  90. };
  91. let users = await get_users();
  92. users[req.body.username] = user;
  93. users = await update_users(users);
  94. const message = 'Successfully set password for ' + req.body.username;
  95. res.render('password', { title: 'Set password', page: page, user: user, readonly: true, message: message });
  96. }
  97. }
  98. exports.user_create_get = async function(req, res) {
  99. const page = 'create_user';
  100. const user =
  101. {
  102. name: null,
  103. password1: null,
  104. password2: null
  105. };
  106. res.render('password', { title: 'Create new admin user', page: page, user: user, readonly: false});
  107. }
  108. exports.user_create_post = async function(req, res) {
  109. const page = 'create_user';
  110. res.redirect(307, '/users/' + req.body.username + '/password');
  111. }
  112. exports.user_delete = async function(req, res) {
  113. const page = 'users';
  114. try {
  115. var users = await get_users();
  116. } catch (err) {
  117. throw err;
  118. }
  119. const user = users[req.params.name];
  120. if (user && (req.session.user.name === user.name)) {
  121. res.render('user_delete', { title: 'Delete user', page: page, user: user, self_delete: true });
  122. }
  123. if (req.body.delete === 'delete') {
  124. if (user) {
  125. const deleted_user = { name: user.name };
  126. delete users[user.name];
  127. users = await update_users(users);
  128. res.render('user_delete', { title: 'Deleted user', page: page, user: deleted_user, deleted: true });
  129. } else {
  130. res.render('user_delete', { title: 'Delete user', page: page, user: null });
  131. }
  132. } else {
  133. if (user) {
  134. res.render('user_delete', { title: 'Delete user', page: page, user: user });
  135. } else {
  136. res.render('user_delete', { title: 'Delete user', page: page, user: null });
  137. }
  138. }
  139. }