add landing and subscription plans
Signed-off-by: Omar Sánchez Pizarro <omar.sanchez@pistacero.net>
This commit is contained in:
230
web/dashboard/src/services/auth.js
Normal file
230
web/dashboard/src/services/auth.js
Normal file
@@ -0,0 +1,230 @@
|
||||
// Servicio de autenticación para gestionar tokens
|
||||
import { getDeviceFingerprint } from './fingerprint.js';
|
||||
|
||||
const AUTH_STORAGE_KEY = 'wallabicher_token';
|
||||
const USERNAME_STORAGE_KEY = 'wallabicher_username';
|
||||
const ROLE_STORAGE_KEY = 'wallabicher_role';
|
||||
|
||||
class AuthService {
|
||||
constructor() {
|
||||
this.token = this.loadToken();
|
||||
this.username = this.loadUsername();
|
||||
this.role = this.loadRole();
|
||||
}
|
||||
|
||||
// Cargar token desde localStorage
|
||||
loadToken() {
|
||||
try {
|
||||
return localStorage.getItem(AUTH_STORAGE_KEY) || '';
|
||||
} catch (error) {
|
||||
console.error('Error cargando token:', error);
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
// Cargar username desde localStorage
|
||||
loadUsername() {
|
||||
try {
|
||||
return localStorage.getItem(USERNAME_STORAGE_KEY) || '';
|
||||
} catch (error) {
|
||||
console.error('Error cargando username:', error);
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
// Guardar token, username y role en localStorage
|
||||
saveSession(token, username, role = 'user') {
|
||||
try {
|
||||
this.token = token;
|
||||
this.username = username;
|
||||
this.role = role;
|
||||
localStorage.setItem(AUTH_STORAGE_KEY, token);
|
||||
localStorage.setItem(USERNAME_STORAGE_KEY, username);
|
||||
localStorage.setItem(ROLE_STORAGE_KEY, role);
|
||||
return true;
|
||||
} catch (error) {
|
||||
console.error('Error guardando sesión:', error);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Cargar role desde localStorage
|
||||
loadRole() {
|
||||
try {
|
||||
return localStorage.getItem(ROLE_STORAGE_KEY) || 'user';
|
||||
} catch (error) {
|
||||
console.error('Error cargando role:', error);
|
||||
return 'user';
|
||||
}
|
||||
}
|
||||
|
||||
// Eliminar token, username y role
|
||||
clearSession() {
|
||||
try {
|
||||
this.token = '';
|
||||
this.username = '';
|
||||
this.role = 'user';
|
||||
localStorage.removeItem(AUTH_STORAGE_KEY);
|
||||
localStorage.removeItem(USERNAME_STORAGE_KEY);
|
||||
localStorage.removeItem(ROLE_STORAGE_KEY);
|
||||
return true;
|
||||
} catch (error) {
|
||||
console.error('Error eliminando sesión:', error);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Obtener token actual
|
||||
getToken() {
|
||||
return this.token;
|
||||
}
|
||||
|
||||
// Obtener username actual
|
||||
getUsername() {
|
||||
return this.username;
|
||||
}
|
||||
|
||||
// Obtener role actual
|
||||
getRole() {
|
||||
return this.role;
|
||||
}
|
||||
|
||||
// Verificar si es admin
|
||||
isAdmin() {
|
||||
return this.role === 'admin';
|
||||
}
|
||||
|
||||
// Verificar si hay sesión activa (token guardado)
|
||||
hasCredentials() {
|
||||
return !!this.token;
|
||||
}
|
||||
|
||||
// Generar header de autenticación Bearer
|
||||
getAuthHeader() {
|
||||
if (!this.token) {
|
||||
return null;
|
||||
}
|
||||
return `Bearer ${this.token}`;
|
||||
}
|
||||
|
||||
// Hacer login (llamar al endpoint de login)
|
||||
async login(username, password) {
|
||||
try {
|
||||
// Obtener fingerprint del dispositivo
|
||||
let fingerprintData = null;
|
||||
try {
|
||||
fingerprintData = await getDeviceFingerprint();
|
||||
} catch (error) {
|
||||
console.warn('Error obteniendo fingerprint, continuando sin él:', error);
|
||||
}
|
||||
|
||||
const requestBody = {
|
||||
username,
|
||||
password,
|
||||
};
|
||||
|
||||
// Agregar fingerprint si está disponible
|
||||
if (fingerprintData) {
|
||||
requestBody.fingerprint = fingerprintData.fingerprint;
|
||||
requestBody.deviceInfo = fingerprintData.deviceInfo;
|
||||
}
|
||||
|
||||
const response = await fetch('/api/users/login', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify(requestBody),
|
||||
});
|
||||
|
||||
const data = await response.json();
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(data.error || 'Error en login');
|
||||
}
|
||||
|
||||
if (data.success && data.token) {
|
||||
const role = data.role || 'user';
|
||||
this.saveSession(data.token, data.username, role);
|
||||
return { success: true, token: data.token, username: data.username, role };
|
||||
}
|
||||
|
||||
throw new Error('Respuesta inválida del servidor');
|
||||
} catch (error) {
|
||||
console.error('Error en login:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
// Hacer logout (llamar al endpoint de logout)
|
||||
async logout() {
|
||||
try {
|
||||
const token = this.token;
|
||||
|
||||
if (token) {
|
||||
try {
|
||||
await fetch('/api/users/logout', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Authorization': `Bearer ${token}`,
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
});
|
||||
} catch (error) {
|
||||
// Si falla el logout en el servidor, aún así limpiar localmente
|
||||
console.error('Error al cerrar sesión en el servidor:', error);
|
||||
}
|
||||
}
|
||||
|
||||
this.clearSession();
|
||||
return true;
|
||||
} catch (error) {
|
||||
console.error('Error en logout:', error);
|
||||
this.clearSession(); // Limpiar localmente de todas formas
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Verificar si el token sigue siendo válido
|
||||
async validateSession() {
|
||||
if (!this.token) {
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await fetch('/api/users/me', {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'Authorization': `Bearer ${this.token}`,
|
||||
},
|
||||
});
|
||||
|
||||
if (response.ok) {
|
||||
const data = await response.json();
|
||||
if (data.success && data.authenticated) {
|
||||
// Actualizar role si está disponible
|
||||
if (data.role) {
|
||||
this.role = data.role;
|
||||
localStorage.setItem(ROLE_STORAGE_KEY, data.role);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Si el token es inválido, limpiar sesión
|
||||
if (response.status === 401) {
|
||||
this.clearSession();
|
||||
}
|
||||
|
||||
return false;
|
||||
} catch (error) {
|
||||
console.error('Error validando sesión:', error);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Exportar instancia singleton
|
||||
const authService = new AuthService();
|
||||
export default authService;
|
||||
|
||||
Reference in New Issue
Block a user