feat(auth): implement refresh token handling and update login method

This commit is contained in:
hamed
2026-06-25 17:37:55 +03:30
parent 694ee28787
commit 9b608aaeac
3 changed files with 62 additions and 7 deletions
+40 -5
View File
@@ -13,6 +13,7 @@ export interface ContextItem {
interface AuthState {
token: string | null;
refreshToken: string | null;
isAuthenticated: boolean;
userUuid: string | null;
userName: string | null;
@@ -23,8 +24,9 @@ interface AuthState {
context: ContextItem | null;
availableContexts: ContextItem[];
login: (token: string) => void;
login: (token: string, refreshToken?: string | null) => void;
logout: () => void;
refresh: () => Promise<string | null>;
fetchMe: () => Promise<void>;
switchContext: (dbUuid: string) => Promise<void>;
}
@@ -56,6 +58,7 @@ export const useAuthStore = create<AuthState>()(
persist(
(set, get) => ({
token: null,
refreshToken: null,
isAuthenticated: false,
userUuid: null,
userName: null,
@@ -66,14 +69,22 @@ export const useAuthStore = create<AuthState>()(
context: null,
availableContexts: [],
login: (token) => {
set({ token, isAuthenticated: true });
login: (token, refreshToken = null) => {
set({ token, refreshToken, isAuthenticated: true });
get().fetchMe();
},
logout: () =>
logout: () => {
const rt = get().refreshToken;
if (rt) {
apiFetch('/oauth/logout', {
method: 'POST',
body: JSON.stringify({ refresh_token: rt }),
}).catch(() => {});
}
set({
token: null,
refreshToken: null,
isAuthenticated: false,
userUuid: null,
userName: null,
@@ -83,7 +94,30 @@ export const useAuthStore = create<AuthState>()(
doctorUuid: null,
context: null,
availableContexts: [],
}),
});
},
refresh: async () => {
const rt = get().refreshToken;
if (!rt) return null;
try {
const res = await fetch('/oauth/token/refresh', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ refresh_token: rt }),
});
const json = await res.json();
if (!res.ok || !json?.access_token) return null;
set({
token: json.access_token,
refreshToken: json.refresh_token ?? rt,
isAuthenticated: true,
});
return json.access_token as string;
} catch {
return null;
}
},
fetchMe: async () => {
try {
@@ -125,6 +159,7 @@ export const useAuthStore = create<AuthState>()(
name: 'clinicpro-auth',
partialize: (s) => ({
token: s.token,
refreshToken: s.refreshToken,
isAuthenticated: s.isAuthenticated,
userUuid: s.userUuid,
userName: s.userName,