PasswordReset.vue 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. <!-- Copyright (C) 2012-2024 Zammad Foundation, https://zammad-foundation.org/ -->
  2. <script setup lang="ts">
  3. import { useRouter } from 'vue-router'
  4. import { ref } from 'vue'
  5. import type {
  6. FormSchemaNode,
  7. FormSubmitData,
  8. } from '#shared/components/Form/types.ts'
  9. import Form from '#shared/components/Form/Form.vue'
  10. import { useForm } from '#shared/components/Form/useForm.ts'
  11. import { useApplicationStore } from '#shared/stores/application.ts'
  12. import { EnumPublicLinksScreen } from '#shared/graphql/types.ts'
  13. import MutationHandler from '#shared/server/apollo/handler/MutationHandler.ts'
  14. import { useNotifications } from '#shared/components/CommonNotifications/useNotifications.ts'
  15. import { NotificationTypes } from '#shared/components/CommonNotifications/types.ts'
  16. import UserError from '#shared/errors/UserError.ts'
  17. import LayoutPublicPage from '#desktop/components/layout/LayoutPublicPage/LayoutPublicPage.vue'
  18. import CommonButton from '#desktop/components/CommonButton/CommonButton.vue'
  19. import CommonPublicLinks from '#desktop/components/CommonPublicLinks/CommonPublicLinks.vue'
  20. import { useUserPasswordResetSendMutation } from '../graphql/mutations/userPasswordResetSend.api.ts'
  21. defineOptions({
  22. beforeRouteEnter(to) {
  23. const application = useApplicationStore()
  24. if (!application.config.user_lost_password) {
  25. return to.redirectedFrom ? false : '/'
  26. }
  27. return true
  28. },
  29. })
  30. const router = useRouter()
  31. interface FormValues {
  32. login: string
  33. }
  34. const formSchema: FormSchemaNode[] = [
  35. {
  36. type: 'text',
  37. label: __('Username / Email'),
  38. name: 'login',
  39. required: true,
  40. },
  41. ]
  42. const { form, isDisabled } = useForm()
  43. const showSuccessScreen = ref(false)
  44. const resetHandler = new MutationHandler(useUserPasswordResetSendMutation())
  45. const { notify } = useNotifications()
  46. const resetPassword = async (form: FormSubmitData<FormValues>) => {
  47. try {
  48. const result = await resetHandler.send({ username: form.login })
  49. if (result?.userPasswordResetSend?.success) {
  50. showSuccessScreen.value = true
  51. }
  52. } catch (error) {
  53. if (error instanceof UserError) {
  54. notify({
  55. type: NotificationTypes.Error,
  56. message: error.generalErrors[0],
  57. })
  58. }
  59. }
  60. }
  61. const resetForm = () => {
  62. showSuccessScreen.value = false
  63. }
  64. const goToLogin = () => {
  65. router.replace('/login')
  66. }
  67. </script>
  68. <template>
  69. <LayoutPublicPage
  70. box-size="small"
  71. :title="
  72. showSuccessScreen
  73. ? __('The password reset request was successful.')
  74. : __('Forgot your password?')
  75. "
  76. >
  77. <Form
  78. v-if="!showSuccessScreen"
  79. id="password-reset"
  80. ref="form"
  81. form-class="mb-2.5"
  82. :schema="formSchema"
  83. @submit="resetPassword($event as FormSubmitData<FormValues>)"
  84. />
  85. <section v-else>
  86. <CommonLabel class="text-center mb-5">
  87. {{ $t('Password reset instructions were sent to your email address.') }}
  88. </CommonLabel>
  89. <CommonLabel class="text-center">
  90. {{
  91. $t(
  92. "If you don't receive instructions within a minute or two, check your email's spam and junk filters, or try resending your request.",
  93. )
  94. }}
  95. </CommonLabel>
  96. </section>
  97. <template #boxActions>
  98. <CommonButton
  99. variant="secondary"
  100. size="medium"
  101. :disabled="isDisabled"
  102. @click="goToLogin()"
  103. >
  104. {{ $t('Cancel & Go Back') }}
  105. </CommonButton>
  106. <CommonButton
  107. v-if="!showSuccessScreen"
  108. type="submit"
  109. variant="submit"
  110. size="medium"
  111. form="password-reset"
  112. :disabled="isDisabled"
  113. >
  114. {{ $t('Submit') }}
  115. </CommonButton>
  116. <CommonButton v-else variant="submit" size="medium" @click="resetForm">
  117. {{ $t('Try again') }}
  118. </CommonButton>
  119. </template>
  120. <template #bottomContent>
  121. <CommonPublicLinks :screen="EnumPublicLinksScreen.PasswordReset" />
  122. </template>
  123. </LayoutPublicPage>
  124. </template>