Skip to content

SunTheCoder/prep

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

11 Commits
 
 
 
 
 
 

Repository files navigation

prep

Authentication Controller Documentation

This document explains how the authentication system works in our TypeScript Express API, covering user registration and login using Prisma (PostgreSQL), JWT, and bcrypt.


🔹 Overview

This module provides authentication functionalities:

  • User Registration (/register)
  • User Login (/login)
  • JWT Token-Based Authentication
  • Secure Password Hashing
  • Manual Input Validation

🔹 Dependencies Used

Package Purpose
express Web framework for Node.js
bcryptjs Hashing passwords securely
jsonwebtoken Generating & verifying JWT tokens
@prisma/client ORM for PostgreSQL database
cookie-parser Storing JWT in secure cookies (optional)

🔹 Environment Variables

Variable Description
JWT_SECRET Secret key for signing JWT tokens
DATABASE_URL PostgreSQL connection string

📌 Ensure you define these in your .env file before running the server.


1️⃣ Register User

🔹 Endpoint:

POST /api/auth/register

🔹 Request Body (JSON):

{
  "name": "John Doe",
  "email": "john.doe@example.com",
  "password": "securepassword"
}

🔹 Response (Success)

{
  "message": "User registered successfully",
  "userId": "123e4567-e89b-12d3-a456-426614174000"
}

🔹 Response (Errors)

Status Code Message
400 Name must be at least 2 characters
400 Invalid email format
400 Password must be at least 6 characters
500 Internal Server Error

🔹 Implementation

export const register = async (req: Request, res: Response, next: NextFunction) => {
  try {
    const { name, email, password } = req.body;

    // Manual validation
    if (!name || name.length < 2) {
      return res.status(400).json({ message: "Name must be at least 2 characters" });
    }
    if (!email || !email.includes("@") || !email.includes(".")) {
      return res.status(400).json({ message: "Invalid email format" });
    }
    if (!password || password.length < 6) {
      return res.status(400).json({ message: "Password must be at least 6 characters" });
    }

    // Hash password before storing in DB
    const hashedPassword = await bcrypt.hash(password, 10);

    // Create user in PostgreSQL using Prisma
    const user = await prisma.user.create({
      data: { name, email, password: hashedPassword },
    });

    res.status(201).json({ message: "User registered successfully", userId: user.id });
  } catch (error) {
    console.error("Error registering user:", error);
    res.status(500).json({ message: "Internal Server Error" });
  }
};

2️⃣ Login User

🔹 Endpoint:

POST /api/auth/login

🔹 Request Body (JSON):

{
  "email": "john.doe@example.com",
  "password": "securepassword"
}

🔹 Response (Success)

{
  "message": "Login successful",
  "token": "eyJhbGciOiJIUzI1..."
}

🔹 Response (Errors)

Status Code Message
400 Invalid email format
400 Password must be at least 6 characters
401 Invalid credentials
500 Internal Server Error

🔹 Implementation

export const login = async (req: Request, res: Response, next: NextFunction) => {
  try {
    const { email, password } = req.body;

    // Manual validation
    if (!email || !email.includes("@") || !email.includes(".")) {
      return res.status(400).json({ message: "Invalid email format" });
    }
    if (!password || password.length < 6) {
      return res.status(400).json({ message: "Password must be at least 6 characters" });
    }

    // Find user by email
    const user = await prisma.user.findUnique({ where: { email } });

    if (!user || !(await bcrypt.compare(password, user.password))) {
      return res.status(401).json({ message: "Invalid credentials" });
    }

    // Generate JWT token
    const token = jwt.sign({ id: user.id }, JWT_SECRET!, { expiresIn: "1h" });

    // Secure cookie storage
    res.cookie("token", token, { httpOnly: true, secure: true, sameSite: "strict" });
    res.json({ message: "Login successful", token });
  } catch (error) {
    console.error("Error logging in:", error);
    res.status(500).json({ message: "Internal Server Error" });
  }
};

3️⃣ JWT-Based Authentication

How JWT Works

  1. User Logs In → Receives a JWT token.
  2. Token is Sent in Requests → Stored in cookies or sent via Authorization headers.
  3. Protected Routes Verify Token → Only authenticated users can access them.

🔹 Middleware for Protecting Routes

import { Request, Response, NextFunction } from "express";
import jwt from "jsonwebtoken";

const JWT_SECRET = process.env.JWT_SECRET!;

interface AuthenticatedRequest extends Request {
  user?: { id: string };
}

export const authMiddleware = (req: AuthenticatedRequest, res: Response, next: NextFunction) => {
  const token = req.cookies?.token || req.headers.authorization?.split(" ")[1];

  if (!token) {
    return res.status(401).json({ message: "Unauthorized: No token provided" });
  }

  try {
    const decoded = jwt.verify(token, JWT_SECRET) as { id: string };
    req.user = decoded;
    next();
  } catch {
    res.status(401).json({ message: "Invalid token" });
  }
};

4️⃣ Logout User

🔹 Endpoint:

POST /api/auth/logout

🔹 Response

{
  "message": "Logout successful"
}

🔹 Implementation

export const logout = async (req: Request, res: Response) => {
  res.clearCookie("token", { httpOnly: true, secure: true, sameSite: "strict" });
  res.json({ message: "Logout successful" });
};

🔹 Summary of API Routes

HTTP Method Endpoint Description Middleware
POST /api/auth/register Register a new user None
POST /api/auth/login Authenticate user & return JWT None
POST /api/auth/logout Clear authentication token None
GET /api/protected Example protected route authMiddleware

✅ What You Mastered TypeScript Express Backend JWT Authentication & Secure Cookies User Registration, Login, and Deletion Redux Toolkit for Authentication Management Fetching and Managing Users in React Debugging CORS & API Route Issues Proper Backend & Frontend Integration

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors