File size: 3,949 Bytes
25f22bf |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 |
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(); |