Lin / frontend /src /services /securityService.js
Zelyanoth's picture
fff
25f22bf
raw
history blame
3.95 kB
import apiClient from './apiClient';
import cacheService from './cacheService';
import cookieService from './cookieService';
/**
* SecurityService - Handles security-related operations
*/
class SecurityService {
/**
* Generate a device fingerprint
* @returns {string} - Device fingerprint
*/
generateDeviceFingerprint() {
const userAgent = navigator.userAgent;
const screenResolution = `${screen.width}x${screen.height}`;
const timezone = Intl.DateTimeFormat().resolvedOptions().timeZone;
const language = navigator.language;
// Create a simple hash-like string
const fingerprint = `${userAgent}-${screenResolution}-${timezone}-${language}`;
return btoa(fingerprint).replace(/[^a-zA-Z0-9]/g, '').substring(0, 32);
}
/**
* Validate device fingerprint
* @param {string} storedFingerprint - Stored fingerprint
* @returns {boolean} - True if fingerprint is valid
*/
validateDeviceFingerprint(storedFingerprint) {
const currentFingerprint = this.generateDeviceFingerprint();
return storedFingerprint === currentFingerprint;
}
/**
* Securely store authentication data
* @param {Object} authData - Authentication data
* @param {string} authData.token - JWT token
* @param {Object} authData.user - User data
* @param {boolean} rememberMe - Remember me flag
* @returns {Promise<void>}
*/
async storeAuthData(authData, rememberMe = false) {
// Store in cache
await cacheService.setAuthCache(authData, rememberMe);
// Store in secure cookies
await cookieService.setAuthTokens(authData.token, rememberMe);
// Store token in localStorage as fallback
localStorage.setItem('token', authData.token);
}
/**
* Clear all authentication data
* @returns {Promise<void>}
*/
async clearAuthData() {
// Clear cache
await cacheService.clearAuthCache();
// Clear cookies
await cookieService.clearAuthTokens();
// Clear localStorage
localStorage.removeItem('token');
localStorage.removeItem('rememberMePreference');
}
/**
* Get stored authentication data
* @returns {Promise<Object|null>} - Authentication data or null
*/
async getAuthData() {
// Try cache first
const cachedAuth = await cacheService.getAuthCache();
if (cachedAuth) {
return cachedAuth;
}
// Try cookies
const cookieAuth = await cookieService.getAuthTokens();
if (cookieAuth) {
return {
token: cookieAuth.accessToken,
user: null, // User data needs to be fetched separately
rememberMe: cookieAuth.rememberMe
};
}
// Try localStorage
const token = localStorage.getItem('token');
if (token) {
return {
token,
user: null,
rememberMe: localStorage.getItem('rememberMePreference') === 'true'
};
}
return null;
}
/**
* Refresh authentication tokens
* @param {string} newToken - New JWT token
* @param {boolean} rememberMe - Remember me flag
* @returns {Promise<void>}
*/
async refreshAuthTokens(newToken, rememberMe = false) {
// Clear existing auth data
await this.clearAuthData();
// Store new auth data
await this.storeAuthData({ token: newToken }, rememberMe);
}
/**
* Make a secure API request
* @param {string} method - HTTP method
* @param {string} url - API endpoint
* @param {Object} data - Request data
* @returns {Promise<Object>} - API response
*/
async secureRequest(method, url, data = null) {
try {
const config = { method, url };
if (data) {
config.data = data;
}
const response = await apiClient(config);
return response.data;
} catch (error) {
console.error(`SecurityService error in ${method} ${url}:`, error);
throw error;
}
}
}
// Export singleton instance
export default new SecurityService();