@krainovsd/js-helpers 0.16.12 → 0.18.0
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.
- package/lib/cjs/index.cjs +47 -64
- package/lib/cjs/index.cjs.map +1 -1
- package/lib/esm/api/api.constants.js +4 -1
- package/lib/esm/api/api.constants.js.map +1 -1
- package/lib/esm/api/api.js +4 -3
- package/lib/esm/api/api.js.map +1 -1
- package/lib/esm/api/before/oauth-before-handler.js +7 -37
- package/lib/esm/api/before/oauth-before-handler.js.map +1 -1
- package/lib/esm/api/oauth.js +32 -28
- package/lib/esm/api/oauth.js.map +1 -1
- package/lib/esm/index.js +3 -3
- package/lib/index.d.ts +28 -32
- package/package.json +2 -2
package/lib/cjs/index.cjs
CHANGED
|
@@ -1775,17 +1775,22 @@ class OauthState {
|
|
|
1775
1775
|
}
|
|
1776
1776
|
}
|
|
1777
1777
|
const OAUTH_STATE = new OauthState();
|
|
1778
|
+
const OAUTH_TOKEN_STORAGE_NAME = "session_token";
|
|
1779
|
+
const OAUTH_TOKEN_EXPIRES_STORAGE_NAME = "session_token_expires";
|
|
1780
|
+
const OAUTH_REFRESH_QUERY = "only_session_refresh";
|
|
1778
1781
|
|
|
1779
1782
|
async function getOauthTokenFromOtherWindow(options) {
|
|
1780
1783
|
let waiting = true;
|
|
1781
1784
|
const url = new URL(typeof options.refreshTokenWindowUrl === "function"
|
|
1782
1785
|
? options.refreshTokenWindowUrl()
|
|
1783
1786
|
: (options.refreshTokenWindowUrl ?? window.origin));
|
|
1784
|
-
|
|
1787
|
+
// added only refresh tag to autoclose window after flow
|
|
1788
|
+
url.searchParams.append(options.onlyRefreshTokenWindowQueryName ?? OAUTH_REFRESH_QUERY, "true");
|
|
1789
|
+
// try open window with both of action
|
|
1785
1790
|
let windowInstance = window.open(url.toString(), "_blank", "width=800,height=600,left=100,top=100");
|
|
1786
1791
|
windowInstance ??= window.open(url.toString(), "_blank");
|
|
1787
1792
|
if (windowInstance) {
|
|
1788
|
-
const channel = new BroadcastChannel(options.onlyRefreshTokenWindowQueryName);
|
|
1793
|
+
const channel = new BroadcastChannel(options.onlyRefreshTokenWindowQueryName ?? OAUTH_REFRESH_QUERY);
|
|
1789
1794
|
const windowCloseObserver = setInterval(() => {
|
|
1790
1795
|
if (windowInstance.closed) {
|
|
1791
1796
|
if (waiting) {
|
|
@@ -1811,11 +1816,14 @@ async function getOauthTokenFromOtherWindow(options) {
|
|
|
1811
1816
|
if (windowInstance && !windowInstance.closed) {
|
|
1812
1817
|
windowInstance.close();
|
|
1813
1818
|
}
|
|
1814
|
-
}, options.wait ??
|
|
1819
|
+
}, options.wait ?? 8000);
|
|
1815
1820
|
}
|
|
1816
1821
|
else {
|
|
1817
|
-
if (options
|
|
1818
|
-
options.onWindowOpenError();
|
|
1822
|
+
if ("onWindowOpenError" in options)
|
|
1823
|
+
options.onWindowOpenError?.();
|
|
1824
|
+
else {
|
|
1825
|
+
getOauthToken(options.oauthUrl);
|
|
1826
|
+
}
|
|
1819
1827
|
waiting = false;
|
|
1820
1828
|
return;
|
|
1821
1829
|
}
|
|
@@ -1828,25 +1836,21 @@ async function refetchAfterOauth(options, refetch) {
|
|
|
1828
1836
|
onWindowOpenError: options.onWindowOpenError,
|
|
1829
1837
|
refreshTokenWindowUrl: options.refreshTokenWindowUrl,
|
|
1830
1838
|
wait: options.wait,
|
|
1831
|
-
expiresTokenStorageName: options.expiresTokenStorageName,
|
|
1832
1839
|
closeObserveInterval: options.closeObserveInterval,
|
|
1833
1840
|
});
|
|
1834
|
-
if (options.tokenRequest) {
|
|
1835
|
-
const token = await options.tokenRequest();
|
|
1836
|
-
if (token != undefined && options.tokenStorageName) {
|
|
1837
|
-
localStorage.setItem(options.tokenStorageName, token);
|
|
1838
|
-
}
|
|
1839
|
-
}
|
|
1840
1841
|
OAUTH_STATE.fetching = false;
|
|
1841
1842
|
return await refetch();
|
|
1842
1843
|
}
|
|
1843
|
-
function getOauthToken(
|
|
1844
|
-
|
|
1845
|
-
|
|
1846
|
-
|
|
1847
|
-
|
|
1848
|
-
|
|
1849
|
-
const
|
|
1844
|
+
function getOauthToken(oauthUrl) {
|
|
1845
|
+
oauthUrl ??= `/api/v1/auth?frontend_protocol=${window.location.protocol.replace(":", "")}&frontend_host=${window.location.host}&comeback_path=${window.location.pathname}${encodeURIComponent(window.location.search)}`;
|
|
1846
|
+
window.location.replace(typeof oauthUrl === "function" ? oauthUrl() : oauthUrl);
|
|
1847
|
+
return null;
|
|
1848
|
+
}
|
|
1849
|
+
async function extractOauthOptions(options = {}) {
|
|
1850
|
+
const { expiresTokenQueryName = OAUTH_TOKEN_EXPIRES_STORAGE_NAME, onlyRefreshTokenWindowQueryName = OAUTH_REFRESH_QUERY, tokenStorageName = OAUTH_TOKEN_STORAGE_NAME, expiresTokenStorageName = OAUTH_TOKEN_EXPIRES_STORAGE_NAME, tokenRequest = undefined, } = options;
|
|
1851
|
+
const queries = getQueryValues([expiresTokenQueryName, onlyRefreshTokenWindowQueryName]);
|
|
1852
|
+
const refreshQuery = queries?.[onlyRefreshTokenWindowQueryName];
|
|
1853
|
+
const expiresQuery = queries?.[expiresTokenQueryName];
|
|
1850
1854
|
/** Is OnlyRefresh window */
|
|
1851
1855
|
const isRefresh = isString(refreshQuery)
|
|
1852
1856
|
? refreshQuery === "true"
|
|
@@ -1859,15 +1863,18 @@ function getOauthToken(options) {
|
|
|
1859
1863
|
: isArray(expiresQuery)
|
|
1860
1864
|
? expiresQuery[expiresQuery.length - 1]
|
|
1861
1865
|
: false;
|
|
1862
|
-
|
|
1863
|
-
|
|
1864
|
-
|
|
1865
|
-
|
|
1866
|
+
if (expires && !Number.isNaN(+expires) && Date.now() < +expires) {
|
|
1867
|
+
localStorage.setItem(expiresTokenStorageName, expires);
|
|
1868
|
+
if (tokenRequest) {
|
|
1869
|
+
const token = await tokenRequest();
|
|
1870
|
+
if (token != undefined && tokenStorageName) {
|
|
1871
|
+
localStorage.setItem(tokenStorageName, token);
|
|
1872
|
+
}
|
|
1873
|
+
}
|
|
1866
1874
|
}
|
|
1867
|
-
localStorage.setItem(options.expiresTokenStorageName, expires);
|
|
1868
1875
|
/** Close if OnlyRefresh window */
|
|
1869
1876
|
if (isRefresh) {
|
|
1870
|
-
const channel = new BroadcastChannel(
|
|
1877
|
+
const channel = new BroadcastChannel(onlyRefreshTokenWindowQueryName);
|
|
1871
1878
|
channel.postMessage(true);
|
|
1872
1879
|
channel.close();
|
|
1873
1880
|
window.close();
|
|
@@ -1875,7 +1882,7 @@ function getOauthToken(options) {
|
|
|
1875
1882
|
/** Delete expires query */
|
|
1876
1883
|
if (expires) {
|
|
1877
1884
|
const url = new URL(window.location.href);
|
|
1878
|
-
url.searchParams.delete(
|
|
1885
|
+
url.searchParams.delete(expiresTokenQueryName);
|
|
1879
1886
|
window.location.replace(url.toString());
|
|
1880
1887
|
return null;
|
|
1881
1888
|
}
|
|
@@ -2029,7 +2036,10 @@ function createFetchClient(options) {
|
|
|
2029
2036
|
request.onError?.(REQUEST_ERROR.CACHE_ERROR, error);
|
|
2030
2037
|
return { data: error, error: REQUEST_ERROR.CACHE_ERROR, response };
|
|
2031
2038
|
}
|
|
2032
|
-
if (response.status
|
|
2039
|
+
if ((oauthOptions?.responseStatusesForOauth?.includes(response.status) ||
|
|
2040
|
+
(!oauthOptions?.responseStatusesForOauth && response.status === 401)) &&
|
|
2041
|
+
oauthOptions &&
|
|
2042
|
+
refetchAfterOauth$1) {
|
|
2033
2043
|
return await refetchAfterOauth(oauthOptions, () => handleRequest({ ...request, refetchAfterOauth: false }));
|
|
2034
2044
|
}
|
|
2035
2045
|
if (response.status === 401 && refetchAfterAuth) {
|
|
@@ -2200,7 +2210,6 @@ function executeBeforeHandlers(handlers, request) {
|
|
|
2200
2210
|
return new Promise((resolve) => {
|
|
2201
2211
|
void (async () => {
|
|
2202
2212
|
for (const handler of handlers) {
|
|
2203
|
-
// eslint-disable-next-line no-await-in-loop
|
|
2204
2213
|
await handler(request);
|
|
2205
2214
|
}
|
|
2206
2215
|
resolve(1);
|
|
@@ -2211,7 +2220,6 @@ function executeAfterHandlers(handlers, request, response) {
|
|
|
2211
2220
|
return new Promise((resolve) => {
|
|
2212
2221
|
void (async () => {
|
|
2213
2222
|
for (const handler of handlers) {
|
|
2214
|
-
// eslint-disable-next-line no-await-in-loop
|
|
2215
2223
|
await handler(request, response);
|
|
2216
2224
|
}
|
|
2217
2225
|
resolve(1);
|
|
@@ -2289,42 +2297,13 @@ function loggerBeforeHandler(options = {}) {
|
|
|
2289
2297
|
};
|
|
2290
2298
|
}
|
|
2291
2299
|
|
|
2292
|
-
const
|
|
2293
|
-
|
|
2294
|
-
throw new Error("Auth middleware hasn't required options");
|
|
2295
|
-
}
|
|
2296
|
-
const isSameOrigin = !startWith(request.path, "http");
|
|
2297
|
-
if (request.token) {
|
|
2298
|
-
if (!isSameOrigin)
|
|
2299
|
-
request.headers = {
|
|
2300
|
-
...request.headers,
|
|
2301
|
-
Authorization: `Bearer ${request.token}`,
|
|
2302
|
-
};
|
|
2303
|
-
return;
|
|
2304
|
-
}
|
|
2300
|
+
const authBeforeHandler = (options = {}) => async (request) => {
|
|
2301
|
+
const { tokenStorageName = OAUTH_TOKEN_STORAGE_NAME, forceSetToken = false } = options;
|
|
2305
2302
|
if (OAUTH_STATE.fetching)
|
|
2306
2303
|
await waitUntil(() => OAUTH_STATE.fetching);
|
|
2307
|
-
const
|
|
2308
|
-
|
|
2309
|
-
if (!
|
|
2310
|
-
OAUTH_STATE.fetching = true;
|
|
2311
|
-
await getOauthTokenFromOtherWindow({
|
|
2312
|
-
onlyRefreshTokenWindowQueryName: options.onlyRefreshTokenWindowQueryName,
|
|
2313
|
-
onWindowOpenError: options.onWindowOpenError,
|
|
2314
|
-
refreshTokenWindowUrl: options.refreshTokenWindowUrl,
|
|
2315
|
-
wait: options.wait,
|
|
2316
|
-
expiresTokenStorageName: options.expiresTokenStorageName,
|
|
2317
|
-
closeObserveInterval: options.closeObserveInterval,
|
|
2318
|
-
});
|
|
2319
|
-
if (options.tokenRequest) {
|
|
2320
|
-
token = await options.tokenRequest();
|
|
2321
|
-
if (token != undefined && options.tokenStorageName) {
|
|
2322
|
-
localStorage.setItem(options.tokenStorageName, token);
|
|
2323
|
-
}
|
|
2324
|
-
}
|
|
2325
|
-
OAUTH_STATE.fetching = false;
|
|
2326
|
-
}
|
|
2327
|
-
if (!isSameOrigin && token)
|
|
2304
|
+
const token = request.token ?? localStorage.getItem(tokenStorageName);
|
|
2305
|
+
const isSameOrigin = request.path.includes(window.location.origin) || !startWith(request.path, "http");
|
|
2306
|
+
if ((!isSameOrigin || forceSetToken) && token)
|
|
2328
2307
|
request.headers = {
|
|
2329
2308
|
...request.headers,
|
|
2330
2309
|
Authorization: `Bearer ${token}`,
|
|
@@ -2340,12 +2319,16 @@ exports.IS_DENO = IS_DENO;
|
|
|
2340
2319
|
exports.IS_JEST = IS_JEST;
|
|
2341
2320
|
exports.IS_NODE = IS_NODE;
|
|
2342
2321
|
exports.IS_WEB_WORKER = IS_WEB_WORKER;
|
|
2322
|
+
exports.OAUTH_REFRESH_QUERY = OAUTH_REFRESH_QUERY;
|
|
2343
2323
|
exports.OAUTH_STATE = OAUTH_STATE;
|
|
2324
|
+
exports.OAUTH_TOKEN_EXPIRES_STORAGE_NAME = OAUTH_TOKEN_EXPIRES_STORAGE_NAME;
|
|
2325
|
+
exports.OAUTH_TOKEN_STORAGE_NAME = OAUTH_TOKEN_STORAGE_NAME;
|
|
2344
2326
|
exports.REQUEST_ERROR = REQUEST_ERROR;
|
|
2345
2327
|
exports.RESPONSE_DATA_SYMBOL = RESPONSE_DATA_SYMBOL;
|
|
2346
2328
|
exports.ResponseError = ResponseError;
|
|
2347
2329
|
exports.arrayToMapByKey = arrayToMapByKey;
|
|
2348
2330
|
exports.asyncLoop = asyncLoop;
|
|
2331
|
+
exports.authBeforeHandler = authBeforeHandler;
|
|
2349
2332
|
exports.buildQueryString = buildQueryString;
|
|
2350
2333
|
exports.checkType = checkType;
|
|
2351
2334
|
exports.cloneDeep = cloneDeep;
|
|
@@ -2364,6 +2347,7 @@ exports.differenceWith = differenceWith;
|
|
|
2364
2347
|
exports.downloadFile = downloadFile;
|
|
2365
2348
|
exports.downloadJson = downloadJson;
|
|
2366
2349
|
exports.execAnimation = execAnimation;
|
|
2350
|
+
exports.extractOauthOptions = extractOauthOptions;
|
|
2367
2351
|
exports.extractQueries = extractQueries;
|
|
2368
2352
|
exports.fieldViewFormat = fieldViewFormat;
|
|
2369
2353
|
exports.getByPath = getByPath;
|
|
@@ -2395,7 +2379,6 @@ exports.jsonParse = jsonParse;
|
|
|
2395
2379
|
exports.limitStreamOfRequests = limitStreamOfRequests;
|
|
2396
2380
|
exports.loggerAfterHandler = loggerAfterHandler;
|
|
2397
2381
|
exports.loggerBeforeHandler = loggerBeforeHandler;
|
|
2398
|
-
exports.oauthBeforeHandler = oauthBeforeHandler;
|
|
2399
2382
|
exports.randomBase64 = randomBase64;
|
|
2400
2383
|
exports.randomHex = randomHex;
|
|
2401
2384
|
exports.randomNumber = randomNumber;
|