ngx-dsxlibrary 2.21.11 → 2.21.13

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.
@@ -1750,6 +1750,29 @@ class AuthorizeService {
1750
1750
  const privateIpv4Pattern = /^(10\.|192\.168\.|172\.(1[6-9]|2\d|3[0-1])\.)/;
1751
1751
  return privateIpv4Pattern.test(normalizedHost);
1752
1752
  }
1753
+ /**
1754
+ * Resuelve el dominio a usar para cookies según entorno/host actual.
1755
+ *
1756
+ * Orden de prioridad:
1757
+ * 1. Si `environment.cookieDomain` está configurado, lo usa (para ambientes locales).
1758
+ * 2. Si HTTPS público, usa `.itgtxela.com`.
1759
+ * 3. Si no coincide nada, devuelve undefined (sin dominio compartido).
1760
+ */
1761
+ resolveCookieDomain(isProduction, isHttps) {
1762
+ if (!isProduction || typeof window === 'undefined') {
1763
+ return undefined;
1764
+ }
1765
+ // 1️⃣ Si está configurado en environment, usarlo (para ambientes locales).
1766
+ if (this.environment.cookieDomain) {
1767
+ return this.environment.cookieDomain;
1768
+ }
1769
+ // 2️⃣ Producción pública con HTTPS: mantener dominio corporativo.
1770
+ if (isHttps) {
1771
+ return '.itgtxela.com';
1772
+ }
1773
+ // 3️⃣ Sin coincidencia: sin dominio compartido.
1774
+ return undefined;
1775
+ }
1753
1776
  // Función para obtener opciones de cookies estándar
1754
1777
  /**
1755
1778
  * Construye las opciones usadas por `CookieService` al crear cookies.
@@ -1769,15 +1792,16 @@ class AuthorizeService {
1769
1792
  getCookieOptions(expiryDate) {
1770
1793
  const isProduction = this.environment.production;
1771
1794
  const isHttps = typeof window !== 'undefined' && window.location?.protocol === 'https:';
1795
+ const cookieDomain = this.resolveCookieDomain(isProduction, isHttps);
1772
1796
  const cookieOptions = {
1773
1797
  path: '/',
1774
1798
  expires: expiryDate,
1775
1799
  secure: isHttps,
1776
1800
  sameSite: isHttps ? 'None' : 'Lax',
1777
1801
  };
1778
- // Solo establecer dominio cuando estemos en producción y usemos HTTPS
1779
- if (isProduction && isHttps) {
1780
- cookieOptions.domain = '.itgtxela.com';
1802
+ // Asignar dominio cuando aplique (público HTTPS o red local .local en producción).
1803
+ if (cookieDomain) {
1804
+ cookieOptions.domain = cookieDomain;
1781
1805
  }
1782
1806
  if (isProduction && !isHttps) {
1783
1807
  console.warn('[AuthorizeService] Entorno en producción pero sin HTTPS. Ajustando opciones de cookie para evitar rechazo por Secure/SameSite.');
@@ -2118,7 +2142,13 @@ class AuthorizeService {
2118
2142
  this._cookieService.delete(cookieName, '/');
2119
2143
  // En producción, también intentar eliminar con dominio específico
2120
2144
  if (this.environment.production) {
2121
- this._cookieService.delete(cookieName, '/', '.itgtxela.com');
2145
+ const isHttps = typeof window !== 'undefined' &&
2146
+ window.location?.protocol === 'https:';
2147
+ const dynamicDomain = this.resolveCookieDomain(this.environment.production, isHttps);
2148
+ const domainsToDelete = Array.from(new Set(['.itgtxela.com', dynamicDomain].filter(Boolean)));
2149
+ domainsToDelete.forEach((domain) => {
2150
+ this._cookieService.delete(cookieName, '/', domain);
2151
+ });
2122
2152
  }
2123
2153
  console.debug(`[AuthorizeService] Cookie eliminada: ${cookieName}`);
2124
2154
  }
@@ -4494,6 +4524,8 @@ class UtilityAddService {
4494
4524
  *
4495
4525
  * @param blob Objeto Blob del archivo a descargar
4496
4526
  * @param fileName Nombre completo del archivo incluyendo extensión
4527
+ * @param expectedExtension Extensión esperada (opcional). Si se envía y no coincide
4528
+ * con la extensión final del archivo, se abrirá en una nueva pestaña en lugar de descargar.
4497
4529
  *
4498
4530
  * @example
4499
4531
  * // Opción 1: Usar directamente con un blob
@@ -4505,16 +4537,33 @@ class UtilityAddService {
4505
4537
  * this.utilityAddService.descargarBlob(blob, fileName);
4506
4538
  * });
4507
4539
  */
4508
- descargarBlob(blob, fileName) {
4540
+ descargarBlob(blob, fileName, expectedExtension) {
4509
4541
  if (!blob) {
4510
4542
  console.warn('No se proporcionó un blob válido para descargar.');
4511
4543
  return;
4512
4544
  }
4513
4545
  const fileUrl = URL.createObjectURL(blob);
4514
- const downloadLink = document.createElement('a');
4515
- downloadLink.href = fileUrl;
4516
4546
  const baseFileName = fileName?.trim() || 'archivo_descargado';
4517
4547
  const fullFileName = this.ensureFileNameWithExtension(baseFileName, blob.type);
4548
+ const normalizedExpectedExtension = (expectedExtension || '')
4549
+ .trim()
4550
+ .toLowerCase();
4551
+ if (normalizedExpectedExtension) {
4552
+ const expectedWithDot = normalizedExpectedExtension.startsWith('.')
4553
+ ? normalizedExpectedExtension
4554
+ : `.${normalizedExpectedExtension}`;
4555
+ const currentExtensionMatch = /\.[^./\\]+$/.exec(fullFileName);
4556
+ const currentExtension = currentExtensionMatch
4557
+ ? currentExtensionMatch[0].toLowerCase()
4558
+ : '';
4559
+ if (currentExtension !== expectedWithDot) {
4560
+ window.open(fileUrl, '_blank');
4561
+ this.revokeObjectUrl(fileUrl);
4562
+ return;
4563
+ }
4564
+ }
4565
+ const downloadLink = document.createElement('a');
4566
+ downloadLink.href = fileUrl;
4518
4567
  downloadLink.download = fullFileName;
4519
4568
  downloadLink.click();
4520
4569
  this.revokeObjectUrl(fileUrl);