@krypton-org/krypton-auth
Version:
Express authentication middleware, using GraphQL and JSON Web Tokens.
207 lines • 8.53 kB
JavaScript
"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