feat: implement user authentication and login modal, refactor backend
This commit is contained in:
95
web/frontend/src/services/auth.js
Normal file
95
web/frontend/src/services/auth.js
Normal file
@@ -0,0 +1,95 @@
|
||||
// Servicio de autenticación para gestionar credenciales
|
||||
|
||||
const AUTH_STORAGE_KEY = 'wallabicher_auth';
|
||||
|
||||
class AuthService {
|
||||
constructor() {
|
||||
this.credentials = this.loadCredentials();
|
||||
}
|
||||
|
||||
// Cargar credenciales desde localStorage
|
||||
loadCredentials() {
|
||||
try {
|
||||
const stored = localStorage.getItem(AUTH_STORAGE_KEY);
|
||||
if (stored) {
|
||||
const parsed = JSON.parse(stored);
|
||||
return {
|
||||
username: parsed.username || '',
|
||||
password: parsed.password || '',
|
||||
};
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error cargando credenciales:', error);
|
||||
}
|
||||
return { username: '', password: '' };
|
||||
}
|
||||
|
||||
// Guardar credenciales en localStorage
|
||||
saveCredentials(username, password) {
|
||||
try {
|
||||
this.credentials = { username, password };
|
||||
localStorage.setItem(AUTH_STORAGE_KEY, JSON.stringify(this.credentials));
|
||||
return true;
|
||||
} catch (error) {
|
||||
console.error('Error guardando credenciales:', error);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Eliminar credenciales
|
||||
clearCredentials() {
|
||||
try {
|
||||
this.credentials = { username: '', password: '' };
|
||||
localStorage.removeItem(AUTH_STORAGE_KEY);
|
||||
return true;
|
||||
} catch (error) {
|
||||
console.error('Error eliminando credenciales:', error);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Obtener credenciales actuales
|
||||
getCredentials() {
|
||||
return { ...this.credentials };
|
||||
}
|
||||
|
||||
// Verificar si hay credenciales guardadas
|
||||
hasCredentials() {
|
||||
return !!(this.credentials.username && this.credentials.password);
|
||||
}
|
||||
|
||||
// Generar header de autenticación Basic
|
||||
getAuthHeader() {
|
||||
if (!this.hasCredentials()) {
|
||||
return null;
|
||||
}
|
||||
const { username, password } = this.credentials;
|
||||
const encoded = btoa(`${username}:${password}`);
|
||||
return `Basic ${encoded}`;
|
||||
}
|
||||
|
||||
// Validar credenciales (test básico)
|
||||
async validateCredentials(username, password) {
|
||||
try {
|
||||
// Intentar hacer una petición simple para validar las credenciales
|
||||
const encoded = btoa(`${username}:${password}`);
|
||||
const response = await fetch('/api/stats', {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'Authorization': `Basic ${encoded}`,
|
||||
},
|
||||
});
|
||||
|
||||
// Si la petición funciona, las credenciales son válidas
|
||||
// Nota: stats no requiere auth, pero podemos usar cualquier endpoint
|
||||
return response.ok || response.status !== 401;
|
||||
} catch (error) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Exportar instancia singleton
|
||||
const authService = new AuthService();
|
||||
export default authService;
|
||||
|
||||
Reference in New Issue
Block a user