Skip to content

LeOndaz/easy-generator

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

5 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Full-Stack Authentication Project

Introduction

A full-stack application with a NestJS backend and React frontend for user authentication. The project is fully containerized with Docker for both development and production environments.

Getting Started with Docker

This project is fully containerized. To run the application in a development environment:

# This will build and start the backend, frontend, and database containers.
# The frontend will be available at http://localhost:5173
# The backend will be available at http://localhost:3000
$ docker-compose up --build

To run the application in a production environment:

$ docker-compose -f docker-compose.prod.yml up --build

Project Architecture

Backend

The backend is built with NestJS, a progressive Node.js framework for building efficient and scalable server-side applications.

  • Database: MongoDB is used as the database, with Mongoose as the ODM for modeling application data.
  • Architecture: The code follows a modular structure (AuthModule, UsersModule) and utilizes the Repository Pattern (UsersRepository) to decouple the business logic from the data access layer.
  • Authentication: Implements a stateless authentication system using JWT (JSON Web Tokens) with an access token/refresh token strategy. Passwords are securely hashed using Argon2.
  • Configuration: Environment variables are managed by the @nestjs/config module and validated against a Joi schema.
  • Logging: Uses nest-winston for structured, production-ready logging.

Frontend

The frontend is a single-page application built with React and Vite.

  • UI Framework: Ant Design is used for UI components, providing a robust set of high-quality components.
  • State Management: Global state, specifically the authenticated user's session, is managed via React Context. Asynchronous state and server-side cache are handled by TanStack Query (React Query), which simplifies data fetching, caching, and synchronization.
  • Routing: React Router is used for all client-side routing, including protected routes that require authentication.
  • Code Structure: Logic is encapsulated in custom hooks (e.g., useLogin, useSignUp) for clean, reusable, and maintainable components.

Type-Safe API Client (Orval)

To ensure type safety between the frontend and backend, this project uses Orval. Orval generates a type-safe client on the frontend based on the backend's OpenAPI (Swagger) specification.

The Workflow

  1. The NestJS backend automatically generates a swagger.yaml file at /api/v1/swagger.yaml. This file describes all API endpoints, request bodies, and response shapes.
  2. On the frontend, the orval command is run (or can be run via npm run generate:api).
  3. Orval reads the swagger endpoint and generates a fully typed React Query client located at frontend/src/api/api.ts.
  4. This generated client includes custom hooks for every API endpoint (e.g., useAuthControllerSignInV1, useAuthControllerMeV1). The directories are named after the swagger tags.
  5. The frontend application imports and uses these generated hooks, providing compile-time type safety for all API interactions. If the backend API changes, running the Orval command will update the client, and any breaking changes will be caught by the TypeScript compiler on the frontend.

Warning The frontend/src/api directory is entirely auto-generated by Orval. Do not edit any files in this directory manually, as your changes will be overwritten the next time the API client is generated.

API Documentation

The API is versioned, with the base path for version 1 being /api/v1. Full, interactive Swagger documentation is available at /api/v1/swagger when the application is running.

Auth Module

1. Sign Up

  • Endpoint: POST /auth/signup
  • Description: Registers a new user.
  • Request Body:
    {
      "username": "testuser",
      "password": "Password123!"
    }
  • Success Response (201):
    {
      "accessToken": "...",
      "refreshToken": "...",
      "user": {
        "username": "testuser",
        "_id": "..."
      }
    }

2. Sign In

  • Endpoint: POST /auth/signin
  • Description: Authenticates a user and returns JWT tokens.
  • Request Body:
    {
      "username": "testuser",
      "password": "Password123!"
    }
  • Success Response (200):
    {
      "accessToken": "...",
      "refreshToken": "...",
      "user": {
        "username": "testuser",
        "_id": "..."
      }
    }

3. Refresh Token

  • Endpoint: POST /auth/refresh
  • Description: Generates a new access token using a valid refresh token.
  • Request Body:
    {
      "refreshToken": "..."
    }
  • Success Response (200):
    {
      "accessToken": "..."
    }

4. Get Current User

  • Endpoint: GET /auth/me
  • Authentication: JWT Token required. This endpoint is protected.
  • Description: Retrieves the profile of the currently authenticated user.
  • Success Response (200):
    {
      "username": "testuser",
      "_id": "..."
    }

Security Notes & Best Practices

  • JWT Payload Security: To prevent leaking personally identifiable information (PII) if a token were ever compromised, the JWT payload contains only the non-sequential user _id (sub claim) and not the email
  • Exposing _id: In the current implementation, the user object returned by the API includes the MongoDB _id field. In a production environment, it is best practice to not expose raw database identifiers. This should be mapped to a different, non-sequential public ID or removed from the public-facing DTO.
  • API Throttling: The API does not currently have rate-limiting implemented. To protect against brute-force attacks and denial-of-service, a throttler (like the one provided by @nestjs/throttler) should be configured globally.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors