UNPKG

@redocly/portal-plugin-gravitee-sso

Version:

Gravitee SSO plugin for @redocly/portal

102 lines 5.3 kB
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; import { setCookie } from 'hono/cookie'; import { DEFAULT_COOKIE_EXPIRATION } from '@redocly/realm/dist/shared/constants.js'; import { JWT_SECRET_KEY } from '@redocly/realm/dist/server/constants.js'; import * as jwt from '@redocly/realm/dist/server/web-server/jwt/jwt.js'; import { getPathPrefix, withPathPrefix } from '@redocly/theme/core/utils'; import { isGraviteeSsoConfig } from './is-gravitee-sso-config.js'; import { GraviteeSsoError, LOGIN_PAGE_SLUG } from './constants.js'; export default function (ctx, store) { return __awaiter(this, void 0, void 0, function* () { var _a; const logger = ctx.get('logger'); const parsedUrl = new URL(ctx.req.url); const idpId = parsedUrl.searchParams.get('idpId'); const redirectTo = parsedUrl.searchParams.get('redirectTo') || '/'; const loginPagePathname = parsedUrl.searchParams.get('loginPagePathname') || withPathPrefix(LOGIN_PAGE_SLUG); if (!idpId) { logger.error('Gravitee SSO: idpId query parameter not found'); return ctx.text('Forbidden', 403); } const createErrorResponse = (error) => { const errorSearchParams = new URLSearchParams({ error, idpId, redirectTo, }); const errorRedirectUrl = `${loginPagePathname}?${errorSearchParams}`; return ctx.newResponse(null, 302, { Location: errorRedirectUrl }); }; const idpConfig = (_a = store.ssoDirect) === null || _a === void 0 ? void 0 : _a[idpId]; if (!isGraviteeSsoConfig(idpConfig)) { logger.error(`Gravitee SSO: invalid idpId in query params: ${idpId}`); return ctx.text('Forbidden', 403); } const formData = yield ctx.req.formData(); const username = formData.get('username'); const password = formData.get('password'); if (!username || !password) { return createErrorResponse(GraviteeSsoError.INVALID_CREDENTIALS); } const basicAuthToken = btoa(username + ':' + password); const apiUrl = `${idpConfig.apiBaseUrl}/portal/environments/${idpConfig.env || 'DEFAULT'}`; try { const authRes = yield fetch(`${apiUrl}/auth/login`, { method: 'POST', headers: { Authorization: `Basic ${basicAuthToken}`, }, }); if (authRes.status === 401) { logger.verbose('Gravitee SSO callback: invalid username or password'); return createErrorResponse(GraviteeSsoError.INVALID_CREDENTIALS); } else if (authRes.status !== 200) { logger.error('Gravitee SSO callback: failed to fetch token from Gravitee API'); return createErrorResponse(GraviteeSsoError.UNKNOWN_ERROR); } const userRes = yield fetch(`${apiUrl}/user`, { method: 'GET', headers: { Authorization: `Basic ${basicAuthToken}`, }, }); if (userRes.status !== 200) { logger.error('Gravitee SSO callback: failed to fetch user information from Gravitee API'); return createErrorResponse(GraviteeSsoError.UNKNOWN_ERROR); } const auth = yield authRes.json(); const user = yield userRes.json(); const userClaims = Object.assign(Object.assign({}, user), { sub: user.id, name: user.display_name || user.email || 'Unknown', idpId }); const encodedToken = yield jwt.sign(userClaims, JWT_SECRET_KEY); const expirationDate = Date.now() + DEFAULT_COOKIE_EXPIRATION * 1000; setCookie(ctx, 'idp_access_token', auth.token || '', { path: getPathPrefix() || '/', httpOnly: true, expires: new Date(expirationDate), }); const c1 = ctx._headers['set-cookie']; setCookie(ctx, 'authorization', encodedToken, { path: getPathPrefix() || '/', httpOnly: true, expires: new Date(expirationDate), }); const resp = ctx.newResponse(null, 302, { Location: withPathPrefix(redirectTo) }); resp.headers.append('set-cookie', c1); return resp; } catch (error) { logger.error(`Gravitee sso callback: ${error.message}`); return createErrorResponse(GraviteeSsoError.UNKNOWN_ERROR); } }); } //# sourceMappingURL=handle-login-callback.js.map