diff --git a/src/components/Pages/EmailVerification.vue b/src/components/Pages/EmailVerification.vue
index 4ac8d850..a9ae4275 100644
--- a/src/components/Pages/EmailVerification.vue
+++ b/src/components/Pages/EmailVerification.vue
@@ -7,6 +7,9 @@
{{state.message}}
+
+ Log in to your account.
+
@@ -22,23 +25,29 @@ const STATES = Object.freeze({
export default {
name: 'EmailVerification',
- computed: {},
+ computed: {
+ showLoginLink () {
+ return this.state === STATES.VERIFIED && !this.$store.getters.isLoggedIn
+ },
+ },
data () {
return {
- state: this.$store.getters.currentUser.verified ? STATES.VERIFIED : STATES.PENDING,
+ state: STATES.PENDING,
}
},
created () {
- if (!this.$store.getters.currentUser.verified) {
- this.$api.verifyEmail({ token: this.$route.params.token })
- .then(message => this.success())
- .catch(expired => this.fail(expired))
- }
+ this.$api.verifyEmail({ token: this.$route.params.token })
+ .then(() => this.success())
+ .catch(expired => this.fail(expired))
},
methods: {
- success (message) {
+ success () {
this.state = STATES.VERIFIED
- this.$store.dispatch('markAsVerified', {})
+ if (this.$store.getters.isLoggedIn) {
+ this.$api.checkVerified()
+ .then(verified => verified && this.$store.dispatch('markAsVerified'))
+ .catch(err => console.error(err))
+ }
},
fail (expired) {
if (expired) {
diff --git a/src/main.js b/src/main.js
index 09f46070..59aa1a06 100644
--- a/src/main.js
+++ b/src/main.js
@@ -54,8 +54,7 @@ enableMocking().then(() => {
return new Promise(function (resolve, reject) {
// Unauthenticated. is the exact error message returned by the API for the auth middle ware
// which is why we check for that message here...
- if (err.response.config && !err.response.config.__isRetryRequest && err.response.data && err.response.data.error && err.response.data.error === 'Unauthenticated.') {
- // TODO this IF should also have a condition for is logged in....
+ if (store.getters.isLoggedIn && err.response.config && !err.response.config.__isRetryRequest && err.response.data && err.response.data.error && err.response.data.error === 'Unauthenticated.') {
console.log('Detected logged out state, so logging out...')
store
.dispatch('logout')
diff --git a/src/router/index.js b/src/router/index.js
index b755b966..d772cdad 100644
--- a/src/router/index.js
+++ b/src/router/index.js
@@ -128,11 +128,6 @@ const router = new Router({
path: '/emailVerification/:token',
name: 'EmailVerification',
component: EmailVerification,
- meta: {
- requiresAuth: {
- excludeFromPolicyChecks: true,
- },
- },
},
{
path: '/user',
diff --git a/tests/unit/email-verification.spec.js b/tests/unit/email-verification.spec.js
new file mode 100644
index 00000000..05af7277
--- /dev/null
+++ b/tests/unit/email-verification.spec.js
@@ -0,0 +1,73 @@
+import { shallowMount } from '@vue/test-utils'
+import EmailVerification from '@/components/Pages/EmailVerification.vue'
+
+const flushPromises = () => new Promise(resolve => setTimeout(resolve))
+
+const mountEmailVerification = ({ isLoggedIn = false, verifyEmail, checkVerified } = {}) => {
+ return shallowMount(EmailVerification, {
+ mocks: {
+ $api: {
+ verifyEmail: verifyEmail || jest.fn().mockResolvedValue(),
+ checkVerified: checkVerified || jest.fn().mockResolvedValue(true),
+ },
+ $route: {
+ params: {
+ token: 'email-verification-token',
+ },
+ },
+ $store: {
+ getters: {
+ isLoggedIn,
+ },
+ dispatch: jest.fn(),
+ },
+ },
+ stubs: {
+ 'v-main': true,
+ 'v-card': true,
+ 'v-toolbar': true,
+ 'v-toolbar-title': true,
+ 'v-card-text': true,
+ 'router-link': {
+ props: ['to'],
+ template: '',
+ },
+ },
+ })
+}
+
+describe('EmailVerification.vue', () => {
+ it('verifies a token without a login and offers a login link', async () => {
+ const verifyEmail = jest.fn().mockResolvedValue()
+ const wrapper = mountEmailVerification({ verifyEmail })
+
+ await flushPromises()
+
+ expect(verifyEmail).toHaveBeenCalledWith({ token: 'email-verification-token' })
+ expect(wrapper.text()).toContain('Email verified!')
+ expect(wrapper.find('a').attributes('href')).toBe('/login')
+ })
+
+ it('does not offer a login link to an existing authenticated session', async () => {
+ const checkVerified = jest.fn().mockResolvedValue(false)
+ const wrapper = mountEmailVerification({ isLoggedIn: true, checkVerified })
+
+ await flushPromises()
+
+ expect(wrapper.text()).toContain('Email verified!')
+ expect(wrapper.find('a').exists()).toBe(false)
+ expect(checkVerified).toHaveBeenCalled()
+ expect(wrapper.vm.$store.dispatch).not.toHaveBeenCalled()
+ })
+
+ it('does not offer a login link when the token cannot be verified', async () => {
+ const wrapper = mountEmailVerification({
+ verifyEmail: jest.fn().mockRejectedValue(true),
+ })
+
+ await flushPromises()
+
+ expect(wrapper.text()).toContain('Verification token expired, or you are already verified!')
+ expect(wrapper.find('a').exists()).toBe(false)
+ })
+})