import passport from "passport"; import { NextFunction, Request, Response } from "express"; import IDPAuthFactory from "./src/services/IDPAuthFactory.js"; import { IDP_TYPES } from "./src/utils/constants.js"; import { existsSync, readFileSync } from "fs"; /** * This is middleware used to authenticate route using Single Sign-On (SSO) of multiple IDP Services. * * Configuration has to be created in AWS Secrets manager and `secret_name` has to be stored in database. * * @param req This method requires keys called `idp` and `tenantId`, * can be passed from `param` or `query` or through `body` * * @example * app.get("/auth/login", IDPAuthenticationMW, function (req, res) { // existing code of authentication... }) */ export function IDPAuthenticationMW(req: Request, res: Response, next: NextFunction) { console.log('[SSO]: Authenticating request'); try { // * Check for the path and idp param in query or param or body // const { query, params, body } = req; // const { idp, tenantId } = Object.assign({}, { ...params, ...query, ...body }); // if (!idp) return res.status(400).json({ message: "IDP not found!!!" }); // if (!tenantId) return res.status(400).json({ message: "TenantID not found!!!" }); // * Initialise passport const config = JSON.parse(req.query.config as string) passport.initialize(); // * Create session passport.session(); // * Create serialization passport.serializeUser(function (user, done) { done(null, user); }); // * Create deserialization passport.deserializeUser(function (id, done) { done(null, { id }); }); // * Get IDP config and set the local // const configSvc = new ConfigSvc({ idp, tenantId }); // const config: any = await configSvc.getConfig(); // console.log(config); // if (Object.keys(config).length === 0) // return res.status(422).json({ message: `Invalid Configuration for IDP: ${IDP_TYPES[idp]?.name || idp}` }); // * Policy should be attached for requesting url and for strategy req.query["p"] = config.policyName; // * Get Factory/Strategy instance using idp const idpAuthObj = IDPAuthFactory.get(req.query.idp as string, config); idpAuthObj.authenticate(req, res, next, (err: any, user: any, info: any, status: any) => { // * Error Handle console.log('err, user, info, status', err, user, info, status); res.status(status ?? 401).json({ err, info }); }); } catch (error: any) { console.log(error.message); res.status(500).json({ error: error.message }); } finally { console.timeEnd('[SSO]'); } }