@masterteam/gateway-auth 0.0.25 → 0.0.26
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.
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { firstValueFrom, EMPTY, of, defer, from, isObservable, map, tap as tap$1, catchError as catchError$1,
|
|
1
|
+
import { firstValueFrom, EMPTY, of, defer, from, isObservable, map, tap as tap$1, throwError, catchError as catchError$1, switchMap as switchMap$1 } from 'rxjs';
|
|
2
2
|
import { HttpClient, HttpContextToken, HttpBackend, HttpResponse } from '@angular/common/http';
|
|
3
3
|
import * as i0 from '@angular/core';
|
|
4
4
|
import { InjectionToken, inject, Injectable, computed, input, ChangeDetectionStrategy, Component, signal, effect } from '@angular/core';
|
|
@@ -1435,25 +1435,64 @@ const normalizePath = (path) => {
|
|
|
1435
1435
|
const withoutQuery = trimmed.split('?')[0] || '';
|
|
1436
1436
|
return withoutQuery.startsWith('api/') ? withoutQuery.slice(4) : withoutQuery;
|
|
1437
1437
|
};
|
|
1438
|
-
|
|
1438
|
+
const getBasePath = (baseUrl) => {
|
|
1439
|
+
if (!baseUrl) {
|
|
1440
|
+
return '';
|
|
1441
|
+
}
|
|
1442
|
+
try {
|
|
1443
|
+
return new URL(baseUrl).pathname;
|
|
1444
|
+
}
|
|
1445
|
+
catch {
|
|
1446
|
+
return baseUrl.startsWith('/') ? baseUrl : '';
|
|
1447
|
+
}
|
|
1448
|
+
};
|
|
1449
|
+
const stripBasePath = (path, baseUrl) => {
|
|
1450
|
+
const basePath = getBasePath(baseUrl).replace(/^\/+/, '').replace(/\/+$/, '');
|
|
1451
|
+
const normalizedPath = path.replace(/^\/+/, '');
|
|
1452
|
+
if (basePath &&
|
|
1453
|
+
(normalizedPath === basePath || normalizedPath.startsWith(`${basePath}/`))) {
|
|
1454
|
+
return normalizedPath.slice(basePath.length).replace(/^\/+/, '');
|
|
1455
|
+
}
|
|
1456
|
+
return path;
|
|
1457
|
+
};
|
|
1458
|
+
const resolveRequestPath = (url, baseUrl) => {
|
|
1459
|
+
let path = url;
|
|
1439
1460
|
if (isAbsoluteUrl(url)) {
|
|
1440
1461
|
try {
|
|
1441
|
-
|
|
1462
|
+
path = new URL(url).pathname;
|
|
1442
1463
|
}
|
|
1443
1464
|
catch {
|
|
1444
|
-
|
|
1465
|
+
path = url;
|
|
1445
1466
|
}
|
|
1446
1467
|
}
|
|
1447
|
-
if (
|
|
1448
|
-
|
|
1468
|
+
else if (baseUrl && url.startsWith(baseUrl)) {
|
|
1469
|
+
path = url.slice(baseUrl.length);
|
|
1449
1470
|
}
|
|
1450
|
-
return normalizePath(
|
|
1471
|
+
return normalizePath(stripBasePath(path, baseUrl));
|
|
1472
|
+
};
|
|
1473
|
+
function resolveGatewayAuthPath(url, gatewayApiBaseUrl) {
|
|
1474
|
+
return resolveRequestPath(url, gatewayApiBaseUrl);
|
|
1451
1475
|
}
|
|
1452
1476
|
function isGatewayAuthRequestUrl(url, gatewayApiBaseUrl) {
|
|
1453
1477
|
const path = resolveGatewayAuthPath(url, gatewayApiBaseUrl).toLowerCase();
|
|
1454
1478
|
return (GATEWAY_AUTH_ENDPOINT_PATHS.has(path) ||
|
|
1455
1479
|
GATEWAY_AUTH_ENDPOINT_PREFIXES.some((prefix) => path.startsWith(prefix)));
|
|
1456
1480
|
}
|
|
1481
|
+
const GATEWAY_APPLICATION_LAUNCH_PATH_PATTERN = /^applications\/[^/]+\/launch$/i;
|
|
1482
|
+
const isGatewayEndpointRequestUrl = (url, gatewayApiBaseUrl) => {
|
|
1483
|
+
const path = resolveGatewayAuthPath(url, gatewayApiBaseUrl).toLowerCase();
|
|
1484
|
+
return (path.startsWith('auth/') ||
|
|
1485
|
+
GATEWAY_APPLICATION_LAUNCH_PATH_PATTERN.test(path));
|
|
1486
|
+
};
|
|
1487
|
+
const isApplicationContextRequestUrl = (url, applicationApiBaseUrl) => resolveRequestPath(url, applicationApiBaseUrl).toLowerCase() ===
|
|
1488
|
+
GATEWAY_AUTH_ENDPOINTS.applicationContext;
|
|
1489
|
+
class GatewaySessionDeadError extends Error {
|
|
1490
|
+
constructor() {
|
|
1491
|
+
super('GATEWAY_SESSION_DEAD');
|
|
1492
|
+
}
|
|
1493
|
+
}
|
|
1494
|
+
const isGatewaySessionDeadError = (error) => error instanceof GatewaySessionDeadError;
|
|
1495
|
+
const isUnauthorizedError = (error) => error?.status === 401;
|
|
1457
1496
|
const getBrowserRefreshLock = () => {
|
|
1458
1497
|
if (typeof navigator === 'undefined') {
|
|
1459
1498
|
return null;
|
|
@@ -1637,22 +1676,31 @@ const executeRelaunch = (context, options) => {
|
|
|
1637
1676
|
},
|
|
1638
1677
|
};
|
|
1639
1678
|
}
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
|
|
1643
|
-
|
|
1644
|
-
|
|
1679
|
+
const ensureGatewayAccessToken = async (forceRefresh = false) => {
|
|
1680
|
+
const gatewayAccessToken = context.auth.token();
|
|
1681
|
+
const gatewayAccessTokenExpiresAt = context.auth.accessTokenExpiresAt();
|
|
1682
|
+
const gatewayAccessExpired = !gatewayAccessToken ||
|
|
1683
|
+
isExpired(gatewayAccessTokenExpiresAt, context.refreshSkewMs);
|
|
1684
|
+
if (!forceRefresh && !gatewayAccessExpired && gatewayAccessToken) {
|
|
1685
|
+
return gatewayAccessToken;
|
|
1686
|
+
}
|
|
1645
1687
|
const gatewayRefreshToken = context.auth.refreshToken();
|
|
1646
1688
|
if (!gatewayRefreshToken ||
|
|
1647
1689
|
isExpired(context.auth.refreshTokenExpiresAt())) {
|
|
1648
|
-
throw new
|
|
1690
|
+
throw new GatewaySessionDeadError();
|
|
1649
1691
|
}
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
if (!gatewayAccessToken) {
|
|
1653
|
-
throw new Error('GATEWAY_SESSION_DEAD');
|
|
1692
|
+
try {
|
|
1693
|
+
await refreshAccessToken({ ...context, scope: 'gateway', applicationCode: undefined }, gatewayRefreshToken);
|
|
1654
1694
|
}
|
|
1655
|
-
|
|
1695
|
+
catch {
|
|
1696
|
+
throw new GatewaySessionDeadError();
|
|
1697
|
+
}
|
|
1698
|
+
const refreshedGatewayAccessToken = context.auth.token();
|
|
1699
|
+
if (!refreshedGatewayAccessToken) {
|
|
1700
|
+
throw new GatewaySessionDeadError();
|
|
1701
|
+
}
|
|
1702
|
+
return refreshedGatewayAccessToken;
|
|
1703
|
+
};
|
|
1656
1704
|
const url = buildGatewayUrl(context.gatewayApiBaseUrl, GATEWAY_AUTH_ENDPOINTS.applicationLaunch(code));
|
|
1657
1705
|
const params = {};
|
|
1658
1706
|
const returnUrl = resolveRelaunchReturnUrl(options, code);
|
|
@@ -1662,7 +1710,7 @@ const executeRelaunch = (context, options) => {
|
|
|
1662
1710
|
if (context.deviceToken) {
|
|
1663
1711
|
params['deviceToken'] = context.deviceToken;
|
|
1664
1712
|
}
|
|
1665
|
-
|
|
1713
|
+
const requestLaunch = (gatewayAccessToken) => firstValueFrom(context.http
|
|
1666
1714
|
.get(url, {
|
|
1667
1715
|
params,
|
|
1668
1716
|
headers: {
|
|
@@ -1686,6 +1734,25 @@ const executeRelaunch = (context, options) => {
|
|
|
1686
1734
|
context.auth.setAppSession(session);
|
|
1687
1735
|
return data.tokens;
|
|
1688
1736
|
})));
|
|
1737
|
+
const gatewayAccessToken = await ensureGatewayAccessToken();
|
|
1738
|
+
try {
|
|
1739
|
+
return await requestLaunch(gatewayAccessToken);
|
|
1740
|
+
}
|
|
1741
|
+
catch (error) {
|
|
1742
|
+
if (!isUnauthorizedError(error)) {
|
|
1743
|
+
throw error;
|
|
1744
|
+
}
|
|
1745
|
+
const refreshedGatewayAccessToken = await ensureGatewayAccessToken(true);
|
|
1746
|
+
try {
|
|
1747
|
+
return await requestLaunch(refreshedGatewayAccessToken);
|
|
1748
|
+
}
|
|
1749
|
+
catch (retryError) {
|
|
1750
|
+
if (isUnauthorizedError(retryError)) {
|
|
1751
|
+
throw new GatewaySessionDeadError();
|
|
1752
|
+
}
|
|
1753
|
+
throw retryError;
|
|
1754
|
+
}
|
|
1755
|
+
}
|
|
1689
1756
|
});
|
|
1690
1757
|
};
|
|
1691
1758
|
const relaunchApplication = (context, options) => {
|
|
@@ -1728,13 +1795,46 @@ const prepareRequest = (req, token, markRetried, baseUrl) => {
|
|
|
1728
1795
|
return modifiedReq;
|
|
1729
1796
|
};
|
|
1730
1797
|
const urlMatchesBase = (url, baseUrl) => {
|
|
1731
|
-
if (!baseUrl
|
|
1798
|
+
if (!baseUrl) {
|
|
1732
1799
|
return false;
|
|
1733
1800
|
}
|
|
1734
|
-
|
|
1801
|
+
const normalizedBase = normalizeBase(baseUrl);
|
|
1802
|
+
if (isAbsoluteUrl(url) && isAbsoluteUrl(normalizedBase)) {
|
|
1803
|
+
return url.startsWith(normalizedBase);
|
|
1804
|
+
}
|
|
1805
|
+
const basePath = getBasePath(baseUrl).replace(/^\/+/, '').replace(/\/+$/, '');
|
|
1806
|
+
if (!basePath) {
|
|
1807
|
+
return !isAbsoluteUrl(url) && url.startsWith(normalizedBase);
|
|
1808
|
+
}
|
|
1809
|
+
let path = url;
|
|
1810
|
+
if (isAbsoluteUrl(url)) {
|
|
1811
|
+
try {
|
|
1812
|
+
path = new URL(url).pathname;
|
|
1813
|
+
}
|
|
1814
|
+
catch {
|
|
1815
|
+
path = url;
|
|
1816
|
+
}
|
|
1817
|
+
}
|
|
1818
|
+
path = path.split('?')[0].replace(/^\/+/, '');
|
|
1819
|
+
return path === basePath || path.startsWith(`${basePath}/`);
|
|
1735
1820
|
};
|
|
1736
|
-
const resolveRequestScope = (req, options, auth, gatewayApiBaseUrl) => {
|
|
1737
|
-
// 1.
|
|
1821
|
+
const resolveRequestScope = (req, options, auth, gatewayApiBaseUrl, applicationApiBaseUrl) => {
|
|
1822
|
+
// 1. Public app context is deliberately unauthenticated app scope.
|
|
1823
|
+
if (isApplicationContextRequestUrl(req.url, applicationApiBaseUrl)) {
|
|
1824
|
+
return { scope: 'application', useGatewayBaseUrl: false };
|
|
1825
|
+
}
|
|
1826
|
+
// 2. Known Gateway endpoints must always use GatewaySession.
|
|
1827
|
+
if (isGatewayEndpointRequestUrl(req.url, gatewayApiBaseUrl)) {
|
|
1828
|
+
return {
|
|
1829
|
+
scope: 'gateway',
|
|
1830
|
+
useGatewayBaseUrl: !urlMatchesBase(req.url, gatewayApiBaseUrl),
|
|
1831
|
+
};
|
|
1832
|
+
}
|
|
1833
|
+
// 3. Caller hint via request context.
|
|
1834
|
+
if (options.shouldUseGatewayApiBaseUrl?.(req)) {
|
|
1835
|
+
return { scope: 'gateway', useGatewayBaseUrl: true };
|
|
1836
|
+
}
|
|
1837
|
+
// 4. Per-request app override.
|
|
1738
1838
|
const explicitCode = options.resolveApplicationCodeForRequest?.(req);
|
|
1739
1839
|
if (explicitCode) {
|
|
1740
1840
|
const session = auth.getAppSession(explicitCode);
|
|
@@ -1745,30 +1845,34 @@ const resolveRequestScope = (req, options, auth, gatewayApiBaseUrl) => {
|
|
|
1745
1845
|
useGatewayBaseUrl: false,
|
|
1746
1846
|
};
|
|
1747
1847
|
}
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
|
|
1848
|
+
const defaultCode = resolveApplicationCodeOption(options.applicationCode) ??
|
|
1849
|
+
auth.activeApplicationCode();
|
|
1850
|
+
// 5. Requests targeting the configured app API use ApplicationAccess.
|
|
1851
|
+
if (urlMatchesBase(req.url, applicationApiBaseUrl) && defaultCode) {
|
|
1852
|
+
return {
|
|
1853
|
+
scope: 'application',
|
|
1854
|
+
applicationCode: defaultCode,
|
|
1855
|
+
session: auth.getAppSession(defaultCode),
|
|
1856
|
+
useGatewayBaseUrl: false,
|
|
1857
|
+
};
|
|
1751
1858
|
}
|
|
1752
|
-
//
|
|
1753
|
-
// Covers /api/auth/*, /api/auth/me/applications, /api/applications/{code}/launch.
|
|
1859
|
+
// 6. Absolute URL pointing at the Gateway base must use GatewaySession.
|
|
1754
1860
|
if (urlMatchesBase(req.url, gatewayApiBaseUrl)) {
|
|
1755
1861
|
return { scope: 'gateway', useGatewayBaseUrl: false };
|
|
1756
1862
|
}
|
|
1757
|
-
//
|
|
1758
|
-
|
|
1759
|
-
|
|
1863
|
+
// 7. App shells with a configured/active app code should not send the
|
|
1864
|
+
// GatewaySession to direct app APIs. The interceptor will launch the app
|
|
1865
|
+
// if the ApplicationAccess pair is not available yet.
|
|
1760
1866
|
if (defaultCode) {
|
|
1761
1867
|
const session = auth.getAppSession(defaultCode);
|
|
1762
|
-
|
|
1763
|
-
|
|
1764
|
-
|
|
1765
|
-
|
|
1766
|
-
|
|
1767
|
-
|
|
1768
|
-
};
|
|
1769
|
-
}
|
|
1868
|
+
return {
|
|
1869
|
+
scope: 'application',
|
|
1870
|
+
applicationCode: defaultCode,
|
|
1871
|
+
session,
|
|
1872
|
+
useGatewayBaseUrl: false,
|
|
1873
|
+
};
|
|
1770
1874
|
}
|
|
1771
|
-
//
|
|
1875
|
+
// 8. No app context known yet - fall back to GatewaySession.
|
|
1772
1876
|
return { scope: 'gateway', useGatewayBaseUrl: false };
|
|
1773
1877
|
};
|
|
1774
1878
|
const gatewayAuthInterceptor = (req, next) => {
|
|
@@ -1784,21 +1888,18 @@ const gatewayAuthInterceptor = (req, next) => {
|
|
|
1784
1888
|
const refreshSkewMs = resolveAccessTokenRefreshSkewMs(options.accessTokenRefreshSkewMs);
|
|
1785
1889
|
const isAuthRequest = isGatewayAuthRequestUrl(req.url, gatewayApiBaseUrl);
|
|
1786
1890
|
const alreadyRetried = req.context.get(GATEWAY_AUTH_RETRY_CONTEXT);
|
|
1787
|
-
const resolved = resolveRequestScope(req, options, auth, gatewayApiBaseUrl);
|
|
1891
|
+
const resolved = resolveRequestScope(req, options, auth, gatewayApiBaseUrl, appApiBaseUrl);
|
|
1788
1892
|
const baseUrl = resolved.useGatewayBaseUrl
|
|
1789
1893
|
? gatewayApiBaseUrl
|
|
1790
1894
|
: appApiBaseUrl;
|
|
1791
1895
|
const gatewayAccessToken = auth.token();
|
|
1792
1896
|
const session = resolved.session ?? null;
|
|
1793
|
-
const accessToken = resolved.scope === 'application'
|
|
1794
|
-
? session
|
|
1897
|
+
const accessToken = resolved.scope === 'application'
|
|
1898
|
+
? (session?.accessToken ?? null)
|
|
1795
1899
|
: gatewayAccessToken;
|
|
1796
|
-
|
|
1797
|
-
|
|
1798
|
-
|
|
1799
|
-
// retries. This avoids the post-login refresh cascade caused by short
|
|
1800
|
-
// access-token TTLs versus any skew.
|
|
1801
|
-
const tokenToAttach = !isAuthRequest && accessToken ? accessToken : null;
|
|
1900
|
+
const isApplicationContextRequest = isApplicationContextRequestUrl(req.url, appApiBaseUrl);
|
|
1901
|
+
const shouldAttachAuth = !isAuthRequest && !isApplicationContextRequest;
|
|
1902
|
+
const tokenToAttach = shouldAttachAuth && accessToken ? accessToken : null;
|
|
1802
1903
|
const buildRefreshContext = (scopeOverride, appCodeOverride) => ({
|
|
1803
1904
|
http,
|
|
1804
1905
|
gatewayApiBaseUrl,
|
|
@@ -1808,18 +1909,74 @@ const gatewayAuthInterceptor = (req, next) => {
|
|
|
1808
1909
|
scope: scopeOverride ?? resolved.scope,
|
|
1809
1910
|
applicationCode: appCodeOverride ?? resolved.applicationCode,
|
|
1810
1911
|
});
|
|
1811
|
-
const
|
|
1812
|
-
|
|
1813
|
-
|
|
1912
|
+
const handleRelaunchError = (relaunchError) => {
|
|
1913
|
+
if (isGatewaySessionDeadError(relaunchError)) {
|
|
1914
|
+
auth.logout();
|
|
1915
|
+
}
|
|
1916
|
+
else if (resolved.applicationCode) {
|
|
1917
|
+
auth.clearAppSession(resolved.applicationCode);
|
|
1918
|
+
}
|
|
1919
|
+
return throwError(() => relaunchError);
|
|
1920
|
+
};
|
|
1921
|
+
const relaunch$ = (clearAppSessionBeforeLaunch = true) => {
|
|
1922
|
+
if (clearAppSessionBeforeLaunch && resolved.applicationCode) {
|
|
1923
|
+
auth.clearAppSession(resolved.applicationCode);
|
|
1924
|
+
}
|
|
1925
|
+
return from(relaunchApplication(buildRefreshContext('application', resolved.applicationCode), options)).pipe(catchError$1(handleRelaunchError));
|
|
1926
|
+
};
|
|
1927
|
+
const resolveGatewayTokenBeforeRequest$ = () => {
|
|
1928
|
+
const currentAccessToken = auth.token();
|
|
1929
|
+
const currentAccessTokenExpiresAt = auth.accessTokenExpiresAt();
|
|
1930
|
+
if (currentAccessToken &&
|
|
1931
|
+
!isExpired(currentAccessTokenExpiresAt, refreshSkewMs)) {
|
|
1932
|
+
return of(currentAccessToken);
|
|
1933
|
+
}
|
|
1934
|
+
const gatewayRefreshToken = auth.refreshToken();
|
|
1935
|
+
if (!currentAccessToken && !gatewayRefreshToken) {
|
|
1936
|
+
return of(null);
|
|
1937
|
+
}
|
|
1938
|
+
if (!gatewayRefreshToken || isExpired(auth.refreshTokenExpiresAt())) {
|
|
1939
|
+
auth.logout();
|
|
1940
|
+
return throwError(() => new GatewaySessionDeadError());
|
|
1941
|
+
}
|
|
1942
|
+
return refreshTokens$(buildRefreshContext('gateway', undefined), gatewayRefreshToken).pipe(map((tokens) => tokens.accessToken), catchError$1((refreshError) => {
|
|
1943
|
+
auth.logout();
|
|
1944
|
+
return throwError(() => refreshError);
|
|
1945
|
+
}));
|
|
1946
|
+
};
|
|
1947
|
+
const resolveAppTokenBeforeRequest$ = () => {
|
|
1948
|
+
const code = resolved.applicationCode;
|
|
1949
|
+
if (!code) {
|
|
1950
|
+
return of(tokenToAttach);
|
|
1951
|
+
}
|
|
1952
|
+
const latestSession = auth.getAppSession(code);
|
|
1953
|
+
if (latestSession?.accessToken &&
|
|
1954
|
+
!isExpired(latestSession.accessTokenExpiresAt, refreshSkewMs)) {
|
|
1955
|
+
return of(latestSession.accessToken);
|
|
1956
|
+
}
|
|
1957
|
+
if (!latestSession?.refreshToken ||
|
|
1958
|
+
isExpired(latestSession.refreshTokenExpiresAt)) {
|
|
1959
|
+
return relaunch$().pipe(map((tokens) => tokens.accessToken));
|
|
1960
|
+
}
|
|
1961
|
+
return refreshTokens$(buildRefreshContext('application', code), latestSession.refreshToken).pipe(map((tokens) => tokens.accessToken), catchError$1(() => relaunch$().pipe(map((tokens) => tokens.accessToken))));
|
|
1962
|
+
};
|
|
1963
|
+
const initialToken$ = !shouldAttachAuth
|
|
1964
|
+
? of(null)
|
|
1965
|
+
: resolved.scope === 'application'
|
|
1966
|
+
? resolveAppTokenBeforeRequest$()
|
|
1967
|
+
: resolveGatewayTokenBeforeRequest$();
|
|
1968
|
+
return initialToken$.pipe(switchMap$1((requestAccessToken) => next(prepareRequest(req, requestAccessToken, false, baseUrl)).pipe(catchError$1((error) => {
|
|
1969
|
+
if (error?.status !== 401 || !shouldAttachAuth || alreadyRetried) {
|
|
1814
1970
|
return throwError(() => error);
|
|
1815
1971
|
}
|
|
1816
1972
|
// If a concurrent flow already rotated the token while this request was
|
|
1817
|
-
// in flight, just retry with the freshest token
|
|
1973
|
+
// in flight, just retry with the freshest token - do NOT trigger another
|
|
1818
1974
|
// refresh against the backend.
|
|
1819
1975
|
const currentAccessToken = resolved.scope === 'application' && resolved.applicationCode
|
|
1820
|
-
? (auth.getAppSession(resolved.applicationCode)?.accessToken ??
|
|
1976
|
+
? (auth.getAppSession(resolved.applicationCode)?.accessToken ??
|
|
1977
|
+
null)
|
|
1821
1978
|
: auth.token();
|
|
1822
|
-
if (currentAccessToken && currentAccessToken !==
|
|
1979
|
+
if (currentAccessToken && currentAccessToken !== requestAccessToken) {
|
|
1823
1980
|
return next(prepareRequest(req, currentAccessToken, true, baseUrl));
|
|
1824
1981
|
}
|
|
1825
1982
|
const isApp = resolved.scope === 'application' && !!resolved.applicationCode;
|
|
@@ -1833,21 +1990,6 @@ const gatewayAuthInterceptor = (req, next) => {
|
|
|
1833
1990
|
? (latestAppSession?.refreshTokenExpiresAt ?? null)
|
|
1834
1991
|
: auth.refreshTokenExpiresAt();
|
|
1835
1992
|
const canRefreshNow = !!latestRefreshToken && !isExpired(latestRefreshTokenExpiresAt);
|
|
1836
|
-
// App-scope recovery: prefer app-refresh, fall back to silent re-launch
|
|
1837
|
-
// (so direct Pplus calls keep working when only the app's refresh
|
|
1838
|
-
// token expired but the Gateway session is still alive).
|
|
1839
|
-
const relaunch$ = () => from(relaunchApplication(buildRefreshContext(), options)).pipe(catchError$1((relaunchError) => {
|
|
1840
|
-
const gatewayDead = !auth.token() &&
|
|
1841
|
-
(!auth.refreshToken() ||
|
|
1842
|
-
isExpired(auth.refreshTokenExpiresAt()));
|
|
1843
|
-
if (gatewayDead) {
|
|
1844
|
-
auth.logout();
|
|
1845
|
-
}
|
|
1846
|
-
else if (resolved.applicationCode) {
|
|
1847
|
-
auth.clearAppSession(resolved.applicationCode);
|
|
1848
|
-
}
|
|
1849
|
-
return throwError(() => relaunchError);
|
|
1850
|
-
}));
|
|
1851
1993
|
const tokens$ = !canRefreshNow || !latestRefreshToken
|
|
1852
1994
|
? isApp
|
|
1853
1995
|
? relaunch$()
|
|
@@ -1860,7 +2002,7 @@ const gatewayAuthInterceptor = (req, next) => {
|
|
|
1860
2002
|
return throwError(() => refreshError);
|
|
1861
2003
|
}));
|
|
1862
2004
|
return tokens$.pipe(switchMap$1((tokens) => next(prepareRequest(req, tokens.accessToken, true, baseUrl))));
|
|
1863
|
-
}));
|
|
2005
|
+
}))));
|
|
1864
2006
|
};
|
|
1865
2007
|
|
|
1866
2008
|
const CORRELATION_ID_HEADER = 'X-Correlation-ID';
|