|
|
|
@ -1,7 +1,7 @@
|
|
|
|
import { useQueryClient } from "@tanstack/react-query";
|
|
|
|
import { useQueryClient } from "@tanstack/react-query";
|
|
|
|
import { createContext, type ReactNode, useCallback, useContext, useMemo, useState } from "react";
|
|
|
|
import { createContext, type ReactNode, useCallback, useContext, useMemo, useState } from "react";
|
|
|
|
import { clearAccessToken, hasStoredToken } from "@/auth-state";
|
|
|
|
import { clearAccessToken, getAccessToken } from "@/auth-state";
|
|
|
|
import { authServiceClient, shortcutServiceClient, userServiceClient } from "@/connect";
|
|
|
|
import { authServiceClient, refreshAccessToken, shortcutServiceClient, userServiceClient } from "@/connect";
|
|
|
|
import { userKeys } from "@/hooks/useUserQueries";
|
|
|
|
import { userKeys } from "@/hooks/useUserQueries";
|
|
|
|
import type { Shortcut } from "@/types/proto/api/v1/shortcut_service_pb";
|
|
|
|
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";
|
|
|
|
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 () => {
|
|
|
|
const initialize = useCallback(async () => {
|
|
|
|
setState((prev) => ({ ...prev, isLoading: true }));
|
|
|
|
setState((prev) => ({ ...prev, isLoading: true }));
|
|
|
|
|
|
|
|
|
|
|
|
// If there is no stored token at all, the user is not authenticated.
|
|
|
|
// Try to get or refresh the access token.
|
|
|
|
// Skip the network call — there is nothing to refresh and no session to restore.
|
|
|
|
// This handles PWA isolated storage scenarios (e.g., iOS Safari) where localStorage
|
|
|
|
if (!hasStoredToken()) {
|
|
|
|
// 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({
|
|
|
|
setState({
|
|
|
|
currentUser: undefined,
|
|
|
|
currentUser: undefined,
|
|
|
|
userGeneralSetting: undefined,
|
|
|
|
userGeneralSetting: undefined,
|
|
|
|
|