Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
C
canifa_note
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Vũ Hoàng Anh
canifa_note
Commits
551ee1d8
Unverified
Commit
551ee1d8
authored
Mar 20, 2026
by
fiatcode
Committed by
GitHub
Mar 20, 2026
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
fix(auth): recover session via refresh cookie when localStorage is empty (#5748)
parent
be00abe8
Changes
2
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
21 additions
and
10 deletions
+21
-10
auth-state.ts
web/src/auth-state.ts
+4
-5
AuthContext.tsx
web/src/contexts/AuthContext.tsx
+17
-5
No files found.
web/src/auth-state.ts
View file @
551ee1d8
...
...
@@ -61,11 +61,10 @@ export const getAccessToken = (): string | null => {
accessToken
=
storedToken
;
tokenExpiresAt
=
expiresAt
;
}
// Do NOT remove expired tokens here. Callers such as InstanceContext.initialize()
// run concurrently with AuthContext.initialize() via Promise.all. If we eagerly
// delete the expired token from localStorage, hasStoredToken() (called synchronously
// inside AuthContext.initialize()) finds nothing and skips the refresh attempt,
// logging the user out even when the refresh-token cookie is still valid.
// Do NOT remove expired tokens here. getRequestToken() in connect.ts calls
// hasStoredToken() to decide whether to attempt a refresh — if we eagerly delete
// the expired token, it returns null immediately, skipping the refresh and sending
// the request without credentials.
// clearAccessToken() handles proper cleanup after a confirmed auth failure or logout.
}
}
catch
(
e
)
{
...
...
web/src/contexts/AuthContext.tsx
View file @
551ee1d8
import
{
useQueryClient
}
from
"@tanstack/react-query"
;
import
{
createContext
,
type
ReactNode
,
useCallback
,
useContext
,
useMemo
,
useState
}
from
"react"
;
import
{
clearAccessToken
,
hasStored
Token
}
from
"@/auth-state"
;
import
{
authServiceClient
,
shortcutServiceClient
,
userServiceClient
}
from
"@/connect"
;
import
{
clearAccessToken
,
getAccess
Token
}
from
"@/auth-state"
;
import
{
authServiceClient
,
refreshAccessToken
,
shortcutServiceClient
,
userServiceClient
}
from
"@/connect"
;
import
{
userKeys
}
from
"@/hooks/useUserQueries"
;
import
type
{
Shortcut
}
from
"@/types/proto/api/v1/shortcut_service_pb"
;
import
type
{
User
,
UserSetting_GeneralSetting
,
UserSetting_WebhooksSetting
}
from
"@/types/proto/api/v1/user_service_pb"
;
...
...
@@ -53,9 +53,21 @@ export function AuthProvider({ children }: { children: ReactNode }) {
const
initialize
=
useCallback
(
async
()
=>
{
setState
((
prev
)
=>
({
...
prev
,
isLoading
:
true
}));
// If there is no stored token at all, the user is not authenticated.
// Skip the network call — there is nothing to refresh and no session to restore.
if
(
!
hasStoredToken
())
{
// Try to get or refresh the access token.
// This handles PWA isolated storage scenarios (e.g., iOS Safari) where localStorage
// may be empty but a valid HTTP-only refresh token cookie still exists.
// getAccessToken() returns a cached token or loads from localStorage if valid.
if
(
!
getAccessToken
())
{
try
{
await
refreshAccessToken
();
}
catch
{
// Refresh failed - no valid session
}
}
// If we still don't have a token after refresh attempt, skip getCurrentUser call
// to avoid unnecessary network request for unauthenticated users.
if
(
!
getAccessToken
())
{
setState
({
currentUser
:
undefined
,
userGeneralSetting
:
undefined
,
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment