mirror of
https://github.com/pacnpal/thrilltrack-explorer.git
synced 2025-12-22 16:11:13 -05:00
Refactor code structure and remove redundant changes
This commit is contained in:
141
lib/services/auth/tokenStorage.ts
Normal file
141
lib/services/auth/tokenStorage.ts
Normal file
@@ -0,0 +1,141 @@
|
||||
/**
|
||||
* Token Storage Utility
|
||||
*
|
||||
* Handles JWT token storage, retrieval, and validation in localStorage.
|
||||
*/
|
||||
|
||||
import { TokenPayload, TokenStorage } from '@/lib/types/auth';
|
||||
|
||||
// Storage keys
|
||||
const ACCESS_TOKEN_KEY = 'auth_access_token';
|
||||
const REFRESH_TOKEN_KEY = 'auth_refresh_token';
|
||||
|
||||
/**
|
||||
* Decode JWT token payload without verification
|
||||
* (Verification happens on the server)
|
||||
*/
|
||||
function decodeToken(token: string): TokenPayload | null {
|
||||
try {
|
||||
const parts = token.split('.');
|
||||
if (parts.length !== 3) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const payload = parts[1];
|
||||
const decoded = JSON.parse(atob(payload));
|
||||
|
||||
return decoded as TokenPayload;
|
||||
} catch (error) {
|
||||
console.error('Failed to decode token:', error);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a token is expired
|
||||
*/
|
||||
function isTokenExpired(token: string): boolean {
|
||||
const decoded = decodeToken(token);
|
||||
if (!decoded || !decoded.exp) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Check if token expires in the next 60 seconds (add buffer)
|
||||
const expiryTime = decoded.exp * 1000; // Convert to milliseconds
|
||||
const now = Date.now();
|
||||
const bufferTime = 60 * 1000; // 60 seconds buffer
|
||||
|
||||
return now >= (expiryTime - bufferTime);
|
||||
}
|
||||
|
||||
/**
|
||||
* Token storage implementation
|
||||
*/
|
||||
export const tokenStorage: TokenStorage = {
|
||||
getAccessToken(): string | null {
|
||||
if (typeof window === 'undefined') {
|
||||
return null;
|
||||
}
|
||||
return localStorage.getItem(ACCESS_TOKEN_KEY);
|
||||
},
|
||||
|
||||
setAccessToken(token: string): void {
|
||||
if (typeof window === 'undefined') {
|
||||
return;
|
||||
}
|
||||
localStorage.setItem(ACCESS_TOKEN_KEY, token);
|
||||
},
|
||||
|
||||
getRefreshToken(): string | null {
|
||||
if (typeof window === 'undefined') {
|
||||
return null;
|
||||
}
|
||||
return localStorage.getItem(REFRESH_TOKEN_KEY);
|
||||
},
|
||||
|
||||
setRefreshToken(token: string): void {
|
||||
if (typeof window === 'undefined') {
|
||||
return;
|
||||
}
|
||||
localStorage.setItem(REFRESH_TOKEN_KEY, token);
|
||||
},
|
||||
|
||||
clearTokens(): void {
|
||||
if (typeof window === 'undefined') {
|
||||
return;
|
||||
}
|
||||
localStorage.removeItem(ACCESS_TOKEN_KEY);
|
||||
localStorage.removeItem(REFRESH_TOKEN_KEY);
|
||||
},
|
||||
|
||||
hasValidAccessToken(): boolean {
|
||||
const token = this.getAccessToken();
|
||||
if (!token) {
|
||||
return false;
|
||||
}
|
||||
return !isTokenExpired(token);
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the decoded payload from the access token
|
||||
*/
|
||||
export function getTokenPayload(): TokenPayload | null {
|
||||
const token = tokenStorage.getAccessToken();
|
||||
if (!token) {
|
||||
return null;
|
||||
}
|
||||
return decodeToken(token);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the refresh token is expired
|
||||
*/
|
||||
export function isRefreshTokenExpired(): boolean {
|
||||
const token = tokenStorage.getRefreshToken();
|
||||
if (!token) {
|
||||
return true;
|
||||
}
|
||||
return isTokenExpired(token);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get time until access token expires (in milliseconds)
|
||||
*/
|
||||
export function getTimeUntilExpiry(): number | null {
|
||||
const token = tokenStorage.getAccessToken();
|
||||
if (!token) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const decoded = decodeToken(token);
|
||||
if (!decoded || !decoded.exp) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const expiryTime = decoded.exp * 1000;
|
||||
const now = Date.now();
|
||||
const timeRemaining = expiryTime - now;
|
||||
|
||||
return timeRemaining > 0 ? timeRemaining : 0;
|
||||
}
|
||||
Reference in New Issue
Block a user