Repository navigation
fix: [Portal] If you sign out of the portal while logged in and using an application that requires authentication, the system will trigger three "Access Denied" error messages. - #7804
Conversation
… an application that requires authentication, the system will trigger three "Access Denied" error messages.
| ) | ||
| .catch(() => {}) | ||
| } | ||
|
|
There was a problem hiding this comment.
Here is the review of the code changes:
1. Potential Issue: Stale Closure of route
Problem: The handleLogout function uses router.replace. Inside the callback, it accesses route.meta and route.params.
If this is a Vue component where route comes from useRoute(), route is a reactive object. However, in a .then() promise callback, if the user navigates away before the logout API resolves, or if the component unmounts, relying on the current reactive route state might be unreliable depending on how Vue handles reactivity during async callbacks.
More importantly, using route inside the async callback risks capturing the wrong context if the logic isn't carefully bound. While Vue's ref/reactive objects generally persist their properties even after navigation events trigger updates, it is clearer and safer to capture the necessary parts (portal status, accessToken) before the promise chain or ensure they are accessed reliably.
However, the bigger issue is UX and Logic:
- If the user is on a chat screen and logs out,
route.params.accessTokenmight no longer be valid or relevant for the new anonymous session ifchat-homeexpects an active access token. Passing a stale/invalidaccessTokenas a param could cause immediate errors upon navigation if the next page guards or composables try to use it immediately.
2. Irregularity: Silent Error Handling
The .catch(() => {}) silently swallows all errors, including network failures from auth.logout() or router errors. This makes debugging extremely difficult.
Suggestion: At minimum, log the error, or show a toast notification if logout failed (though usually, local cleanup should happen regardless).
3. Optimization/Best Practice: Explicit vs. Implicit Navigation
Using route.name === 'portal-application-list' checks route.meta.portal. This couples routing logic with view metadata. It is generally fine but ensure meta.portal is strictly typed and always present when expected.
4. Code Style & Readability
- The ternary operator inside
router.replace()is visually cluttered. Extracting the target route into a variable improves readability. force: trueis passed in both branches. Ensure this is actually needed. Forcing a replace might reset scroll positions unnecessarily if the content is similar, but usually good for login/logout.
✅ Recommended Improved Version
import { useRoute } from 'vue-router' // Ensure these imports exist elsewhere
import type { RouteLocationRaw } from 'vue-router'
// Assuming `route` is from useRoute() and `router` is from useRouter()
const handleLogout = () => {
// Capture needed values BEFORE async operation starts to avoid subtle reactivity issues
// and clarify intent. Also handles cases where route might change during async wait.
const isPortal = !!route.meta.portal
const accessToken = route.params.accessToken
return auth.logout().then(() => {
let targetRoute: RouteLocationRaw;
if (isPortal) {
targetRoute = { name: 'portal-application-list', force: true }
} else {
// Note: Consider if `accessToken` is still needed/safe to pass here.
// If navigating to 'chat-home' without login, usually you don't pass old tokens.
// Verify business logic: Does 'chat-home' require an accessToken param?
targetRoute = {
name: 'chat-home',
params: { accessToken },
force: true
}
}
return router.replace(targetRoute)
}).catch((error) => {
// DO NOT swallow errors completely in production.
console.error('Logout failed:', error)
// Optional: Navigate anyway even if logout API failed? Depends on security requirements.
// If strict, do nothing. If lenient, you might still want to clear local state and redirect.
if (!router.currentRoute.value.meta.requiresAuth) {
// Fallback redirect if appropriate
}
})
}Key Recommendations:
- Remove Silenced Catch: Log errors or notify users.
- Verify Param Necessity: Check if
chat-homereally needsaccessTokenparam after logout. Usually, post-logout routes are public or require new auth initiation, not old tokens. - Readability: Split the ternary logic into
if/elsebefore callingrouter.replacefor cleaner code.
fix: [Portal] If you sign out of the portal while logged in and using an application that requires authentication, the system will trigger three "Access Denied" error messages.