EditUser.vue 5.6 KB

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