UNPKG

@sphereon/ssi-express-support

Version:

281 lines • 12 kB
"use strict"; 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()); }); }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.ExpressCorsConfigurer = exports.ExpressBuilder = void 0; /** * @public */ const body_parser_1 = __importDefault(require("body-parser")); const cors_1 = __importDefault(require("cors")); const express_1 = __importDefault(require("express")); const express_session_1 = __importDefault(require("express-session")); const http_terminator_1 = require("http-terminator"); const morgan_1 = __importDefault(require("morgan")); const passport_1 = __importDefault(require("passport")); const auth_utils_1 = require("./auth-utils"); const express_utils_1 = require("./express-utils"); const functions_1 = require("./functions"); class ExpressBuilder { constructor(opts) { this._handlers = []; this._startListen = undefined; this._usePassportAuth = false; const { existingExpress, envVarPrefix } = opts !== null && opts !== void 0 ? opts : {}; if (existingExpress) { this.withExpress(existingExpress); } this.envVarPrefix = envVarPrefix !== null && envVarPrefix !== void 0 ? envVarPrefix : ''; } static fromExistingExpress(opts) { return new ExpressBuilder(opts !== null && opts !== void 0 ? opts : {}); } static fromServerOpts(opts) { var _a; const builder = new ExpressBuilder({ existingExpress: opts === null || opts === void 0 ? void 0 : opts.existingExpress, envVarPrefix: opts === null || opts === void 0 ? void 0 : opts.envVarPrefix }); return builder.withEnableListenOpts(Object.assign(Object.assign({}, opts), { hostnameOrIP: opts.hostname, startOnBuild: (_a = opts.startListening) !== null && _a !== void 0 ? _a : false })); } enableListen(startOnBuild) { if (startOnBuild !== undefined) { this._startListen = startOnBuild; } return this; } withMorganLogging(opts) { var _a, _b; if ((opts === null || opts === void 0 ? void 0 : opts.existingMorgan) && (opts.format || opts.options)) { throw Error('Cannot using an existing morgan with either a format or options'); } this._morgan = (_a = opts === null || opts === void 0 ? void 0 : opts.existingMorgan) !== null && _a !== void 0 ? _a : (0, morgan_1.default)((_b = opts === null || opts === void 0 ? void 0 : opts.format) !== null && _b !== void 0 ? _b : 'dev', opts === null || opts === void 0 ? void 0 : opts.options); return this; } withEnableListenOpts({ port, hostnameOrIP, callback, startOnBuild, }) { port && this.withPort(port); hostnameOrIP && this.withHostname(hostnameOrIP); if (typeof callback === 'function') { this.withListenCallback(callback); } this._startListen = startOnBuild === true; return this; } withPort(port) { this.port = port; return this; } withHostname(hostnameOrIP) { this.hostnameOrIP = hostnameOrIP; return this; } withListenCallback(callback) { this.listenCallback = callback; return this; } withExpress(existingExpress) { this.existingExpress = existingExpress; this._startListen = false; return this; } withCorsConfigurer(configurer) { this._corsConfigurer = configurer; return this; } withPassportAuth(usePassport, initializeOptions) { this._usePassportAuth = usePassport; this._passportInitOpts = initializeOptions; return this; } withGlobalUserIsInRole(userIsInRole) { this._userIsInRole = userIsInRole; return this; } withEnforcer(enforcer) { this._enforcer = enforcer; return this; } startListening(express) { this._server = express.listen(this.getPort(), this.getHostname(), this.listenCallback); this._terminator = (0, http_terminator_1.createHttpTerminator)({ server: this._server, // gracefulTerminationTimeout: 10 }); return { server: this._server, terminator: this._terminator }; } getHostname() { var _a, _b; return (_b = (_a = this.hostnameOrIP) !== null && _a !== void 0 ? _a : (0, functions_1.env)('HOSTNAME', this.envVarPrefix)) !== null && _b !== void 0 ? _b : '0.0.0.0'; } getPort() { var _a, _b; return ((_b = (_a = this.port) !== null && _a !== void 0 ? _a : (0, functions_1.env)('PORT', this.envVarPrefix)) !== null && _b !== void 0 ? _b : 5000); } setHandlers(handlers) { if (Array.isArray(handlers)) { this._handlers = handlers; } else if (handlers) { if (!this._handlers) { this._handlers = []; } this._handlers.push(handlers); } else { this._handlers = []; } return this; } addHandler(handler) { if (!this._handlers) { this._handlers = []; } this._handlers.push(handler); return this; } withSessionOptions(sessionOpts) { this._sessionOpts = sessionOpts; return this; } build(opts) { const express = this.buildExpress(opts); const startListening = (opts === null || opts === void 0 ? void 0 : opts.startListening) === undefined ? this._startListen !== true : opts.startListening; let started = this._server !== undefined; if (startListening && !started) { this.startListening(express); started = true; } return { express, port: this.getPort(), hostname: this.getHostname(), userIsInRole: this._userIsInRole, startListening, enforcer: this._enforcer, start: (opts) => { if (opts === null || opts === void 0 ? void 0 : opts.doNotStartListening) { console.log('Express will not start listening. You will have to start it yourself'); } else { if (!started) { this.startListening(express); started = true; } } if ((opts === null || opts === void 0 ? void 0 : opts.disableErrorHandler) !== true) { express.use(express_utils_1.jsonErrorHandler); } return { server: this._server, terminator: this._terminator }; }, stop: (terminator) => __awaiter(this, void 0, void 0, function* () { const term = terminator !== null && terminator !== void 0 ? terminator : this._terminator; if (!term) { return false; } return yield term.terminate().then(() => true); }), }; } buildExpress(opts) { var _a, _b, _c; const app = (_b = (_a = opts === null || opts === void 0 ? void 0 : opts.express) !== null && _a !== void 0 ? _a : this.existingExpress) !== null && _b !== void 0 ? _b : (0, express_1.default)(); if (this._morgan) { app.use(this._morgan); } if (this._sessionOpts) { const store = (_c = this._sessionOpts.store) !== null && _c !== void 0 ? _c : new express_session_1.default.MemoryStore(); this._sessionOpts.store = store; app.use((0, express_session_1.default)(this._sessionOpts)); } if (this._usePassportAuth) { app.use(passport_1.default.initialize(this._passportInitOpts)); if (this._sessionOpts) { // app.use(passport.authenticate('session')) //_sessionOpts are not for passport session, they are for express above app.use(passport_1.default.session()); } } if (this._userIsInRole) { app.use((0, auth_utils_1.checkUserIsInRole)({ roles: this._userIsInRole })); } if (this._corsConfigurer) { this._corsConfigurer.configure({ existingExpress: app }); } // @ts-ignore this._handlers && this._handlers.length > 0 && app.use(this._handlers); // @ts-ignore (opts === null || opts === void 0 ? void 0 : opts.handlers) && app.use(opts.handlers); //fixme: this should come from the config app.use(body_parser_1.default.urlencoded({ extended: true })); app.use(body_parser_1.default.json({ limit: '5mb' })); return app; } } exports.ExpressBuilder = ExpressBuilder; class ExpressCorsConfigurer { constructor(args) { const { existingExpress, envVarPrefix } = args !== null && args !== void 0 ? args : {}; this._express = existingExpress; this._envVarPrefix = envVarPrefix; } allowOrigin(value) { this._allowOrigin = value; return this; } disableCors(value) { this._disableCors = value; return this; } allowMethods(value) { this._allowMethods = value; return this; } allowedHeaders(value) { this._allowedHeaders = value; return this; } allowCredentials(value) { this._allowCredentials = value; return this; } configure({ existingExpress }) { var _a, _b, _c; const express = existingExpress !== null && existingExpress !== void 0 ? existingExpress : this._express; if (!express) { throw Error('No express passed in during construction or configure'); } const disableCorsEnv = (0, functions_1.env)('CORS_DISABLE', this._envVarPrefix); const corsDisabled = (_a = this._disableCors) !== null && _a !== void 0 ? _a : (disableCorsEnv ? /true/.test(disableCorsEnv) : false); if (corsDisabled) { return; } const envAllowOriginStr = (_b = (0, functions_1.env)('CORS_ALLOW_ORIGIN', this._envVarPrefix)) !== null && _b !== void 0 ? _b : '*'; let envAllowOrigin; if (envAllowOriginStr.includes(',')) { envAllowOrigin = envAllowOriginStr.split(','); } else if (envAllowOriginStr.includes(' ')) { envAllowOrigin = envAllowOriginStr.split(' '); } else { envAllowOrigin = envAllowOriginStr; } if (Array.isArray(envAllowOrigin) && envAllowOrigin.length === 1) { envAllowOrigin = envAllowOrigin[0]; } const corsOptions = Object.assign(Object.assign(Object.assign(Object.assign({ origin: (_c = this._allowOrigin) !== null && _c !== void 0 ? _c : envAllowOrigin }, (this._allowMethods && { methods: this._allowMethods })), (this._allowedHeaders && { allowedHeaders: this._allowedHeaders })), (this._allowCredentials !== undefined && { credentials: this._allowCredentials })), { optionsSuccessStatus: 204 }); if (this._enablePreflightOptions) { express.options('*', (0, cors_1.default)(corsOptions)); } express.use((0, cors_1.default)(corsOptions)); } } exports.ExpressCorsConfigurer = ExpressCorsConfigurer; //# sourceMappingURL=express-builders.js.map