This repository has been archived on 2024-02-08. You can view files and clone it, but cannot push or open issues or pull requests.
frontend/src/views/user/OpenIdAuth.vue

87 lines
2.7 KiB
Vue
Raw Normal View History

<template>
<div>
<message variant="danger" v-if="errorMessage">
{{ errorMessage }}
</message>
<message variant="danger" v-if="errorMessageFromQuery" class="mt-2">
{{ errorMessageFromQuery }}
</message>
<message v-if="loading">
{{ $t('user.auth.authenticating') }}
</message>
</div>
</template>
2022-02-15 12:07:34 +00:00
<script lang="ts">
2022-06-23 01:08:35 +00:00
export default { name: 'Auth' }
2022-05-21 00:05:42 +00:00
</script>
<script setup lang="ts">
import {ref, computed, onMounted} from 'vue'
2022-10-23 11:12:04 +00:00
import {useRoute} from 'vue-router'
2022-05-21 00:05:42 +00:00
import {useI18n} from 'vue-i18n'
import {getErrorText} from '@/message'
2022-05-21 00:05:42 +00:00
import Message from '@/components/misc/message.vue'
2022-10-23 11:12:04 +00:00
import {useRedirectToLastVisited} from '@/composables/useRedirectToLastVisited'
2022-09-24 13:20:40 +00:00
2022-09-21 01:37:39 +00:00
import {useAuthStore} from '@/stores/auth'
2022-08-04 19:55:02 +00:00
const {t} = useI18n({useScope: 'global'})
2022-05-21 00:05:42 +00:00
const route = useRoute()
2022-10-23 11:12:04 +00:00
const {redirectIfSaved} = useRedirectToLastVisited()
2022-09-21 01:37:39 +00:00
const authStore = useAuthStore()
2022-09-30 10:52:21 +00:00
const loading = computed(() => authStore.isLoading)
2022-05-21 00:05:42 +00:00
const errorMessage = ref('')
const errorMessageFromQuery = computed(() => route.query.error)
2021-08-14 15:31:35 +00:00
2022-05-21 00:05:42 +00:00
async function authenticateWithCode() {
// This component gets mounted twice: The first time when the actual auth request hits the frontend,
// the second time after that auth request succeeded and the outer component "content-no-auth" isn't used
// but instead the "content-auth" component is used. Because this component is just a route and thus
// gets mounted as part of a <router-view/> which both the content-auth and content-no-auth components have,
// this re-mounts the component, even if the user is already authenticated.
// To make sure we only try to authenticate the user once, we set this "authenticating" lock in localStorage
// which ensures only one auth request is done at a time. We don't simply check if the user is already
// authenticated to not prevent the whole authentication if some user is already logged in.
if (localStorage.getItem('authenticating')) {
return
}
2022-10-17 11:14:07 +00:00
localStorage.setItem('authenticating', 'true')
2022-05-21 00:05:42 +00:00
errorMessage.value = ''
if (typeof route.query.error !== 'undefined') {
localStorage.removeItem('authenticating')
errorMessage.value = typeof route.query.message !== 'undefined'
2022-10-17 11:14:07 +00:00
? route.query.message as string
2022-05-21 00:05:42 +00:00
: t('user.auth.openIdGeneralError')
return
}
const state = localStorage.getItem('state')
if (typeof route.query.state === 'undefined' || route.query.state !== state) {
localStorage.removeItem('authenticating')
errorMessage.value = t('user.auth.openIdStateError')
return
}
try {
2022-09-21 01:37:39 +00:00
await authStore.openIdAuth({
2022-05-21 00:05:42 +00:00
provider: route.params.provider,
code: route.query.code,
})
2022-10-23 11:12:04 +00:00
redirectIfSaved()
2022-05-21 00:05:42 +00:00
} catch(e) {
errorMessage.value = getErrorText(e)
2022-05-21 00:05:42 +00:00
} finally {
localStorage.removeItem('authenticating')
}
}
2022-05-21 00:05:42 +00:00
onMounted(() => authenticateWithCode())
</script>