/** * @fileoverview Authentication Service for Rantii * @author retoor * @description Handles user authentication and session management * @keywords auth, authentication, login, session, token */ class AuthService { constructor(apiClient, storageService) { this.api = apiClient; this.storage = storageService; this.currentUser = null; this.onAuthChange = null; } async init() { const authData = this.storage.getAuth(); if (authData && authData.tokenId && authData.tokenKey) { this.api.setAuth(authData.tokenId, authData.tokenKey, authData.userId); this.currentUser = { id: authData.userId, username: authData.username }; this.notifyAuthChange(); return true; } return false; } async login(username, password, remember = true) { const result = await this.api.login(username, password); if (result.success) { let actualUsername = username; try { const profileResult = await this.api.getProfile(result.authToken.user_id); if (profileResult?.success && profileResult.profile?.username) { actualUsername = profileResult.profile.username; } } catch (e) {} const authData = { tokenId: result.authToken.id, tokenKey: result.authToken.key, userId: result.authToken.user_id, username: actualUsername, expireTime: result.authToken.expire_time }; if (remember) { this.storage.setAuth(authData); } this.currentUser = { id: authData.userId, username: actualUsername }; this.notifyAuthChange(); return { success: true, user: this.currentUser }; } return { success: false, error: result.error }; } logout() { this.api.clearAuth(); this.storage.clearAuth(); this.currentUser = null; this.notifyAuthChange(); } isLoggedIn() { return this.api.isAuthenticated() && this.currentUser !== null; } getUser() { return this.currentUser; } getUserId() { return this.currentUser?.id || null; } getUsername() { return this.currentUser?.username || null; } setAuthChangeCallback(callback) { this.onAuthChange = callback; } notifyAuthChange() { if (this.onAuthChange) { this.onAuthChange(this.isLoggedIn(), this.currentUser); } window.dispatchEvent(new CustomEvent('rantii:auth-change', { detail: { isLoggedIn: this.isLoggedIn(), user: this.currentUser } })); } requireAuth() { if (!this.isLoggedIn()) { window.dispatchEvent(new CustomEvent('rantii:require-auth')); return false; } return true; } } export { AuthService };