UNPKG

kopi-id

Version:
298 lines (231 loc) 12.3 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports["default"] = void 0; var _constants = _interopRequireDefault(require("../constants")); var _jwt = _interopRequireDefault(require("./jwt")); var _token = _interopRequireDefault(require("./token")); var _flowUtils = _interopRequireDefault(require("./flowUtils")); var _hash = _interopRequireDefault(require("./hash")); var _logger = _interopRequireDefault(require("./logger")); var _redirect = _interopRequireDefault(require("./redirect")); 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); }); }; } var _default = function _default(oidcConfig) { var _loggerService = (0, _logger["default"])('Auth Service', oidcConfig.logLevel), L = _loggerService.L; var jwtService = (0, _jwt["default"])(oidcConfig); var tokenService = (0, _token["default"])(oidcConfig, jwtService); var handleAuthenticated = /*#__PURE__*/function () { var _ref = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee(res, authenticationRequestId, sub, isUserAuthenticated, isSilentAuthenticated) { var authenticationRequest, scope, clientId, idTokenHint, redirectUri, prompt, state, client, idToken, tokenSub, authorizationRequestId, consentPath, consentUrl, isConsentGiven; return regeneratorRuntime.wrap(function _callee$(_context) { while (1) { switch (_context.prev = _context.next) { case 0: _context.prev = 0; _context.next = 3; return oidcConfig.onLoadAuthenticationRequest(authenticationRequestId); case 3: authenticationRequest = _context.sent; scope = authenticationRequest.scope, clientId = authenticationRequest.client_id, idTokenHint = authenticationRequest.id_token_hint, redirectUri = authenticationRequest.redirect_uri, prompt = authenticationRequest.prompt, state = authenticationRequest.state; // Validate authenticated status if (isUserAuthenticated) { _context.next = 7; break; } return _context.abrupt("return", _redirect["default"].redirectLoginRequired(res, redirectUri, state)); case 7: if (!(isSilentAuthenticated && prompt && prompt.includes(_constants["default"].authenticationRequest.prompt.LOGIN))) { _context.next = 9; break; } return _context.abrupt("return", _redirect["default"].redirectLoginRequired(res, redirectUri, state)); case 9: _context.next = 11; return oidcConfig.onGetClient(clientId); case 11: client = _context.sent; if (!(idTokenHint != null)) { _context.next = 26; break; } _context.prev = 13; _context.next = 16; return jwtService.verifyIdToken(idTokenHint, client); case 16: idToken = _context.sent; tokenSub = idToken.sub; if (!(sub !== tokenSub)) { _context.next = 20; break; } return _context.abrupt("return", _redirect["default"].redirectLoginRequired(res, redirectUri, state, 'user logged in as different id from the id_token')); case 20: _context.next = 26; break; case 22: _context.prev = 22; _context.t0 = _context["catch"](13); L.warn("Error caught when verifying ID Token: ".concat(_context.t0.message)); // Send Redirect with Error (invalid_request) return _context.abrupt("return", _redirect["default"].redirectInvalidRequest(res, redirectUri, state, 'invalid id_token')); case 26: _context.next = 28; return oidcConfig.onSaveAuthorizationRequest(authenticationRequestId, sub); case 28: authorizationRequestId = _context.sent; // Generate Consent Url consentPath = oidcConfig.consentUrl || "".concat(oidcConfig.host, "/").concat(oidcConfig.consentPage); consentUrl = "".concat(consentPath, "?authorizationRequestId=").concat(authorizationRequestId); // Check CONSENT prompt if (!(prompt && prompt.includes(_constants["default"].authenticationRequest.prompt.CONSENT))) { _context.next = 34; break; } // Must show consent page, redirect to consent page res.redirect(consentUrl); return _context.abrupt("return"); case 34: _context.next = 36; return oidcConfig.onIsConsentGiven(sub, scope, clientId); case 36: isConsentGiven = _context.sent; if (!isConsentGiven) { _context.next = 39; break; } return _context.abrupt("return", handleAuthorized(res, authorizationRequestId, true, true)); case 39: // Redirect to consent page res.redirect(consentUrl); _context.next = 47; break; case 42: _context.prev = 42; _context.t1 = _context["catch"](0); L.error(_context.t1.message); L.debug(_context.t1); res.status(500).send(); case 47: case "end": return _context.stop(); } } }, _callee, null, [[0, 42], [13, 22]]); })); return function handleAuthenticated(_x, _x2, _x3, _x4, _x5) { return _ref.apply(this, arguments); }; }(); var handleAuthorized = /*#__PURE__*/function () { var _ref2 = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee2(res, authorizationRequestId, isConsentGiven, isSilentConsent) { var authorizationRequest, authenticationRequestId, sub, authenticationRequest, authTime, responseTypes, scope, clientId, redirectUri, prompt, state, nonce, client, flowType, hasCode, hasIdToken, hasAccessToken, cHash, atHash, query, authorizationCode, buffer, accessToken, _buffer, idToken, clientUrl; return regeneratorRuntime.wrap(function _callee2$(_context2) { while (1) { switch (_context2.prev = _context2.next) { case 0: _context2.prev = 0; _context2.next = 3; return oidcConfig.onLoadAuthorizationRequest(authorizationRequestId); case 3: authorizationRequest = _context2.sent; authenticationRequestId = authorizationRequest.authenticationRequestId, sub = authorizationRequest.sub; _context2.next = 7; return oidcConfig.onLoadAuthenticationRequest(authenticationRequestId); case 7: authenticationRequest = _context2.sent; authTime = authenticationRequest.auth_time, responseTypes = authenticationRequest.response_type, scope = authenticationRequest.scope, clientId = authenticationRequest.client_id, redirectUri = authenticationRequest.redirect_uri, prompt = authenticationRequest.prompt, state = authenticationRequest.state, nonce = authenticationRequest.nonce; _context2.next = 11; return oidcConfig.onGetClient(clientId); case 11: client = _context2.sent; if (isConsentGiven) { _context2.next = 14; break; } return _context2.abrupt("return", _redirect["default"].redirectConsentRequired(res, redirectUri, state)); case 14: if (!(isSilentConsent && prompt && prompt.includes(_constants["default"].authenticationRequest.prompt.CONSENT))) { _context2.next = 16; break; } return _context2.abrupt("return", _redirect["default"].redirectConsentRequired(res, redirectUri, state)); case 16: _context2.next = 18; return oidcConfig.onSetConsentGiven(sub, scope, clientId); case 18: // Flow flowType = _flowUtils["default"].getFlowType(responseTypes); hasCode = responseTypes && responseTypes.includes(_constants["default"].authenticationRequest.responseTypes.CODE); hasIdToken = responseTypes && responseTypes.includes(_constants["default"].authenticationRequest.responseTypes.ID_TOKEN); hasAccessToken = responseTypes && responseTypes.includes(_constants["default"].authenticationRequest.responseTypes.TOKEN); cHash = null; atHash = null; query = state && state !== '' ? "&state=".concat(encodeURIComponent(state)) : ''; if (!hasCode) { _context2.next = 32; break; } _context2.next = 28; return oidcConfig.onSaveAuthorization(authorizationRequestId, sub); case 28: authorizationCode = _context2.sent; // Hash Authorization Code buffer = _hash["default"].hash(authorizationCode, oidcConfig.hashAlgorithm); cHash = buffer.slice(0, buffer.length / 2).toString('base64'); query += "&code=".concat(encodeURIComponent(authorizationCode)); case 32: if (!hasAccessToken) { _context2.next = 41; break; } _context2.next = 35; return tokenService.generateToken(client, sub, scope, authTime, nonce, cHash); case 35: accessToken = _context2.sent; // Hash Access Token _buffer = _hash["default"].hash(accessToken, oidcConfig.hashAlgorithm); atHash = _buffer.slice(0, _buffer.length / 2).toString('base64'); query += "&access_token=".concat(encodeURIComponent(accessToken)); query += "&expires_in=".concat(encodeURIComponent(oidcConfig.accessTokenExpiresIn)); query += "&token_type=Bearer"; case 41: if (!hasIdToken) { _context2.next = 46; break; } _context2.next = 44; return tokenService.generateIdToken(client, sub, authTime, nonce, cHash, atHash); case 44: idToken = _context2.sent; query += "&id_token=".concat(encodeURIComponent(idToken)); case 46: // Redirect to client redirect page query = query.charAt(0) === '&' ? query.slice(1) : query; clientUrl = "".concat(redirectUri, "#").concat(query); res.redirect(clientUrl); _context2.next = 56; break; case 51: _context2.prev = 51; _context2.t0 = _context2["catch"](0); L.error(_context2.t0.message); L.debug(_context2.t0); res.status(500).send(); case 56: case "end": return _context2.stop(); } } }, _callee2, null, [[0, 51]]); })); return function handleAuthorized(_x6, _x7, _x8, _x9) { return _ref2.apply(this, arguments); }; }(); return { handleAuthenticated: handleAuthenticated, handleAuthorized: handleAuthorized }; }; exports["default"] = _default;