Fix the middleware pipeline not handling calls to next() with a route object properly

This commit is contained in:
Bubka
2023-11-15 14:07:26 +01:00
parent 9ae52ae78f
commit f3350e2dda
7 changed files with 24 additions and 25 deletions

View File

@ -14,7 +14,7 @@ const router = createRouter({
{ path: '/start', name: 'start', component: () => import('../views/Start.vue'), meta: { middlewares: [authGuard, setReturnTo] } }, { path: '/start', name: 'start', component: () => import('../views/Start.vue'), meta: { middlewares: [authGuard, setReturnTo] } },
{ path: '/capture', name: 'capture', component: () => import('../views/twofaccounts/Capture.vue'), meta: { middlewares: [authGuard, setReturnTo] } }, { path: '/capture', name: 'capture', component: () => import('../views/twofaccounts/Capture.vue'), meta: { middlewares: [authGuard, setReturnTo] } },
{ path: '/accounts', name: 'accounts', component: () => import('../views/twofaccounts/Accounts.vue'), meta: { middlewares: [authGuard, setReturnTo, starter] }, alias: '/' }, { path: '/accounts', name: 'accounts', component: () => import('../views/twofaccounts/Accounts.vue'), meta: { middlewares: [authGuard, starter, setReturnTo] }, alias: '/' },
{ path: '/account/create', name: 'createAccount', component: () => import('../views/twofaccounts/CreateUpdate.vue'), meta: { middlewares: [authGuard, setReturnTo] } }, { path: '/account/create', name: 'createAccount', component: () => import('../views/twofaccounts/CreateUpdate.vue'), meta: { middlewares: [authGuard, setReturnTo] } },
{ path: '/account/import', name: 'importAccounts', component: () => import('../views/twofaccounts/Import.vue'), meta: { middlewares: [authGuard, setReturnTo] } }, { path: '/account/import', name: 'importAccounts', component: () => import('../views/twofaccounts/Import.vue'), meta: { middlewares: [authGuard, setReturnTo] } },
{ path: '/account/:twofaccountId/edit', name: 'editAccount', component: () => import('../views/twofaccounts/CreateUpdate.vue'), meta: { middlewares: [authGuard, setReturnTo] }, props: true }, { path: '/account/:twofaccountId/edit', name: 'editAccount', component: () => import('../views/twofaccounts/CreateUpdate.vue'), meta: { middlewares: [authGuard, setReturnTo] }, props: true },
@ -49,7 +49,8 @@ router.beforeEach((to, from, next) => {
const user = useUserStore() const user = useUserStore()
const twofaccounts = useTwofaccounts() const twofaccounts = useTwofaccounts()
const stores = { user: user, twofaccounts: twofaccounts } const stores = { user: user, twofaccounts: twofaccounts }
const context = { to, from, next, stores } const nextMiddleware = {}
const context = { to, from, next, nextMiddleware, stores }
if (!middlewares) { if (!middlewares) {
return next(); return next();
@ -57,7 +58,7 @@ router.beforeEach((to, from, next) => {
middlewares[0]({ middlewares[0]({
...context, ...context,
next: middlewarePipeline(context, middlewares, 1), nextMiddleware: middlewarePipeline(context, middlewares, 1),
}); });
}) })

View File

@ -1,12 +1,12 @@
export default function middlewarePipeline(context, middleware, index) { export default function middlewarePipeline(context, middlewares, index) {
const nextMiddleware = middleware[index]; const nextMiddleware = middlewares[index];
if (!nextMiddleware) { if (!nextMiddleware) {
return context.next; return context.next;
} }
return () => { return () => {
nextMiddleware({ nextMiddleware({
...context, ...context,
next: middlewarePipeline(context, middleware, index + 1), nextMiddleware: middlewarePipeline(context, middlewares, index + 1),
}); });
}; };
} }

View File

@ -1,25 +1,28 @@
import authService from '@/services/authService' import authService from '@/services/authService'
export default async function authGuard({ to, next, stores }) { export default async function authGuard({ to, next, nextMiddleware, stores }) {
const { user } = stores const { user } = stores
// No authenticated user on the front-end side, we try to // No authenticated user on the front-end side, we try to
// get an active user from the back-end side // get an active user from the back-end side
if (! user.isAuthenticated) { if (! user.isAuthenticated) {
const currentUser = await authService.getCurrentUser() await authService.getCurrentUser({ returnError: true }).then(async (response) => {
if (currentUser) { const currentUser = response.data
await user.loginAs({ await user.loginAs({
name: currentUser.name, name: currentUser.name,
email: currentUser.email, email: currentUser.email,
preferences: currentUser.preferences, preferences: currentUser.preferences,
isAdmin: currentUser.is_admin, isAdmin: currentUser.is_admin,
}) })
} })
.catch(error => {
// nothing to do
})
} }
if (! user.isAuthenticated) { if (! user.isAuthenticated) {
next({ name: 'login' }) next({ name: 'login' })
} else { } else {
next() nextMiddleware()
} }
} }

View File

@ -1,7 +1,7 @@
export default function noEmptyError({ to, next }) { export default function noEmptyError({ to, next, nextMiddleware }) {
if (to.params.err == undefined) { if (to.params.err == undefined) {
// return to home if no err object is provided to prevent an empty error message // return to home if no err object is provided to prevent an empty error message
next({ name: 'accounts' }); next({ name: 'accounts' });
} }
else next() else nextMiddleware()
} }

View File

@ -2,10 +2,10 @@
* Allows an authenticated user to access the main view only if he owns at least one twofaccount. * Allows an authenticated user to access the main view only if he owns at least one twofaccount.
* Push to the starter view otherwise. * Push to the starter view otherwise.
*/ */
export default function setReturnTo({ to, next, stores }) { export default function setReturnTo({ to, next, nextMiddleware, stores }) {
const { user } = stores const { user } = stores
const returnTo = useStorage(user.$2fauth.prefix + 'returnTo', 'accounts') const returnTo = useStorage(user.$2fauth.prefix + 'returnTo', 'accounts')
returnTo.value = to.name returnTo.value = to.name
next() nextMiddleware()
} }

View File

@ -2,7 +2,7 @@
* Allows an authenticated user to access the main view only if he owns at least one twofaccount. * Allows an authenticated user to access the main view only if he owns at least one twofaccount.
* Push to the starter view otherwise. * Push to the starter view otherwise.
*/ */
export default function starter({ to, next, stores }) { export default function starter({ to, next, nextMiddleware, stores }) {
const { twofaccounts } = stores const { twofaccounts } = stores
if (twofaccounts.isEmpty) { if (twofaccounts.isEmpty) {
@ -10,8 +10,8 @@ export default function starter({ to, next, stores }) {
if (twofaccounts.isEmpty) { if (twofaccounts.isEmpty) {
next({ name: 'start' }) next({ name: 'start' })
} }
else next() else nextMiddleware()
}) })
} }
else next() else nextMiddleware()
} }

View File

@ -14,13 +14,8 @@ export default {
/** /**
* *
*/ */
async getCurrentUser() { async getCurrentUser(config = {}) {
try { return apiClient.get('/user', { ...config })
const { data } = await apiClient.get('/user')
return data
} catch (error) {
return null
}
}, },
} }