You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

256 lines
6.7 KiB

  1. <template lang="pug">
  2. v-dialog(v-model='isShown', max-width='650', persistent)
  3. v-card
  4. .dialog-header.is-short
  5. v-icon.mr-3(color='white') mdi-plus
  6. span New User
  7. v-spacer
  8. v-btn.mx-0(color='white', outlined, disabled, dark)
  9. v-icon(left) mdi-database-import
  10. span Bulk Import
  11. v-card-text.pt-5
  12. v-select(
  13. :items='providers'
  14. item-text='displayName'
  15. item-value='key'
  16. outlined
  17. prepend-icon='mdi-domain'
  18. v-model='provider'
  19. label='Provider'
  20. )
  21. v-text-field(
  22. outlined
  23. prepend-icon='mdi-at'
  24. v-model='email'
  25. label='Email Address'
  26. key='newUserEmail'
  27. persistent-hint
  28. ref='emailInput'
  29. )
  30. v-text-field(
  31. v-if='provider === `local`'
  32. outlined
  33. prepend-icon='mdi-lock-outline'
  34. append-icon='mdi-dice-5'
  35. v-model='password'
  36. :label='mustChangePwd ? `Temporary Password` : `Password`'
  37. counter='255'
  38. @click:append='generatePwd'
  39. key='newUserPassword'
  40. persistent-hint
  41. )
  42. v-text-field(
  43. outlined
  44. prepend-icon='mdi-account-outline'
  45. v-model='name'
  46. label='Name'
  47. :hint='provider === `local` ? `Can be changed by the user.` : `May be overwritten by the provider during login.`'
  48. key='newUserName'
  49. persistent-hint
  50. )
  51. v-select.mt-2(
  52. :items='groups'
  53. item-text='name'
  54. item-value='id'
  55. item-disabled='isSystem'
  56. outlined
  57. prepend-icon='mdi-account-group'
  58. v-model='group'
  59. label='Assign to Group(s)...'
  60. hint='Note that you cannot assign users to the Administrators or Guests groups from this dialog.'
  61. persistent-hint
  62. clearable
  63. multiple
  64. )
  65. v-divider
  66. v-checkbox(
  67. color='primary'
  68. label='Require password change on first login'
  69. v-if='provider === `local`'
  70. v-model='mustChangePwd'
  71. hide-details
  72. )
  73. v-checkbox(
  74. color='primary'
  75. label='Send a welcome email'
  76. hide-details
  77. v-model='sendWelcomeEmail'
  78. disabled
  79. )
  80. v-card-chin
  81. v-spacer
  82. v-btn(text, @click='isShown = false') Cancel
  83. v-btn.px-3(depressed, color='primary', @click='newUser(false)')
  84. v-icon(left) mdi-chevron-right
  85. span Create
  86. v-btn.px-3(depressed, color='primary', @click='newUser(true)')
  87. v-icon(left) mdi-chevron-double-right
  88. span Create and Close
  89. </template>
  90. <script>
  91. import _ from 'lodash'
  92. import validate from 'validate.js'
  93. import gql from 'graphql-tag'
  94. import createUserMutation from 'gql/admin/users/users-mutation-create.gql'
  95. import groupsQuery from 'gql/admin/users/users-query-groups.gql'
  96. export default {
  97. props: {
  98. value: {
  99. type: Boolean,
  100. default: false
  101. }
  102. },
  103. data() {
  104. return {
  105. providers: [],
  106. provider: 'local',
  107. email: '',
  108. password: '',
  109. name: '',
  110. groups: [],
  111. group: [],
  112. mustChangePwd: false,
  113. sendWelcomeEmail: false
  114. }
  115. },
  116. computed: {
  117. isShown: {
  118. get() { return this.value },
  119. set(val) { this.$emit('input', val) }
  120. }
  121. },
  122. watch: {
  123. value(newValue, oldValue) {
  124. if (newValue) {
  125. this.$nextTick(() => {
  126. this.$refs.emailInput.focus()
  127. })
  128. }
  129. }
  130. },
  131. methods: {
  132. async newUser(close = false) {
  133. let rules = {
  134. email: {
  135. presence: {
  136. allowEmpty: false
  137. },
  138. email: true
  139. },
  140. name: {
  141. presence: {
  142. allowEmpty: false
  143. },
  144. length: {
  145. minimum: 2,
  146. maximum: 255
  147. }
  148. }
  149. }
  150. if (this.provider === `local`) {
  151. rules.password = {
  152. presence: {
  153. allowEmpty: false
  154. },
  155. length: {
  156. minimum: 6,
  157. maximum: 255
  158. }
  159. }
  160. }
  161. const validationResults = validate({
  162. email: this.email,
  163. password: this.password,
  164. name: this.name
  165. }, rules, { format: 'flat' })
  166. if (validationResults) {
  167. this.$store.commit('showNotification', {
  168. style: 'red',
  169. message: validationResults[0],
  170. icon: 'alert'
  171. })
  172. return
  173. }
  174. try {
  175. const resp = await this.$apollo.mutate({
  176. mutation: createUserMutation,
  177. variables: {
  178. providerKey: this.provider,
  179. email: this.email,
  180. passwordRaw: this.password,
  181. name: this.name,
  182. groups: this.group,
  183. mustChangePassword: this.mustChangePwd,
  184. sendWelcomeEmail: this.sendWelcomeEmail
  185. },
  186. watchLoading (isLoading) {
  187. this.$store.commit(`loading${isLoading ? 'Start' : 'Stop'}`, 'admin-users-create')
  188. }
  189. })
  190. if (_.get(resp, 'data.users.create.responseResult.succeeded', false)) {
  191. this.$store.commit('showNotification', {
  192. style: 'success',
  193. message: 'New user created successfully.',
  194. icon: 'check'
  195. })
  196. this.email = ''
  197. this.password = ''
  198. this.name = ''
  199. if (close) {
  200. this.isShown = false
  201. this.$emit('refresh')
  202. } else {
  203. this.$refs.emailInput.focus()
  204. }
  205. } else {
  206. this.$store.commit('showNotification', {
  207. style: 'red',
  208. message: _.get(resp, 'data.users.create.responseResult.message', 'An unexpected error occurred.'),
  209. icon: 'alert'
  210. })
  211. }
  212. } catch (err) {
  213. this.$store.commit('pushGraphError', err)
  214. }
  215. },
  216. generatePwd() {
  217. const pwdChars = 'abcdefghkmnpqrstuvwxyzABCDEFHJKLMNPQRSTUVWXYZ23456789_*=?#!()+'
  218. this.password = _.sampleSize(pwdChars, 12).join('')
  219. }
  220. },
  221. apollo: {
  222. providers: {
  223. query: gql`
  224. query {
  225. authentication {
  226. activeStrategies {
  227. key
  228. displayName
  229. }
  230. }
  231. }
  232. `,
  233. fetchPolicy: 'network-only',
  234. update: (data) => data.authentication.activeStrategies,
  235. watchLoading (isLoading) {
  236. this.$store.commit(`loading${isLoading ? 'Start' : 'Stop'}`, 'admin-users-strategies-refresh')
  237. }
  238. },
  239. groups: {
  240. query: groupsQuery,
  241. fetchPolicy: 'network-only',
  242. update: (data) => data.groups.list,
  243. watchLoading (isLoading) {
  244. this.$store.commit(`loading${isLoading ? 'Start' : 'Stop'}`, 'admin-auth-groups-refresh')
  245. }
  246. }
  247. }
  248. }
  249. </script>