@acontplus/ng-auth 1.1.7 → 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 +17 -20
- package/fesm2022/acontplus-ng-auth.mjs +60 -62
- package/fesm2022/acontplus-ng-auth.mjs.map +1 -1
- package/index.d.ts +16 -15
- package/package.json +19 -14
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
|
|
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. **
|
|
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 {
|
|
97
|
+
import { AuthUrlRedirect } from '@acontplus/ng-auth';
|
|
97
98
|
|
|
98
99
|
@Component({...})
|
|
99
100
|
export class MyComponent {
|
|
100
|
-
constructor(private 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
|
-
- **
|
|
161
|
-
- **
|
|
162
|
-
- **
|
|
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 {
|
|
205
|
+
import { CsrfApi } from '@acontplus/ng-auth';
|
|
205
206
|
|
|
206
207
|
@Component({...})
|
|
207
|
-
export class
|
|
208
|
-
constructor(private 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 `
|
|
269
|
-
|
|
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 {
|
|
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: [
|
|
277
|
+
imports: [Login],
|
|
281
278
|
})
|
|
282
279
|
export class AuthPageComponent {}
|
|
283
280
|
```
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export {
|
|
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
|
|
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.
|
|
195
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.
|
|
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.
|
|
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
|
|
204
|
+
// src/lib/presentation/stores/auth-store.ts
|
|
205
205
|
class AuthStore {
|
|
206
206
|
authRepository = inject(AuthRepository);
|
|
207
|
-
tokenRepository = inject(
|
|
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.
|
|
402
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.
|
|
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.
|
|
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
|
|
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.
|
|
521
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.
|
|
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.
|
|
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
|
|
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(
|
|
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.
|
|
545
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.
|
|
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.
|
|
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
|
|
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.
|
|
568
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.
|
|
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.
|
|
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
|
|
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(
|
|
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.
|
|
605
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.
|
|
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.
|
|
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
|
|
614
|
+
// src/lib/application/use-cases/logout-use-case.ts
|
|
615
615
|
class LogoutUseCase extends BaseUseCase {
|
|
616
616
|
authRepository = inject(AuthRepository);
|
|
617
|
-
tokenRepository = inject(
|
|
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.
|
|
635
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.
|
|
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.
|
|
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.
|
|
686
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.
|
|
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.
|
|
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/
|
|
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(
|
|
706
|
+
const tokenRepository = inject(AuthTokenRepositoryImpl);
|
|
709
707
|
const router = inject(Router);
|
|
710
|
-
const urlRedirectService = inject(
|
|
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(
|
|
729
|
-
const tokenRepository = inject(
|
|
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.
|
|
749
|
-
class
|
|
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.
|
|
778
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.
|
|
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.
|
|
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(
|
|
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:
|
|
838
|
-
useClass:
|
|
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.
|
|
847
|
-
class
|
|
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.
|
|
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.
|
|
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
|
|
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,
|
|
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
|