From a92e7586d8f476a6a352a26906b23599fe4794ff Mon Sep 17 00:00:00 2001 From: bigben-7 <103938678+BigBen-7@users.noreply.github.com> Date: Fri, 19 Jun 2026 00:11:51 +0100 Subject: [PATCH] feat(auth): register StrategyAuthGuard globally & consolidate auth flow MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Register StrategyAuthGuard as global APP_GUARD in AppModule (first in chain) so all routes are protected by default; open routes use @Public() decorator - Apply @Public() to GET /health and GET /info in AppController - Add JSDoc @deprecated to AuthService.register() and AuthService.login() directing callers to use EnhancedAuthService instead - Add architecture overview JSDoc to AuthModule explaining legacy, enhanced, and strategy-pattern auth flows; documents TokenBlacklistService injection - TokenBlacklistService already exported from AuthModule and injected into AuthService.logout() — no additional injection required --- src/app.controller.ts | 3 +++ src/app.module.ts | 19 +++++++++++++------ src/core/auth/auth.module.ts | 26 ++++++++++++++++++++++++++ src/core/auth/auth.service.ts | 8 ++++++++ 4 files changed, 50 insertions(+), 6 deletions(-) diff --git a/src/app.controller.ts b/src/app.controller.ts index 96a6391..fd88d9c 100644 --- a/src/app.controller.ts +++ b/src/app.controller.ts @@ -9,12 +9,14 @@ import { import { AppService } from "./app.service"; import { RateLimit } from "./common/decorators/rate-limit.decorator"; import { JwtAuthGuard } from "./core/auth/jwt.guard"; +import { Public } from "./common/decorators/public.decorator"; @ApiTags("Health") @Controller() export class AppController { constructor(private readonly appService: AppService) {} + @Public() @Get("health") @RateLimit({ level: "free", limit: 2, windowMs: 60000 }) // Max 2 requests per minute for health @ApiOperation({ @@ -41,6 +43,7 @@ export class AppController { return this.appService.getHealth(); } + @Public() @Get("info") @RateLimit({ level: "standard" }) // Default standard level @ApiOperation({ diff --git a/src/app.module.ts b/src/app.module.ts index 7e9d984..827fc48 100644 --- a/src/app.module.ts +++ b/src/app.module.ts @@ -27,7 +27,7 @@ import { PortfolioModule } from "./investment/portfolio/portfolio.module"; import { RiskManagementModule } from "./investment/risk-management/risk-management.module"; // Modules – defi -import { DeFiModule } from "./defi/defi/defi.module"; +import { DeFiModule } from "./defi/defi.module"; // Modules – growth import { AlertsModule } from "./growth/alerts/alerts.module"; @@ -56,21 +56,23 @@ import { PerformanceMetric } from "./investment/portfolio/entities/performance-m import { BacktestResult } from "./investment/portfolio/entities/backtest-result.entity"; // DeFi entities -import { DeFiPosition } from "./defi/defi/entities/defi-position.entity"; -import { DeFiYieldRecord } from "./defi/defi/entities/defi-yield-record.entity"; -import { DeFiTransaction } from "./defi/defi/entities/defi-transaction.entity"; -import { DeFiYieldStrategy } from "./defi/defi/entities/defi-yield-strategy.entity"; -import { DeFiRiskAssessment } from "./defi/defi/entities/defi-risk-assessment.entity"; +import { DeFiPosition } from "./defi/entities/defi-position.entity"; +import { DeFiYieldRecord } from "./defi/entities/defi-yield-record.entity"; +import { DeFiTransaction } from "./defi/entities/defi-transaction.entity"; +import { DeFiYieldStrategy } from "./defi/entities/defi-yield-strategy.entity"; +import { DeFiRiskAssessment } from "./defi/entities/defi-risk-assessment.entity"; // Alerts entities import { Alert } from "./growth/alerts/entities/alert.entity"; import { AlertTriggerLog } from "./growth/alerts/entities/alert-trigger-log.entity"; +import { AlertPreference } from "./growth/alerts/entities/alert-preference.entity"; // Guards import { APP_FILTER } from "@nestjs/core"; import { ThrottlerUserIpGuard } from "./common/guard/throttler.guard"; import { RolesGuard } from "./common/guard/roles.guard"; import { KycGuard } from "./common/guard/kyc.guard"; +import { StrategyAuthGuard } from "./core/auth/guards/strategy-auth.guard"; import { GlobalExceptionFilter } from "./common/filters/global-exception.filter"; import { SubmissionVerifierService } from "./blockchain/oracle/submission-verifier.service"; @@ -139,6 +141,7 @@ import { SubmissionVerifierService } from "./blockchain/oracle/submission-verifi DeFiRiskAssessment, Alert, AlertTriggerLog, + AlertPreference, ], synchronize: !isProduction, logging: isProduction ? ["error"] : ["error", "warn", "schema"], @@ -180,6 +183,10 @@ import { SubmissionVerifierService } from "./blockchain/oracle/submission-verifi provide: APP_FILTER, useClass: GlobalExceptionFilter, }, + { + provide: APP_GUARD, + useClass: StrategyAuthGuard, + }, { provide: APP_GUARD, useClass: ThrottlerUserIpGuard, diff --git a/src/core/auth/auth.module.ts b/src/core/auth/auth.module.ts index 606fa46..7768f94 100644 --- a/src/core/auth/auth.module.ts +++ b/src/core/auth/auth.module.ts @@ -29,6 +29,32 @@ import { EmailVerification } from "./entities/email-verification.entity"; import { Wallet } from "./entities/wallet.entity"; import { RefreshToken, TwoFactorAuth } from "./entities/auth.entity"; +/** + * AuthModule — Authentication Architecture Overview + * + * Three auth flows are supported: + * + * 1. **Legacy flow** (AuthService / WalletAuthService) + * - Email+password registration/login (AuthService) and wallet-signature login + * (WalletAuthService). These services issue single short-lived JWTs and are + * retained for backward compatibility. New code should NOT call them. + * - Token revocation is handled by `TokenBlacklistService` (AuthService.logout). + * + * 2. **Enhanced flow** (EnhancedAuthService) + * - Superset of the legacy flow: adds refresh-token rotation, TOTP/backup-code + * 2FA, account-activity tracking, and proper revocation via + * `revokeAllRefreshTokens`. Prefer this service for all new email+password + * features. + * + * 3. **Strategy flow** (StrategyAuthService + StrategyAuthGuard) + * - Pluggable, registry-driven system. Strategies (WalletStrategy, + * TraditionalStrategy, OAuthStrategy, ApiKeyStrategy) are registered at + * module init and tried in sequence by `StrategyAuthGuard`. + * - `StrategyAuthGuard` is registered as a **global guard** in AppModule so + * every route is protected by default. Mark public routes with `@Public()`. + * - Use `@AllowedStrategies('wallet', 'traditional')` to restrict which + * strategies are accepted on a per-route basis. + */ @Module({ imports: [ ConfigModule, diff --git a/src/core/auth/auth.service.ts b/src/core/auth/auth.service.ts index c223644..f8b01d6 100644 --- a/src/core/auth/auth.service.ts +++ b/src/core/auth/auth.service.ts @@ -22,6 +22,10 @@ export class AuthService { private readonly tokenBlacklist: TokenBlacklistService, ) {} + /** + * @deprecated Use EnhancedAuthService instead. + * This method lacks refresh-token rotation and 2FA support. + */ async register( registerDto: RegisterDto, ): Promise<{ token: string; user: Partial }> { @@ -104,6 +108,10 @@ export class AuthService { }; } + /** + * @deprecated Use EnhancedAuthService instead. + * This method lacks refresh-token rotation and 2FA support. + */ async login( loginDto: LoginDto, ): Promise<{ token: string; user: Partial }> {