feat: Implement NestJS Auth, Users, and Licenses modules

Complete authentication system with JWT, refresh tokens, and TOTP 2FA.
Auto-generates license keys on registration (CORR-XXXX-XXXX-XXXX format).
JwtStrategy enriches payload with license_id and permissions from roles.
Multi-tenant isolation enforced at license access layer.

Auth Module:
- 9 REST endpoints (login, register, refresh, 2FA setup/verify, profile, password reset)
- Argon2 password hashing, TOTP with QR code generation
- Public endpoints: login, register, forgot-password, reset-password, validate-key
- Authenticated endpoints require JWT Bearer token

Users Module:
- Admin CRUD for user management (requires users.view permission)
- Password fields excluded from all responses

Licenses Module:
- License lookup with owner authorization
- Public key validation endpoint for plugin verification
- License key generation via random hex parts

All DTOs use class-validator, all controllers documented via Swagger.
Custom decorators: @Public(), @CurrentUser(), @RequirePermission().

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Vantz Stockwell
2026-02-15 21:13:57 -05:00
parent 500d92cbe3
commit 8cd792eb75
19 changed files with 965 additions and 0 deletions

View File

@@ -4,6 +4,77 @@ All notable changes to this project will be documented in this file.
## [Unreleased]
### Added (NestJS Backend — Core Modules)
**Auth Module (`modules/auth/`):**
- Complete authentication system with JWT and refresh tokens
- DTOs: `LoginDto`, `RegisterDto`, `RefreshTokenDto`, `VerifyTotpDto`, `UpdateProfileDto`, `ForgotPasswordDto`, `ResetPasswordDto`
- `JwtStrategy` — Passport strategy with user lookup, license resolution, and role permissions injection
- `AuthService` — Full auth lifecycle:
- `register()` — User creation with auto-generated license key (CORR-XXXX-XXXX-XXXX format)
- `login()` — Credential validation, TOTP verification, token generation
- `refresh()` — Access token refresh from valid refresh token
- `setupTotp()` — TOTP secret generation with QR code (otpauth + qrcode libraries)
- `verifyTotp()` — TOTP code validation and 2FA enablement
- `getProfile()` / `updateProfile()` — User profile management
- `forgotPassword()` / `resetPassword()` — Password recovery stubs (SMTP integration pending)
- `AuthController` — 9 REST endpoints:
- `POST /auth/login` — Email/password login with optional TOTP
- `POST /auth/register` — New user registration with auto-license creation
- `POST /auth/refresh` — Token refresh
- `POST /auth/2fa/setup` — Generate TOTP QR code (authenticated)
- `POST /auth/2fa/verify` — Enable 2FA (authenticated)
- `GET /auth/me` — Current user profile (authenticated)
- `PUT /auth/profile` — Update profile (authenticated)
- `POST /auth/forgot-password` — Request password reset (public)
- `POST /auth/reset-password` — Reset with token (public)
- Password hashing via argon2, TOTP via otpauth with 30-second window validation
- License key auto-generation on registration (random hex parts)
- JWT payload includes: sub (user ID), email, username, is_super_admin, license_id, permissions
- Strategy enriches JWT with license context (owner or team member lookup) and role permissions
**Users Module (`modules/users/`):**
- Simple CRUD wrapper around User repository
- `UsersService``findById()`, `findByEmail()`, `findAll()` with password_hash excluded from select
- `UsersController` — Admin-only endpoints:
- `GET /users` — List all users (requires `users.view` permission)
- `GET /users/:id` — Get user by ID (requires `users.view` permission)
- Password fields excluded from all query results
**Licenses Module (`modules/licenses/`):**
- License management with owner authorization
- DTO: `ValidateKeyDto` — License key validation input
- `LicensesService`:
- `findById()` — License lookup with owner/super admin authorization check
- `findByKey()` — Key-based lookup
- `findByOwner()` — All licenses owned by user
- `create()` — New license generation with CORR-XXXX-XXXX-XXXX format
- `validateKey()` — Public key validation returning status and metadata
- `LicensesController`:
- `GET /licenses/:id` — Get license (owner or super admin only)
- `POST /licenses/validate-key` — Public key validation endpoint
- License key format: `CORR-{4-hex}-{4-hex}-{4-hex}` (e.g., CORR-A1B2-C3D4-E5F6)
- Ownership enforced: non-super-admin users can only access their own licenses
**Patterns Applied:**
- All DTOs use class-validator decorators (@IsEmail, @IsString, @MinLength, etc.)
- All controllers use @ApiTags and @ApiBearerAuth for Swagger documentation
- All routes use @ApiOperation for endpoint descriptions
- Custom decorators: @Public(), @CurrentUser(), @CurrentTenant(), @RequirePermission()
- Entity imports from `../../entities/` directory
- ConfigService for environment variables (JWT_SECRET, JWT_ACCESS_EXPIRY_SECONDS, JWT_REFRESH_EXPIRY_SECONDS)
- Multi-tenant isolation: License lookup respects ownership unless super admin
- JwtStrategy enriches request.user with license_id and permissions for downstream guards
**Security:**
- Argon2 password hashing (not bcrypt — more resistant to GPU attacks)
- TOTP 6-digit codes with ±1 period window validation
- Refresh tokens with separate expiry (default 7 days vs 1 hour access token)
- Password fields never returned in API responses
- License access requires ownership or super admin flag
**Status:** Core auth, users, and licenses modules operational. Registration creates user + license atomically. Login returns JWT with license context. TOTP 2FA flow complete. Password reset stubbed pending SMTP integration. All endpoints documented via Swagger.
### Added (Phase 4 — Module Licensing Backend)
**Backend Infrastructure:**