Files
Ecobuddy/public/js/simpleAuth.js
2025-03-15 01:59:16 +00:00

152 lines
4.2 KiB
JavaScript

/**
* Simplified Authentication Helper
*
* This provides a streamlined authentication solution that works with
* the simplified server-side authentication approach.
*/
class SimpleAuth {
/**
* Initialize the authentication helper
*/
constructor() {
this.token = localStorage.getItem('token');
this.user = JSON.parse(localStorage.getItem('user') || 'null');
}
/**
* Parse a JWT token to extract its payload
* @param {string} token - The JWT token to parse
* @returns {object|null} The decoded payload or null if invalid
*/
parseJwt(token) {
try {
const base64Url = token.split('.')[1];
const base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/');
const jsonPayload = decodeURIComponent(atob(base64).split('').map(function(c) {
return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);
}).join(''));
return JSON.parse(jsonPayload);
} catch (e) {
console.error('Error parsing JWT token:', e);
return null;
}
}
/**
* Login a user
* @param {object} credentials - The user credentials (username, password)
* @returns {Promise<object>} The login result
*/
async login(credentials) {
try {
const response = await fetch('/api/login', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(credentials)
});
const data = await response.json();
if (!response.ok) {
throw new Error(data.error || 'Login failed');
}
// Store token and user data
this.token = data.token;
localStorage.setItem('token', data.token);
// Parse user data from token
const payload = this.parseJwt(data.token);
this.user = {
id: payload.uid,
username: payload.username,
accessLevel: payload.accessLevel
};
localStorage.setItem('user', JSON.stringify(this.user));
return {
success: true,
user: this.user
};
} catch (error) {
console.error('Login error:', error);
return {
success: false,
error: error.message
};
}
}
/**
* Logout the current user
*/
logout() {
this.token = null;
this.user = null;
localStorage.removeItem('token');
localStorage.removeItem('user');
// Redirect to home page
window.location.href = '/';
}
/**
* Check if the user is authenticated
* @returns {boolean} True if authenticated, false otherwise
*/
isAuthenticated() {
return !!this.token && !!this.user;
}
/**
* Check if the user is an admin
* @returns {boolean} True if admin, false otherwise
*/
isAdmin() {
return this.isAuthenticated() && this.user.accessLevel === 1;
}
/**
* Get the current user
* @returns {object|null} The current user or null if not authenticated
*/
getUser() {
return this.user;
}
/**
* Get the authentication token
* @returns {string|null} The token or null if not authenticated
*/
getToken() {
return this.token;
}
/**
* Make an authenticated API request
* @param {string} url - The URL to fetch
* @param {object} options - Fetch options
* @returns {Promise<Response>} The fetch response
*/
async fetchAuth(url, options = {}) {
if (!this.token) {
throw new Error('Not authenticated');
}
const headers = {
...options.headers,
'Authorization': `Bearer ${this.token}`
};
return fetch(url, {
...options,
headers
});
}
}
// Create a global instance
const auth = new SimpleAuth();