Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: Role Redirect #817

Open
ktun95 opened this issue Aug 21, 2024 · 1 comment
Open

fix: Role Redirect #817

ktun95 opened this issue Aug 21, 2024 · 1 comment

Comments

@ktun95
Copy link
Collaborator

ktun95 commented Aug 21, 2024

Table of Contents

Issue Summary

When an authorized user clicks on a single news item link from the frontpage, they are being redirected to /show instead of /editable.

The useAuthorization hook that checks for the user roles via fetchUserInfo in a useEffect, which runs after the RoleRedirect component has been rendered. By this time, the user is already directed to the /show route.

We need to define a way to capture the state where:

  1. Logto is not loading
  2. User is authenticated
  3. User's authorization is not yet determined

Details

When redirecting a user, there are 3 cases we are concerned with:

  1. LOADING
  2. UNAUTHORIZED
  3. AUTHORIZED

Currently we are deriving these cases from useLogtos isLoading, and an isAuthorized state variable that we define and set after the user's roles are fetched (fetchUserInfo) and checked against the allowed roles.

We assume a user is

  1. LOADING when Logto isLoading: true
  2. UNAUTHORIZED when Logto isLoading: false AND isAuthorized: false
  3. AUTHORIZED when Logto isLoading: false AND isAuthorized: true

However, there is a condition when isLoading: false and isAuthorized: false only because fetchUserInfo has not been called yet.
The user is assumed to be UNAUTHORIZED when their actual authorization has yet to be determined.

Solution

  1. Rename isAuthorized to hasRoleMatch
  2. Introduce a new state variable hasCheckedRoles which can be used to help check if a user's authorization has definitively been determined.
  3. Set hasCheckedRoles to true after fetchUserInfo has been called and the role check has been performed.
  4. Resolve the various states variables into 3 outcomes, LOADING/UNAUTHORIZED/AUTHORIZED, according to the chart below.
  5. Return the outcomes from the hook.
  6. Use these outcome values to determine what to render / where to redirect the user in the RoleRedirect component.
flowchart TD

A{Logto isLoading}
B{isAuthenticated}
C{hasCheckedRoles}
D{hasRoleMatch}

L1[LOADING]
L2[LOADING]
UA1[UNAUTHORIZED]
UA2[UNAUTHORIZED]

A -->|Y|L1
A -->|N|B

B -->|N|UA1
B -->|Y|C

C -->|N|L2
C -->|Y|D

D -->|Y|AUTHORIZED
D -->|N|UA2

classDef new stroke:#0f0,fill:#d0f5d0,color:#000

class C,L2 new
linkStyle 4 stroke:#0f0
Loading
ktun95 added a commit that referenced this issue Aug 21, 2024
Using a self-defined loading state instead of Logto's loading state to
indicate whether the user's role check has been completed. Previously
relying on Logto's loading state to determine whether the user's role
has been checked was incorrect.

Fixes #817
@ktun95 ktun95 closed this as completed in dc600db Aug 21, 2024
@ktun95 ktun95 reopened this Aug 22, 2024
@ktun95
Copy link
Collaborator Author

ktun95 commented Aug 26, 2024

Local Storage / Session Storage for user information and manage auth state locally

maybe make a test page for deferred role redirection, make it locked for production

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant