File auth-v2.js of Package PersistenceOS
/**
* PersistenceOS Authentication Module v2
* Modular authentication system for PersistenceOS
* Extracted and improved for Phase 2 modular architecture
*/
// Authentication Configuration
const AUTH_CONFIG = {
API_BASE_URL: '/api',
LOGIN_ENDPOINT: '/api/auth/token',
LOGOUT_ENDPOINT: '/api/auth/logout',
VERIFY_ENDPOINT: '/api/auth/verify',
REDIRECT_URL: '/app-phase1.html', // Updated for Phase 1
LOGIN_URL: '/login.html',
TOKEN_KEY: 'access_token',
USER_KEY: 'user_data',
AUTH_KEY: 'authenticated',
USERNAME_KEY: 'username',
FALLBACK_KEY: 'fallback_auth',
DEBUG: true
};
/**
* PersistenceOS Authentication Manager v2
* Enhanced authentication with better error handling and logging
*/
class PersistenceAuthV2 {
constructor() {
this.token = localStorage.getItem(AUTH_CONFIG.TOKEN_KEY);
this.user = JSON.parse(localStorage.getItem(AUTH_CONFIG.USER_KEY) || 'null');
this.isAuthenticated = localStorage.getItem(AUTH_CONFIG.AUTH_KEY) === 'true';
this.init();
}
init() {
if (AUTH_CONFIG.DEBUG) {
console.log('🔐 PersistenceOS Auth Module v2 initialized');
console.log('📊 Auth state:', {
hasToken: !!this.token,
hasUser: !!this.user,
isAuthenticated: this.isAuthenticated,
username: this.getCurrentUser().username
});
}
}
/**
* Handle login form submission
* Enhanced with better error handling and user feedback
*/
async handleLogin(username, password) {
if (!username || !password) {
throw new Error('Please enter both username and password');
}
if (AUTH_CONFIG.DEBUG) {
console.log('🔑 Attempting login for user:', username);
}
try {
// Try API authentication first
const response = await fetch(AUTH_CONFIG.LOGIN_ENDPOINT, {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: new URLSearchParams({ username, password })
});
if (response.ok) {
const data = await response.json();
this.setAuthData(data.access_token, data.user);
if (AUTH_CONFIG.DEBUG) {
console.log('✅ API authentication successful');
}
return { success: true, method: 'api', data };
}
} catch (error) {
if (AUTH_CONFIG.DEBUG) {
console.warn('⚠️ API authentication failed, trying fallback:', error.message);
}
}
// Fallback authentication for development/testing
if (username === 'root' && password === 'linux') {
localStorage.setItem(AUTH_CONFIG.AUTH_KEY, 'true');
localStorage.setItem(AUTH_CONFIG.USERNAME_KEY, username);
localStorage.setItem(AUTH_CONFIG.FALLBACK_KEY, 'true');
this.isAuthenticated = true;
this.user = { username: username, role: 'admin' };
if (AUTH_CONFIG.DEBUG) {
console.log('✅ Fallback authentication successful');
}
return { success: true, method: 'fallback', user: { username, role: 'admin' } };
} else {
throw new Error('Invalid username or password');
}
}
/**
* Set authentication data in localStorage
*/
setAuthData(token, user) {
this.token = token;
this.user = user;
this.isAuthenticated = true;
localStorage.setItem(AUTH_CONFIG.TOKEN_KEY, token);
localStorage.setItem(AUTH_CONFIG.USER_KEY, JSON.stringify(user));
localStorage.setItem(AUTH_CONFIG.AUTH_KEY, 'true');
if (AUTH_CONFIG.DEBUG) {
console.log('💾 Authentication data stored');
}
}
/**
* Clear all authentication data
*/
clearAuthData() {
this.token = null;
this.user = null;
this.isAuthenticated = false;
// Clear all auth-related localStorage items
localStorage.removeItem(AUTH_CONFIG.TOKEN_KEY);
localStorage.removeItem(AUTH_CONFIG.USER_KEY);
localStorage.removeItem(AUTH_CONFIG.AUTH_KEY);
localStorage.removeItem(AUTH_CONFIG.USERNAME_KEY);
localStorage.removeItem(AUTH_CONFIG.FALLBACK_KEY);
if (AUTH_CONFIG.DEBUG) {
console.log('🗑️ Authentication data cleared');
}
}
/**
* Logout function
*/
async logout() {
try {
// Try API logout if we have a token
if (this.token) {
await fetch(AUTH_CONFIG.LOGOUT_ENDPOINT, {
method: 'POST',
headers: { 'Authorization': `Bearer ${this.token}` }
});
}
} catch (error) {
if (AUTH_CONFIG.DEBUG) {
console.warn('⚠️ Logout request failed:', error.message);
}
}
this.clearAuthData();
if (AUTH_CONFIG.DEBUG) {
console.log('🚪 User logged out');
}
}
/**
* Check if user is authenticated
*/
checkAuth() {
const isAuthenticated = localStorage.getItem(AUTH_CONFIG.AUTH_KEY) === 'true';
this.isAuthenticated = isAuthenticated;
return isAuthenticated;
}
/**
* Require authentication - redirect to login if not authenticated
*/
requireAuth() {
if (!this.checkAuth()) {
if (AUTH_CONFIG.DEBUG) {
console.log('🔒 Authentication required, redirecting to login');
}
window.location.href = AUTH_CONFIG.LOGIN_URL;
return false;
}
return true;
}
/**
* Get authorization headers for API requests
*/
getAuthHeaders() {
const headers = {
'Content-Type': 'application/json'
};
if (this.token) {
headers['Authorization'] = `Bearer ${this.token}`;
}
return headers;
}
/**
* Get current user data
*/
getCurrentUser() {
return this.user || {
username: localStorage.getItem(AUTH_CONFIG.USERNAME_KEY) || 'guest',
role: 'user'
};
}
/**
* Check if using fallback authentication
*/
isFallbackAuth() {
return localStorage.getItem(AUTH_CONFIG.FALLBACK_KEY) === 'true';
}
/**
* Auto-redirect based on authentication state
* Used for login page to redirect authenticated users
*/
autoRedirect() {
if (this.checkAuth()) {
if (AUTH_CONFIG.DEBUG) {
console.log('🔄 User already authenticated, redirecting to dashboard');
}
window.location.href = AUTH_CONFIG.REDIRECT_URL;
return true;
}
return false;
}
}
// Create global authentication instance
window.PersistenceAuthV2 = new PersistenceAuthV2();
// Backward compatibility - also expose as PersistenceAuth
window.PersistenceAuth = window.PersistenceAuthV2;
// Export for module systems
if (typeof module !== 'undefined' && module.exports) {
module.exports = { PersistenceAuthV2, AUTH_CONFIG };
}
console.log('✅ PersistenceOS Authentication Module v2 loaded successfully');