Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/astrxnomo/shop-microservers/llms.txt

Use this file to discover all available pages before exploring further.

The Auth service is the identity backbone of Shop Microservers. It exposes two public endpoints — registration and login — and issues signed JWTs that every other protected service (cart, orders) uses to identify the caller. Passwords are never stored in plain text; they are hashed with bcrypt before being persisted to PostgreSQL. Once a token is issued, the Auth service is not involved in subsequent requests — downstream services verify the JWT independently using the shared JWT_SECRET.

Overview

Runtime

Express on port 3004 inside Docker. Gateway prefix: /api/auth/.

Database

PostgreSQL — database name auth_db. Schema managed by Prisma.

Key Dependencies

bcryptjs, jsonwebtoken, zod, @prisma/client

Authentication

No auth required on any Auth service endpoint — these are the entry points for obtaining a token.

Endpoints

MethodPathAuthDescription
POST/registerNoneCreate a new user account
POST/loginNoneAuthenticate and receive a JWT
All Auth endpoints are reachable through the gateway at /api/auth/register and /api/auth/login.

Data Model

The service has a single User model managed by Prisma:
model User {
  id           String   @id @default(cuid())
  email        String   @unique
  passwordHash String
  createdAt    DateTime @default(now())
}
The passwordHash field stores the bcrypt output (salt rounds: 10). The plain-text password is never persisted.

Input Validation

Both endpoints share the same Zod schema:
export const AuthSchema = z.object({
  email: z.string().email(),
  password: z.string().min(6),
});
Requests that fail validation are rejected with HTTP 400 before reaching the service layer.

JWT Details

Tokens are produced by the issueToken helper inside auth.service.ts:
function issueToken(sub: string, email: string) {
  return jwt.sign({ sub, email }, config.jwtSecret, { expiresIn: "7d" });
}
PropertyValue
AlgorithmHS256 (default for jsonwebtoken)
SecretJWT_SECRET environment variable
Expiry7 days
Payload{ sub: userId, email }

Using Tokens in Other Services

After login or registration, store the returned token and attach it as a Bearer token to every request that requires authentication:
Authorization: Bearer <token>
The cart and orders services both extract sub (the user’s ID) from the decoded JWT to scope data to the correct user.

Response Shape

A successful registration or login response follows the platform-wide envelope:
{
  "success": true,
  "data": {
    "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
    "user": {
      "id": "clxyz123",
      "email": "user@example.com"
    }
  }
}

Service Implementation

// services/auth/src/services/auth.service.ts

export async function register(email: string, password: string) {
  const existing = await prisma.user.findUnique({ where: { email } });
  if (existing) throw new AppError("Email already registered", 409);

  const passwordHash = await bcrypt.hash(password, 10);
  const user = await prisma.user.create({ data: { email, passwordHash } });

  return {
    token: issueToken(user.id, user.email),
    user: { id: user.id, email: user.email },
  };
}

export async function login(email: string, password: string) {
  const user = await prisma.user.findUnique({ where: { email } });
  if (!user || !(await bcrypt.compare(password, user.passwordHash)))
    throw new AppError("Invalid credentials", 401);

  return {
    token: issueToken(user.id, user.email),
    user: { id: user.id, email: user.email },
  };
}

Error Cases

HTTP StatusCondition
400Request body fails Zod validation
401Email not found or password does not match
409Email address is already registered
The 401 response intentionally does not distinguish between “user not found” and “wrong password” to prevent user enumeration.

API Reference

POST /register

Create a new user account and receive a JWT.

POST /login

Authenticate an existing user and receive a JWT.

Build docs developers (and LLMs) love