UNPKG

@okta/okta-auth-js

Version:
231 lines (227 loc) 9.13 kB
/*! * Copyright (c) 2015-present, Okta, Inc. and/or its affiliates. All rights reserved. * The Okta software accompanied by this notice is provided pursuant to the Apache License, Version 2.0 (the "License.") * * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0. * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and limitations under the License. */ import { removeNils, clone } from '../util/object.js'; import { isString } from '../util/types.js'; import { isAbsoluteUrl } from '../util/url.js'; import { STATE_TOKEN_KEY_NAME, DEFAULT_CACHE_DURATION, IOS_MAX_RETRY_COUNT } from '../constants.js'; import AuthApiError from '../errors/AuthApiError.js'; import OAuthError from '../errors/OAuthError.js'; import WWWAuthError from '../errors/WWWAuthError.js'; import { isBrowser } from '../features.js'; let dateDocumentBecameVisible = 0; let trackDateDocumentBecameVisible; if (isBrowser()) { dateDocumentBecameVisible = Date.now(); trackDateDocumentBecameVisible = () => { if (!document.hidden) { dateDocumentBecameVisible = Date.now(); } }; document.addEventListener('visibilitychange', trackDateDocumentBecameVisible); } const formatError = (sdk, error) => { var _a; if (error instanceof Error) { return new AuthApiError({ errorSummary: error.message, }); } let resp = error; let err; let serverErr = {}; if (resp.responseText && isString(resp.responseText)) { try { serverErr = JSON.parse(resp.responseText); } catch (e) { serverErr = { errorSummary: 'Unknown error' }; } } if (resp.status >= 500) { serverErr.errorSummary = 'Unknown error'; } if (sdk.options.transformErrorXHR) { resp = sdk.options.transformErrorXHR(clone(resp)); } const wwwAuthHeader = (_a = WWWAuthError.getWWWAuthenticateHeader(resp === null || resp === void 0 ? void 0 : resp.headers)) !== null && _a !== void 0 ? _a : ''; if (serverErr.error && serverErr.error_description) { err = new OAuthError(serverErr.error, serverErr.error_description, resp); } else { err = new AuthApiError(serverErr, resp, { wwwAuthHeader }); } if (wwwAuthHeader && (resp === null || resp === void 0 ? void 0 : resp.status) >= 400 && (resp === null || resp === void 0 ? void 0 : resp.status) < 500) { const wwwAuthErr = WWWAuthError.parseHeader(wwwAuthHeader); if (resp.status === 403 && (wwwAuthErr === null || wwwAuthErr === void 0 ? void 0 : wwwAuthErr.error) === 'insufficient_authentication_context') { const { max_age, acr_values } = wwwAuthErr.parameters; err = new AuthApiError({ errorSummary: wwwAuthErr.error, errorCauses: [{ errorSummary: wwwAuthErr.errorDescription }] }, resp, Object.assign({ max_age: +max_age }, (acr_values && { acr_values }))); } else if ((wwwAuthErr === null || wwwAuthErr === void 0 ? void 0 : wwwAuthErr.scheme) === 'DPoP') { err = wwwAuthErr; } } return err; }; function httpRequest(sdk, options) { var _a; options = options || {}; if (sdk.options.httpRequestInterceptors) { for (const interceptor of sdk.options.httpRequestInterceptors) { interceptor(options); } } var url = options.url, method = options.method, args = options.args, saveAuthnState = options.saveAuthnState, accessToken = options.accessToken, withCredentials = options.withCredentials === true, storageUtil = sdk.options.storageUtil, storage = storageUtil.storage, httpCache = sdk.storageManager.getHttpCache(sdk.options.cookies), pollingIntent = options.pollingIntent, pollDelay = (_a = sdk.options.pollDelay) !== null && _a !== void 0 ? _a : 0; if (options.cacheResponse) { var cacheContents = httpCache.getStorage(); var cachedResponse = cacheContents[url]; if (cachedResponse && Date.now() / 1000 < cachedResponse.expiresAt) { return Promise.resolve(cachedResponse.response); } } var oktaUserAgentHeader = sdk._oktaUserAgent.getHttpHeader(); var headers = Object.assign({ 'Accept': 'application/json', 'Content-Type': 'application/json' }, oktaUserAgentHeader); Object.assign(headers, sdk.options.headers, options.headers); headers = removeNils(headers); if (accessToken && isString(accessToken)) { headers['Authorization'] = 'Bearer ' + accessToken; } var ajaxOptions = { headers, data: args || undefined, withCredentials }; var err, res, promise; if (pollingIntent && isBrowser() && pollDelay > 0) { let waitForVisibleAndAwakenDocument; let waitForAwakenDocument; let recursiveFetch; let retryCount = 0; waitForAwakenDocument = () => { const timeSinceDocumentIsVisible = Date.now() - dateDocumentBecameVisible; if (timeSinceDocumentIsVisible < pollDelay) { return new Promise((resolve) => setTimeout(() => { if (!document.hidden) { resolve(); } else { resolve(waitForVisibleAndAwakenDocument()); } }, pollDelay - timeSinceDocumentIsVisible)); } else { return Promise.resolve(); } }; waitForVisibleAndAwakenDocument = () => { if (document.hidden) { let pageVisibilityHandler; return new Promise((resolve) => { pageVisibilityHandler = () => { if (!document.hidden) { document.removeEventListener('visibilitychange', pageVisibilityHandler); resolve(waitForAwakenDocument()); } }; document.addEventListener('visibilitychange', pageVisibilityHandler); }); } else { return waitForAwakenDocument(); } }; const retryableFetch = () => { return sdk.options.httpRequestClient(method, url, ajaxOptions).catch((err) => { const isNetworkError = (err === null || err === void 0 ? void 0 : err.message) === 'Load failed'; if (isNetworkError && retryCount < IOS_MAX_RETRY_COUNT) { retryCount++; return recursiveFetch(); } throw err; }); }; recursiveFetch = () => { return waitForVisibleAndAwakenDocument().then(retryableFetch); }; promise = recursiveFetch(); } else { promise = sdk.options.httpRequestClient(method, url, ajaxOptions); } return promise .then(function (resp) { res = resp.responseText; if (res && isString(res)) { res = JSON.parse(res); if (res && typeof res === 'object' && !res.headers) { if (Array.isArray(res)) { res.forEach(item => { item.headers = resp.headers; }); } else { res.headers = resp.headers; } } } if (saveAuthnState) { if (!res.stateToken) { storage.delete(STATE_TOKEN_KEY_NAME); } } if (res && res.stateToken && res.expiresAt) { storage.set(STATE_TOKEN_KEY_NAME, res.stateToken, res.expiresAt, sdk.options.cookies); } if (res && options.cacheResponse) { httpCache.updateStorage(url, { expiresAt: Math.floor(Date.now() / 1000) + DEFAULT_CACHE_DURATION, response: res }); } return res; }) .catch(function (resp) { err = formatError(sdk, resp); if (err.errorCode === 'E0000011') { storage.delete(STATE_TOKEN_KEY_NAME); } throw err; }); } function get(sdk, url, options) { url = isAbsoluteUrl(url) ? url : sdk.getIssuerOrigin() + url; var getOptions = { url: url, method: 'GET' }; Object.assign(getOptions, options); return httpRequest(sdk, getOptions); } function post(sdk, url, args, options) { url = isAbsoluteUrl(url) ? url : sdk.getIssuerOrigin() + url; var postOptions = { url: url, method: 'POST', args: args, saveAuthnState: true }; Object.assign(postOptions, options); return httpRequest(sdk, postOptions); } export { get, httpRequest, post }; //# sourceMappingURL=request.js.map