Skip to main content

Overview

StockPro uses Firebase Authentication to secure access to the application. The authentication system provides email/password-based login, session management, password reset functionality, and automatic route protection.
All authentication logic is implemented using Firebase Authentication SDK v10.12.2 loaded via CDN for optimal performance.

Firebase Configuration

Firebase Initialization

The authentication system starts with Firebase initialization in public/js/firebase.js:
public/js/firebase.js
// Import the functions you need from the SDKs you need
import { initializeApp } from "https://www.gstatic.com/firebasejs/10.12.2/firebase-app.js";
import { getAuth } from "https://www.gstatic.com/firebasejs/10.12.2/firebase-auth.js";
import { getFirestore } from "https://www.gstatic.com/firebasejs/10.12.2/firebase-firestore.js";

// Your web app's Firebase configuration
const firebaseConfig = {
    apiKey: "AIzaSyCK79FXbS3tNPL8V6C03HOMyrr8-rp6YO4",
    authDomain: "autopartes-hessman-68283.firebaseapp.com",
    projectId: "autopartes-hessman-68283",
    storageBucket: "autopartes-hessman-68283.firebasestorage.app",
    messagingSenderId: "854961822123",
    appId: "1:854961822123:web:75d5b5d3d3e567761e9aee",
    measurementId: "G-ENNB0G1JME"
};

// Initialize Firebase
const app = initializeApp(firebaseConfig);
const auth = getAuth(app);
const db = getFirestore(app);

export { auth, db };
The configuration shown above is from the example project. Always replace these values with your own Firebase project credentials before deploying to production.

Key Exports

The firebase.js module exports two critical objects:
  • auth: Firebase Authentication instance for managing user authentication
  • db: Firestore database instance for storing application data
These are imported throughout the application wherever authentication or database access is needed.

Login Flow

Login Page Structure

The login interface is defined in public/login.html:
public/login.html
<form id="inicio_sesion" class="login-form" novalidate>
    <div class="form-group">
        <div class="input-wrapper">
            <input type="email" id="email" name="email" 
                   placeholder="Correo Electrónico" required>
            <span class="error-message" id="emailError"></span>
        </div>
    </div>

    <div class="form-group">
        <div class="input-wrapper password-wrapper">
            <input type="password" id="contrasena" name="contrasena" 
                   placeholder="Contraseña" required>     
            <i class="fa-solid fa-eye-slash toggle-password" 
               id="togglePassword"></i>
            <span class="error-message" id="contrasenaError"></span>
        </div>
    </div>

    <button type="submit" class="login-btn">
        <span class="btn-text">Iniciar Sesión</span>
        <span class="btn-loader"></span>
    </button>
</form>
<a href="restaurar_contraseña.html" class="forgot-password">
    ¿Olvidaste la contraseña?
</a>

Login Authentication Logic

The login functionality is implemented in public/js/login.js:
public/js/login.js
import { auth } from "./firebase.js";
import { onAuthStateChanged, signInWithEmailAndPassword } from "https://www.gstatic.com/firebasejs/10.12.2/firebase-auth.js";

const form = document.getElementById("inicio_sesion");
const emailInput = document.getElementById("email");
const passwordInput = document.getElementById("contrasena");
const passwordError = document.getElementById("contrasenaError");

form.addEventListener("submit", async (e) => {
    e.preventDefault();

    const email = emailInput.value;
    const password = passwordInput.value;

    // Clear previous error messages
    emailError.textContent = "";
    passwordError.textContent = "";

    let valido = true;

    // Validate email field
    if (!email) {
        emailError.textContent = "Este campo es obligatorio";
        valido = false;
    }

    // Validate password field
    if (!password) {
        passwordError.textContent = "Este campo es obligatorio";
        valido = false;
    }

    if (!valido) return;

    try {
        // Attempt to sign in with Firebase
        const credenciales = await signInWithEmailAndPassword(auth, email, password);

        if (credenciales) {
            console.log("Correo:", credenciales.user.email);
            window.location.href = "index.html";
        }

    } catch (error) {
        passwordError.textContent = "Correo o contraseña incorrecta";
    }
});
1
User submits the login form
2
The form submission is intercepted with e.preventDefault() to prevent default browser behavior.
3
Client-side validation
4
The application validates that both email and password fields are filled:
5
  • Empty email shows: “Este campo es obligatorio”
  • Empty password shows: “Este campo es obligatorio”
  • 6
    Firebase authentication attempt
    7
    The signInWithEmailAndPassword() function is called with the user’s credentials:
    8
    const credenciales = await signInWithEmailAndPassword(auth, email, password);
    
    9
    Handle authentication result
    10
    Success: User is redirected to index.html (the main dashboard)
    11
    Failure: Error message “Correo o contraseña incorrecta” is displayed

    Password Visibility Toggle

    The login page includes a show/hide password feature:
    public/js/login.js
    // Toggle password visibility
    const togglePassword = document.querySelector("#togglePassword");
    
    togglePassword.addEventListener("click", () => {
        const type = passwordInput.type === "password" ? "text" : "password";
        passwordInput.type = type;
    
        togglePassword.classList.toggle("fa-eye");
        togglePassword.classList.toggle("fa-eye-slash");
    });
    
    This toggles between Font Awesome’s eye and eye-slash icons while changing the input type between password and text.

    Preventing Duplicate Login

    If a user is already authenticated, they’re automatically redirected to the dashboard:
    public/js/login.js
    // If already logged in, redirect to dashboard
    onAuthStateChanged(auth, (usuario) => {
        if (usuario) {
            window.location.href = "index.html";
        }
    });
    

    Session Management

    Authentication State Listener

    The public/js/auth.js file manages session state across all protected pages:
    public/js/auth.js
    import { auth, db } from "./firebase.js";
    import { onAuthStateChanged, signOut } from "https://www.gstatic.com/firebasejs/10.12.2/firebase-auth.js";
    import { getDocs, collection, query, where } from "https://www.gstatic.com/firebasejs/10.12.2/firebase-firestore.js";
    
    const pagina = window.location.pathname.split("/").pop();
    
    onAuthStateChanged(auth, async (usuario) => {
        if (!usuario) {
            // User is not authenticated, redirect to login
            if (pagina === "panel_configuracion.html") return window.location.href = "login.html";
            if (pagina === "index.html") return window.location.href = "login.html";
            if (pagina === "panel_inventario.html") return window.location.href = "login.html";
            if (pagina === "panel_nueva-venta.html") return window.location.href = "login.html";
            if (pagina === "panel_nuevo_producto.html") return window.location.href = "login.html";
            if (pagina === "panel_reportes.html") return window.location.href = "login.html";
            if (pagina === "panel_ventas.html") return window.location.href = "login.html";
        } 
    });
    
    The onAuthStateChanged listener automatically detects when a user’s authentication state changes, including:
    • Initial page load
    • User logs in
    • User logs out
    • Session expires
    • Token refresh

    How It Works

    1. Extract current page name: window.location.pathname.split("/").pop() gets the current HTML file name
    2. Listen for auth state changes: onAuthStateChanged() fires whenever authentication state changes
    3. Check user status: If usuario is null/undefined, the user is not authenticated
    4. Redirect to login: Protected pages redirect unauthenticated users to login.html

    Protected Pages

    The following pages are protected by the authentication guard:
    • index.html - Main dashboard
    • panel_configuracion.html - Configuration panel
    • panel_inventario.html - Inventory management
    • panel_nueva-venta.html - New sale form
    • panel_nuevo_producto.html - New product form
    • panel_reportes.html - Reports panel
    • panel_ventas.html - Sales history

    Including Auth Protection

    To protect a page, simply include the auth module:
    <script type="module" src="js/auth.js"></script>
    
    This script tag should be added to every protected page in your application.

    Logout Functionality

    Logout Implementation

    The logout button is present in the dashboard header:
    public/index.html
    <button class="btn btn-c" id="cerrar_sesion">Cerrar Sesión</button>
    
    The logout logic in auth.js handles the sign-out process:
    public/js/auth.js
    document.getElementById("cerrar_sesion").addEventListener("click", async () => {
        await signOut(auth);
    });
    
    When the user clicks Cerrar Sesión:
    1
    SignOut is called
    2
    The signOut(auth) function invalidates the user’s session with Firebase.
    3
    Auth state changes
    4
    The onAuthStateChanged listener detects the state change.
    5
    Automatic redirect
    6
    Since the user is now unauthenticated, the auth guard redirects them to login.html.
    No explicit redirect is needed after signOut() because the onAuthStateChanged listener automatically handles the redirect to the login page.

    Password Reset

    Password Reset Page

    Users can reset their password via public/restaurar_contraseña.html:
    public/restaurar_contraseña.html
    <div class="login-header">
        <h2>Restaurar Contraseña</h2>
        <p>Ingrese su correo electrónico para enviar un correo de 
           reinicio de contraseña.</p>
    </div>
    
    <form id="inicio_sesion" class="login-form" novalidate>
        <div class="form-group">
            <div class="input-wrapper">
                <input autocomplete="on" type="email" id="email" 
                       name="email" placeholder="Correo Electrónico" required>
                <span class="error-message" id="emailError"></span>
            </div>
        </div>
    
        <button type="submit" class="login-btn">
            <span class="btn-text">Enviar Correo</span>
            <span class="btn-loader"></span>
        </button>
    </form>
    

    Password Reset Logic

    The password reset functionality is implemented in public/js/restaurar_contraseña.js:
    public/js/restaurar_contraseña.js
    import { auth } from "./firebase.js";
    import { sendPasswordResetEmail } from "https://www.gstatic.com/firebasejs/10.12.2/firebase-auth.js";
    
    const form = document.getElementById("inicio_sesion");
    
    form.addEventListener("submit", async (e) => {
        e.preventDefault();
        const emailInput = document.getElementById("email").value.trim();
        
        if (!emailInput) return console.log("Sin correo");
    
        try {
            await sendPasswordResetEmail(auth, emailInput);
            console.log("Correo Enviado");
        } catch (error) {
            console.error("Error: ", error);
        }
    });
    

    Password Reset Flow

    1
    User enters email address
    2
    The user navigates to restaurar_contraseña.html and enters their email.
    3
    Form submission
    4
    The form is submitted and validated (email must not be empty).
    5
    Send reset email
    6
    Firebase sends a password reset email to the provided address using sendPasswordResetEmail().
    7
    User receives email
    8
    Firebase sends an email with a secure link to reset the password.
    9
    Password reset completion
    10
    The user clicks the link in the email and sets a new password through Firebase’s hosted UI.
    The current implementation logs the result to the console but doesn’t display user-facing success or error messages. Consider adding visual feedback for better user experience.

    Security Considerations

    Firebase Security Rules

    Make sure to configure appropriate Firestore security rules:
    rules_version = '2';
    service cloud.firestore {
      match /databases/{database}/documents {
        // Only authenticated users can read/write
        match /{document=**} {
          allow read, write: if request.auth != null;
        }
      }
    }
    

    Best Practices

    Secure Configuration

    Never commit Firebase configuration with real credentials to public repositories. Use environment variables for production.

    HTTPS Only

    Always serve your application over HTTPS in production. Firebase Authentication requires secure connections.

    Password Policies

    Configure password policies in Firebase Console under Authentication > Settings to enforce strong passwords.

    Email Verification

    Consider enabling email verification for new users to ensure valid email addresses.

    Common Authentication Errors

    The email address is badly formatted.Solution: Validate email format on the client side before submitting.
    The user account has been disabled by an administrator.Solution: Re-enable the user in Firebase Console > Authentication > Users.
    There is no user record corresponding to this email.Solution: Verify the email address or create the user account in Firebase Console.
    The password is invalid for the given email.Solution: Verify the password or use the password reset functionality.
    Access to this account has been temporarily disabled due to many failed login attempts.Solution: Wait a few minutes or reset the password.

    Testing Authentication

    Manual Testing

    To test the authentication system:
    1. Test successful login: Use valid credentials and verify redirect to dashboard
    2. Test failed login: Use invalid credentials and verify error message appears
    3. Test route protection: Try accessing index.html directly while logged out
    4. Test logout: Click the logout button and verify redirect to login
    5. Test password reset: Submit email and check for Firebase password reset email

    User Creation

    Since there’s no registration interface, create test users through Firebase Console:
    1. Navigate to Firebase Console > Authentication > Users
    2. Click “Add user”
    3. Enter email and password
    4. Click “Add user”

    Next Steps

    Now that you understand authentication, explore these related topics:

    Firestore Collections

    Learn about the database collections and schemas

    Security Rules

    Configure secure database rules for your application

    Dashboard Features

    Explore the authenticated dashboard features

    Firebase Config

    Understand the Firebase configuration and setup

    Build docs developers (and LLMs) love