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();