Appearance
Authentication Overview
DaraMex implements a dual-entity authentication system to separate business management from service consumption.
Session-Centric Token Model
- Sessions are the source of truth for auth state.
- Access tokens include
sessionId, and every protected request validates that session is active. - Refresh tokens are single-use, rotated credentials bound to a session.
- Session revocation invalidates both access and refresh behavior immediately.
User vs. Client
| Feature | User (Business Owner) | Client (Consumer) |
|---|---|---|
| Role | Agency owner, admin, or manager. | Customer of a specific agency. |
| Relationship | One User can own or manage multiple agencies. | One Client account belongs to exactly one agency. |
| Multi-account | Single global account to manage all owned agencies. | Can have multiple accounts with the same email across different agencies (disjoint). |
| Login Context | Global login. | Scoped to a specific agencyId. |
| Password Change | Fully supported with security notifications. | Fully supported with security notifications. |
Public vs. Private Routes
All routes are Private by default. This is enforced by global guards registered in CoreModule:
JwtAuthGuard: Extends Passport'sjwt-accessstrategy. It checks for a valid Bearer token.AuthTypeGuard: Ensures the authenticated subject matches the required type (userorclient).TwoFactorChallengeGuard: Enforces second-factor proof on authenticated sensitive routes marked with@RequiresTwoFactor(...).
Making a Route Public
Use the @PublicRoute() decorator. Under the hood:
- The
JwtAuthGuarduses the NestJSReflectorto check for theisPublicmetadata. - If present, it returns
trueimmediately, bypassing token validation.
Restricting Auth Types
Use the @Auth() or @AuthTypes('user', 'client') decorators:
@Auth(): Default shorthand for@AuthTypes('user', 'client').AuthTypeGuardchecks thetypefield in the JWT payload (req.user.type) against the allowed types.
Authentication Strategies
We use Passport.js to handle different authentication methods:
| Strategy | Name | Used In | Purpose |
|---|---|---|---|
LocalUserStrategy | local-user | UserAuthController.login | Validates User email + password. |
LocalClientStrategy | local-client | ClientAuthController.login | Validates Client email + password + agencyId. |
GoogleUserStrategy | google-user | UserAuthController.google | Handles Google OAuth 2.0 callback resolution for agency-scoped user login/registration intent. |
JwtAccessStrategy | jwt-access | Global (JwtAuthGuard) | Validates the Access Token in the Authorization header. |
JwtRefreshStrategy | jwt-refresh | AuthController.refresh | Validates the Refresh Token during rotation. |
JwtTwoFactorStrategy | jwt-two-factor | TwoFactorController.verify | Validates the temporary 2FA token during login hand-off. |
Common Decorators
@PublicRoute(): Bypasses all authentication guards.@Auth(): Requires the subject to be eitheruserorclient.@AuthTypes(...types): Explicitly allowsuser,client, or both.@RequiresTwoFactor(purpose): Marks authenticated sensitive routes that must validate a second factor when 2FA is active.@Req()/@Res(): Access underlying Express objects (standard NestJS).@RateLimit({ windowMs, limit, identifierType }): Applies per-endpoint Redis-backed rate limiting (sliding window algorithm).@Query('...')/@Body(...): Access request data with optional Zod validation viaZodValidationPipe.