Skip to main content
FitAiid provides a secure authentication system with multiple registration and login options, including traditional email/password authentication and Google OAuth integration.

Authentication Methods

FitAiid supports two primary authentication methods:

Email/Password

Traditional registration with email verification code

Google OAuth

One-click authentication with Google account

User Registration

Registration with Email

The email registration flow uses a two-step verification process to ensure account security.
1

Submit Registration Form

Users fill out the registration form with their personal information:
frontend/scripts/register.js
const userData = {
  firstName: 'John',
  lastName: 'Doe',
  email: '[email protected]',
  password: 'SecurePass123!',
  phone: '1234567890'
};

const response = await fetch(`${API_URL}/api/auth/register-with-code`, {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify(userData)
});
The frontend validates:
  • Name fields (letters only, 2-50 characters)
  • Phone number (exactly 10 digits)
  • Email format
  • Password strength (minimum 6 characters)
2

Receive Verification Code

The backend sends a 6-digit verification code to the user’s email:
backend/src/controllers/authController.js
const verificationCode = Math.floor(100000 + Math.random() * 900000).toString();

await savePendingVerification(email, verificationCode, userData);
await sendVerificationCodeEmail(email, firstName, verificationCode);
The user data is stored temporarily and NOT saved to MongoDB until the code is verified. The verification code expires in 15 minutes.
3

Verify Code and Create Account

Users enter the 6-digit code to complete registration:
backend/src/controllers/authController.js
const verification = await getPendingVerification(email);

if (verification.code === code) {
  const user = new User({
    ...verification.userData,
    isEmailVerified: true,
    isActive: true
  });
  await user.save();
  
  const token = user.generateAuthToken();
  // Return JWT token and user profile
}
4

Store Authentication Token

The client stores the JWT token and user information:
localStorage.setItem('token', data.token);
localStorage.setItem('userId', data.user._id);
localStorage.setItem('user', JSON.stringify(data.user));

Registration with Google

Google OAuth provides a streamlined registration experience.
1

Initialize Firebase Authentication

The frontend initializes Firebase with Google provider:
frontend/pages/register.html
import { initializeApp } from 'firebase/app';
import { getAuth, GoogleAuthProvider, signInWithPopup } from 'firebase/auth';

const app = initializeApp(firebaseConfig);
const auth = getAuth(app);
const provider = new GoogleAuthProvider();
2

Authenticate with Google

User clicks “Continue with Google” button:
const result = await signInWithPopup(auth, provider);
const { displayName, email, uid } = result.user;
3

Register in Backend

The frontend sends Google user data to create MongoDB account:
const response = await fetch(`${API_URL}/api/auth/google-register`, {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    firstName: displayName.split(' ')[0],
    lastName: displayName.split(' ').slice(1).join(' '),
    email: email,
    uid: uid
  })
});
Google users are automatically marked as email verified and receive a temporary password GoogleTemp123.

User Login

Login with Email/Password

Standard authentication flow with rate limiting and account lockout protection.
const credentials = {
  email: '[email protected]',
  password: 'myPassword123'
};

const response = await fetch(`${API_URL}/api/auth/login`, {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify(credentials)
});

const data = await response.json();
if (data.success) {
  localStorage.setItem('token', data.data.token);
  localStorage.setItem('user', JSON.stringify(data.data.user));
  window.location.href = 'home.html';
}
After 5 failed login attempts, the account is locked for 30 minutes to prevent brute force attacks.

Login with Google

Google login requires the user to already have an account registered.
backend/src/controllers/authController.js
const googleLogin = async (req, res) => {
  const { email, uid } = req.body;
  
  // Search for existing user in MongoDB
  let user = await User.findOne({ email: email.toLowerCase() });
  
  // Reject if user not registered
  if (!user) {
    throw new AppError('Este correo no está registrado. Por favor regístrate primero.', 404);
  }
  
  // Verify account is active
  if (!user.isActive) {
    throw new AppError('Tu cuenta ha sido desactivada', 401);
  }
  
  // Generate JWT and return user data
  const token = user.generateAuthToken();
  const publicProfile = user.getPublicProfile();
  
  res.status(200).json({
    success: true,
    message: 'Inicio de sesión con Google exitoso',
    token,
    user: publicProfile
  });
};

Password Recovery

FitAiid provides a secure password recovery system using verification codes.
1

Request Reset Code

User enters their email address:
const response = await fetch(`${API_URL}/api/auth/forgot-password`, {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ email: '[email protected]' })
});
The backend generates a 6-digit code and hashes it before saving:
backend/src/controllers/authController.js
const resetCode = Math.floor(100000 + Math.random() * 900000).toString();

const resetCodeHash = crypto
  .createHash('sha256')
  .update(resetCode)
  .digest('hex');

user.resetPasswordCode = resetCodeHash;
user.resetPasswordExpire = Date.now() + 15 * 60 * 1000; // 15 minutes
await user.save();
2

Verify Reset Code

User enters the 6-digit code received via email:
await fetch(`${API_URL}/api/auth/verify-code`, {
  method: 'POST',
  body: JSON.stringify({ email, code })
});
3

Set New Password

User submits new password (minimum 8 characters):
backend/src/controllers/authController.js
const resetPassword = async (req, res) => {
  const { email, code, password } = req.body;
  
  if (password.length < 8) {
    throw new AppError('La contraseña debe tener al menos 8 caracteres', 400);
  }
  
  const codeHash = crypto.createHash('sha256').update(code).digest('hex');
  
  const user = await User.findOne({
    email: email.toLowerCase(),
    resetPasswordCode: codeHash,
    resetPasswordExpire: { $gt: Date.now() }
  });
  
  if (!user) {
    throw new AppError('Código inválido o expirado', 400);
  }
  
  // Update password (automatically hashed by User model)
  user.password = password;
  user.resetPasswordCode = undefined;
  user.resetPasswordExpire = undefined;
  await user.save();
};

Authentication Middleware

All protected routes use JWT authentication middleware:
backend/src/middleware/auth.js
const protect = async (req, res, next) => {
  let token;
  
  if (req.headers.authorization?.startsWith('Bearer')) {
    token = req.headers.authorization.split(' ')[1];
  }
  
  if (!token) {
    throw new AppError('No autorizado. Token requerido', 401);
  }
  
  try {
    const decoded = jwt.verify(token, process.env.JWT_SECRET);
    req.user = await User.findById(decoded.id).select('-password');
    next();
  } catch (error) {
    throw new AppError('Token inválido o expirado', 401);
  }
};

UI Components

The login page features a split-screen design with:

Left Panel

  • Animated gym background image with zoom effect
  • FitAiid logo with gradient styling
  • Motivational hero text with gradient effects
  • Red accent stripes and grid overlay

Right Panel

  • Login form with email and password fields
  • Password visibility toggle
  • Forgot password link
  • Google sign-in button with hover effects
  • Link to registration page

Security Features

Rate Limiting

API requests are rate-limited to prevent abuse

Account Lockout

After 5 failed attempts, accounts lock for 30 minutes

Password Hashing

Passwords are hashed using bcrypt before storage

JWT Tokens

Secure token-based authentication for API requests

API Endpoints

EndpointMethodDescriptionAuth Required
/api/auth/register-with-codePOSTRegister with email verificationNo
/api/auth/verify-registrationPOSTVerify registration codeNo
/api/auth/google-registerPOSTRegister with GoogleNo
/api/auth/loginPOSTLogin with email/passwordNo
/api/auth/googlePOSTLogin with GoogleNo
/api/auth/forgot-passwordPOSTRequest password reset codeNo
/api/auth/verify-codePOSTVerify reset codeNo
/api/auth/reset-passwordPOSTSet new passwordNo
/api/auth/profileGETGet user profileYes
/api/auth/profilePUTUpdate user profileYes
All authentication endpoints include comprehensive logging and audit trails for security monitoring.

Build docs developers (and LLMs) love