PersonalSettingPassword.vue 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. <!-- Copyright (C) 2012-2024 Zammad Foundation, https://zammad-foundation.org/ -->
  2. <script setup lang="ts">
  3. import {
  4. NotificationTypes,
  5. useNotifications,
  6. } from '#shared/components/CommonNotifications/index.ts'
  7. import Form from '#shared/components/Form/Form.vue'
  8. import type { FormSubmitData } from '#shared/components/Form/types.ts'
  9. import { useForm } from '#shared/components/Form/useForm.ts'
  10. import { ErrorRouteType, redirectErrorRoute } from '#shared/router/error.ts'
  11. import { MutationHandler } from '#shared/server/apollo/handler/index.ts'
  12. import { ErrorStatusCodes } from '#shared/types/error.ts'
  13. import CommonButton from '#desktop/components/CommonButton/CommonButton.vue'
  14. import LayoutContent from '#desktop/components/layout/LayoutContent.vue'
  15. import { useCheckChangePassword } from '../composables/permission/useCheckChangePassword.ts'
  16. import { useBreadcrumb } from '../composables/useBreadcrumb.ts'
  17. import { useUserCurrentChangePasswordMutation } from '../graphql/mutations/userCurrentChangePassword.api.ts'
  18. import type { ChangePasswordFormData } from '../types/change-password.ts'
  19. defineOptions({
  20. beforeRouteEnter() {
  21. const { canChangePassword } = useCheckChangePassword()
  22. if (!canChangePassword.value)
  23. return redirectErrorRoute({
  24. type: ErrorRouteType.AuthenticatedError,
  25. title: __('Forbidden'),
  26. message: __('Password change has been disabled by the administrator.'),
  27. statusCode: ErrorStatusCodes.Forbidden,
  28. })
  29. return true
  30. },
  31. })
  32. const { form, isDisabled } = useForm()
  33. const schema = [
  34. {
  35. isLayout: true,
  36. element: 'div',
  37. attrs: {
  38. class: 'grid grid-cols-2 gap-2.5',
  39. },
  40. children: [
  41. {
  42. name: 'current_password',
  43. label: __('Current password'),
  44. type: 'password',
  45. outerClass: 'col-span-2',
  46. props: {
  47. maxLength: 1001,
  48. autocomplete: 'current-password',
  49. },
  50. required: true,
  51. },
  52. {
  53. name: 'new_password',
  54. label: __('New password'),
  55. type: 'password',
  56. outerClass: 'col-span-1',
  57. props: {
  58. maxLength: 1001,
  59. autocomplete: 'new-password',
  60. },
  61. required: true,
  62. },
  63. {
  64. name: 'new_password_confirm',
  65. label: __('Confirm new password'),
  66. type: 'password',
  67. validation: 'confirm',
  68. outerClass: 'col-span-1',
  69. props: {
  70. maxLength: 1001,
  71. autocomplete: 'new-password',
  72. },
  73. required: true,
  74. },
  75. ],
  76. },
  77. ]
  78. const { breadcrumbItems } = useBreadcrumb(__('Password'))
  79. const { notify } = useNotifications()
  80. const changePasswordMutation = new MutationHandler(
  81. useUserCurrentChangePasswordMutation(),
  82. {
  83. errorNotificationMessage: __('Password could not be changed.'),
  84. },
  85. )
  86. const submitForm = async (formData: FormSubmitData<ChangePasswordFormData>) => {
  87. return changePasswordMutation
  88. .send({
  89. currentPassword: formData.current_password as string,
  90. newPassword: formData.new_password as string,
  91. })
  92. .then((data) => {
  93. if (data?.userCurrentChangePassword?.success) {
  94. notify({
  95. id: 'password-changed',
  96. type: NotificationTypes.Success,
  97. message: __('Password changed successfully.'),
  98. })
  99. }
  100. })
  101. }
  102. </script>
  103. <template>
  104. <LayoutContent
  105. :breadcrumb-items="breadcrumbItems"
  106. :help-text="
  107. $t('Enter your current password, insert a new one and confirm it.')
  108. "
  109. width="narrow"
  110. >
  111. <div class="mb-4">
  112. <Form
  113. ref="form"
  114. :schema="schema"
  115. clear-values-after-submit
  116. @submit="submitForm($event as FormSubmitData<ChangePasswordFormData>)"
  117. >
  118. <template #after-fields>
  119. <div class="mt-5 flex items-center justify-end gap-2">
  120. <CommonButton
  121. variant="submit"
  122. type="submit"
  123. size="medium"
  124. :disabled="isDisabled"
  125. >
  126. {{ $t('Change Password') }}
  127. </CommonButton>
  128. </div>
  129. </template>
  130. </Form>
  131. </div>
  132. </LayoutContent>
  133. </template>