npm package: @haykal/auth-backend
Description: > Complete authentication module for NestJS — JWT-based auth with registration, login, email verification, password reset, session management, and account lockout.
Latest version: 1.0.0

# @haykal/auth-backend

> Complete authentication module for NestJS — JWT-based auth with registration, login, email verification, password reset, session management, and account lockout.

## Installation

```bash
pnpm add @haykal/auth-backend
```

**Peer dependencies:** `@nestjs/jwt`, `@nestjs/passport`, `passport-jwt`, `bcrypt`

## Configuration

### `forRoot()` Options

```typescript
import { AuthModule } from '@haykal/auth-backend';

@Module({
  imports: [
    AuthModule.forRoot({
      jwt: {
        secret: process.env.JWT_SECRET,
        accessTokenExpiration: '15m',
        refreshTokenExpiration: '7d',
      },
      password: {
        saltRounds: 10,
        minLength: 8,
        requireUppercase: true,
        requireLowercase: true,
        requireNumbers: true,
        requireSpecialChars: false,
        resetTokenTtlSeconds: 3600,
      },
      registration: {
        enabled: true,
        requireEmailVerification: false,
      },
      lockout: {
        enabled: true,
        maxAttempts: 5,
        durationSeconds: 900,
      },
    }),
  ],
})
export class AppModule {}
```

### Configuration Reference

| Property                                | Type      | Required | Default | Description                             |
| --------------------------------------- | --------- | -------- | ------- | --------------------------------------- |
| `jwt.secret`                            | `string`  | **Yes**  | —       | HMAC signing secret                     |
| `jwt.accessTokenExpiration`             | `string`  | **Yes**  | —       | e.g. `'15m'`, `'1h'`                    |
| `jwt.refreshTokenExpiration`            | `string`  | No       | `'7d'`  | Refresh token TTL                       |
| `password.saltRounds`                   | `number`  | **Yes**  | —       | bcrypt rounds                           |
| `password.minLength`                    | `number`  | **Yes**  | —       | Minimum password length                 |
| `password.requireUppercase`             | `boolean` | **Yes**  | —       | Require uppercase letter                |
| `password.requireLowercase`             | `boolean` | **Yes**  | —       | Require lowercase letter                |
| `password.requireNumbers`               | `boolean` | **Yes**  | —       | Require digit                           |
| `password.requireSpecialChars`          | `boolean` | **Yes**  | —       | Require special character               |
| `password.resetTokenTtlSeconds`         | `number`  | No       | `3600`  | Password reset token TTL                |
| `registration.enabled`                  | `boolean` | **Yes**  | —       | Allow new registrations                 |
| `registration.requireEmailVerification` | `boolean` | No       | `false` | Require email verification before login |
| `lockout.enabled`                       | `boolean` | No       | `false` | Enable account lockout                  |
| `lockout.maxAttempts`                   | `number`  | No       | `5`     | Failed attempts before lockout          |
| `lockout.durationSeconds`               | `number`  | No       | `900`   | Lockout duration (15 min)               |

## Key Exports

| Export            | Type          | Description                                           |
| ----------------- | ------------- | ----------------------------------------------------- |
| `AuthModule`      | NestJS Module | Main module with `forRoot()` / `forRootAsync()`       |
| `AUTH_CONFIG`     | Symbol        | Inject the auth config object                         |
| `AuthService`     | Service       | Core auth operations (register, login, refresh, etc.) |
| `PasswordService` | Service       | Password hashing, comparison, and validation          |
| `TokenService`    | Service       | JWT and opaque token generation/verification          |
| `SessionService`  | Service       | Session listing and revocation                        |
| `JwtAuthGuard`    | Guard         | Global JWT guard — auto-protects all routes           |
| `@Public()`       | Decorator     | Bypass JWT auth on specific routes                    |
| `@CurrentUser()`  | Decorator     | Extract authenticated user from request               |

### Entities

| Export               | Description                                                   |
| -------------------- | ------------------------------------------------------------- |
| `RefreshTokenEntity` | Stores refresh token hashes with device info and expiration   |
| `UserEntity`         | Re-exported from `@haykal/user-management-backend`            |
| `AUTH_ENTITIES`      | Entity array for migration discovery (`[RefreshTokenEntity]`) |

### Domain Errors

| Error                       | Code                          | Status | Description                    |
| --------------------------- | ----------------------------- | ------ | ------------------------------ |
| `InvalidCredentialsError`   | `AUTH_INVALID_CREDENTIALS`    | 401    | Wrong email or password        |
| `EmailAlreadyExistsError`   | `AUTH_EMAIL_ALREADY_EXISTS`   | 409    | Email already registered       |
| `RegistrationDisabledError` | `AUTH_REGISTRATION_DISABLED`  | 403    | Registration turned off        |
| `WeakPasswordError`         | `AUTH_WEAK_PASSWORD`          | 422    | Password fails strength rules  |
| `InvalidTokenError`         | `AUTH_INVALID_TOKEN`          | 401    | Token invalid or expired       |
| `AccountLockedError`        | `AUTH_ACCOUNT_LOCKED`         | 429    | Too many failed login attempts |
| `EmailNotVerifiedError`     | `AUTH_EMAIL_NOT_VERIFIED`     | 403    | Email needs verification       |
| `EmailAlreadyVerifiedError` | `AUTH_EMAIL_ALREADY_VERIFIED` | 409    | Email already verified         |
| `SessionNotFoundError`      | `AUTH_SESSION_NOT_FOUND`      | 404    | Session not found or revoked   |

### Domain Events

| Event                             | Payload                                      |
| --------------------------------- | -------------------------------------------- |
| `UserRegisteredEvent`             | `userId`, `email`                            |
| `UserLoggedInEvent`               | `userId`, `email`, `ipAddress`, `deviceInfo` |
| `UserLoggedOutEvent`              | `userId`                                     |
| `EmailVerificationRequestedEvent` | `userId`, `email`, `token`                   |
| `EmailVerifiedEvent`              | `userId`, `email`                            |
| `PasswordResetRequestedEvent`     | `userId`, `email`, `token`                   |
| `PasswordResetEvent`              | `userId`                                     |
| `PasswordChangedEvent`            | `userId`                                     |
| `AccountLockedEvent`              | `userId`, `failedAttempts`                   |
| `AccountUnlockedEvent`            | `userId`                                     |
| `SessionRevokedEvent`             | `userId`, `sessionId`                        |

## API Endpoints

All endpoints are under `/api/auth`. Routes marked **Public** bypass JWT auth.

| Method   | Path                        | Auth   | Description                                 |
| -------- | --------------------------- | ------ | ------------------------------------------- |
| `POST`   | `/auth/register`            | Public | Register a new user                         |
| `POST`   | `/auth/login`               | Public | Login with email and password               |
| `POST`   | `/auth/refresh`             | Public | Refresh access token                        |
| `POST`   | `/auth/logout`              | JWT    | Logout current session                      |
| `POST`   | `/auth/revoke-all`          | JWT    | Revoke all sessions                         |
| `GET`    | `/auth/me`                  | JWT    | Get current user profile                    |
| `POST`   | `/auth/verify-email`        | Public | Verify email address with token             |
| `POST`   | `/auth/resend-verification` | Public | Resend verification email                   |
| `POST`   | `/auth/forgot-password`     | Public | Request password reset                      |
| `POST`   | `/auth/reset-password`      | Public | Reset password with token                   |
| `POST`   | `/auth/change-password`     | JWT    | Change password (requires current password) |
| `GET`    | `/auth/sessions`            | JWT    | List active sessions                        |
| `DELETE` | `/auth/sessions/:id`        | JWT    | Revoke specific session                     |
| `DELETE` | `/auth/sessions`            | JWT    | Revoke all other sessions                   |

## Usage Examples

### Protecting Routes

All routes are JWT-protected by default. Use `@Public()` to opt out:

```typescript
import { Public, CurrentUser } from '@haykal/auth-backend';
import { UserEntity } from '@haykal/user-management-backend';

@Controller('items')
export class ItemsController {
  @Get()
  @Public()
  listPublicItems() {
    // No auth required
  }

  @Post()
  createItem(@CurrentUser() user: UserEntity) {
    // user is the authenticated user
    return this.service.create(user.id, dto);
  }
}
```

### Listening to Auth Events

```typescript
import { OnDomainEvent } from '@haykal/core-backend';
import {
  UserRegisteredEvent,
  PasswordResetRequestedEvent,
} from '@haykal/auth-backend';

@Injectable()
export class AuthEventListener {
  @OnDomainEvent(UserRegisteredEvent)
  async onRegistered(event: UserRegisteredEvent) {
    // Send welcome email
  }

  @OnDomainEvent(PasswordResetRequestedEvent)
  async onPasswordReset(event: PasswordResetRequestedEvent) {
    // Send reset email with event.token
  }
}
```

## Related Packages

- `@haykal/auth-client` — React Query hooks for auth operations
- `@haykal/auth-ui` — Pre-built auth UI components and screens
- `@haykal/user-management-backend` — User entity and CRUD operations
- `@haykal/core-backend` — Base infrastructure (errors, events, guards)

## Further Reading

- [API Reference](../../../docs/api-reference.md) — Full endpoint listing
- [Architecture Overview](../../../docs/architecture.md) — System design and module composition
- [Backend Style Guide](../../../docs/backend-styleguide.md) — Coding conventions