UNPKG

@livechat/customer-auth

Version:

Authorization library for connecting to LiveChat as a customer.

200 lines (191 loc) 6.26 kB
import storage from '@livechat/isomorphic-storage'; import { getOrigin } from '@livechat/url-utils'; function unfetch (e, n) { return n = n || {}, new Promise(function (t, r) { var s = new XMLHttpRequest(), o = [], u = [], i = {}, a = function () { return { ok: 2 == (s.status / 100 | 0), statusText: s.statusText, status: s.status, url: s.responseURL, text: function () { return Promise.resolve(s.responseText); }, json: function () { return Promise.resolve(s.responseText).then(JSON.parse); }, blob: function () { return Promise.resolve(new Blob([s.response])); }, clone: a, headers: { keys: function () { return o; }, entries: function () { return u; }, get: function (e) { return i[e.toLowerCase()]; }, has: function (e) { return e.toLowerCase() in i; } } }; }; for (var l in s.open(n.method || "get", e, !0), s.onload = function () { s.getAllResponseHeaders().replace(/^(.*?):[^\S\n]*([\s\S]*?)$/gm, function (e, n, t) { o.push(n = n.toLowerCase()), u.push([n, t]), i[n] = i[n] ? i[n] + "," + t : t; }), t(a()); }, s.onerror = r, s.withCredentials = "include" == n.credentials, n.headers) s.setRequestHeader(l, n.headers[l]); s.send(n.body || null); }); } var ACCOUNTS_URL = "https://accounts.livechatinc.com"; var buildPath = function buildPath(_ref) { var uniqueGroups = _ref.uniqueGroups, organizationId = _ref.organizationId, groupId = _ref.groupId; return "" + (uniqueGroups ? "/v2/customer/" + organizationId + "/" + groupId + "/token" : '/v2/customer/token'); }; var buildRequestUrl = function buildRequestUrl(config, env) { var url = env === 'production' ? ACCOUNTS_URL : ACCOUNTS_URL.replace('accounts.', "accounts." + env + "."); var path = buildPath(config); return "" + url + path; }; var createError = function createError(_ref) { var code = _ref.code, message = _ref.message; var err = new Error(message); err.code = code; return err; }; var parseTokenResponse = function parseTokenResponse(token, organizationId) { if ('identity_exception' in token) { throw createError({ code: 'SSO_IDENTITY_EXCEPTION', message: token.identity_exception }); } if ('oauth_exception' in token) { throw createError({ code: 'SSO_OAUTH_EXCEPTION', message: token.oauth_exception }); } return { accessToken: token.access_token, entityId: token.entity_id, expiresIn: token.expires_in * 1000, tokenType: token.token_type, creationDate: Date.now(), organizationId: organizationId }; }; var fetchToken = function fetchToken(config, env) { return unfetch("" + buildRequestUrl(config, env), { method: 'POST', credentials: 'include', body: JSON.stringify({ response_type: 'token', grant_type: 'cookie', client_id: config.clientId, organization_id: config.organizationId, redirect_uri: getOrigin(String(window.location)) + window.location.pathname }) }).then(function (res) { return res.json(); }).then(function (token) { return parseTokenResponse(token, config.organizationId); }); }; var validateConfig = function validateConfig(_ref) { var organizationId = _ref.organizationId, clientId = _ref.clientId; if (typeof organizationId !== 'string' || typeof clientId !== 'string') { throw new Error('You need to pass valid configuration object: { organizationId, clientId }.'); } }; var isExpiredToken = function isExpiredToken(_ref) { var creationDate = _ref.creationDate, expiresIn = _ref.expiresIn; return Date.now() >= creationDate + expiresIn; }; var createAuth = function createAuth(config, licenseId, env) { validateConfig(config); var tokenStoragePrefix = config.tokenStoragePrefix || "@@lc_auth_token:"; var oldCacheKey = "" + tokenStoragePrefix + licenseId + (config.uniqueGroups ? ":" + config.groupId : ''); var newCacheKey = "" + tokenStoragePrefix + config.organizationId + (config.uniqueGroups ? ":" + config.groupId : ''); var pendingTokenRequest = null; var cachedToken = null; var retrievingToken = storage.getItem(oldCacheKey).then(function (token) { if (retrievingToken === null) { return; } retrievingToken = null; if (!token) { storage.removeItem(oldCacheKey).then(function () { return storage.getItem(newCacheKey).then(function (newKeyToken) { if (!newKeyToken) { return; } cachedToken = JSON.parse(newKeyToken); }); }); return; } storage.setItem(newCacheKey, token).then(function () { storage.removeItem(oldCacheKey).then(function () { cachedToken = JSON.parse(token); }); }); }); var getFreshToken = function getFreshToken() { pendingTokenRequest = fetchToken(config, env).then(function (token) { pendingTokenRequest = null; storage.setItem(newCacheKey, JSON.stringify(token)); cachedToken = token; return token; }, function (err) { pendingTokenRequest = null; throw err; }); return pendingTokenRequest; }; var getToken = function getToken() { if (pendingTokenRequest) { return pendingTokenRequest; } if (cachedToken && !isExpiredToken(cachedToken)) { return Promise.resolve(cachedToken); } if (retrievingToken) { return retrievingToken.then(getToken); } return getFreshToken(); }; var hasToken = function hasToken() { if (retrievingToken) { return retrievingToken.then(hasToken); } return Promise.resolve(!!cachedToken); }; var invalidate = function invalidate() { cachedToken = null; retrievingToken = null; return storage.removeItem(newCacheKey); }; return { getFreshToken: getFreshToken, getToken: getToken, hasToken: hasToken, invalidate: invalidate }; }; export default createAuth; export { isExpiredToken, validateConfig };