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
|
-
//
|
|
1779
|
-
if (
|
|
1780
|
-
cookieOptions.domain =
|
|
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
|
-
|
|
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);
|