EditUser.vue 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. <template>
  2. <div>
  3. <modal title='Edit User'>
  4. <div slot='body'>
  5. <p class="control has-addons">
  6. <input class='input is-expanded' type='text' placeholder='Username' v-model='editing.username' autofocus>
  7. <a class="button is-info" @click='updateUsername()'>Update Username</a>
  8. </p>
  9. <p class="control has-addons">
  10. <input class='input is-expanded' type='text' placeholder='Username' v-model='editing.email' autofocus>
  11. <a class="button is-info" @click='updateEmail()'>Update Email Address</a>
  12. </p>
  13. <p class="control has-addons">
  14. <span class="select">
  15. <select v-model="editing.role">
  16. <option>default</option>
  17. <option>admin</option>
  18. </select>
  19. </span>
  20. <a class="button is-info" @click='updateRole()'>Update Role</a>
  21. </p>
  22. <hr>
  23. <p class="control has-addons">
  24. <span class="select">
  25. <select v-model='ban.expiresAt'>
  26. <option value='1h'>1 Hour</option>
  27. <option value='12h'>12 Hours</option>
  28. <option value='1d'>1 Day</option>
  29. <option value='1w'>1 Week</option>
  30. <option value='1m'>1 Month</option>
  31. <option value='3m'>3 Months</option>
  32. <option value='6m'>6 Months</option>
  33. <option value='1y'>1 Year</option>
  34. </select>
  35. </span>
  36. <input class='input is-expanded' type='text' placeholder='Ban reason' v-model='ban.reason' autofocus>
  37. <a class="button is-error" @click='banUser()'>Ban user</a>
  38. </p>
  39. </div>
  40. <div slot='footer'>
  41. <!--button class='button is-warning'>
  42. <span>&nbsp;Send Verification Email</span>
  43. </button>
  44. <button class='button is-warning'>
  45. <span>&nbsp;Send Password Reset Email</span>
  46. </button-->
  47. <button class='button is-warning' @click='removeSessions()'>
  48. <span>&nbsp;Remove all sessions</span>
  49. </button>
  50. <button class='button is-danger' @click='$parent.toggleModal()'>
  51. <span>&nbsp;Close</span>
  52. </button>
  53. </div>
  54. </modal>
  55. </div>
  56. </template>
  57. <script>
  58. import io from '../../io';
  59. import { Toast } from 'vue-roaster';
  60. import Modal from './Modal.vue';
  61. import validation from '../../validation';
  62. export default {
  63. components: { Modal },
  64. data() {
  65. return {
  66. editing: {},
  67. ban: {
  68. expiresAt: '1h'
  69. }
  70. }
  71. },
  72. methods: {
  73. updateUsername: function () {
  74. const username = this.editing.username;
  75. if (!validation.isLength(username, 2, 32)) return Toast.methods.addToast('Username must have between 2 and 32 characters.', 8000);
  76. if (!validation.regex.azAZ09_.test(username)) return Toast.methods.addToast('Invalid username format. Allowed characters: a-z, A-Z, 0-9 and _.', 8000);
  77. this.socket.emit(`users.updateUsername`, this.editing._id, username, res => {
  78. Toast.methods.addToast(res.message, 4000);
  79. });
  80. },
  81. updateEmail: function () {
  82. const email = this.editing.email;
  83. if (!validation.isLength(email, 3, 254)) return Toast.methods.addToast('Email must have between 3 and 254 characters.', 8000);
  84. if (email.indexOf('@') !== email.lastIndexOf('@') || !validation.regex.emailSimple.test(email)) return Toast.methods.addToast('Invalid email format.', 8000);
  85. this.socket.emit(`users.updateEmail`, this.editing._id, email, res => {
  86. Toast.methods.addToast(res.message, 4000);
  87. });
  88. },
  89. updateRole: function () {
  90. this.socket.emit(`users.updateRole`, this.editing._id, this.editing.role, res => {
  91. Toast.methods.addToast(res.message, 4000);
  92. if (
  93. res.status === 'success' &&
  94. this.editing.role === 'default' &&
  95. this.editing._id === this.$parent.$parent.$parent.userId
  96. ) location.reload();
  97. });
  98. },
  99. banUser: function () {
  100. const reason = this.ban.reason;
  101. if (!validation.isLength(reason, 1, 64)) return Toast.methods.addToast('Reason must have between 1 and 64 characters.', 8000);
  102. if (!validation.regex.ascii.test(reason)) return Toast.methods.addToast('Invalid reason format. Only ascii characters are allowed.', 8000);
  103. this.socket.emit(`users.banUserById`, this.editing._id, this.ban.reason, this.ban.expiresAt, res => {
  104. Toast.methods.addToast(res.message, 4000);
  105. });
  106. },
  107. removeSessions: function () {
  108. this.socket.emit(`users.removeSessions`, this.editing._id, res => {
  109. Toast.methods.addToast(res.message, 4000);
  110. });
  111. }
  112. },
  113. ready: function () {
  114. let _this = this;
  115. io.getSocket(socket => _this.socket = socket );
  116. },
  117. events: {
  118. closeModal: function () {
  119. this.$parent.modals.editUser = false;
  120. },
  121. editUser: function (user) {
  122. this.editing = {
  123. _id: user._id,
  124. username: user.username,
  125. email: user.email.address,
  126. role: user.role
  127. };
  128. this.$parent.toggleModal();
  129. }
  130. }
  131. }
  132. </script>
  133. <style type='scss' scoped>
  134. .save-changes { color: #fff; }
  135. .tag:not(:last-child) { margin-right: 5px; }
  136. .select:after { border-color: #029ce3; }
  137. </style>