mirror of
https://github.com/Bubka/2FAuth.git
synced 2024-12-23 23:49:53 +01:00
Add Starter middleware & Restore the Data have changed notification
This commit is contained in:
parent
4dbbae24dc
commit
8c23aa884f
@ -47,7 +47,16 @@
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<notifications id="vueNotification" role="alert" width="100%" position="top" :duration="4000" :speed="0" :max="1" classes="notification is-radiusless" />
|
||||
<notifications
|
||||
id="vueNotification"
|
||||
role="alert"
|
||||
width="100%"
|
||||
position="top"
|
||||
:duration="4000"
|
||||
:speed="0"
|
||||
:max="1"
|
||||
classes="notification is-radiusless"
|
||||
:dangerouslySetInnerHtml="true" />
|
||||
<main class="main-section">
|
||||
<RouterView />
|
||||
</main>
|
||||
|
5
resources/js_vue3/router/index.js
vendored
5
resources/js_vue3/router/index.js
vendored
@ -27,7 +27,8 @@ import EditCredential from '../views/settings/Credentials/Edit.vue'
|
||||
import Errors from '../views/Error.vue'
|
||||
import About from '../views/About.vue'
|
||||
|
||||
import authGuard from './middlewares/authGuard'
|
||||
import authGuard from './middlewares/authGuard'
|
||||
import starter from './middlewares/starter'
|
||||
import noEmptyError from './middlewares/noEmptyError'
|
||||
|
||||
const router = createRouter({
|
||||
@ -36,7 +37,7 @@ const router = createRouter({
|
||||
{ path: '/start', name: 'start', component: Start, meta: { middlewares: [authGuard] } },
|
||||
{ path: '/capture', name: 'capture', component: Capture, meta: { middlewares: [authGuard] } },
|
||||
|
||||
{ path: '/accounts', name: 'accounts', component: Accounts, meta: { middlewares: [authGuard] }, alias: '/' },
|
||||
{ path: '/accounts', name: 'accounts', component: Accounts, meta: { middlewares: [authGuard, starter] }, alias: '/' },
|
||||
{ path: '/account/create', name: 'createAccount', component: CreateAccount, meta: { middlewares: [authGuard] } },
|
||||
{ path: '/account/import', name: 'importAccounts', component: ImportAccount, meta: { middlewares: [authGuard] } },
|
||||
{ path: '/account/:twofaccountId/edit', name: 'editAccount', component: EditAccount, meta: { middlewares: [authGuard] } },
|
||||
|
19
resources/js_vue3/router/middlewares/starter.js
vendored
Normal file
19
resources/js_vue3/router/middlewares/starter.js
vendored
Normal file
@ -0,0 +1,19 @@
|
||||
import { useTwofaccounts } from '@/stores/twofaccounts'
|
||||
|
||||
/**
|
||||
* Allows the user to access the main view only if he owns at least one twofaccount.
|
||||
* Push to the starter view otherwise.
|
||||
*/
|
||||
export default function starter({ to, next }) {
|
||||
const twofaccounts = useTwofaccounts()
|
||||
|
||||
if (twofaccounts.isEmpty) {
|
||||
twofaccounts.refresh().then(() => {
|
||||
if (twofaccounts.isEmpty) {
|
||||
next({ name: 'start' });
|
||||
}
|
||||
else next()
|
||||
})
|
||||
}
|
||||
else next()
|
||||
}
|
30
resources/js_vue3/stores/twofaccounts.js
vendored
30
resources/js_vue3/stores/twofaccounts.js
vendored
@ -51,8 +51,8 @@ export const useTwofaccounts = defineStore({
|
||||
return state.items.map(a => a.id)
|
||||
},
|
||||
|
||||
isNotEmpty(state) {
|
||||
return state.items.length > 0
|
||||
isEmpty(state) {
|
||||
return state.items.length == 0
|
||||
},
|
||||
|
||||
count(state) {
|
||||
@ -83,6 +83,32 @@ export const useTwofaccounts = defineStore({
|
||||
})
|
||||
},
|
||||
|
||||
/**
|
||||
* Tells if the store is up-to-date with the backend
|
||||
*/
|
||||
async isUpToDateWithBackend() {
|
||||
let isUpToDate = true
|
||||
await twofaccountService.getAll().then(response => {
|
||||
isUpToDate = response.data.length === this.items.length
|
||||
|
||||
this.items.forEach((item) => {
|
||||
let matchingBackendItem = response.data.find(e => e.id === item.id)
|
||||
if (matchingBackendItem == undefined) {
|
||||
isUpToDate = false
|
||||
return;
|
||||
}
|
||||
for (const field in item) {
|
||||
if (item[field] != matchingBackendItem[field]) {
|
||||
isUpToDate = false
|
||||
return;
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
return isUpToDate
|
||||
},
|
||||
|
||||
/**
|
||||
* Adds an account to the current selection
|
||||
*/
|
||||
|
@ -51,32 +51,20 @@
|
||||
* Returns whether or not the accounts should be displayed
|
||||
*/
|
||||
const showAccounts = computed(() => {
|
||||
return twofaccounts.isNotEmpty && !showGroupSwitch.value && !showDestinationGroupSelector.value
|
||||
return !twofaccounts.isEmpty && !showGroupSwitch.value && !showDestinationGroupSelector.value
|
||||
})
|
||||
|
||||
onMounted(() => {
|
||||
// we don't have to fetch fresh data so we try to load them from localstorage to avoid display latency
|
||||
// if( user.preferences.getOtpOnRequest && !this.toRefresh && !this.$route.params.isFirstLoad ) {
|
||||
// const accounts = this.$storage.get('accounts', null) // use null as fallback if localstorage is empty
|
||||
// if( accounts ) this.accounts = accounts
|
||||
|
||||
// const groups = this.$storage.get('groups', null) // use null as fallback if localstorage is empty
|
||||
// if( groups ) this.groups = groups
|
||||
// }
|
||||
|
||||
// We fetch fresh data whatever. The user will be notified to reload the page if there are any data changes
|
||||
twofaccounts.refresh()
|
||||
groups.refresh()
|
||||
|
||||
// if (twofaccounts.count === 0) {
|
||||
// // No account yet, we force user to land on the start view.
|
||||
// router.push({ name: 'start' });
|
||||
// }
|
||||
|
||||
// stop OTP generation on modal close
|
||||
// this.$on('modalClose', function() {
|
||||
// this.$refs.OtpDisplayer.clearOTP()
|
||||
// })
|
||||
onMounted(async () => {
|
||||
// This SFC is reached only if the user has some twofaccounts in the store (see the starter middleware).
|
||||
// This allows to display accounts without latency.
|
||||
// We now check the twofaccounts store state in case the backend data have changed.
|
||||
const isUpToDate = await twofaccounts.isUpToDateWithBackend()
|
||||
if (! isUpToDate) {
|
||||
notify.action({
|
||||
text: '<span class="is-size-7">' + trans('commons.data_have_changed_on_server_side') + '</span><br /><a href="." class="button is-rounded is-warning is-small">' + trans('commons.reload') + '</a>',
|
||||
duration: -1
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
/**
|
||||
|
@ -110,7 +110,7 @@
|
||||
<!-- Footer -->
|
||||
<VueFooter :showButtons="true" >
|
||||
<!-- back button -->
|
||||
<p class="control" v-if="twofaccounts.length > 0">
|
||||
<p class="control" v-if="! twofaccounts.isEmpty">
|
||||
<UseColorMode v-slot="{ mode }">
|
||||
<RouterLink id="lnkBack" class="button is-rounded" :class="{'is-dark' : mode == 'dark'}" :to="{ name: 'accounts' }" >
|
||||
{{ $t('commons.back') }}
|
||||
|
Loading…
Reference in New Issue
Block a user