@krainovsd/js-helpers 0.17.0 → 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 +46 -60
- 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 -34
- package/lib/esm/api/before/oauth-before-handler.js.map +1 -1
- package/lib/esm/api/oauth.js +31 -27
- package/lib/esm/api/oauth.js.map +1 -1
- package/lib/esm/index.js +3 -3
- package/lib/index.d.ts +24 -30
- 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,19 +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
1841
|
OAUTH_STATE.fetching = false;
|
|
1835
1842
|
return await refetch();
|
|
1836
1843
|
}
|
|
1837
|
-
|
|
1838
|
-
|
|
1839
|
-
|
|
1840
|
-
|
|
1841
|
-
|
|
1842
|
-
|
|
1843
|
-
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];
|
|
1844
1854
|
/** Is OnlyRefresh window */
|
|
1845
1855
|
const isRefresh = isString(refreshQuery)
|
|
1846
1856
|
? refreshQuery === "true"
|
|
@@ -1853,21 +1863,18 @@ async function getOauthToken(options) {
|
|
|
1853
1863
|
: isArray(expiresQuery)
|
|
1854
1864
|
? expiresQuery[expiresQuery.length - 1]
|
|
1855
1865
|
: false;
|
|
1856
|
-
|
|
1857
|
-
|
|
1858
|
-
|
|
1859
|
-
|
|
1860
|
-
|
|
1861
|
-
|
|
1862
|
-
|
|
1863
|
-
const token = await options.tokenRequest();
|
|
1864
|
-
if (token != undefined && options.tokenStorageName) {
|
|
1865
|
-
localStorage.setItem(options.tokenStorageName, token);
|
|
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
|
+
}
|
|
1866
1873
|
}
|
|
1867
1874
|
}
|
|
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 @@ async 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,39 +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.tokenStorageName) {
|
|
2320
|
-
token = localStorage.getItem(options.tokenStorageName);
|
|
2321
|
-
}
|
|
2322
|
-
OAUTH_STATE.fetching = false;
|
|
2323
|
-
}
|
|
2324
|
-
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)
|
|
2325
2307
|
request.headers = {
|
|
2326
2308
|
...request.headers,
|
|
2327
2309
|
Authorization: `Bearer ${token}`,
|
|
@@ -2337,12 +2319,16 @@ exports.IS_DENO = IS_DENO;
|
|
|
2337
2319
|
exports.IS_JEST = IS_JEST;
|
|
2338
2320
|
exports.IS_NODE = IS_NODE;
|
|
2339
2321
|
exports.IS_WEB_WORKER = IS_WEB_WORKER;
|
|
2322
|
+
exports.OAUTH_REFRESH_QUERY = OAUTH_REFRESH_QUERY;
|
|
2340
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;
|
|
2341
2326
|
exports.REQUEST_ERROR = REQUEST_ERROR;
|
|
2342
2327
|
exports.RESPONSE_DATA_SYMBOL = RESPONSE_DATA_SYMBOL;
|
|
2343
2328
|
exports.ResponseError = ResponseError;
|
|
2344
2329
|
exports.arrayToMapByKey = arrayToMapByKey;
|
|
2345
2330
|
exports.asyncLoop = asyncLoop;
|
|
2331
|
+
exports.authBeforeHandler = authBeforeHandler;
|
|
2346
2332
|
exports.buildQueryString = buildQueryString;
|
|
2347
2333
|
exports.checkType = checkType;
|
|
2348
2334
|
exports.cloneDeep = cloneDeep;
|
|
@@ -2361,6 +2347,7 @@ exports.differenceWith = differenceWith;
|
|
|
2361
2347
|
exports.downloadFile = downloadFile;
|
|
2362
2348
|
exports.downloadJson = downloadJson;
|
|
2363
2349
|
exports.execAnimation = execAnimation;
|
|
2350
|
+
exports.extractOauthOptions = extractOauthOptions;
|
|
2364
2351
|
exports.extractQueries = extractQueries;
|
|
2365
2352
|
exports.fieldViewFormat = fieldViewFormat;
|
|
2366
2353
|
exports.getByPath = getByPath;
|
|
@@ -2392,7 +2379,6 @@ exports.jsonParse = jsonParse;
|
|
|
2392
2379
|
exports.limitStreamOfRequests = limitStreamOfRequests;
|
|
2393
2380
|
exports.loggerAfterHandler = loggerAfterHandler;
|
|
2394
2381
|
exports.loggerBeforeHandler = loggerBeforeHandler;
|
|
2395
|
-
exports.oauthBeforeHandler = oauthBeforeHandler;
|
|
2396
2382
|
exports.randomBase64 = randomBase64;
|
|
2397
2383
|
exports.randomHex = randomHex;
|
|
2398
2384
|
exports.randomNumber = randomNumber;
|