From 3405f184bdb9572c90849af8a9ebd53898f52990 Mon Sep 17 00:00:00 2001 From: Mathew Henson Date: Tue, 3 May 2016 20:00:37 +0100 Subject: [PATCH] Updated builds --- dist/bucket-manager.js | 206 +++--- dist/controllers/bucket-controller.js | 170 ++--- dist/controllers/comms-controller.js | 75 +- dist/controllers/controller.js | 32 +- dist/controllers/cors-controller.js | 32 +- dist/controllers/error-controller.js | 30 +- dist/controllers/user-controller.js | 130 ++-- dist/mailer.js | 40 +- dist/main.js | 31 +- dist/permission-controller.js | 38 +- dist/session.js | 282 ++++---- dist/socket-api.js | 15 +- dist/startup.js | 39 +- dist/users.js | 941 +++++++++++--------------- 14 files changed, 1000 insertions(+), 1061 deletions(-) diff --git a/dist/bucket-manager.js b/dist/bucket-manager.js index 02fbe34..efa3a39 100644 --- a/dist/bucket-manager.js +++ b/dist/bucket-manager.js @@ -1,4 +1,17 @@ "use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promise, generator) { + return new Promise(function (resolve, reject) { + generator = generator.call(thisArg, _arguments); + function cast(value) { return value instanceof Promise && value.constructor === Promise ? value : new Promise(function (resolve) { resolve(value); }); } + function onfulfill(value) { try { step("next", value); } catch (e) { reject(e); } } + function onreject(value) { try { step("throw", value); } catch (e) { reject(e); } } + function step(verb, value) { + var result = generator[verb](value); + result.done ? resolve(result.value) : cast(result.value).then(onfulfill, onreject); + } + step("next", void 0); + }); +}; var gcloud = require("gcloud"); var zlib = require("zlib"); var compressible = require("compressible"); @@ -7,8 +20,8 @@ var socket_event_types_1 = require("./socket-event-types"); /** * Class responsible for managing buckets and uploads to Google storage */ -var BucketManager = (function () { - function BucketManager(buckets, files, stats, config) { +class BucketManager { + constructor(buckets, files, stats, config) { BucketManager._singleton = this; this._gcs = gcloud.storage({ projectId: config.google.bucket.projectId, keyFilename: config.google.keyFile }); this._buckets = buckets; @@ -24,7 +37,7 @@ var BucketManager = (function () { * @param {RegExp} searchTerm [Optional] Specify a search term * @returns {Promise>} */ - BucketManager.prototype.getBucketEntries = function (user, searchTerm) { + getBucketEntries(user, searchTerm) { var that = this; var gcs = this._gcs; var bucketCollection = this._buckets; @@ -39,13 +52,13 @@ var BucketManager = (function () { return resolve(buckets); }); }); - }; + } /** * Fetches the file count based on the given query * @param {IFileEntry} searchQuery The search query to idenfify files * @returns {Promise>} */ - BucketManager.prototype.numFiles = function (searchQuery) { + numFiles(searchQuery) { var files = this._files; return new Promise(function (resolve, reject) { // Save the new entry into the database @@ -55,14 +68,13 @@ var BucketManager = (function () { return resolve(count); }); }); - }; + } /** * Fetches all file entries by a given query * @param {any} searchQuery The search query to idenfify files * @returns {Promise>} */ - BucketManager.prototype.getFiles = function (searchQuery, startIndex, limit) { - if (limit === void 0) { limit = -1; } + getFiles(searchQuery, startIndex, limit = -1) { var that = this; var gcs = this._gcs; var files = this._files; @@ -72,14 +84,14 @@ var BucketManager = (function () { return resolve(files); }); }); - }; + } /** * Updates all file entries for a given search criteria with custom meta data * @param {any} searchQuery The search query to idenfify files * @param {any} meta Optional meta data to associate with the files * @returns {Promise} */ - BucketManager.prototype.setMeta = function (searchQuery, meta) { + setMeta(searchQuery, meta) { var files = this._files; return new Promise(function (resolve, reject) { // Save the new entry into the database @@ -89,7 +101,7 @@ var BucketManager = (function () { return reject(err); }); }); - }; + } /** * Fetches all file entries from the database for a given bucket * @param {IBucketEntry} bucket Specify the bucket from which he files belong to @@ -98,18 +110,18 @@ var BucketManager = (function () { * @param {RegExp} searchTerm Specify a search term * @returns {Promise>} */ - BucketManager.prototype.getFilesByBucket = function (bucket, startIndex, limit, searchTerm) { + getFilesByBucket(bucket, startIndex, limit, searchTerm) { var searchQuery = { bucketId: bucket.identifier }; if (searchTerm) searchQuery.name = searchTerm; return this.getFiles(searchQuery, startIndex, limit); - }; + } /** * Fetches the storage/api data for a given user * @param {string} user The user whos data we are fetching * @returns {Promise} */ - BucketManager.prototype.getUserStats = function (user) { + getUserStats(user) { var that = this; var gcs = this._gcs; var stats = this._stats; @@ -117,18 +129,18 @@ var BucketManager = (function () { // Save the new entry into the database stats.find({ user: user }).limit(1).next().then(function (result) { if (!result) - return reject(new Error("Could not find storage data for the user '" + user + "'")); + return reject(new Error(`Could not find storage data for the user '${user}'`)); else return resolve(result); }); }); - }; + } /** * Attempts to create a user usage statistics * @param {string} user The user associated with this bucket * @returns {Promise} */ - BucketManager.prototype.createUserStats = function (user) { + createUserStats(user) { var that = this; var stats = this._stats; return new Promise(function (resolve, reject) { @@ -145,13 +157,13 @@ var BucketManager = (function () { return reject(err); }); }); - }; + } /** * Attempts to remove the usage stats of a given user * @param {string} user The user associated with this bucket * @returns {Promise} A promise of the number of stats removed */ - BucketManager.prototype.removeUserStats = function (user) { + removeUserStats(user) { var that = this; var stats = this._stats; return new Promise(function (resolve, reject) { @@ -161,13 +173,13 @@ var BucketManager = (function () { return reject(err); }); }); - }; + } /** * Attempts to remove all data associated with a user * @param {string} user The user we are removing * @returns {Promise} */ - BucketManager.prototype.removeUser = function (user) { + removeUser(user) { var that = this; var stats = this._stats; return new Promise(function (resolve, reject) { @@ -179,23 +191,23 @@ var BucketManager = (function () { return reject(err); }); }); - }; + } /** * Attempts to create a new user bucket by first creating the storage on the cloud and then updating the internal DB * @param {string} name The name of the bucket * @param {string} user The user associated with this bucket * @returns {Promise} */ - BucketManager.prototype.createBucket = function (name, user) { + createBucket(name, user) { var that = this; var gcs = this._gcs; - var bucketID = "webinate-bucket-" + that.generateRandString(8).toLowerCase(); + var bucketID = `webinate-bucket-${that.generateRandString(8).toLowerCase()}`; var bucketCollection = this._buckets; var stats = this._stats; return new Promise(function (resolve, reject) { that.getIBucket(name, user).then(function (bucket) { if (bucket) - return reject(new Error("A Bucket with the name '" + name + "' has already been registered")); + return reject(new Error(`A Bucket with the name '${name}' has already been registered`)); var cors = { location: "EU", cors: [ @@ -217,7 +229,7 @@ var BucketManager = (function () { // Attempt to create a new Google bucket gcs.createBucket(bucketID, cors, function (err, bucket) { if (err) - return reject(new Error("Could not create a new bucket: '" + err.message + "'")); + return reject(new Error(`Could not create a new bucket: '${err.message}'`)); else { var newBucket = null; var newEntry = { @@ -247,13 +259,13 @@ var BucketManager = (function () { return reject(err); }); }); - }; + } /** * Attempts to remove buckets of the given search result. This will also update the file and stats collection. * @param {any} searchQuery A valid mongodb search query * @returns {Promise} An array of ID's of the buckets removed */ - BucketManager.prototype.removeBuckets = function (searchQuery) { + removeBuckets(searchQuery) { var that = this; var gcs = this._gcs; var bucketCollection = this._buckets; @@ -280,7 +292,7 @@ var BucketManager = (function () { error = err; attempts++; if (attempts == l) - reject(new Error("Could not delete bucket: " + error.message)); + reject(new Error(`Could not delete bucket: ${error.message}`)); }); } // If no buckets @@ -290,14 +302,14 @@ var BucketManager = (function () { return reject(err); }); }); - }; + } /** * Attempts to remove buckets by id * @param {Array} buckets An array of bucket IDs to remove * @param {string} user The user to whome these buckets belong * @returns {Promise} An array of ID's of the buckets removed */ - BucketManager.prototype.removeBucketsByName = function (buckets, user) { + removeBucketsByName(buckets, user) { if (buckets.length == 0) return Promise.resolve([]); // Create the search query for each of the files @@ -305,19 +317,19 @@ var BucketManager = (function () { for (var i = 0, l = buckets.length; i < l; i++) searchQuery.$or.push({ name: buckets[i] }); return this.removeBuckets(searchQuery); - }; + } /** * Attempts to remove a user bucket * @param {string} user The user associated with this bucket * @returns {Promise} An array of ID's of the buckets removed */ - BucketManager.prototype.removeBucketsByUser = function (user) { + removeBucketsByUser(user) { return this.removeBuckets({ user: user }); - }; + } /** * Deletes the bucket from storage and updates the databases */ - BucketManager.prototype.deleteBucket = function (bucketEntry) { + deleteBucket(bucketEntry) { var that = this; var gcs = this._gcs; var bucketCollection = this._buckets; @@ -332,7 +344,7 @@ var BucketManager = (function () { // If there is an error then return - but not if the file is not found. More than likely // it was removed by an admin if (err && err.code != 404) - return reject(new Error("Could not remove bucket from storage system: '" + err.message + "'")); + return reject(new Error(`Could not remove bucket from storage system: '${err.message}'`)); else { // Remove the bucket entry bucketCollection.deleteOne({ _id: bucketEntry._id }).then(function (deleteResult) { @@ -345,14 +357,14 @@ var BucketManager = (function () { } }); }).catch(function (err) { - return reject("Could not remove the bucket: '" + err.toString() + "'"); + return reject(`Could not remove the bucket: '${err.toString()}'`); }); }); - }; + } /** * Deletes the file from storage and updates the databases */ - BucketManager.prototype.deleteFile = function (fileEntry) { + deleteFile(fileEntry) { var that = this; var gcs = this._gcs; var bucketCollection = this._buckets; @@ -361,14 +373,14 @@ var BucketManager = (function () { return new Promise(function (resolve, reject) { that.getIBucket(fileEntry.bucketId).then(function (bucketEntry) { if (!bucketEntry) - return reject(new Error("Could not find the bucket '" + fileEntry.bucketName + "'")); + return reject(new Error(`Could not find the bucket '${fileEntry.bucketName}'`)); var bucket = gcs.bucket(bucketEntry.identifier); // Get the bucket and delete the file bucket.file(fileEntry.identifier).delete(function (err, apiResponse) { // If there is an error then return - but not if the file is not found. More than likely // it was removed by an admin if (err && err.code != 404) - return reject(new Error("Could not remove file '" + fileEntry.identifier + "' from storage system: '" + err.toString() + "'")); + return reject(new Error(`Could not remove file '${fileEntry.identifier}' from storage system: '${err.toString()}'`)); // Update the bucket data usage bucketCollection.updateOne({ identifier: bucketEntry.identifier }, { $inc: { memoryUsed: -fileEntry.size } }).then(function (result) { return files.deleteOne({ _id: fileEntry._id }); @@ -377,7 +389,7 @@ var BucketManager = (function () { }).then(function (result) { return resolve(fileEntry); }).catch(function (err) { - return reject("Could not remove file '" + fileEntry.identifier + "' from storage system: '" + err.toString() + "'"); + return reject(`Could not remove file '${fileEntry.identifier}' from storage system: '${err.toString()}'`); }); }); }).catch(function (err) { @@ -385,13 +397,13 @@ var BucketManager = (function () { return reject(err); }); }); - }; + } /** * Attempts to remove files from the cloud and database by a query * @param {any} searchQuery The query we use to select the files * @returns {Promise} Returns the file IDs of the files removed */ - BucketManager.prototype.removeFiles = function (searchQuery) { + removeFiles(searchQuery) { var that = this; var gcs = this._gcs; var bucketCollection = this._buckets; @@ -429,14 +441,14 @@ var BucketManager = (function () { return reject(err); }); }); - }; + } /** * Attempts to remove files from the cloud and database * @param {Array} fileIDs The file IDs to remove * @param {string} user Optionally pass in the user to refine the search * @returns {Promise} Returns the file IDs of the files removed */ - BucketManager.prototype.removeFilesById = function (fileIDs, user) { + removeFilesById(fileIDs, user) { if (fileIDs.length == 0) return Promise.resolve([]); // Create the search query for each of the files @@ -446,26 +458,26 @@ var BucketManager = (function () { if (user) searchQuery.user = user; return this.removeFiles(searchQuery); - }; + } /** * Attempts to remove files from the cloud and database that are in a given bucket * @param {string} bucket The id or name of the bucket to remove * @returns {Promise} Returns the file IDs of the files removed */ - BucketManager.prototype.removeFilesByBucket = function (bucket) { + removeFilesByBucket(bucket) { if (!bucket || bucket.trim() == "") return Promise.reject(new Error("Please specify a valid bucket")); // Create the search query for each of the files var searchQuery = { $or: [{ bucketId: bucket }, { bucketName: bucket }] }; return this.removeFiles(searchQuery); - }; + } /** * Gets a bucket entry by its name or ID * @param {string} bucket The id of the bucket. You can also use the name if you provide the user * @param {string} user The username associated with the bucket (Only applicable if bucket is a name and not an ID) * @returns {IBucketEntry} */ - BucketManager.prototype.getIBucket = function (bucket, user) { + getIBucket(bucket, user) { var that = this; var bucketCollection = this._buckets; var searchQuery = {}; @@ -485,14 +497,14 @@ var BucketManager = (function () { return reject(err); }); }); - }; + } /** * Checks to see the user's storage limits to see if they are allowed to upload data * @param {string} user The username * @param {Part} part * @returns {Promise} */ - BucketManager.prototype.canUpload = function (user, part) { + canUpload(user, part) { var that = this; var bucketCollection = this._buckets; var stats = this._stats; @@ -510,19 +522,19 @@ var BucketManager = (function () { return reject(err); }); }); - }; + } /** * Checks to see the user's api limit and make sure they can make calls * @param {string} user The username * @returns {Promise} */ - BucketManager.prototype.withinAPILimit = function (user) { + withinAPILimit(user) { var that = this; var stats = this._stats; return new Promise(function (resolve, reject) { stats.find({ user: user }).limit(1).next().then(function (result) { if (!result) - return reject(new Error("Could not find the user " + user)); + return reject(new Error(`Could not find the user ${user}`)); else if (result.apiCallsUsed + 1 < result.apiCallsAllocated) resolve(true); else @@ -531,13 +543,13 @@ var BucketManager = (function () { return reject(err); }); }); - }; + } /** * Adds an API call to a user * @param {string} user The username * @returns {Promise} */ - BucketManager.prototype.incrementAPI = function (user) { + incrementAPI(user) { var that = this; var stats = this._stats; return new Promise(function (resolve, reject) { @@ -547,13 +559,13 @@ var BucketManager = (function () { return reject(err); }); }); - }; + } /** * Makes a file publicly available * @param {IFileEntry} file * @returns {Promise} */ - BucketManager.prototype.makeFilePublic = function (file) { + makeFilePublic(file) { var that = this; return new Promise(function (resolve, reject) { that.withinAPILimit(file.user).then(function (val) { @@ -576,13 +588,13 @@ var BucketManager = (function () { return reject(new err); }); }); - }; + } /** * Makes a file private * @param {IFileEntry} file * @returns {Promise} */ - BucketManager.prototype.makeFilePrivate = function (file) { + makeFilePrivate(file) { var that = this; return new Promise(function (resolve, reject) { that.withinAPILimit(file.user).then(function (val) { @@ -605,7 +617,7 @@ var BucketManager = (function () { return reject(new err); }); }); - }; + } /** * Registers an uploaded part as a new user file in the local dbs * @param {string} fileID The id of the file on the bucket @@ -616,7 +628,7 @@ var BucketManager = (function () { * @param {string} parentFile Sets an optional parent file - if the parent is removed, then so is this one * @returns {Promise} */ - BucketManager.prototype.registerFile = function (fileID, bucket, part, user, isPublic, parentFile) { + registerFile(fileID, bucket, part, user, isPublic, parentFile) { var that = this; var gcs = this._gcs; var files = this._files; @@ -632,23 +644,23 @@ var BucketManager = (function () { numDownloads: 0, size: part.byteCount, isPublic: isPublic, - publicURL: "https://storage.googleapis.com/" + bucket.identifier + "/" + fileID, + publicURL: `https://storage.googleapis.com/${bucket.identifier}/${fileID}`, mimeType: part.headers["content-type"] }; files.insertOne(entry).then(function (insertResult) { return resolve(insertResult.ops[0]); }).catch(function (err) { - return reject(new Error("Could not save user file entry: " + err.toString())); + return reject(new Error(`Could not save user file entry: ${err.toString()}`)); }); }); - }; - BucketManager.prototype.generateRandString = function (len) { + } + generateRandString(len) { var text = ""; var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; for (var i = 0; i < len; i++) text += possible.charAt(Math.floor(Math.random() * possible.length)); return text; - }; + } /** * Uploads a part stream as a new user file. This checks permissions, updates the local db and uploads the stream to the bucket * @param {Part} part @@ -658,8 +670,7 @@ var BucketManager = (function () { * @param {string} parentFile [Optional] Set a parent file which when deleted will detelete this upload as well * @returns {Promise} */ - BucketManager.prototype.uploadStream = function (part, bucketEntry, user, makePublic, parentFile) { - if (makePublic === void 0) { makePublic = true; } + uploadStream(part, bucketEntry, user, makePublic = true, parentFile) { var that = this; var gcs = this._gcs; var bucketCollection = this._buckets; @@ -677,9 +688,9 @@ var BucketManager = (function () { // Delete the file on the bucket rawFile.delete(function (bucketErr, apiResponse) { if (bucketErr) - return reject(new Error("While uploading a user part an error occurred while cleaning the bucket: " + bucketErr.toString())); + return reject(new Error(`While uploading a user part an error occurred while cleaning the bucket: ${bucketErr.toString()}`)); else - return reject(new Error("Could not upload a user part: " + err.toString())); + return reject(new Error(`Could not upload a user part: ${err.toString()}`)); }); }); var stream; @@ -691,7 +702,7 @@ var BucketManager = (function () { stream = part.pipe(rawFile.createWriteStream({ metadata: { contentType: part.headers["content-type"] } })); // Pipe the file to the bucket stream.on("error", function (err) { - return reject(new Error("Could not upload the file '" + part.filename + "' to bucket: " + err.toString())); + return reject(new Error(`Could not upload the file '${part.filename}' to bucket: ${err.toString()}`)); }).on('finish', function () { bucketCollection.updateOne({ identifier: bucketEntry.identifier }, { $inc: { memoryUsed: part.byteCount } }).then(function (updateResult) { return statCollection.updateOne({ user: user }, { $inc: { memoryUsed: part.byteCount, apiCallsUsed: 1 } }); @@ -716,7 +727,7 @@ var BucketManager = (function () { return reject(err); }); }); - }; + } /** * Fetches a file by its ID * @param {string} fileID The file ID of the file on the bucket @@ -724,7 +735,7 @@ var BucketManager = (function () { * @param {RegExp} searchTerm Specify a search term * @returns {Promise} */ - BucketManager.prototype.getFile = function (fileID, user, searchTerm) { + getFile(fileID, user, searchTerm) { var that = this; var gcs = this._gcs; var files = this._files; @@ -736,21 +747,21 @@ var BucketManager = (function () { searchQuery.name = searchTerm; files.find(searchQuery).limit(1).next().then(function (result) { if (!result) - return reject("File '" + fileID + "' does not exist"); + return reject(`File '${fileID}' does not exist`); else return resolve(result); }).catch(function (err) { return reject(err); }); }); - }; + } /** * Renames a file * @param {string} file The file to rename * @param {string} name The new name of the file * @returns {Promise} */ - BucketManager.prototype.renameFile = function (file, name) { + renameFile(file, name) { var that = this; var gcs = this._gcs; var files = this._files; @@ -763,7 +774,7 @@ var BucketManager = (function () { }); }); }); - }; + } /** * Downloads the data from the cloud and sends it to the requester. This checks the request for encoding and * sets the appropriate headers if and when supported @@ -771,7 +782,7 @@ var BucketManager = (function () { * @param {Response} response The response stream to return the data * @param {IFileEntry} file The file to download */ - BucketManager.prototype.downloadFile = function (request, response, file) { + downloadFile(request, response, file) { var that = this; var gcs = this._gcs; var buckets = this._buckets; @@ -817,44 +828,39 @@ var BucketManager = (function () { stream.pipe(response); } }); - }; + } /** * Finds and downloads a file * @param {string} fileID The file ID of the file on the bucket * @returns {Promise} Returns the number of results affected */ - BucketManager.prototype.updateStorage = function (user, value) { + updateStorage(user, value) { var that = this; var stats = this._stats; return new Promise(function (resolve, reject) { stats.updateOne({ user: user }, { $set: value }).then(function (updateResult) { if (updateResult.matchedCount === 0) - return reject("Could not find user '" + user + "'"); + return reject(`Could not find user '${user}'`); else return resolve(updateResult.modifiedCount); }).catch(function (err) { return reject(err); }); }); - }; + } /** * Creates the bucket manager singleton */ - BucketManager.create = function (buckets, files, stats, config) { + static create(buckets, files, stats, config) { return new BucketManager(buckets, files, stats, config); - }; - Object.defineProperty(BucketManager, "get", { - /** - * Gets the bucket singleton - */ - get: function () { - return BucketManager._singleton; - }, - enumerable: true, - configurable: true - }); - BucketManager.MEMORY_ALLOCATED = 5e+8; //500mb - BucketManager.API_CALLS_ALLOCATED = 20000; //20,000 - return BucketManager; -})(); + } + /** + * Gets the bucket singleton + */ + static get get() { + return BucketManager._singleton; + } +} +BucketManager.MEMORY_ALLOCATED = 5e+8; //500mb +BucketManager.API_CALLS_ALLOCATED = 20000; //20,000 exports.BucketManager = BucketManager; diff --git a/dist/controllers/bucket-controller.js b/dist/controllers/bucket-controller.js index 83bcd04..949426d 100644 --- a/dist/controllers/bucket-controller.js +++ b/dist/controllers/bucket-controller.js @@ -1,8 +1,16 @@ "use strict"; -var __extends = (this && this.__extends) || function (d, b) { - for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promise, generator) { + return new Promise(function (resolve, reject) { + generator = generator.call(thisArg, _arguments); + function cast(value) { return value instanceof Promise && value.constructor === Promise ? value : new Promise(function (resolve) { resolve(value); }); } + function onfulfill(value) { try { step("next", value); } catch (e) { reject(e); } } + function onreject(value) { try { step("throw", value); } catch (e) { reject(e); } } + function step(verb, value) { + var result = generator[verb](value); + result.done ? resolve(result.value) : cast(result.value).then(onfulfill, onreject); + } + step("next", void 0); + }); }; var express = require("express"); var bodyParser = require('body-parser'); @@ -19,16 +27,15 @@ var socket_event_types_1 = require("../socket-event-types"); /** * Main class to use for managing users */ -var BucketController = (function (_super) { - __extends(BucketController, _super); +class BucketController extends controller_1.Controller { /** * Creates an instance of the user manager * @param {mongodb.Collection} userCollection The mongo collection that stores the users * @param {mongodb.Collection} sessionCollection The mongo collection that stores the session data * @param {def.IConfig} The config options of this manager */ - function BucketController(e, config) { - _super.call(this); + constructor(e, config) { + super(); this._config = config; this._allowedFileTypes = ["image/bmp", "image/png", "image/jpeg", "image/jpg", "image/gif", "image/tiff", "text/plain", "text/json", "application/octet-stream"]; // Setup the rest calls @@ -54,7 +61,7 @@ var BucketController = (function (_super) { router.put("/files/:id/make-public", [permission_controller_1.requireUser, this.makePublic.bind(this)]); router.put("/files/:id/make-private", [permission_controller_1.requireUser, this.makePrivate.bind(this)]); // Register the path - e.use("" + config.apiPrefix, router); + e.use(`${config.apiPrefix}`, router); } /** * Makes sure the target user exists and the numeric value specified is valid @@ -62,7 +69,7 @@ var BucketController = (function (_super) { * @param {express.Response} res * @param {Function} next */ - BucketController.prototype.verifyTargetValue = function (req, res, next) { + verifyTargetValue(req, res, next) { // Set the content type var value = parseInt(req.params.value); if (!req.params.target || req.params.target.trim() == "") { @@ -77,7 +84,7 @@ var BucketController = (function (_super) { users_1.UserManager.get.getUser(req.params.target).then(function (user) { if (!user) { res.setHeader('Content-Type', 'application/json'); - return res.end(JSON.stringify({ message: "Could not find the user '" + req.params.target + "'", error: true })); + return res.end(JSON.stringify({ message: `Could not find the user '${req.params.target}'`, error: true })); } else { req._target = user; @@ -87,86 +94,86 @@ var BucketController = (function (_super) { res.setHeader('Content-Type', 'application/json'); return res.end(JSON.stringify({ message: err.toString(), error: true })); }); - }; + } /** * Updates the target user's api calls * @param {express.Request} req * @param {express.Response} res * @param {Function} next */ - BucketController.prototype.updateCalls = function (req, res, next) { + updateCalls(req, res, next) { // Set the content type res.setHeader('Content-Type', 'application/json'); var value = parseInt(req.params.value); var manager = bucket_manager_1.BucketManager.get; manager.updateStorage(req._target.dbEntry.username, { apiCallsUsed: value }).then(function () { - return res.end(JSON.stringify({ message: "Updated the user API calls to [" + value + "]", error: false })); + return res.end(JSON.stringify({ message: `Updated the user API calls to [${value}]`, error: false })); }).catch(function (err) { winston.error(err.toString(), { process: process.pid }); return res.end(JSON.stringify({ message: err.toString(), error: true })); }); - }; + } /** * Updates the target user's memory usage * @param {express.Request} req * @param {express.Response} res * @param {Function} next */ - BucketController.prototype.updateMemory = function (req, res, next) { + updateMemory(req, res, next) { // Set the content type res.setHeader('Content-Type', 'application/json'); var value = parseInt(req.params.value); var manager = bucket_manager_1.BucketManager.get; manager.updateStorage(req._target.dbEntry.username, { memoryUsed: value }).then(function () { - return res.end(JSON.stringify({ message: "Updated the user memory to [" + value + "] bytes", error: false })); + return res.end(JSON.stringify({ message: `Updated the user memory to [${value}] bytes`, error: false })); }).catch(function (err) { winston.error(err.toString(), { process: process.pid }); return res.end(JSON.stringify({ message: err.toString(), error: true })); }); - }; + } /** * Updates the target user's allocated api calls * @param {express.Request} req * @param {express.Response} res * @param {Function} next */ - BucketController.prototype.updateAllocatedCalls = function (req, res, next) { + updateAllocatedCalls(req, res, next) { // Set the content type res.setHeader('Content-Type', 'application/json'); var value = parseInt(req.params.value); var manager = bucket_manager_1.BucketManager.get; manager.updateStorage(req._target.dbEntry.username, { apiCallsAllocated: value }).then(function () { - return res.end(JSON.stringify({ message: "Updated the user API calls to [" + value + "]", error: false })); + return res.end(JSON.stringify({ message: `Updated the user API calls to [${value}]`, error: false })); }).catch(function (err) { winston.error(err.toString(), { process: process.pid }); return res.end(JSON.stringify({ message: err.toString(), error: true })); }); - }; + } /** * Updates the target user's allocated memory * @param {express.Request} req * @param {express.Response} res * @param {Function} next */ - BucketController.prototype.updateAllocatedMemory = function (req, res, next) { + updateAllocatedMemory(req, res, next) { // Set the content type res.setHeader('Content-Type', 'application/json'); var value = parseInt(req.params.value); var manager = bucket_manager_1.BucketManager.get; manager.updateStorage(req._target.dbEntry.username, { memoryAllocated: value }).then(function () { - return res.end(JSON.stringify({ message: "Updated the user memory to [" + value + "] bytes", error: false })); + return res.end(JSON.stringify({ message: `Updated the user memory to [${value}] bytes`, error: false })); }).catch(function (err) { winston.error(err.toString(), { process: process.pid }); return res.end(JSON.stringify({ message: err.toString(), error: true })); }); - }; + } /** * Removes files specified in the URL * @param {express.Request} req * @param {express.Response} res * @param {Function} next */ - BucketController.prototype.removeFiles = function (req, res, next) { + removeFiles(req, res, next) { // Set the content type res.setHeader('Content-Type', 'application/json'); var manager = bucket_manager_1.BucketManager.get; @@ -176,7 +183,7 @@ var BucketController = (function (_super) { files = req.params.files.split(","); manager.removeFilesById(files, req._user.dbEntry.username).then(function (numRemoved) { return res.end(JSON.stringify({ - message: "Removed [" + numRemoved.length + "] files", + message: `Removed [${numRemoved.length}] files`, error: false, data: numRemoved })); @@ -187,14 +194,14 @@ var BucketController = (function (_super) { error: true })); }); - }; + } /** * Renames a file * @param {express.Request} req * @param {express.Response} res * @param {Function} next */ - BucketController.prototype.renameFile = function (req, res, next) { + renameFile(req, res, next) { // Set the content type res.setHeader('Content-Type', 'application/json'); var manager = bucket_manager_1.BucketManager.get; @@ -204,11 +211,11 @@ var BucketController = (function (_super) { return res.end(JSON.stringify({ message: "Please specify the new name of the file", error: true })); manager.getFile(req.params.file, req._user.dbEntry.username).then(function (file) { if (!file) - return Promise.reject(new Error("Could not find the file '" + req.params.file + "'")); + return Promise.reject(new Error(`Could not find the file '${req.params.file}'`)); return manager.renameFile(file, req.body.name); }).then(function (file) { return res.end(JSON.stringify({ - message: "Renamed file to '" + req.body.name + "'", + message: `Renamed file to '${req.body.name}'`, error: false })); }).catch(function (err) { @@ -218,14 +225,14 @@ var BucketController = (function (_super) { error: true })); }); - }; + } /** * Removes buckets specified in the URL * @param {express.Request} req * @param {express.Response} res * @param {Function} next */ - BucketController.prototype.removeBuckets = function (req, res, next) { + removeBuckets(req, res, next) { // Set the content type res.setHeader('Content-Type', 'application/json'); var manager = bucket_manager_1.BucketManager.get; @@ -235,7 +242,7 @@ var BucketController = (function (_super) { buckets = req.params.buckets.split(","); manager.removeBucketsByName(buckets, req._user.dbEntry.username).then(function (numRemoved) { return res.end(JSON.stringify({ - message: "Removed [" + numRemoved.length + "] buckets", + message: `Removed [${numRemoved.length}] buckets`, error: false, data: numRemoved })); @@ -246,20 +253,20 @@ var BucketController = (function (_super) { error: true })); }); - }; + } /** * Fetches the statistic information for the specified user * @param {express.Request} req * @param {express.Response} res * @param {Function} next */ - BucketController.prototype.getStats = function (req, res, next) { + getStats(req, res, next) { // Set the content type res.setHeader('Content-Type', 'application/json'); var manager = bucket_manager_1.BucketManager.get; manager.getUserStats(req._user.dbEntry.username).then(function (stats) { return res.end(JSON.stringify({ - message: "Successfully retrieved " + req._user.dbEntry.username + "'s stats", + message: `Successfully retrieved ${req._user.dbEntry.username}'s stats`, error: false, data: stats })); @@ -270,20 +277,20 @@ var BucketController = (function (_super) { error: true })); }); - }; + } /** * Attempts to download a file from the server * @param {express.Request} req * @param {express.Response} res * @param {Function} next */ - BucketController.prototype.getFile = function (req, res, next) { + getFile(req, res, next) { var manager = bucket_manager_1.BucketManager.get; var fileID = req.params.id; var file = null; var cache = this._config.google.bucket.cacheLifetime; if (!fileID || fileID.trim() == "") - return res.end(JSON.stringify({ message: "Please specify a file ID", error: true })); + return res.end(JSON.stringify({ message: `Please specify a file ID`, error: true })); manager.getFile(fileID).then(function (iFile) { file = iFile; res.setHeader('Content-Type', file.mimeType); @@ -296,25 +303,25 @@ var BucketController = (function (_super) { winston.error(err.toString(), { process: process.pid }); return res.status(404).send('File not found'); }); - }; + } /** * Attempts to make a file public * @param {express.Request} req * @param {express.Response} res * @param {Function} next */ - BucketController.prototype.makePublic = function (req, res, next) { + makePublic(req, res, next) { res.setHeader('Content-Type', 'application/json'); var manager = bucket_manager_1.BucketManager.get; var fileID = req.params.id; var file = null; var cache = this._config.google.bucket.cacheLifetime; if (!fileID || fileID.trim() == "") - return res.end(JSON.stringify({ message: "Please specify a file ID", error: true })); + return res.end(JSON.stringify({ message: `Please specify a file ID`, error: true })); manager.getFile(fileID, req._user.dbEntry.username).then(function (iFile) { return manager.makeFilePublic(iFile); }).then(function (iFile) { - return res.end(JSON.stringify({ message: "File is now public", error: false, data: iFile })); + return res.end(JSON.stringify({ message: `File is now public`, error: false, data: iFile })); }).catch(function (err) { winston.error(err.toString(), { process: process.pid }); return res.end(JSON.stringify({ @@ -322,25 +329,25 @@ var BucketController = (function (_super) { error: true })); }); - }; + } /** * Attempts to make a file private * @param {express.Request} req * @param {express.Response} res * @param {Function} next */ - BucketController.prototype.makePrivate = function (req, res, next) { + makePrivate(req, res, next) { res.setHeader('Content-Type', 'application/json'); var manager = bucket_manager_1.BucketManager.get; var fileID = req.params.id; var file = null; var cache = this._config.google.bucket.cacheLifetime; if (!fileID || fileID.trim() == "") - return res.end(JSON.stringify({ message: "Please specify a file ID", error: true })); + return res.end(JSON.stringify({ message: `Please specify a file ID`, error: true })); manager.getFile(fileID, req._user.dbEntry.username).then(function (iFile) { return manager.makeFilePrivate(iFile); }).then(function (iFile) { - return res.end(JSON.stringify({ message: "File is now private", error: false, data: iFile })); + return res.end(JSON.stringify({ message: `File is now private`, error: false, data: iFile })); }).catch(function (err) { winston.error(err.toString(), { process: process.pid }); return res.end(JSON.stringify({ @@ -348,14 +355,14 @@ var BucketController = (function (_super) { error: true })); }); - }; + } /** * Fetches all file entries from the database. Optionally specifying the bucket to fetch from. * @param {express.Request} req * @param {express.Response} res * @param {Function} next */ - BucketController.prototype.getFiles = function (req, res, next) { + getFiles(req, res, next) { // Set the content type res.setHeader('Content-Type', 'application/json'); var manager = bucket_manager_1.BucketManager.get; @@ -371,7 +378,7 @@ var BucketController = (function (_super) { searchTerm = new RegExp(req.query.search, "i"); manager.getIBucket(req.params.bucket, req._user.dbEntry.username).then(function (bucket) { if (!bucket) - return Promise.reject(new Error("Could not find the bucket '" + req.params.bucket + "'")); + return Promise.reject(new Error(`Could not find the bucket '${req.params.bucket}'`)); bucketEntry = bucket; return manager.numFiles({ bucketId: bucket.identifier }); }).then(function (count) { @@ -379,7 +386,7 @@ var BucketController = (function (_super) { return manager.getFilesByBucket(bucketEntry, index, limit, searchTerm); }).then(function (files) { return res.end(JSON.stringify({ - message: "Found [" + numFiles + "] files", + message: `Found [${numFiles}] files`, error: false, data: files, count: numFiles @@ -391,14 +398,14 @@ var BucketController = (function (_super) { error: true })); }); - }; + } /** * Fetches all bucket entries from the database * @param {express.Request} req * @param {express.Response} res * @param {Function} next */ - BucketController.prototype.getBuckets = function (req, res, next) { + getBuckets(req, res, next) { var user = req.params.user; // Set the content type res.setHeader('Content-Type', 'application/json'); @@ -410,7 +417,7 @@ var BucketController = (function (_super) { searchTerm = new RegExp(req.query.search, "i"); manager.getBucketEntries(user, searchTerm).then(function (buckets) { return res.end(JSON.stringify({ - message: "Found [" + buckets.length + "] buckets", + message: `Found [${buckets.length}] buckets`, error: false, data: buckets, count: buckets.length @@ -422,20 +429,20 @@ var BucketController = (function (_super) { error: true })); }); - }; + } /** * Creates a new user stat entry. This is usually done for you when creating a new user * @param {express.Request} req * @param {express.Response} res * @param {Function} next */ - BucketController.prototype.createStats = function (req, res, next) { + createStats(req, res, next) { // Set the content type res.setHeader('Content-Type', 'application/json'); var manager = bucket_manager_1.BucketManager.get; manager.createUserStats(req.params.target).then(function (stats) { return res.end(JSON.stringify({ - message: "Stats for the user '" + req.params.target + "' have been created", + message: `Stats for the user '${req.params.target}' have been created`, error: false })); }).catch(function (err) { @@ -445,20 +452,20 @@ var BucketController = (function (_super) { error: true })); }); - }; - BucketController.prototype.alphaNumericDashSpace = function (str) { + } + alphaNumericDashSpace(str) { if (!str.match(/^[0-9A-Z _\-]+$/i)) return false; else return true; - }; + } /** * Creates a new user bucket based on the target provided * @param {express.Request} req * @param {express.Response} res * @param {Function} next */ - BucketController.prototype.createBucket = function (req, res, next) { + createBucket(req, res, next) { // Set the content type res.setHeader('Content-Type', 'application/json'); var manager = bucket_manager_1.BucketManager.get; @@ -474,14 +481,14 @@ var BucketController = (function (_super) { if (user) return manager.withinAPILimit(username); else - return Promise.reject(new Error("Could not find a user with the name '" + username + "'")); + return Promise.reject(new Error(`Could not find a user with the name '${username}'`)); }).then(function (inLimits) { if (!inLimits) - return Promise.reject(new Error("You have run out of API calls, please contact one of our sales team or upgrade your account.")); + return Promise.reject(new Error(`You have run out of API calls, please contact one of our sales team or upgrade your account.`)); return manager.createBucket(bucketName, username); }).then(function (bucket) { return res.end(JSON.stringify({ - message: "Bucket '" + bucketName + "' created", + message: `Bucket '${bucketName}' created`, error: false })); }).catch(function (err) { @@ -491,12 +498,12 @@ var BucketController = (function (_super) { error: true })); }); - }; + } /** * Checks if a part is allowed to be uploaded * @returns {boolean} */ - BucketController.prototype.isPartAllowed = function (part) { + isPartAllowed(part) { if (!part.headers) return false; if (!part.headers["content-type"]) @@ -507,12 +514,12 @@ var BucketController = (function (_super) { return true; else return false; - }; + } /** * Checks if a file part is allowed to be uploaded * @returns {boolean} */ - BucketController.prototype.isFileTypeAllowed = function (part) { + isFileTypeAllowed(part) { if (!part.headers) return false; if (!part.headers["content-type"]) @@ -528,14 +535,14 @@ var BucketController = (function (_super) { if (!found) return false; return true; - }; + } /** * Attempts to upload a file to the user's bucket * @param {express.Request} req * @param {express.Response} res * @param {Function} next */ - BucketController.prototype.uploadUserFiles = function (req, res, next) { + uploadUserFiles(req, res, next) { var form = new multiparty.Form({ maxFields: 8, maxFieldsSize: 5 * 1024 * 1024, maxFilesSize: 10 * 1024 * 1024 }); var successfulParts = 0; var numParts = 0; @@ -551,11 +558,11 @@ var BucketController = (function (_super) { res.setHeader('Content-Type', 'application/json'); var bucketName = req.params.bucket; if (!bucketName || bucketName.trim() == "") - return res.end(JSON.stringify({ message: "Please specify a bucket", error: true, tokens: [] })); + return res.end(JSON.stringify({ message: `Please specify a bucket`, error: true, tokens: [] })); manager.getIBucket(bucketName, username).then(function (bucketEntry) { if (!bucketEntry) { - winston.error("No bucket exists with the name '" + bucketName + "'", { process: process.pid }); - return res.end(JSON.stringify({ message: "No bucket exists with the name '" + bucketName + "'", error: true, tokens: [] })); + winston.error(`No bucket exists with the name '${bucketName}'`, { process: process.pid }); + return res.end(JSON.stringify({ message: `No bucket exists with the name '${bucketName}'`, error: true, tokens: [] })); } var metaJson; // Parts are emitted when parsing the form @@ -583,7 +590,7 @@ var BucketController = (function (_super) { if (!that.isFileTypeAllowed(part)) { numParts++; uploadedTokens.push(newUpload); - errFunc("Please only use approved file types '" + that._allowedFileTypes.join(", ") + "'"); + errFunc(`Please only use approved file types '${that._allowedFileTypes.join(", ")}'`); return; } // Add the token to the upload array we are sending back to the user @@ -675,7 +682,7 @@ var BucketController = (function (_super) { return promise; }).then(function (val) { var error = false; - var msg = "Upload complete. [" + successfulParts + "] Files have been saved."; + var msg = `Upload complete. [${successfulParts}] Files have been saved.`; for (var i = 0, l = uploadedTokens.length; i < l; i++) if (uploadedTokens[i].error) { error = true; @@ -705,14 +712,14 @@ var BucketController = (function (_super) { winston.error("Could not get bucket: " + err.toString(), { process: process.pid }); return res.end(JSON.stringify({ message: "Could not get bucket: " + err.toString(), error: true, tokens: [] })); }); - }; + } /** * Attempts to upload a file to the user's bucket * @param {express.Request} req * @param {express.Response} res * @param {Function} next */ - BucketController.prototype.uploadUserData = function (req, res, next) { + uploadUserData(req, res, next) { var form = new multiparty.Form(); var count = 0; // Parts are emitted when parsing the form @@ -752,12 +759,12 @@ var BucketController = (function (_super) { }); // Parse req form.parse(req); - }; + } /** * Called to initialize this controller and its related database objects * @returns {Promise} */ - BucketController.prototype.initialize = function (db) { + initialize(db) { var that = this; return new Promise(function (resolve, reject) { var bucketsCollection; @@ -792,7 +799,6 @@ var BucketController = (function (_super) { reject(error); }); }); - }; - return BucketController; -})(controller_1.Controller); + } +} exports.BucketController = BucketController; diff --git a/dist/controllers/comms-controller.js b/dist/controllers/comms-controller.js index fa3baeb..a1527b1 100644 --- a/dist/controllers/comms-controller.js +++ b/dist/controllers/comms-controller.js @@ -1,9 +1,4 @@ "use strict"; -var __extends = (this && this.__extends) || function (d, b) { - for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); -}; var ws = require("ws"); var events = require("events"); var https = require("https"); @@ -17,21 +12,20 @@ var socket_api_1 = require("../socket-api"); * This wraps data around events sent via the web socket to the users server. Optionally * these events can respond to the client who initiated the event as well as to all listeners. */ -var ClientEvent = (function () { - function ClientEvent(event, client) { +class ClientEvent { + constructor(event, client) { this.client = client; this.error = null; this.clientEvent = event; this.responseType = socket_event_types_1.EventResponseType.NoResponse; } - return ClientEvent; -})(); +} exports.ClientEvent = ClientEvent; /** * A wrapper class for client connections made to the CommsController */ -var ClientConnection = (function () { - function ClientConnection(ws, domain, controller) { +class ClientConnection { + constructor(ws, domain, controller) { var that = this; this.domain = domain; this._controller = controller; @@ -48,47 +42,45 @@ var ClientConnection = (function () { * Called whenever we recieve a message from a client * @param {string|any} message */ - ClientConnection.prototype.onMessage = function (message) { - winston.info("Received message from client: '" + message + "'", { process: process.pid }); + onMessage(message) { + winston.info(`Received message from client: '${message}'`, { process: process.pid }); try { var event = JSON.parse(message); this._controller.alertMessage(new ClientEvent(event, this)); } catch (err) { - winston.error("Could not parse socket message: '" + err + "'", { process: process.pid }); + winston.error(`Could not parse socket message: '${err}'`, { process: process.pid }); } - }; + } /** * Called whenever a client disconnnects */ - ClientConnection.prototype.onClose = function () { + onClose() { this.ws.removeAllListeners("message"); this.ws.removeAllListeners("close"); this.ws.removeAllListeners("error"); this.ws.clientConnection = null; this.ws = null; this._controller = null; - }; + } /** * Called whenever an error has occurred * @param {Error} err */ - ClientConnection.prototype.onError = function (err) { - winston.error("An error has occurred for web socket : '" + err.message + "'", { process: process.pid }); - }; - return ClientConnection; -})(); + onError(err) { + winston.error(`An error has occurred for web socket : '${err.message}'`, { process: process.pid }); + } +} /** * A controller that deals with any any IPC or web socket communications */ -var CommsController = (function (_super) { - __extends(CommsController, _super); +class CommsController extends events.EventEmitter { /** * Creates an instance of the Communication server * @param {IConfig} cfg */ - function CommsController(cfg) { - _super.call(this); + constructor(cfg) { + super(); var that = this; CommsController.singleton = this; // dummy request processing - this is not actually called as its handed off to the socket api @@ -102,7 +94,7 @@ var CommsController = (function (_super) { var caChain = [fs.readFileSync(cfg.sslIntermediate), fs.readFileSync(cfg.sslRoot)]; var privkey = cfg.sslKey ? fs.readFileSync(cfg.sslKey) : null; var theCert = cfg.sslCert ? fs.readFileSync(cfg.sslCert) : null; - winston.info("Attempting to start Websocket server with SSL...", { process: process.pid }); + winston.info(`Attempting to start Websocket server with SSL...`, { process: process.pid }); httpsServer = https.createServer({ key: privkey, cert: theCert, passphrase: cfg.sslPassPhrase, ca: caChain }, processRequest); httpsServer.listen(cfg.websocket.port); this._server = new ws.Server({ server: httpsServer }); @@ -126,7 +118,7 @@ var CommsController = (function (_super) { } } if (!clientApproved) { - winston.error("A connection was made by " + (headers.host || headers.origin) + " but it is not on the approved domain list"); + winston.error(`A connection was made by ${headers.host || headers.origin} but it is not on the approved domain list`); ws.terminate(); ws.close(); } @@ -138,38 +130,38 @@ var CommsController = (function (_super) { * Sends an event to all connected clients of this server listening for a specific event * @param {ClientEvent} event The event to alert the server of */ - CommsController.prototype.alertMessage = function (event) { + alertMessage(event) { if (!event.clientEvent) - return winston.error("Websocket alert error: No ClientEvent set", { process: process.pid }); + return winston.error(`Websocket alert error: No ClientEvent set`, { process: process.pid }); this.emit(socket_event_types_1.EventType[event.clientEvent.eventType], event); if (event.responseType != socket_event_types_1.EventResponseType.NoResponse && !event.responseEvent) - return winston.error("Websocket alert error: The response type is expecting a responseEvent but one is not created", { process: process.pid }); + return winston.error(`Websocket alert error: The response type is expecting a responseEvent but one is not created`, { process: process.pid }); if (event.responseType == socket_event_types_1.EventResponseType.RespondClient) this.broadcastEventToClient(event.responseEvent, event.client); else if (event.responseType == socket_event_types_1.EventResponseType.ReBroadcast) this.broadcastEventToAll(event.responseEvent); - }; + } /** * Sends an event to the client specified * @param {IEvent} event The event to broadcast */ - CommsController.prototype.broadcastEventToClient = function (event, client) { + broadcastEventToClient(event, client) { var that = this; return new Promise(function (resolve, reject) { client.ws.send(JSON.stringify(event), undefined, function (error) { if (error) { - winston.error("Websocket broadcase error: '" + error + "'", { process: process.pid }); + winston.error(`Websocket broadcase error: '${error}'`, { process: process.pid }); return reject(); } return resolve(); }); }); - }; + } /** * Sends an event to all connected clients of this server listening for a specific event * @param {IEvent} event The event to broadcast */ - CommsController.prototype.broadcastEventToAll = function (event) { + broadcastEventToAll(event) { var that = this; return new Promise(function (resolve, reject) { var numResponded = 0, errorOccurred = false, releventClients = []; @@ -186,7 +178,7 @@ var CommsController = (function (_super) { if (errorOccurred) return; if (error) { - winston.error("Websocket broadcase error: '" + error + "'", { process: process.pid }); + winston.error(`Websocket broadcase error: '${error}'`, { process: process.pid }); errorOccurred = true; return reject(); } @@ -200,14 +192,13 @@ var CommsController = (function (_super) { if (clientLength == 0) return resolve(); }); - }; + } /** * Called to initialize this controller and its related database objects * @returns {Promise} */ - CommsController.prototype.initialize = function (db) { + initialize(db) { return Promise.resolve(null); - }; - return CommsController; -})(events.EventEmitter); + } +} exports.CommsController = CommsController; diff --git a/dist/controllers/controller.js b/dist/controllers/controller.js index 7391b72..0249ffc 100644 --- a/dist/controllers/controller.js +++ b/dist/controllers/controller.js @@ -1,20 +1,33 @@ "use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promise, generator) { + return new Promise(function (resolve, reject) { + generator = generator.call(thisArg, _arguments); + function cast(value) { return value instanceof Promise && value.constructor === Promise ? value : new Promise(function (resolve) { resolve(value); }); } + function onfulfill(value) { try { step("next", value); } catch (e) { reject(e); } } + function onreject(value) { try { step("throw", value); } catch (e) { reject(e); } } + function step(verb, value) { + var result = generator[verb](value); + result.done ? resolve(result.value) : cast(result.value).then(onfulfill, onreject); + } + step("next", void 0); + }); +}; /** * Base class for all controllers */ -var Controller = (function () { - function Controller() { +class Controller { + constructor() { } /** * All controllers must successfully return a promise for its initialization phase. */ - Controller.prototype.initialize = function (db) { + initialize(db) { return null; - }; + } /** * Ensures the index of a collection */ - Controller.prototype.ensureIndex = function (collection, name) { + ensureIndex(collection, name) { return new Promise(function (resolve, reject) { collection.createIndex(name, function (err, indexName) { if (err) @@ -23,14 +36,14 @@ var Controller = (function () { return resolve(); }); }); - }; + } /** * Creates a new mongodb collection * @param {string} name The name of the collection to create * @param {mongodb.Db} db The database to use * @param {Promise} */ - Controller.prototype.createCollection = function (name, db) { + createCollection(name, db) { return new Promise(function (resolve, reject) { db.createCollection(name, function (err, collection) { if (err || !collection) @@ -39,7 +52,6 @@ var Controller = (function () { return resolve(collection); }); }); - }; - return Controller; -})(); + } +} exports.Controller = Controller; diff --git a/dist/controllers/cors-controller.js b/dist/controllers/cors-controller.js index 82e1305..b90c23e 100644 --- a/dist/controllers/cors-controller.js +++ b/dist/controllers/cors-controller.js @@ -1,23 +1,30 @@ "use strict"; -var __extends = (this && this.__extends) || function (d, b) { - for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promise, generator) { + return new Promise(function (resolve, reject) { + generator = generator.call(thisArg, _arguments); + function cast(value) { return value instanceof Promise && value.constructor === Promise ? value : new Promise(function (resolve) { resolve(value); }); } + function onfulfill(value) { try { step("next", value); } catch (e) { reject(e); } } + function onreject(value) { try { step("throw", value); } catch (e) { reject(e); } } + function step(verb, value) { + var result = generator[verb](value); + result.done ? resolve(result.value) : cast(result.value).then(onfulfill, onreject); + } + step("next", void 0); + }); }; var controller_1 = require("./controller"); /** * Checks all incomming requests to see if they are CORS approved */ -var CORSController = (function (_super) { - __extends(CORSController, _super); +class CORSController extends controller_1.Controller { /** * Creates an instance of the user manager * @param {mongodb.Collection} userCollection The mongo collection that stores the users * @param {mongodb.Collection} sessionCollection The mongo collection that stores the session data * @param {def.IConfig} The config options of this manager */ - function CORSController(e, config) { - _super.call(this); + constructor(e, config) { + super(); var matches = []; for (var i = 0, l = config.approvedDomains.length; i < l; i++) matches.push(new RegExp(config.approvedDomains[i])); @@ -35,7 +42,7 @@ var CORSController = (function (_super) { break; } if (!matched) - console.log(req.headers.origin + " Does not have permission. Add it to the allowed "); + console.log(`${req.headers.origin} Does not have permission. Add it to the allowed `); } if (req.method === 'OPTIONS') { res.status(200); @@ -48,9 +55,8 @@ var CORSController = (function (_super) { /** * All controllers must successfully return a promise for its initialization phase. */ - CORSController.prototype.initialize = function (db) { + initialize(db) { return Promise.resolve(null); - }; - return CORSController; -})(controller_1.Controller); + } +} exports.CORSController = CORSController; diff --git a/dist/controllers/error-controller.js b/dist/controllers/error-controller.js index fad925b..30caf9a 100644 --- a/dist/controllers/error-controller.js +++ b/dist/controllers/error-controller.js @@ -1,20 +1,27 @@ "use strict"; -var __extends = (this && this.__extends) || function (d, b) { - for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promise, generator) { + return new Promise(function (resolve, reject) { + generator = generator.call(thisArg, _arguments); + function cast(value) { return value instanceof Promise && value.constructor === Promise ? value : new Promise(function (resolve) { resolve(value); }); } + function onfulfill(value) { try { step("next", value); } catch (e) { reject(e); } } + function onreject(value) { try { step("throw", value); } catch (e) { reject(e); } } + function step(verb, value) { + var result = generator[verb](value); + result.done ? resolve(result.value) : cast(result.value).then(onfulfill, onreject); + } + step("next", void 0); + }); }; var controller_1 = require("./controller"); /** * Handles express errors */ -var ErrorController = (function (_super) { - __extends(ErrorController, _super); +class ErrorController extends controller_1.Controller { /** * Creates an instance */ - function ErrorController(e, config) { - _super.call(this); + constructor(e, config) { + super(); // Handle all errors the same way e.use(function (err, req, res, next) { res.setHeader('Content-Type', 'application/json'); @@ -24,9 +31,8 @@ var ErrorController = (function (_super) { /** * All controllers must successfully return a promise for its initialization phase. */ - ErrorController.prototype.initialize = function (db) { + initialize(db) { return Promise.resolve(null); - }; - return ErrorController; -})(controller_1.Controller); + } +} exports.ErrorController = ErrorController; diff --git a/dist/controllers/user-controller.js b/dist/controllers/user-controller.js index 4761e6f..60d43c0 100644 --- a/dist/controllers/user-controller.js +++ b/dist/controllers/user-controller.js @@ -1,8 +1,16 @@ "use strict"; -var __extends = (this && this.__extends) || function (d, b) { - for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promise, generator) { + return new Promise(function (resolve, reject) { + generator = generator.call(thisArg, _arguments); + function cast(value) { return value instanceof Promise && value.constructor === Promise ? value : new Promise(function (resolve) { resolve(value); }); } + function onfulfill(value) { try { step("next", value); } catch (e) { reject(e); } } + function onreject(value) { try { step("throw", value); } catch (e) { reject(e); } } + function step(verb, value) { + var result = generator[verb](value); + result.done ? resolve(result.value) : cast(result.value).then(onfulfill, onreject); + } + step("next", void 0); + }); }; var express = require("express"); var bodyParser = require('body-parser'); @@ -14,16 +22,15 @@ var winston = require("winston"); /** * Main class to use for managing users */ -var UserController = (function (_super) { - __extends(UserController, _super); +class UserController extends controller_1.Controller { /** * Creates an instance of the user manager * @param {mongodb.Collection} userCollection The mongo collection that stores the users * @param {mongodb.Collection} sessionCollection The mongo collection that stores the session data * @param {def.IConfig} The config options of this manager */ - function UserController(e, config) { - _super.call(this); + constructor(e, config) { + super(); this._config = config; // Setup the rest calls var router = express.Router(); @@ -59,7 +66,7 @@ var UserController = (function (_super) { * Called to initialize this controller and its related database objects * @returns {Promise} */ - UserController.prototype.initialize = function (db) { + initialize(db) { var that = this; return new Promise(function (resolve, reject) { var userCollection; @@ -86,7 +93,7 @@ var UserController = (function (_super) { reject(error); }); }); - }; + } /** * Gets a specific user by username or email - the "username" parameter must be set. Some of the user data will be obscured unless the verbose parameter * is specified. Specify the verbose=true parameter in order to get all user data. @@ -94,7 +101,7 @@ var UserController = (function (_super) { * @param {express.Response} res * @param {Function} next */ - UserController.prototype.getUser = function (req, res, next) { + getUser(req, res, next) { // Set the content type res.setHeader('Content-Type', 'application/json'); var that = this; @@ -103,7 +110,7 @@ var UserController = (function (_super) { return res.end(JSON.stringify({ message: "No user found", error: true })); var token = { error: false, - message: "Found " + user.dbEntry.username, + message: `Found ${user.dbEntry.username}`, data: user.generateCleanedData(Boolean(req.query.verbose)) }; return res.end(JSON.stringify(token)); @@ -111,7 +118,7 @@ var UserController = (function (_super) { winston.error(err.toString(), { process: process.pid }); return res.end(JSON.stringify({ message: err.toString(), error: true })); }); - }; + } /** * Gets a list of users. You can limit the haul by specifying the 'index' and 'limit' query parameters. * Also specify the verbose=true parameter in order to get all user data. You can also filter usernames with the @@ -120,7 +127,7 @@ var UserController = (function (_super) { * @param {express.Response} res * @param {Function} next */ - UserController.prototype.getUsers = function (req, res, next) { + getUsers(req, res, next) { // Set the content type res.setHeader('Content-Type', 'application/json'); var that = this; @@ -141,7 +148,7 @@ var UserController = (function (_super) { sanitizedData.push(users[i].generateCleanedData(verbose)); var token = { error: false, - message: "Found " + users.length + " users", + message: `Found ${users.length} users`, data: sanitizedData, count: totalNumUsers }; @@ -153,14 +160,14 @@ var UserController = (function (_super) { error: true })); }); - }; + } /** * Gets a list of active sessions. You can limit the haul by specifying the 'index' and 'limit' query parameters. * @param {express.Request} req * @param {express.Response} res * @param {Function} next */ - UserController.prototype.getSessions = function (req, res, next) { + getSessions(req, res, next) { // Set the content type res.setHeader('Content-Type', 'application/json'); var that = this; @@ -171,7 +178,7 @@ var UserController = (function (_super) { }).then(function (sessions) { var token = { error: false, - message: "Found " + sessions.length + " active sessions", + message: `Found ${sessions.length} active sessions`, data: sessions, count: numSessions }; @@ -183,21 +190,21 @@ var UserController = (function (_super) { error: true })); }); - }; + } /** * Resends the activation link to the user * @param {express.Request} req * @param {express.Response} res * @param {Function} next */ - UserController.prototype.deleteSession = function (req, res, next) { + deleteSession(req, res, next) { // Set the content type res.setHeader('Content-Type', 'application/json'); var that = this; that._userManager.sessionManager.clearSession(req.params.id, req, res).then(function (result) { var token = { error: false, - message: "Session " + req.params.id + " has been removed", + message: `Session ${req.params.id} has been removed`, }; return res.end(JSON.stringify(token)); }).catch(function (error) { @@ -207,30 +214,30 @@ var UserController = (function (_super) { error: true })); }); - }; + } /** * Activates the user's account * @param {express.Request} req * @param {express.Response} res * @param {Function} next */ - UserController.prototype.activateAccount = function (req, res, next) { + activateAccount(req, res, next) { var redirectURL = this._config.accountRedirectURL; // Check the user's activation and forward them onto the admin message page this._userManager.checkActivation(req.query.user, req.query.key).then(function (success) { - res.redirect(redirectURL + "?message=" + encodeURIComponent("Your account has been activated!") + "&status=success&origin=" + encodeURIComponent(req.query.origin)); + res.redirect(`${redirectURL}?message=${encodeURIComponent("Your account has been activated!")}&status=success&origin=${encodeURIComponent(req.query.origin)}`); }).catch(function (error) { winston.error(error.toString(), { process: process.pid }); - res.redirect(redirectURL + "?message=" + encodeURIComponent(error.message) + "&status=error&origin=" + encodeURIComponent(req.query.origin)); + res.redirect(`${redirectURL}?message=${encodeURIComponent(error.message)}&status=error&origin=${encodeURIComponent(req.query.origin)}`); }); - }; + } /** * Resends the activation link to the user * @param {express.Request} req * @param {express.Response} res * @param {Function} next */ - UserController.prototype.resendActivation = function (req, res, next) { + resendActivation(req, res, next) { // Set the content type res.setHeader('Content-Type', 'application/json'); var origin = encodeURIComponent(req.headers["origin"] || req.headers["referer"]); @@ -246,14 +253,14 @@ var UserController = (function (_super) { error: true })); }); - }; + } /** * Resends the activation link to the user * @param {express.Request} req * @param {express.Response} res * @param {Function} next */ - UserController.prototype.requestPasswordReset = function (req, res, next) { + requestPasswordReset(req, res, next) { // Set the content type res.setHeader('Content-Type', 'application/json'); var origin = encodeURIComponent(req.headers["origin"] || req.headers["referer"]); @@ -269,14 +276,14 @@ var UserController = (function (_super) { error: true })); }); - }; + } /** * resets the password if the user has a valid password token * @param {express.Request} req * @param {express.Response} res * @param {Function} next */ - UserController.prototype.passwordReset = function (req, res, next) { + passwordReset(req, res, next) { res.setHeader('Content-Type', 'application/json'); if (!req.body) return res.end(JSON.stringify({ message: "Expecting body content and found none", error: true })); @@ -299,14 +306,14 @@ var UserController = (function (_super) { error: true })); }); - }; + } /** * Approves a user's activation code so they can login without email validation * @param {express.Request} req * @param {express.Response} res * @param {Function} next */ - UserController.prototype.approveActivation = function (req, res, next) { + approveActivation(req, res, next) { // Set the content type res.setHeader('Content-Type', 'application/json'); var that = this; @@ -322,14 +329,14 @@ var UserController = (function (_super) { error: true })); }); - }; + } /** * Attempts to log the user in. Expects the username, password and rememberMe parameters be set. * @param {express.Request} req * @param {express.Response} res * @param {Function} next */ - UserController.prototype.login = function (req, res, next) { + login(req, res, next) { // Set the content type res.setHeader('Content-Type', 'application/json'); var token = req.body; @@ -348,14 +355,14 @@ var UserController = (function (_super) { error: true })); }); - }; + } /** * Attempts to log the user out * @param {express.Request} req * @param {express.Response} res * @param {Function} next */ - UserController.prototype.logout = function (req, res, next) { + logout(req, res, next) { // Set the content type res.setHeader('Content-Type', 'application/json'); this._userManager.logOut(req, res).then(function (result) { @@ -370,14 +377,14 @@ var UserController = (function (_super) { error: true })); }); - }; + } /** * Attempts to send the webmaster an email message * @param {express.Request} req * @param {express.Response} res * @param {Function} next */ - UserController.prototype.messageWebmaster = function (req, res, next) { + messageWebmaster(req, res, next) { // Set the content type res.setHeader('Content-Type', 'application/json'); var token = req.body; @@ -389,14 +396,14 @@ var UserController = (function (_super) { winston.error(error.toString(), { process: process.pid }); return res.end(JSON.stringify({ message: error.message, error: true })); }); - }; + } /** * Attempts to register a new user * @param {express.Request} req * @param {express.Response} res * @param {Function} next */ - UserController.prototype.register = function (req, res, next) { + register(req, res, next) { // Set the content type res.setHeader('Content-Type', 'application/json'); var token = req.body; @@ -415,14 +422,14 @@ var UserController = (function (_super) { error: true })); }); - }; + } /** * Sets a user's meta data * @param {express.Request} req * @param {express.Response} res * @param {Function} next */ - UserController.prototype.setData = function (req, res, next) { + setData(req, res, next) { // Set the content type res.setHeader('Content-Type', 'application/json'); var that = this; @@ -432,7 +439,7 @@ var UserController = (function (_super) { val = {}; that._userManager.setMeta(user, val).then(function () { return res.end(JSON.stringify({ - message: "User's data has been updated", + message: `User's data has been updated`, error: false })); }).catch(function (error) { @@ -442,14 +449,14 @@ var UserController = (function (_super) { error: true })); }); - }; + } /** * Sets a user's meta value * @param {express.Request} req * @param {express.Response} res * @param {Function} next */ - UserController.prototype.setVal = function (req, res, next) { + setVal(req, res, next) { // Set the content type res.setHeader('Content-Type', 'application/json'); var that = this; @@ -457,7 +464,7 @@ var UserController = (function (_super) { var name = req.params.name; that._userManager.setMetaVal(user, name, req.body.value).then(function () { return res.end(JSON.stringify({ - message: "Value '" + name + "' has been updated", + message: `Value '${name}' has been updated`, error: false })); }).catch(function (error) { @@ -467,14 +474,14 @@ var UserController = (function (_super) { error: true })); }); - }; + } /** * Gets a user's meta value * @param {express.Request} req * @param {express.Response} res * @param {Function} next */ - UserController.prototype.getVal = function (req, res, next) { + getVal(req, res, next) { // Set the content type res.setHeader('Content-Type', 'application/json'); var that = this; @@ -489,14 +496,14 @@ var UserController = (function (_super) { error: true })); }); - }; + } /** * Gets a user's meta data * @param {express.Request} req * @param {express.Response} res * @param {Function} next */ - UserController.prototype.getData = function (req, res, next) { + getData(req, res, next) { // Set the content type res.setHeader('Content-Type', 'application/json'); var that = this; @@ -511,14 +518,14 @@ var UserController = (function (_super) { error: true })); }); - }; + } /** * Removes a user from the database * @param {express.Request} req * @param {express.Response} res * @param {Function} next */ - UserController.prototype.removeUser = function (req, res, next) { + removeUser(req, res, next) { // Set the content type res.setHeader('Content-Type', 'application/json'); var that = this; @@ -528,7 +535,7 @@ var UserController = (function (_super) { that._userManager.removeUser(toRemove).then(function () { var token = { error: false, - message: "User " + toRemove + " has been removed" + message: `User ${toRemove} has been removed` }; return res.end(JSON.stringify(token)); }).catch(function (error) { @@ -538,14 +545,14 @@ var UserController = (function (_super) { error: true })); }); - }; + } /** * Allows an admin to create a new user without registration * @param {express.Request} req * @param {express.Response} res * @param {Function} next */ - UserController.prototype.createUser = function (req, res, next) { + createUser(req, res, next) { // Set the content type res.setHeader('Content-Type', 'application/json'); var that = this; @@ -561,7 +568,7 @@ var UserController = (function (_super) { that._userManager.createUser(token.username, token.email, token.password, (this._config.ssl ? "https://" : "http://") + this._config.host, token.privileges, token.meta).then(function (user) { var token = { error: false, - message: "User " + user.dbEntry.username + " has been created", + message: `User ${user.dbEntry.username} has been created`, data: user.dbEntry }; return res.end(JSON.stringify(token)); @@ -572,7 +579,7 @@ var UserController = (function (_super) { error: true })); }); - }; + } /** * Checks to see if the current session is logged in. If the user is, it will be returned redacted. You can specify the 'verbose' query parameter. * @param {express.Request} req @@ -580,7 +587,7 @@ var UserController = (function (_super) { * @param {Function} next * @returns {IAuthenticationResponse} */ - UserController.prototype.authenticated = function (req, res, next) { + authenticated(req, res, next) { // Set the content type res.setHeader('Content-Type', 'application/json'); this._userManager.loggedIn(req, res).then(function (user) { @@ -598,7 +605,6 @@ var UserController = (function (_super) { error: true })); }); - }; - return UserController; -})(controller_1.Controller); + } +} exports.UserController = UserController; diff --git a/dist/mailer.js b/dist/mailer.js index 6945840..ee6c9e0 100644 --- a/dist/mailer.js +++ b/dist/mailer.js @@ -1,4 +1,17 @@ "use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promise, generator) { + return new Promise(function (resolve, reject) { + generator = generator.call(thisArg, _arguments); + function cast(value) { return value instanceof Promise && value.constructor === Promise ? value : new Promise(function (resolve) { resolve(value); }); } + function onfulfill(value) { try { step("next", value); } catch (e) { reject(e); } } + function onreject(value) { try { step("throw", value); } catch (e) { reject(e); } } + function step(verb, value) { + var result = generator[verb](value); + result.done ? resolve(result.value) : cast(result.value).then(onfulfill, onreject); + } + step("next", void 0); + }); +}; var google = require("googleapis"); var googleAuth = require("google-auth-library"); var fs = require("fs"); @@ -6,11 +19,11 @@ var winston = require("winston"); /** * A simple class for sending mail using Google Mail's API */ -var Mailer = (function () { +class Mailer { /** * Creates an instance of the mailer */ - function Mailer(debugMode) { + constructor(debugMode) { this._debugMode = debugMode; this._scopes = [ 'https://mail.google.com/', @@ -25,7 +38,7 @@ var Mailer = (function () { * @param {string} apiEmail The email address of the authorized email using the Gmail API * @returns {Promise} */ - Mailer.prototype.initialize = function (keyFilePath, apiEmail) { + initialize(keyFilePath, apiEmail) { var that = this; return new Promise(function (resolve, reject) { that.gmail = google.gmail('v1'); @@ -34,20 +47,20 @@ var Mailer = (function () { // Authorize a client with the loaded credentials that.authorize(that._keyFile) .then(function (data) { - winston.info("Connected to Google Authentication", { process: process.pid }); + winston.info(`Connected to Google Authentication`, { process: process.pid }); resolve(true); }) .catch(function (err) { - winston.error("Could not authorize Google API: " + err.message, { process: process.pid }); + winston.error(`Could not authorize Google API: ${err.message}`, { process: process.pid }); resolve(false); }); }); - }; + } /** * Attempts to authorize the google service account credentials * @returns {Promise} */ - Mailer.prototype.authorize = function (credentials) { + authorize(credentials) { var that = this; return new Promise(function (resolve, reject) { var auth = new googleAuth(); @@ -59,7 +72,7 @@ var Mailer = (function () { resolve(jwt); }); }); - }; + } /** * Sends an email using Google's Gmail API * @param {stirng} to The email address to send the message to @@ -68,7 +81,7 @@ var Mailer = (function () { * @param {stirng} msg The message to be sent * @returns {Promise} */ - Mailer.prototype.sendMail = function (to, from, subject, msg) { + sendMail(to, from, subject, msg) { var that = this; return new Promise(function (resolve, reject) { // Build the message string @@ -86,7 +99,7 @@ var Mailer = (function () { resolve(true); }); }); - }; + } /** * Builds a message string in base64 encoding * @param {stirng} to The email address to send the message to @@ -95,7 +108,7 @@ var Mailer = (function () { * @param {stirng} message The message to be sent * @returns {string} */ - Mailer.prototype.buildMessage = function (to, from, subject, message) { + buildMessage(to, from, subject, message) { var str = ["Content-Type: text/plain; charset=\"UTF-8\"\n", "MIME-Version: 1.0\n", "Content-Transfer-Encoding: 7bit\n", @@ -107,7 +120,6 @@ var Mailer = (function () { // Encode the mail into base 64 var encodedMail = new Buffer(str).toString("base64").replace(/\+/g, '-').replace(/\//g, '_'); return encodedMail; - }; - return Mailer; -})(); + } +} exports.Mailer = Mailer; diff --git a/dist/main.js b/dist/main.js index 4cef812..62263a5 100644 --- a/dist/main.js +++ b/dist/main.js @@ -1,4 +1,17 @@ "use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promise, generator) { + return new Promise(function (resolve, reject) { + generator = generator.call(thisArg, _arguments); + function cast(value) { return value instanceof Promise && value.constructor === Promise ? value : new Promise(function (resolve) { resolve(value); }); } + function onfulfill(value) { try { step("next", value); } catch (e) { reject(e); } } + function onreject(value) { try { step("throw", value); } catch (e) { reject(e); } } + function step(verb, value) { + var result = generator[verb](value); + result.done ? resolve(result.value) : cast(result.value).then(onfulfill, onreject); + } + step("next", void 0); + }); +}; var cluster = require("cluster"); var os = require("os"); var yargs = require("yargs"); @@ -6,25 +19,25 @@ var args = yargs.argv; var numCPUs = os.cpus().length; // Check for the threads argument if (args.numThreads) { - console.log("numThreads specified as '" + args.numThreads + "'"); + console.log(`numThreads specified as '${args.numThreads}'`); if (args.numThreads == "max") { - console.log("Setting the number of clusters to " + numCPUs); + console.log(`Setting the number of clusters to ${numCPUs}`); } else if (isNaN(parseInt(args.numThreads))) { console.log("attribute numThreads must be a number"); process.exit(); } else if (args.numThreads > numCPUs) { - console.log("You only have " + numCPUs + " threads available - attribute numThreads will be set to " + numCPUs); + console.log(`You only have ${numCPUs} threads available - attribute numThreads will be set to ${numCPUs}`); } else if (args.numThreads) { - console.log("Setting the number of clusters to " + args.numThreads); + console.log(`Setting the number of clusters to ${args.numThreads}`); numCPUs = args.numThreads; } } // Run as a single cluster if (numCPUs == 1) { - console.log("Running as single cluster"); + console.log(`Running as single cluster`); require("./startup.js"); } else if (cluster.isMaster) { @@ -41,11 +54,11 @@ else if (cluster.isMaster) { // Note the process IDs var newPID = worker.process.pid; var oldPID = deadWorker.process.pid; - console.log("Cluster " + worker.process.pid + " died"); - console.log("Attempting to restart failed cluster"); + console.log(`Cluster ${worker.process.pid} died`); + console.log(`Attempting to restart failed cluster`); // Log the event - console.log("worker " + oldPID + " died"); - console.log("worker " + newPID + " born"); + console.log(`worker ${oldPID} died`); + console.log(`worker ${newPID} born`); }); } else { diff --git a/dist/permission-controller.js b/dist/permission-controller.js index 8fb9c9a..35ab19c 100644 --- a/dist/permission-controller.js +++ b/dist/permission-controller.js @@ -1,4 +1,17 @@ "use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promise, generator) { + return new Promise(function (resolve, reject) { + generator = generator.call(thisArg, _arguments); + function cast(value) { return value instanceof Promise && value.constructor === Promise ? value : new Promise(function (resolve) { resolve(value); }); } + function onfulfill(value) { try { step("next", value); } catch (e) { reject(e); } } + function onreject(value) { try { step("throw", value); } catch (e) { reject(e); } } + function step(verb, value) { + var result = generator[verb](value); + result.done ? resolve(result.value) : cast(result.value).then(onfulfill, onreject); + } + step("next", void 0); + }); +}; var users_1 = require("./users"); /** * Checks if the request has owner rights (admin/owner). If not, an error is sent back to the user @@ -83,19 +96,18 @@ exports.requireUser = requireUser; * @param {Function} next */ function requestHasPermission(level, req, res, existingUser) { - return new Promise(function (resolve, reject) { - users_1.UserManager.get.loggedIn(req, res).then(function (user) { - if (!user) - return reject(new Error("You must be logged in to make this request")); - if (existingUser !== undefined) { - if ((user.dbEntry.email != existingUser && user.dbEntry.username != existingUser) && user.dbEntry.privileges > level) - return reject(new Error("You don't have permission to make this request")); - } - else if (user.dbEntry.privileges > level) - return reject(new Error("You don't have permission to make this request")); - req._user = user; - resolve(true); - }); + return __awaiter(this, void 0, Promise, function* () { + var user = yield users_1.UserManager.get.loggedIn(req, res); + if (!user) + throw new Error("You must be logged in to make this request"); + if (existingUser !== undefined) { + if ((user.dbEntry.email != existingUser && user.dbEntry.username != existingUser) && user.dbEntry.privileges > level) + throw new Error("You don't have permission to make this request"); + } + else if (user.dbEntry.privileges > level) + throw new Error("You don't have permission to make this request"); + req._user = user; + return true; }); } exports.requestHasPermission = requestHasPermission; diff --git a/dist/session.js b/dist/session.js index 835b30f..792634d 100644 --- a/dist/session.js +++ b/dist/session.js @@ -1,21 +1,28 @@ "use strict"; -var __extends = (this && this.__extends) || function (d, b) { - for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promise, generator) { + return new Promise(function (resolve, reject) { + generator = generator.call(thisArg, _arguments); + function cast(value) { return value instanceof Promise && value.constructor === Promise ? value : new Promise(function (resolve) { resolve(value); }); } + function onfulfill(value) { try { step("next", value); } catch (e) { reject(e); } } + function onreject(value) { try { step("throw", value); } catch (e) { reject(e); } } + function step(verb, value) { + var result = generator[verb](value); + result.done ? resolve(result.value) : cast(result.value).then(onfulfill, onreject); + } + step("next", void 0); + }); }; var events_1 = require("events"); /** * A class that manages session data for active users */ -var SessionManager = (function (_super) { - __extends(SessionManager, _super); +class SessionManager extends events_1.EventEmitter { /** * Creates an instance of a session manager * @param { mongodb.Collection} sessionCollection The mongoDB collection to use for saving sessions */ - function SessionManager(dbCollection, options) { - _super.call(this); + constructor(dbCollection, options) { + super(); this._dbCollection = dbCollection; this._cleanupProxy = this.cleanup.bind(this); this._timeout = 0; @@ -31,32 +38,23 @@ var SessionManager = (function (_super) { * @param {number} startIndex * @param {number} limit */ - SessionManager.prototype.numActiveSessions = function (startIndex, limit) { - var that = this; - return new Promise(function (resolve, reject) { - that._dbCollection.count({}, function (error, count) { - if (error) - return reject(error); - resolve(count); - }); + numActiveSessions(startIndex, limit) { + return __awaiter(this, void 0, Promise, function* () { + var result = yield this._dbCollection.count({}); + return result; }); - }; + } /** * Gets an array of all active sessions * @param {number} startIndex * @param {number} limit */ - SessionManager.prototype.getActiveSessions = function (startIndex, limit) { - if (limit === void 0) { limit = -1; } - var that = this; - return new Promise(function (resolve, reject) { - that._dbCollection.find({}).skip(startIndex).limit(limit).toArray().then(function (results) { - resolve(results); - }).catch(function (error) { - return reject(error); - }); + getActiveSessions(startIndex, limit = -1) { + return __awaiter(this, void 0, Promise, function* () { + var results = yield this._dbCollection.find({}).skip(startIndex).limit(limit).toArray(); + return results; }); - }; + } /** * Clears the users session cookie so that its no longer tracked * @param {string} sessionId The session ID to remove, if null then the currently authenticated session will be used @@ -64,168 +62,142 @@ var SessionManager = (function (_super) { * @param {http.ServerResponse} response * @returns {Promise} */ - SessionManager.prototype.clearSession = function (sessionId, request, response) { - var that = this; - return new Promise(function (resolve, reject) { + clearSession(sessionId, request, response) { + return __awaiter(this, void 0, Promise, function* () { // Check if the request has a valid session ID - var sId = sessionId || that.getIDFromRequest(request); + var sId = sessionId || this.getIDFromRequest(request); if (sId != "") { // We have a session ID, lets try to find it in the DB - that._dbCollection.find({ sessionId: sId }).limit(1).next().then(function (sessionDB) { - // Create a new session - var session = new Session(sId, that._options); - session.expiration = -1; - // Adds / updates the DB with the new session - that._dbCollection.deleteOne({ sessionId: session.sessionId }).then(function (result) { - that.emit("sessionRemoved", sId); - // Set the session cookie header - response.setHeader('Set-Cookie', session.getSetCookieHeaderValue()); - // Resolve the request - resolve(true); - }).catch(function (err) { - reject(err); - }); - }).catch(function (err) { - reject(err); - }); + var sessionDB = yield this._dbCollection.find({ sessionId: sId }).limit(1).next(); + // Create a new session + var session = new Session(sId, this._options); + session.expiration = -1; + // Adds / updates the DB with the new session + var result = yield this._dbCollection.deleteOne({ sessionId: session.sessionId }); + this.emit("sessionRemoved", sId); + // Set the session cookie header + response.setHeader('Set-Cookie', session.getSetCookieHeaderValue()); + // Resolve the request + return true; } else - resolve(true); + return true; }); - }; + } /** * Attempts to get a session from the request object of the client * @param {http.ServerRequest} request * @param {http.ServerResponse} response * @returns {Promise} Returns a session or null if none can be found */ - SessionManager.prototype.getSession = function (request, response) { - var that = this; - return new Promise(function (resolve, reject) { + getSession(request, response) { + return __awaiter(this, void 0, Promise, function* () { // Check if the request has a valid session ID - var sessionId = that.getIDFromRequest(request); + var sessionId = this.getIDFromRequest(request); if (sessionId != "") { // We have a session ID, lets try to find it in the DB - that._dbCollection.find({ sessionId: sessionId }).limit(1).next().then(function (sessionDB) { - // Cant seem to find any session - so create a new one - if (!sessionDB) - resolve(null); - else { - // Create a new session - var session = new Session(sessionId, that._options, sessionDB); - // Adds / updates the DB with the new session - that._dbCollection.updateOne({ sessionId: session.sessionId }, session.save()).then(function (result) { - // make sure a timeout is pending for the expired session reaper - if (!that._timeout) - that._timeout = setTimeout(that._cleanupProxy, 60000); - // Set the session cookie header - if (response) - response.setHeader('Set-Cookie', session.getSetCookieHeaderValue()); - // Resolve the request - resolve(session); - }).catch(function (err) { - return reject(err); - }); - } - }).catch(function (err) { - reject(err); - }); + var sessionDB = yield this._dbCollection.find({ sessionId: sessionId }).limit(1).next(); + // Cant seem to find any session - so create a new one + if (!sessionDB) + return null; + // Create a new session + var session = new Session(sessionId, this._options, sessionDB); + // Adds / updates the DB with the new session + var result = yield this._dbCollection.updateOne({ sessionId: session.sessionId }, session.save()); + // make sure a timeout is pending for the expired session reaper + if (!this._timeout) + this._timeout = setTimeout(this._cleanupProxy, 60000); + // Set the session cookie header + if (response) + response.setHeader('Set-Cookie', session.getSetCookieHeaderValue()); + // Resolve the request + return session; } else // Resolve with no session data - resolve(null); + return null; }); - }; + } /** * Attempts to create a session from the request object of the client * @param {http.ServerRequest} request * @returns {Promise} */ - SessionManager.prototype.createSession = function (request, response) { - var that = this; - return new Promise(function (resolve, reject) { - var session = new Session(that.createID(), that._options, null); + createSession(request, response) { + return __awaiter(this, void 0, Promise, function* () { + var session = new Session(this.createID(), this._options, null); // Adds / updates the DB with the new session - that._dbCollection.insertOne(session.save()).then(function (insertResult) { - // Set the session cookie header - response.setHeader('Set-Cookie', session.getSetCookieHeaderValue()); - // Resolve the request - resolve(session); - }).catch(function (err) { - reject(err); - }); + var insertResult = yield this._dbCollection.insertOne(session.save()); + // Set the session cookie header + response.setHeader('Set-Cookie', session.getSetCookieHeaderValue()); + // Resolve the request + return session; }); - }; + } /** * Each time a session is created, a timer is started to check all sessions in the DB. * Once the lifetime of a session is up its then removed from the DB and we check for any remaining sessions. * @param {boolean} force If true, this will force a cleanup instead of waiting on the next timer */ - SessionManager.prototype.cleanup = function (force) { - if (force === void 0) { force = false; } - var that = this; - var now = +new Date; - var next = Infinity; - this._timeout = 0; - that._dbCollection.find(function (err, result) { - // If an error occurs, just try again in 2 minutes - if (err) - that._timeout = setTimeout(that._cleanupProxy, 120000); - else { - result.toArray(function (err, sessions) { - // If an error occurs, just try again in 2 minutes - if (err) - that._timeout = setTimeout(that._cleanupProxy, 120000); - else { - // Remove query - var toRemoveQuery = { $or: [] }; - for (var i = 0, l = sessions.length; i < l; i++) { - var expiration = parseFloat(sessions[i].expiration.toString()); - // If the session's time is up - if (expiration < now || force) - toRemoveQuery.$or.push({ _id: sessions[i]._id, sessionId: sessions[i].sessionId }); - else - // Session time is not up, but may be the next time target - next = next < expiration ? next : expiration; - } - // Check if we need to remove sessions - if we do, then remove them :) - if (toRemoveQuery.$or.length > 0) { - that._dbCollection.deleteMany(toRemoveQuery).then(function (result) { - for (var i = 0, l = toRemoveQuery.$or.length; i < l; i++) - that.emit("sessionRemoved", toRemoveQuery.$or[i].sessionId); - if (next < Infinity) - that._timeout = setTimeout(that._cleanupProxy, next - (+new Date) + 1000); - }); - } - else { - if (next < Infinity) - that._timeout = setTimeout(that._cleanupProxy, next - (+new Date) + 1000); - } - } - }); + cleanup(force = false) { + return __awaiter(this, void 0, Promise, function* () { + var now = +new Date; + var next = Infinity; + this._timeout = 0; + try { + // TODO: We need to replace the findToken with one where mongo looks at the conditions + var findToken = {}; + var sessions = yield this._dbCollection.find(findToken).toArray(); + // Remove query + var toRemoveQuery = { $or: [] }; + for (var i = 0, l = sessions.length; i < l; i++) { + var expiration = parseFloat(sessions[i].expiration.toString()); + // If the session's time is up + if (expiration < now || force) + toRemoveQuery.$or.push({ _id: sessions[i]._id, sessionId: sessions[i].sessionId }); + else + // Session time is not up, but may be the next time target + next = next < expiration ? next : expiration; + } + // Check if we need to remove sessions - if we do, then remove them :) + if (toRemoveQuery.$or.length > 0) { + var result = yield this._dbCollection.deleteMany(toRemoveQuery); + for (var i = 0, l = toRemoveQuery.$or.length; i < l; i++) + this.emit("sessionRemoved", toRemoveQuery.$or[i].sessionId); + if (next < Infinity) + this._timeout = setTimeout(this._cleanupProxy, next - (+new Date) + 1000); + } + else { + if (next < Infinity) + this._timeout = setTimeout(this._cleanupProxy, next - (+new Date) + 1000); + } + } + catch (err) { + // If an error occurs, just try again in 2 minutes + this._timeout = setTimeout(this._cleanupProxy, 120000); } }); - }; + } /** * Looks at the headers from the HTTP request to determine if a session cookie has been asssigned and returns the ID. * @param {http.ServerRequest} req * @returns {string} The ID of the user session, or an empty string */ - SessionManager.prototype.getIDFromRequest = function (req) { + getIDFromRequest(req) { var m; // look for an existing SID in the Cookie header for which we have a session if (req.headers.cookie && (m = /SID=([^ ,;]*)/.exec(req.headers.cookie))) return m[1]; else return ""; - }; + } /** * Creates a random session ID. * The ID is a pseude-random ASCII string which contains at least the specified number of bits of entropy (64 in this case) * the return value is a string of length [bits/6] of characters from the base64 alphabet * @returns {string} A user session ID */ - SessionManager.prototype.createID = function () { + createID() { var bits = 64; var chars, rand, i, ret; chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; @@ -238,21 +210,20 @@ var SessionManager = (function (_super) { ret += chars[0x3F & rand >>> i]; } return ret; - }; - return SessionManager; -})(events_1.EventEmitter); + } +} exports.SessionManager = SessionManager; /** * A class to represent session data */ -var Session = (function () { +class Session { /** * Creates an instance of the session * @param {string} sessionId The ID of the session * @param {SessionOptions} options The options associated with this session * @param {ISessionEntry} data The data of the session in the database */ - function Session(sessionId, options, data) { + constructor(sessionId, options, data) { this.sessionId = sessionId; this.data = data || {}; this.options = options; @@ -264,27 +235,27 @@ var Session = (function () { * Fills in the data of this session from the data saved in the database * @param {ISessionEntry} data The data fetched from the database */ - Session.prototype.open = function (data) { + open(data) { this.sessionId = data.sessionId; this.data = data.data; this.expiration = data.expiration; - }; + } /** * Creates an object that represents this session to be saved in the database * @returns {ISessionEntry} */ - Session.prototype.save = function () { + save() { var data = {}; data.sessionId = this.sessionId; data.data = this.data; data.expiration = (new Date(Date.now() + this.options.lifetime * 1000)).getTime(); return data; - }; + } /** * This method returns the value to send in the Set-Cookie header which you should send with every request that goes back to the browser, e.g. * response.setHeader('Set-Cookie', session.getSetCookieHeaderValue()); */ - Session.prototype.getSetCookieHeaderValue = function () { + getSetCookieHeaderValue() { var parts; parts = ['SID=' + this.sessionId]; if (this.options.path) @@ -296,24 +267,23 @@ var Session = (function () { if (this.options.secure) parts.push("secure"); return parts.join('; '); - }; + } /** * Converts from milliseconds to string, since the epoch to Cookie 'expires' format which is Wdy, DD-Mon-YYYY HH:MM:SS GMT */ - Session.prototype.dateCookieString = function (ms) { + dateCookieString(ms) { var d, wdy, mon; d = new Date(ms); wdy = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat']; mon = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']; return wdy[d.getUTCDay()] + ', ' + this.pad(d.getUTCDate()) + '-' + mon[d.getUTCMonth()] + '-' + d.getUTCFullYear() + ' ' + this.pad(d.getUTCHours()) + ':' + this.pad(d.getUTCMinutes()) + ':' + this.pad(d.getUTCSeconds()) + ' GMT'; - }; + } /** * Pads a string with 0's */ - Session.prototype.pad = function (n) { + pad(n) { return n > 9 ? '' + n : '0' + n; - }; - return Session; -})(); + } +} exports.Session = Session; diff --git a/dist/socket-api.js b/dist/socket-api.js index df6e58b..1eb91cb 100644 --- a/dist/socket-api.js +++ b/dist/socket-api.js @@ -4,8 +4,8 @@ var socket_event_types_1 = require("./socket-event-types"); /** * Handles express errors */ -var SocketAPI = (function () { - function SocketAPI(comms) { +class SocketAPI { + constructor(comms) { this._comms = comms; // Setup all socket API listeners comms.on(socket_event_types_1.EventType[socket_event_types_1.EventType.Echo], this.onEcho.bind(this)); @@ -15,7 +15,7 @@ var SocketAPI = (function () { * Responds to a meta request from a client * @param {SocketEvents.IMetaEvent} e */ - SocketAPI.prototype.onMeta = function (e) { + onMeta(e) { var comms = this._comms; if (!users_1.UserManager.get) return; @@ -39,11 +39,11 @@ var SocketAPI = (function () { }).catch(function (err) { comms.broadcastEventToClient({ error: err.toString(), eventType: e.clientEvent.eventType }, e.client); }); - }; + } /** * Responds to a echo request from a client */ - SocketAPI.prototype.onEcho = function (e) { + onEcho(e) { e.responseEvent = { eventType: socket_event_types_1.EventType.Echo, message: e.clientEvent.message @@ -52,7 +52,6 @@ var SocketAPI = (function () { e.responseType = socket_event_types_1.EventResponseType.ReBroadcast; else e.responseType = socket_event_types_1.EventResponseType.RespondClient; - }; - return SocketAPI; -})(); + } +} exports.SocketAPI = SocketAPI; diff --git a/dist/startup.js b/dist/startup.js index 118d6d2..d6b7b59 100644 --- a/dist/startup.js +++ b/dist/startup.js @@ -1,4 +1,17 @@ "use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promise, generator) { + return new Promise(function (resolve, reject) { + generator = generator.call(thisArg, _arguments); + function cast(value) { return value instanceof Promise && value.constructor === Promise ? value : new Promise(function (resolve) { resolve(value); }); } + function onfulfill(value) { try { step("next", value); } catch (e) { reject(e); } } + function onreject(value) { try { step("throw", value); } catch (e) { reject(e); } } + function step(verb, value) { + var result = generator[verb](value); + result.done ? resolve(result.value) : cast(result.value).then(onfulfill, onreject); + } + step("next", void 0); + }); +}; var http = require("http"); var https = require("https"); var fs = require("fs"); @@ -34,27 +47,27 @@ if (!args.config || args.config.trim() == "") { } // Make sure the file exists if (!fs.existsSync(args.config)) { - winston.error("Could not locate the config file at '" + args.config + "'", { process: process.pid }); + winston.error(`Could not locate the config file at '${args.config}'`, { process: process.pid }); process.exit(); } // Load the file var jsonConfig = fs.readFileSync(args.config, "utf8"); try { // Parse the config - console.log("Parsing file config..."); + console.log(`Parsing file config...`); var config = JSON.parse(jsonConfig); // If the debug paramter is present then go into debug mode if (args.debug) config.debugMode = true; } catch (exp) { - winston.error("There was an error parsing the config file '" + exp.toString() + "'", { process: process.pid }, function () { + winston.error(`There was an error parsing the config file '${exp.toString()}'`, { process: process.pid }, function () { process.exit(); }); } -winston.info("Opening the database...", { process: process.pid }); +winston.info(`Opening the database...`, { process: process.pid }); openDB(config).then(function (db) { - winston.info("Initializing controllers...", { process: process.pid }); + winston.info(`Initializing controllers...`, { process: process.pid }); return Promise.all([ new comms_controller_1.CommsController(config).initialize(db), new cors_controller_1.CORSController(app, config).initialize(db), @@ -69,38 +82,38 @@ openDB(config).then(function (db) { // Start node server.js var httpServer = http.createServer(app); httpServer.listen(config.portHTTP); - winston.info("Listening on HTTP port " + config.portHTTP, { process: process.pid }); + winston.info(`Listening on HTTP port ${config.portHTTP}`, { process: process.pid }); // If we use SSL then start listening for that as well if (config.ssl) { if (config.sslIntermediate != "" && !fs.existsSync(config.sslIntermediate)) { - winston.error("Could not find sslIntermediate: '" + config.sslIntermediate + "'", { process: process.pid }); + winston.error(`Could not find sslIntermediate: '${config.sslIntermediate}'`, { process: process.pid }); process.exit(); } if (config.sslCert != "" && !fs.existsSync(config.sslCert)) { - winston.error("Could not find sslIntermediate: '" + config.sslCert + "'", { process: process.pid }); + winston.error(`Could not find sslIntermediate: '${config.sslCert}'`, { process: process.pid }); process.exit(); } if (config.sslRoot != "" && !fs.existsSync(config.sslRoot)) { - winston.error("Could not find sslIntermediate: '" + config.sslRoot + "'", { process: process.pid }); + winston.error(`Could not find sslIntermediate: '${config.sslRoot}'`, { process: process.pid }); process.exit(); } if (config.sslKey != "" && !fs.existsSync(config.sslKey)) { - winston.error("Could not find sslIntermediate: '" + config.sslKey + "'", { process: process.pid }); + winston.error(`Could not find sslIntermediate: '${config.sslKey}'`, { process: process.pid }); process.exit(); } var caChain = [fs.readFileSync(config.sslIntermediate), fs.readFileSync(config.sslRoot)]; var privkey = config.sslKey ? fs.readFileSync(config.sslKey) : null; var theCert = config.sslCert ? fs.readFileSync(config.sslCert) : null; var port = config.portHTTPS ? config.portHTTPS : 443; - winston.info("Attempting to start SSL server...", { process: process.pid }); + winston.info(`Attempting to start SSL server...`, { process: process.pid }); var httpsServer = https.createServer({ key: privkey, cert: theCert, passphrase: config.sslPassPhrase, ca: caChain }, app); httpsServer.listen(port); - winston.info("Listening on HTTPS port " + port, { process: process.pid }); + winston.info(`Listening on HTTPS port ${port}`, { process: process.pid }); } // Done! winston.info("Users is up and running!", { process: process.pid }); }).catch(function (error) { - winston.error("An error has occurred and the application needs to shut down: '" + error.message + "'", { process: process.pid }, function () { + winston.error(`An error has occurred and the application needs to shut down: '${error.message}'`, { process: process.pid }, function () { process.exit(); }); }); diff --git a/dist/users.js b/dist/users.js index 4cc9357..3df465c 100644 --- a/dist/users.js +++ b/dist/users.js @@ -1,4 +1,17 @@ "use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promise, generator) { + return new Promise(function (resolve, reject) { + generator = generator.call(thisArg, _arguments); + function cast(value) { return value instanceof Promise && value.constructor === Promise ? value : new Promise(function (resolve) { resolve(value); }); } + function onfulfill(value) { try { step("next", value); } catch (e) { reject(e); } } + function onreject(value) { try { step("throw", value); } catch (e) { reject(e); } } + function step(verb, value) { + var result = generator[verb](value); + result.done ? resolve(result.value) : cast(result.value).then(onfulfill, onreject); + } + step("next", void 0); + }); +}; var validator = require("validator"); var bcrypt = require("bcryptjs"); var recaptcha = require("recaptcha-async"); @@ -20,12 +33,12 @@ var UserPrivileges = exports.UserPrivileges; /* * Class that represents a user and its database entry */ -var User = (function () { +class User { /** * Creates a new User instance * @param {IUserEntry} dbEntry The data object that represents the user in the DB */ - function User(dbEntry) { + constructor(dbEntry) { this.dbEntry = dbEntry; } /** @@ -33,8 +46,7 @@ var User = (function () { * @param {boolean} verbose If true, sensitive database data will be sent (things like passwords will still be obscured) * @returns {IUserEntry} */ - User.prototype.generateCleanedData = function (verbose) { - if (verbose === void 0) { verbose = false; } + generateCleanedData(verbose = false) { if (!this.dbEntry.passwordTag) this.dbEntry.passwordTag = ""; if (!this.dbEntry.sessionId) @@ -61,12 +73,12 @@ var User = (function () { username: this.dbEntry.username, privileges: this.dbEntry.privileges }; - }; + } /** * Generates the object to be stored in the database * @returns {IUserEntry} */ - User.prototype.generateDbEntry = function () { + generateDbEntry() { return { email: this.dbEntry.email, lastLoggedIn: Date.now(), @@ -79,34 +91,32 @@ var User = (function () { passwordTag: this.dbEntry.passwordTag, meta: this.dbEntry.meta }; - }; + } /** * Creates a random string that is assigned to the dbEntry registration key * @param {number} length The length of the password * @returns {string} */ - User.prototype.generateKey = function (length) { - if (length === void 0) { length = 10; } + generateKey(length = 10) { var text = ""; var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; for (var i = 0; i < length; i++) text += possible.charAt(Math.floor(Math.random() * possible.length)); return text; - }; - return User; -})(); + } +} exports.User = User; /** * Main class to use for managing users */ -var UserManager = (function () { +class UserManager { /** * Creates an instance of the user manager * @param {mongodb.Collection} userCollection The mongo collection that stores the users * @param {mongodb.Collection} sessionCollection The mongo collection that stores the session data * @param {IConfig} The config options of this manager */ - function UserManager(userCollection, sessionCollection, config) { + constructor(userCollection, sessionCollection, config) { this._userCollection = userCollection; this._config = config; UserManager._singleton = this; @@ -124,52 +134,67 @@ var UserManager = (function () { * Called whenever a session is removed from the database * @returns {Promise} */ - UserManager.prototype.onSessionRemoved = function (sessionId) { - if (!sessionId || sessionId == "") - return; - this._userCollection.find({ sessionId: sessionId }).limit(1).next().then(function (useEntry) { + onSessionRemoved(sessionId) { + return __awaiter(this, void 0, Promise, function* () { + if (!sessionId || sessionId == "") + return; + var useEntry = yield this._userCollection.find({ sessionId: sessionId }).limit(1).next(); if (useEntry) { // Send logged in event to socket var sEvent = { username: useEntry.username, eventType: socket_event_types_1.EventType.Logout, error: undefined }; - comms_controller_1.CommsController.singleton.broadcastEventToAll(sEvent).then(function () { - winston.info("User '" + useEntry.username + "' has logged out", { process: process.pid }); - }); + yield comms_controller_1.CommsController.singleton.broadcastEventToAll(sEvent); + winston.info(`User '${useEntry.username}' has logged out`, { process: process.pid }); } + return; }); - }; + } /** * Initializes the API * @returns {Promise} */ - UserManager.prototype.initialize = function () { + initialize() { + return __awaiter(this, void 0, Promise, function* () { + var that = this; + var config = this._config; + if (config.google.bucket && config.google.keyFile) { + this._mailer = new mailer_1.Mailer(config.debugMode); + this._mailer.initialize(config.google.keyFile, config.google.mail.apiEmail); + } + // Clear all existing indices and then re-add them + yield this._userCollection.dropIndexes(); + // Make sure the user collection has an index to search the username field + yield this._userCollection.createIndex({ username: "text", email: "text" }); + // See if we have an admin user + var user = yield this.getUser(config.adminUser.username); + // If no admin user exists, so lets try to create one + if (!user) + user = yield this.createUser(config.adminUser.username, config.adminUser.email, config.adminUser.password, (config.ssl ? "https://" : "http://") + config.host, UserPrivileges.SuperAdmin, {}, true); + return; + }); + } + /** + * Checks if a Google captcha sent from a user is valid + * @param {string} captchaChallenge The captcha challenge + * @param {string} captcha The captcha value the user guessed + * @param {http.ServerRequest} request + * @returns {Promise} + */ + checkCaptcha(captchaChallenge, captcha, request) { var that = this; - var config = this._config; - if (that._config.google.bucket && that._config.google.keyFile) { - that._mailer = new mailer_1.Mailer(that._config.debugMode); - that._mailer.initialize(that._config.google.keyFile, that._config.google.mail.apiEmail); - } return new Promise(function (resolve, reject) { - // Clear all existing indices and then re-add them - that._userCollection.dropIndexes().then(function () { - // Make sure the user collection has an index to search the username field - return that._userCollection.createIndex({ username: "text", email: "text" }); - }).then(function () { - // See if we have an admin user - return that.getUser(config.adminUser.username); - }).then(function (user) { - // No admin user exists, so lets try to create one - if (!user) - return that.createUser(config.adminUser.username, config.adminUser.email, config.adminUser.password, (config.ssl ? "https://" : "http://") + config.host, UserPrivileges.SuperAdmin, {}, true); - else - // Admin user already exists - return user; - }).then(function (newUser) { - resolve(); - }).catch(function (error) { - return reject(error); + // Create the captcha checker + var remoteIP = request.headers['x-forwarded-for'] || request.connection.remoteAddress; + var privatekey = that._config.captchaPrivateKey; + var captchaChecker = new recaptcha.reCaptcha(); + captchaChecker.on("data", function (captchaResult) { + if (!captchaResult.is_valid) + return reject(new Error("Your captcha code seems to be wrong. Please try another.")); + resolve(true); }); + // Check for valid captcha + captchaChecker.checkAnswer(privatekey, remoteIP, captchaChallenge, captcha); }); - }; + } /** * Attempts to register a new user * @param {string} username The username of the user @@ -182,103 +207,69 @@ var UserManager = (function () { * @param {http.ServerResponse} response * @returns {Promise} */ - UserManager.prototype.register = function (username, pass, email, captcha, captchaChallenge, meta, request, response) { - if (username === void 0) { username = ""; } - if (pass === void 0) { pass = ""; } - if (email === void 0) { email = ""; } - if (captcha === void 0) { captcha = ""; } - if (captchaChallenge === void 0) { captchaChallenge = ""; } - if (meta === void 0) { meta = {}; } - var that = this; - var origin = encodeURIComponent(request.headers["origin"] || request.headers["referer"]); - return new Promise(function (resolve, reject) { + register(username = "", pass = "", email = "", captcha = "", captchaChallenge = "", meta = {}, request, response) { + return __awaiter(this, void 0, Promise, function* () { + var origin = encodeURIComponent(request.headers["origin"] || request.headers["referer"]); // First check if user exists, make sure the details supplied are ok, then create the new user - that.getUser(username, email).then(function (user) { - // If we already a user then error out - if (user) - throw new Error("That username or email is already in use; please choose another or login."); - // Validate other data - if (!pass || pass == "") - throw new Error("Password cannot be null or empty"); - if (!email || email == "") - throw new Error("Email cannot be null or empty"); - if (!validator.isEmail(email)) - throw new Error("Please use a valid email address"); - if (request && (!captcha || captcha == "")) - throw new Error("Captcha cannot be null or empty"); - if (request && (!captchaChallenge || captchaChallenge == "")) - throw new Error("Captcha challenge cannot be null or empty"); - // Check captcha details - return new Promise(function (resolve, reject) { - // Create the captcha checker - var remoteIP = request.headers['x-forwarded-for'] || request.connection.remoteAddress; - var privatekey = that._config.captchaPrivateKey; - var captchaChecker = new recaptcha.reCaptcha(); - var newUser = null; - captchaChecker.on("data", function (captchaResult) { - if (!captchaResult.is_valid) - return reject(new Error("Your captcha code seems to be wrong. Please try another.")); - that.createUser(username, email, pass, origin, UserPrivileges.Regular, meta).then(function (user) { - newUser = user; - return resolve(newUser); - }).catch(function (err) { - return reject(err); - }); - }); - // Check for valid captcha - captchaChecker.checkAnswer(privatekey, remoteIP, captchaChallenge, captcha); - }); - }).then(function (user) { - return resolve(user); - }).catch(function (error) { - return reject(error); - }); + var user = yield this.getUser(username, email); + // If we already a user then error out + if (user) + throw new Error("That username or email is already in use; please choose another or login."); + // Validate other data + if (!pass || pass == "") + throw new Error("Password cannot be null or empty"); + if (!email || email == "") + throw new Error("Email cannot be null or empty"); + if (!validator.isEmail(email)) + throw new Error("Please use a valid email address"); + if (request && (!captcha || captcha == "")) + throw new Error("Captcha cannot be null or empty"); + if (request && (!captchaChallenge || captchaChallenge == "")) + throw new Error("Captcha challenge cannot be null or empty"); + // Check the captcha + yield this.checkCaptcha(captchaChallenge, captcha, request); + user = yield this.createUser(username, email, pass, origin, UserPrivileges.Regular, meta); + return user; }); - }; + } /** * Creates the link to send to the user for activation * @param {string} user The user we are activating * @param {string} origin The origin of where the activation link came from * @returns {string} */ - UserManager.prototype.createActivationLink = function (user, origin) { - return "" + (this._config.ssl ? "https://" : "http://") + this._config.host + ":" + (this._config.ssl ? this._config.portHTTPS : this._config.portHTTP) + this._config.apiPrefix + "activate-account?key=" + user.dbEntry.registerKey + "&user=" + user.dbEntry.username + "&origin=" + origin; - }; + createActivationLink(user, origin) { + return `${(this._config.ssl ? "https://" : "http://")}${this._config.host}:${(this._config.ssl ? this._config.portHTTPS : this._config.portHTTP)}${this._config.apiPrefix}activate-account?key=${user.dbEntry.registerKey}&user=${user.dbEntry.username}&origin=${origin}`; + } /** * Creates the link to send to the user for password reset * @param {string} username The username of the user * @param {string} origin The origin of where the activation link came from * @returns {string} */ - UserManager.prototype.createResetLink = function (user, origin) { - return this._config.passwordResetURL + "?key=" + user.dbEntry.passwordTag + "&user=" + user.dbEntry.username + "&origin=" + origin; - }; + createResetLink(user, origin) { + return `${this._config.passwordResetURL}?key=${user.dbEntry.passwordTag}&user=${user.dbEntry.username}&origin=${origin}`; + } /** * Approves a user's activation code so they can login without email validation * @param {string} username The username or email of the user * @returns {Promise} */ - UserManager.prototype.approveActivation = function (username) { - var that = this; - // Get the user - return that.getUser(username).then(function (user) { + approveActivation(username) { + return __awaiter(this, void 0, Promise, function* () { + // Get the user + var user = yield this.getUser(username); if (!user) - return Promise.reject(new Error("No user exists with the specified details")); - return new Promise(function (resolve, reject) { - // Clear the user's activation - that._userCollection.updateOne({ _id: user.dbEntry._id }, { $set: { registerKey: "" } }).then(function (result) { - // Send activated event - var sEvent = { username: username, eventType: socket_event_types_1.EventType.Activated, error: undefined }; - return comms_controller_1.CommsController.singleton.broadcastEventToAll(sEvent); - }).then(function () { - winston.info("User '" + username + "' has been activated", { process: process.pid }); - return resolve(); - }).catch(function (error) { - return reject(error); - }); - }); + throw new Error("No user exists with the specified details"); + // Clear the user's activation + var result = yield this._userCollection.updateOne({ _id: user.dbEntry._id }, { $set: { registerKey: "" } }); + // Send activated event + var sEvent = { username: username, eventType: socket_event_types_1.EventType.Activated, error: undefined }; + yield comms_controller_1.CommsController.singleton.broadcastEventToAll(sEvent); + winston.info(`User '${username}' has been activated`, { process: process.pid }); + return; }); - }; + } /** * Attempts to send the an email to the admin user * @param {string} message The message body @@ -286,99 +277,96 @@ var UserManager = (function () { * @param {string} from The email of the sender * @returns {Promise} */ - UserManager.prototype.sendAdminEmail = function (message, name, from) { - var that = this; - return new Promise(function (resolve, reject) { - if (!that._mailer) - reject(new Error("No email account has been setup")); - that._mailer.sendMail(that._config.adminUser.email, that._config.google.mail.from, "Message from " + (name ? name : "a user"), message + "

Email: " + (from ? from : "")).then(function () { - return resolve(true); - }).catch(function (err) { - return reject(new Error("Could not send email to user: " + err.message)); - }); + sendAdminEmail(message, name, from) { + return __awaiter(this, void 0, Promise, function* () { + if (!this._mailer) + throw new Error(`No email account has been setup`); + try { + yield this._mailer.sendMail(this._config.adminUser.email, this._config.google.mail.from, `Message from ${(name ? name : "a user")}`, message + "

Email: " + (from ? from : "")); + } + catch (err) { + new Error(`Could not send email to user: ${err.message}`); + } + return true; }); - }; + } /** * Attempts to resend the activation link * @param {string} username The username of the user * @param {string} origin The origin of where the request came from (this is emailed to the user) * @returns {Promise} */ - UserManager.prototype.resendActivation = function (username, origin) { - var that = this; - return new Promise(function (resolve, reject) { + resendActivation(username, origin) { + return __awaiter(this, void 0, Promise, function* () { // Get the user - that.getUser(username).then(function (user) { - if (!user) - throw new Error("No user exists with the specified details"); - if (user.dbEntry.registerKey == "") - throw new Error("Account has already been activated"); - var newKey = user.generateKey(); - user.dbEntry.registerKey = newKey; - // Update the collection with a new key - that._userCollection.updateOne({ _id: user.dbEntry._id }, { $set: { registerKey: newKey } }).then(function (result) { - // Send a message to the user to say they are registered but need to activate their account - var message = "Thank you for registering with Webinate!\n\t\t\t\t\tTo activate your account please click the link below:\n\n\t\t\t\t\t" + that.createActivationLink(user, origin) + "\n\n\t\t\t\t\tThanks\n\t\t\t\t\tThe Webinate Team"; - // If no mailer is setup - if (!that._mailer) - reject(new Error("No email account has been setup")); - // Send mail using the mailer - that._mailer.sendMail(user.dbEntry.email, that._config.google.mail.from, "Activate your account", message).then(function () { - return resolve(true); - }).catch(function (err) { - reject(new Error("Could not send email to user: " + err.message)); - }); - }).catch(function (error) { - return reject(error); - }); - }).catch(function (error) { - reject(error); - }); + var user = yield this.getUser(username); + if (!user) + throw new Error("No user exists with the specified details"); + if (user.dbEntry.registerKey == "") + throw new Error("Account has already been activated"); + var newKey = user.generateKey(); + user.dbEntry.registerKey = newKey; + // Update the collection with a new key + var result = yield this._userCollection.updateOne({ _id: user.dbEntry._id }, { $set: { registerKey: newKey } }); + // Send a message to the user to say they are registered but need to activate their account + var message = "Thank you for registering with Webinate!\nTo activate your account please click the link below:" + + this.createActivationLink(user, origin) + + "Thanks\n\n" + + "The Webinate Team"; + // If no mailer is setup + if (!this._mailer) + throw new Error(`No email account has been setup`); + try { + // Send mail using the mailer + yield this._mailer.sendMail(user.dbEntry.email, this._config.google.mail.from, "Activate your account", message); + } + catch (err) { + new Error(`Could not send email to user: ${err.message}`); + } + return true; }); - }; + } /** * Sends the user an email with instructions on how to reset their password * @param {string} username The username of the user * @param {string} origin The site where the request came from * @returns {Promise} */ - UserManager.prototype.requestPasswordReset = function (username, origin) { - var that = this; - return new Promise(function (resolve, reject) { + requestPasswordReset(username, origin) { + return __awaiter(this, void 0, Promise, function* () { // Get the user - that.getUser(username).then(function (user) { - if (!user) - throw new Error("No user exists with the specified details"); - var newKey = user.generateKey(); - // Password token - user.dbEntry.passwordTag = newKey; - // Update the collection with a new key - that._userCollection.updateOne({ _id: user.dbEntry._id }, { $set: { passwordTag: newKey } }).then(function (result) { - // Send a message to the user to say they are registered but need to activate their account - var message = "A request has been made to reset your password.\n\t\t\t\t\tTo change your password please click the link below:\n\n\t\t\t\t\t" + that.createResetLink(user, origin) + "\n\n\t\t\t\t\tThanks\n\t\t\t\t\tThe Webinate Team"; - // If no mailer is setup - if (!that._mailer) - reject(new Error("No email account has been setup")); - // Send mail using the mailer - that._mailer.sendMail(user.dbEntry.email, that._config.google.mail.from, "Reset Password", message).then(function () { - return resolve(true); - }).catch(function (err) { - reject(new Error("Could not send email to user: " + err.message)); - }); - }).catch(function (error) { - return reject(error); - }); - }).catch(function (error) { - reject(error); - }); + var user = yield this.getUser(username); + if (!user) + throw new Error("No user exists with the specified details"); + var newKey = user.generateKey(); + // Password token + user.dbEntry.passwordTag = newKey; + // Update the collection with a new key + var result = yield this._userCollection.updateOne({ _id: user.dbEntry._id }, { $set: { passwordTag: newKey } }); + // Send a message to the user to say they are registered but need to activate their account + var message = "A request has been made to reset your password. To change your password please click the link below:\n\n" + + this.createResetLink(user, origin) + + "Thanks\n\n" + + "The Webinate Team"; + // If no mailer is setup + if (!this._mailer) + throw new Error(`No email account has been setup`); + // Send mail using the mailer + try { + yield this._mailer.sendMail(user.dbEntry.email, this._config.google.mail.from, "Reset Password", message); + } + catch (err) { + throw new Error(`Could not send email to user: ${err.message}`); + } + return true; }); - }; + } /** * Creates a hashed password * @param {string} pass The password to hash * @returns {Promise} */ - UserManager.prototype.hashPassword = function (pass) { + hashPassword(pass) { return new Promise(function (resolve, reject) { bcrypt.hash(pass, 8, function (err, encrypted) { if (err) @@ -387,14 +375,14 @@ var UserManager = (function () { return resolve(encrypted); }); }); - }; + } /** * Compares a password to the stored hash in the database * @param {string} pass The password to test * @param {string} hash The hash stored in the DB * @returns {Promise} */ - UserManager.prototype.comparePassword = function (pass, hash) { + comparePassword(pass, hash) { return new Promise(function (resolve, reject) { bcrypt.compare(pass, hash, function (err, same) { if (err) @@ -403,7 +391,7 @@ var UserManager = (function () { return resolve(same); }); }); - }; + } /** * Attempts to reset a user's password. * @param {string} username The username of the user @@ -411,117 +399,92 @@ var UserManager = (function () { * @param {string} newPassword The new password * @returns {Promise} */ - UserManager.prototype.resetPassword = function (username, code, newPassword) { - var that = this; - return new Promise(function (resolve, reject) { - var user; + resetPassword(username, code, newPassword) { + return __awaiter(this, void 0, Promise, function* () { // Get the user - that.getUser(username).then(function (selectedUser) { - user = selectedUser; - // No user - so invalid - if (!user) - return Promise.reject(new Error("No user exists with those credentials")); - // If key is the same - if (user.dbEntry.passwordTag != code) - return Promise.reject(new Error("Password codes do not match. Please try resetting your password again")); - // Make sure password is valid - if (newPassword === undefined || newPassword == "" || validator.blacklist(newPassword, "@\'\"{}") != newPassword) - return Promise.reject(new Error("Please enter a valid password")); - return that.hashPassword(newPassword); - }).then(function (hashed) { - // Update the key to be blank - return that._userCollection.updateOne({ _id: user.dbEntry._id }, { $set: { passwordTag: "", password: hashed } }); - }).then(function (result) { - // All done :) - resolve(true); - }).catch(function (error) { - reject(error); - }); + var user = yield this.getUser(username); + // No user - so invalid + if (!user) + throw new Error("No user exists with those credentials"); + // If key is the same + if (user.dbEntry.passwordTag != code) + throw new Error("Password codes do not match. Please try resetting your password again"); + // Make sure password is valid + if (newPassword === undefined || newPassword == "" || validator.blacklist(newPassword, "@\'\"{}") != newPassword) + throw new Error("Please enter a valid password"); + var hashed = yield this.hashPassword(newPassword); + // Update the key to be blank + var result = yield this._userCollection.updateOne({ _id: user.dbEntry._id }, { $set: { passwordTag: "", password: hashed } }); + // All done :) + return true; }); - }; + } /** * Checks the users activation code to see if its valid * @param {string} username The username of the user * @returns {Promise} */ - UserManager.prototype.checkActivation = function (username, code) { - var that = this; - return new Promise(function (resolve, reject) { + checkActivation(username, code) { + return __awaiter(this, void 0, Promise, function* () { // Get the user - that.getUser(username).then(function (user) { - // No user - so invalid - if (!user) - return reject(new Error("No user exists with those credentials")); - // If key is already blank - then its good to go - if (user.dbEntry.registerKey == "") - return resolve(true); - // Check key - if (user.dbEntry.registerKey != code) - return reject(new Error("Activation key is not valid. Please try send another.")); - // Update the key to be blank - that._userCollection.updateOne({ _id: user.dbEntry._id }, { $set: { registerKey: "" } }).then(function (result) { - // Send activated event - var sEvent = { username: username, eventType: socket_event_types_1.EventType.Activated, error: undefined }; - return comms_controller_1.CommsController.singleton.broadcastEventToAll(sEvent); - }).then(function () { - winston.info("User '" + username + "' has been activated", { process: process.pid }); - return resolve(true); - }).catch(function (err) { - return reject(err); - }); - }).catch(function (error) { - reject(error); - }); + var user = yield this.getUser(username); + // No user - so invalid + if (!user) + throw new Error("No user exists with those credentials"); + // If key is already blank - then its good to go + if (user.dbEntry.registerKey == "") + return true; + // Check key + if (user.dbEntry.registerKey != code) + throw new Error("Activation key is not valid. Please try send another."); + // Update the key to be blank + yield this._userCollection.updateOne({ _id: user.dbEntry._id }, { $set: { registerKey: "" } }); + // Send activated event + var sEvent = { username: username, eventType: socket_event_types_1.EventType.Activated, error: undefined }; + yield comms_controller_1.CommsController.singleton.broadcastEventToAll(sEvent); + winston.info(`User '${username}' has been activated`, { process: process.pid }); + return true; }); - }; + } /** * Creates the script tag for the Google captcha API * @param {string} */ - UserManager.prototype.getCaptchaHTML = function () { + getCaptchaHTML() { var captchaChecker = new recaptcha.reCaptcha(); return captchaChecker.getCaptchaHtml(this._config.captchaPublicKey, "", this._config.ssl); - }; + } /** * Checks to see if a user is logged in * @param {http.ServerRequest} request * @param {http.ServerResponse} response * @param {Promise} Gets the user or null if the user is not logged in */ - UserManager.prototype.loggedIn = function (request, response) { - var that = this; - return new Promise(function (resolve, reject) { + loggedIn(request, response) { + return __awaiter(this, void 0, Promise, function* () { // If no request or response, then assume its an admin user - that.sessionManager.getSession(request, response).then(function (session) { - if (!session) - return resolve(null); - return that._userCollection.find({ sessionId: session.sessionId }).limit(1).next(); - }).then(function (useEntry) { - if (!useEntry) - return resolve(null); - else - return resolve(new User(useEntry)); - }).catch(function (error) { - return reject(error); - }); + var session = yield this.sessionManager.getSession(request, response); + if (!session) + return null; + var useEntry = yield this._userCollection.find({ sessionId: session.sessionId }).limit(1).next(); + if (!useEntry) + return null; + else + return new User(useEntry); }); - }; + } /** * Attempts to log the user out * @param {http.ServerRequest} request * @param {http.ServerResponse} response * @returns {Promise} */ - UserManager.prototype.logOut = function (request, response) { - var that = this; - return new Promise(function (resolve, reject) { - that.sessionManager.clearSession(null, request, response).then(function (cleared) { - resolve(cleared); - }).catch(function (error) { - reject(error); - }); + logOut(request, response) { + return __awaiter(this, void 0, Promise, function* () { + var sessionCleaered = yield this.sessionManager.clearSession(null, request, response); + return sessionCleaered; }); - }; + } /** * Creates a new user * @param {string} user The unique username @@ -533,132 +496,108 @@ var UserManager = (function () { * @param {boolean} allowAdmin Should this be allowed to create a super user * @returns {Promise} */ - UserManager.prototype.createUser = function (user, email, password, origin, privilege, meta, allowAdmin) { - if (privilege === void 0) { privilege = UserPrivileges.Regular; } - if (meta === void 0) { meta = {}; } - if (allowAdmin === void 0) { allowAdmin = false; } - var that = this; - return new Promise(function (resolve, reject) { + createUser(user, email, password, origin, privilege = UserPrivileges.Regular, meta = {}, allowAdmin = false) { + return __awaiter(this, void 0, Promise, function* () { // Basic checks if (!user || validator.trim(user) == "") - return reject(new Error("Username cannot be empty")); + throw new Error("Username cannot be empty"); if (!validator.isAlphanumeric(user)) - return reject(new Error("Username must be alphanumeric")); + throw new Error("Username must be alphanumeric"); if (!email || validator.trim(email) == "") - return reject(new Error("Email cannot be empty")); + throw new Error("Email cannot be empty"); if (!validator.isEmail(email)) - return reject(new Error("Email must be valid")); + throw new Error("Email must be valid"); if (!password || validator.trim(password) == "") - return reject(new Error("Password cannot be empty")); + throw new Error("Password cannot be empty"); if (privilege > 3) - return reject(new Error("Privilege type is unrecognised")); + throw new Error("Privilege type is unrecognised"); if (privilege == UserPrivileges.SuperAdmin && allowAdmin == false) - return reject(new Error("You cannot create a super user")); - var hashedPsw; - var newUser; + throw new Error("You cannot create a super user"); // Check if the user already exists - that.hashPassword(password).then(function (hashedPassword) { - hashedPsw = hashedPassword; - return that.getUser(user, email); - }).then(function (existingUser) { - if (existingUser) - return Promise.reject(new Error("A user with that name or email already exists")); - // Create the user - newUser = new User({ - username: user, - password: hashedPsw, - email: email, - privileges: privilege, - passwordTag: "", - meta: meta - }); - // Update the database - return that._userCollection.insertOne(newUser.generateDbEntry()); - }).then(function (insertResult) { - // Assing the ID and pass the user on - newUser.dbEntry = insertResult.ops[0]; - // Send a message to the user to say they are registered but need to activate their account - var message = "Thank you for registering with Webinate!\n To activate your account please click the link below:\n\n " + that.createActivationLink(newUser, origin) + "\n\n Thanks\n The Webinate Team"; - // If no mailer is setup - if (!that._mailer) - return Promise.reject(new Error("No email account has been setup")); - // Send mail using the mailer - return that._mailer.sendMail(newUser.dbEntry.email, that._config.google.mail.from, "Activate your account", message); - }).then(function () { - // All users have default stats created for them - return bucket_manager_1.BucketManager.get.createUserStats(newUser.dbEntry.username); - }).then(function () { - // All users have a bucket created for them - return bucket_manager_1.BucketManager.get.createBucket(newUser.dbEntry.username + "-bucket", newUser.dbEntry.username); - }).then(function () { - return resolve(newUser); - }).catch(function (error) { - return reject(error); + var hashedPsw = yield this.hashPassword(password); + var existingUser = yield this.getUser(user, email); + if (existingUser) + throw new Error(`A user with that name or email already exists`); + // Create the user + var newUser = new User({ + username: user, + password: hashedPsw, + email: email, + privileges: privilege, + passwordTag: "", + meta: meta }); + // Update the database + var insertResult = yield this._userCollection.insertOne(newUser.generateDbEntry()); + // Assing the ID and pass the user on + newUser.dbEntry = insertResult.ops[0]; + // Send a message to the user to say they are registered but need to activate their account + var message = "Thank you for registering with Webinate! To activate your account please click the link below: \n\n" + + this.createActivationLink(newUser, origin) + "\n\n" + + "Thanks\n" + + "The Webinate Team"; + // If no mailer is setup + if (!this._mailer) + throw new Error(`No email account has been setup`); + // Send mail using the mailer + yield this._mailer.sendMail(newUser.dbEntry.email, this._config.google.mail.from, "Activate your account", message); + // All users have default stats created for them + yield bucket_manager_1.BucketManager.get.createUserStats(newUser.dbEntry.username); + // All users have a bucket created for them + yield bucket_manager_1.BucketManager.get.createBucket(newUser.dbEntry.username + "-bucket", newUser.dbEntry.username); + return newUser; }); - }; + } /** * Deletes a user from the database * @param {string} user The unique username or email of the user to remove * @returns {Promise} */ - UserManager.prototype.removeUser = function (user) { - var that = this; - var username = ""; - return new Promise(function (resolve, reject) { - var existingUser; - that.getUser(user).then(function (user) { - existingUser = user; - if (!user) - return Promise.reject(new Error("Could not find any users with those credentials")); - if (user.dbEntry.privileges == UserPrivileges.SuperAdmin) - return Promise.reject(new Error("You cannot remove a super user")); - username = user.dbEntry.username; - return bucket_manager_1.BucketManager.get.removeUser(user.dbEntry.username); - }).then(function (numDeleted) { - return that._userCollection.deleteOne({ _id: existingUser.dbEntry._id }); - }).then(function (result) { - if (result.result.n == 0) - return reject(new Error("Could not remove the user from the database")); - // Send event to sockets - var sEvent = { username: username, eventType: socket_event_types_1.EventType.Removed, error: undefined }; - comms_controller_1.CommsController.singleton.broadcastEventToAll(sEvent).then(function () { - winston.info("User '" + username + "' has been removed", { process: process.pid }); - }); - return resolve(); - }).catch(function (error) { - reject(error); + removeUser(user) { + return __awaiter(this, void 0, Promise, function* () { + var username = ""; + var userInstance = yield this.getUser(user); + if (!user) + throw new Error("Could not find any users with those credentials"); + if (userInstance.dbEntry.privileges == UserPrivileges.SuperAdmin) + throw new Error("You cannot remove a super user"); + username = userInstance.dbEntry.username; + var numDeleted = yield bucket_manager_1.BucketManager.get.removeUser(username); + var result = yield this._userCollection.deleteOne({ _id: userInstance.dbEntry._id }); + if (result.deletedCount == 0) + throw new Error("Could not remove the user from the database"); + // Send event to sockets + var sEvent = { username: username, eventType: socket_event_types_1.EventType.Removed, error: undefined }; + comms_controller_1.CommsController.singleton.broadcastEventToAll(sEvent).then(function () { + winston.info(`User '${username}' has been removed`, { process: process.pid }); }); + return; }); - }; + } /** * Gets a user by a username or email * @param {string} user The username or email of the user to get * @param {string} email [Optional] Do a check if the email exists as well * @returns {Promise} Resolves with either a valid user or null if none exists */ - UserManager.prototype.getUser = function (user, email) { - var that = this; - email = email != undefined ? email : user; - return new Promise(function (resolve, reject) { + getUser(user, email) { + return __awaiter(this, void 0, Promise, function* () { + email = email != undefined ? email : user; // Validate user string user = validator.trim(user); if (!user || user == "") - return reject(new Error("Please enter a valid username")); + throw new Error("Please enter a valid username"); if (!validator.isAlphanumeric(user) && !validator.isEmail(user)) - return reject(new Error("Please only use alpha numeric characters for your username")); + throw new Error("Please only use alpha numeric characters for your username"); var target = [{ email: email }, { username: user }]; // Search the collection for the user - that._userCollection.find({ $or: target }).limit(1).next().then(function (userEntry) { - if (!userEntry) - return resolve(null); - else - return resolve(new User(userEntry)); - }).catch(function (error) { - return reject(error); - }); + var userEntry = yield this._userCollection.find({ $or: target }).limit(1).next(); + if (!userEntry) + return null; + else + return new User(userEntry); }); - }; + } /** * Attempts to log a user in * @param {string} username The username or email of the user @@ -668,61 +607,41 @@ var UserManager = (function () { * @param {http.ServerResponse} response * @returns {Promise} */ - UserManager.prototype.logIn = function (username, pass, rememberMe, request, response) { - if (username === void 0) { username = ""; } - if (pass === void 0) { pass = ""; } - if (rememberMe === void 0) { rememberMe = true; } - var that = this; - return new Promise(function (resolve, reject) { - var user; - that.logOut(request, response).then(function (success) { - return that.getUser(username); - }).then(function (selectedUser) { - user = selectedUser; - // If no user - then reject - if (!user) - return Promise.reject(new Error("The username or password is incorrect.")); - // Validate password - pass = validator.trim(pass); - if (!pass || pass == "") - return Promise.reject(new Error("Please enter a valid password")); - // Check if the registration key has been removed yet - if (user.dbEntry.registerKey != "") - return Promise.reject(new Error("Please authorise your account by clicking on the link that was sent to your email")); - return that.comparePassword(pass, user.dbEntry.password); - }).then(function (same) { - // Check the password - if (!same) - return Promise.reject(new Error("The username or password is incorrect.")); - // Set the user last login time - user.dbEntry.lastLoggedIn = Date.now(); - // Update the collection - return that._userCollection.updateOne({ _id: user.dbEntry._id }, { $set: { lastLoggedIn: user.dbEntry.lastLoggedIn } }); - }).then(function (result) { - if (result.matchedCount === 0) - return Promise.reject(new Error("Could not find the user in the database, please make sure its setup correctly")); - if (!rememberMe) - return resolve(user); - that.sessionManager.createSession(request, response).then(function (session) { - // Search the collection for the user - if (session instanceof session_1.Session) - return that._userCollection.updateOne({ _id: user.dbEntry._id }, { $set: { sessionId: session.sessionId } }); - }).then(function (result) { - if (result.matchedCount === 0) - return Promise.reject(new Error("Could not find the user in the database, please make sure its setup correctly")); - // Send logged in event to socket - var sEvent = { username: username, eventType: socket_event_types_1.EventType.Login, error: undefined }; - return comms_controller_1.CommsController.singleton.broadcastEventToAll(sEvent); - }).then(function () { - return resolve(user); - }).catch(function (err) { - return reject(err); - }); - }).catch(function (err) { - return reject(err); - }); + logIn(username = "", pass = "", rememberMe = true, request, response) { + return __awaiter(this, void 0, Promise, function* () { + var loggedOut = yield this.logOut(request, response); + var user = yield this.getUser(username); + // If no user - then reject + if (!user) + throw new Error("The username or password is incorrect."); + // Validate password + pass = validator.trim(pass); + if (!pass || pass == "") + throw new Error("Please enter a valid password"); + // Check if the registration key has been removed yet + if (user.dbEntry.registerKey != "") + throw new Error("Please authorise your account by clicking on the link that was sent to your email"); + var passworldValid = yield this.comparePassword(pass, user.dbEntry.password); + if (!passworldValid) + throw new Error("The username or password is incorrect."); + // Set the user last login time + user.dbEntry.lastLoggedIn = Date.now(); + // Update the collection + var result = yield this._userCollection.updateOne({ _id: user.dbEntry._id }, { $set: { lastLoggedIn: user.dbEntry.lastLoggedIn } }); + if (result.matchedCount === 0) + throw new Error("Could not find the user in the database, please make sure its setup correctly"); + if (!rememberMe) + return user; + var session = yield this.sessionManager.createSession(request, response); + result = yield this._userCollection.updateOne({ _id: user.dbEntry._id }, { $set: { sessionId: session.sessionId } }); + if (result.matchedCount === 0) + throw new Error("Could not find the user in the database, please make sure its setup correctly"); + // Send logged in event to socket + var sEvent = { username: username, eventType: socket_event_types_1.EventType.Login, error: undefined }; + yield comms_controller_1.CommsController.singleton.broadcastEventToAll(sEvent); + return user; }); - }; + } /** * Removes a user by his email or username * @param {string} username The username or email of the user @@ -730,48 +649,39 @@ var UserManager = (function () { * @param {http.ServerResponse} response * @returns {Promise} True if the user was in the DB or false if they were not */ - UserManager.prototype.remove = function (username, request, response) { - if (username === void 0) { username = ""; } - var that = this; - return that.getUser(username).then(function (user) { - return new Promise(function (resolve, reject) { - // There was no user - if (!user) - return resolve(false); - // Remove the user from the DB - that._userCollection.deleteOne({ _id: user.dbEntry._id }).then(function (result) { - if (result.result.n === 0) - return resolve(false); - else - return resolve(true); - }).catch(function (error) { - return reject(error); - }); - }); + remove(username = "", request, response) { + return __awaiter(this, void 0, Promise, function* () { + var user = yield this.getUser(username); + // There was no user + if (!user) + return false; + // Remove the user from the DB + var result = yield this._userCollection.deleteOne({ _id: user.dbEntry._id }); + if (result.deletedCount === 0) + return false; + else + return true; }); - }; + } /** * Sets the meta data associated with the user * @param {IUserEntry} user The user * @param {any} data The meta data object to set * @param {http.ServerRequest} request * @param {http.ServerResponse} response - * @returns {Promise} Returns the data set + * @returns {Promise} Returns the data set */ - UserManager.prototype.setMeta = function (user, data, request, response) { - var that = this; - return new Promise(function (resolve, reject) { + setMeta(user, data, request, response) { + return __awaiter(this, void 0, Promise, function* () { + var that = this; // There was no user if (!user) - return reject(false); + return false; // Remove the user from the DB - that._userCollection.updateOne({ _id: user._id }, { $set: { meta: (data ? data : {}) } }).then(function (result) { - return resolve(data); - }).catch(function (error) { - return reject(error); - }); + var result = yield that._userCollection.updateOne({ _id: user._id }, { $set: { meta: (data ? data : {}) } }); + return data; }); - }; + } /** * Sets a meta value on the user. This updates the user's meta value by name * @param {IUserEntry} user The user @@ -779,84 +689,72 @@ var UserManager = (function () { * @param {any} data The value of the meta to set * @param {http.ServerRequest} request * @param {http.ServerResponse} response - * @returns {Promise} Returns the value of the set + * @returns {Promise} Returns the value of the set */ - UserManager.prototype.setMetaVal = function (user, name, val, request, response) { - var that = this; - return new Promise(function (resolve, reject) { + setMetaVal(user, name, val, request, response) { + return __awaiter(this, void 0, Promise, function* () { + var that = this; // There was no user if (!user) - return resolve(false); + return false; var datum = "meta." + name; var updateToken = { $set: {} }; updateToken.$set[datum] = val; // Remove the user from the DB - that._userCollection.updateOne({ _id: user._id }, updateToken).then(function (result) { - return resolve(val); - }).catch(function (error) { - return reject(error); - }); + var result = yield that._userCollection.updateOne({ _id: user._id }, updateToken); + return val; }); - }; + } /** * Gets the value of user's meta by name * @param {IUserEntry} user The user * @param {any} name The name of the meta to get * @param {http.ServerRequest} request * @param {http.ServerResponse} response - * @returns {Promise} The value to get + * @returns {Promise} The value to get */ - UserManager.prototype.getMetaVal = function (user, name, request, response) { - var that = this; - return new Promise(function (resolve, reject) { + getMetaVal(user, name, request, response) { + return __awaiter(this, void 0, Promise, function* () { + var that = this; // There was no user if (!user) - return resolve(false); + return false; // Remove the user from the DB - that._userCollection.find({ _id: user._id }).project({ _id: 0, meta: 1 }).limit(1).next().then(function (result) { - return resolve(result.meta[name]); - }).catch(function (error) { - return reject(error); - }); + var result = yield that._userCollection.find({ _id: user._id }).project({ _id: 0, meta: 1 }).limit(1).next(); + return result.meta[name]; }); - }; + } /** * Gets the meta data of a user * @param {IUserEntry} user The user * @param {http.ServerRequest} request * @param {http.ServerResponse} response - * @returns {Promise} The value to get + * @returns {Promise} The value to get */ - UserManager.prototype.getMetaData = function (user, request, response) { - var that = this; - return new Promise(function (resolve, reject) { + getMetaData(user, request, response) { + return __awaiter(this, void 0, Promise, function* () { + var that = this; // There was no user if (!user) - return resolve(false); + return false; // Remove the user from the DB - that._userCollection.find({ _id: user._id }).project({ _id: 0, meta: 1 }).limit(1).next().then(function (result) { - return resolve(result.meta); - }).catch(function (error) { - return reject(error); - }); + var result = yield that._userCollection.find({ _id: user._id }).project({ _id: 0, meta: 1 }).limit(1).next(); + return result.meta; }); - }; + } /** * Gets the total number of users * @param {RegExp} searchPhrases Search phrases * @returns {Promise} */ - UserManager.prototype.numUsers = function (searchPhrases) { - var that = this; - return new Promise(function (resolve, reject) { + numUsers(searchPhrases) { + return __awaiter(this, void 0, Promise, function* () { + var that = this; var findToken = { $or: [{ username: searchPhrases }, { email: searchPhrases }] }; - that._userCollection.count(findToken, function (error, result) { - if (error) - return reject(error); - resolve(result); - }); + var result = yield that._userCollection.count(findToken); + return result; }); - }; + } /** * Prints user objects from the database * @param {number} limit The number of users to fetch @@ -864,38 +762,27 @@ var UserManager = (function () { * @param {RegExp} searchPhrases Search phrases * @returns {Promise>} */ - UserManager.prototype.getUsers = function (startIndex, limit, searchPhrases) { - if (startIndex === void 0) { startIndex = 0; } - if (limit === void 0) { limit = 0; } - var that = this; - return new Promise(function (resolve, reject) { + getUsers(startIndex = 0, limit = 0, searchPhrases) { + return __awaiter(this, void 0, Promise, function* () { var findToken = { $or: [{ username: searchPhrases }, { email: searchPhrases }] }; - that._userCollection.find(findToken).skip(startIndex).limit(limit).toArray().then(function (results) { - var users = []; - for (var i = 0, l = results.length; i < l; i++) - users.push(new User(results[i])); - resolve(users); - }).catch(function (error) { - return reject(error); - }); + var results = yield this._userCollection.find(findToken).skip(startIndex).limit(limit).toArray(); + var users = []; + for (var i = 0, l = results.length; i < l; i++) + users.push(new User(results[i])); + return users; }); - }; + } /** * Creates the user manager singlton */ - UserManager.create = function (users, sessions, config) { + static create(users, sessions, config) { return new UserManager(users, sessions, config); - }; - Object.defineProperty(UserManager, "get", { - /** - * Gets the user manager singlton - */ - get: function () { - return UserManager._singleton; - }, - enumerable: true, - configurable: true - }); - return UserManager; -})(); + } + /** + * Gets the user manager singlton + */ + static get get() { + return UserManager._singleton; + } +} exports.UserManager = UserManager;