valtech-components 2.0.451 → 2.0.453
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/esm2022/lib/components/organisms/tabbed-content/tabbed-content.component.mjs +170 -0
- package/esm2022/lib/components/organisms/tabbed-content/types.mjs +2 -0
- package/esm2022/lib/components/templates/page-content/page-content.component.mjs +11 -11
- package/esm2022/lib/components/templates/page-template/page-template.component.mjs +3 -5
- package/esm2022/lib/services/auth/auth-state.service.mjs +173 -0
- package/esm2022/lib/services/auth/auth.service.mjs +454 -0
- package/esm2022/lib/services/auth/config.mjs +76 -0
- package/esm2022/lib/services/auth/guards.mjs +194 -0
- package/esm2022/lib/services/auth/index.mjs +70 -0
- package/esm2022/lib/services/auth/interceptor.mjs +98 -0
- package/esm2022/lib/services/auth/storage.service.mjs +141 -0
- package/esm2022/lib/services/auth/sync.service.mjs +149 -0
- package/esm2022/lib/services/auth/token.service.mjs +113 -0
- package/esm2022/lib/services/auth/types.mjs +29 -0
- package/esm2022/lib/services/firebase/config.mjs +108 -0
- package/esm2022/lib/services/firebase/firebase.service.mjs +288 -0
- package/esm2022/lib/services/firebase/firestore-collection.mjs +254 -0
- package/esm2022/lib/services/firebase/firestore.service.mjs +509 -0
- package/esm2022/lib/services/firebase/index.mjs +49 -0
- package/esm2022/lib/services/firebase/messaging.service.mjs +512 -0
- package/esm2022/lib/services/firebase/shared-config.mjs +138 -0
- package/esm2022/lib/services/firebase/storage.service.mjs +422 -0
- package/esm2022/lib/services/firebase/types.mjs +8 -0
- package/esm2022/lib/services/firebase/utils/path-builder.mjs +195 -0
- package/esm2022/lib/services/firebase/utils/query-builder.mjs +302 -0
- package/esm2022/lib/services/link-processor.service.mjs +61 -43
- package/esm2022/lib/services/modal/modal.service.mjs +8 -9
- package/esm2022/lib/services/navigation.service.mjs +11 -11
- package/esm2022/public-api.mjs +23 -4
- package/fesm2022/valtech-components.mjs +4599 -102
- package/fesm2022/valtech-components.mjs.map +1 -1
- package/lib/components/organisms/tabbed-content/tabbed-content.component.d.ts +65 -0
- package/lib/components/organisms/tabbed-content/types.d.ts +53 -0
- package/lib/components/templates/page-content/page-content.component.d.ts +3 -0
- package/lib/services/auth/auth-state.service.d.ts +85 -0
- package/lib/services/auth/auth.service.d.ts +146 -0
- package/lib/services/auth/config.d.ts +38 -0
- package/lib/services/auth/guards.d.ts +123 -0
- package/lib/services/auth/index.d.ts +63 -0
- package/lib/services/auth/interceptor.d.ts +22 -0
- package/lib/services/auth/storage.service.d.ts +48 -0
- package/lib/services/auth/sync.service.d.ts +49 -0
- package/lib/services/auth/token.service.d.ts +51 -0
- package/lib/services/auth/types.d.ts +315 -0
- package/lib/services/firebase/config.d.ts +49 -0
- package/lib/services/firebase/firebase.service.d.ts +140 -0
- package/lib/services/firebase/firestore-collection.d.ts +175 -0
- package/lib/services/firebase/firestore.service.d.ts +304 -0
- package/lib/services/firebase/index.d.ts +39 -0
- package/lib/services/firebase/messaging.service.d.ts +263 -0
- package/lib/services/firebase/shared-config.d.ts +126 -0
- package/lib/services/firebase/storage.service.d.ts +206 -0
- package/lib/services/firebase/types.d.ts +281 -0
- package/lib/services/firebase/utils/path-builder.d.ts +132 -0
- package/lib/services/firebase/utils/query-builder.d.ts +210 -0
- package/lib/services/modal/modal.service.d.ts +2 -0
- package/lib/services/navigation.service.d.ts +4 -4
- package/package.json +3 -1
- package/public-api.d.ts +9 -0
- package/fesm2022/valtech-components-simple-modal-content.component-DQhEgUmS.mjs +0 -136
- package/fesm2022/valtech-components-simple-modal-content.component-DQhEgUmS.mjs.map +0 -1
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { EventEmitter, OnInit } from '@angular/core';
|
|
2
|
+
import { SegmentControlMetadata } from '../../molecules/segment-control/types';
|
|
3
|
+
import { TabbedContentMetadata, TabbedContentTab, TabbedContentContext } from './types';
|
|
4
|
+
import * as i0 from "@angular/core";
|
|
5
|
+
/**
|
|
6
|
+
* val-tabbed-content
|
|
7
|
+
*
|
|
8
|
+
* A container component that combines segment navigation with dynamic content panels.
|
|
9
|
+
* Uses segment-control internally for tab navigation and renders the associated
|
|
10
|
+
* template for the active tab.
|
|
11
|
+
*
|
|
12
|
+
* @example Basic usage with templates
|
|
13
|
+
* ```html
|
|
14
|
+
* <ng-template #catalogTemplate>
|
|
15
|
+
* <div>Catalog Content</div>
|
|
16
|
+
* </ng-template>
|
|
17
|
+
* <ng-template #settingsTemplate>
|
|
18
|
+
* <div>Settings Content</div>
|
|
19
|
+
* </ng-template>
|
|
20
|
+
*
|
|
21
|
+
* <val-tabbed-content [props]="{
|
|
22
|
+
* tabs: [
|
|
23
|
+
* { value: 'catalog', label: 'Catalog', icon: 'layers-outline', template: catalogTemplate },
|
|
24
|
+
* { value: 'settings', label: 'Settings', icon: 'settings-outline', template: settingsTemplate }
|
|
25
|
+
* ],
|
|
26
|
+
* selectedTab: 'catalog',
|
|
27
|
+
* scrollable: true,
|
|
28
|
+
* animated: true
|
|
29
|
+
* }" (tabChange)="onTabChange($event)"></val-tabbed-content>
|
|
30
|
+
* ```
|
|
31
|
+
*
|
|
32
|
+
* @input props: TabbedContentMetadata - Configuration for the tabbed content
|
|
33
|
+
* @output tabChange: string - Emits the selected tab value when changed
|
|
34
|
+
*/
|
|
35
|
+
export declare class TabbedContentComponent implements OnInit {
|
|
36
|
+
/**
|
|
37
|
+
* Configuration object for the tabbed content.
|
|
38
|
+
*/
|
|
39
|
+
props: TabbedContentMetadata;
|
|
40
|
+
/**
|
|
41
|
+
* Emits when the active tab changes.
|
|
42
|
+
*/
|
|
43
|
+
tabChange: EventEmitter<string>;
|
|
44
|
+
/** Currently selected tab value */
|
|
45
|
+
private selectedValue;
|
|
46
|
+
/** Whether a transition is in progress */
|
|
47
|
+
isTransitioning: import("@angular/core").WritableSignal<boolean>;
|
|
48
|
+
/** Computed animation duration string */
|
|
49
|
+
animationDuration: import("@angular/core").Signal<string>;
|
|
50
|
+
/** Computed segment control props derived from tabs config */
|
|
51
|
+
segmentControlProps: import("@angular/core").Signal<SegmentControlMetadata>;
|
|
52
|
+
/** Computed active tab object */
|
|
53
|
+
activeTab: import("@angular/core").Signal<TabbedContentTab>;
|
|
54
|
+
ngOnInit(): void;
|
|
55
|
+
/**
|
|
56
|
+
* Handles segment change events.
|
|
57
|
+
*/
|
|
58
|
+
onSegmentChange(value: string): void;
|
|
59
|
+
/**
|
|
60
|
+
* Creates the context object for the template outlet.
|
|
61
|
+
*/
|
|
62
|
+
getTemplateContext(tab: TabbedContentTab): TabbedContentContext;
|
|
63
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<TabbedContentComponent, never>;
|
|
64
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<TabbedContentComponent, "val-tabbed-content", never, { "props": { "alias": "props"; "required": false; }; }, { "tabChange": "tabChange"; }, never, never, true, never>;
|
|
65
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { TemplateRef } from '@angular/core';
|
|
2
|
+
import { Color } from '@ionic/core';
|
|
3
|
+
/**
|
|
4
|
+
* Context passed to each tab's template.
|
|
5
|
+
*/
|
|
6
|
+
export interface TabbedContentContext {
|
|
7
|
+
/** The value of the active tab */
|
|
8
|
+
$implicit: string;
|
|
9
|
+
/** The full tab configuration */
|
|
10
|
+
tab: TabbedContentTab;
|
|
11
|
+
/** Index of the tab */
|
|
12
|
+
index: number;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Configuration for a single tab.
|
|
16
|
+
*/
|
|
17
|
+
export interface TabbedContentTab {
|
|
18
|
+
/** Unique identifier for the tab */
|
|
19
|
+
value: string;
|
|
20
|
+
/** Display label for the tab button */
|
|
21
|
+
label?: string;
|
|
22
|
+
/** Icon name (Ionicons) */
|
|
23
|
+
icon?: string;
|
|
24
|
+
/** Whether the tab is disabled */
|
|
25
|
+
disabled?: boolean;
|
|
26
|
+
/** Layout direction for icon and label */
|
|
27
|
+
layout?: 'icon-start' | 'icon-end' | 'icon-top' | 'icon-bottom';
|
|
28
|
+
/** Template to render when this tab is active */
|
|
29
|
+
template: TemplateRef<TabbedContentContext>;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Metadata for the tabbed-content component.
|
|
33
|
+
*/
|
|
34
|
+
export interface TabbedContentMetadata {
|
|
35
|
+
/** Array of tab configurations */
|
|
36
|
+
tabs: TabbedContentTab[];
|
|
37
|
+
/** Initially selected tab value (defaults to first tab) */
|
|
38
|
+
selectedTab?: string;
|
|
39
|
+
/** Color theme for the segment control */
|
|
40
|
+
color?: Color;
|
|
41
|
+
/** Allow horizontal scrolling for many tabs */
|
|
42
|
+
scrollable?: boolean;
|
|
43
|
+
/** Enable swipe gesture to change tabs (iOS only) */
|
|
44
|
+
swipeGesture?: boolean;
|
|
45
|
+
/** Visual mode style */
|
|
46
|
+
mode?: 'ios' | 'md';
|
|
47
|
+
/** Enable fade animation on tab change */
|
|
48
|
+
animated?: boolean;
|
|
49
|
+
/** Animation duration in milliseconds */
|
|
50
|
+
animationDuration?: number;
|
|
51
|
+
/** Additional CSS class for the container */
|
|
52
|
+
cssClass?: string;
|
|
53
|
+
}
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { EventEmitter } from '@angular/core';
|
|
2
|
+
import { ThemeService } from '../../../services/theme.service';
|
|
3
|
+
import { NavigationService } from '../../../services/navigation.service';
|
|
2
4
|
import { PageContentMetadata } from './types';
|
|
3
5
|
import * as i0 from "@angular/core";
|
|
4
6
|
/**
|
|
@@ -34,6 +36,7 @@ export declare class PageContentComponent {
|
|
|
34
36
|
* Page content configuration.
|
|
35
37
|
*/
|
|
36
38
|
props: PageContentMetadata;
|
|
39
|
+
constructor(theme: ThemeService, nav: NavigationService);
|
|
37
40
|
/**
|
|
38
41
|
* Emits when a header action is clicked.
|
|
39
42
|
*/
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { AuthState, AuthUser, AuthError, MFAPendingState, StoredAuthState } from './types';
|
|
2
|
+
import * as i0 from "@angular/core";
|
|
3
|
+
/**
|
|
4
|
+
* Servicio para manejo de estado de autenticación con Angular Signals.
|
|
5
|
+
* Proporciona estado reactivo inmutable.
|
|
6
|
+
*/
|
|
7
|
+
export declare class AuthStateService {
|
|
8
|
+
private _state;
|
|
9
|
+
private _mfaPending;
|
|
10
|
+
/** Estado completo de autenticación */
|
|
11
|
+
readonly state: import("@angular/core").Signal<AuthState>;
|
|
12
|
+
/** Estado de MFA pendiente */
|
|
13
|
+
readonly mfaPending: import("@angular/core").Signal<MFAPendingState>;
|
|
14
|
+
/** Usuario está autenticado */
|
|
15
|
+
readonly isAuthenticated: import("@angular/core").Signal<boolean>;
|
|
16
|
+
/** Estado de carga */
|
|
17
|
+
readonly isLoading: import("@angular/core").Signal<boolean>;
|
|
18
|
+
/** Token de acceso */
|
|
19
|
+
readonly accessToken: import("@angular/core").Signal<string>;
|
|
20
|
+
/** Roles del usuario */
|
|
21
|
+
readonly roles: import("@angular/core").Signal<string[]>;
|
|
22
|
+
/** Permisos del usuario */
|
|
23
|
+
readonly permissions: import("@angular/core").Signal<string[]>;
|
|
24
|
+
/** Usuario es super admin */
|
|
25
|
+
readonly isSuperAdmin: import("@angular/core").Signal<boolean>;
|
|
26
|
+
/** Error actual */
|
|
27
|
+
readonly error: import("@angular/core").Signal<AuthError>;
|
|
28
|
+
/** Información del usuario */
|
|
29
|
+
readonly user: import("@angular/core").Signal<AuthUser>;
|
|
30
|
+
/**
|
|
31
|
+
* Establece el estado de carga.
|
|
32
|
+
*/
|
|
33
|
+
setLoading(isLoading: boolean): void;
|
|
34
|
+
/**
|
|
35
|
+
* Establece el estado de autenticación exitosa.
|
|
36
|
+
*/
|
|
37
|
+
setAuthenticated(data: {
|
|
38
|
+
accessToken: string;
|
|
39
|
+
refreshToken: string;
|
|
40
|
+
userId?: string;
|
|
41
|
+
email?: string;
|
|
42
|
+
roles: string[];
|
|
43
|
+
permissions: string[];
|
|
44
|
+
isSuperAdmin: boolean;
|
|
45
|
+
expiresAt: number;
|
|
46
|
+
}): void;
|
|
47
|
+
/**
|
|
48
|
+
* Actualiza solo el access token (después de refresh).
|
|
49
|
+
*/
|
|
50
|
+
updateAccessToken(accessToken: string, expiresIn: number): void;
|
|
51
|
+
/**
|
|
52
|
+
* Actualiza los permisos.
|
|
53
|
+
*/
|
|
54
|
+
updatePermissions(roles: string[], permissions: string[], isSuperAdmin: boolean): void;
|
|
55
|
+
/**
|
|
56
|
+
* Establece un error de autenticación.
|
|
57
|
+
*/
|
|
58
|
+
setError(error: AuthError): void;
|
|
59
|
+
/**
|
|
60
|
+
* Limpia el error.
|
|
61
|
+
*/
|
|
62
|
+
clearError(): void;
|
|
63
|
+
/**
|
|
64
|
+
* Establece estado de MFA pendiente.
|
|
65
|
+
*/
|
|
66
|
+
setMFAPending(mfaState: MFAPendingState): void;
|
|
67
|
+
/**
|
|
68
|
+
* Limpia el estado de MFA pendiente.
|
|
69
|
+
*/
|
|
70
|
+
clearMFAPending(): void;
|
|
71
|
+
/**
|
|
72
|
+
* Resetea todo el estado a valores iniciales.
|
|
73
|
+
*/
|
|
74
|
+
reset(): void;
|
|
75
|
+
/**
|
|
76
|
+
* Restaura estado desde datos almacenados.
|
|
77
|
+
*/
|
|
78
|
+
restoreFromStorage(stored: Partial<StoredAuthState>): void;
|
|
79
|
+
/**
|
|
80
|
+
* Actualiza el userId y email (después de parsear el token).
|
|
81
|
+
*/
|
|
82
|
+
updateUserInfo(userId: string, email: string): void;
|
|
83
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<AuthStateService, never>;
|
|
84
|
+
static ɵprov: i0.ɵɵInjectableDeclaration<AuthStateService>;
|
|
85
|
+
}
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
import { OnDestroy } from '@angular/core';
|
|
2
|
+
import { HttpClient } from '@angular/common/http';
|
|
3
|
+
import { Router } from '@angular/router';
|
|
4
|
+
import { Observable } from 'rxjs';
|
|
5
|
+
import { AuthStateService } from './auth-state.service';
|
|
6
|
+
import { TokenService } from './token.service';
|
|
7
|
+
import { AuthStorageService } from './storage.service';
|
|
8
|
+
import { AuthSyncService } from './sync.service';
|
|
9
|
+
import { SigninRequest, SigninResponse, SignupRequest, SignupResponse, VerifyEmailRequest, VerifyEmailResponse, ResendCodeRequest, ResendCodeResponse, MFAVerifyResponse, RefreshResponse, GetPermissionsResponse, MFASetupResponse, MFAConfirmResponse, MFADisableResponse, MFAMethod, AuthError, ValtechAuthConfig } from './types';
|
|
10
|
+
import { FirebaseService } from '../firebase';
|
|
11
|
+
import * as i0 from "@angular/core";
|
|
12
|
+
/**
|
|
13
|
+
* Servicio principal de autenticación.
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```typescript
|
|
17
|
+
* import { AuthService } from 'valtech-components';
|
|
18
|
+
*
|
|
19
|
+
* @Component({...})
|
|
20
|
+
* export class LoginComponent {
|
|
21
|
+
* private auth = inject(AuthService);
|
|
22
|
+
*
|
|
23
|
+
* async login() {
|
|
24
|
+
* await firstValueFrom(this.auth.signin({ email, password }));
|
|
25
|
+
* if (this.auth.mfaPending().required) {
|
|
26
|
+
* // Mostrar UI de MFA
|
|
27
|
+
* } else {
|
|
28
|
+
* this.router.navigate(['/']);
|
|
29
|
+
* }
|
|
30
|
+
* }
|
|
31
|
+
* }
|
|
32
|
+
* ```
|
|
33
|
+
*/
|
|
34
|
+
export declare class AuthService implements OnDestroy {
|
|
35
|
+
private config;
|
|
36
|
+
private http;
|
|
37
|
+
private router;
|
|
38
|
+
private stateService;
|
|
39
|
+
private tokenService;
|
|
40
|
+
private storageService;
|
|
41
|
+
private syncService;
|
|
42
|
+
private firebaseService;
|
|
43
|
+
private refreshTimerId;
|
|
44
|
+
private syncSubscription;
|
|
45
|
+
constructor(config: ValtechAuthConfig, http: HttpClient, router: Router, stateService: AuthStateService, tokenService: TokenService, storageService: AuthStorageService, syncService: AuthSyncService, firebaseService: FirebaseService);
|
|
46
|
+
/** Estado completo de autenticación */
|
|
47
|
+
readonly state: import("@angular/core").Signal<import("./types").AuthState>;
|
|
48
|
+
/** Usuario está autenticado */
|
|
49
|
+
readonly isAuthenticated: import("@angular/core").Signal<boolean>;
|
|
50
|
+
/** Estado de carga */
|
|
51
|
+
readonly isLoading: import("@angular/core").Signal<boolean>;
|
|
52
|
+
/** Información del usuario */
|
|
53
|
+
readonly user: import("@angular/core").Signal<import("./types").AuthUser>;
|
|
54
|
+
/** Token de acceso */
|
|
55
|
+
readonly accessToken: import("@angular/core").Signal<string>;
|
|
56
|
+
/** Roles del usuario */
|
|
57
|
+
readonly roles: import("@angular/core").Signal<string[]>;
|
|
58
|
+
/** Permisos del usuario */
|
|
59
|
+
readonly permissions: import("@angular/core").Signal<string[]>;
|
|
60
|
+
/** Usuario es super admin */
|
|
61
|
+
readonly isSuperAdmin: import("@angular/core").Signal<boolean>;
|
|
62
|
+
/** Estado de MFA pendiente */
|
|
63
|
+
readonly mfaPending: import("@angular/core").Signal<import("./types").MFAPendingState>;
|
|
64
|
+
/** Error actual */
|
|
65
|
+
readonly error: import("@angular/core").Signal<AuthError>;
|
|
66
|
+
/**
|
|
67
|
+
* Inicializa el servicio de autenticación.
|
|
68
|
+
* Llamado automáticamente por provideValtechAuth.
|
|
69
|
+
*/
|
|
70
|
+
initialize(): Promise<void>;
|
|
71
|
+
ngOnDestroy(): void;
|
|
72
|
+
/**
|
|
73
|
+
* Inicia sesión con email y contraseña.
|
|
74
|
+
*/
|
|
75
|
+
signin(request: SigninRequest): Observable<SigninResponse>;
|
|
76
|
+
/**
|
|
77
|
+
* Registra un nuevo usuario.
|
|
78
|
+
* El usuario queda en estado PENDING hasta verificar su email.
|
|
79
|
+
*/
|
|
80
|
+
signup(request: SignupRequest): Observable<SignupResponse>;
|
|
81
|
+
/**
|
|
82
|
+
* Verifica email con código de 6 dígitos.
|
|
83
|
+
* Si es exitoso, hace auto-login y retorna tokens.
|
|
84
|
+
*/
|
|
85
|
+
verifyEmail(request: VerifyEmailRequest): Observable<VerifyEmailResponse>;
|
|
86
|
+
/**
|
|
87
|
+
* Reenvía código de verificación al email.
|
|
88
|
+
*/
|
|
89
|
+
resendCode(request: ResendCodeRequest): Observable<ResendCodeResponse>;
|
|
90
|
+
/**
|
|
91
|
+
* Verifica código MFA.
|
|
92
|
+
*/
|
|
93
|
+
verifyMFA(code: string): Observable<MFAVerifyResponse>;
|
|
94
|
+
/**
|
|
95
|
+
* Refresca el token de acceso.
|
|
96
|
+
*/
|
|
97
|
+
refreshAccessToken(): Observable<RefreshResponse>;
|
|
98
|
+
/**
|
|
99
|
+
* Cierra sesión.
|
|
100
|
+
*/
|
|
101
|
+
logout(): void;
|
|
102
|
+
/**
|
|
103
|
+
* Configura MFA para el usuario.
|
|
104
|
+
*/
|
|
105
|
+
setupMFA(method: MFAMethod, phone?: string): Observable<MFASetupResponse>;
|
|
106
|
+
/**
|
|
107
|
+
* Confirma la configuración de MFA.
|
|
108
|
+
*/
|
|
109
|
+
confirmMFA(code: string): Observable<MFAConfirmResponse>;
|
|
110
|
+
/**
|
|
111
|
+
* Deshabilita MFA.
|
|
112
|
+
*/
|
|
113
|
+
disableMFA(password: string): Observable<MFADisableResponse>;
|
|
114
|
+
/**
|
|
115
|
+
* Obtiene los permisos actualizados del backend.
|
|
116
|
+
*/
|
|
117
|
+
fetchPermissions(): Observable<GetPermissionsResponse>;
|
|
118
|
+
/**
|
|
119
|
+
* Verifica si el usuario tiene un permiso específico.
|
|
120
|
+
* Formato: "resource:action" (ej: "templates:edit")
|
|
121
|
+
*/
|
|
122
|
+
hasPermission(permission: string): boolean;
|
|
123
|
+
/**
|
|
124
|
+
* Verifica si el usuario tiene alguno de los permisos dados.
|
|
125
|
+
*/
|
|
126
|
+
hasAnyPermission(permissions: string[]): boolean;
|
|
127
|
+
/**
|
|
128
|
+
* Verifica si el usuario tiene todos los permisos dados.
|
|
129
|
+
*/
|
|
130
|
+
hasAllPermissions(permissions: string[]): boolean;
|
|
131
|
+
/**
|
|
132
|
+
* Verifica si el usuario tiene un rol específico.
|
|
133
|
+
*/
|
|
134
|
+
hasRole(role: string): boolean;
|
|
135
|
+
private get baseUrl();
|
|
136
|
+
private handleSuccessfulAuth;
|
|
137
|
+
private clearState;
|
|
138
|
+
private startRefreshTimer;
|
|
139
|
+
private stopRefreshTimer;
|
|
140
|
+
private handleSyncEvent;
|
|
141
|
+
private handleAuthError;
|
|
142
|
+
private signInWithFirebase;
|
|
143
|
+
private signOutFirebase;
|
|
144
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<AuthService, never>;
|
|
145
|
+
static ɵprov: i0.ɵɵInjectableDeclaration<AuthService>;
|
|
146
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { EnvironmentProviders, InjectionToken } from '@angular/core';
|
|
2
|
+
import { ValtechAuthConfig } from './types';
|
|
3
|
+
/**
|
|
4
|
+
* Token de inyección para la configuración de Auth.
|
|
5
|
+
*/
|
|
6
|
+
export declare const VALTECH_AUTH_CONFIG: InjectionToken<ValtechAuthConfig>;
|
|
7
|
+
/**
|
|
8
|
+
* Configuración por defecto.
|
|
9
|
+
*/
|
|
10
|
+
export declare const DEFAULT_AUTH_CONFIG: Partial<ValtechAuthConfig>;
|
|
11
|
+
/**
|
|
12
|
+
* Provee el servicio de autenticación a la aplicación Angular.
|
|
13
|
+
*
|
|
14
|
+
* @param config - Configuración de autenticación
|
|
15
|
+
* @returns EnvironmentProviders para usar en bootstrapApplication
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* ```typescript
|
|
19
|
+
* // main.ts
|
|
20
|
+
* import { bootstrapApplication } from '@angular/platform-browser';
|
|
21
|
+
* import { provideValtechAuth } from 'valtech-components';
|
|
22
|
+
* import { environment } from './environments/environment';
|
|
23
|
+
*
|
|
24
|
+
* bootstrapApplication(AppComponent, {
|
|
25
|
+
* providers: [
|
|
26
|
+
* provideValtechAuth({
|
|
27
|
+
* apiUrl: environment.apiUrl,
|
|
28
|
+
* enableFirebaseIntegration: true,
|
|
29
|
+
* }),
|
|
30
|
+
* ],
|
|
31
|
+
* });
|
|
32
|
+
* ```
|
|
33
|
+
*/
|
|
34
|
+
export declare function provideValtechAuth(config: ValtechAuthConfig): EnvironmentProviders;
|
|
35
|
+
/**
|
|
36
|
+
* Provee solo el interceptor (para apps que ya tienen AuthService configurado manualmente).
|
|
37
|
+
*/
|
|
38
|
+
export declare function provideValtechAuthInterceptor(): EnvironmentProviders;
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import { CanActivateFn } from '@angular/router';
|
|
2
|
+
/**
|
|
3
|
+
* Guard que verifica si el usuario está autenticado.
|
|
4
|
+
* Redirige a loginRoute si no está autenticado.
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* ```typescript
|
|
8
|
+
* import { authGuard } from 'valtech-components';
|
|
9
|
+
*
|
|
10
|
+
* const routes: Routes = [
|
|
11
|
+
* {
|
|
12
|
+
* path: 'dashboard',
|
|
13
|
+
* canActivate: [authGuard],
|
|
14
|
+
* loadComponent: () => import('./dashboard.page'),
|
|
15
|
+
* },
|
|
16
|
+
* ];
|
|
17
|
+
* ```
|
|
18
|
+
*/
|
|
19
|
+
export declare const authGuard: CanActivateFn;
|
|
20
|
+
/**
|
|
21
|
+
* Guard que verifica si el usuario NO está autenticado.
|
|
22
|
+
* Redirige a homeRoute si ya está autenticado.
|
|
23
|
+
* Útil para páginas de login/registro.
|
|
24
|
+
*
|
|
25
|
+
* @example
|
|
26
|
+
* ```typescript
|
|
27
|
+
* import { guestGuard } from 'valtech-components';
|
|
28
|
+
*
|
|
29
|
+
* const routes: Routes = [
|
|
30
|
+
* {
|
|
31
|
+
* path: 'login',
|
|
32
|
+
* canActivate: [guestGuard],
|
|
33
|
+
* loadComponent: () => import('./login.page'),
|
|
34
|
+
* },
|
|
35
|
+
* ];
|
|
36
|
+
* ```
|
|
37
|
+
*/
|
|
38
|
+
export declare const guestGuard: CanActivateFn;
|
|
39
|
+
/**
|
|
40
|
+
* Factory para crear guard de permisos.
|
|
41
|
+
* Verifica si el usuario tiene el permiso especificado.
|
|
42
|
+
*
|
|
43
|
+
* @param permissions - Permiso o lista de permisos requeridos (OR)
|
|
44
|
+
* @returns Guard function
|
|
45
|
+
*
|
|
46
|
+
* @example
|
|
47
|
+
* ```typescript
|
|
48
|
+
* import { authGuard, permissionGuard } from 'valtech-components';
|
|
49
|
+
*
|
|
50
|
+
* const routes: Routes = [
|
|
51
|
+
* {
|
|
52
|
+
* path: 'templates',
|
|
53
|
+
* canActivate: [authGuard, permissionGuard('templates:read')],
|
|
54
|
+
* loadComponent: () => import('./templates.page'),
|
|
55
|
+
* },
|
|
56
|
+
* {
|
|
57
|
+
* path: 'admin',
|
|
58
|
+
* canActivate: [authGuard, permissionGuard(['admin:*', 'super_admin'])],
|
|
59
|
+
* loadComponent: () => import('./admin.page'),
|
|
60
|
+
* },
|
|
61
|
+
* ];
|
|
62
|
+
* ```
|
|
63
|
+
*/
|
|
64
|
+
export declare function permissionGuard(permissions: string | string[]): CanActivateFn;
|
|
65
|
+
/**
|
|
66
|
+
* Guard que lee permisos desde route.data.
|
|
67
|
+
* Permite configurar permisos directamente en la definición de rutas.
|
|
68
|
+
*
|
|
69
|
+
* @example
|
|
70
|
+
* ```typescript
|
|
71
|
+
* import { authGuard, permissionGuardFromRoute } from 'valtech-components';
|
|
72
|
+
*
|
|
73
|
+
* const routes: Routes = [
|
|
74
|
+
* {
|
|
75
|
+
* path: 'admin/users',
|
|
76
|
+
* canActivate: [authGuard, permissionGuardFromRoute],
|
|
77
|
+
* data: {
|
|
78
|
+
* permissions: ['users:read', 'users:manage'],
|
|
79
|
+
* requireAll: false // true = AND, false = OR (default)
|
|
80
|
+
* },
|
|
81
|
+
* loadComponent: () => import('./users.page'),
|
|
82
|
+
* },
|
|
83
|
+
* ];
|
|
84
|
+
* ```
|
|
85
|
+
*/
|
|
86
|
+
export declare const permissionGuardFromRoute: CanActivateFn;
|
|
87
|
+
/**
|
|
88
|
+
* Guard que verifica si el usuario es super admin.
|
|
89
|
+
*
|
|
90
|
+
* @example
|
|
91
|
+
* ```typescript
|
|
92
|
+
* import { authGuard, superAdminGuard } from 'valtech-components';
|
|
93
|
+
*
|
|
94
|
+
* const routes: Routes = [
|
|
95
|
+
* {
|
|
96
|
+
* path: 'super-admin',
|
|
97
|
+
* canActivate: [authGuard, superAdminGuard],
|
|
98
|
+
* loadComponent: () => import('./super-admin.page'),
|
|
99
|
+
* },
|
|
100
|
+
* ];
|
|
101
|
+
* ```
|
|
102
|
+
*/
|
|
103
|
+
export declare const superAdminGuard: CanActivateFn;
|
|
104
|
+
/**
|
|
105
|
+
* Guard que verifica si el usuario tiene un rol específico.
|
|
106
|
+
*
|
|
107
|
+
* @param roles - Rol o lista de roles requeridos (OR)
|
|
108
|
+
* @returns Guard function
|
|
109
|
+
*
|
|
110
|
+
* @example
|
|
111
|
+
* ```typescript
|
|
112
|
+
* import { authGuard, roleGuard } from 'valtech-components';
|
|
113
|
+
*
|
|
114
|
+
* const routes: Routes = [
|
|
115
|
+
* {
|
|
116
|
+
* path: 'editor',
|
|
117
|
+
* canActivate: [authGuard, roleGuard(['editor', 'admin'])],
|
|
118
|
+
* loadComponent: () => import('./editor.page'),
|
|
119
|
+
* },
|
|
120
|
+
* ];
|
|
121
|
+
* ```
|
|
122
|
+
*/
|
|
123
|
+
export declare function roleGuard(roles: string | string[]): CanActivateFn;
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Valtech Auth Service
|
|
3
|
+
*
|
|
4
|
+
* Servicio de autenticación reutilizable para aplicaciones Angular.
|
|
5
|
+
* Proporciona autenticación con AuthV2, MFA, sincronización entre pestañas,
|
|
6
|
+
* y refresh proactivo de tokens.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```typescript
|
|
10
|
+
* // En main.ts
|
|
11
|
+
* import { bootstrapApplication } from '@angular/platform-browser';
|
|
12
|
+
* import { provideValtechAuth } from 'valtech-components';
|
|
13
|
+
* import { environment } from './environments/environment';
|
|
14
|
+
*
|
|
15
|
+
* bootstrapApplication(AppComponent, {
|
|
16
|
+
* providers: [
|
|
17
|
+
* provideValtechAuth({
|
|
18
|
+
* apiUrl: environment.apiUrl,
|
|
19
|
+
* enableFirebaseIntegration: true,
|
|
20
|
+
* }),
|
|
21
|
+
* ],
|
|
22
|
+
* });
|
|
23
|
+
*
|
|
24
|
+
* // En app.routes.ts
|
|
25
|
+
* import { authGuard, guestGuard, permissionGuard } from 'valtech-components';
|
|
26
|
+
*
|
|
27
|
+
* const routes: Routes = [
|
|
28
|
+
* { path: 'login', canActivate: [guestGuard], loadComponent: () => import('./login.page') },
|
|
29
|
+
* { path: 'dashboard', canActivate: [authGuard], loadComponent: () => import('./dashboard.page') },
|
|
30
|
+
* { path: 'admin', canActivate: [authGuard, permissionGuard('admin:*')], loadComponent: () => import('./admin.page') },
|
|
31
|
+
* ];
|
|
32
|
+
*
|
|
33
|
+
* // En componentes
|
|
34
|
+
* import { AuthService } from 'valtech-components';
|
|
35
|
+
*
|
|
36
|
+
* @Component({...})
|
|
37
|
+
* export class LoginComponent {
|
|
38
|
+
* private auth = inject(AuthService);
|
|
39
|
+
*
|
|
40
|
+
* async login() {
|
|
41
|
+
* await firstValueFrom(this.auth.signin({ email, password }));
|
|
42
|
+
* if (this.auth.mfaPending().required) {
|
|
43
|
+
* // Mostrar UI de MFA
|
|
44
|
+
* } else {
|
|
45
|
+
* this.router.navigate(['/dashboard']);
|
|
46
|
+
* }
|
|
47
|
+
* }
|
|
48
|
+
*
|
|
49
|
+
* // En template: usar signals directamente
|
|
50
|
+
* // {{ auth.user()?.email }}
|
|
51
|
+
* // @if (auth.hasPermission('templates:edit')) { ... }
|
|
52
|
+
* }
|
|
53
|
+
* ```
|
|
54
|
+
*/
|
|
55
|
+
export * from './types';
|
|
56
|
+
export { VALTECH_AUTH_CONFIG, provideValtechAuth, provideValtechAuthInterceptor, DEFAULT_AUTH_CONFIG, } from './config';
|
|
57
|
+
export { AuthService } from './auth.service';
|
|
58
|
+
export { authGuard, guestGuard, permissionGuard, permissionGuardFromRoute, superAdminGuard, roleGuard, } from './guards';
|
|
59
|
+
export { authInterceptor } from './interceptor';
|
|
60
|
+
export { AuthStateService } from './auth-state.service';
|
|
61
|
+
export { TokenService } from './token.service';
|
|
62
|
+
export { AuthStorageService } from './storage.service';
|
|
63
|
+
export { AuthSyncService } from './sync.service';
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { HttpInterceptorFn } from '@angular/common/http';
|
|
2
|
+
/**
|
|
3
|
+
* Interceptor HTTP que:
|
|
4
|
+
* 1. Agrega header Authorization con Bearer token a requests API
|
|
5
|
+
* 2. Maneja errores 401 refrescando el token automáticamente
|
|
6
|
+
* 3. Encola requests durante el refresco para evitar múltiples refresh
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```typescript
|
|
10
|
+
* // Incluido automáticamente por provideValtechAuth()
|
|
11
|
+
* // Para uso manual:
|
|
12
|
+
* import { provideHttpClient, withInterceptors } from '@angular/common/http';
|
|
13
|
+
* import { authInterceptor } from 'valtech-components';
|
|
14
|
+
*
|
|
15
|
+
* bootstrapApplication(AppComponent, {
|
|
16
|
+
* providers: [
|
|
17
|
+
* provideHttpClient(withInterceptors([authInterceptor])),
|
|
18
|
+
* ],
|
|
19
|
+
* });
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
22
|
+
export declare const authInterceptor: HttpInterceptorFn;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { StoredAuthState, GetPermissionsResponse, ValtechAuthConfig } from './types';
|
|
2
|
+
import * as i0 from "@angular/core";
|
|
3
|
+
/**
|
|
4
|
+
* Servicio para persistencia de estado de autenticación en localStorage.
|
|
5
|
+
*/
|
|
6
|
+
export declare class AuthStorageService {
|
|
7
|
+
private config;
|
|
8
|
+
private keys;
|
|
9
|
+
constructor(config: ValtechAuthConfig);
|
|
10
|
+
/**
|
|
11
|
+
* Guarda el estado completo de autenticación.
|
|
12
|
+
*/
|
|
13
|
+
saveState(state: StoredAuthState): void;
|
|
14
|
+
/**
|
|
15
|
+
* Carga el estado de autenticación desde storage.
|
|
16
|
+
*/
|
|
17
|
+
loadState(): Partial<StoredAuthState>;
|
|
18
|
+
/**
|
|
19
|
+
* Guarda solo el access token.
|
|
20
|
+
*/
|
|
21
|
+
saveAccessToken(token: string, expiresAt?: number): void;
|
|
22
|
+
/**
|
|
23
|
+
* Guarda los permisos actualizados.
|
|
24
|
+
*/
|
|
25
|
+
savePermissions(response: GetPermissionsResponse): void;
|
|
26
|
+
/**
|
|
27
|
+
* Carga los permisos desde storage.
|
|
28
|
+
*/
|
|
29
|
+
loadPermissions(): {
|
|
30
|
+
roles: string[];
|
|
31
|
+
permissions: string[];
|
|
32
|
+
isSuperAdmin: boolean;
|
|
33
|
+
};
|
|
34
|
+
/**
|
|
35
|
+
* Obtiene el refresh token.
|
|
36
|
+
*/
|
|
37
|
+
getRefreshToken(): string | null;
|
|
38
|
+
/**
|
|
39
|
+
* Limpia todo el estado de autenticación.
|
|
40
|
+
*/
|
|
41
|
+
clear(): void;
|
|
42
|
+
/**
|
|
43
|
+
* Verifica si hay estado guardado.
|
|
44
|
+
*/
|
|
45
|
+
hasStoredState(): boolean;
|
|
46
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<AuthStorageService, never>;
|
|
47
|
+
static ɵprov: i0.ɵɵInjectableDeclaration<AuthStorageService>;
|
|
48
|
+
}
|