Tech Stack Advisor - Code Viewer

← Back to File Tree

auth.js

Language: javascript | Path: backend/static/auth.js | Lines: 163
/**
 * Authentication utility functions
 * Shared across login, register, and main pages
 */

const TOKEN_KEY = 'tech_stack_advisor_token';
const USER_KEY = 'tech_stack_advisor_user';

/**
 * Save authentication token to localStorage
 */
function saveToken(token) {
    localStorage.setItem(TOKEN_KEY, token);
}

/**
 * Get authentication token from localStorage
 */
function getToken() {
    return localStorage.getItem(TOKEN_KEY);
}

/**
 * Remove authentication token from localStorage
 */
function removeToken() {
    localStorage.removeItem(TOKEN_KEY);
    localStorage.removeItem(USER_KEY);
}

/**
 * Check if user is authenticated
 */
function isAuthenticated() {
    return getToken() !== null;
}

/**
 * Save user data to localStorage
 */
function saveUser(user) {
    localStorage.setItem(USER_KEY, JSON.stringify(user));
}

/**
 * Get user data from localStorage
 */
function getUser() {
    const userStr = localStorage.getItem(USER_KEY);
    return userStr ? JSON.parse(userStr) : null;
}

/**
 * Logout user
 */
async function logout() {
    try {
        const token = getToken();
        if (token) {
            // Call logout endpoint
            await fetch('/auth/logout', {
                method: 'POST',
                headers: {
                    'Authorization': `Bearer ${token}`,
                    'Content-Type': 'application/json',
                },
            });
        }
    } catch (error) {
        console.error('Logout error:', error);
    } finally {
        // Always clear local storage
        removeToken();
        window.location.href = '/login.html';
    }
}

/**
 * Fetch user info from API
 */
async function fetchUserInfo() {
    const token = getToken();
    if (!token) {
        return null;
    }

    try {
        const response = await fetch('/auth/me', {
            headers: {
                'Authorization': `Bearer ${token}`,
            },
        });

        if (response.ok) {
            const user = await response.json();
            saveUser(user);
            return user;
        } else {
            // Token might be invalid, logout
            removeToken();
            return null;
        }
    } catch (error) {
        console.error('Error fetching user info:', error);
        return null;
    }
}

/**
 * Make authenticated API request
 */
async function authenticatedFetch(url, options = {}) {
    const token = getToken();
    if (!token) {
        throw new Error('Not authenticated');
    }

    const headers = {
        ...options.headers,
        'Authorization': `Bearer ${token}`,
    };

    const response = await fetch(url, {
        ...options,
        headers,
    });

    // If 401, token is invalid
    if (response.status === 401) {
        removeToken();
        window.location.href = '/login.html';
        throw new Error('Authentication failed');
    }

    return response;
}

/**
 * Require authentication - redirect to login if not authenticated
 */
function requireAuth() {
    if (!isAuthenticated()) {
        window.location.href = '/login.html';
        return false;
    }
    return true;
}

// Export functions for use in other scripts
if (typeof module !== 'undefined' && module.exports) {
    module.exports = {
        saveToken,
        getToken,
        removeToken,
        isAuthenticated,
        saveUser,
        getUser,
        logout,
        fetchUserInfo,
        authenticatedFetch,
        requireAuth,
    };
}