teko-oauth2
Version:
Teko Identity OAuth 2 Javascript Library for Web App Client
267 lines (229 loc) • 10.8 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = void 0;
require("regenerator-runtime/runtime");
var _utils = require("./utils");
var _clientOauth = _interopRequireDefault(require("client-oauth2"));
var _jwtDecode = _interopRequireDefault(require("jwt-decode"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }
function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; }
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
var OidcClient = /*#__PURE__*/function () {
function OidcClient() {
var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
clientId = _ref.clientId,
authorizationUri = _ref.authorizationUri,
accessTokenUri = _ref.accessTokenUri,
refreshTokenUri = _ref.refreshTokenUri,
logoutUri = _ref.logoutUri,
userInfoUri = _ref.userInfoUri,
checkSessionUri = _ref.checkSessionUri,
redirectUri = _ref.redirectUri,
postLogoutRedirectUri = _ref.postLogoutRedirectUri,
scopes = _ref.scopes;
_classCallCheck(this, OidcClient);
this._client = new _clientOauth["default"]({
clientId: clientId,
authorizationUri: authorizationUri,
accessTokenUri: accessTokenUri,
redirectUri: redirectUri,
scopes: scopes
});
this._refreshTokenUri = refreshTokenUri;
this._logoutUri = logoutUri;
this._userInfoUri = userInfoUri;
this._checkSessionUri = checkSessionUri;
this._redirectUri = redirectUri;
this._postLogoutRedirectUri = postLogoutRedirectUri;
this._scopes = scopes;
}
_createClass(OidcClient, [{
key: "getAuthorizeUri",
value: function getAuthorizeUri(inputUri, extraQueryParams) {
var redirectUri = inputUri || this._redirectUri;
var state = (0, _utils.randomString)(16);
var nonce = (0, _utils.randomString)(16);
var codeVerifier = (0, _utils.randomString)(48);
var codeChallenge = (0, _utils.createS256CodeChallenge)(codeVerifier);
var authorizeUri = this._client.code.getUri({
redirectUri: redirectUri,
query: _objectSpread({
code_challenge: codeChallenge,
code_challenge_method: 'S256',
state: state,
nonce: nonce
}, extraQueryParams)
});
var stateInfo = {
state: state,
nonce: nonce,
codeVerifier: codeVerifier,
redirectUri: redirectUri,
createdAt: (0, _utils.currentTimestamp)()
};
return [authorizeUri, stateInfo];
}
}, {
key: "getToken",
value: function () {
var _getToken = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee(authorizeUri) {
var stateInfo,
extraOptions,
state,
nonce,
codeVerifier,
_stateInfo$redirectUr,
redirectUri,
newRedirectUri,
newAuthorizeUri,
buildAuthUri,
sessionState,
_args = arguments;
return regeneratorRuntime.wrap(function _callee$(_context) {
while (1) {
switch (_context.prev = _context.next) {
case 0:
stateInfo = _args.length > 1 && _args[1] !== undefined ? _args[1] : {};
extraOptions = _args.length > 2 ? _args[2] : undefined;
state = stateInfo.state, nonce = stateInfo.nonce, codeVerifier = stateInfo.codeVerifier, _stateInfo$redirectUr = stateInfo.redirectUri, redirectUri = _stateInfo$redirectUr === void 0 ? this._redirectUri : _stateInfo$redirectUr;
newRedirectUri = (0, _utils.removeTrailingSlash)(redirectUri);
newAuthorizeUri = (0, _utils.removeTrailingSlash)(authorizeUri);
buildAuthUri = new URL(newAuthorizeUri);
sessionState = buildAuthUri.searchParams.get('session_state');
return _context.abrupt("return", this._client.code.getToken(newAuthorizeUri, _objectSpread({
state: state,
redirectUri: newRedirectUri,
body: {
code_verifier: codeVerifier
}
}, extraOptions)).then(function (res) {
if (!res.data) {
throw new Error("Unable to get token");
}
return res.data;
}).then(this._handleTokenResponse).then(function (authData) {
var profile = authData.profile;
if (profile && profile.nonce !== nonce) {
throw new Error("Invalid nonce: ".concat(nonce));
}
return _objectSpread({}, authData, {}, sessionState && {
sessionState: sessionState
});
}));
case 8:
case "end":
return _context.stop();
}
}
}, _callee, this);
}));
function getToken(_x) {
return _getToken.apply(this, arguments);
}
return getToken;
}()
}, {
key: "refreshToken",
value: function () {
var _refreshToken = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee2() {
return regeneratorRuntime.wrap(function _callee2$(_context2) {
while (1) {
switch (_context2.prev = _context2.next) {
case 0:
return _context2.abrupt("return", fetch(this._refreshTokenUri, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
scopes: this._scopes.join(' ')
}),
credentials: 'include'
}).then(function (res) {
return res.json();
}).then(this._handleTokenResponse));
case 1:
case "end":
return _context2.stop();
}
}
}, _callee2, this);
}));
function refreshToken() {
return _refreshToken.apply(this, arguments);
}
return refreshToken;
}()
}, {
key: "_handleTokenResponse",
value: function _handleTokenResponse(tokenRes) {
var accessToken = tokenRes.access_token,
refreshToken = tokenRes.refresh_token,
idToken = tokenRes.id_token,
expiresIn = tokenRes.expires_in,
tokenType = tokenRes.token_type,
scopes = tokenRes.scope;
var profile = null;
if (idToken) {
try {
profile = (0, _jwtDecode["default"])(idToken);
var filterClaims = ['at_hash', 'aud', 'exp', 'iat', 'iss', 'sid', 'auth_time'];
profile = Object.keys(profile).filter(function (claim) {
return !filterClaims.includes(claim);
}).reduce(function (obj, key) {
return _objectSpread({}, obj, _defineProperty({}, key, profile[key]));
}, {});
} catch (err) {
throw new Error("Failed to parse idToken: ".concat(err.message));
}
}
return _objectSpread({
tokenType: tokenType,
accessToken: accessToken,
refreshToken: refreshToken
}, idToken && {
idToken: idToken
}, {}, profile && {
profile: profile
}, {
expiresIn: expiresIn,
expiresAt: (0, _utils.currentTimestamp)() + expiresIn,
scopes: (scopes || '').split(' ').filter(function (item) {
return !!item;
})
});
}
}, {
key: "getUserInfoUri",
value: function getUserInfoUri(extraQueryParams) {
var uri = new URL(this._userInfoUri);
for (var key in extraQueryParams) {
uri.searchParams.set(key, extraQueryParams[key]);
}
return uri.href;
}
}, {
key: "getLogoutUri",
value: function getLogoutUri(inputUri, extraQueryParams) {
var postLogoutRedirectUri = inputUri || this._postLogoutRedirectUri;
var uri = new URL(this._logoutUri);
extraQueryParams = _objectSpread({}, extraQueryParams, {
post_logout_redirect_uri: postLogoutRedirectUri
});
for (var key in extraQueryParams) {
uri.searchParams.set(key, extraQueryParams[key]);
}
return uri.href;
}
}]);
return OidcClient;
}();
exports["default"] = OidcClient;