SignupVerify.vue 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. <!-- Copyright (C) 2012-2024 Zammad Foundation, https://zammad-foundation.org/ -->
  2. <script setup lang="ts">
  3. import { computed, onMounted, ref } from 'vue'
  4. import { useRouter } from 'vue-router'
  5. import useFingerprint from '#shared/composables/useFingerprint.ts'
  6. import { MutationHandler } from '#shared/server/apollo/handler/index.ts'
  7. import { useApplicationStore } from '#shared/stores/application.ts'
  8. import { useAuthenticationStore } from '#shared/stores/authentication.ts'
  9. import CommonLoader from '#desktop/components/CommonLoader/CommonLoader.vue'
  10. import LayoutPublicPage from '#desktop/components/layout/LayoutPublicPage/LayoutPublicPage.vue'
  11. import { ensureAfterAuth } from '../after-auth/composable/useAfterAuthPlugins.ts'
  12. import { useUserSignupVerifyMutation } from '../graphql/mutations/userSignupVerify.api.ts'
  13. import type { VerifyState } from '../types/signup.ts'
  14. defineOptions({
  15. beforeRouteEnter(to) {
  16. const application = useApplicationStore()
  17. if (!application.config.user_create_account) {
  18. return to.redirectedFrom ? false : '/'
  19. }
  20. return true
  21. },
  22. })
  23. interface Props {
  24. token?: string
  25. }
  26. const props = defineProps<Props>()
  27. const router = useRouter()
  28. const state = ref<VerifyState>('loading')
  29. const setState = (newState: VerifyState) => {
  30. state.value = newState
  31. }
  32. const message = computed(() => {
  33. switch (state.value) {
  34. case 'success':
  35. return __('Woo hoo! Your email address has been verified!')
  36. case 'error':
  37. return __(
  38. 'Email could not be verified. Please contact your administrator.',
  39. )
  40. case 'loading':
  41. default:
  42. return __('Verifying your email…')
  43. }
  44. })
  45. onMounted(() => {
  46. if (!props.token) {
  47. state.value = 'error'
  48. return
  49. }
  50. const { fingerprint } = useFingerprint()
  51. const userSignupVerify = new MutationHandler(
  52. useUserSignupVerifyMutation({
  53. variables: { token: props.token },
  54. context: {
  55. headers: {
  56. 'X-Browser-Fingerprint': fingerprint.value,
  57. },
  58. },
  59. }),
  60. {
  61. errorShowNotification: false,
  62. },
  63. )
  64. userSignupVerify
  65. .send()
  66. .then(async (result) => {
  67. const { setAuthenticatedSessionId } = useAuthenticationStore()
  68. if (
  69. await setAuthenticatedSessionId(
  70. result?.userSignupVerify?.session?.id || null,
  71. )
  72. ) {
  73. setState('success')
  74. const afterAuth = result?.userSignupVerify?.session?.afterAuth
  75. // Redirect only after some seconds, in order to give the user a chance to read the message.
  76. window.setTimeout(() => {
  77. if (afterAuth) {
  78. ensureAfterAuth(router, afterAuth)
  79. return
  80. }
  81. router.replace('/')
  82. }, 2000)
  83. return
  84. }
  85. setState('error')
  86. })
  87. .catch(() => {
  88. setState('error')
  89. })
  90. })
  91. </script>
  92. <template>
  93. <LayoutPublicPage box-size="small" :title="__('Email Verification')">
  94. <div class="mt-1 text-center">
  95. <CommonLabel>
  96. {{ $t(message) }}
  97. </CommonLabel>
  98. <CommonLoader v-if="state === 'loading'" class="mb-3 mt-9" loading />
  99. <CommonIcon
  100. v-else-if="state === 'success'"
  101. class="mx-auto mb-3 mt-9 fill-green-500"
  102. name="check-circle-outline"
  103. />
  104. <CommonIcon
  105. v-else-if="state === 'error'"
  106. class="mx-auto mb-3 mt-9 fill-red-500"
  107. name="x-circle"
  108. />
  109. </div>
  110. </LayoutPublicPage>
  111. </template>