UNPKG

@krypton-org/krypton-auth

Version:

Express authentication middleware, using GraphQL and JSON Web Tokens.

207 lines 8.53 kB
"use strict"; /** * Holding the service config * @module config */ var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const fs_1 = __importDefault(require("fs")); const path_1 = __importDefault(require("path")); const url_parse_1 = __importDefault(require("url-parse")); const RSAKeysGeneration_1 = require("./crypto/RSAKeysGeneration"); const DEFAULT_PUBLIC_KEY_FILE = __dirname.includes('node_modules') ? path_1.default.resolve(__dirname, '../../../public-key.txt') : path_1.default.resolve(__dirname, '../public-key.txt'); const DEFAULT_PRIVATE_KEY_FILE = __dirname.includes('node_modules') ? path_1.default.resolve(__dirname, '../../../private-key.txt') : path_1.default.resolve(__dirname, '../private-key.txt'); class DefaultProperties { constructor() { this.algorithm = 'RS256'; this.authTokenExpiryTime = 15 * 60 * 1000; this.dbAddress = 'mongodb://localhost:27017/users'; this.dbConfig = { useCreateIndex: true, useFindAndModify: false, useNewUrlParser: true, useUnifiedTopology: true, }; this.eventEmitter = null; this.extendedSchema = {}; this.graphiql = true; this.host = null; this.mailFrom = null; this.nodemailerConfig = null; this.notificationPageTemplate = path_1.default.resolve(__dirname, '../lib/templates/pages/Notification.ejs'); this.privateKey = null; this.privateKeyFilePath = null; this.publicKey = null; this.publicKeyFilePath = null; this.refreshTokenExpiryTime = 7 * 24 * 60 * 60 * 1000; this.resetPasswordEmailTemplate = path_1.default.resolve(__dirname, '../lib/templates/emails/ResetPassword.ejs'); this.resetPasswordFormTemplate = path_1.default.resolve(__dirname, '../lib/templates/forms/ResetPassword.ejs'); this.verifyEmailTemplate = path_1.default.resolve(__dirname, '../lib/templates/emails/VerifyEmail.ejs'); this.onReady = () => { // Execute some code when Krypton is set-up }; } } exports.DefaultProperties = DefaultProperties; class ServiceConfiguration extends DefaultProperties { constructor() { super(...arguments); this.hostURLObject = undefined; this.isAgendaReady = false; this.isMongooseReady = false; this.isTestEmailReady = false; /** * Setting SocketIO server to push email notifications to GraphiQL IDE * @param {SocketIO.Server} io * @returns {void} */ this.setSocketIO = (io) => { this.io = io; }; /** * Called by Mongoose and Agenda when connection established with MongoDB. * When both calls has been made it calls {@link Config#onReady} * @param {ReadyStatus} status * @returns {void} */ this.serviceReady = (status) => { if (status.isAgendaReady) { this.isAgendaReady = true; } if (status.isMongooseReady) { this.isMongooseReady = true; } if (status.isTestEmailReady) { this.isTestEmailReady = true; console.log('\u2705 Ethereal credentials obtained'); } if (this.isAgendaReady && this.isMongooseReady && (this.nodemailerConfig || this.isTestEmailReady)) { console.log('\u2705 MongoDB connection established'); console.log('\u2705 Krypton Authentication is ready'); this.onReady(); } }; /** * Called by Mongoose when connection with MongoDB failed. * @param {Error} err * @returns {void} */ this.dbConnectionFailed = (err) => { console.log('\u274C Connection to MongoDB failed'); if (config.eventEmitter) { config.eventEmitter.emit('error', err); } }; /** * Returns the complete router adress of Krypton Authentication * @param {Request} req * @returns The the complete router of the service */ this.getRouterAddress = (req) => { return config.hostURLObject ? config.hostURLObject.href + req.baseUrl : req.protocol + '://' + req.get('host') + req.baseUrl; }; /** * Returns the domain of Krypton Authentication to set the domain parameter into cookies * @param {Request} req * @returns The domain of the service */ this.getDomainAddress = () => { return config.hostURLObject ? config.hostURLObject.hostname : null; }; } /** * Merging user options and default properties * @param {Properties} properties? * @returns {void} */ set(properties) { if (!properties) { properties = {}; } if (!properties.publicKey || !properties.privateKey) { if (properties.publicKeyFilePath || properties.privateKeyFilePath) { if (fs_1.default.existsSync(properties.publicKeyFilePath) && fs_1.default.existsSync(properties.privateKeyFilePath)) { properties.publicKey = fs_1.default.readFileSync(properties.publicKeyFilePath).toString(); properties.privateKey = fs_1.default.readFileSync(properties.privateKeyFilePath).toString(); } else { const { publicKey, privateKey } = this.createAndSaveKeyPair(properties.publicKeyFilePath, properties.privateKeyFilePath); properties.publicKey = publicKey; properties.privateKey = privateKey; } } else if (fs_1.default.existsSync(DEFAULT_PUBLIC_KEY_FILE) && fs_1.default.existsSync(DEFAULT_PRIVATE_KEY_FILE)) { properties.publicKey = fs_1.default.readFileSync(DEFAULT_PUBLIC_KEY_FILE).toString(); properties.privateKey = fs_1.default.readFileSync(DEFAULT_PRIVATE_KEY_FILE).toString(); } else { const { publicKey, privateKey } = this.createAndSaveKeyPair(DEFAULT_PUBLIC_KEY_FILE, DEFAULT_PRIVATE_KEY_FILE); properties.publicKey = publicKey; properties.privateKey = privateKey; } } // Merge taking place here Object.keys(new DefaultProperties()).map(function (prop) { if (properties[prop]) { if (prop === 'dbConfig') { this[prop] = Object.assign(Object.assign({}, this[prop]), properties[prop]); } else { this[prop] = properties[prop]; } } }.bind(this)); this.dbAddress = this.getValidMongoDBUrl(this.dbAddress); if (this.host) { this.host = this.getValidhttpUrl(this.host); this.hostURLObject = url_parse_1.default(this.host); } } /** * Creates the public and private key pair and saves them in the file paths provided * @private * @param {string} publicKeyFilePath * @param {string} privateKeyFilePath * @returns {{ publicKey: string, privateKey: string }} * @memberof DefaultConfig */ createAndSaveKeyPair(publicKeyFilePath, privateKeyFilePath) { const { publicKey, privateKey } = RSAKeysGeneration_1.generateKeys(); fs_1.default.writeFileSync(privateKeyFilePath, privateKey); fs_1.default.writeFileSync(publicKeyFilePath, publicKey); return { publicKey, privateKey }; } getValidMongoDBUrl(url) { if (url.match(/mongodb(?:\+srv)?:\/\/.*/) !== null) { return url; } else { return 'mongodb://' + url; } } getValidhttpUrl(url) { url = url.trim().replace(/\s/g, ''); if (/\/$/.test(url)) { url = url.slice(0, -1); } if (/^(:\/\/)/.test(url)) { return `http${url}`; } if (!/^(f|ht)tps?:\/\//i.test(url)) { return `http://${url}`; } return url; } } /* Exporting an instance of Config that acts like singleton */ const config = new ServiceConfiguration(); exports.default = config; //# sourceMappingURL=config.js.map