UNPKG

teko-oauth2

Version:

Teko Identity OAuth 2 Javascript Library for Web App Client

267 lines (229 loc) 10.8 kB
"use strict"; 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;