shared-lib-angular 2.0.1 → 2.0.2

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.
@@ -20,14 +20,14 @@ import { CommonModule } from '@angular/common';
20
20
  * Versión actual de la librería @dinafi/frmk
21
21
  * Sincronizada con package.json
22
22
  */
23
- const VERSION = '2.0.1';
23
+ const VERSION = '2.0.2';
24
24
  /**
25
25
  * Información completa de la versión
26
26
  */
27
27
  const VERSION_INFO = {
28
- version: '2.0.1',
28
+ version: '2.0.2',
29
29
  name: 'shared-lib-angular',
30
- buildDate: '2026-02-05T20:39:22.686Z',
30
+ buildDate: '2026-02-05T20:47:48.315Z',
31
31
  angular: '^20.0.0'
32
32
  };
33
33
 
@@ -1073,7 +1073,7 @@ class LoginComponent {
1073
1073
  const storeConfig = this.store.isConfigured()
1074
1074
  ? this.store.loginConfig()
1075
1075
  : DEFAULT_LOGIN_CONFIG;
1076
- const inputCfg = this.config();
1076
+ const inputCfg = this.config() ?? {};
1077
1077
  return {
1078
1078
  ...storeConfig,
1079
1079
  ...inputCfg,
@@ -1184,7 +1184,7 @@ class DashboardComponent {
1184
1184
  const storeConfig = this.store.isConfigured()
1185
1185
  ? this.store.dashboardConfig()
1186
1186
  : DEFAULT_DASHBOARD_CONFIG;
1187
- const inputCfg = this.config();
1187
+ const inputCfg = this.config() ?? {};
1188
1188
  return {
1189
1189
  ...storeConfig,
1190
1190
  ...inputCfg,
@@ -1 +1 @@
1
- {"version":3,"file":"shared-lib-angular.mjs","sources":["../../src/lib/version.ts","../../src/lib/models/login-config.interface.ts","../../src/lib/models/dashboard-config.interface.ts","../../src/lib/models/library-config.interface.ts","../../src/lib/services/frmk-config-store.service.ts","../../src/lib/services/authentication.service.ts","../../src/lib/services/config.service.ts","../../src/lib/services/authorization.service.ts","../../src/lib/guards/authorization.guard.ts","../../src/lib/components/login/login.component.ts","../../src/lib/components/login/login.component.html","../../src/lib/components/dashboard/dashboard.component.ts","../../src/lib/components/dashboard/dashboard.component.html","../../src/public-api.ts","../../src/shared-lib-angular.ts"],"sourcesContent":["// ========================================\n// VERSION - Auto-generado por sync-version.js\n// ========================================\n// Ejecutar 'npm run sync-version' para actualizar manualmente\n// Se sincroniza automáticamente en prebuild\n\n/**\n * Versión actual de la librería @dinafi/frmk\n * Sincronizada con package.json\n */\nexport const VERSION = '2.0.1';\n\n/**\n * Información completa de la versión\n */\nexport const VERSION_INFO = {\n version: '2.0.1',\n name: 'shared-lib-angular',\n buildDate: '2026-02-05T20:39:22.686Z',\n angular: '^20.0.0'\n} as const;\n","/**\r\n * Interface for configuring the LoginComponent appearance and behavior\r\n */\r\nexport interface LoginConfig {\r\n // === IDENTITY ===\r\n /** URL of the logo image. Defaults to the Ministerio de Hacienda logo */\r\n logoUrl: string;\r\n /** Alt text for the logo image */\r\n logoAlt: string;\r\n /** Width of the logo (CSS value, e.g., '120px') */\r\n logoWidth: string;\r\n /** Height of the logo (CSS value, e.g., '120px') */\r\n logoHeight: string;\r\n\r\n // === TEXTS ===\r\n /** Main title displayed on the login page */\r\n title: string;\r\n /** Optional subtitle displayed below the title */\r\n subtitle?: string;\r\n /** Institution name displayed in the footer */\r\n institutionName: string;\r\n /** Text for the login button */\r\n loginButtonText: string;\r\n /** Text for the logout button */\r\n logoutButtonText: string;\r\n /** Text for the \"go to dashboard\" button when already authenticated */\r\n dashboardButtonText: string;\r\n\r\n // === VERSION ===\r\n /** Whether to show the version number */\r\n showVersion: boolean;\r\n /** Version string to display */\r\n version: string;\r\n\r\n // === COLORS (CSS custom properties override) ===\r\n /** Primary color (overrides --color-primary) */\r\n primaryColor?: string;\r\n /** Background color of the container */\r\n backgroundColor?: string;\r\n /** Text color */\r\n textColor?: string;\r\n\r\n // === BEHAVIOR ===\r\n /** URL to redirect after successful login */\r\n redirectUrl: string;\r\n /** Whether to show the logout button when authenticated */\r\n showLogoutButton: boolean;\r\n\r\n // === FOOTER ===\r\n /** Custom footer text */\r\n footerText?: string;\r\n /** Whether to show the footer */\r\n showFooter: boolean;\r\n}\r\n\r\n/**\r\n * Default configuration for the LoginComponent\r\n */\r\nexport const DEFAULT_LOGIN_CONFIG: LoginConfig = {\r\n logoUrl: 'assets/@dinafi/frmk/logo-mh.png',\r\n logoAlt: 'Logo',\r\n logoWidth: '120px',\r\n logoHeight: '120px',\r\n title: 'Sistema de Autenticación',\r\n institutionName: 'Ministerio de Hacienda de El Salvador',\r\n loginButtonText: 'Iniciar Sesión con OIDC',\r\n logoutButtonText: 'Cerrar Sesión',\r\n dashboardButtonText: 'Ir al Dashboard',\r\n showVersion: true,\r\n version: '1.0.0',\r\n redirectUrl: '/home',\r\n showLogoutButton: true,\r\n showFooter: true\r\n};\r\n","/**\r\n * Interface for configuring the DashboardComponent appearance and behavior\r\n */\r\nexport interface DashboardConfig {\r\n /** Application title displayed in the header */\r\n title: string;\r\n /** Optional subtitle */\r\n subtitle?: string;\r\n /** Logo URL */\r\n logoUrl: string;\r\n /** Logo alt text */\r\n logoAlt: string;\r\n /** Footer text */\r\n footerText: string;\r\n /** Whether to show the version in the footer */\r\n showVersion: boolean;\r\n /** Version string */\r\n version: string;\r\n /** Whether to show static menu items (Inicio, Página Ejemplo, Componentes UI) */\r\n showStaticMenu: boolean;\r\n}\r\n\r\n/**\r\n * Default configuration for the DashboardComponent\r\n */\r\nexport const DEFAULT_DASHBOARD_CONFIG: DashboardConfig = {\r\n title: 'Sistema',\r\n logoUrl: 'assets/@dinafi/frmk/logo-mh.png',\r\n logoAlt: 'Logo',\r\n footerText: 'Ministerio de Hacienda, El Salvador',\r\n showVersion: true,\r\n version: '1.0.0',\r\n showStaticMenu: true\r\n};\r\n","import { LoginConfig } from './login-config.interface';\r\nimport { DashboardConfig } from './dashboard-config.interface';\r\n\r\n/**\r\n * Configuración de la librería que debe ser proporcionada por la aplicación consumidora.\r\n * Estos valores son críticos y deben ser configurados al inicializar la librería\r\n * mediante `FrmkConfigStore.initialize()` en el APP_INITIALIZER.\r\n */\r\nexport interface FrmkLibraryConfig {\r\n /**\r\n * URL del servidor de configuración (Config Server)\r\n * Ejemplo: 'config-server.example.com' o 'localhost:8080'\r\n */\r\n configServerHost: string;\r\n\r\n /**\r\n * Identificador del frontend en el Config Server\r\n * Este valor identifica la aplicación para obtener su configuración específica\r\n * Ejemplo: 'mi-aplicacion-frontend'\r\n */\r\n frontendId: string;\r\n\r\n /**\r\n * Ruta del servicio de configuración (opcional)\r\n * Por defecto: '/api/v1/config/service'\r\n */\r\n configServicePath?: string;\r\n\r\n /**\r\n * Realm de autenticación (opcional)\r\n * Por defecto se obtiene del Config Server\r\n */\r\n realm?: string;\r\n\r\n /**\r\n * Si es ambiente de producción (opcional)\r\n * Por defecto: false\r\n */\r\n production?: boolean;\r\n\r\n /**\r\n * Si requiere HTTPS (opcional)\r\n * Por defecto: true\r\n */\r\n requireHttps?: boolean;\r\n\r\n /**\r\n * Mostrar información de debug (opcional)\r\n * Por defecto: false\r\n */\r\n showDebugInformation?: boolean;\r\n\r\n /**\r\n * Configuración del componente de Login (opcional)\r\n * Permite personalizar textos, logos y comportamiento del login\r\n */\r\n loginConfig?: Partial<LoginConfig>;\r\n\r\n /**\r\n * Configuración del componente Dashboard (opcional)\r\n * Permite personalizar el layout principal de la aplicación\r\n */\r\n dashboardConfig?: Partial<DashboardConfig>;\r\n}\r\n\r\n/**\r\n * Configuración por defecto de la librería\r\n */\r\nexport const DEFAULT_LIBRARY_CONFIG: Partial<FrmkLibraryConfig> = {\r\n configServicePath: '/api/v1/config/service',\r\n production: false,\r\n requireHttps: true,\r\n showDebugInformation: false\r\n};\r\n","import { Injectable, signal, computed } from '@angular/core';\r\nimport { AuthConfig } from 'angular-oauth2-oidc';\r\nimport { AppConfiguration, ConfigServerResponse } from '../models/app-config.interface';\r\nimport { FrmkLibraryConfig, DEFAULT_LIBRARY_CONFIG } from '../models/library-config.interface';\r\nimport { LoginConfig, DEFAULT_LOGIN_CONFIG } from '../models/login-config.interface';\r\nimport { DashboardConfig, DEFAULT_DASHBOARD_CONFIG } from '../models/dashboard-config.interface';\r\n\r\n/**\r\n * Store centralizado de configuración del framework.\r\n *\r\n * Reemplaza las variables globales mutables (`currentAppConfig`, `libraryConfig`)\r\n * con un servicio inyectable basado en signals de Angular.\r\n *\r\n * Ciclo de vida:\r\n * 1. `initialize(config)` — llamado en APP_INITIALIZER con FrmkLibraryConfig\r\n * 2. `applyServerConfig(data)` — llamado por ConfigService tras obtener datos del Config Server\r\n *\r\n * Todas las propiedades computadas lanzan error si se leen antes de `initialize()`.\r\n *\r\n * @example\r\n * // En APP_INITIALIZER:\r\n * const store = inject(FrmkConfigStore);\r\n * store.initialize(myLibraryConfig);\r\n * await configService.loadConfig(); // internamente llama store.applyServerConfig()\r\n * authService.initializeAuth(store.authConfig());\r\n */\r\n@Injectable({ providedIn: 'root' })\r\nexport class FrmkConfigStore {\r\n\r\n // ── Signals internos ──────────────────────────────────────────────\r\n\r\n private readonly _libraryConfig = signal<FrmkLibraryConfig | null>(null);\r\n private readonly _serverConfig = signal<ConfigServerResponse | null>(null);\r\n\r\n // ── Estado público (read-only) ────────────────────────────────────\r\n\r\n /** Indica si la librería ha sido inicializada con `initialize()`. */\r\n readonly isConfigured = computed(() => this._libraryConfig() !== null);\r\n\r\n /** Configuración de la librería (merged con defaults). Lanza si no inicializada. */\r\n readonly libraryConfig = computed(() => {\r\n const cfg = this._libraryConfig();\r\n if (!cfg) {\r\n throw new Error(\r\n '[FRMK] La librería no ha sido configurada. ' +\r\n 'Llame a FrmkConfigStore.initialize() en su APP_INITIALIZER.'\r\n );\r\n }\r\n return cfg;\r\n });\r\n\r\n /** Configuración del componente Login (defaults + libraryConfig.loginConfig). */\r\n readonly loginConfig = computed<LoginConfig>(() => {\r\n const lib = this.libraryConfig();\r\n return { ...DEFAULT_LOGIN_CONFIG, ...(lib.loginConfig || {}) };\r\n });\r\n\r\n /** Configuración del componente Dashboard (defaults + libraryConfig.dashboardConfig). */\r\n readonly dashboardConfig = computed<DashboardConfig>(() => {\r\n const lib = this.libraryConfig();\r\n return { ...DEFAULT_DASHBOARD_CONFIG, ...(lib.dashboardConfig || {}) };\r\n });\r\n\r\n /**\r\n * Configuración completa de la aplicación.\r\n * Si hay datos del Config Server se aplican; en caso contrario se usan solo los defaults + libraryConfig.\r\n */\r\n readonly appConfig = computed<AppConfiguration>(() => {\r\n const lib = this.libraryConfig(); // lanza si no inicializada\r\n let config = this.createDefaultAppConfig(lib);\r\n\r\n const serverData = this._serverConfig();\r\n if (serverData) {\r\n const mapped = this.mapConfigServerResponse(serverData, config);\r\n config = this.mergeConfigurations(config, mapped);\r\n }\r\n\r\n return this.buildDynamicUrls(config);\r\n });\r\n\r\n /** AuthConfig de angular-oauth2-oidc derivada de appConfig. */\r\n readonly authConfig = computed<AuthConfig>(() => {\r\n const app = this.appConfig();\r\n return {\r\n issuer: app.auth.issuer,\r\n loginUrl: app.auth.loginUrl,\r\n tokenEndpoint: app.auth.tokenEndpoint,\r\n userinfoEndpoint: app.auth.userinfoEndpoint,\r\n logoutUrl: app.auth.logoutUrl,\r\n redirectUri: app.auth.redirectUri,\r\n postLogoutRedirectUri: app.auth.postLogoutRedirectUri,\r\n clientId: app.auth.clientId,\r\n responseType: 'code',\r\n scope: app.auth.scope,\r\n disableAtHashCheck: true,\r\n requireHttps: app.environment.requireHttps,\r\n showDebugInformation: app.environment.showDebugInformation,\r\n strictDiscoveryDocumentValidation: false,\r\n skipIssuerCheck: true,\r\n requestAccessToken: true,\r\n customQueryParams: {},\r\n silentRefreshTimeout: 5000,\r\n timeoutFactor: 0.25,\r\n sessionChecksEnabled: false,\r\n clearHashAfterLogin: true,\r\n oidc: true,\r\n clockSkewInSec: 30,\r\n disableIdTokenTimer: true\r\n };\r\n });\r\n\r\n // ── Métodos públicos ──────────────────────────────────────────────\r\n\r\n /**\r\n * Inicializa la librería con la configuración proporcionada por la app consumidora.\r\n * Debe llamarse UNA vez dentro del APP_INITIALIZER, antes de cualquier otro uso.\r\n *\r\n * @param config Configuración de la librería (se fusiona con DEFAULT_LIBRARY_CONFIG)\r\n */\r\n initialize(config: FrmkLibraryConfig): void {\r\n this._libraryConfig.set({\r\n ...DEFAULT_LIBRARY_CONFIG,\r\n ...config\r\n } as FrmkLibraryConfig);\r\n\r\n // Resetear server config para que appConfig se recalcule con los nuevos defaults\r\n this._serverConfig.set(null);\r\n }\r\n\r\n /**\r\n * Aplica los datos devueltos por el Config Server.\r\n * Llamado por `ConfigService.loadConfig()` después de la petición HTTP.\r\n *\r\n * @param data Respuesta del Config Server (o undefined si falló la carga)\r\n */\r\n applyServerConfig(data?: ConfigServerResponse): void {\r\n this._serverConfig.set(data ?? null);\r\n }\r\n\r\n // ── Lógica privada (migrada de app.config.ts) ─────────────────────\r\n\r\n private createDefaultAppConfig(lib: FrmkLibraryConfig): AppConfiguration {\r\n return {\r\n hosts: {\r\n configServer: lib.configServerHost,\r\n authServer: '',\r\n keycloak: '',\r\n localApp: ''\r\n },\r\n paths: {\r\n configService: lib.configServicePath || '/api/v1/config/service',\r\n realm: lib.realm || 'realm-to-create'\r\n },\r\n configServer: {\r\n url: '',\r\n frontend: lib.frontendId\r\n },\r\n auth: {\r\n issuer: '',\r\n loginUrl: '',\r\n tokenEndpoint: '',\r\n userinfoEndpoint: '',\r\n logoutUrl: '',\r\n clientId: '',\r\n redirectUri: '',\r\n postLogoutRedirectUri: '',\r\n silentRefreshRedirectUri: '',\r\n scope: 'openid email profile'\r\n },\r\n authorization: {\r\n baseUrl: '',\r\n verifyEndpoint: '/api/v1/authz/verify-groups',\r\n hierarchyEndpoint: '/api/v1/authz/hierarchy-by-component-and-groups'\r\n },\r\n environment: {\r\n production: lib.production ?? false,\r\n requireHttps: lib.requireHttps ?? true,\r\n showDebugInformation: lib.showDebugInformation ?? false\r\n }\r\n };\r\n }\r\n\r\n private mapConfigServerResponse(\r\n data: ConfigServerResponse,\r\n defaultConfig: AppConfiguration\r\n ): Partial<AppConfiguration> {\r\n const mapped: Partial<AppConfiguration> = {};\r\n\r\n if (data['security.url.auth']) {\r\n mapped.hosts = {\r\n ...defaultConfig.hosts,\r\n ...(mapped.hosts || {}),\r\n authServer: data['security.url.auth']\r\n };\r\n }\r\n\r\n if (data['quarkus.oidc.client-id']) {\r\n mapped.auth = {\r\n ...defaultConfig.auth,\r\n ...(mapped.auth || {}),\r\n clientId: data['quarkus.oidc.client-id']\r\n };\r\n }\r\n\r\n if (data['security.realm']) {\r\n mapped.paths = {\r\n ...defaultConfig.paths,\r\n ...(mapped.paths || {}),\r\n realm: data['security.realm']\r\n };\r\n }\r\n\r\n if (data['security.url.authz']) {\r\n mapped.authorization = {\r\n ...defaultConfig.authorization,\r\n ...(mapped.authorization || {}),\r\n baseUrl: data['security.url.authz']\r\n };\r\n }\r\n\r\n if (data['security.scope']) {\r\n mapped.auth = {\r\n ...defaultConfig.auth,\r\n ...(mapped.auth || {}),\r\n scope: data['security.scope']\r\n };\r\n }\r\n\r\n if (data['security.url.keycloak']) {\r\n mapped.hosts = {\r\n ...defaultConfig.hosts,\r\n ...(mapped.hosts || {}),\r\n keycloak: data['security.url.keycloak']\r\n };\r\n }\r\n\r\n if (data['security.url.callback']) {\r\n mapped.hosts = {\r\n ...defaultConfig.hosts,\r\n ...(mapped.hosts || {}),\r\n localApp: data['security.url.callback']\r\n };\r\n }\r\n\r\n if (data['security.url.https'] !== undefined) {\r\n mapped.environment = {\r\n ...defaultConfig.environment,\r\n ...(mapped.environment || {}),\r\n requireHttps: data['security.url.https']\r\n };\r\n }\r\n\r\n return mapped;\r\n }\r\n\r\n private mergeConfigurations(\r\n base: AppConfiguration,\r\n override: Partial<AppConfiguration>\r\n ): AppConfiguration {\r\n const merged = { ...base };\r\n\r\n if (override.hosts) {\r\n merged.hosts = { ...merged.hosts, ...override.hosts };\r\n }\r\n if (override.paths) {\r\n merged.paths = { ...merged.paths, ...override.paths };\r\n }\r\n if (override.configServer) {\r\n merged.configServer = { ...merged.configServer, ...override.configServer };\r\n }\r\n if (override.auth) {\r\n merged.auth = { ...merged.auth, ...override.auth };\r\n }\r\n if (override.authorization) {\r\n merged.authorization = { ...merged.authorization, ...override.authorization };\r\n }\r\n if (override.environment) {\r\n merged.environment = { ...merged.environment, ...override.environment };\r\n }\r\n\r\n return merged;\r\n }\r\n\r\n private buildDynamicUrls(config: AppConfiguration): AppConfiguration {\r\n const c = { ...config };\r\n const proto = c.environment.requireHttps ? 'https' : 'http';\r\n\r\n // Config Server URL\r\n c.configServer = { ...c.configServer };\r\n c.configServer.url = `${proto}://${c.hosts.configServer}${c.paths.configService}`;\r\n\r\n // Auth URLs\r\n c.auth = { ...c.auth };\r\n c.auth.issuer = `${proto}://${c.hosts.keycloak}/realms/${c.paths.realm}`;\r\n c.auth.loginUrl = `${proto}://${c.hosts.keycloak}/realms/${c.paths.realm}/protocol/openid-connect/auth`;\r\n c.auth.tokenEndpoint = `${proto}://${c.hosts.authServer}/oidc/realm/${c.paths.realm}/protocol/openid-connect/token`;\r\n c.auth.userinfoEndpoint = `${proto}://${c.hosts.authServer}/oidc/realm/${c.paths.realm}/protocol/openid-connect/userinfo`;\r\n c.auth.logoutUrl = `${proto}://${c.hosts.authServer}/oidc/realm/${c.paths.realm}/protocol/openid-connect/logout`;\r\n\r\n // Redirect URLs (locales)\r\n const currentOrigin = globalThis.window?.location?.origin ?? c.hosts.localApp;\r\n c.auth.redirectUri = `${currentOrigin}/login`;\r\n c.auth.postLogoutRedirectUri = `${currentOrigin}/login`;\r\n\r\n // Authorization URL\r\n c.authorization = { ...c.authorization };\r\n c.authorization.baseUrl = `${proto}://${c.authorization.baseUrl}`;\r\n\r\n return c;\r\n }\r\n}\r\n","import { Injectable } from '@angular/core';\r\nimport { Router } from '@angular/router';\r\nimport { AuthConfig, OAuthService, OAuthEvent } from 'angular-oauth2-oidc';\r\nimport { BehaviorSubject } from 'rxjs';\r\nimport { FrmkConfigStore } from './frmk-config-store.service';\r\n\r\n@Injectable({ \r\n providedIn: 'root'\r\n})\r\nexport class AuthService {\r\n private readonly isAuthenticatedSubject$ = new BehaviorSubject<boolean>(false);\r\n public isAuthenticated$ = this.isAuthenticatedSubject$.asObservable();\r\n\r\n private readonly isDoneLoadingSubject$ = new BehaviorSubject<boolean>(false);\r\n public isDoneLoading$ = this.isDoneLoadingSubject$.asObservable();\r\n\r\n private isInitialLogin = true;\r\n\r\n constructor(\r\n private readonly oauthService: OAuthService,\r\n private readonly router: Router,\r\n private readonly store: FrmkConfigStore\r\n ) {\r\n // IMPORTANTE: Limpiar tokens expirados ANTES de cualquier otra operación\r\n this.clearExpiredTokensOnStartup();\r\n \r\n this.oauthService.events \r\n .subscribe((event) => {\r\n if (event instanceof OAuthEvent) {\r\n if (event.type === 'token_received') {\r\n this.handleSuccessfulAuthentication();\r\n }\r\n if (event.type === 'logout') {\r\n this.handleLogout();\r\n }\r\n if (event.type === 'token_error') {\r\n this.isDoneLoadingSubject$.next(true);\r\n }\r\n if (event.type === 'silently_refreshed') {\r\n this.handleSilentRefresh();\r\n }\r\n }\r\n });\r\n }\r\n\r\n /**\r\n * Limpia tokens expirados al iniciar la aplicación\r\n * Solo limpia si NO estamos en un callback OAuth\r\n */\r\n private clearExpiredTokensOnStartup(): void {\r\n const urlParams = new URLSearchParams(window.location.search);\r\n \r\n // Detectar TODOS los parámetros que indican un callback OAuth\r\n // Keycloak puede enviar: code, state, session_state, iss (RFC 9207)\r\n const isOAuthCallback = urlParams.has('code') || \r\n urlParams.has('iss') || \r\n urlParams.has('session_state') ||\r\n urlParams.has('state') ||\r\n window.location.hash.includes('access_token') ||\r\n window.location.hash.includes('code');\r\n \r\n if (isOAuthCallback) {\r\n console.log('[AuthService] OAuth callback detected, skipping token cleanup');\r\n return;\r\n }\r\n\r\n // Verificar si hay un token y si está expirado\r\n const expiresAt = localStorage.getItem('expires_at') || sessionStorage.getItem('expires_at');\r\n if (expiresAt) {\r\n const expirationTime = parseInt(expiresAt, 10);\r\n const now = Date.now();\r\n \r\n if (expirationTime < now) {\r\n console.log('[AuthService] Expired token detected, clearing storage');\r\n this.clearAllTokens();\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Limpia todos los tokens del storage\r\n */\r\n private clearAllTokens(): void {\r\n const keysToRemove = [\r\n 'access_token', 'refresh_token', 'id_token', 'token_type',\r\n 'expires_at', 'nonce', 'PKCE_verifier', 'session_state',\r\n 'id_token_claims_obj', 'id_token_expires_at', 'id_token_stored_at',\r\n 'access_token_stored_at'\r\n ];\r\n \r\n keysToRemove.forEach(key => {\r\n localStorage.removeItem(key);\r\n sessionStorage.removeItem(key);\r\n });\r\n }\r\n\r\n /**\r\n * Limpia tokens antiguos pero MANTIENE state, nonce y PKCE_verifier\r\n * que son necesarios para validar el callback OAuth\r\n */\r\n private clearOldTokensKeepState(): void {\r\n // Solo limpiar tokens, NO state/nonce/PKCE_verifier\r\n const keysToRemove = [\r\n 'access_token', 'refresh_token', 'id_token', 'token_type',\r\n 'expires_at', 'id_token_claims_obj', 'id_token_expires_at', \r\n 'id_token_stored_at', 'access_token_stored_at'\r\n ];\r\n \r\n keysToRemove.forEach(key => {\r\n localStorage.removeItem(key);\r\n sessionStorage.removeItem(key);\r\n });\r\n \r\n console.log('[AuthService] Cleared old tokens, kept state/nonce/PKCE for callback validation');\r\n }\r\n\r\n private handleSuccessfulAuthentication(): void {\r\n if (this.oauthService.hasValidAccessToken()) {\r\n this.isAuthenticatedSubject$.next(true);\r\n this.isDoneLoadingSubject$.next(true);\r\n \r\n // Limpiar parámetros OAuth de la URL para evitar problemas al refrescar\r\n this.cleanupOAuthParams();\r\n \r\n if (this.isInitialLogin) {\r\n this.isInitialLogin = false;\r\n }\r\n } else {\r\n this.isDoneLoadingSubject$.next(true);\r\n }\r\n }\r\n\r\n /**\r\n * Limpia los parámetros OAuth de la URL después del login exitoso\r\n * Esto evita problemas cuando el usuario refresca la página\r\n */\r\n private cleanupOAuthParams(): void {\r\n try {\r\n const url = new URL(window.location.href);\r\n const paramsToRemove = ['code', 'state', 'session_state', 'iss'];\r\n let hasOAuthParams = false;\r\n \r\n paramsToRemove.forEach(param => {\r\n if (url.searchParams.has(param)) {\r\n url.searchParams.delete(param);\r\n hasOAuthParams = true;\r\n }\r\n });\r\n \r\n if (hasOAuthParams) {\r\n // Reemplazar URL sin recargar la página\r\n window.history.replaceState({}, document.title, url.toString());\r\n console.log('[AuthService] OAuth params cleaned from URL');\r\n }\r\n } catch (error) {\r\n console.warn('[AuthService] Error cleaning OAuth params:', error);\r\n }\r\n }\r\n\r\n private handleSilentRefresh(): void {\r\n if (this.oauthService.hasValidAccessToken()) {\r\n this.isAuthenticatedSubject$.next(true);\r\n this.isDoneLoadingSubject$.next(true);\r\n }\r\n }\r\n\r\n private handleLogout(): void {\r\n this.isAuthenticatedSubject$.next(false);\r\n this.isDoneLoadingSubject$.next(true);\r\n }\r\n\r\n /**\r\n * Limpia todos los tokens del storage\r\n */\r\n private clearTokenStorage(): void {\r\n this.oauthService.logOut(true); // true = no redirect, solo limpiar\r\n localStorage.removeItem('access_token');\r\n localStorage.removeItem('refresh_token');\r\n localStorage.removeItem('id_token');\r\n localStorage.removeItem('nonce');\r\n localStorage.removeItem('expires_at');\r\n sessionStorage.removeItem('access_token');\r\n sessionStorage.removeItem('refresh_token');\r\n sessionStorage.removeItem('id_token');\r\n }\r\n\r\n /**\r\n * Verifica si el token actual está expirado\r\n */\r\n private isTokenExpired(): boolean {\r\n const expiresAt = this.oauthService.getAccessTokenExpiration();\r\n if (!expiresAt) {\r\n return false; // Si no hay token, no está \"expirado\", simplemente no existe\r\n }\r\n return expiresAt < Date.now();\r\n }\r\n\r\n private async runInitialLoginSequence(): Promise<void> {\r\n try {\r\n const urlParams = new URLSearchParams(window.location.search);\r\n const hasCode = urlParams.has('code');\r\n const hasState = urlParams.has('state');\r\n const hasIss = urlParams.has('iss');\r\n const hasSessionState = urlParams.has('session_state');\r\n const hasFragment = window.location.hash.includes('access_token') || window.location.hash.includes('code');\r\n \r\n // Detectar si estamos en un callback OAuth (Keycloak envía code, state, session_state, iss)\r\n const isOAuthCallback = hasCode || hasFragment || (hasState && (hasIss || hasSessionState));\r\n\r\n // Si NO estamos en callback OAuth y hay tokens expirados, limpiar y terminar\r\n if (!isOAuthCallback && this.isTokenExpired()) {\r\n console.log('[AuthService] No OAuth callback detected and token expired, clearing storage');\r\n this.clearTokenStorage();\r\n this.isDoneLoadingSubject$.next(true);\r\n return;\r\n }\r\n\r\n // Si estamos en callback OAuth, SIEMPRE limpiar tokens anteriores para evitar conflictos\r\n // Esto es crítico: angular-oauth2-oidc valida tokens existentes antes de procesar el código nuevo\r\n if (isOAuthCallback) {\r\n console.log('[AuthService] OAuth callback detected, clearing old tokens before processing');\r\n // Limpiar solo tokens, NO el state/nonce que necesitamos para validar el callback\r\n this.clearOldTokensKeepState();\r\n \r\n this.isInitialLogin = true;\r\n await this.oauthService.tryLoginCodeFlow();\r\n } \r\n\r\n const hasValidToken = this.oauthService.hasValidAccessToken();\r\n \r\n if (hasValidToken) {\r\n if (!hasCode && !hasFragment) {\r\n this.isInitialLogin = false;\r\n }\r\n this.handleSuccessfulAuthentication();\r\n } else {\r\n this.isDoneLoadingSubject$.next(true);\r\n }\r\n \r\n } catch (error: any) {\r\n console.error('[AuthService] Error during authentication initialization:', error);\r\n \r\n // Si el error es por token expirado, limpiar y permitir nuevo login\r\n if (error?.message?.includes('expired') || error?.reason?.includes('expired')) {\r\n this.clearTokenStorage();\r\n }\r\n \r\n this.isDoneLoadingSubject$.next(true);\r\n } \r\n }\r\n\r\n private setupManualConfiguration(): void {\r\n const authConfig = this.store.authConfig();\r\n this.oauthService.tokenEndpoint = authConfig.tokenEndpoint!;\r\n this.oauthService.userinfoEndpoint = authConfig.userinfoEndpoint!;\r\n this.oauthService.loginUrl = authConfig.loginUrl!;\r\n this.oauthService.logoutUrl = authConfig.logoutUrl!;\r\n this.oauthService.clientId = authConfig.clientId!;\r\n this.oauthService.redirectUri = authConfig.redirectUri!;\r\n this.oauthService.scope = authConfig.scope!;\r\n this.oauthService.responseType = authConfig.responseType!;\r\n }\r\n\r\n public initializeAuth(authConfig: AuthConfig): void {\r\n const urlParams = new URLSearchParams(window.location.search);\r\n const hasCode = urlParams.has('code');\r\n \r\n // Si es callback OAuth, resetear TODO el estado de OAuthService\r\n if (hasCode) {\r\n console.log('[AuthService] OAuth callback detected: resetting OAuthService state');\r\n \r\n // Limpiar storage EXCEPTO state/nonce/PKCE\r\n this.clearOldTokensKeepState();\r\n \r\n // CRÍTICO: Resetear propiedades internas de OAuthService\r\n // para que no valide tokens viejos en memoria\r\n this.resetOAuthServiceInternalState();\r\n } else {\r\n // No es callback - verificar si hay tokens expirados\r\n const expiresAt = localStorage.getItem('expires_at');\r\n const isExpired = expiresAt && parseInt(expiresAt, 10) < Date.now();\r\n \r\n if (isExpired) {\r\n console.log('[AuthService] Clearing all expired tokens before configure');\r\n this.clearAllTokens();\r\n this.resetOAuthServiceInternalState();\r\n }\r\n }\r\n \r\n // Ahora es seguro configurar OAuthService\r\n this.oauthService.configure(authConfig);\r\n this.setupManualConfiguration();\r\n this.runInitialLoginSequence();\r\n }\r\n\r\n /**\r\n * Resetea las propiedades internas de OAuthService\r\n * Esto es necesario porque la librería guarda tokens en memoria\r\n * que no se limpian con localStorage/sessionStorage\r\n */\r\n private resetOAuthServiceInternalState(): void {\r\n try {\r\n const oauth = this.oauthService as any;\r\n oauth._accessToken = null;\r\n oauth._idToken = null;\r\n oauth._idTokenClaims = null;\r\n oauth.idTokenClaimsJson = null;\r\n oauth._refreshToken = null;\r\n console.log('[AuthService] OAuthService internal state reset');\r\n } catch (e) {\r\n console.warn('[AuthService] Could not reset internal state:', e);\r\n }\r\n }\r\n\r\n public getAuthConfig(): AuthConfig {\r\n return this.store.authConfig();\r\n }\r\n\r\n public login(targetUrl?: string): void {\r\n this.isInitialLogin = true;\r\n \r\n if (!this.oauthService.clientId) {\r\n return;\r\n }\r\n if (!this.oauthService.redirectUri) {\r\n return;\r\n }\r\n\r\n this.oauthService.initLoginFlow(targetUrl || undefined);\r\n }\r\n\r\n public async logout(): Promise<void> {\r\n try {\r\n await this.callKeycloakLogoutEndpoint().catch(err => {\r\n console.warn('Keycloak logout endpoint failed, but will continue with local cleanup:', err);\r\n });\r\n \r\n this.performLocalLogout();\r\n \r\n } catch (error) {\r\n console.error('Error during logout:', error);\r\n this.performLocalLogout();\r\n }\r\n }\r\n\r\n private async callKeycloakLogoutEndpoint(): Promise<void> {\r\n const authConfig = this.store.authConfig();\r\n const logoutUrl = authConfig.logoutUrl;\r\n \r\n let refreshToken: string | null = this.oauthService.getRefreshToken();\r\n \r\n if (!refreshToken) {\r\n refreshToken = localStorage.getItem('refresh_token') \r\n || localStorage.getItem('refresh_token_' + authConfig.clientId)\r\n || sessionStorage.getItem('refresh_token');\r\n }\r\n \r\n if (!logoutUrl) {\r\n console.warn('Logout URL not configured, skipping Keycloak logout');\r\n return;\r\n }\r\n\r\n if (!refreshToken) {\r\n console.warn('No refresh token found, logout endpoint may fail');\r\n }\r\n\r\n const body = new URLSearchParams();\r\n body.set('client_id', authConfig.clientId!);\r\n \r\n if (refreshToken) {\r\n body.set('refresh_token', refreshToken);\r\n }\r\n\r\n const headers: HeadersInit = {\r\n 'Content-Type': 'application/x-www-form-urlencoded'\r\n };\r\n\r\n try {\r\n const response = await fetch(logoutUrl, {\r\n method: 'POST',\r\n headers,\r\n body: body.toString()\r\n });\r\n\r\n if (!response.ok) {\r\n const errorText = await response.text();\r\n console.warn('Keycloak logout returned error, but local cleanup completed:', errorText);\r\n }\r\n } catch (error) {\r\n console.warn('Failed to call Keycloak logout endpoint:', error);\r\n }\r\n }\r\n\r\n private performLocalLogout(): void {\r\n this.oauthService.logOut(true);\r\n \r\n // Limpiar tokens del localStorage\r\n localStorage.removeItem('access_token');\r\n localStorage.removeItem('id_token');\r\n localStorage.removeItem('refresh_token');\r\n localStorage.removeItem('code_verifier');\r\n localStorage.removeItem('nonce');\r\n localStorage.removeItem('PKCE_verifier');\r\n \r\n // Limpiar tokens del sessionStorage\r\n sessionStorage.removeItem('access_token');\r\n sessionStorage.removeItem('id_token');\r\n sessionStorage.removeItem('refresh_token');\r\n sessionStorage.removeItem('nonce');\r\n sessionStorage.removeItem('PKCE_verifier');\r\n \r\n this.isAuthenticatedSubject$.next(false);\r\n this.isDoneLoadingSubject$.next(true);\r\n \r\n const currentUrl = this.router.url;\r\n if (currentUrl !== '/login' && !currentUrl.includes('/login')) {\r\n this.router.navigate(['/login']);\r\n }\r\n }\r\n\r\n public logoutAndRedirect(targetUrl: string = '/login'): void {\r\n this.logout();\r\n this.router.navigate([targetUrl]);\r\n }\r\n\r\n public hasValidToken(): boolean {\r\n return this.oauthService.hasValidAccessToken();\r\n }\r\n\r\n public get identityClaims(): any {\r\n return this.oauthService.getIdentityClaims();\r\n }\r\n\r\n public get accessToken(): string {\r\n return this.oauthService.getAccessToken();\r\n }\r\n\r\n public getUserRoles(): string[] {\r\n const claims = this.identityClaims;\r\n if (claims?.roles) {\r\n return Array.isArray(claims.roles) ? claims.roles : [claims.roles];\r\n }\r\n \r\n if (claims) {\r\n const roles: string[] = [];\r\n \r\n if (claims.realm_access?.roles) {\r\n roles.push(...claims.realm_access.roles);\r\n }\r\n \r\n const authConfig = this.store.authConfig();\r\n if (claims.resource_access?.[authConfig.clientId!]?.roles) {\r\n roles.push(...claims.resource_access[authConfig.clientId!].roles);\r\n }\r\n \r\n return roles;\r\n }\r\n return [];\r\n }\r\n\r\n public hasRole(role: string): boolean {\r\n return this.getUserRoles().includes(role);\r\n }\r\n\r\n public hasAnyRole(roles: string[]): boolean {\r\n const userRoles = this.getUserRoles();\r\n return roles.some(role => userRoles.includes(role));\r\n }\r\n\r\n public getUserGroups(): string[] {\r\n const claims = this.identityClaims;\r\n const groups: string[] = [];\r\n\r\n // First, try to get groups from identity claims (ID token)\r\n if (claims) {\r\n if (claims.groups) {\r\n if (Array.isArray(claims.groups)) {\r\n groups.push(...claims.groups);\r\n } else {\r\n groups.push(claims.groups);\r\n }\r\n }\r\n\r\n if (claims.accessTokenGroups) {\r\n if (Array.isArray(claims.accessTokenGroups)) {\r\n groups.push(...claims.accessTokenGroups);\r\n } else {\r\n groups.push(claims.accessTokenGroups);\r\n }\r\n }\r\n\r\n if (claims.realm_access?.groups) {\r\n groups.push(...claims.realm_access.groups);\r\n }\r\n }\r\n\r\n // If no groups found in ID token, try to decode access token\r\n if (groups.length === 0) {\r\n const accessToken = this.accessToken;\r\n if (accessToken) {\r\n try {\r\n const payload = this.decodeJwtPayload(accessToken);\r\n console.log('[AuthService] Access token payload:', payload);\r\n\r\n // Extract groups from access token\r\n if (payload.groups) {\r\n if (Array.isArray(payload.groups)) {\r\n groups.push(...payload.groups);\r\n } else {\r\n groups.push(payload.groups);\r\n }\r\n }\r\n\r\n // Also check realm_access.roles as groups (Keycloak pattern)\r\n if (payload.realm_access?.roles) {\r\n groups.push(...payload.realm_access.roles);\r\n }\r\n\r\n // Check resource_access for client-specific roles\r\n if (payload.resource_access) {\r\n Object.values(payload.resource_access).forEach((resource: any) => {\r\n if (resource.roles && Array.isArray(resource.roles)) {\r\n groups.push(...resource.roles);\r\n }\r\n });\r\n }\r\n } catch (error) {\r\n console.error('[AuthService] Error decoding access token:', error);\r\n }\r\n }\r\n }\r\n\r\n const uniqueGroups = [...new Set(groups)];\r\n console.log('[AuthService] getUserGroups result:', uniqueGroups);\r\n return uniqueGroups;\r\n }\r\n\r\n private decodeJwtPayload(token: string): any {\r\n try {\r\n const parts = token.split('.');\r\n if (parts.length !== 3) {\r\n throw new Error('Invalid JWT format');\r\n }\r\n const payload = parts[1];\r\n const decoded = atob(payload.replace(/-/g, '+').replace(/_/g, '/'));\r\n return JSON.parse(decoded);\r\n } catch (error) {\r\n console.error('[AuthService] Failed to decode JWT:', error);\r\n return {};\r\n }\r\n }\r\n}\r\n","import { Injectable } from '@angular/core';\r\nimport { HttpClient } from '@angular/common/http';\r\nimport { firstValueFrom } from 'rxjs';\r\nimport { AppConfiguration, ConfigServerResponse } from '../models/app-config.interface';\r\nimport { FrmkConfigStore } from './frmk-config-store.service';\r\n\r\n@Injectable({ \r\n providedIn: 'root' \r\n})\r\nexport class ConfigService {\r\n private configServerData: ConfigServerResponse | null = null;\r\n private isLoaded = false;\r\n\r\n constructor(\r\n private readonly http: HttpClient,\r\n private readonly store: FrmkConfigStore\r\n ) {}\r\n\r\n /**\r\n * Carga la configuración desde el config-server\r\n */\r\n async loadConfig(): Promise<void> {\r\n try {\r\n const appConfig = this.store.appConfig();\r\n const url = `${appConfig.configServer.url}/${appConfig.configServer.frontend}`;\r\n \r\n this.configServerData = await firstValueFrom(\r\n this.http.get<ConfigServerResponse>(url)\r\n );\r\n \r\n // Aplicar datos del server al store — todos los computeds se recalculan automáticamente\r\n this.store.applyServerConfig(this.configServerData);\r\n \r\n this.isLoaded = true;\r\n } catch (error) {\r\n console.log(`Exception while loading config: ${error}`);\r\n this.store.applyServerConfig();\r\n this.isLoaded = true;\r\n }\r\n }\r\n\r\n /**\r\n * Obtiene un valor de configuración por clave del config server\r\n */\r\n get(key: string): string | boolean | undefined {\r\n return this.configServerData?.[key as keyof ConfigServerResponse];\r\n }\r\n\r\n /**\r\n * Obtiene toda la configuración del config server\r\n */\r\n getAll(): ConfigServerResponse | null {\r\n return this.configServerData ? { ...this.configServerData } : null;\r\n }\r\n\r\n /**\r\n * Verifica si la configuración ha sido cargada\r\n */\r\n isConfigLoaded(): boolean {\r\n return this.isLoaded;\r\n }\r\n\r\n /**\r\n * Obtiene la configuración final de la aplicación (con valores del config server aplicados)\r\n */\r\n getAppConfig(): AppConfiguration {\r\n return this.store.appConfig();\r\n }\r\n\r\n /**\r\n * Obtiene los datos raw del config server\r\n */\r\n getConfigServerData(): ConfigServerResponse | null {\r\n return this.configServerData;\r\n }\r\n}\r\n","import { Injectable } from '@angular/core';\r\nimport { HttpClient, HttpParams, HttpHeaders } from '@angular/common/http';\r\nimport { Observable, of } from 'rxjs';\r\nimport { catchError, map } from 'rxjs/operators';\r\nimport { AuthService } from './authentication.service';\r\nimport { ConfigService } from './config.service';\r\nimport { AuthorizationRequest, AuthorizationResponse, MenuHierarchyItem } from '../models/authorization.interface';\r\n\r\n@Injectable({\r\n providedIn: 'root'\r\n})\r\nexport class AuthorizationService {\r\n\r\n constructor(\r\n private readonly http: HttpClient,\r\n private readonly authService: AuthService,\r\n private readonly configService: ConfigService\r\n ) {}\r\n\r\n /**\r\n * Verifica si el usuario tiene permisos para acceder a un recurso específico\r\n */\r\n verifyPermission(resourcePath: string, operationName: string = 'VIEW'): Observable<boolean> {\r\n const groups = this.getUserGroups();\r\n const config = this.configService.getAppConfig();\r\n \r\n if (groups.length === 0) {\r\n return of(false);\r\n }\r\n\r\n const request: AuthorizationRequest = {\r\n groupIds: groups,\r\n componentId: config.configServer.frontend,\r\n resourcePath: resourcePath,\r\n operationName: operationName\r\n };\r\n\r\n return this.checkAuthorization(request);\r\n }\r\n\r\n /**\r\n * Realiza la llamada HTTP al servicio de autorización\r\n */\r\n private checkAuthorization(request: AuthorizationRequest): Observable<boolean> {\r\n let params = new HttpParams();\r\n \r\n const cleanGroups = request.groupIds.map(group => group.replace(/\\//g, ''));\r\n const groupIdsString = cleanGroups.join(',');\r\n \r\n params = params.set('groupIds', groupIdsString);\r\n params = params.set('componentId', request.componentId);\r\n params = params.set('resourcePath', request.resourcePath);\r\n params = params.set('operationName', request.operationName);\r\n\r\n let headers = new HttpHeaders();\r\n\r\n const url = `${this.configService.getAppConfig().authorization.baseUrl}${this.configService.getAppConfig().authorization.verifyEndpoint}`;\r\n\r\n return this.http.get<AuthorizationResponse>(url, { \r\n params,\r\n headers\r\n }).pipe(\r\n map(response => {\r\n return response.hasPermission;\r\n }),\r\n catchError(() => {\r\n return of(false);\r\n })\r\n );\r\n }\r\n\r\n /**\r\n * Obtiene los grupos del usuario desde el access token\r\n */\r\n private getUserGroups(): string[] {\r\n return this.authService.getUserGroups();\r\n }\r\n\r\n /** \r\n * Método público para obtener los grupos del usuario (útil para debugging)\r\n */\r\n public getUserGroupsDebug(): string[] {\r\n return this.authService.getUserGroups();\r\n }\r\n\r\n /**\r\n * Obtiene la jerarquía de menús basada en el componente y los grupos del usuario\r\n */\r\n getMenuHierarchy(): Observable<MenuHierarchyItem[]> {\r\n const groups = this.getUserGroups();\r\n const config = this.configService.getAppConfig();\r\n \r\n if (groups.length === 0) {\r\n return of([]);\r\n }\r\n\r\n const cleanGroups = groups.map(group => group.replace(/\\//g, ''));\r\n const groupIdsString = cleanGroups.join(',');\r\n\r\n let params = new HttpParams();\r\n params = params.set('componentId', config.configServer.frontend);\r\n params = params.set('groupIds', groupIdsString);\r\n\r\n let headers = new HttpHeaders();\r\n\r\n const url = `${config.authorization.baseUrl}${config.authorization.hierarchyEndpoint}`;\r\n\r\n return this.http.get<MenuHierarchyItem[]>(url, { \r\n params,\r\n headers\r\n }).pipe(\r\n catchError(error => {\r\n console.error('Error obteniendo jerarquía de menús:', error);\r\n return of([]);\r\n })\r\n );\r\n }\r\n\r\n /**\r\n * Obtiene elementos de menú de nivel raíz (level 1)\r\n */\r\n getRootMenuItems(menuHierarchy: MenuHierarchyItem[]): MenuHierarchyItem[] {\r\n return menuHierarchy.filter(item => item.level === 1);\r\n }\r\n\r\n /**\r\n * Obtiene elementos hijos de un elemento padre específico por path\r\n */\r\n getChildMenuItems(menuHierarchy: MenuHierarchyItem[], parentPath: string, level: number): MenuHierarchyItem[] {\r\n return menuHierarchy.filter(item => \r\n item.level === level && \r\n item.hasParent && \r\n item.path.startsWith(parentPath) &&\r\n item.path !== parentPath &&\r\n this.isDirectChild(item.path, parentPath, level)\r\n );\r\n }\r\n\r\n /**\r\n * Verifica si un elemento tiene hijos\r\n */\r\n hasChildren(menuHierarchy: MenuHierarchyItem[], item: MenuHierarchyItem): boolean {\r\n return this.getChildMenuItems(menuHierarchy, item.path, item.level + 1).length > 0;\r\n }\r\n\r\n /**\r\n * Verifica si un path es hijo directo de otro path\r\n */\r\n private isDirectChild(childPath: string, parentPath: string, expectedLevel: number): boolean {\r\n const relativePath = childPath.substring(parentPath.length);\r\n const slashCount = (relativePath.match(/\\//g) || []).length;\r\n return slashCount === 1;\r\n }\r\n\r\n /**\r\n * Verifica múltiples permisos a la vez\r\n */\r\n verifyMultiplePermissions(permissions: { resourcePath: string, operationName?: string }[]): Observable<{ [key: string]: boolean }> {\r\n const results: { [key: string]: boolean } = {};\r\n const observables = permissions.map(permission => \r\n this.verifyPermission(permission.resourcePath, permission.operationName).pipe(\r\n map(authorized => ({ \r\n key: `${permission.resourcePath}_${permission.operationName || 'VIEW'}`, \r\n authorized \r\n }))\r\n )\r\n );\r\n\r\n return new Observable(observer => {\r\n let completed = 0;\r\n observables.forEach(obs => {\r\n obs.subscribe(result => {\r\n results[result.key] = result.authorized;\r\n completed++;\r\n if (completed === observables.length) {\r\n observer.next(results);\r\n observer.complete();\r\n }\r\n });\r\n });\r\n });\r\n }\r\n}\r\n","import { inject } from '@angular/core';\r\nimport { CanActivateFn, Router } from '@angular/router';\r\nimport { AuthService } from '../services/authentication.service';\r\nimport { map, take } from 'rxjs/operators';\r\n\r\nexport const authGuard: CanActivateFn = (route, state) => {\r\n const authService = inject(AuthService);\r\n const router = inject(Router);\r\n\r\n const handleAuthenticated = (): boolean => {\r\n return true;\r\n };\r\n\r\n const handleUnauthenticated = (currentUrl: string): boolean => {\r\n if (currentUrl !== '/login' && !currentUrl.includes('/login')) {\r\n router.navigate(['/login'], { \r\n queryParams: { returnUrl: currentUrl } \r\n });\r\n }\r\n return false;\r\n }; \r\n\r\n return authService.isAuthenticated$.pipe(\r\n take(1),\r\n map(isAuthenticated => {\r\n return isAuthenticated \r\n ? handleAuthenticated() \r\n : handleUnauthenticated(state.url);\r\n })\r\n );\r\n};\r\n","import { Component, OnInit, OnDestroy, input, computed, inject } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { Subscription } from 'rxjs';\r\nimport { AuthService } from '../../services/authentication.service';\r\nimport { FrmkConfigStore } from '../../services/frmk-config-store.service';\r\nimport { LoginConfig, DEFAULT_LOGIN_CONFIG } from '../../models/login-config.interface';\r\nimport { VERSION } from '../../version';\r\n\r\n@Component({\r\n selector: 'lib-login',\r\n standalone: true,\r\n imports: [CommonModule],\r\n templateUrl: './login.component.html',\r\n styleUrls: ['./login.component.scss']\r\n})\r\nexport class LoginComponent implements OnInit, OnDestroy {\r\n /**\r\n * Configuration object to customize the login component appearance and behavior\r\n */\r\n readonly config = input<Partial<LoginConfig>>({});\r\n\r\n private readonly store = inject(FrmkConfigStore);\r\n\r\n isLoggingIn = false;\r\n statusMessage = '';\r\n private authSubscription?: Subscription;\r\n private isProcessingCallback = false;\r\n\r\n /** Configuración merged: defaults ← libraryConfig.loginConfig ← @Input config */\r\n readonly mergedConfig = computed<LoginConfig>(() => {\r\n const storeConfig = this.store.isConfigured()\r\n ? this.store.loginConfig()\r\n : DEFAULT_LOGIN_CONFIG;\r\n const inputCfg = this.config();\r\n return {\r\n ...storeConfig,\r\n ...inputCfg,\r\n version: inputCfg.version || storeConfig.version || VERSION\r\n };\r\n });\r\n\r\n constructor(public authService: AuthService) {}\r\n\r\n ngOnInit() {\r\n // Check if processing OAuth callback\r\n // Also check for 'iss' and 'session_state' which indicate we came from OAuth even if 'code' was already processed\r\n const urlParams = new URLSearchParams(globalThis.location?.search || '');\r\n const hasCode = urlParams.has('code');\r\n const hasIss = urlParams.has('iss');\r\n const hasSessionState = urlParams.has('session_state');\r\n const hasFragment = (globalThis.location?.hash || '').includes('access_token') || \r\n (globalThis.location?.hash || '').includes('code');\r\n \r\n if (hasCode || hasFragment || hasIss || hasSessionState) {\r\n this.isProcessingCallback = true;\r\n this.statusMessage = 'Procesando autenticación...';\r\n }\r\n\r\n // Subscribe to authentication state changes\r\n this.authSubscription = this.authService.isAuthenticated$.subscribe(isAuthenticated => {\r\n if (isAuthenticated) {\r\n this.statusMessage = '¡Autenticación exitosa! Redirigiendo...';\r\n // Small delay to show success message, then redirect\r\n setTimeout(() => {\r\n this.navigateToRedirect();\r\n }, 500);\r\n }\r\n });\r\n }\r\n\r\n ngOnDestroy() {\r\n if (this.authSubscription) {\r\n this.authSubscription.unsubscribe();\r\n }\r\n }\r\n\r\n /**\r\n * Get merged configuration value\r\n */\r\n getConfig<K extends keyof LoginConfig>(key: K): LoginConfig[K] {\r\n return this.mergedConfig()[key];\r\n }\r\n\r\n /**\r\n * Get custom CSS styles for theming\r\n */\r\n getCustomStyles(): { [key: string]: string } {\r\n const styles: { [key: string]: string } = {};\r\n const cfg = this.mergedConfig();\r\n \r\n if (cfg.primaryColor) {\r\n styles['--color-primary'] = cfg.primaryColor;\r\n }\r\n if (cfg.backgroundColor) {\r\n styles['--login-bg-color'] = cfg.backgroundColor;\r\n }\r\n if (cfg.textColor) {\r\n styles['--login-text-color'] = cfg.textColor;\r\n }\r\n \r\n return styles;\r\n }\r\n\r\n login(): void {\r\n this.isLoggingIn = true;\r\n this.statusMessage = 'Redirigiendo al proveedor de autenticación...';\r\n \r\n setTimeout(() => {\r\n this.authService.login();\r\n }, 500);\r\n }\r\n\r\n logout(): void {\r\n this.authService.logout();\r\n this.isLoggingIn = false;\r\n this.statusMessage = '';\r\n this.isProcessingCallback = false;\r\n }\r\n\r\n goToDashboard(): void {\r\n this.navigateToRedirect();\r\n }\r\n\r\n private navigateToRedirect(): void {\r\n const redirectUrl = this.mergedConfig().redirectUrl;\r\n if (typeof globalThis.location !== 'undefined') {\r\n const baseUrl = `${globalThis.location.protocol}//${globalThis.location.host}`;\r\n globalThis.location.href = `${baseUrl}${redirectUrl}`;\r\n }\r\n }\r\n}\r\n","<div class=\"login-page\" [ngStyle]=\"getCustomStyles()\">\r\n <div class=\"login-page__container\">\r\n <!-- Logo -->\r\n <div class=\"login-page__logo\">\r\n <img \r\n [src]=\"getConfig('logoUrl')\" \r\n [alt]=\"getConfig('logoAlt')\" \r\n class=\"login-page__logo-img\"\r\n [style.width]=\"getConfig('logoWidth')\"\r\n [style.height]=\"getConfig('logoHeight')\" />\r\n </div>\r\n\r\n <!-- Header -->\r\n <div class=\"login-page__header\">\r\n <h1>{{ getConfig('title') }}</h1>\r\n <p *ngIf=\"getConfig('subtitle')\" class=\"subtitle\">{{ getConfig('subtitle') }}</p>\r\n </div>\r\n \r\n <!-- Login Form -->\r\n <div *ngIf=\"(authService.isDoneLoading$ | async)\" class=\"login-page__form\">\r\n <div *ngIf=\"!(authService.isAuthenticated$ | async)\">\r\n <!-- Status Message -->\r\n <div *ngIf=\"statusMessage\" class=\"auth-alert auth-alert--info\">\r\n <div class=\"auth-alert__content\">\r\n <p>{{ statusMessage }}</p>\r\n </div>\r\n </div>\r\n\r\n <!-- Login Button -->\r\n <button \r\n class=\"btn btn--primary btn--lg\" \r\n (click)=\"login()\" \r\n [disabled]=\"isLoggingIn\"\r\n [class.loading]=\"isLoggingIn\">\r\n {{ isLoggingIn ? 'Redirigiendo...' : getConfig('loginButtonText') }}\r\n </button>\r\n\r\n <!-- Footer -->\r\n <div class=\"login-page__footer\" *ngIf=\"getConfig('showFooter')\">\r\n <p *ngIf=\"getConfig('footerText'); else defaultFooter\">\r\n {{ getConfig('footerText') }}\r\n </p>\r\n <ng-template #defaultFooter>\r\n <p>\r\n Acceso seguro para usuarios de \r\n <strong>{{ getConfig('institutionName') }}</strong>\r\n </p>\r\n </ng-template>\r\n </div>\r\n </div>\r\n \r\n <!-- Already Authenticated -->\r\n <div *ngIf=\"authService.isAuthenticated$ | async\" class=\"auth-alert auth-alert--success\">\r\n <div class=\"auth-alert__content\">\r\n <h4>¡Sesión activa!</h4>\r\n <p>Ya tienes una sesión iniciada en el sistema.</p>\r\n </div>\r\n \r\n <div class=\"login-page__actions\">\r\n <button class=\"btn btn--primary btn--lg\" (click)=\"goToDashboard()\">\r\n {{ getConfig('dashboardButtonText') }}\r\n </button>\r\n \r\n <button \r\n *ngIf=\"getConfig('showLogoutButton')\"\r\n class=\"btn btn--secondary btn--lg\" \r\n (click)=\"logout()\">\r\n {{ getConfig('logoutButtonText') }}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n \r\n <!-- Loading State -->\r\n <div *ngIf=\"!(authService.isDoneLoading$ | async)\" class=\"auth-loading\">\r\n <div class=\"auth-loading__spinner\"></div>\r\n <p class=\"auth-loading__text\">Procesando autenticación...</p>\r\n </div>\r\n\r\n <!-- Version -->\r\n <div *ngIf=\"getConfig('showVersion')\" class=\"login-page__version\">\r\n <span>v{{ getConfig('version') }}</span>\r\n </div>\r\n </div>\r\n</div>\r\n","import { Component, OnInit, HostListener, input, computed, inject } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { RouterModule } from '@angular/router';\r\nimport { AuthService } from '../../services/authentication.service';\r\nimport { AuthorizationService } from '../../services/authorization.service';\r\nimport { FrmkConfigStore } from '../../services/frmk-config-store.service';\r\nimport { MenuHierarchyItem } from '../../models/authorization.interface';\r\nimport { DashboardConfig, DEFAULT_DASHBOARD_CONFIG } from '../../models/dashboard-config.interface';\r\nimport { VERSION } from '../../version';\r\n\r\n// Re-export for backwards compatibility\r\nexport { DashboardConfig } from '../../models/dashboard-config.interface';\r\n\r\n@Component({\r\n selector: 'lib-dashboard',\r\n standalone: true,\r\n imports: [CommonModule, RouterModule],\r\n templateUrl: './dashboard.component.html',\r\n styleUrls: ['./dashboard.component.scss']\r\n})\r\nexport class DashboardComponent implements OnInit {\r\n readonly config = input<Partial<DashboardConfig>>({});\r\n\r\n private readonly store = inject(FrmkConfigStore);\r\n\r\n userInfo: any = null;\r\n userRoles: string[] = [];\r\n menuHierarchy: MenuHierarchyItem[] = [];\r\n isMenuOpen = false;\r\n isLoadingMenu = false;\r\n openMenuItems: Set<string> = new Set();\r\n isUserPanelOpen = false;\r\n isMobileMenuOpen = false;\r\n\r\n /** Configuración merged: defaults ← libraryConfig.dashboardConfig ← @Input config */\r\n readonly mergedConfig = computed<DashboardConfig>(() => {\r\n const storeConfig = this.store.isConfigured()\r\n ? this.store.dashboardConfig()\r\n : DEFAULT_DASHBOARD_CONFIG;\r\n const inputCfg = this.config();\r\n return {\r\n ...storeConfig,\r\n ...inputCfg,\r\n version: inputCfg.version || storeConfig.version || VERSION\r\n };\r\n });\r\n\r\n constructor(\r\n public authService: AuthService,\r\n private readonly authorizationService: AuthorizationService\r\n ) {}\r\n\r\n ngOnInit(): void {\r\n this.loadUserInfo();\r\n this.loadMenuHierarchy();\r\n }\r\n\r\n getConfig<K extends keyof DashboardConfig>(key: K): DashboardConfig[K] {\r\n return this.mergedConfig()[key];\r\n }\r\n\r\n get appVersion(): string {\r\n return this.mergedConfig().version;\r\n }\r\n\r\n private loadUserInfo(): void {\r\n this.userInfo = this.authService.identityClaims;\r\n this.userRoles = this.authService.getUserRoles();\r\n }\r\n\r\n private loadMenuHierarchy(): void {\r\n this.isLoadingMenu = true;\r\n this.authorizationService.getMenuHierarchy().subscribe({\r\n next: (menuItems) => {\r\n this.menuHierarchy = this.buildHierarchicalMenu(menuItems);\r\n this.isLoadingMenu = false;\r\n },\r\n error: (error) => {\r\n console.error('Error loading menu hierarchy:', error);\r\n this.menuHierarchy = [];\r\n this.isLoadingMenu = false;\r\n }\r\n });\r\n }\r\n\r\n private buildHierarchicalMenu(flatItems: MenuHierarchyItem[]): MenuHierarchyItem[] {\r\n const itemMap = new Map<string, MenuHierarchyItem>();\r\n \r\n flatItems.forEach(item => {\r\n itemMap.set(item.path, { ...item, children: [] });\r\n });\r\n\r\n const rootItems: MenuHierarchyItem[] = [];\r\n \r\n flatItems.forEach(item => {\r\n const currentItem = itemMap.get(item.path)!;\r\n \r\n if (item.level === 1) {\r\n rootItems.push(currentItem);\r\n } else {\r\n const parent = this.findParent(item, flatItems);\r\n if (parent) {\r\n const parentItem = itemMap.get(parent.path);\r\n if (parentItem?.children) {\r\n parentItem.children.push(currentItem);\r\n }\r\n }\r\n }\r\n });\r\n\r\n return rootItems;\r\n }\r\n\r\n private findParent(item: MenuHierarchyItem, allItems: MenuHierarchyItem[]): MenuHierarchyItem | null {\r\n for (const potentialParent of allItems) {\r\n if (potentialParent.level === item.level - 1 && \r\n item.path.startsWith(potentialParent.path) &&\r\n item.path !== potentialParent.path) {\r\n return potentialParent;\r\n }\r\n }\r\n return null;\r\n }\r\n\r\n toggleMenuItem(itemId: string, item: MenuHierarchyItem): void {\r\n const isCurrentlyOpen = this.openMenuItems.has(itemId);\r\n \r\n if (isCurrentlyOpen) {\r\n this.closeMenuAndChildren(itemId);\r\n } else {\r\n this.closeSiblingMenus(item);\r\n this.openMenuItems.add(itemId);\r\n }\r\n }\r\n\r\n private closeMenuAndChildren(itemId: string): void {\r\n this.openMenuItems.delete(itemId);\r\n const itemsToClose = Array.from(this.openMenuItems).filter(id => id.startsWith(itemId + '-'));\r\n itemsToClose.forEach(id => this.openMenuItems.delete(id));\r\n }\r\n\r\n private closeSiblingMenus(currentItem: MenuHierarchyItem): void {\r\n if (currentItem.level === 1) {\r\n const rootItems = this.getRootMenuItems();\r\n rootItems.forEach(rootItem => {\r\n if (rootItem.code !== currentItem.code) {\r\n this.closeMenuAndChildren(rootItem.code);\r\n }\r\n });\r\n } else {\r\n const allItems = this.flattenMenuItems(this.menuHierarchy);\r\n const parent = this.findParent(currentItem, allItems);\r\n if (parent?.children) {\r\n parent.children.forEach(sibling => {\r\n if (sibling.code !== currentItem.code) {\r\n this.closeMenuAndChildren(sibling.code);\r\n }\r\n });\r\n }\r\n }\r\n }\r\n\r\n private flattenMenuItems(items: MenuHierarchyItem[]): MenuHierarchyItem[] {\r\n const flattened: MenuHierarchyItem[] = [];\r\n \r\n const flatten = (itemList: MenuHierarchyItem[]) => {\r\n itemList.forEach(item => {\r\n flattened.push(item);\r\n if (item.children) {\r\n flatten(item.children);\r\n }\r\n });\r\n };\r\n \r\n flatten(items);\r\n return flattened;\r\n }\r\n\r\n onMenuItemClick(event: Event, item: MenuHierarchyItem): void {\r\n if (this.hasChildren(item)) {\r\n event.preventDefault();\r\n event.stopPropagation();\r\n this.toggleMenuItem(item.code, item);\r\n } else {\r\n // Close mobile menu when navigating to a page\r\n this.closeMobileMenu();\r\n }\r\n }\r\n\r\n @HostListener('document:click', ['$event'])\r\n onDocumentClick(event: Event): void {\r\n const target = event.target as HTMLElement;\r\n const navElement = target.closest('.dashboard-nav');\r\n const userPanel = target.closest('.user-profile');\r\n \r\n if (!navElement) {\r\n this.openMenuItems.clear();\r\n }\r\n \r\n if (!userPanel) {\r\n this.isUserPanelOpen = false;\r\n }\r\n }\r\n\r\n toggleUserPanel(event: Event): void {\r\n event.stopPropagation();\r\n this.isUserPanelOpen = !this.isUserPanelOpen;\r\n }\r\n\r\n getUsername(): string {\r\n if (!this.userInfo?.preferred_username) return 'usuario';\r\n const username = this.userInfo.preferred_username;\r\n const atIndex = username.indexOf('@');\r\n return atIndex > 0 ? username.substring(0, atIndex) : username;\r\n }\r\n\r\n getUserFullName(): string {\r\n return this.userInfo?.name || 'Usuario';\r\n }\r\n\r\n getDocument(): string {\r\n return this.userInfo?.dui || 'N/A';\r\n }\r\n\r\n getInstitution(): string {\r\n return this.userInfo?.direccion || 'N/A';\r\n }\r\n\r\n getDependency(): string {\r\n return this.userInfo?.dependencia || 'N/A';\r\n }\r\n\r\n getRole(): string {\r\n return this.userInfo?.cargo || 'N/A';\r\n }\r\n\r\n isMenuItemOpen(itemId: string): boolean {\r\n return this.openMenuItems.has(itemId);\r\n }\r\n\r\n hasChildren(item: MenuHierarchyItem): boolean {\r\n return !!(item.children && item.children.length > 0);\r\n }\r\n\r\n getRootMenuItems(): MenuHierarchyItem[] {\r\n return this.menuHierarchy.filter(item => item.level === 1);\r\n }\r\n\r\n /**\r\n * Obtiene el icono para un item del menú.\r\n * Si el item tiene un icono definido, lo usa; de lo contrario, usa un icono por defecto según el nivel.\r\n */\r\n getMenuIcon(item: MenuHierarchyItem): string {\r\n // Si tiene icono definido, usarlo\r\n if (item.icono && item.icono.trim() !== '') {\r\n return item.icono;\r\n }\r\n \r\n // Iconos por defecto según el nivel\r\n if (item.level === 1) {\r\n return 'folder';\r\n } else if (item.level === 2) {\r\n return 'article';\r\n } else {\r\n return 'radio_button_unchecked';\r\n }\r\n }\r\n\r\n logoutAndRedirect(): void {\r\n this.authService.logoutAndRedirect();\r\n }\r\n\r\n getUserInitials(): string {\r\n if (!this.userInfo) return 'U';\r\n \r\n const name = this.userInfo.name || this.userInfo.preferred_username || 'Usuario';\r\n const words = name.split(' ');\r\n \r\n if (words.length >= 2) {\r\n return (words[0][0] + words[1][0]).toUpperCase();\r\n } else {\r\n return name.substring(0, 2).toUpperCase();\r\n }\r\n }\r\n\r\n toggleMobileMenu(): void {\r\n this.isMobileMenuOpen = !this.isMobileMenuOpen;\r\n }\r\n\r\n closeMobileMenu(): void {\r\n this.isMobileMenuOpen = false;\r\n document.body.style.overflow = '';\r\n }\r\n}\r\n","<div class=\"dashboard\">\r\n <!-- Header -->\r\n <header class=\"dashboard-header\">\r\n <!-- Mobile Header Top -->\r\n <div class=\"header-mobile-top\">\r\n <div class=\"ministry-logo-mobile\">\r\n <img [src]=\"getConfig('logoUrl')\" [alt]=\"getConfig('logoAlt')\" />\r\n </div>\r\n <h1 class=\"mobile-title\">{{ getConfig('title') }}</h1>\r\n </div>\r\n\r\n <!-- Mobile Header Bottom -->\r\n <div class=\"header-mobile-bottom\">\r\n <button class=\"hamburger-btn\" \r\n (click)=\"toggleMobileMenu()\"\r\n [class.active]=\"isMobileMenuOpen\"\r\n aria-label=\"Toggle menu\">\r\n <span class=\"hamburger-line\"></span>\r\n <span class=\"hamburger-line\"></span>\r\n <span class=\"hamburger-line\"></span>\r\n </button>\r\n\r\n <div class=\"user-profile mobile-user\" *ngIf=\"userInfo\">\r\n <button class=\"user-info-trigger\" \r\n (click)=\"toggleUserPanel($event)\"\r\n [attr.aria-expanded]=\"isUserPanelOpen\"\r\n aria-label=\"Abrir menú de usuario\">\r\n <div class=\"user-avatar\">\r\n <span>{{ getUserInitials() }}</span>\r\n </div>\r\n <div class=\"user-details\">\r\n <span class=\"user-name\">{{ getUsername() }}</span>\r\n </div>\r\n <span class=\"material-symbols-outlined dropdown-icon\">\r\n {{ isUserPanelOpen ? 'expand_less' : 'expand_more' }}\r\n </span>\r\n </button>\r\n \r\n <!-- User Panel -->\r\n <ng-container *ngTemplateOutlet=\"userPanelTemplate\"></ng-container>\r\n </div>\r\n </div>\r\n\r\n <!-- Desktop Header -->\r\n <div class=\"header-desktop-layout\">\r\n <div class=\"header-left\">\r\n <div class=\"ministry-logo\">\r\n <div class=\"logo-icon\">\r\n <img [src]=\"getConfig('logoUrl')\" [alt]=\"getConfig('logoAlt')\" />\r\n </div>\r\n <div class=\"ministry-info\">\r\n <h1>{{ getConfig('title') }}</h1>\r\n <span class=\"subtitle\" *ngIf=\"getConfig('subtitle')\">{{ getConfig('subtitle') }}</span>\r\n </div>\r\n </div>\r\n </div>\r\n \r\n <div class=\"header-right\">\r\n <div class=\"user-profile desktop-user\" *ngIf=\"userInfo\">\r\n <button class=\"user-info-trigger\" \r\n (click)=\"toggleUserPanel($event)\"\r\n [attr.aria-expanded]=\"isUserPanelOpen\"\r\n aria-label=\"Abrir menú de usuario\">\r\n <div class=\"user-avatar\">\r\n <span>{{ getUserInitials() }}</span>\r\n </div>\r\n <div class=\"user-details\">\r\n <span class=\"user-name\">{{ getUsername() }}</span>\r\n </div>\r\n <span class=\"material-symbols-outlined dropdown-icon\">\r\n {{ isUserPanelOpen ? 'expand_less' : 'expand_more' }}\r\n </span>\r\n </button>\r\n \r\n <!-- User Panel -->\r\n <ng-container *ngTemplateOutlet=\"userPanelTemplate\"></ng-container>\r\n </div>\r\n </div>\r\n </div>\r\n </header>\r\n\r\n <!-- User Panel Template -->\r\n <ng-template #userPanelTemplate>\r\n <div class=\"user-panel\" *ngIf=\"isUserPanelOpen\">\r\n <div class=\"user-panel-header\">\r\n <span class=\"panel-title\">Perfil de Usuario</span>\r\n </div>\r\n <div class=\"user-panel-content\">\r\n <div class=\"user-info-item\">\r\n <span class=\"material-symbols-outlined info-icon\">person</span>\r\n <div class=\"info-content\">\r\n <span class=\"info-label\">Código de Usuario:</span>\r\n <span class=\"info-value\">{{ getUsername() }}</span>\r\n </div>\r\n </div>\r\n \r\n <div class=\"user-info-item\">\r\n <span class=\"material-symbols-outlined info-icon\">badge</span>\r\n <div class=\"info-content\">\r\n <span class=\"info-label\">Nombre de Usuario:</span>\r\n <span class=\"info-value\">{{ getUserFullName() }}</span>\r\n </div>\r\n </div>\r\n \r\n <div class=\"user-info-item\">\r\n <span class=\"material-symbols-outlined info-icon\">credit_card</span>\r\n <div class=\"info-content\">\r\n <span class=\"info-label\">Documento:</span>\r\n <span class=\"info-value\">{{ getDocument() }}</span>\r\n </div>\r\n </div>\r\n \r\n <div class=\"user-info-item mobile-hidden\">\r\n <span class=\"material-symbols-outlined info-icon\">business</span>\r\n <div class=\"info-content\">\r\n <span class=\"info-label\">Institución:</span>\r\n <span class=\"info-value\">{{ getInstitution() }}</span>\r\n </div>\r\n </div>\r\n \r\n <div class=\"user-info-item mobile-hidden\">\r\n <span class=\"material-symbols-outlined info-icon\">apartment</span>\r\n <div class=\"info-content\">\r\n <span class=\"info-label\">Dependencia:</span>\r\n <span class=\"info-value\">{{ getDependency() }}</span>\r\n </div>\r\n </div>\r\n \r\n <div class=\"user-info-item mobile-hidden\">\r\n <span class=\"material-symbols-outlined info-icon\">work</span>\r\n <div class=\"info-content\">\r\n <span class=\"info-label\">Rol:</span>\r\n <span class=\"info-value\">{{ getRole() }}</span>\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"user-panel-footer\">\r\n <button class=\"logout-btn-panel\" (click)=\"logoutAndRedirect()\" title=\"Cerrar sesión\">\r\n <span class=\"material-symbols-outlined\">logout</span>\r\n <span class=\"logout-text\">CERRAR SESIÓN</span>\r\n </button>\r\n </div>\r\n </div>\r\n </ng-template>\r\n\r\n <!-- Mobile Menu Overlay -->\r\n <div class=\"nav-overlay\" *ngIf=\"isMobileMenuOpen\" (click)=\"closeMobileMenu()\"></div>\r\n\r\n <!-- Navigation (Horizontal Desktop / Sidebar Mobile) -->\r\n <nav class=\"dashboard-nav\" [class.mobile-open]=\"isMobileMenuOpen\">\r\n <div class=\"nav-mobile-header\">\r\n <div class=\"nav-mobile-logo\">\r\n <img [src]=\"getConfig('logoUrl')\" [alt]=\"getConfig('logoAlt')\" />\r\n <span class=\"nav-mobile-title\">Menú</span>\r\n </div>\r\n <button class=\"nav-close-btn\" (click)=\"closeMobileMenu()\" aria-label=\"Cerrar menú\">\r\n <span class=\"material-symbols-outlined\">close</span>\r\n </button>\r\n </div>\r\n\r\n <div class=\"nav-container\">\r\n <!-- Static Menu Items -->\r\n <ng-container *ngIf=\"getConfig('showStaticMenu')\">\r\n <a routerLink=\".\" \r\n routerLinkActive=\"active\" \r\n [routerLinkActiveOptions]=\"{exact: true}\" \r\n class=\"nav-item\"\r\n (click)=\"closeMobileMenu()\">\r\n <span class=\"material-symbols-outlined nav-icon\">home</span>\r\n <span class=\"nav-text\">Inicio</span>\r\n </a>\r\n </ng-container>\r\n\r\n <!-- Separator -->\r\n <div class=\"nav-separator\" *ngIf=\"!isLoadingMenu && menuHierarchy.length > 0\"></div>\r\n \r\n <!-- Dynamic Menu -->\r\n <div class=\"dynamic-menu\" *ngIf=\"!isLoadingMenu && menuHierarchy.length > 0\">\r\n <ng-container *ngFor=\"let rootItem of getRootMenuItems()\">\r\n <div class=\"menu-item-container\" [class.has-children]=\"hasChildren(rootItem)\">\r\n <a \r\n [routerLink]=\"hasChildren(rootItem) ? null : rootItem.path\" \r\n routerLinkActive=\"active\" \r\n class=\"nav-item root-item\"\r\n [class.expandable]=\"hasChildren(rootItem)\"\r\n (click)=\"onMenuItemClick($event, rootItem)\">\r\n <span class=\"material-symbols-outlined nav-icon\">{{ getMenuIcon(rootItem) }}</span>\r\n <span class=\"nav-text\">{{ rootItem.name }}</span>\r\n <span class=\"material-symbols-outlined expand-icon\" *ngIf=\"hasChildren(rootItem)\">\r\n {{ isMenuItemOpen(rootItem.code) ? 'expand_more' : 'chevron_right' }}\r\n </span>\r\n </a>\r\n \r\n <!-- Submenu -->\r\n <div class=\"submenu\" *ngIf=\"hasChildren(rootItem) && isMenuItemOpen(rootItem.code)\">\r\n <ng-container *ngTemplateOutlet=\"menuTemplate; context: { items: rootItem.children, level: 2 }\"></ng-container>\r\n </div>\r\n </div>\r\n </ng-container>\r\n </div>\r\n \r\n <!-- Loading Indicator -->\r\n <div class=\"menu-loading\" *ngIf=\"isLoadingMenu\">\r\n <span class=\"material-symbols-outlined nav-icon\">hourglass_empty</span>\r\n <span class=\"nav-text\">Cargando menú...</span>\r\n </div>\r\n </div>\r\n </nav>\r\n\r\n <!-- Recursive Menu Template -->\r\n <ng-template #menuTemplate let-items=\"items\" let-level=\"level\">\r\n <ng-container *ngFor=\"let item of items\">\r\n <div class=\"menu-item-container\" [class.has-children]=\"hasChildren(item)\" [attr.data-level]=\"level\">\r\n <a \r\n [routerLink]=\"hasChildren(item) ? null : item.path\" \r\n routerLinkActive=\"active\" \r\n class=\"nav-item submenu-item\"\r\n [class.expandable]=\"hasChildren(item)\"\r\n (click)=\"onMenuItemClick($event, item)\">\r\n <span class=\"material-symbols-outlined nav-icon\">{{ getMenuIcon(item) }}</span>\r\n <span class=\"nav-text\">{{ item.name }}</span>\r\n <span class=\"material-symbols-outlined expand-icon\" *ngIf=\"hasChildren(item)\">\r\n {{ isMenuItemOpen(item.code) ? 'expand_more' : 'chevron_right' }}\r\n </span>\r\n </a>\r\n\r\n <!-- Recursive Submenu (max 5 levels) -->\r\n <div class=\"submenu\" *ngIf=\"hasChildren(item) && isMenuItemOpen(item.code) && level < 5\">\r\n <ng-container *ngTemplateOutlet=\"menuTemplate; context: { items: item.children, level: level + 1 }\"></ng-container>\r\n </div>\r\n </div>\r\n </ng-container>\r\n </ng-template>\r\n\r\n <!-- Main Content -->\r\n <main class=\"dashboard-content\">\r\n <div class=\"content-wrapper\">\r\n <router-outlet></router-outlet>\r\n </div>\r\n </main>\r\n\r\n <!-- Footer -->\r\n <footer class=\"dashboard-footer\">\r\n <div class=\"footer-content\">\r\n <span class=\"footer-text\">\r\n {{ getConfig('footerText') }}\r\n <ng-container *ngIf=\"getConfig('showVersion')\">\r\n Versión {{ appVersion }}.\r\n </ng-container>\r\n Todos los derechos reservados.\r\n </span>\r\n </div>\r\n </footer>\r\n</div>\r\n","// ========================================\r\n// @dinafi/frmk - Public API\r\n// Angular Shared Library - Ministerio de Hacienda\r\n// ========================================\r\n\r\n// === VERSION ===\r\nexport { VERSION, VERSION_INFO } from './lib/version';\r\n\r\n// === MODELS / INTERFACES ===\r\nexport {\r\n // Login Configuration\r\n LoginConfig,\r\n DEFAULT_LOGIN_CONFIG,\r\n \r\n // Dashboard Configuration\r\n DashboardConfig,\r\n DEFAULT_DASHBOARD_CONFIG,\r\n \r\n // Application Configuration\r\n AppConfiguration,\r\n ConfigServerResponse,\r\n \r\n // Authorization\r\n AuthorizationRequest,\r\n AuthorizationResponse,\r\n MenuHierarchyItem,\r\n MenuHierarchyRequest,\r\n \r\n // Library Configuration\r\n FrmkLibraryConfig,\r\n DEFAULT_LIBRARY_CONFIG\r\n} from './lib/models';\r\n\r\n// === SERVICES ===\r\nexport {\r\n // Central Configuration Store (v2.0 — reemplaza funciones globales)\r\n FrmkConfigStore,\r\n \r\n // Authentication Service\r\n AuthService,\r\n \r\n // Authorization Service\r\n AuthorizationService,\r\n \r\n // Configuration Service\r\n ConfigService\r\n} from './lib/services';\r\n\r\n// === GUARDS ===\r\nexport { authGuard } from './lib/guards';\r\n\r\n// === COMPONENTS ===\r\nexport { \r\n LoginComponent \r\n} from './lib/components/login/login.component';\r\n\r\nexport { \r\n DashboardComponent\r\n} from './lib/components/dashboard/dashboard.component';\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":["i2","i3.FrmkConfigStore","i1","i2.FrmkConfigStore","i2.AuthService","i3.ConfigService","i1.AuthService","i2.AuthorizationService"],"mappings":"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"}
1
+ {"version":3,"file":"shared-lib-angular.mjs","sources":["../../src/lib/version.ts","../../src/lib/models/login-config.interface.ts","../../src/lib/models/dashboard-config.interface.ts","../../src/lib/models/library-config.interface.ts","../../src/lib/services/frmk-config-store.service.ts","../../src/lib/services/authentication.service.ts","../../src/lib/services/config.service.ts","../../src/lib/services/authorization.service.ts","../../src/lib/guards/authorization.guard.ts","../../src/lib/components/login/login.component.ts","../../src/lib/components/login/login.component.html","../../src/lib/components/dashboard/dashboard.component.ts","../../src/lib/components/dashboard/dashboard.component.html","../../src/public-api.ts","../../src/shared-lib-angular.ts"],"sourcesContent":["// ========================================\n// VERSION - Auto-generado por sync-version.js\n// ========================================\n// Ejecutar 'npm run sync-version' para actualizar manualmente\n// Se sincroniza automáticamente en prebuild\n\n/**\n * Versión actual de la librería @dinafi/frmk\n * Sincronizada con package.json\n */\nexport const VERSION = '2.0.2';\n\n/**\n * Información completa de la versión\n */\nexport const VERSION_INFO = {\n version: '2.0.2',\n name: 'shared-lib-angular',\n buildDate: '2026-02-05T20:47:48.315Z',\n angular: '^20.0.0'\n} as const;\n","/**\r\n * Interface for configuring the LoginComponent appearance and behavior\r\n */\r\nexport interface LoginConfig {\r\n // === IDENTITY ===\r\n /** URL of the logo image. Defaults to the Ministerio de Hacienda logo */\r\n logoUrl: string;\r\n /** Alt text for the logo image */\r\n logoAlt: string;\r\n /** Width of the logo (CSS value, e.g., '120px') */\r\n logoWidth: string;\r\n /** Height of the logo (CSS value, e.g., '120px') */\r\n logoHeight: string;\r\n\r\n // === TEXTS ===\r\n /** Main title displayed on the login page */\r\n title: string;\r\n /** Optional subtitle displayed below the title */\r\n subtitle?: string;\r\n /** Institution name displayed in the footer */\r\n institutionName: string;\r\n /** Text for the login button */\r\n loginButtonText: string;\r\n /** Text for the logout button */\r\n logoutButtonText: string;\r\n /** Text for the \"go to dashboard\" button when already authenticated */\r\n dashboardButtonText: string;\r\n\r\n // === VERSION ===\r\n /** Whether to show the version number */\r\n showVersion: boolean;\r\n /** Version string to display */\r\n version: string;\r\n\r\n // === COLORS (CSS custom properties override) ===\r\n /** Primary color (overrides --color-primary) */\r\n primaryColor?: string;\r\n /** Background color of the container */\r\n backgroundColor?: string;\r\n /** Text color */\r\n textColor?: string;\r\n\r\n // === BEHAVIOR ===\r\n /** URL to redirect after successful login */\r\n redirectUrl: string;\r\n /** Whether to show the logout button when authenticated */\r\n showLogoutButton: boolean;\r\n\r\n // === FOOTER ===\r\n /** Custom footer text */\r\n footerText?: string;\r\n /** Whether to show the footer */\r\n showFooter: boolean;\r\n}\r\n\r\n/**\r\n * Default configuration for the LoginComponent\r\n */\r\nexport const DEFAULT_LOGIN_CONFIG: LoginConfig = {\r\n logoUrl: 'assets/@dinafi/frmk/logo-mh.png',\r\n logoAlt: 'Logo',\r\n logoWidth: '120px',\r\n logoHeight: '120px',\r\n title: 'Sistema de Autenticación',\r\n institutionName: 'Ministerio de Hacienda de El Salvador',\r\n loginButtonText: 'Iniciar Sesión con OIDC',\r\n logoutButtonText: 'Cerrar Sesión',\r\n dashboardButtonText: 'Ir al Dashboard',\r\n showVersion: true,\r\n version: '1.0.0',\r\n redirectUrl: '/home',\r\n showLogoutButton: true,\r\n showFooter: true\r\n};\r\n","/**\r\n * Interface for configuring the DashboardComponent appearance and behavior\r\n */\r\nexport interface DashboardConfig {\r\n /** Application title displayed in the header */\r\n title: string;\r\n /** Optional subtitle */\r\n subtitle?: string;\r\n /** Logo URL */\r\n logoUrl: string;\r\n /** Logo alt text */\r\n logoAlt: string;\r\n /** Footer text */\r\n footerText: string;\r\n /** Whether to show the version in the footer */\r\n showVersion: boolean;\r\n /** Version string */\r\n version: string;\r\n /** Whether to show static menu items (Inicio, Página Ejemplo, Componentes UI) */\r\n showStaticMenu: boolean;\r\n}\r\n\r\n/**\r\n * Default configuration for the DashboardComponent\r\n */\r\nexport const DEFAULT_DASHBOARD_CONFIG: DashboardConfig = {\r\n title: 'Sistema',\r\n logoUrl: 'assets/@dinafi/frmk/logo-mh.png',\r\n logoAlt: 'Logo',\r\n footerText: 'Ministerio de Hacienda, El Salvador',\r\n showVersion: true,\r\n version: '1.0.0',\r\n showStaticMenu: true\r\n};\r\n","import { LoginConfig } from './login-config.interface';\r\nimport { DashboardConfig } from './dashboard-config.interface';\r\n\r\n/**\r\n * Configuración de la librería que debe ser proporcionada por la aplicación consumidora.\r\n * Estos valores son críticos y deben ser configurados al inicializar la librería\r\n * mediante `FrmkConfigStore.initialize()` en el APP_INITIALIZER.\r\n */\r\nexport interface FrmkLibraryConfig {\r\n /**\r\n * URL del servidor de configuración (Config Server)\r\n * Ejemplo: 'config-server.example.com' o 'localhost:8080'\r\n */\r\n configServerHost: string;\r\n\r\n /**\r\n * Identificador del frontend en el Config Server\r\n * Este valor identifica la aplicación para obtener su configuración específica\r\n * Ejemplo: 'mi-aplicacion-frontend'\r\n */\r\n frontendId: string;\r\n\r\n /**\r\n * Ruta del servicio de configuración (opcional)\r\n * Por defecto: '/api/v1/config/service'\r\n */\r\n configServicePath?: string;\r\n\r\n /**\r\n * Realm de autenticación (opcional)\r\n * Por defecto se obtiene del Config Server\r\n */\r\n realm?: string;\r\n\r\n /**\r\n * Si es ambiente de producción (opcional)\r\n * Por defecto: false\r\n */\r\n production?: boolean;\r\n\r\n /**\r\n * Si requiere HTTPS (opcional)\r\n * Por defecto: true\r\n */\r\n requireHttps?: boolean;\r\n\r\n /**\r\n * Mostrar información de debug (opcional)\r\n * Por defecto: false\r\n */\r\n showDebugInformation?: boolean;\r\n\r\n /**\r\n * Configuración del componente de Login (opcional)\r\n * Permite personalizar textos, logos y comportamiento del login\r\n */\r\n loginConfig?: Partial<LoginConfig>;\r\n\r\n /**\r\n * Configuración del componente Dashboard (opcional)\r\n * Permite personalizar el layout principal de la aplicación\r\n */\r\n dashboardConfig?: Partial<DashboardConfig>;\r\n}\r\n\r\n/**\r\n * Configuración por defecto de la librería\r\n */\r\nexport const DEFAULT_LIBRARY_CONFIG: Partial<FrmkLibraryConfig> = {\r\n configServicePath: '/api/v1/config/service',\r\n production: false,\r\n requireHttps: true,\r\n showDebugInformation: false\r\n};\r\n","import { Injectable, signal, computed } from '@angular/core';\r\nimport { AuthConfig } from 'angular-oauth2-oidc';\r\nimport { AppConfiguration, ConfigServerResponse } from '../models/app-config.interface';\r\nimport { FrmkLibraryConfig, DEFAULT_LIBRARY_CONFIG } from '../models/library-config.interface';\r\nimport { LoginConfig, DEFAULT_LOGIN_CONFIG } from '../models/login-config.interface';\r\nimport { DashboardConfig, DEFAULT_DASHBOARD_CONFIG } from '../models/dashboard-config.interface';\r\n\r\n/**\r\n * Store centralizado de configuración del framework.\r\n *\r\n * Reemplaza las variables globales mutables (`currentAppConfig`, `libraryConfig`)\r\n * con un servicio inyectable basado en signals de Angular.\r\n *\r\n * Ciclo de vida:\r\n * 1. `initialize(config)` — llamado en APP_INITIALIZER con FrmkLibraryConfig\r\n * 2. `applyServerConfig(data)` — llamado por ConfigService tras obtener datos del Config Server\r\n *\r\n * Todas las propiedades computadas lanzan error si se leen antes de `initialize()`.\r\n *\r\n * @example\r\n * // En APP_INITIALIZER:\r\n * const store = inject(FrmkConfigStore);\r\n * store.initialize(myLibraryConfig);\r\n * await configService.loadConfig(); // internamente llama store.applyServerConfig()\r\n * authService.initializeAuth(store.authConfig());\r\n */\r\n@Injectable({ providedIn: 'root' })\r\nexport class FrmkConfigStore {\r\n\r\n // ── Signals internos ──────────────────────────────────────────────\r\n\r\n private readonly _libraryConfig = signal<FrmkLibraryConfig | null>(null);\r\n private readonly _serverConfig = signal<ConfigServerResponse | null>(null);\r\n\r\n // ── Estado público (read-only) ────────────────────────────────────\r\n\r\n /** Indica si la librería ha sido inicializada con `initialize()`. */\r\n readonly isConfigured = computed(() => this._libraryConfig() !== null);\r\n\r\n /** Configuración de la librería (merged con defaults). Lanza si no inicializada. */\r\n readonly libraryConfig = computed(() => {\r\n const cfg = this._libraryConfig();\r\n if (!cfg) {\r\n throw new Error(\r\n '[FRMK] La librería no ha sido configurada. ' +\r\n 'Llame a FrmkConfigStore.initialize() en su APP_INITIALIZER.'\r\n );\r\n }\r\n return cfg;\r\n });\r\n\r\n /** Configuración del componente Login (defaults + libraryConfig.loginConfig). */\r\n readonly loginConfig = computed<LoginConfig>(() => {\r\n const lib = this.libraryConfig();\r\n return { ...DEFAULT_LOGIN_CONFIG, ...(lib.loginConfig || {}) };\r\n });\r\n\r\n /** Configuración del componente Dashboard (defaults + libraryConfig.dashboardConfig). */\r\n readonly dashboardConfig = computed<DashboardConfig>(() => {\r\n const lib = this.libraryConfig();\r\n return { ...DEFAULT_DASHBOARD_CONFIG, ...(lib.dashboardConfig || {}) };\r\n });\r\n\r\n /**\r\n * Configuración completa de la aplicación.\r\n * Si hay datos del Config Server se aplican; en caso contrario se usan solo los defaults + libraryConfig.\r\n */\r\n readonly appConfig = computed<AppConfiguration>(() => {\r\n const lib = this.libraryConfig(); // lanza si no inicializada\r\n let config = this.createDefaultAppConfig(lib);\r\n\r\n const serverData = this._serverConfig();\r\n if (serverData) {\r\n const mapped = this.mapConfigServerResponse(serverData, config);\r\n config = this.mergeConfigurations(config, mapped);\r\n }\r\n\r\n return this.buildDynamicUrls(config);\r\n });\r\n\r\n /** AuthConfig de angular-oauth2-oidc derivada de appConfig. */\r\n readonly authConfig = computed<AuthConfig>(() => {\r\n const app = this.appConfig();\r\n return {\r\n issuer: app.auth.issuer,\r\n loginUrl: app.auth.loginUrl,\r\n tokenEndpoint: app.auth.tokenEndpoint,\r\n userinfoEndpoint: app.auth.userinfoEndpoint,\r\n logoutUrl: app.auth.logoutUrl,\r\n redirectUri: app.auth.redirectUri,\r\n postLogoutRedirectUri: app.auth.postLogoutRedirectUri,\r\n clientId: app.auth.clientId,\r\n responseType: 'code',\r\n scope: app.auth.scope,\r\n disableAtHashCheck: true,\r\n requireHttps: app.environment.requireHttps,\r\n showDebugInformation: app.environment.showDebugInformation,\r\n strictDiscoveryDocumentValidation: false,\r\n skipIssuerCheck: true,\r\n requestAccessToken: true,\r\n customQueryParams: {},\r\n silentRefreshTimeout: 5000,\r\n timeoutFactor: 0.25,\r\n sessionChecksEnabled: false,\r\n clearHashAfterLogin: true,\r\n oidc: true,\r\n clockSkewInSec: 30,\r\n disableIdTokenTimer: true\r\n };\r\n });\r\n\r\n // ── Métodos públicos ──────────────────────────────────────────────\r\n\r\n /**\r\n * Inicializa la librería con la configuración proporcionada por la app consumidora.\r\n * Debe llamarse UNA vez dentro del APP_INITIALIZER, antes de cualquier otro uso.\r\n *\r\n * @param config Configuración de la librería (se fusiona con DEFAULT_LIBRARY_CONFIG)\r\n */\r\n initialize(config: FrmkLibraryConfig): void {\r\n this._libraryConfig.set({\r\n ...DEFAULT_LIBRARY_CONFIG,\r\n ...config\r\n } as FrmkLibraryConfig);\r\n\r\n // Resetear server config para que appConfig se recalcule con los nuevos defaults\r\n this._serverConfig.set(null);\r\n }\r\n\r\n /**\r\n * Aplica los datos devueltos por el Config Server.\r\n * Llamado por `ConfigService.loadConfig()` después de la petición HTTP.\r\n *\r\n * @param data Respuesta del Config Server (o undefined si falló la carga)\r\n */\r\n applyServerConfig(data?: ConfigServerResponse): void {\r\n this._serverConfig.set(data ?? null);\r\n }\r\n\r\n // ── Lógica privada (migrada de app.config.ts) ─────────────────────\r\n\r\n private createDefaultAppConfig(lib: FrmkLibraryConfig): AppConfiguration {\r\n return {\r\n hosts: {\r\n configServer: lib.configServerHost,\r\n authServer: '',\r\n keycloak: '',\r\n localApp: ''\r\n },\r\n paths: {\r\n configService: lib.configServicePath || '/api/v1/config/service',\r\n realm: lib.realm || 'realm-to-create'\r\n },\r\n configServer: {\r\n url: '',\r\n frontend: lib.frontendId\r\n },\r\n auth: {\r\n issuer: '',\r\n loginUrl: '',\r\n tokenEndpoint: '',\r\n userinfoEndpoint: '',\r\n logoutUrl: '',\r\n clientId: '',\r\n redirectUri: '',\r\n postLogoutRedirectUri: '',\r\n silentRefreshRedirectUri: '',\r\n scope: 'openid email profile'\r\n },\r\n authorization: {\r\n baseUrl: '',\r\n verifyEndpoint: '/api/v1/authz/verify-groups',\r\n hierarchyEndpoint: '/api/v1/authz/hierarchy-by-component-and-groups'\r\n },\r\n environment: {\r\n production: lib.production ?? false,\r\n requireHttps: lib.requireHttps ?? true,\r\n showDebugInformation: lib.showDebugInformation ?? false\r\n }\r\n };\r\n }\r\n\r\n private mapConfigServerResponse(\r\n data: ConfigServerResponse,\r\n defaultConfig: AppConfiguration\r\n ): Partial<AppConfiguration> {\r\n const mapped: Partial<AppConfiguration> = {};\r\n\r\n if (data['security.url.auth']) {\r\n mapped.hosts = {\r\n ...defaultConfig.hosts,\r\n ...(mapped.hosts || {}),\r\n authServer: data['security.url.auth']\r\n };\r\n }\r\n\r\n if (data['quarkus.oidc.client-id']) {\r\n mapped.auth = {\r\n ...defaultConfig.auth,\r\n ...(mapped.auth || {}),\r\n clientId: data['quarkus.oidc.client-id']\r\n };\r\n }\r\n\r\n if (data['security.realm']) {\r\n mapped.paths = {\r\n ...defaultConfig.paths,\r\n ...(mapped.paths || {}),\r\n realm: data['security.realm']\r\n };\r\n }\r\n\r\n if (data['security.url.authz']) {\r\n mapped.authorization = {\r\n ...defaultConfig.authorization,\r\n ...(mapped.authorization || {}),\r\n baseUrl: data['security.url.authz']\r\n };\r\n }\r\n\r\n if (data['security.scope']) {\r\n mapped.auth = {\r\n ...defaultConfig.auth,\r\n ...(mapped.auth || {}),\r\n scope: data['security.scope']\r\n };\r\n }\r\n\r\n if (data['security.url.keycloak']) {\r\n mapped.hosts = {\r\n ...defaultConfig.hosts,\r\n ...(mapped.hosts || {}),\r\n keycloak: data['security.url.keycloak']\r\n };\r\n }\r\n\r\n if (data['security.url.callback']) {\r\n mapped.hosts = {\r\n ...defaultConfig.hosts,\r\n ...(mapped.hosts || {}),\r\n localApp: data['security.url.callback']\r\n };\r\n }\r\n\r\n if (data['security.url.https'] !== undefined) {\r\n mapped.environment = {\r\n ...defaultConfig.environment,\r\n ...(mapped.environment || {}),\r\n requireHttps: data['security.url.https']\r\n };\r\n }\r\n\r\n return mapped;\r\n }\r\n\r\n private mergeConfigurations(\r\n base: AppConfiguration,\r\n override: Partial<AppConfiguration>\r\n ): AppConfiguration {\r\n const merged = { ...base };\r\n\r\n if (override.hosts) {\r\n merged.hosts = { ...merged.hosts, ...override.hosts };\r\n }\r\n if (override.paths) {\r\n merged.paths = { ...merged.paths, ...override.paths };\r\n }\r\n if (override.configServer) {\r\n merged.configServer = { ...merged.configServer, ...override.configServer };\r\n }\r\n if (override.auth) {\r\n merged.auth = { ...merged.auth, ...override.auth };\r\n }\r\n if (override.authorization) {\r\n merged.authorization = { ...merged.authorization, ...override.authorization };\r\n }\r\n if (override.environment) {\r\n merged.environment = { ...merged.environment, ...override.environment };\r\n }\r\n\r\n return merged;\r\n }\r\n\r\n private buildDynamicUrls(config: AppConfiguration): AppConfiguration {\r\n const c = { ...config };\r\n const proto = c.environment.requireHttps ? 'https' : 'http';\r\n\r\n // Config Server URL\r\n c.configServer = { ...c.configServer };\r\n c.configServer.url = `${proto}://${c.hosts.configServer}${c.paths.configService}`;\r\n\r\n // Auth URLs\r\n c.auth = { ...c.auth };\r\n c.auth.issuer = `${proto}://${c.hosts.keycloak}/realms/${c.paths.realm}`;\r\n c.auth.loginUrl = `${proto}://${c.hosts.keycloak}/realms/${c.paths.realm}/protocol/openid-connect/auth`;\r\n c.auth.tokenEndpoint = `${proto}://${c.hosts.authServer}/oidc/realm/${c.paths.realm}/protocol/openid-connect/token`;\r\n c.auth.userinfoEndpoint = `${proto}://${c.hosts.authServer}/oidc/realm/${c.paths.realm}/protocol/openid-connect/userinfo`;\r\n c.auth.logoutUrl = `${proto}://${c.hosts.authServer}/oidc/realm/${c.paths.realm}/protocol/openid-connect/logout`;\r\n\r\n // Redirect URLs (locales)\r\n const currentOrigin = globalThis.window?.location?.origin ?? c.hosts.localApp;\r\n c.auth.redirectUri = `${currentOrigin}/login`;\r\n c.auth.postLogoutRedirectUri = `${currentOrigin}/login`;\r\n\r\n // Authorization URL\r\n c.authorization = { ...c.authorization };\r\n c.authorization.baseUrl = `${proto}://${c.authorization.baseUrl}`;\r\n\r\n return c;\r\n }\r\n}\r\n","import { Injectable } from '@angular/core';\r\nimport { Router } from '@angular/router';\r\nimport { AuthConfig, OAuthService, OAuthEvent } from 'angular-oauth2-oidc';\r\nimport { BehaviorSubject } from 'rxjs';\r\nimport { FrmkConfigStore } from './frmk-config-store.service';\r\n\r\n@Injectable({ \r\n providedIn: 'root'\r\n})\r\nexport class AuthService {\r\n private readonly isAuthenticatedSubject$ = new BehaviorSubject<boolean>(false);\r\n public isAuthenticated$ = this.isAuthenticatedSubject$.asObservable();\r\n\r\n private readonly isDoneLoadingSubject$ = new BehaviorSubject<boolean>(false);\r\n public isDoneLoading$ = this.isDoneLoadingSubject$.asObservable();\r\n\r\n private isInitialLogin = true;\r\n\r\n constructor(\r\n private readonly oauthService: OAuthService,\r\n private readonly router: Router,\r\n private readonly store: FrmkConfigStore\r\n ) {\r\n // IMPORTANTE: Limpiar tokens expirados ANTES de cualquier otra operación\r\n this.clearExpiredTokensOnStartup();\r\n \r\n this.oauthService.events \r\n .subscribe((event) => {\r\n if (event instanceof OAuthEvent) {\r\n if (event.type === 'token_received') {\r\n this.handleSuccessfulAuthentication();\r\n }\r\n if (event.type === 'logout') {\r\n this.handleLogout();\r\n }\r\n if (event.type === 'token_error') {\r\n this.isDoneLoadingSubject$.next(true);\r\n }\r\n if (event.type === 'silently_refreshed') {\r\n this.handleSilentRefresh();\r\n }\r\n }\r\n });\r\n }\r\n\r\n /**\r\n * Limpia tokens expirados al iniciar la aplicación\r\n * Solo limpia si NO estamos en un callback OAuth\r\n */\r\n private clearExpiredTokensOnStartup(): void {\r\n const urlParams = new URLSearchParams(window.location.search);\r\n \r\n // Detectar TODOS los parámetros que indican un callback OAuth\r\n // Keycloak puede enviar: code, state, session_state, iss (RFC 9207)\r\n const isOAuthCallback = urlParams.has('code') || \r\n urlParams.has('iss') || \r\n urlParams.has('session_state') ||\r\n urlParams.has('state') ||\r\n window.location.hash.includes('access_token') ||\r\n window.location.hash.includes('code');\r\n \r\n if (isOAuthCallback) {\r\n console.log('[AuthService] OAuth callback detected, skipping token cleanup');\r\n return;\r\n }\r\n\r\n // Verificar si hay un token y si está expirado\r\n const expiresAt = localStorage.getItem('expires_at') || sessionStorage.getItem('expires_at');\r\n if (expiresAt) {\r\n const expirationTime = parseInt(expiresAt, 10);\r\n const now = Date.now();\r\n \r\n if (expirationTime < now) {\r\n console.log('[AuthService] Expired token detected, clearing storage');\r\n this.clearAllTokens();\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Limpia todos los tokens del storage\r\n */\r\n private clearAllTokens(): void {\r\n const keysToRemove = [\r\n 'access_token', 'refresh_token', 'id_token', 'token_type',\r\n 'expires_at', 'nonce', 'PKCE_verifier', 'session_state',\r\n 'id_token_claims_obj', 'id_token_expires_at', 'id_token_stored_at',\r\n 'access_token_stored_at'\r\n ];\r\n \r\n keysToRemove.forEach(key => {\r\n localStorage.removeItem(key);\r\n sessionStorage.removeItem(key);\r\n });\r\n }\r\n\r\n /**\r\n * Limpia tokens antiguos pero MANTIENE state, nonce y PKCE_verifier\r\n * que son necesarios para validar el callback OAuth\r\n */\r\n private clearOldTokensKeepState(): void {\r\n // Solo limpiar tokens, NO state/nonce/PKCE_verifier\r\n const keysToRemove = [\r\n 'access_token', 'refresh_token', 'id_token', 'token_type',\r\n 'expires_at', 'id_token_claims_obj', 'id_token_expires_at', \r\n 'id_token_stored_at', 'access_token_stored_at'\r\n ];\r\n \r\n keysToRemove.forEach(key => {\r\n localStorage.removeItem(key);\r\n sessionStorage.removeItem(key);\r\n });\r\n \r\n console.log('[AuthService] Cleared old tokens, kept state/nonce/PKCE for callback validation');\r\n }\r\n\r\n private handleSuccessfulAuthentication(): void {\r\n if (this.oauthService.hasValidAccessToken()) {\r\n this.isAuthenticatedSubject$.next(true);\r\n this.isDoneLoadingSubject$.next(true);\r\n \r\n // Limpiar parámetros OAuth de la URL para evitar problemas al refrescar\r\n this.cleanupOAuthParams();\r\n \r\n if (this.isInitialLogin) {\r\n this.isInitialLogin = false;\r\n }\r\n } else {\r\n this.isDoneLoadingSubject$.next(true);\r\n }\r\n }\r\n\r\n /**\r\n * Limpia los parámetros OAuth de la URL después del login exitoso\r\n * Esto evita problemas cuando el usuario refresca la página\r\n */\r\n private cleanupOAuthParams(): void {\r\n try {\r\n const url = new URL(window.location.href);\r\n const paramsToRemove = ['code', 'state', 'session_state', 'iss'];\r\n let hasOAuthParams = false;\r\n \r\n paramsToRemove.forEach(param => {\r\n if (url.searchParams.has(param)) {\r\n url.searchParams.delete(param);\r\n hasOAuthParams = true;\r\n }\r\n });\r\n \r\n if (hasOAuthParams) {\r\n // Reemplazar URL sin recargar la página\r\n window.history.replaceState({}, document.title, url.toString());\r\n console.log('[AuthService] OAuth params cleaned from URL');\r\n }\r\n } catch (error) {\r\n console.warn('[AuthService] Error cleaning OAuth params:', error);\r\n }\r\n }\r\n\r\n private handleSilentRefresh(): void {\r\n if (this.oauthService.hasValidAccessToken()) {\r\n this.isAuthenticatedSubject$.next(true);\r\n this.isDoneLoadingSubject$.next(true);\r\n }\r\n }\r\n\r\n private handleLogout(): void {\r\n this.isAuthenticatedSubject$.next(false);\r\n this.isDoneLoadingSubject$.next(true);\r\n }\r\n\r\n /**\r\n * Limpia todos los tokens del storage\r\n */\r\n private clearTokenStorage(): void {\r\n this.oauthService.logOut(true); // true = no redirect, solo limpiar\r\n localStorage.removeItem('access_token');\r\n localStorage.removeItem('refresh_token');\r\n localStorage.removeItem('id_token');\r\n localStorage.removeItem('nonce');\r\n localStorage.removeItem('expires_at');\r\n sessionStorage.removeItem('access_token');\r\n sessionStorage.removeItem('refresh_token');\r\n sessionStorage.removeItem('id_token');\r\n }\r\n\r\n /**\r\n * Verifica si el token actual está expirado\r\n */\r\n private isTokenExpired(): boolean {\r\n const expiresAt = this.oauthService.getAccessTokenExpiration();\r\n if (!expiresAt) {\r\n return false; // Si no hay token, no está \"expirado\", simplemente no existe\r\n }\r\n return expiresAt < Date.now();\r\n }\r\n\r\n private async runInitialLoginSequence(): Promise<void> {\r\n try {\r\n const urlParams = new URLSearchParams(window.location.search);\r\n const hasCode = urlParams.has('code');\r\n const hasState = urlParams.has('state');\r\n const hasIss = urlParams.has('iss');\r\n const hasSessionState = urlParams.has('session_state');\r\n const hasFragment = window.location.hash.includes('access_token') || window.location.hash.includes('code');\r\n \r\n // Detectar si estamos en un callback OAuth (Keycloak envía code, state, session_state, iss)\r\n const isOAuthCallback = hasCode || hasFragment || (hasState && (hasIss || hasSessionState));\r\n\r\n // Si NO estamos en callback OAuth y hay tokens expirados, limpiar y terminar\r\n if (!isOAuthCallback && this.isTokenExpired()) {\r\n console.log('[AuthService] No OAuth callback detected and token expired, clearing storage');\r\n this.clearTokenStorage();\r\n this.isDoneLoadingSubject$.next(true);\r\n return;\r\n }\r\n\r\n // Si estamos en callback OAuth, SIEMPRE limpiar tokens anteriores para evitar conflictos\r\n // Esto es crítico: angular-oauth2-oidc valida tokens existentes antes de procesar el código nuevo\r\n if (isOAuthCallback) {\r\n console.log('[AuthService] OAuth callback detected, clearing old tokens before processing');\r\n // Limpiar solo tokens, NO el state/nonce que necesitamos para validar el callback\r\n this.clearOldTokensKeepState();\r\n \r\n this.isInitialLogin = true;\r\n await this.oauthService.tryLoginCodeFlow();\r\n } \r\n\r\n const hasValidToken = this.oauthService.hasValidAccessToken();\r\n \r\n if (hasValidToken) {\r\n if (!hasCode && !hasFragment) {\r\n this.isInitialLogin = false;\r\n }\r\n this.handleSuccessfulAuthentication();\r\n } else {\r\n this.isDoneLoadingSubject$.next(true);\r\n }\r\n \r\n } catch (error: any) {\r\n console.error('[AuthService] Error during authentication initialization:', error);\r\n \r\n // Si el error es por token expirado, limpiar y permitir nuevo login\r\n if (error?.message?.includes('expired') || error?.reason?.includes('expired')) {\r\n this.clearTokenStorage();\r\n }\r\n \r\n this.isDoneLoadingSubject$.next(true);\r\n } \r\n }\r\n\r\n private setupManualConfiguration(): void {\r\n const authConfig = this.store.authConfig();\r\n this.oauthService.tokenEndpoint = authConfig.tokenEndpoint!;\r\n this.oauthService.userinfoEndpoint = authConfig.userinfoEndpoint!;\r\n this.oauthService.loginUrl = authConfig.loginUrl!;\r\n this.oauthService.logoutUrl = authConfig.logoutUrl!;\r\n this.oauthService.clientId = authConfig.clientId!;\r\n this.oauthService.redirectUri = authConfig.redirectUri!;\r\n this.oauthService.scope = authConfig.scope!;\r\n this.oauthService.responseType = authConfig.responseType!;\r\n }\r\n\r\n public initializeAuth(authConfig: AuthConfig): void {\r\n const urlParams = new URLSearchParams(window.location.search);\r\n const hasCode = urlParams.has('code');\r\n \r\n // Si es callback OAuth, resetear TODO el estado de OAuthService\r\n if (hasCode) {\r\n console.log('[AuthService] OAuth callback detected: resetting OAuthService state');\r\n \r\n // Limpiar storage EXCEPTO state/nonce/PKCE\r\n this.clearOldTokensKeepState();\r\n \r\n // CRÍTICO: Resetear propiedades internas de OAuthService\r\n // para que no valide tokens viejos en memoria\r\n this.resetOAuthServiceInternalState();\r\n } else {\r\n // No es callback - verificar si hay tokens expirados\r\n const expiresAt = localStorage.getItem('expires_at');\r\n const isExpired = expiresAt && parseInt(expiresAt, 10) < Date.now();\r\n \r\n if (isExpired) {\r\n console.log('[AuthService] Clearing all expired tokens before configure');\r\n this.clearAllTokens();\r\n this.resetOAuthServiceInternalState();\r\n }\r\n }\r\n \r\n // Ahora es seguro configurar OAuthService\r\n this.oauthService.configure(authConfig);\r\n this.setupManualConfiguration();\r\n this.runInitialLoginSequence();\r\n }\r\n\r\n /**\r\n * Resetea las propiedades internas de OAuthService\r\n * Esto es necesario porque la librería guarda tokens en memoria\r\n * que no se limpian con localStorage/sessionStorage\r\n */\r\n private resetOAuthServiceInternalState(): void {\r\n try {\r\n const oauth = this.oauthService as any;\r\n oauth._accessToken = null;\r\n oauth._idToken = null;\r\n oauth._idTokenClaims = null;\r\n oauth.idTokenClaimsJson = null;\r\n oauth._refreshToken = null;\r\n console.log('[AuthService] OAuthService internal state reset');\r\n } catch (e) {\r\n console.warn('[AuthService] Could not reset internal state:', e);\r\n }\r\n }\r\n\r\n public getAuthConfig(): AuthConfig {\r\n return this.store.authConfig();\r\n }\r\n\r\n public login(targetUrl?: string): void {\r\n this.isInitialLogin = true;\r\n \r\n if (!this.oauthService.clientId) {\r\n return;\r\n }\r\n if (!this.oauthService.redirectUri) {\r\n return;\r\n }\r\n\r\n this.oauthService.initLoginFlow(targetUrl || undefined);\r\n }\r\n\r\n public async logout(): Promise<void> {\r\n try {\r\n await this.callKeycloakLogoutEndpoint().catch(err => {\r\n console.warn('Keycloak logout endpoint failed, but will continue with local cleanup:', err);\r\n });\r\n \r\n this.performLocalLogout();\r\n \r\n } catch (error) {\r\n console.error('Error during logout:', error);\r\n this.performLocalLogout();\r\n }\r\n }\r\n\r\n private async callKeycloakLogoutEndpoint(): Promise<void> {\r\n const authConfig = this.store.authConfig();\r\n const logoutUrl = authConfig.logoutUrl;\r\n \r\n let refreshToken: string | null = this.oauthService.getRefreshToken();\r\n \r\n if (!refreshToken) {\r\n refreshToken = localStorage.getItem('refresh_token') \r\n || localStorage.getItem('refresh_token_' + authConfig.clientId)\r\n || sessionStorage.getItem('refresh_token');\r\n }\r\n \r\n if (!logoutUrl) {\r\n console.warn('Logout URL not configured, skipping Keycloak logout');\r\n return;\r\n }\r\n\r\n if (!refreshToken) {\r\n console.warn('No refresh token found, logout endpoint may fail');\r\n }\r\n\r\n const body = new URLSearchParams();\r\n body.set('client_id', authConfig.clientId!);\r\n \r\n if (refreshToken) {\r\n body.set('refresh_token', refreshToken);\r\n }\r\n\r\n const headers: HeadersInit = {\r\n 'Content-Type': 'application/x-www-form-urlencoded'\r\n };\r\n\r\n try {\r\n const response = await fetch(logoutUrl, {\r\n method: 'POST',\r\n headers,\r\n body: body.toString()\r\n });\r\n\r\n if (!response.ok) {\r\n const errorText = await response.text();\r\n console.warn('Keycloak logout returned error, but local cleanup completed:', errorText);\r\n }\r\n } catch (error) {\r\n console.warn('Failed to call Keycloak logout endpoint:', error);\r\n }\r\n }\r\n\r\n private performLocalLogout(): void {\r\n this.oauthService.logOut(true);\r\n \r\n // Limpiar tokens del localStorage\r\n localStorage.removeItem('access_token');\r\n localStorage.removeItem('id_token');\r\n localStorage.removeItem('refresh_token');\r\n localStorage.removeItem('code_verifier');\r\n localStorage.removeItem('nonce');\r\n localStorage.removeItem('PKCE_verifier');\r\n \r\n // Limpiar tokens del sessionStorage\r\n sessionStorage.removeItem('access_token');\r\n sessionStorage.removeItem('id_token');\r\n sessionStorage.removeItem('refresh_token');\r\n sessionStorage.removeItem('nonce');\r\n sessionStorage.removeItem('PKCE_verifier');\r\n \r\n this.isAuthenticatedSubject$.next(false);\r\n this.isDoneLoadingSubject$.next(true);\r\n \r\n const currentUrl = this.router.url;\r\n if (currentUrl !== '/login' && !currentUrl.includes('/login')) {\r\n this.router.navigate(['/login']);\r\n }\r\n }\r\n\r\n public logoutAndRedirect(targetUrl: string = '/login'): void {\r\n this.logout();\r\n this.router.navigate([targetUrl]);\r\n }\r\n\r\n public hasValidToken(): boolean {\r\n return this.oauthService.hasValidAccessToken();\r\n }\r\n\r\n public get identityClaims(): any {\r\n return this.oauthService.getIdentityClaims();\r\n }\r\n\r\n public get accessToken(): string {\r\n return this.oauthService.getAccessToken();\r\n }\r\n\r\n public getUserRoles(): string[] {\r\n const claims = this.identityClaims;\r\n if (claims?.roles) {\r\n return Array.isArray(claims.roles) ? claims.roles : [claims.roles];\r\n }\r\n \r\n if (claims) {\r\n const roles: string[] = [];\r\n \r\n if (claims.realm_access?.roles) {\r\n roles.push(...claims.realm_access.roles);\r\n }\r\n \r\n const authConfig = this.store.authConfig();\r\n if (claims.resource_access?.[authConfig.clientId!]?.roles) {\r\n roles.push(...claims.resource_access[authConfig.clientId!].roles);\r\n }\r\n \r\n return roles;\r\n }\r\n return [];\r\n }\r\n\r\n public hasRole(role: string): boolean {\r\n return this.getUserRoles().includes(role);\r\n }\r\n\r\n public hasAnyRole(roles: string[]): boolean {\r\n const userRoles = this.getUserRoles();\r\n return roles.some(role => userRoles.includes(role));\r\n }\r\n\r\n public getUserGroups(): string[] {\r\n const claims = this.identityClaims;\r\n const groups: string[] = [];\r\n\r\n // First, try to get groups from identity claims (ID token)\r\n if (claims) {\r\n if (claims.groups) {\r\n if (Array.isArray(claims.groups)) {\r\n groups.push(...claims.groups);\r\n } else {\r\n groups.push(claims.groups);\r\n }\r\n }\r\n\r\n if (claims.accessTokenGroups) {\r\n if (Array.isArray(claims.accessTokenGroups)) {\r\n groups.push(...claims.accessTokenGroups);\r\n } else {\r\n groups.push(claims.accessTokenGroups);\r\n }\r\n }\r\n\r\n if (claims.realm_access?.groups) {\r\n groups.push(...claims.realm_access.groups);\r\n }\r\n }\r\n\r\n // If no groups found in ID token, try to decode access token\r\n if (groups.length === 0) {\r\n const accessToken = this.accessToken;\r\n if (accessToken) {\r\n try {\r\n const payload = this.decodeJwtPayload(accessToken);\r\n console.log('[AuthService] Access token payload:', payload);\r\n\r\n // Extract groups from access token\r\n if (payload.groups) {\r\n if (Array.isArray(payload.groups)) {\r\n groups.push(...payload.groups);\r\n } else {\r\n groups.push(payload.groups);\r\n }\r\n }\r\n\r\n // Also check realm_access.roles as groups (Keycloak pattern)\r\n if (payload.realm_access?.roles) {\r\n groups.push(...payload.realm_access.roles);\r\n }\r\n\r\n // Check resource_access for client-specific roles\r\n if (payload.resource_access) {\r\n Object.values(payload.resource_access).forEach((resource: any) => {\r\n if (resource.roles && Array.isArray(resource.roles)) {\r\n groups.push(...resource.roles);\r\n }\r\n });\r\n }\r\n } catch (error) {\r\n console.error('[AuthService] Error decoding access token:', error);\r\n }\r\n }\r\n }\r\n\r\n const uniqueGroups = [...new Set(groups)];\r\n console.log('[AuthService] getUserGroups result:', uniqueGroups);\r\n return uniqueGroups;\r\n }\r\n\r\n private decodeJwtPayload(token: string): any {\r\n try {\r\n const parts = token.split('.');\r\n if (parts.length !== 3) {\r\n throw new Error('Invalid JWT format');\r\n }\r\n const payload = parts[1];\r\n const decoded = atob(payload.replace(/-/g, '+').replace(/_/g, '/'));\r\n return JSON.parse(decoded);\r\n } catch (error) {\r\n console.error('[AuthService] Failed to decode JWT:', error);\r\n return {};\r\n }\r\n }\r\n}\r\n","import { Injectable } from '@angular/core';\r\nimport { HttpClient } from '@angular/common/http';\r\nimport { firstValueFrom } from 'rxjs';\r\nimport { AppConfiguration, ConfigServerResponse } from '../models/app-config.interface';\r\nimport { FrmkConfigStore } from './frmk-config-store.service';\r\n\r\n@Injectable({ \r\n providedIn: 'root' \r\n})\r\nexport class ConfigService {\r\n private configServerData: ConfigServerResponse | null = null;\r\n private isLoaded = false;\r\n\r\n constructor(\r\n private readonly http: HttpClient,\r\n private readonly store: FrmkConfigStore\r\n ) {}\r\n\r\n /**\r\n * Carga la configuración desde el config-server\r\n */\r\n async loadConfig(): Promise<void> {\r\n try {\r\n const appConfig = this.store.appConfig();\r\n const url = `${appConfig.configServer.url}/${appConfig.configServer.frontend}`;\r\n \r\n this.configServerData = await firstValueFrom(\r\n this.http.get<ConfigServerResponse>(url)\r\n );\r\n \r\n // Aplicar datos del server al store — todos los computeds se recalculan automáticamente\r\n this.store.applyServerConfig(this.configServerData);\r\n \r\n this.isLoaded = true;\r\n } catch (error) {\r\n console.log(`Exception while loading config: ${error}`);\r\n this.store.applyServerConfig();\r\n this.isLoaded = true;\r\n }\r\n }\r\n\r\n /**\r\n * Obtiene un valor de configuración por clave del config server\r\n */\r\n get(key: string): string | boolean | undefined {\r\n return this.configServerData?.[key as keyof ConfigServerResponse];\r\n }\r\n\r\n /**\r\n * Obtiene toda la configuración del config server\r\n */\r\n getAll(): ConfigServerResponse | null {\r\n return this.configServerData ? { ...this.configServerData } : null;\r\n }\r\n\r\n /**\r\n * Verifica si la configuración ha sido cargada\r\n */\r\n isConfigLoaded(): boolean {\r\n return this.isLoaded;\r\n }\r\n\r\n /**\r\n * Obtiene la configuración final de la aplicación (con valores del config server aplicados)\r\n */\r\n getAppConfig(): AppConfiguration {\r\n return this.store.appConfig();\r\n }\r\n\r\n /**\r\n * Obtiene los datos raw del config server\r\n */\r\n getConfigServerData(): ConfigServerResponse | null {\r\n return this.configServerData;\r\n }\r\n}\r\n","import { Injectable } from '@angular/core';\r\nimport { HttpClient, HttpParams, HttpHeaders } from '@angular/common/http';\r\nimport { Observable, of } from 'rxjs';\r\nimport { catchError, map } from 'rxjs/operators';\r\nimport { AuthService } from './authentication.service';\r\nimport { ConfigService } from './config.service';\r\nimport { AuthorizationRequest, AuthorizationResponse, MenuHierarchyItem } from '../models/authorization.interface';\r\n\r\n@Injectable({\r\n providedIn: 'root'\r\n})\r\nexport class AuthorizationService {\r\n\r\n constructor(\r\n private readonly http: HttpClient,\r\n private readonly authService: AuthService,\r\n private readonly configService: ConfigService\r\n ) {}\r\n\r\n /**\r\n * Verifica si el usuario tiene permisos para acceder a un recurso específico\r\n */\r\n verifyPermission(resourcePath: string, operationName: string = 'VIEW'): Observable<boolean> {\r\n const groups = this.getUserGroups();\r\n const config = this.configService.getAppConfig();\r\n \r\n if (groups.length === 0) {\r\n return of(false);\r\n }\r\n\r\n const request: AuthorizationRequest = {\r\n groupIds: groups,\r\n componentId: config.configServer.frontend,\r\n resourcePath: resourcePath,\r\n operationName: operationName\r\n };\r\n\r\n return this.checkAuthorization(request);\r\n }\r\n\r\n /**\r\n * Realiza la llamada HTTP al servicio de autorización\r\n */\r\n private checkAuthorization(request: AuthorizationRequest): Observable<boolean> {\r\n let params = new HttpParams();\r\n \r\n const cleanGroups = request.groupIds.map(group => group.replace(/\\//g, ''));\r\n const groupIdsString = cleanGroups.join(',');\r\n \r\n params = params.set('groupIds', groupIdsString);\r\n params = params.set('componentId', request.componentId);\r\n params = params.set('resourcePath', request.resourcePath);\r\n params = params.set('operationName', request.operationName);\r\n\r\n let headers = new HttpHeaders();\r\n\r\n const url = `${this.configService.getAppConfig().authorization.baseUrl}${this.configService.getAppConfig().authorization.verifyEndpoint}`;\r\n\r\n return this.http.get<AuthorizationResponse>(url, { \r\n params,\r\n headers\r\n }).pipe(\r\n map(response => {\r\n return response.hasPermission;\r\n }),\r\n catchError(() => {\r\n return of(false);\r\n })\r\n );\r\n }\r\n\r\n /**\r\n * Obtiene los grupos del usuario desde el access token\r\n */\r\n private getUserGroups(): string[] {\r\n return this.authService.getUserGroups();\r\n }\r\n\r\n /** \r\n * Método público para obtener los grupos del usuario (útil para debugging)\r\n */\r\n public getUserGroupsDebug(): string[] {\r\n return this.authService.getUserGroups();\r\n }\r\n\r\n /**\r\n * Obtiene la jerarquía de menús basada en el componente y los grupos del usuario\r\n */\r\n getMenuHierarchy(): Observable<MenuHierarchyItem[]> {\r\n const groups = this.getUserGroups();\r\n const config = this.configService.getAppConfig();\r\n \r\n if (groups.length === 0) {\r\n return of([]);\r\n }\r\n\r\n const cleanGroups = groups.map(group => group.replace(/\\//g, ''));\r\n const groupIdsString = cleanGroups.join(',');\r\n\r\n let params = new HttpParams();\r\n params = params.set('componentId', config.configServer.frontend);\r\n params = params.set('groupIds', groupIdsString);\r\n\r\n let headers = new HttpHeaders();\r\n\r\n const url = `${config.authorization.baseUrl}${config.authorization.hierarchyEndpoint}`;\r\n\r\n return this.http.get<MenuHierarchyItem[]>(url, { \r\n params,\r\n headers\r\n }).pipe(\r\n catchError(error => {\r\n console.error('Error obteniendo jerarquía de menús:', error);\r\n return of([]);\r\n })\r\n );\r\n }\r\n\r\n /**\r\n * Obtiene elementos de menú de nivel raíz (level 1)\r\n */\r\n getRootMenuItems(menuHierarchy: MenuHierarchyItem[]): MenuHierarchyItem[] {\r\n return menuHierarchy.filter(item => item.level === 1);\r\n }\r\n\r\n /**\r\n * Obtiene elementos hijos de un elemento padre específico por path\r\n */\r\n getChildMenuItems(menuHierarchy: MenuHierarchyItem[], parentPath: string, level: number): MenuHierarchyItem[] {\r\n return menuHierarchy.filter(item => \r\n item.level === level && \r\n item.hasParent && \r\n item.path.startsWith(parentPath) &&\r\n item.path !== parentPath &&\r\n this.isDirectChild(item.path, parentPath, level)\r\n );\r\n }\r\n\r\n /**\r\n * Verifica si un elemento tiene hijos\r\n */\r\n hasChildren(menuHierarchy: MenuHierarchyItem[], item: MenuHierarchyItem): boolean {\r\n return this.getChildMenuItems(menuHierarchy, item.path, item.level + 1).length > 0;\r\n }\r\n\r\n /**\r\n * Verifica si un path es hijo directo de otro path\r\n */\r\n private isDirectChild(childPath: string, parentPath: string, expectedLevel: number): boolean {\r\n const relativePath = childPath.substring(parentPath.length);\r\n const slashCount = (relativePath.match(/\\//g) || []).length;\r\n return slashCount === 1;\r\n }\r\n\r\n /**\r\n * Verifica múltiples permisos a la vez\r\n */\r\n verifyMultiplePermissions(permissions: { resourcePath: string, operationName?: string }[]): Observable<{ [key: string]: boolean }> {\r\n const results: { [key: string]: boolean } = {};\r\n const observables = permissions.map(permission => \r\n this.verifyPermission(permission.resourcePath, permission.operationName).pipe(\r\n map(authorized => ({ \r\n key: `${permission.resourcePath}_${permission.operationName || 'VIEW'}`, \r\n authorized \r\n }))\r\n )\r\n );\r\n\r\n return new Observable(observer => {\r\n let completed = 0;\r\n observables.forEach(obs => {\r\n obs.subscribe(result => {\r\n results[result.key] = result.authorized;\r\n completed++;\r\n if (completed === observables.length) {\r\n observer.next(results);\r\n observer.complete();\r\n }\r\n });\r\n });\r\n });\r\n }\r\n}\r\n","import { inject } from '@angular/core';\r\nimport { CanActivateFn, Router } from '@angular/router';\r\nimport { AuthService } from '../services/authentication.service';\r\nimport { map, take } from 'rxjs/operators';\r\n\r\nexport const authGuard: CanActivateFn = (route, state) => {\r\n const authService = inject(AuthService);\r\n const router = inject(Router);\r\n\r\n const handleAuthenticated = (): boolean => {\r\n return true;\r\n };\r\n\r\n const handleUnauthenticated = (currentUrl: string): boolean => {\r\n if (currentUrl !== '/login' && !currentUrl.includes('/login')) {\r\n router.navigate(['/login'], { \r\n queryParams: { returnUrl: currentUrl } \r\n });\r\n }\r\n return false;\r\n }; \r\n\r\n return authService.isAuthenticated$.pipe(\r\n take(1),\r\n map(isAuthenticated => {\r\n return isAuthenticated \r\n ? handleAuthenticated() \r\n : handleUnauthenticated(state.url);\r\n })\r\n );\r\n};\r\n","import { Component, OnInit, OnDestroy, input, computed, inject } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { Subscription } from 'rxjs';\r\nimport { AuthService } from '../../services/authentication.service';\r\nimport { FrmkConfigStore } from '../../services/frmk-config-store.service';\r\nimport { LoginConfig, DEFAULT_LOGIN_CONFIG } from '../../models/login-config.interface';\r\nimport { VERSION } from '../../version';\r\n\r\n@Component({\r\n selector: 'lib-login',\r\n standalone: true,\r\n imports: [CommonModule],\r\n templateUrl: './login.component.html',\r\n styleUrls: ['./login.component.scss']\r\n})\r\nexport class LoginComponent implements OnInit, OnDestroy {\r\n /**\r\n * Configuration object to customize the login component appearance and behavior\r\n */\r\n readonly config = input<Partial<LoginConfig>>({});\r\n\r\n private readonly store = inject(FrmkConfigStore);\r\n\r\n isLoggingIn = false;\r\n statusMessage = '';\r\n private authSubscription?: Subscription;\r\n private isProcessingCallback = false;\r\n\r\n /** Configuración merged: defaults ← libraryConfig.loginConfig ← @Input config */\r\n readonly mergedConfig = computed<LoginConfig>(() => {\r\n const storeConfig = this.store.isConfigured()\r\n ? this.store.loginConfig()\r\n : DEFAULT_LOGIN_CONFIG;\r\n const inputCfg = this.config() ?? {};\r\n return {\r\n ...storeConfig,\r\n ...inputCfg,\r\n version: inputCfg.version || storeConfig.version || VERSION\r\n };\r\n });\r\n\r\n constructor(public authService: AuthService) {}\r\n\r\n ngOnInit() {\r\n // Check if processing OAuth callback\r\n // Also check for 'iss' and 'session_state' which indicate we came from OAuth even if 'code' was already processed\r\n const urlParams = new URLSearchParams(globalThis.location?.search || '');\r\n const hasCode = urlParams.has('code');\r\n const hasIss = urlParams.has('iss');\r\n const hasSessionState = urlParams.has('session_state');\r\n const hasFragment = (globalThis.location?.hash || '').includes('access_token') || \r\n (globalThis.location?.hash || '').includes('code');\r\n \r\n if (hasCode || hasFragment || hasIss || hasSessionState) {\r\n this.isProcessingCallback = true;\r\n this.statusMessage = 'Procesando autenticación...';\r\n }\r\n\r\n // Subscribe to authentication state changes\r\n this.authSubscription = this.authService.isAuthenticated$.subscribe(isAuthenticated => {\r\n if (isAuthenticated) {\r\n this.statusMessage = '¡Autenticación exitosa! Redirigiendo...';\r\n // Small delay to show success message, then redirect\r\n setTimeout(() => {\r\n this.navigateToRedirect();\r\n }, 500);\r\n }\r\n });\r\n }\r\n\r\n ngOnDestroy() {\r\n if (this.authSubscription) {\r\n this.authSubscription.unsubscribe();\r\n }\r\n }\r\n\r\n /**\r\n * Get merged configuration value\r\n */\r\n getConfig<K extends keyof LoginConfig>(key: K): LoginConfig[K] {\r\n return this.mergedConfig()[key];\r\n }\r\n\r\n /**\r\n * Get custom CSS styles for theming\r\n */\r\n getCustomStyles(): { [key: string]: string } {\r\n const styles: { [key: string]: string } = {};\r\n const cfg = this.mergedConfig();\r\n \r\n if (cfg.primaryColor) {\r\n styles['--color-primary'] = cfg.primaryColor;\r\n }\r\n if (cfg.backgroundColor) {\r\n styles['--login-bg-color'] = cfg.backgroundColor;\r\n }\r\n if (cfg.textColor) {\r\n styles['--login-text-color'] = cfg.textColor;\r\n }\r\n \r\n return styles;\r\n }\r\n\r\n login(): void {\r\n this.isLoggingIn = true;\r\n this.statusMessage = 'Redirigiendo al proveedor de autenticación...';\r\n \r\n setTimeout(() => {\r\n this.authService.login();\r\n }, 500);\r\n }\r\n\r\n logout(): void {\r\n this.authService.logout();\r\n this.isLoggingIn = false;\r\n this.statusMessage = '';\r\n this.isProcessingCallback = false;\r\n }\r\n\r\n goToDashboard(): void {\r\n this.navigateToRedirect();\r\n }\r\n\r\n private navigateToRedirect(): void {\r\n const redirectUrl = this.mergedConfig().redirectUrl;\r\n if (typeof globalThis.location !== 'undefined') {\r\n const baseUrl = `${globalThis.location.protocol}//${globalThis.location.host}`;\r\n globalThis.location.href = `${baseUrl}${redirectUrl}`;\r\n }\r\n }\r\n}\r\n","<div class=\"login-page\" [ngStyle]=\"getCustomStyles()\">\r\n <div class=\"login-page__container\">\r\n <!-- Logo -->\r\n <div class=\"login-page__logo\">\r\n <img \r\n [src]=\"getConfig('logoUrl')\" \r\n [alt]=\"getConfig('logoAlt')\" \r\n class=\"login-page__logo-img\"\r\n [style.width]=\"getConfig('logoWidth')\"\r\n [style.height]=\"getConfig('logoHeight')\" />\r\n </div>\r\n\r\n <!-- Header -->\r\n <div class=\"login-page__header\">\r\n <h1>{{ getConfig('title') }}</h1>\r\n <p *ngIf=\"getConfig('subtitle')\" class=\"subtitle\">{{ getConfig('subtitle') }}</p>\r\n </div>\r\n \r\n <!-- Login Form -->\r\n <div *ngIf=\"(authService.isDoneLoading$ | async)\" class=\"login-page__form\">\r\n <div *ngIf=\"!(authService.isAuthenticated$ | async)\">\r\n <!-- Status Message -->\r\n <div *ngIf=\"statusMessage\" class=\"auth-alert auth-alert--info\">\r\n <div class=\"auth-alert__content\">\r\n <p>{{ statusMessage }}</p>\r\n </div>\r\n </div>\r\n\r\n <!-- Login Button -->\r\n <button \r\n class=\"btn btn--primary btn--lg\" \r\n (click)=\"login()\" \r\n [disabled]=\"isLoggingIn\"\r\n [class.loading]=\"isLoggingIn\">\r\n {{ isLoggingIn ? 'Redirigiendo...' : getConfig('loginButtonText') }}\r\n </button>\r\n\r\n <!-- Footer -->\r\n <div class=\"login-page__footer\" *ngIf=\"getConfig('showFooter')\">\r\n <p *ngIf=\"getConfig('footerText'); else defaultFooter\">\r\n {{ getConfig('footerText') }}\r\n </p>\r\n <ng-template #defaultFooter>\r\n <p>\r\n Acceso seguro para usuarios de \r\n <strong>{{ getConfig('institutionName') }}</strong>\r\n </p>\r\n </ng-template>\r\n </div>\r\n </div>\r\n \r\n <!-- Already Authenticated -->\r\n <div *ngIf=\"authService.isAuthenticated$ | async\" class=\"auth-alert auth-alert--success\">\r\n <div class=\"auth-alert__content\">\r\n <h4>¡Sesión activa!</h4>\r\n <p>Ya tienes una sesión iniciada en el sistema.</p>\r\n </div>\r\n \r\n <div class=\"login-page__actions\">\r\n <button class=\"btn btn--primary btn--lg\" (click)=\"goToDashboard()\">\r\n {{ getConfig('dashboardButtonText') }}\r\n </button>\r\n \r\n <button \r\n *ngIf=\"getConfig('showLogoutButton')\"\r\n class=\"btn btn--secondary btn--lg\" \r\n (click)=\"logout()\">\r\n {{ getConfig('logoutButtonText') }}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n \r\n <!-- Loading State -->\r\n <div *ngIf=\"!(authService.isDoneLoading$ | async)\" class=\"auth-loading\">\r\n <div class=\"auth-loading__spinner\"></div>\r\n <p class=\"auth-loading__text\">Procesando autenticación...</p>\r\n </div>\r\n\r\n <!-- Version -->\r\n <div *ngIf=\"getConfig('showVersion')\" class=\"login-page__version\">\r\n <span>v{{ getConfig('version') }}</span>\r\n </div>\r\n </div>\r\n</div>\r\n","import { Component, OnInit, HostListener, input, computed, inject } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { RouterModule } from '@angular/router';\r\nimport { AuthService } from '../../services/authentication.service';\r\nimport { AuthorizationService } from '../../services/authorization.service';\r\nimport { FrmkConfigStore } from '../../services/frmk-config-store.service';\r\nimport { MenuHierarchyItem } from '../../models/authorization.interface';\r\nimport { DashboardConfig, DEFAULT_DASHBOARD_CONFIG } from '../../models/dashboard-config.interface';\r\nimport { VERSION } from '../../version';\r\n\r\n// Re-export for backwards compatibility\r\nexport { DashboardConfig } from '../../models/dashboard-config.interface';\r\n\r\n@Component({\r\n selector: 'lib-dashboard',\r\n standalone: true,\r\n imports: [CommonModule, RouterModule],\r\n templateUrl: './dashboard.component.html',\r\n styleUrls: ['./dashboard.component.scss']\r\n})\r\nexport class DashboardComponent implements OnInit {\r\n readonly config = input<Partial<DashboardConfig>>({});\r\n\r\n private readonly store = inject(FrmkConfigStore);\r\n\r\n userInfo: any = null;\r\n userRoles: string[] = [];\r\n menuHierarchy: MenuHierarchyItem[] = [];\r\n isMenuOpen = false;\r\n isLoadingMenu = false;\r\n openMenuItems: Set<string> = new Set();\r\n isUserPanelOpen = false;\r\n isMobileMenuOpen = false;\r\n\r\n /** Configuración merged: defaults ← libraryConfig.dashboardConfig ← @Input config */\r\n readonly mergedConfig = computed<DashboardConfig>(() => {\r\n const storeConfig = this.store.isConfigured()\r\n ? this.store.dashboardConfig()\r\n : DEFAULT_DASHBOARD_CONFIG;\r\n const inputCfg = this.config() ?? {};\r\n return {\r\n ...storeConfig,\r\n ...inputCfg,\r\n version: inputCfg.version || storeConfig.version || VERSION\r\n };\r\n });\r\n\r\n constructor(\r\n public authService: AuthService,\r\n private readonly authorizationService: AuthorizationService\r\n ) {}\r\n\r\n ngOnInit(): void {\r\n this.loadUserInfo();\r\n this.loadMenuHierarchy();\r\n }\r\n\r\n getConfig<K extends keyof DashboardConfig>(key: K): DashboardConfig[K] {\r\n return this.mergedConfig()[key];\r\n }\r\n\r\n get appVersion(): string {\r\n return this.mergedConfig().version;\r\n }\r\n\r\n private loadUserInfo(): void {\r\n this.userInfo = this.authService.identityClaims;\r\n this.userRoles = this.authService.getUserRoles();\r\n }\r\n\r\n private loadMenuHierarchy(): void {\r\n this.isLoadingMenu = true;\r\n this.authorizationService.getMenuHierarchy().subscribe({\r\n next: (menuItems) => {\r\n this.menuHierarchy = this.buildHierarchicalMenu(menuItems);\r\n this.isLoadingMenu = false;\r\n },\r\n error: (error) => {\r\n console.error('Error loading menu hierarchy:', error);\r\n this.menuHierarchy = [];\r\n this.isLoadingMenu = false;\r\n }\r\n });\r\n }\r\n\r\n private buildHierarchicalMenu(flatItems: MenuHierarchyItem[]): MenuHierarchyItem[] {\r\n const itemMap = new Map<string, MenuHierarchyItem>();\r\n \r\n flatItems.forEach(item => {\r\n itemMap.set(item.path, { ...item, children: [] });\r\n });\r\n\r\n const rootItems: MenuHierarchyItem[] = [];\r\n \r\n flatItems.forEach(item => {\r\n const currentItem = itemMap.get(item.path)!;\r\n \r\n if (item.level === 1) {\r\n rootItems.push(currentItem);\r\n } else {\r\n const parent = this.findParent(item, flatItems);\r\n if (parent) {\r\n const parentItem = itemMap.get(parent.path);\r\n if (parentItem?.children) {\r\n parentItem.children.push(currentItem);\r\n }\r\n }\r\n }\r\n });\r\n\r\n return rootItems;\r\n }\r\n\r\n private findParent(item: MenuHierarchyItem, allItems: MenuHierarchyItem[]): MenuHierarchyItem | null {\r\n for (const potentialParent of allItems) {\r\n if (potentialParent.level === item.level - 1 && \r\n item.path.startsWith(potentialParent.path) &&\r\n item.path !== potentialParent.path) {\r\n return potentialParent;\r\n }\r\n }\r\n return null;\r\n }\r\n\r\n toggleMenuItem(itemId: string, item: MenuHierarchyItem): void {\r\n const isCurrentlyOpen = this.openMenuItems.has(itemId);\r\n \r\n if (isCurrentlyOpen) {\r\n this.closeMenuAndChildren(itemId);\r\n } else {\r\n this.closeSiblingMenus(item);\r\n this.openMenuItems.add(itemId);\r\n }\r\n }\r\n\r\n private closeMenuAndChildren(itemId: string): void {\r\n this.openMenuItems.delete(itemId);\r\n const itemsToClose = Array.from(this.openMenuItems).filter(id => id.startsWith(itemId + '-'));\r\n itemsToClose.forEach(id => this.openMenuItems.delete(id));\r\n }\r\n\r\n private closeSiblingMenus(currentItem: MenuHierarchyItem): void {\r\n if (currentItem.level === 1) {\r\n const rootItems = this.getRootMenuItems();\r\n rootItems.forEach(rootItem => {\r\n if (rootItem.code !== currentItem.code) {\r\n this.closeMenuAndChildren(rootItem.code);\r\n }\r\n });\r\n } else {\r\n const allItems = this.flattenMenuItems(this.menuHierarchy);\r\n const parent = this.findParent(currentItem, allItems);\r\n if (parent?.children) {\r\n parent.children.forEach(sibling => {\r\n if (sibling.code !== currentItem.code) {\r\n this.closeMenuAndChildren(sibling.code);\r\n }\r\n });\r\n }\r\n }\r\n }\r\n\r\n private flattenMenuItems(items: MenuHierarchyItem[]): MenuHierarchyItem[] {\r\n const flattened: MenuHierarchyItem[] = [];\r\n \r\n const flatten = (itemList: MenuHierarchyItem[]) => {\r\n itemList.forEach(item => {\r\n flattened.push(item);\r\n if (item.children) {\r\n flatten(item.children);\r\n }\r\n });\r\n };\r\n \r\n flatten(items);\r\n return flattened;\r\n }\r\n\r\n onMenuItemClick(event: Event, item: MenuHierarchyItem): void {\r\n if (this.hasChildren(item)) {\r\n event.preventDefault();\r\n event.stopPropagation();\r\n this.toggleMenuItem(item.code, item);\r\n } else {\r\n // Close mobile menu when navigating to a page\r\n this.closeMobileMenu();\r\n }\r\n }\r\n\r\n @HostListener('document:click', ['$event'])\r\n onDocumentClick(event: Event): void {\r\n const target = event.target as HTMLElement;\r\n const navElement = target.closest('.dashboard-nav');\r\n const userPanel = target.closest('.user-profile');\r\n \r\n if (!navElement) {\r\n this.openMenuItems.clear();\r\n }\r\n \r\n if (!userPanel) {\r\n this.isUserPanelOpen = false;\r\n }\r\n }\r\n\r\n toggleUserPanel(event: Event): void {\r\n event.stopPropagation();\r\n this.isUserPanelOpen = !this.isUserPanelOpen;\r\n }\r\n\r\n getUsername(): string {\r\n if (!this.userInfo?.preferred_username) return 'usuario';\r\n const username = this.userInfo.preferred_username;\r\n const atIndex = username.indexOf('@');\r\n return atIndex > 0 ? username.substring(0, atIndex) : username;\r\n }\r\n\r\n getUserFullName(): string {\r\n return this.userInfo?.name || 'Usuario';\r\n }\r\n\r\n getDocument(): string {\r\n return this.userInfo?.dui || 'N/A';\r\n }\r\n\r\n getInstitution(): string {\r\n return this.userInfo?.direccion || 'N/A';\r\n }\r\n\r\n getDependency(): string {\r\n return this.userInfo?.dependencia || 'N/A';\r\n }\r\n\r\n getRole(): string {\r\n return this.userInfo?.cargo || 'N/A';\r\n }\r\n\r\n isMenuItemOpen(itemId: string): boolean {\r\n return this.openMenuItems.has(itemId);\r\n }\r\n\r\n hasChildren(item: MenuHierarchyItem): boolean {\r\n return !!(item.children && item.children.length > 0);\r\n }\r\n\r\n getRootMenuItems(): MenuHierarchyItem[] {\r\n return this.menuHierarchy.filter(item => item.level === 1);\r\n }\r\n\r\n /**\r\n * Obtiene el icono para un item del menú.\r\n * Si el item tiene un icono definido, lo usa; de lo contrario, usa un icono por defecto según el nivel.\r\n */\r\n getMenuIcon(item: MenuHierarchyItem): string {\r\n // Si tiene icono definido, usarlo\r\n if (item.icono && item.icono.trim() !== '') {\r\n return item.icono;\r\n }\r\n \r\n // Iconos por defecto según el nivel\r\n if (item.level === 1) {\r\n return 'folder';\r\n } else if (item.level === 2) {\r\n return 'article';\r\n } else {\r\n return 'radio_button_unchecked';\r\n }\r\n }\r\n\r\n logoutAndRedirect(): void {\r\n this.authService.logoutAndRedirect();\r\n }\r\n\r\n getUserInitials(): string {\r\n if (!this.userInfo) return 'U';\r\n \r\n const name = this.userInfo.name || this.userInfo.preferred_username || 'Usuario';\r\n const words = name.split(' ');\r\n \r\n if (words.length >= 2) {\r\n return (words[0][0] + words[1][0]).toUpperCase();\r\n } else {\r\n return name.substring(0, 2).toUpperCase();\r\n }\r\n }\r\n\r\n toggleMobileMenu(): void {\r\n this.isMobileMenuOpen = !this.isMobileMenuOpen;\r\n }\r\n\r\n closeMobileMenu(): void {\r\n this.isMobileMenuOpen = false;\r\n document.body.style.overflow = '';\r\n }\r\n}\r\n","<div class=\"dashboard\">\r\n <!-- Header -->\r\n <header class=\"dashboard-header\">\r\n <!-- Mobile Header Top -->\r\n <div class=\"header-mobile-top\">\r\n <div class=\"ministry-logo-mobile\">\r\n <img [src]=\"getConfig('logoUrl')\" [alt]=\"getConfig('logoAlt')\" />\r\n </div>\r\n <h1 class=\"mobile-title\">{{ getConfig('title') }}</h1>\r\n </div>\r\n\r\n <!-- Mobile Header Bottom -->\r\n <div class=\"header-mobile-bottom\">\r\n <button class=\"hamburger-btn\" \r\n (click)=\"toggleMobileMenu()\"\r\n [class.active]=\"isMobileMenuOpen\"\r\n aria-label=\"Toggle menu\">\r\n <span class=\"hamburger-line\"></span>\r\n <span class=\"hamburger-line\"></span>\r\n <span class=\"hamburger-line\"></span>\r\n </button>\r\n\r\n <div class=\"user-profile mobile-user\" *ngIf=\"userInfo\">\r\n <button class=\"user-info-trigger\" \r\n (click)=\"toggleUserPanel($event)\"\r\n [attr.aria-expanded]=\"isUserPanelOpen\"\r\n aria-label=\"Abrir menú de usuario\">\r\n <div class=\"user-avatar\">\r\n <span>{{ getUserInitials() }}</span>\r\n </div>\r\n <div class=\"user-details\">\r\n <span class=\"user-name\">{{ getUsername() }}</span>\r\n </div>\r\n <span class=\"material-symbols-outlined dropdown-icon\">\r\n {{ isUserPanelOpen ? 'expand_less' : 'expand_more' }}\r\n </span>\r\n </button>\r\n \r\n <!-- User Panel -->\r\n <ng-container *ngTemplateOutlet=\"userPanelTemplate\"></ng-container>\r\n </div>\r\n </div>\r\n\r\n <!-- Desktop Header -->\r\n <div class=\"header-desktop-layout\">\r\n <div class=\"header-left\">\r\n <div class=\"ministry-logo\">\r\n <div class=\"logo-icon\">\r\n <img [src]=\"getConfig('logoUrl')\" [alt]=\"getConfig('logoAlt')\" />\r\n </div>\r\n <div class=\"ministry-info\">\r\n <h1>{{ getConfig('title') }}</h1>\r\n <span class=\"subtitle\" *ngIf=\"getConfig('subtitle')\">{{ getConfig('subtitle') }}</span>\r\n </div>\r\n </div>\r\n </div>\r\n \r\n <div class=\"header-right\">\r\n <div class=\"user-profile desktop-user\" *ngIf=\"userInfo\">\r\n <button class=\"user-info-trigger\" \r\n (click)=\"toggleUserPanel($event)\"\r\n [attr.aria-expanded]=\"isUserPanelOpen\"\r\n aria-label=\"Abrir menú de usuario\">\r\n <div class=\"user-avatar\">\r\n <span>{{ getUserInitials() }}</span>\r\n </div>\r\n <div class=\"user-details\">\r\n <span class=\"user-name\">{{ getUsername() }}</span>\r\n </div>\r\n <span class=\"material-symbols-outlined dropdown-icon\">\r\n {{ isUserPanelOpen ? 'expand_less' : 'expand_more' }}\r\n </span>\r\n </button>\r\n \r\n <!-- User Panel -->\r\n <ng-container *ngTemplateOutlet=\"userPanelTemplate\"></ng-container>\r\n </div>\r\n </div>\r\n </div>\r\n </header>\r\n\r\n <!-- User Panel Template -->\r\n <ng-template #userPanelTemplate>\r\n <div class=\"user-panel\" *ngIf=\"isUserPanelOpen\">\r\n <div class=\"user-panel-header\">\r\n <span class=\"panel-title\">Perfil de Usuario</span>\r\n </div>\r\n <div class=\"user-panel-content\">\r\n <div class=\"user-info-item\">\r\n <span class=\"material-symbols-outlined info-icon\">person</span>\r\n <div class=\"info-content\">\r\n <span class=\"info-label\">Código de Usuario:</span>\r\n <span class=\"info-value\">{{ getUsername() }}</span>\r\n </div>\r\n </div>\r\n \r\n <div class=\"user-info-item\">\r\n <span class=\"material-symbols-outlined info-icon\">badge</span>\r\n <div class=\"info-content\">\r\n <span class=\"info-label\">Nombre de Usuario:</span>\r\n <span class=\"info-value\">{{ getUserFullName() }}</span>\r\n </div>\r\n </div>\r\n \r\n <div class=\"user-info-item\">\r\n <span class=\"material-symbols-outlined info-icon\">credit_card</span>\r\n <div class=\"info-content\">\r\n <span class=\"info-label\">Documento:</span>\r\n <span class=\"info-value\">{{ getDocument() }}</span>\r\n </div>\r\n </div>\r\n \r\n <div class=\"user-info-item mobile-hidden\">\r\n <span class=\"material-symbols-outlined info-icon\">business</span>\r\n <div class=\"info-content\">\r\n <span class=\"info-label\">Institución:</span>\r\n <span class=\"info-value\">{{ getInstitution() }}</span>\r\n </div>\r\n </div>\r\n \r\n <div class=\"user-info-item mobile-hidden\">\r\n <span class=\"material-symbols-outlined info-icon\">apartment</span>\r\n <div class=\"info-content\">\r\n <span class=\"info-label\">Dependencia:</span>\r\n <span class=\"info-value\">{{ getDependency() }}</span>\r\n </div>\r\n </div>\r\n \r\n <div class=\"user-info-item mobile-hidden\">\r\n <span class=\"material-symbols-outlined info-icon\">work</span>\r\n <div class=\"info-content\">\r\n <span class=\"info-label\">Rol:</span>\r\n <span class=\"info-value\">{{ getRole() }}</span>\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"user-panel-footer\">\r\n <button class=\"logout-btn-panel\" (click)=\"logoutAndRedirect()\" title=\"Cerrar sesión\">\r\n <span class=\"material-symbols-outlined\">logout</span>\r\n <span class=\"logout-text\">CERRAR SESIÓN</span>\r\n </button>\r\n </div>\r\n </div>\r\n </ng-template>\r\n\r\n <!-- Mobile Menu Overlay -->\r\n <div class=\"nav-overlay\" *ngIf=\"isMobileMenuOpen\" (click)=\"closeMobileMenu()\"></div>\r\n\r\n <!-- Navigation (Horizontal Desktop / Sidebar Mobile) -->\r\n <nav class=\"dashboard-nav\" [class.mobile-open]=\"isMobileMenuOpen\">\r\n <div class=\"nav-mobile-header\">\r\n <div class=\"nav-mobile-logo\">\r\n <img [src]=\"getConfig('logoUrl')\" [alt]=\"getConfig('logoAlt')\" />\r\n <span class=\"nav-mobile-title\">Menú</span>\r\n </div>\r\n <button class=\"nav-close-btn\" (click)=\"closeMobileMenu()\" aria-label=\"Cerrar menú\">\r\n <span class=\"material-symbols-outlined\">close</span>\r\n </button>\r\n </div>\r\n\r\n <div class=\"nav-container\">\r\n <!-- Static Menu Items -->\r\n <ng-container *ngIf=\"getConfig('showStaticMenu')\">\r\n <a routerLink=\".\" \r\n routerLinkActive=\"active\" \r\n [routerLinkActiveOptions]=\"{exact: true}\" \r\n class=\"nav-item\"\r\n (click)=\"closeMobileMenu()\">\r\n <span class=\"material-symbols-outlined nav-icon\">home</span>\r\n <span class=\"nav-text\">Inicio</span>\r\n </a>\r\n </ng-container>\r\n\r\n <!-- Separator -->\r\n <div class=\"nav-separator\" *ngIf=\"!isLoadingMenu && menuHierarchy.length > 0\"></div>\r\n \r\n <!-- Dynamic Menu -->\r\n <div class=\"dynamic-menu\" *ngIf=\"!isLoadingMenu && menuHierarchy.length > 0\">\r\n <ng-container *ngFor=\"let rootItem of getRootMenuItems()\">\r\n <div class=\"menu-item-container\" [class.has-children]=\"hasChildren(rootItem)\">\r\n <a \r\n [routerLink]=\"hasChildren(rootItem) ? null : rootItem.path\" \r\n routerLinkActive=\"active\" \r\n class=\"nav-item root-item\"\r\n [class.expandable]=\"hasChildren(rootItem)\"\r\n (click)=\"onMenuItemClick($event, rootItem)\">\r\n <span class=\"material-symbols-outlined nav-icon\">{{ getMenuIcon(rootItem) }}</span>\r\n <span class=\"nav-text\">{{ rootItem.name }}</span>\r\n <span class=\"material-symbols-outlined expand-icon\" *ngIf=\"hasChildren(rootItem)\">\r\n {{ isMenuItemOpen(rootItem.code) ? 'expand_more' : 'chevron_right' }}\r\n </span>\r\n </a>\r\n \r\n <!-- Submenu -->\r\n <div class=\"submenu\" *ngIf=\"hasChildren(rootItem) && isMenuItemOpen(rootItem.code)\">\r\n <ng-container *ngTemplateOutlet=\"menuTemplate; context: { items: rootItem.children, level: 2 }\"></ng-container>\r\n </div>\r\n </div>\r\n </ng-container>\r\n </div>\r\n \r\n <!-- Loading Indicator -->\r\n <div class=\"menu-loading\" *ngIf=\"isLoadingMenu\">\r\n <span class=\"material-symbols-outlined nav-icon\">hourglass_empty</span>\r\n <span class=\"nav-text\">Cargando menú...</span>\r\n </div>\r\n </div>\r\n </nav>\r\n\r\n <!-- Recursive Menu Template -->\r\n <ng-template #menuTemplate let-items=\"items\" let-level=\"level\">\r\n <ng-container *ngFor=\"let item of items\">\r\n <div class=\"menu-item-container\" [class.has-children]=\"hasChildren(item)\" [attr.data-level]=\"level\">\r\n <a \r\n [routerLink]=\"hasChildren(item) ? null : item.path\" \r\n routerLinkActive=\"active\" \r\n class=\"nav-item submenu-item\"\r\n [class.expandable]=\"hasChildren(item)\"\r\n (click)=\"onMenuItemClick($event, item)\">\r\n <span class=\"material-symbols-outlined nav-icon\">{{ getMenuIcon(item) }}</span>\r\n <span class=\"nav-text\">{{ item.name }}</span>\r\n <span class=\"material-symbols-outlined expand-icon\" *ngIf=\"hasChildren(item)\">\r\n {{ isMenuItemOpen(item.code) ? 'expand_more' : 'chevron_right' }}\r\n </span>\r\n </a>\r\n\r\n <!-- Recursive Submenu (max 5 levels) -->\r\n <div class=\"submenu\" *ngIf=\"hasChildren(item) && isMenuItemOpen(item.code) && level < 5\">\r\n <ng-container *ngTemplateOutlet=\"menuTemplate; context: { items: item.children, level: level + 1 }\"></ng-container>\r\n </div>\r\n </div>\r\n </ng-container>\r\n </ng-template>\r\n\r\n <!-- Main Content -->\r\n <main class=\"dashboard-content\">\r\n <div class=\"content-wrapper\">\r\n <router-outlet></router-outlet>\r\n </div>\r\n </main>\r\n\r\n <!-- Footer -->\r\n <footer class=\"dashboard-footer\">\r\n <div class=\"footer-content\">\r\n <span class=\"footer-text\">\r\n {{ getConfig('footerText') }}\r\n <ng-container *ngIf=\"getConfig('showVersion')\">\r\n Versión {{ appVersion }}.\r\n </ng-container>\r\n Todos los derechos reservados.\r\n </span>\r\n </div>\r\n </footer>\r\n</div>\r\n","// ========================================\r\n// @dinafi/frmk - Public API\r\n// Angular Shared Library - Ministerio de Hacienda\r\n// ========================================\r\n\r\n// === VERSION ===\r\nexport { VERSION, VERSION_INFO } from './lib/version';\r\n\r\n// === MODELS / INTERFACES ===\r\nexport {\r\n // Login Configuration\r\n LoginConfig,\r\n DEFAULT_LOGIN_CONFIG,\r\n \r\n // Dashboard Configuration\r\n DashboardConfig,\r\n DEFAULT_DASHBOARD_CONFIG,\r\n \r\n // Application Configuration\r\n AppConfiguration,\r\n ConfigServerResponse,\r\n \r\n // Authorization\r\n AuthorizationRequest,\r\n AuthorizationResponse,\r\n MenuHierarchyItem,\r\n MenuHierarchyRequest,\r\n \r\n // Library Configuration\r\n FrmkLibraryConfig,\r\n DEFAULT_LIBRARY_CONFIG\r\n} from './lib/models';\r\n\r\n// === SERVICES ===\r\nexport {\r\n // Central Configuration Store (v2.0 — reemplaza funciones globales)\r\n FrmkConfigStore,\r\n \r\n // Authentication Service\r\n AuthService,\r\n \r\n // Authorization Service\r\n AuthorizationService,\r\n \r\n // Configuration Service\r\n ConfigService\r\n} from './lib/services';\r\n\r\n// === GUARDS ===\r\nexport { authGuard } from './lib/guards';\r\n\r\n// === COMPONENTS ===\r\nexport { \r\n LoginComponent \r\n} from './lib/components/login/login.component';\r\n\r\nexport { \r\n DashboardComponent\r\n} from './lib/components/dashboard/dashboard.component';\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":["i2","i3.FrmkConfigStore","i1","i2.FrmkConfigStore","i2.AuthService","i3.ConfigService","i1.AuthService","i2.AuthorizationService"],"mappings":"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"}
package/index.d.ts CHANGED
@@ -10,14 +10,14 @@ import { HttpClient } from '@angular/common/http';
10
10
  * Versión actual de la librería @dinafi/frmk
11
11
  * Sincronizada con package.json
12
12
  */
13
- declare const VERSION = "2.0.1";
13
+ declare const VERSION = "2.0.2";
14
14
  /**
15
15
  * Información completa de la versión
16
16
  */
17
17
  declare const VERSION_INFO: {
18
- readonly version: "2.0.1";
18
+ readonly version: "2.0.2";
19
19
  readonly name: "shared-lib-angular";
20
- readonly buildDate: "2026-02-05T20:39:22.686Z";
20
+ readonly buildDate: "2026-02-05T20:47:48.315Z";
21
21
  readonly angular: "^20.0.0";
22
22
  };
23
23
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "shared-lib-angular",
3
- "version": "2.0.1",
3
+ "version": "2.0.2",
4
4
  "description": "Angular Librería Framework para autenticación, autorización y componentes de UI",
5
5
  "keywords": [
6
6
  "angular",