@redocly/portal-plugin-gravitee-sso
Version:
Gravitee SSO plugin for @redocly/portal
102 lines • 5.32 kB
JavaScript
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.getConfig().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