Skip to content

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

Closed
shaohuzhang1 wants to merge 1 commit into
v3from
pr@v3@fix_chat_login

Conversation

@shaohuzhang1

Copy link
Copy Markdown
Contributor

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.

… an application that requires authentication, the system will trigger three "Access Denied" error messages.
)
.catch(() => {})
}

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.accessToken might no longer be valid or relevant for the new anonymous session if chat-home expects an active access token. Passing a stale/invalid accessToken as 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: true is 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:

  1. Remove Silenced Catch: Log errors or notify users.
  2. Verify Param Necessity: Check if chat-home really needs accessToken param after logout. Usually, post-logout routes are public or require new auth initiation, not old tokens.
  3. Readability: Split the ternary logic into if/else before calling router.replace for cleaner code.

@shaohuzhang1
shaohuzhang1 deleted the pr@v3@fix_chat_login branch November 10, 2026 08:21
@shaohuzhang1
shaohuzhang1 restored the pr@v3@fix_chat_login branch November 10, 2026 08:22
@shaohuzhang1
shaohuzhang1 deleted the pr@v3@fix_chat_login branch November 10, 2026 08:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant