@livechat/customer-auth
Version:
Authorization library for connecting to LiveChat as a customer.
200 lines (191 loc) • 6.26 kB
JavaScript
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 };