Added warning message when logged out due to timeout.
This commit is contained in:
parent
6e810997a3
commit
24b531652d
|
|
@ -61,3 +61,15 @@ a:hover {
|
|||
border: 2px solid var(--theme-secondary);
|
||||
padding: 0.1rem 0.25rem;
|
||||
}
|
||||
|
||||
/* An alert banner, usually using <p>, to present some highlighted info. */
|
||||
.alert-banner {
|
||||
background-color: var(--bg-lighter);
|
||||
padding: 0.5rem;
|
||||
border-radius: 0.5rem;
|
||||
}
|
||||
|
||||
.alert-banner-warning {
|
||||
background-color: var(--warning);
|
||||
color: var(--bg);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<script setup lang="ts">
|
||||
import { useAuthStore } from '@/stores/auth-store'
|
||||
import { LogoutReason, useAuthStore } from '@/stores/auth-store'
|
||||
import { useTemplateRef, ref, computed } from 'vue'
|
||||
import ModalWrapper from './common/ModalWrapper.vue'
|
||||
import AppButton from './common/AppButton.vue'
|
||||
|
|
@ -23,7 +23,7 @@ function start() {
|
|||
timeoutTimerId.value = window.setInterval(() => {
|
||||
secondsUntilLogout.value = secondsUntilLogout.value - 1
|
||||
if (secondsUntilLogout.value <= 0) {
|
||||
authStore.onUserLoggedOut()
|
||||
authStore.onUserLoggedOut(LogoutReason.INACTIVITY_TIMEOUT)
|
||||
window.clearInterval(timeoutTimerId.value)
|
||||
}
|
||||
}, 1000)
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import AppButton from '@/components/common/AppButton.vue'
|
|||
import AppForm from '@/components/common/form/AppForm.vue'
|
||||
import FormControl from '@/components/common/form/FormControl.vue'
|
||||
import FormGroup from '@/components/common/form/FormGroup.vue'
|
||||
import { useAuthStore } from '@/stores/auth-store'
|
||||
import { LogoutReason, useAuthStore } from '@/stores/auth-store'
|
||||
import { showAlert } from '@/util/alert'
|
||||
import { hideLoader, showLoader } from '@/util/loader'
|
||||
import { ref } from 'vue'
|
||||
|
|
@ -89,6 +89,22 @@ function generateSampleData() {
|
|||
<p style="text-align: center; font-weight: 600; margin-top: 0">
|
||||
<em>Personal finance for the modern era.</em>
|
||||
</p>
|
||||
|
||||
<p
|
||||
v-if="authStore.logoutReason === LogoutReason.INACTIVITY_TIMEOUT"
|
||||
class="alert-banner alert-banner-warning"
|
||||
>
|
||||
You were logged out automatically after being inactive for a while. Please log in again to
|
||||
resume your session.
|
||||
</p>
|
||||
|
||||
<p
|
||||
v-if="authStore.logoutReason === LogoutReason.TOKEN_EXPIRED"
|
||||
class="alert-banner alert-banner-warning"
|
||||
>
|
||||
You were logged out because your session expired. Please log in again to resume your session.
|
||||
</p>
|
||||
|
||||
<AppForm @submit="doLogin()">
|
||||
<FormGroup>
|
||||
<FormControl
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ import { AuthApiClient } from '@/api/auth'
|
|||
import { getSelectedProfile } from '@/api/profile'
|
||||
import { secondsUntilExpired } from '@/api/token-util'
|
||||
import IdleTimeoutModal from '@/components/IdleTimeoutModal.vue'
|
||||
import { useAuthStore } from '@/stores/auth-store'
|
||||
import { LogoutReason, useAuthStore } from '@/stores/auth-store'
|
||||
import { useIdleObserver } from '@idle-observer/vue3'
|
||||
import { onMounted, ref, useTemplateRef, type Ref } from 'vue'
|
||||
import { useRoute, useRouter } from 'vue-router'
|
||||
|
|
@ -17,7 +17,7 @@ const route = useRoute()
|
|||
const router = useRouter()
|
||||
const authStore = useAuthStore()
|
||||
|
||||
const IDLE_TIMEOUT_SECONDS = 300
|
||||
const IDLE_TIMEOUT_SECONDS = 10
|
||||
const idleTimeoutModal = useTemplateRef('idleTimeoutModal')
|
||||
useIdleObserver({
|
||||
timeout: IDLE_TIMEOUT_SECONDS * 1000,
|
||||
|
|
@ -61,7 +61,7 @@ async function checkAuth() {
|
|||
console.warn('Failed to refresh token.', err)
|
||||
}
|
||||
} else if (secondsUntilExpiration <= 0) {
|
||||
authStore.onUserLoggedOut()
|
||||
authStore.onUserLoggedOut(LogoutReason.TOKEN_EXPIRED)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
|
@ -87,7 +87,7 @@ async function checkAuth() {
|
|||
|
||||
<span
|
||||
class="app-logout-button"
|
||||
@click="authStore.onUserLoggedOut()"
|
||||
@click="authStore.onUserLoggedOut(LogoutReason.USER_LOGGED_OUT)"
|
||||
>
|
||||
<font-awesome-icon icon="fa-solid fa-arrow-right-from-bracket"></font-awesome-icon>
|
||||
</span>
|
||||
|
|
|
|||
|
|
@ -9,20 +9,31 @@ export interface AuthenticatedData {
|
|||
|
||||
const LOCAL_STORAGE_KEY = 'token'
|
||||
|
||||
export enum LogoutReason {
|
||||
USER_LOGGED_OUT,
|
||||
INACTIVITY_TIMEOUT,
|
||||
TOKEN_EXPIRED,
|
||||
}
|
||||
|
||||
export const useAuthStore = defineStore('auth', () => {
|
||||
console.log('Initializing authStore')
|
||||
|
||||
const state: Ref<AuthenticatedData | null> = ref(getStateFromLocalStorage())
|
||||
const logoutReason: Ref<LogoutReason | null> = ref(null)
|
||||
|
||||
function onUserLoggedIn(username: string, token: string) {
|
||||
state.value = { username, token }
|
||||
logoutReason.value = null
|
||||
localStorage.setItem(LOCAL_STORAGE_KEY, token)
|
||||
}
|
||||
|
||||
function onUserLoggedOut() {
|
||||
function onUserLoggedOut(reason: LogoutReason) {
|
||||
state.value = null
|
||||
logoutReason.value = reason
|
||||
localStorage.removeItem(LOCAL_STORAGE_KEY)
|
||||
}
|
||||
|
||||
return { state, onUserLoggedIn, onUserLoggedOut }
|
||||
return { state, logoutReason, onUserLoggedIn, onUserLoggedOut }
|
||||
})
|
||||
|
||||
function getStateFromLocalStorage(): AuthenticatedData | null {
|
||||
|
|
@ -32,6 +43,5 @@ function getStateFromLocalStorage(): AuthenticatedData | null {
|
|||
return null
|
||||
}
|
||||
const username = parseSubject(token)
|
||||
console.info('Loaded authentication information for user', username)
|
||||
return { username, token }
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue