Tasks

Ecosistema completo para organización y gestión de contenido con interfaces espaciales

Security Library - Implementation Tasks

Sprint: Security Improvements Epic: Security Library Compliance Start Date: 2025-09-29


Phase 1: Critical Fixes (Week 1)

Task 1.1: Remove Timer-Based Auto-Refresh 🔴

Priority: Critical Estimate: 8 hours Assignee: TBD Files: libs/core/security/src/lib/auth/token.service.ts

Description

Replace polling-based token refresh (timer every 30s) with event-driven refresh based on actual token expiration time.

Acceptance Criteria

Definition of Done (DoD)

Validation Commands

# Verify no timer polling
grep -r "timer.*30000" libs/core/security/src/
# Should return: no matches

# Verify no setTimeout
grep -r "setTimeout\|setInterval" libs/core/security/src/ --exclude="*.spec.ts"
# Should return: no matches (tests are allowed)

# Run tests
npx nx test security
# Should pass: all tests green

Implementation Notes


Task 1.2: Replace Console Logging with LoggerService 🔴

Priority: Critical Estimate: 6 hours Assignee: TBD Files:

Description

Replace all console.error, console.log, console.warn with LoggerService from @libs-core/log-system.

Acceptance Criteria

Definition of Done (DoD)

Validation Commands

# Verify no console usage in production code
grep -r "console\." libs/core/security/src/lib/ --exclude-dir=__tests__ --exclude="*.spec.ts"
# Should return: no matches

# Verify LoggerService injection
grep -r "private.*logger.*=.*inject(LoggerService)" libs/core/security/src/lib/auth/
# Should return: matches in token.service.ts and auth.service.ts

# Run tests
npx nx test security
# Should pass: all tests green

Log Level Guidelines

Example Replacements

// ❌ Before
console.error('Error inicializando tokens:', error);

// ✅ After
this.logger.error('Token initialization failed', {
  error,
  operation: 'token_initialization',
  tenantId: this.contextService.getCurrentTenantId(),
  correlationId: this.sessionService.getCorrelationId(),
  recoverable: true
});

Task 1.3: Convert Crypto Utils to RxJS Observables 🔴

Priority: Critical Estimate: 4 hours Assignee: TBD Files: libs/core/security/src/lib/utils/crypto.utils.ts

Description

Convert async/await Promise-based functions to Observable-based API to comply with "Always use rxJS, never use promises" rule.

Acceptance Criteria

Definition of Done (DoD)

Validation Commands

# Verify no Promise usage
grep -r "Promise<\|async function\|async (" libs/core/security/src/lib/utils/crypto.utils.ts
# Should return: no matches

# Verify Observable usage
grep -r "Observable<" libs/core/security/src/lib/utils/crypto.utils.ts
# Should return: matches for encryptForStorage and decryptFromStorage

# Run tests
npx nx test security --testNamePattern="CryptoUtils"
# Should pass: all crypto utils tests green

Implementation Example

// ❌ Before
export async function encryptForStorage(
  data: string,
  password: string
): Promise<{ encrypted: string; salt: string; iv: string }> {
  const encoder = new TextEncoder();
  const salt = generateRandomBytes(16);
  // ... more async code
  return { encrypted, salt, iv };
}

// ✅ After
export function encryptForStorage(
  data: string,
  password: string
): Observable<{ encrypted: string; salt: string; iv: string }> {
  return new Observable(observer => {
    const encoder = new TextEncoder();
    const salt = generateRandomBytes(16);

    performEncryption(data, password, salt)
      .then(result => {
        observer.next(result);
        observer.complete();
      })
      .catch(error => observer.error(error));
  });
}

// Or simpler with from()
export function encryptForStorage(
  data: string,
  password: string
): Observable<{ encrypted: string; salt: string; iv: string }> {
  return from(performEncryptionAsync(data, password));
}

Task 1.4: Fix CSRFTokenService Test Failures 🔴

Priority: Critical Estimate: 3 hours Assignee: TBD Files:

Description

Fix 3 failing tests related to LoggerService injection in CSRFTokenService test suite.

Failing Tests

  1. CSRFTokenService > token management > should get token for specific tenant
  2. CSRFTokenService > token management > should clear all tokens
  3. CSRFTokenService > token management > should clear token for specific tenant

Error Message

NG0203: The `LoggerService2` token injection failed.
inject() function must be called from an injection context

Acceptance Criteria

Definition of Done (DoD)

Validation Commands

# Run specific test suite
npx nx test security --testNamePattern="CSRFTokenService"
# Should pass: all tests green, no NG0203 errors

# Run full test suite
npx nx test security
# Should pass: all tests green

Implementation Notes

// ✅ Proper TestBed setup
beforeEach(() => {
  TestBed.configureTestingModule({
    providers: [
      CSRFTokenService,
      {
        provide: LoggerService,
        useValue: {
          debug: vi.fn(),
          info: vi.fn(),
          warn: vi.fn(),
          error: vi.fn()
        }
      },
      {
        provide: ContextService,
        useValue: mockContextService
      }
    ]
  });
});

// ✅ Proper service instantiation in tests
it('should get token for specific tenant', () => {
  TestBed.runInInjectionContext(() => {
    const service = TestBed.inject(CSRFTokenService);
    const token = service.getToken('tenant-123');
    expect(token).toBeDefined();
  });
});

Task 1.5: Full Test Suite Validation 🔴

Priority: Critical Estimate: 2 hours Assignee: TBD Files: All test files in libs/core/security/

Description

Run complete test suite and ensure 100% pass rate after all Phase 1 fixes.

Acceptance Criteria

Definition of Done (DoD)

Validation Commands

# Run all tests
npx nx test security
# Expected: ✅ All tests passing

# Check test coverage
npx nx test security --coverage
# Expected: >= 85% coverage

# Lint check
npx nx lint security
# Expected: ✅ No errors

# Build check
npx nx build security
# Expected: ✅ Build successful

Success Metrics

Test Suites: X passed, X total
Tests:       Y passed, Y total
Coverage:    >= 85%
Duration:    < 3 minutes

Phase 2: High Priority Improvements (Week 2)

Task 2.1: Migrate Directives to Signal Inputs/Outputs 🟡

Priority: High Estimate: 12 hours Assignee: TBD Files: All files in libs/core/security/src/lib/directives/

Description

Migrate all 8 directives from decorator-based @Input()/@Output() to Angular 20 signal-based input()/output().

Affected Directives

  1. has-permission.directive.ts
  2. has-any-permission.directive.ts
  3. has-all-permissions.directive.ts
  4. has-role.directive.ts
  5. has-any-role.directive.ts
  6. has-minimum-role.directive.ts
  7. is-admin.directive.ts
  8. secure-content.directive.ts

Acceptance Criteria

Definition of Done (DoD)

Validation Commands

# Verify no decorator inputs/outputs in directives
grep -r "@Input()\|@Output()" libs/core/security/src/lib/directives/
# Should return: no matches

# Verify signal usage
grep -r "input()\|input\.required()\|output()" libs/core/security/src/lib/directives/
# Should return: matches in all directive files

# Verify OnPush
grep -r "ChangeDetectionStrategy.OnPush" libs/core/security/src/lib/directives/
# Should return: matches in all directive files

# Run tests
npx nx test security --testNamePattern="Directive"
# Should pass: all directive tests green

Migration Pattern

// ❌ Before
@Directive({
  selector: '[hasPermission]',
  standalone: true
})
export class HasPermissionDirective {
  @Input() permission!: string;
  @Input() strict = false;
  @Output() accessDenied = new EventEmitter<void>();

  constructor(
    private authService: AuthService,
    private templateRef: TemplateRef<any>,
    private viewContainer: ViewContainerRef
  ) {}

  ngOnInit() {
    if (this.authService.hasPermission(this.permission)) {
      this.viewContainer.createEmbeddedView(this.templateRef);
    } else {
      this.viewContainer.clear();
      this.accessDenied.emit();
    }
  }
}

// ✅ After
@Directive({
  selector: '[hasPermission]',
  standalone: true,
  changeDetection: ChangeDetectionStrategy.OnPush
})
export class HasPermissionDirective {
  // Signal inputs
  permission = input.required<string>();
  strict = input(false);

  // Signal output
  accessDenied = output<void>();

  // Services
  private authService = inject(AuthService);
  private templateRef = inject(TemplateRef<any>);
  private viewContainer = inject(ViewContainerRef);

  // Computed signal for access check
  hasAccess = computed(() =>
    this.authService.hasPermission(this.permission())
  );

  constructor() {
    // Effect to react to access changes
    effect(() => {
      if (this.hasAccess()) {
        this.viewContainer.createEmbeddedView(this.templateRef);
      } else {
        this.viewContainer.clear();
        this.accessDenied.emit();
      }
    });
  }
}

Task 2.2: Add Performance Monitoring Decorators 🟡

Priority: High Estimate: 4 hours Assignee: TBD Files:

Description

Add @performance decorators from @libs-core/log-system to critical authentication methods.

Target Methods

AuthService:

TokenService:

Acceptance Criteria

Definition of Done (DoD)

Validation Commands

# Verify @performance usage
grep -r "@performance" libs/core/security/src/lib/auth/
# Should return: matches for all target methods

# Run tests
npx nx test security
# Should pass: all tests green

# Manual test: Check logs for performance metrics
# Start dev server and perform login
# Expected: See performance logs like "login completed in 145ms"

Implementation Example

import { performance } from '@libs-core/log-system';

@Injectable({ providedIn: 'root' })
export class AuthService {
  @performance({ threshold: 200, level: 'warn' })
  login(credentials: LoginCredentials): Observable<LoginResult> {
    // ... implementation
  }

  @performance({ threshold: 100, level: 'warn' })
  logout(redirectToLogin = true): Observable<void> {
    // ... implementation
  }

  @performance({ threshold: 150, level: 'warn' })
  refreshAuthentication(): Observable<void> {
    // ... implementation
  }

  @performance({ threshold: 100 })
  selectContext(tenantId: string): Observable<void> {
    // ... implementation
  }

  @performance({ threshold: 100 })
  switchContext(tenantId: string): Observable<void> {
    // ... implementation
  }
}

Performance Thresholds


Task 2.3: Enhance Error Handling 🟡

Priority: High Estimate: 8 hours Assignee: TBD Files:

Description

Implement structured error handling with custom error classes and rich context.

Acceptance Criteria

Custom Error Classes to Create

- SecurityError (base class)
  - AuthenticationError
    - InvalidCredentialsError
    - TokenExpiredError
    - TokenInvalidError
  - AuthorizationError
    - InsufficientPermissionsError
    - TenantAccessDeniedError
  - TokenError
    - TokenRefreshError
    - TokenStorageError
  - ContextError
    - ContextSelectionError
    - ContextSwitchError

Definition of Done (DoD)

Validation Commands

# Verify error classes exist
ls libs/core/security/src/lib/models/errors/
# Should show: security.errors.ts

# Verify error usage
grep -r "throw new.*Error" libs/core/security/src/lib/auth/
# Should show: domain-specific errors

# Run tests
npx nx test security
# Should pass: all tests including error scenarios

Implementation Example

// ❌ Before
catch (error) {
  console.error('Error inicializando tokens:', error);
  return this.clearTokens();
}

// ✅ After
catch (error) {
  const tokenError = new TokenInitializationError(
    'Failed to initialize authentication tokens',
    {
      cause: error,
      operation: 'token_initialization',
      tenantId: this.contextService.getCurrentTenantId(),
      correlationId: this.sessionService.getCorrelationId(),
      recoverable: true
    }
  );

  this.logger.error('Token initialization failed', {
    error: tokenError,
    operation: 'token_initialization',
    tenantId: tokenError.context.tenantId,
    correlationId: tokenError.context.correlationId,
    recoverable: tokenError.context.recoverable
  });

  return this.clearTokens().pipe(
    catchError(() => throwError(() => tokenError))
  );
}

Task 2.4: Add Correlation IDs to All Operations 🟡

Priority: High Estimate: 6 hours Assignee: TBD Files:

Description

Ensure all security operations include correlation IDs for distributed tracing and debugging.

Acceptance Criteria

Definition of Done (DoD)

Validation Commands

# Verify correlation ID generation
grep -r "correlationId.*=.*Date.now()" libs/core/security/src/lib/auth/
# Should return: multiple matches

# Verify correlation ID in logs
grep -r "correlationId:" libs/core/security/src/lib/auth/
# Should return: many matches in log calls

# Run tests
npx nx test security
# Should pass: all tests including correlation ID tests

Implementation Example

login(credentials: LoginCredentials): Observable<LoginResult> {
  const correlationId = `login-${credentials.username}-${Date.now()}`;

  this.logger.info('Login attempt started', {
    operation: 'login',
    correlationId,
    username: credentials.username
  });

  return generateDeviceFingerprint().pipe(
    switchMap((deviceFingerprint) => {
      this.logger.debug('Device fingerprint generated', {
        operation: 'login',
        correlationId
      });

      return this.httpClient.post<LoginResult>(
        this.config.loginEndpoint,
        { ...credentials, deviceFingerprint },
        { headers: { 'X-Correlation-ID': correlationId } }
      );
    }),
    tap(result => {
      this.logger.info('Login successful', {
        operation: 'login',
        correlationId,
        userId: result.user.id
      });
    }),
    catchError(error => {
      this.logger.error('Login failed', {
        operation: 'login',
        correlationId,
        error
      });
      return throwError(() => error);
    })
  );
}

Phase 3: Architecture Improvements (Week 3)

Task 3.1: Evaluate AuthService Split (SRP Analysis) 🟠

Priority: Medium Estimate: 4 hours Assignee: TBD Files: libs/core/security/src/lib/auth/auth.service.ts

Description

Analyze AuthService (883 lines) to determine if it violates Single Responsibility Principle and should be split into smaller services.

Analysis Areas

  1. Authentication Operations (login, logout, refresh)
  2. Authorization Operations (hasPermission, hasRole, etc.)
  3. Context Management (selectContext, switchContext)
  4. Session Management (initialization, monitoring)
  5. Event Management (authentication events)

Acceptance Criteria

Definition of Done (DoD)

Deliverables

  1. Analysis Document: docs/libs/security/adr/001-auth-service-split-analysis.md
  2. Proposed Architecture Diagram
  3. Migration Plan (if split approved)
  4. Breaking Changes List

Decision Criteria


Task 3.2: Implement Service Split (If Approved) 🟠

Priority: Medium (Conditional on Task 3.1) Estimate: 16 hours Assignee: TBD Files: Multiple new service files

Description

If Task 3.1 approves split, implement the new service architecture.

Proposed New Services

  1. AuthenticationService: Login, logout, token operations
  2. AuthorizationService: Permission and role checks
  3. TenantContextService: Context selection and switching
  4. AuthStateService: State management and events

Acceptance Criteria

Definition of Done (DoD)

Validation Commands

# Verify new services exist
ls libs/core/security/src/lib/auth/
# Should show: authentication.service.ts, authorization.service.ts, etc.

# Run all tests
npx nx test security
# Should pass: all tests green

# Verify no breaking changes
npx nx build security
# Should build successfully

Task 3.3: Add Integration Tests for Auth Flows 🟠

Priority: Medium Estimate: 12 hours Assignee: TBD Files: libs/core/security/__tests__/integration/

Description

Create comprehensive integration tests for complex authentication flows.

Test Scenarios

  1. Complete Login Flow

    • Login → Context Selection → Dashboard
    • Multi-tenant user with multiple contexts
  2. Token Refresh Flow

    • Token near expiry → Auto-refresh → Continue operation
  3. Context Switching Flow

    • User switches tenant → New tokens → Updated permissions
  4. Session Timeout Flow

    • User inactive → Warning → Auto-logout
  5. Error Recovery Flow

    • Network error → Retry → Success
    • Invalid token → Refresh → Recover

Acceptance Criteria

Definition of Done (DoD)

Validation Commands

# Run integration tests
npx nx test security --testPathPattern="integration"
# Should pass: all integration tests green

# Check coverage
npx nx test security --coverage
# Should show: >80% coverage for auth flows

Phase 4: Documentation & Polish (Week 4)

Task 4.1: Complete API Documentation 🟢

Priority: Low Estimate: 8 hours Assignee: TBD Files: All service and utility files

Description

Add comprehensive JSDoc comments to all public APIs.

Acceptance Criteria

Definition of Done (DoD)


Task 4.2: Create Usage Examples 🟢

Priority: Low Estimate: 6 hours Assignee: TBD Files: docs/libs/security/examples/

Description

Create practical code examples for common use cases.

Examples to Create

  1. Basic authentication setup
  2. Protected route with guard
  3. Permission-based UI (directives)
  4. Multi-tenant context switching
  5. Custom authorization logic
  6. Error handling patterns
  7. Testing authentication

Definition of Done (DoD)


Task 4.3: Migration Guide (If Breaking Changes) 🟢

Priority: Low (Conditional) Estimate: 4 hours Assignee: TBD Files: docs/libs/security/MIGRATION.md

Description

Create migration guide if Phase 1-3 introduced breaking changes.

Acceptance Criteria

Definition of Done (DoD)


Task 4.4: Final Cleanup & Code Review 🟢

Priority: Low Estimate: 4 hours Assignee: TBD Files: All files in libs/core/security/

Description

Final code review and cleanup before marking improvements complete.

Acceptance Criteria

Definition of Done (DoD)


Summary Checklist

Phase 1 (Week 1) - Critical Fixes

Phase 2 (Week 2) - High Priority

Phase 3 (Week 3) - Architecture

Phase 4 (Week 4) - Documentation


Success Criteria

Code Quality Metrics

Architecture Metrics

Documentation Metrics


Document Version: 1.0 Last Updated: 2025-09-29 Next Review: End of each phase