valtech-components 2.0.428 → 2.0.430

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.
Files changed (28) hide show
  1. package/esm2022/lib/components/organisms/data-table/data-table.component.mjs +17 -3
  2. package/esm2022/lib/components/organisms/data-table/types.mjs +1 -1
  3. package/esm2022/lib/services/auth/auth-state.service.mjs +173 -0
  4. package/esm2022/lib/services/auth/auth.service.mjs +432 -0
  5. package/esm2022/lib/services/auth/config.mjs +76 -0
  6. package/esm2022/lib/services/auth/guards.mjs +194 -0
  7. package/esm2022/lib/services/auth/index.mjs +70 -0
  8. package/esm2022/lib/services/auth/interceptor.mjs +98 -0
  9. package/esm2022/lib/services/auth/storage.service.mjs +138 -0
  10. package/esm2022/lib/services/auth/sync.service.mjs +146 -0
  11. package/esm2022/lib/services/auth/token.service.mjs +113 -0
  12. package/esm2022/lib/services/auth/types.mjs +29 -0
  13. package/esm2022/public-api.mjs +4 -1
  14. package/fesm2022/valtech-components.mjs +1465 -8
  15. package/fesm2022/valtech-components.mjs.map +1 -1
  16. package/lib/components/organisms/data-table/types.d.ts +8 -0
  17. package/lib/services/auth/auth-state.service.d.ts +85 -0
  18. package/lib/services/auth/auth.service.d.ts +123 -0
  19. package/lib/services/auth/config.d.ts +38 -0
  20. package/lib/services/auth/guards.d.ts +123 -0
  21. package/lib/services/auth/index.d.ts +63 -0
  22. package/lib/services/auth/interceptor.d.ts +22 -0
  23. package/lib/services/auth/storage.service.d.ts +48 -0
  24. package/lib/services/auth/sync.service.d.ts +49 -0
  25. package/lib/services/auth/token.service.d.ts +51 -0
  26. package/lib/services/auth/types.d.ts +264 -0
  27. package/package.json +1 -9
  28. package/public-api.d.ts +1 -0
@@ -0,0 +1,194 @@
1
+ import { inject } from '@angular/core';
2
+ import { Router, } from '@angular/router';
3
+ import { AuthService } from './auth.service';
4
+ import { VALTECH_AUTH_CONFIG } from './config';
5
+ /**
6
+ * Guard que verifica si el usuario está autenticado.
7
+ * Redirige a loginRoute si no está autenticado.
8
+ *
9
+ * @example
10
+ * ```typescript
11
+ * import { authGuard } from 'valtech-components';
12
+ *
13
+ * const routes: Routes = [
14
+ * {
15
+ * path: 'dashboard',
16
+ * canActivate: [authGuard],
17
+ * loadComponent: () => import('./dashboard.page'),
18
+ * },
19
+ * ];
20
+ * ```
21
+ */
22
+ export const authGuard = () => {
23
+ const authService = inject(AuthService);
24
+ const router = inject(Router);
25
+ const config = inject(VALTECH_AUTH_CONFIG);
26
+ if (authService.isAuthenticated()) {
27
+ return true;
28
+ }
29
+ return router.createUrlTree([config.loginRoute]);
30
+ };
31
+ /**
32
+ * Guard que verifica si el usuario NO está autenticado.
33
+ * Redirige a homeRoute si ya está autenticado.
34
+ * Útil para páginas de login/registro.
35
+ *
36
+ * @example
37
+ * ```typescript
38
+ * import { guestGuard } from 'valtech-components';
39
+ *
40
+ * const routes: Routes = [
41
+ * {
42
+ * path: 'login',
43
+ * canActivate: [guestGuard],
44
+ * loadComponent: () => import('./login.page'),
45
+ * },
46
+ * ];
47
+ * ```
48
+ */
49
+ export const guestGuard = () => {
50
+ const authService = inject(AuthService);
51
+ const router = inject(Router);
52
+ const config = inject(VALTECH_AUTH_CONFIG);
53
+ if (!authService.isAuthenticated()) {
54
+ return true;
55
+ }
56
+ return router.createUrlTree([config.homeRoute]);
57
+ };
58
+ /**
59
+ * Factory para crear guard de permisos.
60
+ * Verifica si el usuario tiene el permiso especificado.
61
+ *
62
+ * @param permissions - Permiso o lista de permisos requeridos (OR)
63
+ * @returns Guard function
64
+ *
65
+ * @example
66
+ * ```typescript
67
+ * import { authGuard, permissionGuard } from 'valtech-components';
68
+ *
69
+ * const routes: Routes = [
70
+ * {
71
+ * path: 'templates',
72
+ * canActivate: [authGuard, permissionGuard('templates:read')],
73
+ * loadComponent: () => import('./templates.page'),
74
+ * },
75
+ * {
76
+ * path: 'admin',
77
+ * canActivate: [authGuard, permissionGuard(['admin:*', 'super_admin'])],
78
+ * loadComponent: () => import('./admin.page'),
79
+ * },
80
+ * ];
81
+ * ```
82
+ */
83
+ export function permissionGuard(permissions) {
84
+ return () => {
85
+ const authService = inject(AuthService);
86
+ const router = inject(Router);
87
+ const config = inject(VALTECH_AUTH_CONFIG);
88
+ const permArray = Array.isArray(permissions) ? permissions : [permissions];
89
+ if (authService.hasAnyPermission(permArray)) {
90
+ return true;
91
+ }
92
+ console.warn(`[ValtechAuth] Permiso denegado. Requerido: ${permArray.join(' o ')}`);
93
+ return router.createUrlTree([config.unauthorizedRoute]);
94
+ };
95
+ }
96
+ /**
97
+ * Guard que lee permisos desde route.data.
98
+ * Permite configurar permisos directamente en la definición de rutas.
99
+ *
100
+ * @example
101
+ * ```typescript
102
+ * import { authGuard, permissionGuardFromRoute } from 'valtech-components';
103
+ *
104
+ * const routes: Routes = [
105
+ * {
106
+ * path: 'admin/users',
107
+ * canActivate: [authGuard, permissionGuardFromRoute],
108
+ * data: {
109
+ * permissions: ['users:read', 'users:manage'],
110
+ * requireAll: false // true = AND, false = OR (default)
111
+ * },
112
+ * loadComponent: () => import('./users.page'),
113
+ * },
114
+ * ];
115
+ * ```
116
+ */
117
+ export const permissionGuardFromRoute = (route) => {
118
+ const authService = inject(AuthService);
119
+ const router = inject(Router);
120
+ const config = inject(VALTECH_AUTH_CONFIG);
121
+ const permissions = route.data['permissions'];
122
+ const requireAll = route.data['requireAll'];
123
+ if (!permissions || permissions.length === 0) {
124
+ return true;
125
+ }
126
+ const hasAccess = requireAll
127
+ ? authService.hasAllPermissions(permissions)
128
+ : authService.hasAnyPermission(permissions);
129
+ if (hasAccess) {
130
+ return true;
131
+ }
132
+ console.warn(`[ValtechAuth] Permiso denegado. Requerido: ${permissions.join(requireAll ? ' y ' : ' o ')}`);
133
+ return router.createUrlTree([config.unauthorizedRoute]);
134
+ };
135
+ /**
136
+ * Guard que verifica si el usuario es super admin.
137
+ *
138
+ * @example
139
+ * ```typescript
140
+ * import { authGuard, superAdminGuard } from 'valtech-components';
141
+ *
142
+ * const routes: Routes = [
143
+ * {
144
+ * path: 'super-admin',
145
+ * canActivate: [authGuard, superAdminGuard],
146
+ * loadComponent: () => import('./super-admin.page'),
147
+ * },
148
+ * ];
149
+ * ```
150
+ */
151
+ export const superAdminGuard = () => {
152
+ const authService = inject(AuthService);
153
+ const router = inject(Router);
154
+ const config = inject(VALTECH_AUTH_CONFIG);
155
+ if (authService.isSuperAdmin()) {
156
+ return true;
157
+ }
158
+ console.warn('[ValtechAuth] Acceso de super admin requerido');
159
+ return router.createUrlTree([config.unauthorizedRoute]);
160
+ };
161
+ /**
162
+ * Guard que verifica si el usuario tiene un rol específico.
163
+ *
164
+ * @param roles - Rol o lista de roles requeridos (OR)
165
+ * @returns Guard function
166
+ *
167
+ * @example
168
+ * ```typescript
169
+ * import { authGuard, roleGuard } from 'valtech-components';
170
+ *
171
+ * const routes: Routes = [
172
+ * {
173
+ * path: 'editor',
174
+ * canActivate: [authGuard, roleGuard(['editor', 'admin'])],
175
+ * loadComponent: () => import('./editor.page'),
176
+ * },
177
+ * ];
178
+ * ```
179
+ */
180
+ export function roleGuard(roles) {
181
+ return () => {
182
+ const authService = inject(AuthService);
183
+ const router = inject(Router);
184
+ const config = inject(VALTECH_AUTH_CONFIG);
185
+ const roleArray = Array.isArray(roles) ? roles : [roles];
186
+ const hasRole = roleArray.some((role) => authService.hasRole(role));
187
+ if (hasRole) {
188
+ return true;
189
+ }
190
+ console.warn(`[ValtechAuth] Rol requerido: ${roleArray.join(' o ')}`);
191
+ return router.createUrlTree([config.unauthorizedRoute]);
192
+ };
193
+ }
194
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ3VhcmRzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vc3JjL2xpYi9zZXJ2aWNlcy9hdXRoL2d1YXJkcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ3ZDLE9BQU8sRUFDTCxNQUFNLEdBSVAsTUFBTSxpQkFBaUIsQ0FBQztBQUN6QixPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDN0MsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0sVUFBVSxDQUFDO0FBRS9DOzs7Ozs7Ozs7Ozs7Ozs7O0dBZ0JHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sU0FBUyxHQUFrQixHQUFzQixFQUFFO0lBQzlELE1BQU0sV0FBVyxHQUFHLE1BQU0sQ0FBQyxXQUFXLENBQUMsQ0FBQztJQUN4QyxNQUFNLE1BQU0sR0FBRyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUM7SUFDOUIsTUFBTSxNQUFNLEdBQUcsTUFBTSxDQUFDLG1CQUFtQixDQUFDLENBQUM7SUFFM0MsSUFBSSxXQUFXLENBQUMsZUFBZSxFQUFFLEVBQUUsQ0FBQztRQUNsQyxPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7SUFFRCxPQUFPLE1BQU0sQ0FBQyxhQUFhLENBQUMsQ0FBQyxNQUFNLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQztBQUNuRCxDQUFDLENBQUM7QUFFRjs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FpQkc7QUFDSCxNQUFNLENBQUMsTUFBTSxVQUFVLEdBQWtCLEdBQXNCLEVBQUU7SUFDL0QsTUFBTSxXQUFXLEdBQUcsTUFBTSxDQUFDLFdBQVcsQ0FBQyxDQUFDO0lBQ3hDLE1BQU0sTUFBTSxHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQztJQUM5QixNQUFNLE1BQU0sR0FBRyxNQUFNLENBQUMsbUJBQW1CLENBQUMsQ0FBQztJQUUzQyxJQUFJLENBQUMsV0FBVyxDQUFD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Q0FBQztJQUNkLENBQUM7SUFFRCxPQUFPLENBQUMsSUFBSSxDQUFDLCtDQUErQyxDQUFDLENBQUM7SUFDOUQsT0FBTyxNQUFNLENBQUMsYUFBYSxDQUFDLENBQUMsTUFBTSxDQUFDLGlCQUFpQixDQUFDLENBQUMsQ0FBQztBQUMxRCxDQUFDLENBQUM7QUFFRjs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBa0JHO0FBQ0gsTUFBTSxVQUFVLFNBQVMsQ0FBQyxLQUF3QjtJQUNoRCxPQUFPLEdBQXNCLEVBQUU7UUFDN0IsTUFBTSxXQUFXLEdBQUcsTUFBTSxDQUFDLFdBQVcsQ0FBQyxDQUFDO1FBQ3hDLE1BQU0sTUFBTSxHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUM5QixNQUFNLE1BQU0sR0FBRyxNQUFNLENBQUMsbUJBQW1CLENBQUMsQ0FBQztRQUUzQyxNQUFNLFNBQVMsR0FBRyxLQUFLLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUM7UUFFekQsTUFBTSxPQUFPLEdBQUcsU0FBUyxDQUFDLElBQUksQ0FBQyxDQUFDLElBQUksRUFBRSxFQUFFLENBQUMsV0FBVyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDO1FBRXBFLElBQUksT0FBTyxFQUFFLENBQUM7WUFDWixPQUFPLElBQUksQ0FBQztRQUNkLENBQUM7UUFFRCxPQUFPLENBQUMsSUFBSSxDQUNWLGdDQUFnQyxTQUFTLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQ3hELENBQUM7UUFDRixPQUFPLE1BQU0sQ0FBQyxhQUFhLENBQUMsQ0FBQyxNQUFNLENBQUMsaUJBQWlCLENBQUMsQ0FBQyxDQUFDO0lBQzFELENBQUMsQ0FBQztBQUNKLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBpbmplY3QgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7XG4gIFJvdXRlcixcbiAgQ2FuQWN0aXZhdGVGbixcbiAgVXJsVHJlZSxcbiAgQWN0aXZhdGVkUm91dGVTbmFwc2hvdCxcbn0gZnJvbSAnQGFuZ3VsYXIvcm91dGVyJztcbmltcG9ydCB7IEF1dGhTZXJ2aWNlIH0gZnJvbSAnLi9hdXRoLnNlcnZpY2UnO1xuaW1wb3J0IHsgVkFMVEVDSF9BVVRIX0NPTkZJRyB9IGZyb20gJy4vY29uZmlnJztcblxuLyoqXG4gKiBHdWFyZCBxdWUgdmVyaWZpY2Egc2kgZWwgdXN1YXJpbyBlc3TDoSBhdXRlbnRpY2Fkby5cbiAqIFJlZGlyaWdlIGEgbG9naW5Sb3V0ZSBzaSBubyBlc3TDoSBhdXRlbnRpY2Fkby5cbiAqXG4gKiBAZXhhbXBsZVxuICogYGBgdHlwZXNjcmlwdFxuICogaW1wb3J0IHsgYXV0aEd1YXJkIH0gZnJvbSAndmFsdGVjaC1jb21wb25lbnRzJztcbiAqXG4gKiBjb25zdCByb3V0ZXM6IFJvdXRlcyA9IFtcbiAqICAge1xuICogICAgIHBhdGg6ICdkYXNoYm9hcmQnLFxuICogICAgIGNhbkFjdGl2YXRlOiBbYXV0aEd1YXJkXSxcbiAqICAgICBsb2FkQ29tcG9uZW50OiAoKSA9PiBpbXBvcnQoJy4vZGFzaGJvYXJkLnBhZ2UnKSxcbiAqICAgfSxcbiAqIF07XG4gKiBgYGBcbiAqL1xuZXhwb3J0IGNvbnN0IGF1dGhHdWFyZDogQ2FuQWN0aXZhdGVGbiA9ICgpOiBib29sZWFuIHwgVXJsVHJlZSA9PiB7XG4gIGNvbnN0IGF1dGhTZXJ2aWNlID0gaW5qZWN0KEF1dGhTZXJ2aWNlKTtcbiAgY29uc3Qgcm91dGVyID0gaW5qZWN0KFJvdXRlcik7XG4gIGNvbnN0IGNvbmZpZyA9IGluamVjdChWQUxURUNIX0FVVEhfQ09ORklHKTtcblxuICBpZiAoYXV0aFNlcnZpY2UuaXNBdXRoZW50aWNhdGVkKCkpIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIHJldHVybiByb3V0ZXIuY3JlYXRlVXJsVHJlZShbY29uZmlnLmxvZ2luUm91dGVdKTtcbn07XG5cbi8qKlxuICogR3VhcmQgcXVlIHZlcmlmaWNhIHNpIGVsIHVzdWFyaW8gTk8gZXN0w6EgYXV0ZW50aWNhZG8uXG4gKiBSZWRpcmlnZSBhIGhvbWVSb3V0ZSBzaSB5YSBlc3TDoSBhdXRlbnRpY2Fkby5cbiAqIMOadGlsIHBhcmEgcMOhZ2luYXMgZGUgbG9naW4vcmVnaXN0cm8uXG4gKlxuICogQGV4YW1wbGVcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIGltcG9ydCB7IGd1ZXN0R3VhcmQgfSBmcm9tICd2YWx0ZWNoLWNvbXBvbmVudHMnO1xuICpcbiAqIGNvbnN0IHJvdXRlczogUm91dGVzID0gW1xuICogICB7XG4gKiAgICAgcGF0aDogJ2xvZ2luJyxcbiAqICAgICBjYW5BY3RpdmF0ZTogW2d1ZXN0R3VhcmRdLFxuICogICAgIGxvYWRDb21wb25lbnQ6ICgpID0+IGltcG9ydCgnLi9sb2dpbi5wYWdlJyksXG4gKiAgIH0sXG4gKiBdO1xuICogYGBgXG4gKi9cbmV4cG9ydCBjb25zdCBndWVzdEd1YXJkOiBDYW5BY3RpdmF0ZUZuID0gKCk6IGJvb2xlYW4gfCBVcmxUcmVlID0+IHtcbiAgY29uc3QgYXV0aFNlcnZpY2UgPSBpbmplY3QoQXV0aFNlcnZpY2UpO1xuICBjb25zdCByb3V0ZXIgPSBpbmplY3QoUm91dGVyKTtcbiAgY29uc3QgY29uZmlnID0gaW5qZWN0KFZBTFRFQ0hfQVVUSF9DT05GSUcpO1xuXG4gIGlmICghYXV0aFNlcnZpY2UuaXNBdXRoZW50aWNhdGVkKCkpIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIHJldHVybiByb3V0ZXIuY3JlYXRlVXJsVHJlZShbY29uZmlnLmhvbWVSb3V0ZV0pO1xufTtcblxuLyoqXG4gKiBGYWN0b3J5IHBhcmEgY3JlYXIgZ3VhcmQgZGUgcGVybWlzb3MuXG4gKiBWZXJpZmljYSBzaSBlbCB1c3VhcmlvIHRpZW5lIGVsIHBlcm1pc28gZXNwZWNpZmljYWRvLlxuICpcbiAqIEBwYXJhbSBwZXJtaXNzaW9ucyAtIFBlcm1pc28gbyBsaXN0YSBkZSBwZXJtaXNvcyByZXF1ZXJpZG9zIChPUilcbiAqIEByZXR1cm5zIEd1YXJkIGZ1bmN0aW9uXG4gKlxuICogQGV4YW1wbGVcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIGltcG9ydCB7IGF1dGhHdWFyZCwgcGVybWlzc2lvbkd1YXJkIH0gZnJvbSAndmFsdGVjaC1jb21wb25lbnRzJztcbiAqXG4gKiBjb25zdCByb3V0ZXM6IFJvdXRlcyA9IFtcbiAqICAge1xuICogICAgIHBhdGg6ICd0ZW1wbGF0ZXMnLFxuICogICAgIGNhbkFjdGl2YXRlOiBbYXV0aEd1YXJkLCBwZXJtaXNzaW9uR3VhcmQoJ3RlbXBsYXRlczpyZWFkJyldLFxuICogICAgIGxvYWRDb21wb25lbnQ6ICgpID0+IGltcG9ydCgnLi90ZW1wbGF0ZXMucGFnZScpLFxuICogICB9LFxuICogICB7XG4gKiAgICAgcGF0aDogJ2FkbWluJyxcbiAqICAgICBjYW5BY3RpdmF0ZTogW2F1dGhHdWFyZCwgcGVybWlzc2lvbkd1YXJkKFsnYWRtaW46KicsICdzdXBlcl9hZG1pbiddKV0sXG4gKiAgICAgbG9hZENvbXBvbmVudDogKCkgPT4gaW1wb3J0KCcuL2FkbWluLnBhZ2UnKSxcbiAqICAgfSxcbiAqIF07XG4gKiBgYGBcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHBlcm1pc3Npb25HdWFyZChcbiAgcGVybWlzc2lvbnM6IHN0cmluZyB8IHN0cmluZ1tdXG4pOiBDYW5BY3RpdmF0ZUZuIHtcbiAgcmV0dXJuICgpOiBib29sZWFuIHwgVXJsVHJlZSA9PiB7XG4gICAgY29uc3QgYXV0aFNlcnZpY2UgPSBpbmplY3QoQXV0aFNlcnZpY2UpO1xuICAgIGNvbnN0IHJvdXRlciA9IGluamVjdChSb3V0ZXIpO1xuICAgIGNvbnN0IGNvbmZpZyA9IGluamVjdChWQUxURUNIX0FVVEhfQ09ORklHKTtcblxuICAgIGNvbnN0IHBlcm1BcnJheSA9IEFycmF5LmlzQXJyYXkocGVybWlzc2lvbnMpID8gcGVybWlzc2lvbnMgOiBbcGVybWlzc2lvbnNdO1xuXG4gICAgaWYgKGF1dGhTZXJ2aWNlLmhhc0FueVBlcm1pc3Npb24ocGVybUFycmF5KSkge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuXG4gICAgY29uc29sZS53YXJuKFxuICAgICAgYFtWYWx0ZWNoQXV0aF0gUGVybWlzbyBkZW5lZ2Fkby4gUmVxdWVyaWRvOiAke3Blcm1BcnJheS5qb2luKCcgbyAnKX1gXG4gICAgKTtcbiAgICByZXR1cm4gcm91dGVyLmNyZWF0ZVVybFRyZWUoW2NvbmZpZy51bmF1dGhvcml6ZWRSb3V0ZV0pO1xuICB9O1xufVxuXG4vKipcbiAqIEd1YXJkIHF1ZSBsZWUgcGVybWlzb3MgZGVzZGUgcm91dGUuZGF0YS5cbiAqIFBlcm1pdGUgY29uZmlndXJhciBwZXJtaXNvcyBkaXJlY3RhbWVudGUgZW4gbGEgZGVmaW5pY2nDs24gZGUgcnV0YXMuXG4gKlxuICogQGV4YW1wbGVcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIGltcG9ydCB7IGF1dGhHdWFyZCwgcGVybWlzc2lvbkd1YXJkRnJvbVJvdXRlIH0gZnJvbSAndmFsdGVjaC1jb21wb25lbnRzJztcbiAqXG4gKiBjb25zdCByb3V0ZXM6IFJvdXRlcyA9IFtcbiAqICAge1xuICogICAgIHBhdGg6ICdhZG1pbi91c2VycycsXG4gKiAgICAgY2FuQWN0aXZhdGU6IFthdXRoR3VhcmQsIHBlcm1pc3Npb25HdWFyZEZyb21Sb3V0ZV0sXG4gKiAgICAgZGF0YToge1xuICogICAgICAgcGVybWlzc2lvbnM6IFsndXNlcnM6cmVhZCcsICd1c2VyczptYW5hZ2UnXSxcbiAqICAgICAgIHJlcXVpcmVBbGw6IGZhbHNlICAvLyB0cnVlID0gQU5ELCBmYWxzZSA9IE9SIChkZWZhdWx0KVxuICogICAgIH0sXG4gKiAgICAgbG9hZENvbXBvbmVudDogKCkgPT4gaW1wb3J0KCcuL3VzZXJzLnBhZ2UnKSxcbiAqICAgfSxcbiAqIF07XG4gKiBgYGBcbiAqL1xuZXhwb3J0IGNvbnN0IHBlcm1pc3Npb25HdWFyZEZyb21Sb3V0ZTogQ2FuQWN0aXZhdGVGbiA9IChcbiAgcm91dGU6IEFjdGl2YXRlZFJvdXRlU25hcHNob3Rcbik6IGJvb2xlYW4gfCBVcmxUcmVlID0+IHtcbiAgY29uc3QgYXV0aFNlcnZpY2UgPSBpbmplY3QoQXV0aFNlcnZpY2UpO1xuICBjb25zdCByb3V0ZXIgPSBpbmplY3QoUm91dGVyKTtcbiAgY29uc3QgY29uZmlnID0gaW5qZWN0KFZBTFRFQ0hfQVVUSF9DT05GSUcpO1xuXG4gIGNvbnN0IHBlcm1pc3Npb25zID0gcm91dGUuZGF0YVsncGVybWlzc2lvbnMnXSBhcyBzdHJpbmdbXSB8IHVuZGVmaW5lZDtcbiAgY29uc3QgcmVxdWlyZUFsbCA9IHJvdXRlLmRhdGFbJ3JlcXVpcmVBbGwnXSBhcyBib29sZWFuIHwgdW5kZWZpbmVkO1xuXG4gIGlmICghcGVybWlzc2lvbnMgfHwgcGVybWlzc2lvbnMubGVuZ3RoID09PSAwKSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICBjb25zdCBoYXNBY2Nlc3MgPSByZXF1aXJlQWxsXG4gICAgPyBhdXRoU2VydmljZS5oYXNBbGxQZXJtaXNzaW9ucyhwZXJtaXNzaW9ucylcbiAgICA6IGF1dGhTZXJ2aWNlLmhhc0FueVBlcm1pc3Npb24ocGVybWlzc2lvbnMpO1xuXG4gIGlmIChoYXNBY2Nlc3MpIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIGNvbnNvbGUud2FybihcbiAgICBgW1ZhbHRlY2hBdXRoXSBQZXJtaXNvIGRlbmVnYWRvLiBSZXF1ZXJpZG86ICR7cGVybWlzc2lvbnMuam9pbihcbiAgICAgIHJlcXVpcmVBbGwgPyAnIHkgJyA6ICcgbyAnXG4gICAgKX1gXG4gICk7XG4gIHJldHVybiByb3V0ZXIuY3JlYXRlVXJsVHJlZShbY29uZmlnLnVuYXV0aG9yaXplZFJvdXRlXSk7XG59O1xuXG4vKipcbiAqIEd1YXJkIHF1ZSB2ZXJpZmljYSBzaSBlbCB1c3VhcmlvIGVzIHN1cGVyIGFkbWluLlxuICpcbiAqIEBleGFtcGxlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiBpbXBvcnQgeyBhdXRoR3VhcmQsIHN1cGVyQWRtaW5HdWFyZCB9IGZyb20gJ3ZhbHRlY2gtY29tcG9uZW50cyc7XG4gKlxuICogY29uc3Qgcm91dGVzOiBSb3V0ZXMgPSBbXG4gKiAgIHtcbiAqICAgICBwYXRoOiAnc3VwZXItYWRtaW4nLFxuICogICAgIGNhbkFjdGl2YXRlOiBbYXV0aEd1YXJkLCBzdXBlckFkbWluR3VhcmRdLFxuICogICAgIGxvYWRDb21wb25lbnQ6ICgpID0+IGltcG9ydCgnLi9zdXBlci1hZG1pbi5wYWdlJyksXG4gKiAgIH0sXG4gKiBdO1xuICogYGBgXG4gKi9cbmV4cG9ydCBjb25zdCBzdXBlckFkbWluR3VhcmQ6IENhbkFjdGl2YXRlRm4gPSAoKTogYm9vbGVhbiB8IFVybFRyZWUgPT4ge1xuICBjb25zdCBhdXRoU2VydmljZSA9IGluamVjdChBdXRoU2VydmljZSk7XG4gIGNvbnN0IHJvdXRlciA9IGluamVjdChSb3V0ZXIpO1xuICBjb25zdCBjb25maWcgPSBpbmplY3QoVkFMVEVDSF9BVVRIX0NPTkZJRyk7XG5cbiAgaWYgKGF1dGhTZXJ2aWNlLmlzU3VwZXJBZG1pbigpKSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICBjb25zb2xlLndhcm4oJ1tWYWx0ZWNoQXV0aF0gQWNjZXNvIGRlIHN1cGVyIGFkbWluIHJlcXVlcmlkbycpO1xuICByZXR1cm4gcm91dGVyLmNyZWF0ZVVybFRyZWUoW2NvbmZpZy51bmF1dGhvcml6ZWRSb3V0ZV0pO1xufTtcblxuLyoqXG4gKiBHdWFyZCBxdWUgdmVyaWZpY2Egc2kgZWwgdXN1YXJpbyB0aWVuZSB1biByb2wgZXNwZWPDrWZpY28uXG4gKlxuICogQHBhcmFtIHJvbGVzIC0gUm9sIG8gbGlzdGEgZGUgcm9sZXMgcmVxdWVyaWRvcyAoT1IpXG4gKiBAcmV0dXJucyBHdWFyZCBmdW5jdGlvblxuICpcbiAqIEBleGFtcGxlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiBpbXBvcnQgeyBhdXRoR3VhcmQsIHJvbGVHdWFyZCB9IGZyb20gJ3ZhbHRlY2gtY29tcG9uZW50cyc7XG4gKlxuICogY29uc3Qgcm91dGVzOiBSb3V0ZXMgPSBbXG4gKiAgIHtcbiAqICAgICBwYXRoOiAnZWRpdG9yJyxcbiAqICAgICBjYW5BY3RpdmF0ZTogW2F1dGhHdWFyZCwgcm9sZUd1YXJkKFsnZWRpdG9yJywgJ2FkbWluJ10pXSxcbiAqICAgICBsb2FkQ29tcG9uZW50OiAoKSA9PiBpbXBvcnQoJy4vZWRpdG9yLnBhZ2UnKSxcbiAqICAgfSxcbiAqIF07XG4gKiBgYGBcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJvbGVHdWFyZChyb2xlczogc3RyaW5nIHwgc3RyaW5nW10pOiBDYW5BY3RpdmF0ZUZuIHtcbiAgcmV0dXJuICgpOiBib29sZWFuIHwgVXJsVHJlZSA9PiB7XG4gICAgY29uc3QgYXV0aFNlcnZpY2UgPSBpbmplY3QoQXV0aFNlcnZpY2UpO1xuICAgIGNvbnN0IHJvdXRlciA9IGluamVjdChSb3V0ZXIpO1xuICAgIGNvbnN0IGNvbmZpZyA9IGluamVjdChWQUxURUNIX0FVVEhfQ09ORklHKTtcblxuICAgIGNvbnN0IHJvbGVBcnJheSA9IEFycmF5LmlzQXJyYXkocm9sZXMpID8gcm9sZXMgOiBbcm9sZXNdO1xuXG4gICAgY29uc3QgaGFzUm9sZSA9IHJvbGVBcnJheS5zb21lKChyb2xlKSA9PiBhdXRoU2VydmljZS5oYXNSb2xlKHJvbGUpKTtcblxuICAgIGlmIChoYXNSb2xlKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG5cbiAgICBjb25zb2xlLndhcm4oXG4gICAgICBgW1ZhbHRlY2hBdXRoXSBSb2wgcmVxdWVyaWRvOiAke3JvbGVBcnJheS5qb2luKCcgbyAnKX1gXG4gICAgKTtcbiAgICByZXR1cm4gcm91dGVyLmNyZWF0ZVVybFRyZWUoW2NvbmZpZy51bmF1dGhvcml6ZWRSb3V0ZV0pO1xuICB9O1xufVxuIl19
@@ -0,0 +1,70 @@
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
+ // Tipos
56
+ export * from './types';
57
+ // Configuración
58
+ export { VALTECH_AUTH_CONFIG, provideValtechAuth, provideValtechAuthInterceptor, DEFAULT_AUTH_CONFIG, } from './config';
59
+ // Servicio principal
60
+ export { AuthService } from './auth.service';
61
+ // Guards
62
+ export { authGuard, guestGuard, permissionGuard, permissionGuardFromRoute, superAdminGuard, roleGuard, } from './guards';
63
+ // Interceptor (para uso avanzado)
64
+ export { authInterceptor } from './interceptor';
65
+ // Servicios internos (para testing o extensión)
66
+ export { AuthStateService } from './auth-state.service';
67
+ export { TokenService } from './token.service';
68
+ export { AuthStorageService } from './storage.service';
69
+ export { AuthSyncService } from './sync.service';
70
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9zcmMvbGliL3NlcnZpY2VzL2F1dGgvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBcURHO0FBRUgsUUFBUTtBQUNSLGNBQWMsU0FBUyxDQUFDO0FBRXhCLGdCQUFnQjtBQUNoQixPQUFPLEVBQ0wsbUJBQW1CLEVBQ25CLGtCQUFrQixFQUNsQiw2QkFBNkIsRUFDN0IsbUJBQW1CLEdBQ3BCLE1BQU0sVUFBVSxDQUFDO0FBRWxCLHFCQUFxQjtBQUNyQixPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFFN0MsU0FBUztBQUNULE9BQU8sRUFDTCxTQUFTLEVBQ1QsVUFBVSxFQUNWLGVBQWUsRUFDZix3QkFBd0IsRUFDeEIsZUFBZSxFQUNmLFNBQVMsR0FDVixNQUFNLFVBQVUsQ0FBQztBQUVsQixrQ0FBa0M7QUFDbEMsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUVoRCxnREFBZ0Q7QUFDaEQsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFDeEQsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQy9DLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBQ3ZELE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogVmFsdGVjaCBBdXRoIFNlcnZpY2VcbiAqXG4gKiBTZXJ2aWNpbyBkZSBhdXRlbnRpY2FjacOzbiByZXV0aWxpemFibGUgcGFyYSBhcGxpY2FjaW9uZXMgQW5ndWxhci5cbiAqIFByb3BvcmNpb25hIGF1dGVudGljYWNpw7NuIGNvbiBBdXRoVjIsIE1GQSwgc2luY3Jvbml6YWNpw7NuIGVudHJlIHBlc3Rhw7FhcyxcbiAqIHkgcmVmcmVzaCBwcm9hY3Rpdm8gZGUgdG9rZW5zLlxuICpcbiAqIEBleGFtcGxlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiAvLyBFbiBtYWluLnRzXG4gKiBpbXBvcnQgeyBib290c3RyYXBBcHBsaWNhdGlvbiB9IGZyb20gJ0Bhbmd1bGFyL3BsYXRmb3JtLWJyb3dzZXInO1xuICogaW1wb3J0IHsgcHJvdmlkZVZhbHRlY2hBdXRoIH0gZnJvbSAndmFsdGVjaC1jb21wb25lbnRzJztcbiAqIGltcG9ydCB7IGVudmlyb25tZW50IH0gZnJvbSAnLi9lbnZpcm9ubWVudHMvZW52aXJvbm1lbnQnO1xuICpcbiAqIGJvb3RzdHJhcEFwcGxpY2F0aW9uKEFwcENvbXBvbmVudCwge1xuICogICBwcm92aWRlcnM6IFtcbiAqICAgICBwcm92aWRlVmFsdGVjaEF1dGgoe1xuICogICAgICAgYXBpVXJsOiBlbnZpcm9ubWVudC5hcGlVcmwsXG4gKiAgICAgICBlbmFibGVGaXJlYmFzZUludGVncmF0aW9uOiB0cnVlLFxuICogICAgIH0pLFxuICogICBdLFxuICogfSk7XG4gKlxuICogLy8gRW4gYXBwLnJvdXRlcy50c1xuICogaW1wb3J0IHsgYXV0aEd1YXJkLCBndWVzdEd1YXJkLCBwZXJtaXNzaW9uR3VhcmQgfSBmcm9tICd2YWx0ZWNoLWNvbXBvbmVudHMnO1xuICpcbiAqIGNvbnN0IHJvdXRlczogUm91dGVzID0gW1xuICogICB7IHBhdGg6ICdsb2dpbicsIGNhbkFjdGl2YXRlOiBbZ3Vlc3RHdWFyZF0sIGxvYWRDb21wb25lbnQ6ICgpID0+IGltcG9ydCgnLi9sb2dpbi5wYWdlJykgfSxcbiAqICAgeyBwYXRoOiAnZGFzaGJvYXJkJywgY2FuQWN0aXZhdGU6IFthdXRoR3VhcmRdLCBsb2FkQ29tcG9uZW50OiAoKSA9PiBpbXBvcnQoJy4vZGFzaGJvYXJkLnBhZ2UnKSB9LFxuICogICB7IHBhdGg6ICdhZG1pbicsIGNhbkFjdGl2YXRlOiBbYXV0aEd1YXJkLCBwZXJtaXNzaW9uR3VhcmQoJ2FkbWluOionKV0sIGxvYWRDb21wb25lbnQ6ICgpID0+IGltcG9ydCgnLi9hZG1pbi5wYWdlJykgfSxcbiAqIF07XG4gKlxuICogLy8gRW4gY29tcG9uZW50ZXNcbiAqIGltcG9ydCB7IEF1dGhTZXJ2aWNlIH0gZnJvbSAndmFsdGVjaC1jb21wb25lbnRzJztcbiAqXG4gKiBAQ29tcG9uZW50KHsuLi59KVxuICogZXhwb3J0IGNsYXNzIExvZ2luQ29tcG9uZW50IHtcbiAqICAgcHJpdmF0ZSBhdXRoID0gaW5qZWN0KEF1dGhTZXJ2aWNlKTtcbiAqXG4gKiAgIGFzeW5jIGxvZ2luKCkge1xuICogICAgIGF3YWl0IGZpcnN0VmFsdWVGcm9tKHRoaXMuYXV0aC5zaWduaW4oeyBlbWFpbCwgcGFzc3dvcmQgfSkpO1xuICogICAgIGlmICh0aGlzLmF1dGgubWZhUGVuZGluZygpLnJlcXVpcmVkKSB7XG4gKiAgICAgICAvLyBNb3N0cmFyIFVJIGRlIE1GQVxuICogICAgIH0gZWxzZSB7XG4gKiAgICAgICB0aGlzLnJvdXRlci5uYXZpZ2F0ZShbJy9kYXNoYm9hcmQnXSk7XG4gKiAgICAgfVxuICogICB9XG4gKlxuICogICAvLyBFbiB0ZW1wbGF0ZTogdXNhciBzaWduYWxzIGRpcmVjdGFtZW50ZVxuICogICAvLyB7eyBhdXRoLnVzZXIoKT8uZW1haWwgfX1cbiAqICAgLy8gQGlmIChhdXRoLmhhc1Blcm1pc3Npb24oJ3RlbXBsYXRlczplZGl0JykpIHsgLi4uIH1cbiAqIH1cbiAqIGBgYFxuICovXG5cbi8vIFRpcG9zXG5leHBvcnQgKiBmcm9tICcuL3R5cGVzJztcblxuLy8gQ29uZmlndXJhY2nDs25cbmV4cG9ydCB7XG4gIFZBTFRFQ0hfQVVUSF9DT05GSUcsXG4gIHByb3ZpZGVWYWx0ZWNoQXV0aCxcbiAgcHJvdmlkZVZhbHRlY2hBdXRoSW50ZXJjZXB0b3IsXG4gIERFRkFVTFRfQVVUSF9DT05GSUcsXG59IGZyb20gJy4vY29uZmlnJztcblxuLy8gU2VydmljaW8gcHJpbmNpcGFsXG5leHBvcnQgeyBBdXRoU2VydmljZSB9IGZyb20gJy4vYXV0aC5zZXJ2aWNlJztcblxuLy8gR3VhcmRzXG5leHBvcnQge1xuICBhdXRoR3VhcmQsXG4gIGd1ZXN0R3VhcmQsXG4gIHBlcm1pc3Npb25HdWFyZCxcbiAgcGVybWlzc2lvbkd1YXJkRnJvbVJvdXRlLFxuICBzdXBlckFkbWluR3VhcmQsXG4gIHJvbGVHdWFyZCxcbn0gZnJvbSAnLi9ndWFyZHMnO1xuXG4vLyBJbnRlcmNlcHRvciAocGFyYSB1c28gYXZhbnphZG8pXG5leHBvcnQgeyBhdXRoSW50ZXJjZXB0b3IgfSBmcm9tICcuL2ludGVyY2VwdG9yJztcblxuLy8gU2VydmljaW9zIGludGVybm9zIChwYXJhIHRlc3RpbmcgbyBleHRlbnNpw7NuKVxuZXhwb3J0IHsgQXV0aFN0YXRlU2VydmljZSB9IGZyb20gJy4vYXV0aC1zdGF0ZS5zZXJ2aWNlJztcbmV4cG9ydCB7IFRva2VuU2VydmljZSB9IGZyb20gJy4vdG9rZW4uc2VydmljZSc7XG5leHBvcnQgeyBBdXRoU3RvcmFnZVNlcnZpY2UgfSBmcm9tICcuL3N0b3JhZ2Uuc2VydmljZSc7XG5leHBvcnQgeyBBdXRoU3luY1NlcnZpY2UgfSBmcm9tICcuL3N5bmMuc2VydmljZSc7XG4iXX0=
@@ -0,0 +1,98 @@
1
+ import { inject } from '@angular/core';
2
+ import { throwError, BehaviorSubject } from 'rxjs';
3
+ import { catchError, filter, take, switchMap, finalize } from 'rxjs/operators';
4
+ import { AuthService } from './auth.service';
5
+ import { VALTECH_AUTH_CONFIG } from './config';
6
+ // Control de estado de refresco (singleton a nivel de módulo)
7
+ let isRefreshing = false;
8
+ const refreshTokenSubject = new BehaviorSubject(null);
9
+ /**
10
+ * Interceptor HTTP que:
11
+ * 1. Agrega header Authorization con Bearer token a requests API
12
+ * 2. Maneja errores 401 refrescando el token automáticamente
13
+ * 3. Encola requests durante el refresco para evitar múltiples refresh
14
+ *
15
+ * @example
16
+ * ```typescript
17
+ * // Incluido automáticamente por provideValtechAuth()
18
+ * // Para uso manual:
19
+ * import { provideHttpClient, withInterceptors } from '@angular/common/http';
20
+ * import { authInterceptor } from 'valtech-components';
21
+ *
22
+ * bootstrapApplication(AppComponent, {
23
+ * providers: [
24
+ * provideHttpClient(withInterceptors([authInterceptor])),
25
+ * ],
26
+ * });
27
+ * ```
28
+ */
29
+ export const authInterceptor = (request, next) => {
30
+ const authService = inject(AuthService);
31
+ const config = inject(VALTECH_AUTH_CONFIG);
32
+ // Omitir requests que no son a nuestra API
33
+ if (!isApiRequest(request, config.apiUrl)) {
34
+ return next(request);
35
+ }
36
+ // Omitir endpoints de auth que no necesitan token
37
+ if (isAuthEndpoint(request, config.authPrefix)) {
38
+ return next(request);
39
+ }
40
+ const accessToken = authService.accessToken();
41
+ // Agregar header de autorización si hay token
42
+ if (accessToken) {
43
+ request = addAuthHeader(request, accessToken);
44
+ }
45
+ return next(request).pipe(catchError((error) => {
46
+ if (error.status === 401 && !isAuthEndpoint(request, config.authPrefix)) {
47
+ return handle401Error(request, next, authService);
48
+ }
49
+ if (error.status === 403) {
50
+ console.error('[ValtechAuth] Permiso denegado:', error.error?.message || 'Acceso prohibido');
51
+ }
52
+ return throwError(() => error);
53
+ }));
54
+ };
55
+ /**
56
+ * Agrega header de autorización a la request.
57
+ */
58
+ function addAuthHeader(request, token) {
59
+ return request.clone({
60
+ setHeaders: {
61
+ Authorization: `Bearer ${token}`,
62
+ },
63
+ });
64
+ }
65
+ /**
66
+ * Verifica si la request es a nuestra API.
67
+ */
68
+ function isApiRequest(request, apiUrl) {
69
+ return request.url.startsWith(apiUrl) || request.url.includes('/v2/auth');
70
+ }
71
+ /**
72
+ * Verifica si la request es a un endpoint de auth que no debe reintentar.
73
+ */
74
+ function isAuthEndpoint(request, authPrefix) {
75
+ const authEndpoints = ['/signin', '/signup', '/refresh', '/logout', '/mfa/verify'];
76
+ return authEndpoints.some((endpoint) => request.url.includes(`${authPrefix}${endpoint}`));
77
+ }
78
+ /**
79
+ * Maneja errores 401 refrescando el token.
80
+ */
81
+ function handle401Error(request, next, authService) {
82
+ if (!isRefreshing) {
83
+ isRefreshing = true;
84
+ refreshTokenSubject.next(null);
85
+ return authService.refreshAccessToken().pipe(switchMap((response) => {
86
+ refreshTokenSubject.next(response.accessToken);
87
+ return next(addAuthHeader(request, response.accessToken));
88
+ }), catchError((error) => {
89
+ authService.logout();
90
+ return throwError(() => error);
91
+ }), finalize(() => {
92
+ isRefreshing = false;
93
+ }));
94
+ }
95
+ // Esperar a que termine el refresco en curso
96
+ return refreshTokenSubject.pipe(filter((token) => token !== null), take(1), switchMap((token) => next(addAuthHeader(request, token))));
97
+ }
98
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW50ZXJjZXB0b3IuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9zcmMvbGliL3NlcnZpY2VzL2F1dGgvaW50ZXJjZXB0b3IudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLGVBQWUsQ0FBQztBQVF2QyxPQUFPLEVBQWMsVUFBVSxFQUFFLGVBQWUsRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUMvRCxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUUsU0FBUyxFQUFFLFFBQVEsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQy9FLE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUM3QyxPQUFPLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSxVQUFVLENBQUM7QUFFL0MsOERBQThEO0FBQzlELElBQUksWUFBWSxHQUFHLEtBQUssQ0FBQztBQUN6QixNQUFNLG1CQUFtQixHQUFHLElBQUksZUFBZSxDQUFnQixJQUFJLENBQUMsQ0FBQztBQUVyRTs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQW1CRztBQUNILE1BQU0sQ0FBQyxNQUFNLGVBQWUsR0FBc0IsQ0FDaEQsT0FBNkIsRUFDN0IsSUFBbUIsRUFDYSxFQUFFO0lBQ2xDLE1BQU0sV0FBVyxHQUFHLE1BQU0sQ0FBQyxXQUFXLENBQUMsQ0FBQztJQUN4QyxNQUFNLE1BQU0sR0FBRyxNQUFNLENBQUMsbUJBQW1CLENBQUMsQ0FBQztJQUUzQywyQ0FBMkM7SUFDM0MsSUFBSSxDQUFDLFlBQVksQ0FBQyxPQUFPLEVBQUUsTUFBTSxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUM7UUFDMUMsT0FBTyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUM7SUFDdkIsQ0FBQztJQUVELGtEQUFrRDtJQUNsRCxJQUFJLGNBQWMsQ0FBQyxPQUFPLEVBQUUsTUFBTSxDQUFDLFVBQVcsQ0FBQyxFQUFFLENBQUM7UUFDaEQsT0FB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Q0FBQztRQUN2QixDQUFDLENBQUMsQ0FDSCxDQUFDO0lBQ0osQ0FBQztJQUVELDZDQUE2QztJQUM3QyxPQUFPLG1CQUFtQixDQUFDLElBQUksQ0FDN0IsTUFBTSxDQUFDLENBQUMsS0FBSyxFQUFtQixFQUFFLENBQUMsS0FBSyxLQUFLLElBQUksQ0FBQyxFQUNsRCxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQ1AsU0FBUyxDQUFDLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLE9BQU8sRUFBRSxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQzFELENBQUM7QUFDSixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgaW5qZWN0IH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQge1xuICBIdHRwSW50ZXJjZXB0b3JGbixcbiAgSHR0cFJlcXVlc3QsXG4gIEh0dHBIYW5kbGVyRm4sXG4gIEh0dHBFdmVudCxcbiAgSHR0cEVycm9yUmVzcG9uc2UsXG59IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbi9odHRwJztcbmltcG9ydCB7IE9ic2VydmFibGUsIHRocm93RXJyb3IsIEJlaGF2aW9yU3ViamVjdCB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgY2F0Y2hFcnJvciwgZmlsdGVyLCB0YWtlLCBzd2l0Y2hNYXAsIGZpbmFsaXplIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuaW1wb3J0IHsgQXV0aFNlcnZpY2UgfSBmcm9tICcuL2F1dGguc2VydmljZSc7XG5pbXBvcnQgeyBWQUxURUNIX0FVVEhfQ09ORklHIH0gZnJvbSAnLi9jb25maWcnO1xuXG4vLyBDb250cm9sIGRlIGVzdGFkbyBkZSByZWZyZXNjbyAoc2luZ2xldG9uIGEgbml2ZWwgZGUgbcOzZHVsbylcbmxldCBpc1JlZnJlc2hpbmcgPSBmYWxzZTtcbmNvbnN0IHJlZnJlc2hUb2tlblN1YmplY3QgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PHN0cmluZyB8IG51bGw+KG51bGwpO1xuXG4vKipcbiAqIEludGVyY2VwdG9yIEhUVFAgcXVlOlxuICogMS4gQWdyZWdhIGhlYWRlciBBdXRob3JpemF0aW9uIGNvbiBCZWFyZXIgdG9rZW4gYSByZXF1ZXN0cyBBUElcbiAqIDIuIE1hbmVqYSBlcnJvcmVzIDQwMSByZWZyZXNjYW5kbyBlbCB0b2tlbiBhdXRvbcOhdGljYW1lbnRlXG4gKiAzLiBFbmNvbGEgcmVxdWVzdHMgZHVyYW50ZSBlbCByZWZyZXNjbyBwYXJhIGV2aXRhciBtw7psdGlwbGVzIHJlZnJlc2hcbiAqXG4gKiBAZXhhbXBsZVxuICogYGBgdHlwZXNjcmlwdFxuICogLy8gSW5jbHVpZG8gYXV0b23DoXRpY2FtZW50ZSBwb3IgcHJvdmlkZVZhbHRlY2hBdXRoKClcbiAqIC8vIFBhcmEgdXNvIG1hbnVhbDpcbiAqIGltcG9ydCB7IHByb3ZpZGVIdHRwQ2xpZW50LCB3aXRoSW50ZXJjZXB0b3JzIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uL2h0dHAnO1xuICogaW1wb3J0IHsgYXV0aEludGVyY2VwdG9yIH0gZnJvbSAndmFsdGVjaC1jb21wb25lbnRzJztcbiAqXG4gKiBib290c3RyYXBBcHBsaWNhdGlvbihBcHBDb21wb25lbnQsIHtcbiAqICAgcHJvdmlkZXJzOiBbXG4gKiAgICAgcHJvdmlkZUh0dHBDbGllbnQod2l0aEludGVyY2VwdG9ycyhbYXV0aEludGVyY2VwdG9yXSkpLFxuICogICBdLFxuICogfSk7XG4gKiBgYGBcbiAqL1xuZXhwb3J0IGNvbnN0IGF1dGhJbnRlcmNlcHRvcjogSHR0cEludGVyY2VwdG9yRm4gPSAoXG4gIHJlcXVlc3Q6IEh0dHBSZXF1ZXN0PHVua25vd24+LFxuICBuZXh0OiBIdHRwSGFuZGxlckZuXG4pOiBPYnNlcnZhYmxlPEh0dHBFdmVudDx1bmtub3duPj4gPT4ge1xuICBjb25zdCBhdXRoU2VydmljZSA9IGluamVjdChBdXRoU2VydmljZSk7XG4gIGNvbnN0IGNvbmZpZyA9IGluamVjdChWQUxURUNIX0FVVEhfQ09ORklHKTtcblxuICAvLyBPbWl0aXIgcmVxdWVzdHMgcXVlIG5vIHNvbiBhIG51ZXN0cmEgQVBJXG4gIGlmICghaXNBcGlSZXF1ZXN0KHJlcXVlc3QsIGNvbmZpZy5hcGlVcmwpKSB7XG4gICAgcmV0dXJuIG5leHQocmVxdWVzdCk7XG4gIH1cblxuICAvLyBPbWl0aXIgZW5kcG9pbnRzIGRlIGF1dGggcXVlIG5vIG5lY2VzaXRhbiB0b2tlblxuICBpZiAoaXNBdXRoRW5kcG9pbnQocmVxdWVzdCwgY29uZmlnLmF1dGhQcmVmaXghKSkge1xuICAgIHJldHVybiBuZXh0KHJlcXVlc3QpO1xuICB9XG5cbiAgY29uc3QgYWNjZXNzVG9rZW4gPSBhdXRoU2VydmljZS5hY2Nlc3NUb2tlbigpO1xuXG4gIC8vIEFncmVnYXIgaGVhZGVyIGRlIGF1dG9yaXphY2nDs24gc2kgaGF5IHRva2VuXG4gIGlmIChhY2Nlc3NUb2tlbikge1xuICAgIHJlcXVlc3QgPSBhZGRBdXRoSGVhZGVyKHJlcXVlc3QsIGFjY2Vzc1Rva2VuKTtcbiAgfVxuXG4gIHJldHVybiBuZXh0KHJlcXVlc3QpLnBpcGUoXG4gICAgY2F0Y2hFcnJvcigoZXJyb3I6IEh0dHBFcnJvclJlc3BvbnNlKSA9PiB7XG4gICAgICBpZiAoZXJyb3Iuc3RhdHVzID09PSA0MDEgJiYgIWlzQXV0aEVuZHBvaW50KHJlcXVlc3QsIGNvbmZpZy5hdXRoUHJlZml4ISkpIHtcbiAgICAgICAgcmV0dXJuIGhhbmRsZTQwMUVycm9yKHJlcXVlc3QsIG5leHQsIGF1dGhTZXJ2aWNlKTtcbiAgICAgIH1cblxuICAgICAgaWYgKGVycm9yLnN0YXR1cyA9PT0gNDAzKSB7XG4gICAgICAgIGNvbnNvbGUuZXJyb3IoXG4gICAgICAgICAgJ1tWYWx0ZWNoQXV0aF0gUGVybWlzbyBkZW5lZ2FkbzonLFxuICAgICAgICAgIGVycm9yLmVycm9yPy5tZXNzYWdlIHx8ICdBY2Nlc28gcHJvaGliaWRvJ1xuICAgICAgICApO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gdGhyb3dFcnJvcigoKSA9PiBlcnJvcik7XG4gICAgfSlcbiAgKTtcbn07XG5cbi8qKlxuICogQWdyZWdhIGhlYWRlciBkZSBhdXRvcml6YWNpw7NuIGEgbGEgcmVxdWVzdC5cbiAqL1xuZnVuY3Rpb24gYWRkQXV0aEhlYWRlcihcbiAgcmVxdWVzdDogSHR0cFJlcXVlc3Q8dW5rbm93bj4sXG4gIHRva2VuOiBzdHJpbmdcbik6IEh0dHBSZXF1ZXN0PHVua25vd24+IHtcbiAgcmV0dXJuIHJlcXVlc3QuY2xvbmUoe1xuICAgIHNldEhlYWRlcnM6IHtcbiAgICAgIEF1dGhvcml6YXRpb246IGBCZWFyZXIgJHt0b2tlbn1gLFxuICAgIH0sXG4gIH0pO1xufVxuXG4vKipcbiAqIFZlcmlmaWNhIHNpIGxhIHJlcXVlc3QgZXMgYSBudWVzdHJhIEFQSS5cbiAqL1xuZnVuY3Rpb24gaXNBcGlSZXF1ZXN0KHJlcXVlc3Q6IEh0dHBSZXF1ZXN0PHVua25vd24+LCBhcGlVcmw6IHN0cmluZyk6IGJvb2xlYW4ge1xuICByZXR1cm4gcmVxdWVzdC51cmwuc3RhcnRzV2l0aChhcGlVcmwpIHx8IHJlcXVlc3QudXJsLmluY2x1ZGVzKCcvdjIvYXV0aCcpO1xufVxuXG4vKipcbiAqIFZlcmlmaWNhIHNpIGxhIHJlcXVlc3QgZXMgYSB1biBlbmRwb2ludCBkZSBhdXRoIHF1ZSBubyBkZWJlIHJlaW50ZW50YXIuXG4gKi9cbmZ1bmN0aW9uIGlzQXV0aEVuZHBvaW50KFxuICByZXF1ZXN0OiBIdHRwUmVxdWVzdDx1bmtub3duPixcbiAgYXV0aFByZWZpeDogc3RyaW5nXG4pOiBib29sZWFuIHtcbiAgY29uc3QgYXV0aEVuZHBvaW50cyA9IFsnL3NpZ25pbicsICcvc2lnbnVwJywgJy9yZWZyZXNoJywgJy9sb2dvdXQnLCAnL21mYS92ZXJpZnknXTtcbiAgcmV0dXJuIGF1dGhFbmRwb2ludHMuc29tZSgoZW5kcG9pbnQpID0+XG4gICAgcmVxdWVzdC51cmwuaW5jbHVkZXMoYCR7YXV0aFByZWZpeH0ke2VuZHBvaW50fWApXG4gICk7XG59XG5cbi8qKlxuICogTWFuZWphIGVycm9yZXMgNDAxIHJlZnJlc2NhbmRvIGVsIHRva2VuLlxuICovXG5mdW5jdGlvbiBoYW5kbGU0MDFFcnJvcihcbiAgcmVxdWVzdDogSHR0cFJlcXVlc3Q8dW5rbm93bj4sXG4gIG5leHQ6IEh0dHBIYW5kbGVyRm4sXG4gIGF1dGhTZXJ2aWNlOiBBdXRoU2VydmljZVxuKTogT2JzZXJ2YWJsZTxIdHRwRXZlbnQ8dW5rbm93bj4+IHtcbiAgaWYgKCFpc1JlZnJlc2hpbmcpIHtcbiAgICBpc1JlZnJlc2hpbmcgPSB0cnVlO1xuICAgIHJlZnJlc2hUb2tlblN1YmplY3QubmV4dChudWxsKTtcblxuICAgIHJldHVybiBhdXRoU2VydmljZS5yZWZyZXNoQWNjZXNzVG9rZW4oKS5waXBlKFxuICAgICAgc3dpdGNoTWFwKChyZXNwb25zZSkgPT4ge1xuICAgICAgICByZWZyZXNoVG9rZW5TdWJqZWN0Lm5leHQocmVzcG9uc2UuYWNjZXNzVG9rZW4pO1xuICAgICAgICByZXR1cm4gbmV4dChhZGRBdXRoSGVhZGVyKHJlcXVlc3QsIHJlc3BvbnNlLmFjY2Vzc1Rva2VuKSk7XG4gICAgICB9KSxcbiAgICAgIGNhdGNoRXJyb3IoKGVycm9yKSA9PiB7XG4gICAgICAgIGF1dGhTZXJ2aWNlLmxvZ291dCgpO1xuICAgICAgICByZXR1cm4gdGhyb3dFcnJvcigoKSA9PiBlcnJvcik7XG4gICAgICB9KSxcbiAgICAgIGZpbmFsaXplKCgpID0+IHtcbiAgICAgICAgaXNSZWZyZXNoaW5nID0gZmFsc2U7XG4gICAgICB9KVxuICAgICk7XG4gIH1cblxuICAvLyBFc3BlcmFyIGEgcXVlIHRlcm1pbmUgZWwgcmVmcmVzY28gZW4gY3Vyc29cbiAgcmV0dXJuIHJlZnJlc2hUb2tlblN1YmplY3QucGlwZShcbiAgICBmaWx0ZXIoKHRva2VuKTogdG9rZW4gaXMgc3RyaW5nID0+IHRva2VuICE9PSBudWxsKSxcbiAgICB0YWtlKDEpLFxuICAgIHN3aXRjaE1hcCgodG9rZW4pID0+IG5leHQoYWRkQXV0aEhlYWRlcihyZXF1ZXN0LCB0b2tlbikpKVxuICApO1xufVxuIl19
@@ -0,0 +1,138 @@
1
+ import { Injectable, inject } from '@angular/core';
2
+ import { VALTECH_AUTH_CONFIG } from './config';
3
+ import * as i0 from "@angular/core";
4
+ /**
5
+ * Servicio para persistencia de estado de autenticación en localStorage.
6
+ */
7
+ export class AuthStorageService {
8
+ constructor() {
9
+ this.config = inject(VALTECH_AUTH_CONFIG);
10
+ const prefix = this.config.storagePrefix || 'valtech_auth_';
11
+ this.keys = {
12
+ ACCESS_TOKEN: `${prefix}access_token`,
13
+ REFRESH_TOKEN: `${prefix}refresh_token`,
14
+ ROLES: `${prefix}roles`,
15
+ PERMISSIONS: `${prefix}permissions`,
16
+ IS_SUPER_ADMIN: `${prefix}is_super_admin`,
17
+ EXPIRES_AT: `${prefix}expires_at`,
18
+ };
19
+ }
20
+ /**
21
+ * Guarda el estado completo de autenticación.
22
+ */
23
+ saveState(state) {
24
+ try {
25
+ localStorage.setItem(this.keys.ACCESS_TOKEN, state.accessToken);
26
+ localStorage.setItem(this.keys.REFRESH_TOKEN, state.refreshToken);
27
+ localStorage.setItem(this.keys.ROLES, JSON.stringify(state.roles));
28
+ localStorage.setItem(this.keys.PERMISSIONS, JSON.stringify(state.permissions));
29
+ localStorage.setItem(this.keys.IS_SUPER_ADMIN, String(state.isSuperAdmin));
30
+ if (state.expiresAt) {
31
+ localStorage.setItem(this.keys.EXPIRES_AT, String(state.expiresAt));
32
+ }
33
+ }
34
+ catch (e) {
35
+ console.warn('[ValtechAuth] Error guardando estado en storage:', e);
36
+ }
37
+ }
38
+ /**
39
+ * Carga el estado de autenticación desde storage.
40
+ */
41
+ loadState() {
42
+ try {
43
+ const accessToken = localStorage.getItem(this.keys.ACCESS_TOKEN);
44
+ const refreshToken = localStorage.getItem(this.keys.REFRESH_TOKEN);
45
+ const rolesJson = localStorage.getItem(this.keys.ROLES);
46
+ const permissionsJson = localStorage.getItem(this.keys.PERMISSIONS);
47
+ const isSuperAdmin = localStorage.getItem(this.keys.IS_SUPER_ADMIN) === 'true';
48
+ const expiresAtStr = localStorage.getItem(this.keys.EXPIRES_AT);
49
+ return {
50
+ accessToken: accessToken || undefined,
51
+ refreshToken: refreshToken || undefined,
52
+ roles: rolesJson ? JSON.parse(rolesJson) : [],
53
+ permissions: permissionsJson ? JSON.parse(permissionsJson) : [],
54
+ isSuperAdmin,
55
+ expiresAt: expiresAtStr ? Number(expiresAtStr) : undefined,
56
+ };
57
+ }
58
+ catch (e) {
59
+ console.warn('[ValtechAuth] Error cargando estado desde storage:', e);
60
+ return {};
61
+ }
62
+ }
63
+ /**
64
+ * Guarda solo el access token.
65
+ */
66
+ saveAccessToken(token, expiresAt) {
67
+ try {
68
+ localStorage.setItem(this.keys.ACCESS_TOKEN, token);
69
+ if (expiresAt) {
70
+ localStorage.setItem(this.keys.EXPIRES_AT, String(expiresAt));
71
+ }
72
+ }
73
+ catch (e) {
74
+ console.warn('[ValtechAuth] Error guardando access token:', e);
75
+ }
76
+ }
77
+ /**
78
+ * Guarda los permisos actualizados.
79
+ */
80
+ savePermissions(response) {
81
+ try {
82
+ localStorage.setItem(this.keys.ROLES, JSON.stringify(response.roles));
83
+ localStorage.setItem(this.keys.PERMISSIONS, JSON.stringify(response.permissions));
84
+ localStorage.setItem(this.keys.IS_SUPER_ADMIN, String(response.isSuperAdmin));
85
+ }
86
+ catch (e) {
87
+ console.warn('[ValtechAuth] Error guardando permisos:', e);
88
+ }
89
+ }
90
+ /**
91
+ * Carga los permisos desde storage.
92
+ */
93
+ loadPermissions() {
94
+ try {
95
+ const rolesJson = localStorage.getItem(this.keys.ROLES);
96
+ const permissionsJson = localStorage.getItem(this.keys.PERMISSIONS);
97
+ const isSuperAdmin = localStorage.getItem(this.keys.IS_SUPER_ADMIN) === 'true';
98
+ return {
99
+ roles: rolesJson ? JSON.parse(rolesJson) : [],
100
+ permissions: permissionsJson ? JSON.parse(permissionsJson) : [],
101
+ isSuperAdmin,
102
+ };
103
+ }
104
+ catch {
105
+ return { roles: [], permissions: [], isSuperAdmin: false };
106
+ }
107
+ }
108
+ /**
109
+ * Obtiene el refresh token.
110
+ */
111
+ getRefreshToken() {
112
+ return localStorage.getItem(this.keys.REFRESH_TOKEN);
113
+ }
114
+ /**
115
+ * Limpia todo el estado de autenticación.
116
+ */
117
+ clear() {
118
+ try {
119
+ Object.values(this.keys).forEach((key) => localStorage.removeItem(key));
120
+ }
121
+ catch (e) {
122
+ console.warn('[ValtechAuth] Error limpiando storage:', e);
123
+ }
124
+ }
125
+ /**
126
+ * Verifica si hay estado guardado.
127
+ */
128
+ hasStoredState() {
129
+ return !!localStorage.getItem(this.keys.ACCESS_TOKEN);
130
+ }
131
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: AuthStorageService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
132
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: AuthStorageService, providedIn: 'root' }); }
133
+ }
134
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: AuthStorageService, decorators: [{
135
+ type: Injectable,
136
+ args: [{ providedIn: 'root' }]
137
+ }], ctorParameters: () => [] });
138
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RvcmFnZS5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vc3JjL2xpYi9zZXJ2aWNlcy9hdXRoL3N0b3JhZ2Uuc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUNuRCxPQUFPLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSxVQUFVLENBQUM7O0FBZS9DOztHQUVHO0FBRUgsTUFBTSxPQUFPLGtCQUFrQjtJQUk3QjtRQUhRLFdBQU0sR0FBRyxNQUFNLENBQUMsbUJBQW1CLENBQUMsQ0FBQztRQUkzQyxNQUFNLE1BQU0sR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLGFBQWEsSUFBSSxlQUFlLENBQUM7UUFDNUQsSUFBSSxDQUFDLElBQUksR0FBRztZQUNWLFlBQVksRUFBRSxHQUFHLE1BQU0sY0FBYztZQUNyQyxhQUFhLEVBQUUsR0FBRyxNQUFNLGVBQWU7WUFDdkMsS0FBSyxFQUFFLEdBQUcsTUFBTSxPQUFPO1lBQ3ZCLFdBQVcsRUFBRSxHQUFHLE1BQU0sYUFBYTtZQUNuQyxjQUFjLEVBQUUsR0FBRyxNQUFNLGdCQUFnQjtZQUN6QyxVQUFVLEVBQUUsR0FBRyxNQUFNLFlBQVk7U0FDbEMsQ0FBQztJQUNKLENBQUM7SUFFRDs7T0FFRztJQUNILFNBQVMsQ0FBQyxLQUFzQjtRQUM5QixJQUFJLENBQUM7WUFDSCxZQUFZLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsWUFBWSxFQUFFLEtBQUssQ0FBQyxXQUFXLENBQUMsQ0FBQztZQUNoRSxZQUFZLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsYUFBYSxFQUFFLEtBQUssQ0FBQyxZQUFZLENBQUMsQ0FBQztZQUNsRSxZQUFZLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxFQUFFLElBQUksQ0FBQyxT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QUFDLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxlQUFlLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRTtnQkFDL0QsWUFBWTthQUNiLENBQUM7UUFDSixDQUFDO1FBQUMsTUFBTSxDQUFDO1lBQ1AsT0FBTyxFQUFFLEtBQUssRUFBRSxFQUFFLEVBQUUsV0FBVyxFQUFFLEVBQUUsRUFBRSxZQUFZLEVBQUUsS0FBSyxFQUFFLENBQUM7UUFDN0QsQ0FBQztJQUNILENBQUM7SUFFRDs7T0FFRztJQUNILGVBQWU7UUFDYixPQUFPLFlBQVksQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsQ0FBQztJQUN2RCxDQUFDO0lBRUQ7O09BRUc7SUFDSCxLQUFLO1FBQ0gsSUFBSSxDQUFDO1lBQ0gsTUFBTSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsR0FBRyxFQUFFLEVBQUUsQ0FBQyxZQUFZLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7UUFDMUUsQ0FBQztRQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUM7WUFDWCxPQUFPLENBQUMsSUFBSSxDQUFDLHdDQUF3QyxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBQzVELENBQUM7SUFDSCxDQUFDO0lBRUQ7O09BRUc7SUFDSCxjQUFjO1FBQ1osT0FBTyxDQUFDLENBQUMsWUFBWSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxDQUFDO0lBQ3hELENBQUM7K0dBbkpVLGtCQUFrQjttSEFBbEIsa0JBQWtCLGNBREwsTUFBTTs7NEZBQ25CLGtCQUFrQjtrQkFEOUIsVUFBVTttQkFBQyxFQUFFLFVBQVUsRUFBRSxNQUFNLEVBQUUiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBJbmplY3RhYmxlLCBpbmplY3QgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IFZBTFRFQ0hfQVVUSF9DT05GSUcgfSBmcm9tICcuL2NvbmZpZyc7XG5pbXBvcnQgeyBTdG9yZWRBdXRoU3RhdGUsIEdldFBlcm1pc3Npb25zUmVzcG9uc2UgfSBmcm9tICcuL3R5cGVzJztcblxuLyoqXG4gKiBDbGF2ZXMgZGUgc3RvcmFnZSBwYXJhIGF1dGVudGljYWNpw7NuLlxuICovXG5pbnRlcmZhY2UgU3RvcmFnZUtleXMge1xuICBBQ0NFU1NfVE9LRU46IHN0cmluZztcbiAgUkVGUkVTSF9UT0tFTjogc3RyaW5nO1xuICBST0xFUzogc3RyaW5nO1xuICBQRVJNSVNTSU9OUzogc3RyaW5nO1xuICBJU19TVVBFUl9BRE1JTjogc3RyaW5nO1xuICBFWFBJUkVTX0FUOiBzdHJpbmc7XG59XG5cbi8qKlxuICogU2VydmljaW8gcGFyYSBwZXJzaXN0ZW5jaWEgZGUgZXN0YWRvIGRlIGF1dGVudGljYWNpw7NuIGVuIGxvY2FsU3RvcmFnZS5cbiAqL1xuQEluamVjdGFibGUoeyBwcm92aWRlZEluOiAncm9vdCcgfSlcbmV4cG9ydCBjbGFzcyBBdXRoU3RvcmFnZVNlcnZpY2Uge1xuICBwcml2YXRlIGNvbmZpZyA9IGluamVjdChWQUxURUNIX0FVVEhfQ09ORklHKTtcbiAgcHJpdmF0ZSBrZXlzOiBTdG9yYWdlS2V5cztcblxuICBjb25zdHJ1Y3RvcigpIHtcbiAgICBjb25zdCBwcmVmaXggPSB0aGlzLmNvbmZpZy5zdG9yYWdlUHJlZml4IHx8ICd2YWx0ZWNoX2F1dGhfJztcbiAgICB0aGlzLmtleXMgPSB7XG4gICAgICBBQ0NFU1NfVE9LRU46IGAke3ByZWZpeH1hY2Nlc3NfdG9rZW5gLFxuICAgICAgUkVGUkVTSF9UT0tFTjogYCR7cHJlZml4fXJlZnJlc2hfdG9rZW5gLFxuICAgICAgUk9MRVM6IGAke3ByZWZpeH1yb2xlc2AsXG4gICAgICBQRVJNSVNTSU9OUzogYCR7cHJlZml4fXBlcm1pc3Npb25zYCxcbiAgICAgIElTX1NVUEVSX0FETUlOOiBgJHtwcmVmaXh9aXNfc3VwZXJfYWRtaW5gLFxuICAgICAgRVhQSVJFU19BVDogYCR7cHJlZml4fWV4cGlyZXNfYXRgLFxuICAgIH07XG4gIH1cblxuICAvKipcbiAgICogR3VhcmRhIGVsIGVzdGFkbyBjb21wbGV0byBkZSBhdXRlbnRpY2FjacOzbi5cbiAgICovXG4gIHNhdmVTdGF0ZShzdGF0ZTogU3RvcmVkQXV0aFN0YXRlKTogdm9pZCB7XG4gICAgdHJ5IHtcbiAgICAgIGxvY2FsU3RvcmFnZS5zZXRJdGVtKHRoaXMua2V5cy5BQ0NFU1NfVE9LRU4sIHN0YXRlLmFjY2Vzc1Rva2VuKTtcbiAgICAgIGxvY2FsU3RvcmFnZS5zZXRJdGVtKHRoaXMua2V5cy5SRUZSRVNIX1RPS0VOLCBzdGF0ZS5yZWZyZXNoVG9rZW4pO1xuICAgICAgbG9jYWxTdG9yYWdlLnNldEl0ZW0odGhpcy5rZXlzLlJPTEVTLCBKU09OLnN0cmluZ2lmeShzdGF0ZS5yb2xlcykpO1xuICAgICAgbG9jYWxTdG9yYWdlLnNldEl0ZW0oXG4gICAgICAgIHRoaXMua2V5cy5QRVJNSVNTSU9OUyxcbiAgICAgICAgSlNPTi5zdHJpbmdpZnkoc3RhdGUucGVybWlzc2lvbnMpXG4gICAgICApO1xuICAgICAgbG9jYWxTdG9yYWdlLnNldEl0ZW0oXG4gICAgICAgIHRoaXMua2V5cy5JU19TVVBFUl9BRE1JTixcbiAgICAgICAgU3RyaW5nKHN0YXRlLmlzU3VwZXJBZG1pbilcbiAgICAgICk7XG4gICAgICBpZiAoc3RhdGUuZXhwaXJlc0F0KSB7XG4gICAgICAgIGxvY2FsU3RvcmFnZS5zZXRJdGVtKHRoaXMua2V5cy5FWFBJUkVTX0FULCBTdHJpbmcoc3RhdGUuZXhwaXJlc0F0KSk7XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgY29uc29sZS53YXJuKCdbVmFsdGVjaEF1dGhdIEVycm9yIGd1YXJkYW5kbyBlc3RhZG8gZW4gc3RvcmFnZTonLCBlKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQ2FyZ2EgZWwgZXN0YWRvIGRlIGF1dGVudGljYWNpw7NuIGRlc2RlIHN0b3JhZ2UuXG4gICAqL1xuICBsb2FkU3RhdGUoKTogUGFydGlhbDxTdG9yZWRBdXRoU3RhdGU+IHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgYWNjZXNzVG9rZW4gPSBsb2NhbFN0b3JhZ2UuZ2V0SXRlbSh0aGlzLmtleXMuQUNDRVNTX1RPS0VOKTtcbiAgICAgIGNvbnN0IHJlZnJlc2hUb2tlbiA9IGxvY2FsU3RvcmFnZS5nZXRJdGVtKHRoaXMua2V5cy5SRUZSRVNIX1RPS0VOKTtcbiAgICAgIGNvbnN0IHJvbGVzSnNvbiA9IGxvY2FsU3RvcmFnZS5nZXRJdGVtKHRoaXMua2V5cy5ST0xFUyk7XG4gICAgICBjb25zdCBwZXJtaXNzaW9uc0pzb24gPSBsb2NhbFN0b3JhZ2UuZ2V0SXRlbSh0aGlzLmtleXMuUEVSTUlTU0lPTlMpO1xuICAgICAgY29uc3QgaXNTdXBlckFkbWluID1cbiAgICAgICAgbG9jYWxTdG9yYWdlLmdldEl0ZW0odGhpcy5rZXlzLklTX1NVUEVSX0FETUlOKSA9PT0gJ3RydWUnO1xuICAgICAgY29uc3QgZXhwaXJlc0F0U3RyID0gbG9jYWxTdG9yYWdlLmdldEl0ZW0odGhpcy5rZXlzLkVYUElSRVNfQVQpO1xuXG4gICAgICByZXR1cm4ge1xuICAgICAgICBhY2Nlc3NUb2tlbjogYWNjZXNzVG9rZW4gfHwgdW5kZWZpbmVkLFxuICAgICAgICByZWZyZXNoVG9rZW46IHJlZnJlc2hUb2tlbiB8fCB1bmRlZmluZWQsXG4gICAgICAgIHJvbGVzOiByb2xlc0pzb24gPyBKU09OLnBhcnNlKHJvbGVzSnNvbikgOiBbXSxcbiAgICAgICAgcGVybWlzc2lvbnM6IHBlcm1pc3Npb25zSnNvbiA/IEpTT04ucGFyc2UocGVybWlzc2lvbnNKc29uKSA6IFtdLFxuICAgICAgICBpc1N1cGVyQWRtaW4sXG4gICAgICAgIGV4cGlyZXNBdDogZXhwaXJlc0F0U3RyID8gTnVtYmVyKGV4cGlyZXNBdFN0cikgOiB1bmRlZmluZWQsXG4gICAgICB9O1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIGNvbnNvbGUud2FybignW1ZhbHRlY2hBdXRoXSBFcnJvciBjYXJnYW5kbyBlc3RhZG8gZGVzZGUgc3RvcmFnZTonLCBlKTtcbiAgICAgIHJldHVybiB7fTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogR3VhcmRhIHNvbG8gZWwgYWNjZXNzIHRva2VuLlxuICAgKi9cbiAgc2F2ZUFjY2Vzc1Rva2VuKHRva2VuOiBzdHJpbmcsIGV4cGlyZXNBdD86IG51bWJlcik6IHZvaWQge1xuICAgIHRyeSB7XG4gICAgICBsb2NhbFN0b3JhZ2Uuc2V0SXRlbSh0aGlzLmtleXMuQUNDRVNTX1RPS0VOLCB0b2tlbik7XG4gICAgICBpZiAoZXhwaXJlc0F0KSB7XG4gICAgICAgIGxvY2FsU3RvcmFnZS5zZXRJdGVtKHRoaXMua2V5cy5FWFBJUkVTX0FULCBTdHJpbmcoZXhwaXJlc0F0KSk7XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgY29uc29sZS53YXJuKCdbVmFsdGVjaEF1dGhdIEVycm9yIGd1YXJkYW5kbyBhY2Nlc3MgdG9rZW46JywgZSk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEd1YXJkYSBsb3MgcGVybWlzb3MgYWN0dWFsaXphZG9zLlxuICAgKi9cbiAgc2F2ZVBlcm1pc3Npb25zKHJlc3BvbnNlOiBHZXRQZXJtaXNzaW9uc1Jlc3BvbnNlKTogdm9pZCB7XG4gICAgdHJ5IHtcbiAgICAgIGxvY2FsU3RvcmFnZS5zZXRJdGVtKHRoaXMua2V5cy5ST0xFUywgSlNPTi5zdHJpbmdpZnkocmVzcG9uc2Uucm9sZXMpKTtcbiAgICAgIGxvY2FsU3RvcmFnZS5zZXRJdGVtKFxuICAgICAgICB0aGlzLmtleXMuUEVSTUlTU0lPTlMsXG4gICAgICAgIEpTT04uc3RyaW5naWZ5KHJlc3BvbnNlLnBlcm1pc3Npb25zKVxuICAgICAgKTtcbiAgICAgIGxvY2FsU3RvcmFnZS5zZXRJdGVtKFxuICAgICAgICB0aGlzLmtleXMuSVNfU1VQRVJfQURNSU4sXG4gICAgICAgIFN0cmluZyhyZXNwb25zZS5pc1N1cGVyQWRtaW4pXG4gICAgICApO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIGNvbnNvbGUud2FybignW1ZhbHRlY2hBdXRoXSBFcnJvciBndWFyZGFuZG8gcGVybWlzb3M6JywgZSk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIENhcmdhIGxvcyBwZXJtaXNvcyBkZXNkZSBzdG9yYWdlLlxuICAgKi9cbiAgbG9hZFBlcm1pc3Npb25zKCk6IHtcbiAgICByb2xlczogc3RyaW5nW107XG4gICAgcGVybWlzc2lvbnM6IHN0cmluZ1tdO1xuICAgIGlzU3VwZXJBZG1pbjogYm9vbGVhbjtcbiAgfSB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHJvbGVzSnNvbiA9IGxvY2FsU3RvcmFnZS5nZXRJdGVtKHRoaXMua2V5cy5ST0xFUyk7XG4gICAgICBjb25zdCBwZXJtaXNzaW9uc0pzb24gPSBsb2NhbFN0b3JhZ2UuZ2V0SXRlbSh0aGlzLmtleXMuUEVSTUlTU0lPTlMpO1xuICAgICAgY29uc3QgaXNTdXBlckFkbWluID1cbiAgICAgICAgbG9jYWxTdG9yYWdlLmdldEl0ZW0odGhpcy5rZXlzLklTX1NVUEVSX0FETUlOKSA9PT0gJ3RydWUnO1xuXG4gICAgICByZXR1cm4ge1xuICAgICAgICByb2xlczogcm9sZXNKc29uID8gSlNPTi5wYXJzZShyb2xlc0pzb24pIDogW10sXG4gICAgICAgIHBlcm1pc3Npb25zOiBwZXJtaXNzaW9uc0pzb24gPyBKU09OLnBhcnNlKHBlcm1pc3Npb25zSnNvbikgOiBbXSxcbiAgICAgICAgaXNTdXBlckFkbWluLFxuICAgICAgfTtcbiAgICB9IGNhdGNoIHtcbiAgICAgIHJldHVybiB7IHJvbGVzOiBbXSwgcGVybWlzc2lvbnM6IFtdLCBpc1N1cGVyQWRtaW46IGZhbHNlIH07XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIE9idGllbmUgZWwgcmVmcmVzaCB0b2tlbi5cbiAgICovXG4gIGdldFJlZnJlc2hUb2tlbigpOiBzdHJpbmcgfCBudWxsIHtcbiAgICByZXR1cm4gbG9jYWxTdG9yYWdlLmdldEl0ZW0odGhpcy5rZXlzLlJFRlJFU0hfVE9LRU4pO1xuICB9XG5cbiAgLyoqXG4gICAqIExpbXBpYSB0b2RvIGVsIGVzdGFkbyBkZSBhdXRlbnRpY2FjacOzbi5cbiAgICovXG4gIGNsZWFyKCk6IHZvaWQge1xuICAgIHRyeSB7XG4gICAgICBPYmplY3QudmFsdWVzKHRoaXMua2V5cykuZm9yRWFjaCgoa2V5KSA9PiBsb2NhbFN0b3JhZ2UucmVtb3ZlSXRlbShrZXkpKTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICBjb25zb2xlLndhcm4oJ1tWYWx0ZWNoQXV0aF0gRXJyb3IgbGltcGlhbmRvIHN0b3JhZ2U6JywgZSk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFZlcmlmaWNhIHNpIGhheSBlc3RhZG8gZ3VhcmRhZG8uXG4gICAqL1xuICBoYXNTdG9yZWRTdGF0ZSgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gISFsb2NhbFN0b3JhZ2UuZ2V0SXRlbSh0aGlzLmtleXMuQUNDRVNTX1RPS0VOKTtcbiAgfVxufVxuIl19