From 3af2559dd0de155f0c584cb395f22b47c6c31b86 Mon Sep 17 00:00:00 2001 From: c0mrade Date: Tue, 26 May 2026 15:52:49 +0300 Subject: [PATCH] refactor(auth): extract applySession / clearSession from initialize() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit initialize() had six inline set({ accessToken, refreshToken, user, isAuthenticated, isLoading }) blocks — three success variants and three failure variants. They were byte-identical aside from which access token they passed through, so any future field addition would have required updating six places in lockstep, with no compile-time guarantee. Extract two closure-scoped helpers: applySession(token, refresh, user) — the success shape clearSession() — the failure shape, with the tokenStorage.clearTokens() call bundled in State writes are byte-for-byte identical to before; this is a maintenance-only refactor. The accessToken param keeps the same 'string | null' typing the inline set() previously accepted, so behavior on edge cases (null tokens reaching success branches via type-flow gaps) is unchanged. --- src/store/auth.ts | 83 ++++++++++++++++++++++------------------------- 1 file changed, 38 insertions(+), 45 deletions(-) diff --git a/src/store/auth.ts b/src/store/auth.ts index 59b1070..cfcf23f 100644 --- a/src/store/auth.ts +++ b/src/store/auth.ts @@ -159,6 +159,38 @@ export const useAuthStore = create()( return initState.promise; } + // Three identical state shapes appeared inline 6 times — extract them + // here (closure-scoped to keep auth state internal). Behaviour is + // byte-for-byte identical to the previous inline blocks; the only + // change is that mistypes can't drift between branches. + // accessToken is typed `string | null` to match the previous inline + // set() shape and AuthState's field; in practice it's only called + // along the post-isTokenValid / post-refresh branches where the + // value is guaranteed non-null at runtime. + const applySession = ( + accessToken: string | null, + refreshTokenValue: string, + user: User, + ): void => { + set({ + accessToken, + refreshToken: refreshTokenValue, + user, + isAuthenticated: true, + isLoading: false, + }); + }; + const clearSession = (): void => { + tokenStorage.clearTokens(); + set({ + accessToken: null, + refreshToken: null, + user: null, + isAuthenticated: false, + isLoading: false, + }); + }; + initState.isInitializing = true; initState.promise = (async () => { try { @@ -184,22 +216,9 @@ export const useAuthStore = create()( if (newToken) { const user = await authApi.getMe(); await get().checkAdminStatus(); - set({ - accessToken: newToken, - refreshToken, - user, - isAuthenticated: true, - isLoading: false, - }); + applySession(newToken, refreshToken, user); } else { - tokenStorage.clearTokens(); - set({ - accessToken: null, - refreshToken: null, - user: null, - isAuthenticated: false, - isLoading: false, - }); + clearSession(); } return; } @@ -207,45 +226,19 @@ export const useAuthStore = create()( try { const user = await authApi.getMe(); await get().checkAdminStatus(); - set({ - accessToken, - refreshToken, - user, - isAuthenticated: true, - isLoading: false, - }); + applySession(accessToken, refreshToken, user); } catch { const newToken = await tokenRefreshManager.refreshAccessToken(); if (newToken) { try { const user = await authApi.getMe(); await get().checkAdminStatus(); - set({ - accessToken: newToken, - refreshToken, - user, - isAuthenticated: true, - isLoading: false, - }); + applySession(newToken, refreshToken, user); } catch { - tokenStorage.clearTokens(); - set({ - accessToken: null, - refreshToken: null, - user: null, - isAuthenticated: false, - isLoading: false, - }); + clearSession(); } } else { - tokenStorage.clearTokens(); - set({ - accessToken: null, - refreshToken: null, - user: null, - isAuthenticated: false, - isLoading: false, - }); + clearSession(); } } } finally {