@acontplus/ng-auth 1.1.6 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -18,8 +18,8 @@ npm install @acontplus/ng-auth
18
18
  - **Session Expiry Handling**: Manages session expiry during HTTP requests with
19
19
  automatic redirection
20
20
  - **CSRF Protection**: Built-in CSRF token management for secure API requests
21
- - **Token Repository**: Secure token storage and retrieval with local storage
22
- support
21
+ - **Token BaseRepository**: Secure token storage and retrieval with local
22
+ storage support
23
23
  - **Authentication Use Cases**: Login, register, refresh token, and logout
24
24
  functionality
25
25
  - **Domain Models**: User domain models and value objects
@@ -37,7 +37,7 @@ sessions expire.
37
37
 
38
38
  ### Components
39
39
 
40
- 1. **UrlRedirectService** - Manages URL storage and redirection logic
40
+ 1. **AuthUrlRedirect** - Manages URL storage and redirection logic
41
41
  2. **Enhanced Auth Guard** - Captures URLs before redirecting to login
42
42
  3. **Enhanced Login Use Case** - Redirects to stored URLs after successful
43
43
  authentication
@@ -63,13 +63,14 @@ const routes: Routes = [
63
63
 
64
64
  ```typescript
65
65
  // app.config.ts
66
- import { authRedirectInterceptor } from '@acontplus/ng-auth';
66
+ import { authRedirectInterceptor, csrfInterceptor } from '@acontplus/ng-auth';
67
67
 
68
68
  export const appConfig: ApplicationConfig = {
69
69
  providers: [
70
70
  provideHttpClient(
71
71
  withInterceptors([
72
72
  authRedirectInterceptor, // Handles session expiry during API calls
73
+ csrfInterceptor, // CSRF protection
73
74
  ]),
74
75
  ),
75
76
  ],
@@ -93,11 +94,11 @@ User on /reports → API Call → 401 Error → Store URL → Login → Success
93
94
  ### Manual Usage
94
95
 
95
96
  ```typescript
96
- import { UrlRedirectService } from '@acontplus/ng-auth';
97
+ import { AuthUrlRedirect } from '@acontplus/ng-auth';
97
98
 
98
99
  @Component({...})
99
100
  export class MyComponent {
100
- constructor(private urlRedirectService: UrlRedirectService) {}
101
+ constructor(private urlRedirectService: AuthUrlRedirect) {}
101
102
 
102
103
  navigateToForm() {
103
104
  // Store current URL before potentially losing session
@@ -157,9 +158,9 @@ styling.
157
158
 
158
159
  ### Core Services
159
160
 
160
- - **UrlRedirectService**: URL storage and redirection management
161
- - **CsrfService**: CSRF token management for secure API requests
162
- - **TokenRepository**: Secure token storage and retrieval
161
+ - **AuthUrlRedirect**: URL storage and redirection management
162
+ - **CsrfApi**: CSRF token management for secure API requests
163
+ - **AuthTokenRepositoryImpl**: Secure token storage and retrieval
163
164
 
164
165
  ### Guards and Interceptors
165
166
 
@@ -201,11 +202,11 @@ export class MyComponent {
201
202
  ### CSRF Protection
202
203
 
203
204
  ```typescript
204
- import { CsrfService } from '@acontplus/ng-auth';
205
+ import { CsrfApi } from '@acontplus/ng-auth';
205
206
 
206
207
  @Component({...})
207
- export class LoginComponent {
208
- constructor(private csrfService: CsrfService) {}
208
+ export class Login {
209
+ constructor(private csrfService: CsrfApi) {}
209
210
 
210
211
  async login(credentials: LoginCredentials) {
211
212
  const csrfToken = await this.csrfService.getCsrfToken();
@@ -259,25 +260,21 @@ import { authProviders } from '@acontplus/ng-auth';
259
260
  export class AppModule {}
260
261
  ```
261
262
 
262
- ## Running unit tests
263
-
264
- Run `nx test ng-auth` to execute the unit tests.
265
-
266
263
  ## Login Component
267
264
 
268
- The `LoginComponent` provides a flexible, themeable authentication UI component
269
- with support for custom fields and dynamic content.
265
+ The `Login` provides a flexible, themeable authentication UI component with
266
+ support for custom fields and dynamic content.
270
267
 
271
268
  ### Basic Usage
272
269
 
273
270
  ```typescript
274
- import { LoginComponent } from '@acontplus/ng-auth/ui/login';
271
+ import { Login } from '@acontplus/ng-auth/ui/login';
275
272
 
276
273
  @Component({
277
274
  template: `
278
275
  <acp-login title="Welcome Back" [showRegisterButton]="true"> </acp-login>
279
276
  `,
280
- imports: [LoginComponent],
277
+ imports: [Login],
281
278
  })
282
279
  export class AuthPageComponent {}
283
280
  ```
@@ -1,13 +1,13 @@
1
- import { BaseUseCase, TOKEN_PROVIDER, LoggingService } from '@acontplus/ng-infrastructure';
2
- export { TOKEN_PROVIDER } from '@acontplus/ng-infrastructure';
1
+ import { ENVIRONMENT, AUTH_API, AUTH_TOKEN } from '@acontplus/ng-config';
2
+ export { AUTH_TOKEN } from '@acontplus/ng-config';
3
3
  import * as i0 from '@angular/core';
4
4
  import { inject, PLATFORM_ID, Injectable, NgZone, signal, input, computed, ViewEncapsulation, ChangeDetectionStrategy, Component } from '@angular/core';
5
5
  import { Router } from '@angular/router';
6
6
  import { of, tap, catchError, throwError, firstValueFrom, map, from } from 'rxjs';
7
+ import { BaseUseCase, LoggingService } from '@acontplus/ng-infrastructure';
7
8
  import * as i1 from '@angular/common';
8
9
  import { isPlatformBrowser, DOCUMENT, CommonModule } from '@angular/common';
9
10
  import { jwtDecode } from 'jwt-decode';
10
- import { ENVIRONMENT, AUTH_API } from '@acontplus/ng-config';
11
11
  import { HttpClient, HttpContextToken } from '@angular/common/http';
12
12
  import { catchError as catchError$1, switchMap } from 'rxjs/operators';
13
13
  import * as i2 from '@angular/forms';
@@ -22,7 +22,7 @@ import { MatCheckbox } from '@angular/material/checkbox';
22
22
  class AuthRepository {
23
23
  }
24
24
 
25
- class TokenRepository {
25
+ class AuthTokenRepositoryImpl {
26
26
  environment = inject(ENVIRONMENT);
27
27
  platformId = inject(PLATFORM_ID);
28
28
  saveTokens(tokens, rememberMe = false) {
@@ -191,20 +191,20 @@ class TokenRepository {
191
191
  }
192
192
  return undefined;
193
193
  }
194
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.2", ngImport: i0, type: TokenRepository, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
195
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.2", ngImport: i0, type: TokenRepository, providedIn: 'root' });
194
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: AuthTokenRepositoryImpl, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
195
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: AuthTokenRepositoryImpl, providedIn: 'root' });
196
196
  }
197
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.2", ngImport: i0, type: TokenRepository, decorators: [{
197
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: AuthTokenRepositoryImpl, decorators: [{
198
198
  type: Injectable,
199
199
  args: [{
200
200
  providedIn: 'root',
201
201
  }]
202
202
  }] });
203
203
 
204
- // src/lib/presentation/stores/auth.store.ts
204
+ // src/lib/presentation/stores/auth-store.ts
205
205
  class AuthStore {
206
206
  authRepository = inject(AuthRepository);
207
- tokenRepository = inject(TokenRepository);
207
+ tokenRepository = inject(AuthTokenRepositoryImpl);
208
208
  router = inject(Router);
209
209
  ngZone = inject(NgZone);
210
210
  // Authentication state signals
@@ -398,10 +398,10 @@ class AuthStore {
398
398
  ngOnDestroy() {
399
399
  this.stopTokenRefreshTimer();
400
400
  }
401
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.2", ngImport: i0, type: AuthStore, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
402
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.2", ngImport: i0, type: AuthStore, providedIn: 'root' });
401
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: AuthStore, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
402
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: AuthStore, providedIn: 'root' });
403
403
  }
404
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.2", ngImport: i0, type: AuthStore, decorators: [{
404
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: AuthStore, decorators: [{
405
405
  type: Injectable,
406
406
  args: [{
407
407
  providedIn: 'root',
@@ -413,7 +413,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.2", ngImpor
413
413
  * Stores the intended URL when session is lost and redirects to it after successful login
414
414
  * SSR-compatible by checking platform before accessing sessionStorage
415
415
  */
416
- class UrlRedirectService {
416
+ class AuthUrlRedirect {
417
417
  REDIRECT_URL_KEY = 'acp_redirect_url';
418
418
  EXCLUDED_ROUTES = [
419
419
  '/login',
@@ -517,22 +517,22 @@ class UrlRedirectService {
517
517
  return null;
518
518
  }
519
519
  }
520
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.2", ngImport: i0, type: UrlRedirectService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
521
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.2", ngImport: i0, type: UrlRedirectService, providedIn: 'root' });
520
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: AuthUrlRedirect, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
521
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: AuthUrlRedirect, providedIn: 'root' });
522
522
  }
523
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.2", ngImport: i0, type: UrlRedirectService, decorators: [{
523
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: AuthUrlRedirect, decorators: [{
524
524
  type: Injectable,
525
525
  args: [{
526
526
  providedIn: 'root',
527
527
  }]
528
528
  }] });
529
529
 
530
- // src/lib/application/use-cases/login.use-case.ts
530
+ // src/lib/application/use-cases/login-use-case.ts
531
531
  class LoginUseCase extends BaseUseCase {
532
532
  authRepository = inject(AuthRepository);
533
533
  authStore = inject(AuthStore);
534
534
  router = inject(Router);
535
- urlRedirectService = inject(UrlRedirectService);
535
+ urlRedirectService = inject(AuthUrlRedirect);
536
536
  execute(request) {
537
537
  return this.authRepository.login(request).pipe(tap(tokens => {
538
538
  // Set authentication state with rememberMe preference
@@ -541,17 +541,17 @@ class LoginUseCase extends BaseUseCase {
541
541
  this.urlRedirectService.redirectToIntendedUrl('/');
542
542
  }));
543
543
  }
544
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.2", ngImport: i0, type: LoginUseCase, deps: null, target: i0.ɵɵFactoryTarget.Injectable });
545
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.2", ngImport: i0, type: LoginUseCase, providedIn: 'root' });
544
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: LoginUseCase, deps: null, target: i0.ɵɵFactoryTarget.Injectable });
545
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: LoginUseCase, providedIn: 'root' });
546
546
  }
547
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.2", ngImport: i0, type: LoginUseCase, decorators: [{
547
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: LoginUseCase, decorators: [{
548
548
  type: Injectable,
549
549
  args: [{
550
550
  providedIn: 'root',
551
551
  }]
552
552
  }] });
553
553
 
554
- // src/lib/application/use-cases/register.use-case.ts
554
+ // src/lib/application/use-cases/register-use-case.ts
555
555
  class RegisterUseCase extends BaseUseCase {
556
556
  authRepository = inject(AuthRepository);
557
557
  authStore = inject(AuthStore);
@@ -564,20 +564,20 @@ class RegisterUseCase extends BaseUseCase {
564
564
  this.router.navigate(['/']);
565
565
  }));
566
566
  }
567
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.2", ngImport: i0, type: RegisterUseCase, deps: null, target: i0.ɵɵFactoryTarget.Injectable });
568
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.2", ngImport: i0, type: RegisterUseCase, providedIn: 'root' });
567
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: RegisterUseCase, deps: null, target: i0.ɵɵFactoryTarget.Injectable });
568
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: RegisterUseCase, providedIn: 'root' });
569
569
  }
570
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.2", ngImport: i0, type: RegisterUseCase, decorators: [{
570
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: RegisterUseCase, decorators: [{
571
571
  type: Injectable,
572
572
  args: [{
573
573
  providedIn: 'root',
574
574
  }]
575
575
  }] });
576
576
 
577
- // src/lib/application/use-cases/refresh-token.use-case.ts
577
+ // src/lib/application/use-cases/refresh-token-use-case.ts
578
578
  class RefreshTokenUseCase extends BaseUseCase {
579
579
  authRepository = inject(AuthRepository);
580
- tokenRepository = inject(TokenRepository);
580
+ tokenRepository = inject(AuthTokenRepositoryImpl);
581
581
  authStore = inject(AuthStore);
582
582
  execute() {
583
583
  const userData = this.tokenRepository.getUserData();
@@ -601,20 +601,20 @@ class RefreshTokenUseCase extends BaseUseCase {
601
601
  return throwError(() => error);
602
602
  }));
603
603
  }
604
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.2", ngImport: i0, type: RefreshTokenUseCase, deps: null, target: i0.ɵɵFactoryTarget.Injectable });
605
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.2", ngImport: i0, type: RefreshTokenUseCase, providedIn: 'root' });
604
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: RefreshTokenUseCase, deps: null, target: i0.ɵɵFactoryTarget.Injectable });
605
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: RefreshTokenUseCase, providedIn: 'root' });
606
606
  }
607
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.2", ngImport: i0, type: RefreshTokenUseCase, decorators: [{
607
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: RefreshTokenUseCase, decorators: [{
608
608
  type: Injectable,
609
609
  args: [{
610
610
  providedIn: 'root',
611
611
  }]
612
612
  }] });
613
613
 
614
- // src/lib/application/use-cases/logout.use-case.ts
614
+ // src/lib/application/use-cases/logout-use-case.ts
615
615
  class LogoutUseCase extends BaseUseCase {
616
616
  authRepository = inject(AuthRepository);
617
- tokenRepository = inject(TokenRepository);
617
+ tokenRepository = inject(AuthTokenRepositoryImpl);
618
618
  authStore = inject(AuthStore);
619
619
  execute() {
620
620
  const userData = this.tokenRepository.getUserData();
@@ -631,10 +631,10 @@ class LogoutUseCase extends BaseUseCase {
631
631
  // Use auth store for centralized logout
632
632
  this.authStore.logout();
633
633
  }
634
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.2", ngImport: i0, type: LogoutUseCase, deps: null, target: i0.ɵɵFactoryTarget.Injectable });
635
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.2", ngImport: i0, type: LogoutUseCase, providedIn: 'root' });
634
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: LogoutUseCase, deps: null, target: i0.ɵɵFactoryTarget.Injectable });
635
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: LogoutUseCase, providedIn: 'root' });
636
636
  }
637
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.2", ngImport: i0, type: LogoutUseCase, decorators: [{
637
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: LogoutUseCase, decorators: [{
638
638
  type: Injectable,
639
639
  args: [{
640
640
  providedIn: 'root',
@@ -645,7 +645,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.2", ngImpor
645
645
 
646
646
  // src/lib/application/index.ts
647
647
 
648
- // src/lib/data/repositories/auth-http.repository.ts
648
+ // src/lib/data/repositories/auth-http.base-repository.ts
649
649
  function getDeviceInfo() {
650
650
  return `${navigator.platform ?? 'Unknown'} - ${navigator.userAgent}`;
651
651
  }
@@ -682,10 +682,10 @@ class AuthHttpRepository extends AuthRepository {
682
682
  withCredentials: true, // Ensure cookies are sent
683
683
  });
684
684
  }
685
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.2", ngImport: i0, type: AuthHttpRepository, deps: null, target: i0.ɵɵFactoryTarget.Injectable });
686
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.2", ngImport: i0, type: AuthHttpRepository, providedIn: 'root' });
685
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: AuthHttpRepository, deps: null, target: i0.ɵɵFactoryTarget.Injectable });
686
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: AuthHttpRepository, providedIn: 'root' });
687
687
  }
688
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.2", ngImport: i0, type: AuthHttpRepository, decorators: [{
688
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: AuthHttpRepository, decorators: [{
689
689
  type: Injectable,
690
690
  args: [{
691
691
  providedIn: 'root',
@@ -696,18 +696,16 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.2", ngImpor
696
696
 
697
697
  // src/lib/data/index.ts
698
698
 
699
- // src/lib/domain/models/auth.ts
700
-
701
- // src/lib/domain/models/index.ts
699
+ // src/lib/domain/repositories/auth.ts
702
700
 
703
701
  // src/lib/domain/repositories/index.ts
704
702
 
705
- // src/lib/domain/index.ts
703
+ // src/lib/domain/repositories/index.ts
706
704
 
707
705
  const authGuard = (_route, state) => {
708
- const tokenRepository = inject(TokenRepository);
706
+ const tokenRepository = inject(AuthTokenRepositoryImpl);
709
707
  const router = inject(Router);
710
- const urlRedirectService = inject(UrlRedirectService);
708
+ const urlRedirectService = inject(AuthUrlRedirect);
711
709
  const environment = inject(ENVIRONMENT);
712
710
  if (tokenRepository.isAuthenticated()) {
713
711
  return true;
@@ -725,8 +723,8 @@ const authGuard = (_route, state) => {
725
723
  */
726
724
  const authRedirectInterceptor = (req, next) => {
727
725
  const router = inject(Router);
728
- const urlRedirectService = inject(UrlRedirectService);
729
- const tokenRepository = inject(TokenRepository);
726
+ const urlRedirectService = inject(AuthUrlRedirect);
727
+ const tokenRepository = inject(AuthTokenRepositoryImpl);
730
728
  const environment = inject(ENVIRONMENT);
731
729
  return next(req).pipe(catchError$1((error) => {
732
730
  // Handle 401 Unauthorized errors
@@ -745,8 +743,8 @@ const authRedirectInterceptor = (req, next) => {
745
743
  }));
746
744
  };
747
745
 
748
- // src/lib/services/csrf.service.ts
749
- class CsrfService {
746
+ // src/lib/services/csrf-api.ts
747
+ class CsrfApi {
750
748
  http = inject(HttpClient);
751
749
  csrfToken = null;
752
750
  /**
@@ -774,10 +772,10 @@ class CsrfService {
774
772
  clearCsrfToken() {
775
773
  this.csrfToken = null;
776
774
  }
777
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.2", ngImport: i0, type: CsrfService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
778
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.2", ngImport: i0, type: CsrfService, providedIn: 'root' });
775
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: CsrfApi, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
776
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: CsrfApi, providedIn: 'root' });
779
777
  }
780
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.2", ngImport: i0, type: CsrfService, decorators: [{
778
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: CsrfApi, decorators: [{
781
779
  type: Injectable,
782
780
  args: [{
783
781
  providedIn: 'root',
@@ -791,7 +789,7 @@ const SKIP_CSRF = new HttpContextToken(() => false);
791
789
  * Only applies to requests to the same origin to avoid leaking tokens to external APIs
792
790
  */
793
791
  const csrfInterceptor = (req, next) => {
794
- const csrfService = inject(CsrfService);
792
+ const csrfService = inject(CsrfApi);
795
793
  // Check if CSRF should be skipped for this request
796
794
  const skipCsrf = req.context.get(SKIP_CSRF);
797
795
  if (skipCsrf) {
@@ -834,8 +832,8 @@ const authProviders = [
834
832
  useClass: AuthHttpRepository,
835
833
  },
836
834
  {
837
- provide: TOKEN_PROVIDER,
838
- useClass: TokenRepository,
835
+ provide: AUTH_TOKEN,
836
+ useClass: AuthTokenRepositoryImpl,
839
837
  },
840
838
  ];
841
839
 
@@ -843,8 +841,8 @@ const authProviders = [
843
841
 
844
842
  // src/lib/presentation/stores/index.ts
845
843
 
846
- // src/lib/presentation/components/login/login.component.ts
847
- class LoginComponent {
844
+ // src/lib/presentation/components/login/login.ts
845
+ class Login {
848
846
  title = input('Login', ...(ngDevMode ? [{ debugName: "title" }] : []));
849
847
  showRegisterButton = input(true, ...(ngDevMode ? [{ debugName: "showRegisterButton" }] : []));
850
848
  showRememberMe = input(true, ...(ngDevMode ? [{ debugName: "showRememberMe" }] : []));
@@ -940,10 +938,10 @@ class LoginComponent {
940
938
  });
941
939
  }
942
940
  }
943
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.2", ngImport: i0, type: LoginComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
944
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.2", type: LoginComponent, isStandalone: true, selector: "acp-login", inputs: { title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, showRegisterButton: { classPropertyName: "showRegisterButton", publicName: "showRegisterButton", isSignal: true, isRequired: false, transformFunction: null }, showRememberMe: { classPropertyName: "showRememberMe", publicName: "showRememberMe", isSignal: true, isRequired: false, transformFunction: null }, additionalSigninControls: { classPropertyName: "additionalSigninControls", publicName: "additionalSigninControls", isSignal: true, isRequired: false, transformFunction: null }, additionalSignupControls: { classPropertyName: "additionalSignupControls", publicName: "additionalSignupControls", isSignal: true, isRequired: false, transformFunction: null }, additionalSigninFields: { classPropertyName: "additionalSigninFields", publicName: "additionalSigninFields", isSignal: true, isRequired: false, transformFunction: null }, additionalSignupFields: { classPropertyName: "additionalSignupFields", publicName: "additionalSignupFields", isSignal: true, isRequired: false, transformFunction: null }, footerContent: { classPropertyName: "footerContent", publicName: "footerContent", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<mat-card class=\"mat-elevation-z8 p-4 rounded\">\n <mat-card-header>\n <mat-card-title class=\"text-center\">{{ title() }}</mat-card-title>\n </mat-card-header>\n <mat-card-content>\n @if (isLoginMode()) {\n <form [formGroup]=\"signinForm\" (ngSubmit)=\"signIn()\" class=\"d-flex flex-column gap-3\">\n <mat-form-field class=\"w-100\">\n <mat-label>Usuario</mat-label>\n <input matInput type=\"text\" placeholder=\"Ingrese su usuario\" formControlName=\"email\" />\n </mat-form-field>\n\n <mat-form-field class=\"w-100\">\n <mat-label>Contrase\u00F1a</mat-label>\n <input\n matInput\n type=\"password\"\n placeholder=\"Ingrese su contrase\u00F1a\"\n formControlName=\"password\"\n autocomplete=\"current-password\"\n />\n </mat-form-field>\n\n <!-- Remember Me checkbox - conditional -->\n @if (showRememberMe()) {\n <div class=\"d-flex align-items-center mt-2\">\n <mat-checkbox formControlName=\"rememberMe\"> Recordarme </mat-checkbox>\n </div>\n }\n\n <!-- Additional signin fields -->\n <ng-container *ngTemplateOutlet=\"additionalSigninFields()\"></ng-container>\n\n <div class=\"d-flex justify-content-center mt-3\">\n <button\n mat-raised-button\n color=\"primary\"\n [disabled]=\"!signinForm.valid || isLoading()\"\n type=\"submit\"\n class=\"w-100\"\n >\n @if (isLoading()) {\n Ingresando...\n } @else {\n <ng-container>Ingresar <mat-icon>login</mat-icon></ng-container>\n }\n </button>\n </div>\n\n <div class=\"text-center mt-2\">\n @if (showRegisterButton()) {\n <button mat-button type=\"button\" (click)=\"switchMode()\">\n \u00BFNo tienes cuenta? Reg\u00EDstrate\n </button>\n }\n </div>\n </form>\n } @else {\n <form [formGroup]=\"signupForm\" (ngSubmit)=\"registerUser()\" class=\"d-flex flex-column gap-3\">\n <mat-form-field class=\"w-100\">\n <mat-label>Nombre</mat-label>\n <input\n matInput\n type=\"text\"\n placeholder=\"Ingrese su nombre\"\n formControlName=\"displayName\"\n />\n </mat-form-field>\n\n <mat-form-field class=\"w-100\">\n <mat-label>Email</mat-label>\n <input matInput type=\"email\" placeholder=\"Ingrese su email\" formControlName=\"email\" />\n </mat-form-field>\n\n <mat-form-field class=\"w-100\">\n <mat-label>Contrase\u00F1a</mat-label>\n <input\n matInput\n type=\"password\"\n placeholder=\"Ingrese su contrase\u00F1a\"\n formControlName=\"password\"\n autocomplete=\"new-password\"\n />\n </mat-form-field>\n\n <!-- Additional signup fields -->\n <ng-container *ngTemplateOutlet=\"additionalSignupFields()\"></ng-container>\n\n <div class=\"d-flex justify-content-center mt-3\">\n <button\n mat-raised-button\n color=\"primary\"\n [disabled]=\"!signupForm.valid || isLoading()\"\n type=\"submit\"\n class=\"w-100\"\n >\n @if (isLoading()) {\n Registrando...\n } @else {\n <ng-container>Registrarse <mat-icon>person_add</mat-icon></ng-container>\n }\n </button>\n </div>\n\n <div class=\"text-center mt-2\">\n <button mat-button type=\"button\" (click)=\"switchMode()\">\n \u00BFYa tienes cuenta? Inicia sesi\u00F3n\n </button>\n </div>\n </form>\n }\n @if (errorMessage()) {\n <div class=\"alert alert-danger mt-3\" role=\"alert\">\n {{ errorMessage() }}\n </div>\n }\n </mat-card-content>\n @if (hasFooterContent()) {\n <mat-card-footer>\n <ng-container *ngTemplateOutlet=\"footerContent()\"></ng-container>\n </mat-card-footer>\n }\n</mat-card>\n", styles: [":host{display:flex;justify-content:center;align-items:center;min-height:100vh;width:100%;padding:16px;box-sizing:border-box}:host mat-card{width:100%;max-width:400px;border-radius:12px;box-shadow:0 8px 32px #0000001a}:host mat-card-header{text-align:center;margin-bottom:20px}:host mat-card-title{font-size:24px;font-weight:600;color:var(--mat-sys-primary, #6750a4)}:host mat-form-field{width:100%}:host mat-button{border-radius:8px}:host .w-100{width:100%}:host .d-flex{display:flex}:host .flex-column{flex-direction:column}:host .gap-3{gap:12px}:host .justify-content-center{justify-content:center}:host .align-items-center{align-items:center}:host .mt-3{margin-top:12px}:host .mt-2{margin-top:8px}:host .text-center{text-align:center}:host .p-4{padding:16px}:host .rounded{border-radius:12px}:host .m-t-10{margin-top:10px}:host .alert-danger{background-color:var(--mat-sys-error-container, #ffdad6);border-color:var(--mat-sys-error, #ba1a1a);color:var(--mat-sys-on-error-container, #410002);padding:12px;border-radius:4px;border:1px solid transparent}:host .row{display:flex;flex-wrap:wrap;margin:0 -15px}:host .col-xs-12,:host .col-sm-12,:host .col-md-12{flex:0 0 100%;max-width:100%;padding:0 15px}:host .social{display:flex;justify-content:center}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i2.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: MatCard, selector: "mat-card", inputs: ["appearance"], exportAs: ["matCard"] }, { kind: "component", type: MatCardHeader, selector: "mat-card-header" }, { kind: "directive", type: MatLabel, selector: "mat-label" }, { kind: "directive", type: MatCardTitle, selector: "mat-card-title, [mat-card-title], [matCardTitle]" }, { kind: "directive", type: MatCardContent, selector: "mat-card-content" }, { kind: "component", type: MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "directive", type: MatCardFooter, selector: "mat-card-footer" }, { kind: "component", type: MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "aria-expanded", "aria-controls", "aria-owns", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "disabledInteractive", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
941
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: Login, deps: [], target: i0.ɵɵFactoryTarget.Component });
942
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.4", type: Login, isStandalone: true, selector: "acp-login", inputs: { title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, showRegisterButton: { classPropertyName: "showRegisterButton", publicName: "showRegisterButton", isSignal: true, isRequired: false, transformFunction: null }, showRememberMe: { classPropertyName: "showRememberMe", publicName: "showRememberMe", isSignal: true, isRequired: false, transformFunction: null }, additionalSigninControls: { classPropertyName: "additionalSigninControls", publicName: "additionalSigninControls", isSignal: true, isRequired: false, transformFunction: null }, additionalSignupControls: { classPropertyName: "additionalSignupControls", publicName: "additionalSignupControls", isSignal: true, isRequired: false, transformFunction: null }, additionalSigninFields: { classPropertyName: "additionalSigninFields", publicName: "additionalSigninFields", isSignal: true, isRequired: false, transformFunction: null }, additionalSignupFields: { classPropertyName: "additionalSignupFields", publicName: "additionalSignupFields", isSignal: true, isRequired: false, transformFunction: null }, footerContent: { classPropertyName: "footerContent", publicName: "footerContent", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<mat-card class=\"mat-elevation-z8 p-4 rounded\">\n <mat-card-header>\n <mat-card-title class=\"text-center\">{{ title() }}</mat-card-title>\n </mat-card-header>\n <mat-card-content>\n @if (isLoginMode()) {\n <form [formGroup]=\"signinForm\" (ngSubmit)=\"signIn()\" class=\"d-flex flex-column gap-3\">\n <mat-form-field class=\"w-100\">\n <mat-label>Usuario</mat-label>\n <input matInput type=\"text\" placeholder=\"Ingrese su usuario\" formControlName=\"email\" />\n </mat-form-field>\n\n <mat-form-field class=\"w-100\">\n <mat-label>Contrase\u00F1a</mat-label>\n <input\n matInput\n type=\"password\"\n placeholder=\"Ingrese su contrase\u00F1a\"\n formControlName=\"password\"\n autocomplete=\"current-password\"\n />\n </mat-form-field>\n\n <!-- Remember Me checkbox - conditional -->\n @if (showRememberMe()) {\n <div class=\"d-flex align-items-center mt-2\">\n <mat-checkbox formControlName=\"rememberMe\"> Recordarme </mat-checkbox>\n </div>\n }\n\n <!-- Additional signin fields -->\n <ng-container *ngTemplateOutlet=\"additionalSigninFields()\"></ng-container>\n\n <div class=\"d-flex justify-content-center mt-3\">\n <button\n mat-raised-button\n color=\"primary\"\n [disabled]=\"!signinForm.valid || isLoading()\"\n type=\"submit\"\n class=\"w-100\"\n >\n @if (isLoading()) { Ingresando... } @else {\n <ng-container>Ingresar <mat-icon>login</mat-icon></ng-container>\n }\n </button>\n </div>\n\n <div class=\"text-center mt-2\">\n @if (showRegisterButton()) {\n <button mat-button type=\"button\" (click)=\"switchMode()\">\n \u00BFNo tienes cuenta? Reg\u00EDstrate\n </button>\n }\n </div>\n </form>\n } @else {\n <form [formGroup]=\"signupForm\" (ngSubmit)=\"registerUser()\" class=\"d-flex flex-column gap-3\">\n <mat-form-field class=\"w-100\">\n <mat-label>Nombre</mat-label>\n <input matInput type=\"text\" placeholder=\"Ingrese su nombre\" formControlName=\"displayName\" />\n </mat-form-field>\n\n <mat-form-field class=\"w-100\">\n <mat-label>Email</mat-label>\n <input matInput type=\"email\" placeholder=\"Ingrese su email\" formControlName=\"email\" />\n </mat-form-field>\n\n <mat-form-field class=\"w-100\">\n <mat-label>Contrase\u00F1a</mat-label>\n <input\n matInput\n type=\"password\"\n placeholder=\"Ingrese su contrase\u00F1a\"\n formControlName=\"password\"\n autocomplete=\"new-password\"\n />\n </mat-form-field>\n\n <!-- Additional signup fields -->\n <ng-container *ngTemplateOutlet=\"additionalSignupFields()\"></ng-container>\n\n <div class=\"d-flex justify-content-center mt-3\">\n <button\n mat-raised-button\n color=\"primary\"\n [disabled]=\"!signupForm.valid || isLoading()\"\n type=\"submit\"\n class=\"w-100\"\n >\n @if (isLoading()) { Registrando... } @else {\n <ng-container>Registrarse <mat-icon>person_add</mat-icon></ng-container>\n }\n </button>\n </div>\n\n <div class=\"text-center mt-2\">\n <button mat-button type=\"button\" (click)=\"switchMode()\">\n \u00BFYa tienes cuenta? Inicia sesi\u00F3n\n </button>\n </div>\n </form>\n } @if (errorMessage()) {\n <div class=\"alert alert-danger mt-3\" role=\"alert\">{{ errorMessage() }}</div>\n }\n </mat-card-content>\n @if (hasFooterContent()) {\n <mat-card-footer>\n <ng-container *ngTemplateOutlet=\"footerContent()\"></ng-container>\n </mat-card-footer>\n }\n</mat-card>\n", styles: [":host{display:flex;justify-content:center;align-items:center;min-height:100vh;width:100%;padding:16px;box-sizing:border-box}:host mat-card{width:100%;max-width:400px;border-radius:12px;box-shadow:0 8px 32px #0000001a}:host mat-card-header{text-align:center;margin-bottom:20px}:host mat-card-title{font-size:24px;font-weight:600;color:var(--mat-sys-primary, #6750a4)}:host mat-form-field{width:100%}:host mat-button{border-radius:8px}:host .w-100{width:100%}:host .d-flex{display:flex}:host .flex-column{flex-direction:column}:host .gap-3{gap:12px}:host .justify-content-center{justify-content:center}:host .align-items-center{align-items:center}:host .mt-3{margin-top:12px}:host .mt-2{margin-top:8px}:host .text-center{text-align:center}:host .p-4{padding:16px}:host .rounded{border-radius:12px}:host .m-t-10{margin-top:10px}:host .alert-danger{background-color:var(--mat-sys-error-container, #ffdad6);border-color:var(--mat-sys-error, #ba1a1a);color:var(--mat-sys-on-error-container, #410002);padding:12px;border-radius:4px;border:1px solid transparent}:host .row{display:flex;flex-wrap:wrap;margin:0 -15px}:host .col-xs-12,:host .col-sm-12,:host .col-md-12{flex:0 0 100%;max-width:100%;padding:0 15px}:host .social{display:flex;justify-content:center}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i2.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: MatCard, selector: "mat-card", inputs: ["appearance"], exportAs: ["matCard"] }, { kind: "component", type: MatCardHeader, selector: "mat-card-header" }, { kind: "directive", type: MatLabel, selector: "mat-label" }, { kind: "directive", type: MatCardTitle, selector: "mat-card-title, [mat-card-title], [matCardTitle]" }, { kind: "directive", type: MatCardContent, selector: "mat-card-content" }, { kind: "component", type: MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "directive", type: MatCardFooter, selector: "mat-card-footer" }, { kind: "component", type: MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "aria-expanded", "aria-controls", "aria-owns", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "disabledInteractive", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
945
943
  }
946
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.2", ngImport: i0, type: LoginComponent, decorators: [{
944
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: Login, decorators: [{
947
945
  type: Component,
948
946
  args: [{ selector: 'acp-login', imports: [
949
947
  CommonModule,
@@ -960,7 +958,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.2", ngImpor
960
958
  MatCardFooter,
961
959
  MatAnchor,
962
960
  MatCheckbox,
963
- ], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: "<mat-card class=\"mat-elevation-z8 p-4 rounded\">\n <mat-card-header>\n <mat-card-title class=\"text-center\">{{ title() }}</mat-card-title>\n </mat-card-header>\n <mat-card-content>\n @if (isLoginMode()) {\n <form [formGroup]=\"signinForm\" (ngSubmit)=\"signIn()\" class=\"d-flex flex-column gap-3\">\n <mat-form-field class=\"w-100\">\n <mat-label>Usuario</mat-label>\n <input matInput type=\"text\" placeholder=\"Ingrese su usuario\" formControlName=\"email\" />\n </mat-form-field>\n\n <mat-form-field class=\"w-100\">\n <mat-label>Contrase\u00F1a</mat-label>\n <input\n matInput\n type=\"password\"\n placeholder=\"Ingrese su contrase\u00F1a\"\n formControlName=\"password\"\n autocomplete=\"current-password\"\n />\n </mat-form-field>\n\n <!-- Remember Me checkbox - conditional -->\n @if (showRememberMe()) {\n <div class=\"d-flex align-items-center mt-2\">\n <mat-checkbox formControlName=\"rememberMe\"> Recordarme </mat-checkbox>\n </div>\n }\n\n <!-- Additional signin fields -->\n <ng-container *ngTemplateOutlet=\"additionalSigninFields()\"></ng-container>\n\n <div class=\"d-flex justify-content-center mt-3\">\n <button\n mat-raised-button\n color=\"primary\"\n [disabled]=\"!signinForm.valid || isLoading()\"\n type=\"submit\"\n class=\"w-100\"\n >\n @if (isLoading()) {\n Ingresando...\n } @else {\n <ng-container>Ingresar <mat-icon>login</mat-icon></ng-container>\n }\n </button>\n </div>\n\n <div class=\"text-center mt-2\">\n @if (showRegisterButton()) {\n <button mat-button type=\"button\" (click)=\"switchMode()\">\n \u00BFNo tienes cuenta? Reg\u00EDstrate\n </button>\n }\n </div>\n </form>\n } @else {\n <form [formGroup]=\"signupForm\" (ngSubmit)=\"registerUser()\" class=\"d-flex flex-column gap-3\">\n <mat-form-field class=\"w-100\">\n <mat-label>Nombre</mat-label>\n <input\n matInput\n type=\"text\"\n placeholder=\"Ingrese su nombre\"\n formControlName=\"displayName\"\n />\n </mat-form-field>\n\n <mat-form-field class=\"w-100\">\n <mat-label>Email</mat-label>\n <input matInput type=\"email\" placeholder=\"Ingrese su email\" formControlName=\"email\" />\n </mat-form-field>\n\n <mat-form-field class=\"w-100\">\n <mat-label>Contrase\u00F1a</mat-label>\n <input\n matInput\n type=\"password\"\n placeholder=\"Ingrese su contrase\u00F1a\"\n formControlName=\"password\"\n autocomplete=\"new-password\"\n />\n </mat-form-field>\n\n <!-- Additional signup fields -->\n <ng-container *ngTemplateOutlet=\"additionalSignupFields()\"></ng-container>\n\n <div class=\"d-flex justify-content-center mt-3\">\n <button\n mat-raised-button\n color=\"primary\"\n [disabled]=\"!signupForm.valid || isLoading()\"\n type=\"submit\"\n class=\"w-100\"\n >\n @if (isLoading()) {\n Registrando...\n } @else {\n <ng-container>Registrarse <mat-icon>person_add</mat-icon></ng-container>\n }\n </button>\n </div>\n\n <div class=\"text-center mt-2\">\n <button mat-button type=\"button\" (click)=\"switchMode()\">\n \u00BFYa tienes cuenta? Inicia sesi\u00F3n\n </button>\n </div>\n </form>\n }\n @if (errorMessage()) {\n <div class=\"alert alert-danger mt-3\" role=\"alert\">\n {{ errorMessage() }}\n </div>\n }\n </mat-card-content>\n @if (hasFooterContent()) {\n <mat-card-footer>\n <ng-container *ngTemplateOutlet=\"footerContent()\"></ng-container>\n </mat-card-footer>\n }\n</mat-card>\n", styles: [":host{display:flex;justify-content:center;align-items:center;min-height:100vh;width:100%;padding:16px;box-sizing:border-box}:host mat-card{width:100%;max-width:400px;border-radius:12px;box-shadow:0 8px 32px #0000001a}:host mat-card-header{text-align:center;margin-bottom:20px}:host mat-card-title{font-size:24px;font-weight:600;color:var(--mat-sys-primary, #6750a4)}:host mat-form-field{width:100%}:host mat-button{border-radius:8px}:host .w-100{width:100%}:host .d-flex{display:flex}:host .flex-column{flex-direction:column}:host .gap-3{gap:12px}:host .justify-content-center{justify-content:center}:host .align-items-center{align-items:center}:host .mt-3{margin-top:12px}:host .mt-2{margin-top:8px}:host .text-center{text-align:center}:host .p-4{padding:16px}:host .rounded{border-radius:12px}:host .m-t-10{margin-top:10px}:host .alert-danger{background-color:var(--mat-sys-error-container, #ffdad6);border-color:var(--mat-sys-error, #ba1a1a);color:var(--mat-sys-on-error-container, #410002);padding:12px;border-radius:4px;border:1px solid transparent}:host .row{display:flex;flex-wrap:wrap;margin:0 -15px}:host .col-xs-12,:host .col-sm-12,:host .col-md-12{flex:0 0 100%;max-width:100%;padding:0 15px}:host .social{display:flex;justify-content:center}\n"] }]
961
+ ], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: "<mat-card class=\"mat-elevation-z8 p-4 rounded\">\n <mat-card-header>\n <mat-card-title class=\"text-center\">{{ title() }}</mat-card-title>\n </mat-card-header>\n <mat-card-content>\n @if (isLoginMode()) {\n <form [formGroup]=\"signinForm\" (ngSubmit)=\"signIn()\" class=\"d-flex flex-column gap-3\">\n <mat-form-field class=\"w-100\">\n <mat-label>Usuario</mat-label>\n <input matInput type=\"text\" placeholder=\"Ingrese su usuario\" formControlName=\"email\" />\n </mat-form-field>\n\n <mat-form-field class=\"w-100\">\n <mat-label>Contrase\u00F1a</mat-label>\n <input\n matInput\n type=\"password\"\n placeholder=\"Ingrese su contrase\u00F1a\"\n formControlName=\"password\"\n autocomplete=\"current-password\"\n />\n </mat-form-field>\n\n <!-- Remember Me checkbox - conditional -->\n @if (showRememberMe()) {\n <div class=\"d-flex align-items-center mt-2\">\n <mat-checkbox formControlName=\"rememberMe\"> Recordarme </mat-checkbox>\n </div>\n }\n\n <!-- Additional signin fields -->\n <ng-container *ngTemplateOutlet=\"additionalSigninFields()\"></ng-container>\n\n <div class=\"d-flex justify-content-center mt-3\">\n <button\n mat-raised-button\n color=\"primary\"\n [disabled]=\"!signinForm.valid || isLoading()\"\n type=\"submit\"\n class=\"w-100\"\n >\n @if (isLoading()) { Ingresando... } @else {\n <ng-container>Ingresar <mat-icon>login</mat-icon></ng-container>\n }\n </button>\n </div>\n\n <div class=\"text-center mt-2\">\n @if (showRegisterButton()) {\n <button mat-button type=\"button\" (click)=\"switchMode()\">\n \u00BFNo tienes cuenta? Reg\u00EDstrate\n </button>\n }\n </div>\n </form>\n } @else {\n <form [formGroup]=\"signupForm\" (ngSubmit)=\"registerUser()\" class=\"d-flex flex-column gap-3\">\n <mat-form-field class=\"w-100\">\n <mat-label>Nombre</mat-label>\n <input matInput type=\"text\" placeholder=\"Ingrese su nombre\" formControlName=\"displayName\" />\n </mat-form-field>\n\n <mat-form-field class=\"w-100\">\n <mat-label>Email</mat-label>\n <input matInput type=\"email\" placeholder=\"Ingrese su email\" formControlName=\"email\" />\n </mat-form-field>\n\n <mat-form-field class=\"w-100\">\n <mat-label>Contrase\u00F1a</mat-label>\n <input\n matInput\n type=\"password\"\n placeholder=\"Ingrese su contrase\u00F1a\"\n formControlName=\"password\"\n autocomplete=\"new-password\"\n />\n </mat-form-field>\n\n <!-- Additional signup fields -->\n <ng-container *ngTemplateOutlet=\"additionalSignupFields()\"></ng-container>\n\n <div class=\"d-flex justify-content-center mt-3\">\n <button\n mat-raised-button\n color=\"primary\"\n [disabled]=\"!signupForm.valid || isLoading()\"\n type=\"submit\"\n class=\"w-100\"\n >\n @if (isLoading()) { Registrando... } @else {\n <ng-container>Registrarse <mat-icon>person_add</mat-icon></ng-container>\n }\n </button>\n </div>\n\n <div class=\"text-center mt-2\">\n <button mat-button type=\"button\" (click)=\"switchMode()\">\n \u00BFYa tienes cuenta? Inicia sesi\u00F3n\n </button>\n </div>\n </form>\n } @if (errorMessage()) {\n <div class=\"alert alert-danger mt-3\" role=\"alert\">{{ errorMessage() }}</div>\n }\n </mat-card-content>\n @if (hasFooterContent()) {\n <mat-card-footer>\n <ng-container *ngTemplateOutlet=\"footerContent()\"></ng-container>\n </mat-card-footer>\n }\n</mat-card>\n", styles: [":host{display:flex;justify-content:center;align-items:center;min-height:100vh;width:100%;padding:16px;box-sizing:border-box}:host mat-card{width:100%;max-width:400px;border-radius:12px;box-shadow:0 8px 32px #0000001a}:host mat-card-header{text-align:center;margin-bottom:20px}:host mat-card-title{font-size:24px;font-weight:600;color:var(--mat-sys-primary, #6750a4)}:host mat-form-field{width:100%}:host mat-button{border-radius:8px}:host .w-100{width:100%}:host .d-flex{display:flex}:host .flex-column{flex-direction:column}:host .gap-3{gap:12px}:host .justify-content-center{justify-content:center}:host .align-items-center{align-items:center}:host .mt-3{margin-top:12px}:host .mt-2{margin-top:8px}:host .text-center{text-align:center}:host .p-4{padding:16px}:host .rounded{border-radius:12px}:host .m-t-10{margin-top:10px}:host .alert-danger{background-color:var(--mat-sys-error-container, #ffdad6);border-color:var(--mat-sys-error, #ba1a1a);color:var(--mat-sys-on-error-container, #410002);padding:12px;border-radius:4px;border:1px solid transparent}:host .row{display:flex;flex-wrap:wrap;margin:0 -15px}:host .col-xs-12,:host .col-sm-12,:host .col-md-12{flex:0 0 100%;max-width:100%;padding:0 15px}:host .social{display:flex;justify-content:center}\n"] }]
964
962
  }], ctorParameters: () => [] });
965
963
 
966
964
  // src/lib/presentation/components/index.ts
@@ -971,5 +969,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.2", ngImpor
971
969
  * Generated bundle index. Do not edit.
972
970
  */
973
971
 
974
- export { AuthHttpRepository, AuthRepository, AuthStore, CsrfService, LoginComponent, LoginUseCase, LogoutUseCase, RefreshTokenUseCase, RegisterUseCase, SKIP_CSRF, TokenRepository, UrlRedirectService, authGuard, authProviders, authRedirectInterceptor, csrfInterceptor };
972
+ export { AuthHttpRepository, AuthRepository, AuthStore, AuthTokenRepositoryImpl, AuthUrlRedirect, CsrfApi, Login, LoginUseCase, LogoutUseCase, RefreshTokenUseCase, RegisterUseCase, SKIP_CSRF, authGuard, authProviders, authRedirectInterceptor, csrfInterceptor };
975
973
  //# sourceMappingURL=acontplus-ng-auth.mjs.map