diff --git a/src/bucket-manager.ts b/src/bucket-manager.ts index 24156a0..9c61779 100644 --- a/src/bucket-manager.ts +++ b/src/bucket-manager.ts @@ -607,7 +607,7 @@ export class BucketManager removeFilesByBucket(bucket: string): Promise|Error> { if (!bucket || bucket.trim() == "") - return Promise.reject( new Error("Please specify a valid bucket")); + 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 }] }; @@ -738,7 +738,7 @@ export class BucketManager that.withinAPILimit(file.user).then(function (val) : Promise { if (!val) - return Promise.reject(new Error("You do not have enough API calls left to make this request")); + return Promise.reject(new Error("You do not have enough API calls left to make this request")); return that.incrementAPI(file.user); @@ -778,7 +778,7 @@ export class BucketManager that.withinAPILimit(file.user).then(function (val) : Promise { if (!val) - return Promise.reject( new Error("You do not have enough API calls left to make this request")); + return Promise.reject( new Error("You do not have enough API calls left to make this request")); return that.incrementAPI(file.user); diff --git a/src/controllers/bucket-controller.ts b/src/controllers/bucket-controller.ts index 3bd7299..e6f0d95 100644 --- a/src/controllers/bucket-controller.ts +++ b/src/controllers/bucket-controller.ts @@ -267,7 +267,7 @@ export class BucketController extends Controller manager.getFile(req.params.file, req._user.dbEntry.username).then(function(file) : Promise { 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); @@ -492,7 +492,7 @@ export class BucketController extends Controller manager.getIBucket(req.params.bucket, req._user.dbEntry.username).then(function(bucket) : Promise { 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 }); @@ -623,12 +623,12 @@ export class BucketController extends Controller 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: boolean ) : Promise { 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); diff --git a/src/definitions/required/es6-promise.d.ts b/src/definitions/required/es6-promise.d.ts deleted file mode 100644 index 4c9a5e1..0000000 --- a/src/definitions/required/es6-promise.d.ts +++ /dev/null @@ -1,74 +0,0 @@ -// Type definitions for es6-promise -// Project: https://github.com/jakearchibald/ES6-Promise -// Definitions by: François de Campredon , vvakame -// Definitions: https://github.com/borisyankov/DefinitelyTyped - -interface Thenable -{ - then(onFulfilled?: (value: R) => U | Thenable, onRejected?: (error: any) => U | Thenable): Thenable; -} - -declare class Promise implements Thenable { - /** - * If you call resolve in the body of the callback passed to the constructor, - * your promise is fulfilled with result object passed to resolve. - * If you call reject your promise is rejected with the object passed to resolve. - * For consistency and debugging (eg stack traces), obj should be an instanceof Error. - * Any errors thrown in the constructor callback will be implicitly passed to reject(). - */ - constructor(callback: (resolve: (value?: R | Thenable) => void, reject: (error?: any) => void) => void); - - /** - * onFulfilled is called when/if "promise" resolves. onRejected is called when/if "promise" rejects. - * Both are optional, if either/both are omitted the next onFulfilled/onRejected in the chain is called. - * Both callbacks have a single parameter , the fulfillment value or rejection reason. - * "then" returns a new promise equivalent to the value you return from onFulfilled/onRejected after being passed through Promise.resolve. - * If an error is thrown in the callback, the returned promise rejects with that error. - * - * @param onFulfilled called when/if "promise" resolves - * @param onRejected called when/if "promise" rejects - */ - then(onFulfilled?: (value: R) => U | Thenable, onRejected?: (error: any) => U | Thenable): Promise; - - /** - * Sugar for promise.then(undefined, onRejected) - * - * @param onRejected called when/if "promise" rejects - */ - catch(onRejected?: (error: any) => U | Thenable): Promise; -} - -declare module Promise -{ - /** - * Make a new promise from the thenable. - * A thenable is promise-like in as far as it has a "then" method. - */ - function resolve(value?: R | Thenable): Promise; - - /** - * Make a promise that rejects to obj. For consistency and debugging (eg stack traces), obj should be an instanceof Error - */ - function reject(error: any): Promise; - - /** - * Make a promise that fulfills when every item in the array fulfills, and rejects if (and when) any item rejects. - * the array passed to all can be a mixture of promise-like objects and other objects. - * The fulfillment value is an array (in order) of fulfillment values. The rejection value is the first rejection value. - */ - function all(promises: (R | Thenable)[]): Promise; - - /** - * Make a Promise that fulfills when any item fulfills, and rejects if any item rejects. - */ - function race(promises: (R | Thenable)[]): Promise; -} - -declare module 'es6-promise' { - var foo: typeof Promise; // Temp variable to reference Promise in local context - module rsvp - { - export var Promise: typeof foo; - } - export = rsvp; -} \ No newline at end of file diff --git a/src/permission-controller.ts b/src/permission-controller.ts index 44cd47a..fdb63a6 100644 --- a/src/permission-controller.ts +++ b/src/permission-controller.ts @@ -107,27 +107,22 @@ export function requireUser(req: def.AuthRequest, res: express.Response, next: F * @param {string} existingUser [Optional] If specified this also checks if the authenticated user is the user making the request * @param {Function} next */ -export function requestHasPermission(level: UserPrivileges, req: def.AuthRequest, res: express.Response, existingUser?: string): Promise +export async function requestHasPermission(level: UserPrivileges, req: def.AuthRequest, res: express.Response, existingUser?: string): Promise { - return new Promise(function (resolve, reject) - { - UserManager.get.loggedIn(req, res).then(function (user) - { - if (!user) - return reject(new Error("You must be logged in to make this request")); + var user = await UserManager.get.loggedIn(req, res); - 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")); + if (!user) + throw new Error("You must be logged in to make this request"); - req._user = user; + 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"); - resolve(true); + req._user = user; - }) - }) + return true; } \ No newline at end of file diff --git a/src/session.ts b/src/session.ts index 65a7af4..ac7ac47 100644 --- a/src/session.ts +++ b/src/session.ts @@ -76,19 +76,10 @@ export class SessionManager extends EventEmitter * @param {number} startIndex * @param {number} limit */ - numActiveSessions(startIndex?: number, limit?: number): Promise + async numActiveSessions(startIndex?: number, limit?: number): Promise { - var that = this; - return new Promise(function (resolve, reject) - { - that._dbCollection.count({}, function (error: Error, count: number) - { - if (error) - return reject(error); - - resolve(count); - }) - }); + var result = await this._dbCollection.count({}); + return result; } /** @@ -96,18 +87,10 @@ export class SessionManager extends EventEmitter * @param {number} startIndex * @param {number} limit */ - getActiveSessions(startIndex?: number, limit: number = -1): Promise> + async getActiveSessions(startIndex?: number, limit: number = -1): Promise> { - var that = this; - - return new Promise>(function (resolve, reject) - { - that._dbCollection.find({}).skip(startIndex).limit(limit).toArray().then(function (results: Array) { - resolve(results); - }).catch(function(error: Error){ - return reject(error); - }); - }); + var results : Array = await this._dbCollection.find({}).skip(startIndex).limit(limit).toArray(); + return results; } /** @@ -117,46 +100,33 @@ export class SessionManager extends EventEmitter * @param {http.ServerResponse} response * @returns {Promise} */ - clearSession(sessionId: string, request: http.ServerRequest, response: http.ServerResponse): Promise + async clearSession(sessionId: string, request: http.ServerRequest, response: http.ServerResponse): Promise { - var that = this; + // Check if the request has a valid session ID + var sId: string = sessionId || this.getIDFromRequest(request); - return new Promise((resolve, reject) => + if (sId != "") { - // Check if the request has a valid session ID - var sId: string = sessionId || that.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: ISessionEntry) { - - // 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: any) { + // We have a session ID, lets try to find it in the DB + var sessionDB: ISessionEntry = await this._dbCollection.find({ sessionId: sId }).limit(1).next(); - that.emit("sessionRemoved", sId); + // Create a new session + var session = new Session(sId, this._options); + session.expiration = -1; - // Set the session cookie header - response.setHeader('Set-Cookie', session.getSetCookieHeaderValue()); + // Adds / updates the DB with the new session + var result = await this._dbCollection.deleteOne({ sessionId: session.sessionId }); - // Resolve the request - resolve(true); + this.emit("sessionRemoved", sId); - }).catch(function(err: Error){ - reject(err); - }); + // Set the session cookie header + response.setHeader('Set-Cookie', session.getSetCookieHeaderValue()); - }).catch(function(err: Error){ - reject(err); - }); - } - else - resolve(true); - }); + // Resolve the request + return true; + } + else + return true; } /** @@ -165,53 +135,40 @@ export class SessionManager extends EventEmitter * @param {http.ServerResponse} response * @returns {Promise} Returns a session or null if none can be found */ - getSession(request: http.ServerRequest, response: http.ServerResponse): Promise + async getSession(request: http.ServerRequest, response: http.ServerResponse): Promise { - var that = this; + // Check if the request has a valid session ID + var sessionId: string = this.getIDFromRequest(request); - return new Promise( (resolve, reject) => + if (sessionId != "") { - // Check if the request has a valid session ID - var sessionId: string = that.getIDFromRequest(request); + // We have a session ID, lets try to find it in the DB + var sessionDB: ISessionEntry = await this._dbCollection.find({ sessionId: sessionId }).limit(1).next(); - 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: ISessionEntry) { - // 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: Error){ - return reject(err); - }); - } - }).catch(function(err: Error){ - reject(err); - }); - } - else - // Resolve with no session data - resolve(null); - }); + // 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 = await 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 + return null; } /** @@ -219,27 +176,18 @@ export class SessionManager extends EventEmitter * @param {http.ServerRequest} request * @returns {Promise} */ - createSession(request: http.ServerRequest, response?: http.ServerResponse): Promise + async createSession(request: http.ServerRequest, response?: http.ServerResponse): Promise { - var that = this; - - return new Promise(function (resolve, reject) - { - var session = new Session(that.createID(), that._options, null); + 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()); + // Adds / updates the DB with the new session + var insertResult = await this._dbCollection.insertOne(session.save()); - // Resolve the request - resolve(session); + // Set the session cookie header + response.setHeader('Set-Cookie', session.getSetCookieHeaderValue()); - }).catch(function(err: Error){ - reject(err); - }); - }); + // Resolve the request + return session; } /** @@ -247,64 +195,54 @@ export class SessionManager extends EventEmitter * 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 */ - cleanup(force: boolean = false) + async cleanup(force: boolean = false) { - var that = this; var now: number = +new Date; var next: number = Infinity; - this._timeout = 0; - that._dbCollection.find(function(err: Error, result: mongodb.Cursor) - { - // If an error occurs, just try again in 2 minutes - if (err) - that._timeout = setTimeout(that._cleanupProxy, 120000); + try { + + // TODO: We need to replace the findToken with one where mongo looks at the conditions + var findToken = {}; + + var sessions : Array = await this._dbCollection.find(findToken).toArray(); + + // Remove query + var toRemoveQuery: { $or: Array } = { $or: [] }; + + for (var i = 0, l = sessions.length; i < l; i++) + { + var expiration: number = 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 = await 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 { - result.toArray(function (err: Error, sessions: Array) - { - // If an error occurs, just try again in 2 minutes - if (err) - that._timeout = setTimeout(that._cleanupProxy, 120000); - else - { - // Remove query - var toRemoveQuery: { $or: Array } = { $or: [] }; - - for (var i = 0, l = sessions.length; i < l; i++) - { - var expiration: number = 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); - } - } - }); + 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); + } } /** diff --git a/src/users.ts b/src/users.ts index bd4b57b..d6ddfd0 100644 --- a/src/users.ts +++ b/src/users.ts @@ -141,14 +141,13 @@ export class UserManager UserManager._singleton = this; // Create the session manager - this.sessionManager = new SessionManager(sessionCollection, - { - domain: config.sessionDomain, - lifetime: config.sessionLifetime, - path: config.sessionPath, - persistent: config.sessionPersistent, - secure: config.ssl - }); + this.sessionManager = new SessionManager(sessionCollection, { + domain: config.sessionDomain, + lifetime: config.sessionLifetime, + path: config.sessionPath, + persistent: config.sessionPersistent, + secure: config.ssl + }); this.sessionManager.on("sessionRemoved", this.onSessionRemoved.bind(this)); } @@ -157,70 +156,84 @@ export class UserManager * Called whenever a session is removed from the database * @returns {Promise} */ - onSessionRemoved(sessionId: string) + async onSessionRemoved(sessionId: string) { if (!sessionId || sessionId == "") return; - this._userCollection.find({ sessionId: sessionId }).limit(1).next().then( function (useEntry: def.IUserEntry) { - if (useEntry) - { - // Send logged in event to socket - var sEvent: def.SocketEvents.IUserEvent = { username: useEntry.username, eventType: EventType.Logout, error : undefined }; - CommsController.singleton.broadcastEventToAll(sEvent).then(function () - { - winston.info(`User '${useEntry.username}' has logged out`, { process: process.pid }); - }); - } - }); + var useEntry: def.IUserEntry = await this._userCollection.find({ sessionId: sessionId }).limit(1).next(); + if (useEntry) + { + // Send logged in event to socket + var sEvent: def.SocketEvents.IUserEvent = { username: useEntry.username, eventType: EventType.Logout, error : undefined }; + await CommsController.singleton.broadcastEventToAll(sEvent); + winston.info(`User '${useEntry.username}' has logged out`, { process: process.pid }); + } + + return; } /** * Initializes the API * @returns {Promise} */ - initialize(): Promise + async initialize(): Promise { var that = this; var config = this._config; - if (that._config.google.bucket && that._config.google.keyFile) + if (config.google.bucket && config.google.keyFile) { - that._mailer = new Mailer(that._config.debugMode); - that._mailer.initialize(that._config.google.keyFile, that._config.google.mail.apiEmail); + this._mailer = new Mailer(config.debugMode); + this._mailer.initialize(config.google.keyFile, config.google.mail.apiEmail); } - return new Promise(function( resolve, reject ) - { - // Clear all existing indices and then re-add them - that._userCollection.dropIndexes().then(function(){ + // Clear all existing indices and then re-add them + await this._userCollection.dropIndexes(); - // Make sure the user collection has an index to search the username field - return that._userCollection.createIndex( { username: "text", email: "text" } ); + // Make sure the user collection has an index to search the username field + await this._userCollection.createIndex( { username: "text", email: "text" } ); - }).then(function() - { - // See if we have an admin user - return that.getUser(config.adminUser.username); + // See if we have an admin user + var user = await this.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; + // If no admin user exists, so lets try to create one + if (!user) + user = await this.createUser(config.adminUser.username, config.adminUser.email, config.adminUser.password, (config.ssl ? "https://" : "http://") + config.host, UserPrivileges.SuperAdmin, {}, true); - }).then(function(newUser){ - resolve(); + 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} + */ + private checkCaptcha( captchaChallenge : string, captcha: string, request: express.Request ): Promise + { + var that = this; + return new Promise(function(resolve, reject) { + + // Create the captcha checker + var remoteIP: string = request.headers['x-forwarded-for'] || request.connection.remoteAddress; + var privatekey: string = 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.")); - }).catch(function(error: Error){ - return reject(error); + resolve(true); }); - }); - } + + // Check for valid captcha + captchaChecker.checkAnswer(privatekey, remoteIP, captchaChallenge, captcha); + }); + } /** * Attempts to register a new user @@ -234,63 +247,29 @@ export class UserManager * @param {http.ServerResponse} response * @returns {Promise} */ - register(username: string = "", pass: string = "", email: string = "", captcha: string = "", captchaChallenge: string = "", meta: any = {}, request?: express.Request, response?: express.Response): Promise + async register(username: string = "", pass: string = "", email: string = "", captcha: string = "", captchaChallenge: string = "", meta: any = {}, request?: express.Request, response?: express.Response): Promise { - var that = this; var origin = encodeURIComponent( request.headers["origin"] || request.headers["referer"] ); - return new Promise(function (resolve, reject) - { - // First check if user exists, make sure the details supplied are ok, then create the new user - that.getUser(username, email).then(function (user: 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: string = request.headers['x-forwarded-for'] || request.connection.remoteAddress; - var privatekey: string = that._config.captchaPrivateKey; - var captchaChecker = new recaptcha.reCaptcha(); - var newUser: User = 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: Error) - { - return reject(err); - }); - }); - - // Check for valid captcha - captchaChecker.checkAnswer(privatekey, remoteIP, captchaChallenge, captcha); - }); - - }).then(function (user) - { - return resolve(user); + // First check if user exists, make sure the details supplied are ok, then create the new user + var user: User = await this.getUser(username, email); - }).catch(function (error: Error) - { - return reject(error); - }); - }); + // 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 + await this.checkCaptcha( captchaChallenge, captcha, request); + + user = await this.createUser(username, email, pass, origin, UserPrivileges.Regular, meta); + return user; } /** @@ -320,35 +299,23 @@ export class UserManager * @param {string} username The username or email of the user * @returns {Promise} */ - approveActivation(username: string): Promise + async approveActivation(username: string): Promise { - var that = this; - // Get the user - return that.getUser(username).then(function (user: User) - { - 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: def.SocketEvents.IUserEvent = { username: username, eventType: EventType.Activated, error : undefined }; - return CommsController.singleton.broadcastEventToAll(sEvent); - - }).then(function () { - - winston.info(`User '${username}' has been activated`, { process: process.pid }); - return resolve(); - - }).catch(function(error: Error) { - return reject(error); - }); - }); - }); + var user: User = await this.getUser(username); + + if (!user) + throw new Error("No user exists with the specified details"); + + // Clear the user's activation + var result = await this._userCollection.updateOne({ _id: user.dbEntry._id }, { $set: { registerKey: "" } }); + + // Send activated event + var sEvent: def.SocketEvents.IUserEvent = { username: username, eventType: EventType.Activated, error : undefined }; + await CommsController.singleton.broadcastEventToAll(sEvent); + + winston.info(`User '${username}' has been activated`, { process: process.pid }); + return; } /** @@ -358,25 +325,19 @@ export class UserManager * @param {string} from The email of the sender * @returns {Promise} */ - sendAdminEmail(message: string, name? : string, from? : string): Promise + async sendAdminEmail(message: string, name? : string, from? : string): Promise { - 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}`)); - }); - }); + if (!this._mailer) + throw new Error(`No email account has been setup`); + + try { + await 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; } /** @@ -385,61 +346,41 @@ export class UserManager * @param {string} origin The origin of where the request came from (this is emailed to the user) * @returns {Promise} */ - resendActivation(username: string, origin : string): Promise + async resendActivation(username: string, origin : string): Promise { - var that = this; - - return new Promise(function (resolve, reject) - { - // Get the user - that.getUser(username).then(function (user: User) - { - if (!user) - throw new Error("No user exists with the specified details"); + // Get the user + var user : User = await this.getUser(username); - if (user.dbEntry.registerKey == "") - throw new Error("Account has already been activated"); + if (!user) + throw new Error("No user exists with the specified details"); - var newKey = user.generateKey(); - user.dbEntry.registerKey = newKey; + if (user.dbEntry.registerKey == "") + throw new Error("Account has already been activated"); - // Update the collection with a new key - that._userCollection.updateOne({ _id: user.dbEntry._id }, { $set: { registerKey: newKey } }).then(function (result) { + var newKey = user.generateKey(); + user.dbEntry.registerKey = newKey; - // Send a message to the user to say they are registered but need to activate their account - var message: string = `Thank you for registering with Webinate! - To activate your account please click the link below: + // Update the collection with a new key + var result = await this._userCollection.updateOne({ _id: user.dbEntry._id }, { $set: { registerKey: newKey } }); - ${that.createActivationLink(user, origin) } + // Send a message to the user to say they are registered but need to activate their account + var message: string = "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"; - Thanks - The Webinate Team`; + // If no mailer is setup + if (!this._mailer) + throw new Error(`No email account has been setup`); - // 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: Error){ - return reject(error); - }); - - }).catch(function (error: Error) { + try { + // Send mail using the mailer + await 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}`) + } - reject(error); - }); - }); + return true; } /** @@ -448,60 +389,41 @@ export class UserManager * @param {string} origin The site where the request came from * @returns {Promise} */ - requestPasswordReset(username: string, origin: string ): Promise + async requestPasswordReset(username: string, origin: string ): Promise { - var that = this; - - return new Promise(function (resolve, reject) - { - // Get the user - that.getUser(username).then(function (user: User) - { - if (!user) - throw new Error("No user exists with the specified details"); + // Get the user + var user: User = await this.getUser(username); - var newKey = user.generateKey(); + if (!user) + throw new Error("No user exists with the specified details"); - // Password token - user.dbEntry.passwordTag = newKey; + var newKey = user.generateKey(); - // Update the collection with a new key - that._userCollection.updateOne({ _id: user.dbEntry._id }, { $set: { passwordTag: newKey } }).then(function (result) { + // Password token + user.dbEntry.passwordTag = newKey; - // Send a message to the user to say they are registered but need to activate their account - var message: string = `A request has been made to reset your password. - To change your password please click the link below: + // Update the collection with a new key + var result = await this._userCollection.updateOne({ _id: user.dbEntry._id }, { $set: { passwordTag: newKey } }); - ${that.createResetLink(user, origin)} + // Send a message to the user to say they are registered but need to activate their account + var message: string = "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"; - Thanks - The Webinate Team`; + // If no mailer is setup + if (!this._mailer) + throw new Error(`No email account has been setup`); - // 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: Error){ - return reject(error); - }); + // Send mail using the mailer + try { + await 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}`) + } - }).catch(function (error: Error) - { - reject(error); - }); - }); + return true; } /** @@ -550,47 +472,30 @@ export class UserManager * @param {string} newPassword The new password * @returns {Promise} */ - resetPassword(username: string, code: string, newPassword: string): Promise + async resetPassword(username: string, code: string, newPassword: string): Promise { - var that = this; - return new Promise(function (resolve, reject) - { - var user: User; - - // Get the user - that.getUser(username).then(function(selectedUser) : Promise - { - 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")); + // Get the user + var user: User = await this.getUser(username); - // Make sure password is valid - if (newPassword === undefined || newPassword == "" || validator.blacklist(newPassword, "@\'\"{}") != newPassword) - return Promise.reject(new Error("Please enter a valid password")); + // No user - so invalid + if (!user) + throw new Error("No user exists with those credentials"); - return that.hashPassword(newPassword); + // If key is the same + if (user.dbEntry.passwordTag != code) + throw new Error("Password codes do not match. Please try resetting your password again"); - }).then( function(hashed: string) - { - // Update the key to be blank - return that._userCollection.updateOne({ _id: user.dbEntry._id }, { $set: { passwordTag: "", password: hashed } }); + // Make sure password is valid + if (newPassword === undefined || newPassword == "" || validator.blacklist(newPassword, "@\'\"{}") != newPassword) + throw new Error("Please enter a valid password"); - }).then(function (result) { + var hashed = await this.hashPassword(newPassword); - // All done :) - resolve(true); + // Update the key to be blank + var result = await this._userCollection.updateOne({ _id: user.dbEntry._id }, { $set: { passwordTag: "", password: hashed } }); - }).catch(function (error: Error) - { - reject(error); - }); - }); + // All done :) + return true; } /** @@ -598,47 +503,32 @@ export class UserManager * @param {string} username The username of the user * @returns {Promise} */ - checkActivation( username : string, code : string ): Promise + async checkActivation( username : string, code : string ): Promise { - var that = this; - return new Promise(function( resolve, reject ) - { - // 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")); + // Get the user + var user = await this.getUser(username); - // If key is already blank - then its good to go - if (user.dbEntry.registerKey == "") - return resolve(true); + // No user - so invalid + if (!user) + throw new Error("No user exists with those credentials"); - // Check key - if (user.dbEntry.registerKey != code) - return reject(new Error("Activation key is not valid. Please try send another.")); + // If key is already blank - then its good to go + if (user.dbEntry.registerKey == "") + return true; - // Update the key to be blank - that._userCollection.updateOne({ _id: user.dbEntry._id }, { $set: { registerKey: "" } }).then(function (result) { + // Check key + if (user.dbEntry.registerKey != code) + throw new Error("Activation key is not valid. Please try send another."); - // Send activated event - var sEvent: def.SocketEvents.IUserEvent = { username: username, eventType: EventType.Activated, error : undefined }; - return CommsController.singleton.broadcastEventToAll(sEvent); + // Update the key to be blank + await this._userCollection.updateOne({ _id: user.dbEntry._id }, { $set: { registerKey: "" } }); - }).then(function () { + // Send activated event + var sEvent: def.SocketEvents.IUserEvent = { username: username, eventType: EventType.Activated, error : undefined }; + await CommsController.singleton.broadcastEventToAll(sEvent); - winston.info(`User '${username}' has been activated`, { process: process.pid }); - return resolve(true); - - }).catch(function(err){ - return reject(err); - }); - - }).catch(function (error: Error) - { - reject(error); - }); - }); + winston.info(`User '${username}' has been activated`, { process: process.pid }); + return true; } /** @@ -657,31 +547,18 @@ export class UserManager * @param {http.ServerResponse} response * @param {Promise} Gets the user or null if the user is not logged in */ - loggedIn(request: http.ServerRequest, response: http.ServerResponse): Promise + async loggedIn(request: http.ServerRequest, response: http.ServerResponse): Promise { - var that = this; - - return new Promise(function (resolve, reject) - { - // 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: def.IUserEntry) { - - if (!useEntry) - return resolve(null); - else - return resolve(new User(useEntry)); - - }).catch(function (error: Error) - { - return reject(error); - }); - }); + // If no request or response, then assume its an admin user + var session = await this.sessionManager.getSession(request, response); + if (!session) + return null; + + var useEntry = await this._userCollection.find({ sessionId: session.sessionId }).limit(1).next(); + if (!useEntry) + return null; + else + return new User(useEntry); } /** @@ -690,20 +567,10 @@ export class UserManager * @param {http.ServerResponse} response * @returns {Promise} */ - logOut(request: http.ServerRequest, response?: http.ServerResponse): Promise + async logOut(request: http.ServerRequest, response?: http.ServerResponse): Promise { - var that = this; - return new Promise(function (resolve, reject) - { - that.sessionManager.clearSession(null, request, response).then(function (cleared) - { - resolve(cleared); - - }).catch(function (error: Error) - { - reject(error); - }); - }); + var sessionCleaered = await this.sessionManager.clearSession(null, request, response); + return sessionCleaered; } /** @@ -717,92 +584,72 @@ export class UserManager * @param {boolean} allowAdmin Should this be allowed to create a super user * @returns {Promise} */ - createUser(user: string, email: string, password: string, origin: string, privilege: UserPrivileges = UserPrivileges.Regular, meta: any = {}, allowAdmin: boolean = false ): Promise + async createUser(user: string, email: string, password: string, origin: string, privilege: UserPrivileges = UserPrivileges.Regular, meta: any = {}, allowAdmin: boolean = false ): Promise { - var that = this; - - return new Promise(function (resolve, reject) - { - // Basic checks - if (!user || validator.trim(user) == "") return reject(new Error("Username cannot be empty")); - if (!validator.isAlphanumeric(user)) return reject(new Error("Username must be alphanumeric")); - if (!email || validator.trim(email) == "") return reject(new Error("Email cannot be empty")); - if (!validator.isEmail(email)) return reject(new Error("Email must be valid")); - if (!password || validator.trim(password) == "") return reject(new Error("Password cannot be empty")); - if (privilege > 3) return reject(new Error("Privilege type is unrecognised")); - if (privilege == UserPrivileges.SuperAdmin && allowAdmin == false ) return reject(new Error("You cannot create a super user")); - var hashedPsw : string; - var newUser: User; - - // Check if the user already exists - that.hashPassword(password).then(function (hashedPassword: string) - { - hashedPsw = hashedPassword; - return that.getUser(user, email); - - }).then(function(existingUser): Promise - { - 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: mongodb.InsertOneWriteOpResult) : Promise { - - // 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: string = `Thank you for registering with Webinate! - To activate your account please click the link below: - - ${that.createActivationLink(newUser, origin) } - - Thanks - The Webinate Team`; - - // If no mailer is setup - if (!that._mailer) - return Promise.reject(new Error(`No email account has been setup`)); + // Basic checks + if (!user || validator.trim(user) == "") + throw new Error("Username cannot be empty"); + if (!validator.isAlphanumeric(user)) + throw new Error("Username must be alphanumeric"); + if (!email || validator.trim(email) == "") + throw new Error("Email cannot be empty"); + if (!validator.isEmail(email)) + throw new Error("Email must be valid"); + if (!password || validator.trim(password) == "") + throw new Error("Password cannot be empty"); + if (privilege > 3) + throw new Error("Privilege type is unrecognised"); + if (privilege == UserPrivileges.SuperAdmin && allowAdmin == false ) + throw new Error("You cannot create a super user"); + + // Check if the user already exists + var hashedPsw: string = await this.hashPassword(password); + var existingUser = await this.getUser(user, email); + + if (existingUser) + throw new Error(`A user with that name or email already exists`); + + // Create the user + var newUser : User = new User({ + username: user, + password: hashedPsw, + email: email, + privileges: privilege, + passwordTag: "", + meta: meta + }); - // Send mail using the mailer - return that._mailer.sendMail( - newUser.dbEntry.email, - that._config.google.mail.from, - "Activate your account", - message - ); + // Update the database + var insertResult = await this._userCollection.insertOne(newUser.generateDbEntry()); - }).then(function(){ + // Assing the ID and pass the user on + newUser.dbEntry = insertResult.ops[0]; - // All users have default stats created for them - return BucketManager.get.createUserStats(newUser.dbEntry.username); + // Send a message to the user to say they are registered but need to activate their account + var message: string = "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"; - }).then(function(){ + // If no mailer is setup + if (!this._mailer) + throw new Error(`No email account has been setup`); - // All users have a bucket created for them - return BucketManager.get.createBucket(newUser.dbEntry.username + "-bucket", newUser.dbEntry.username); + // Send mail using the mailer + await this._mailer.sendMail( + newUser.dbEntry.email, + this._config.google.mail.from, + "Activate your account", + message + ); - }).then(function(){ + // All users have default stats created for them + await BucketManager.get.createUserStats(newUser.dbEntry.username); - return resolve(newUser); + // All users have a bucket created for them + await BucketManager.get.createBucket(newUser.dbEntry.username + "-bucket", newUser.dbEntry.username); - }).catch(function (error: Error) - { - return reject(error); - }); - }); + return newUser; } /** @@ -810,52 +657,32 @@ export class UserManager * @param {string} user The unique username or email of the user to remove * @returns {Promise} */ - removeUser(user: string): Promise + async removeUser(user: string): Promise { - var that = this; var username: string = ""; + var userInstance = await this.getUser(user); - return new Promise(function (resolve, reject) - { - var existingUser: User; - - that.getUser(user).then(function (user) - { - existingUser = user; + if (!user) + throw new Error("Could not find any users with those credentials"); - 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 BucketManager.get.removeUser(user.dbEntry.username); - - }).then(function (numDeleted) - { - return that._userCollection.deleteOne({ _id: existingUser.dbEntry._id }); + if (userInstance.dbEntry.privileges == UserPrivileges.SuperAdmin) + throw new Error("You cannot remove a super user"); - }).then(function (result) { + username = userInstance.dbEntry.username; - if (result.result.n == 0) - return reject(new Error("Could not remove the user from the database")); + var numDeleted = await BucketManager.get.removeUser(username); + var result = await this._userCollection.deleteOne({ _id: userInstance.dbEntry._id }); - // Send event to sockets - var sEvent: def.SocketEvents.IUserEvent = { username: username, eventType: EventType.Removed, error : undefined }; - CommsController.singleton.broadcastEventToAll(sEvent).then(function () - { - winston.info(`User '${username}' has been removed`, { process: process.pid }); - }); + if (result.deletedCount == 0) + throw new Error("Could not remove the user from the database"); - return resolve(); + // Send event to sockets + var sEvent: def.SocketEvents.IUserEvent = { username: username, eventType: EventType.Removed, error : undefined }; + CommsController.singleton.broadcastEventToAll(sEvent).then(function() { + winston.info(`User '${username}' has been removed`, { process: process.pid }); + }); - }).catch(function (error: Error) - { - reject(error); - }); - }); + return; } /** @@ -864,37 +691,27 @@ export class UserManager * @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 */ - getUser(user: string, email?: string): Promise + async getUser(user: string, email?: string): Promise { - var that = this; - email = email != undefined ? email : user; - return new Promise(function( resolve, reject ) - { - // Validate user string - user = validator.trim(user); + // Validate user string + user = validator.trim(user); - if (!user || user == "") - return reject(new Error("Please enter a valid username")); + if (!user || user == "") + 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")); + if (!validator.isAlphanumeric(user) && !validator.isEmail(user)) + throw new Error("Please only use alpha numeric characters for your username"); - var target = [{ email: email }, { username: user }]; + var target = [{ email: email }, { username: user }]; - // Search the collection for the user - that._userCollection.find({ $or: target }).limit(1).next().then(function (userEntry: def.IUserEntry) { - - if (!userEntry) - return resolve(null); - else - return resolve(new User(userEntry)); - - }).catch(function(error: Error){ - return reject(error); - }); - }); + // Search the collection for the user + var userEntry: def.IUserEntry = await this._userCollection.find({ $or: target }).limit(1).next(); + if (!userEntry) + return null; + else + return new User(userEntry); } /** @@ -906,83 +723,50 @@ export class UserManager * @param {http.ServerResponse} response * @returns {Promise} */ - logIn(username: string = "", pass: string = "", rememberMe: boolean = true, request?: http.ServerRequest, response?: http.ServerResponse): Promise + async logIn(username: string = "", pass: string = "", rememberMe: boolean = true, request?: http.ServerRequest, response?: http.ServerResponse): Promise { - var that = this; - - return new Promise(function (resolve, reject) - { - var user: User; - - that.logOut(request, response).then(function (success: boolean) - { - return that.getUser(username); - - }).then(function (selectedUser) : Promise - { - 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: boolean) : Promise { - // 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 : mongodb.UpdateWriteOpResult) { + var loggedOut = await this.logOut(request, response); + var user: User = await this.getUser(username); - if (result.matchedCount === 0) - return Promise.reject(new Error("Could not find the user in the database, please make sure its setup correctly")); + // If no user - then reject + if (!user) + throw new Error("The username or password is incorrect."); - if (!rememberMe) - return resolve(user); + // Validate password + pass = validator.trim(pass); + if (!pass || pass == "") + throw new Error("Please enter a valid password"); - that.sessionManager.createSession(request, response).then(function (session: Session | User) { + // 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"); - // Search the collection for the user - if (session instanceof Session) - return that._userCollection.updateOne({ _id: user.dbEntry._id }, { $set: { sessionId: session.sessionId } }); + var passworldValid : boolean = await this.comparePassword(pass, user.dbEntry.password); + if (!passworldValid) + throw new Error("The username or password is incorrect."); - }).then( function(result : mongodb.UpdateWriteOpResult) { + // Set the user last login time + user.dbEntry.lastLoggedIn = Date.now(); - if (result.matchedCount === 0) - return Promise.reject(new Error("Could not find the user in the database, please make sure its setup correctly")); + // Update the collection + var result = await this._userCollection.updateOne({ _id: user.dbEntry._id }, { $set: { lastLoggedIn: user.dbEntry.lastLoggedIn } }); - // Send logged in event to socket - var sEvent: def.SocketEvents.IUserEvent = { username: username, eventType: EventType.Login, error : undefined }; - return CommsController.singleton.broadcastEventToAll(sEvent); + if (result.matchedCount === 0) + throw new Error("Could not find the user in the database, please make sure its setup correctly"); - }).then(function () { + if (!rememberMe) + return user; - return resolve(user); + var session: Session = await this.sessionManager.createSession(request, response); + result = await this._userCollection.updateOne({ _id: user.dbEntry._id }, { $set: { sessionId: session.sessionId } }); - }).catch(function (err) { - return reject(err); - }); + if (result.matchedCount === 0) + throw new Error("Could not find the user in the database, please make sure its setup correctly"); - }).catch(function (err) { - return reject(err); - }); - }); + // Send logged in event to socket + var sEvent: def.SocketEvents.IUserEvent = { username: username, eventType: EventType.Login, error : undefined }; + await CommsController.singleton.broadcastEventToAll(sEvent); + return user; } /** @@ -992,30 +776,20 @@ export class UserManager * @param {http.ServerResponse} response * @returns {Promise} True if the user was in the DB or false if they were not */ - remove(username: string = "", request?: http.ServerRequest, response?: http.ServerResponse): Promise + async remove(username: string = "", request?: http.ServerRequest, response?: http.ServerResponse): Promise { - var that = this; + var user = await this.getUser(username); - 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: Error){ - return reject(error); - }); - }); - }); + // There was no user + if (!user) + return false; + + // Remove the user from the DB + var result = await this._userCollection.deleteOne({ _id: user.dbEntry._id }); + if (result.deletedCount === 0) + return false; + else + return true; } /** @@ -1024,25 +798,19 @@ export class UserManager * @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 */ - setMeta(user: def.IUserEntry, data?: any, request?: http.ServerRequest, response?: http.ServerResponse): Promise + async setMeta(user: def.IUserEntry, data?: any, request?: http.ServerRequest, response?: http.ServerResponse): Promise { var that = this; - return new Promise(function (resolve, reject) - { - // There was no user - if (!user) - return reject(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: Error){ - return reject(error); - }); - }); + // There was no user + if (!user) + return false; + + // Remove the user from the DB + var result = await that._userCollection.updateOne({ _id: user._id }, { $set: { meta: ( data ? data : {} ) } }); + return data; } /** @@ -1052,30 +820,23 @@ export class UserManager * @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 */ - setMetaVal(user: def.IUserEntry, name : string, val: any, request?: http.ServerRequest, response?: http.ServerResponse): Promise + async setMetaVal(user: def.IUserEntry, name : string, val: any, request?: http.ServerRequest, response?: http.ServerResponse): Promise { var that = this; - return new Promise(function (resolve, reject) - { - // There was no user - if (!user) - return resolve(false); - - var datum = "meta." + name; + // There was no user + if (!user) + return false; - var updateToken = { $set: {} }; - updateToken.$set[datum] = val; + 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: Error){ - return reject(error); - }); - }); + // Remove the user from the DB + var result = await that._userCollection.updateOne({ _id: user._id }, updateToken); + return val; } /** @@ -1084,26 +845,19 @@ export class UserManager * @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 */ - getMetaVal(user: def.IUserEntry, name: string, request?: http.ServerRequest, response?: http.ServerResponse): Promise + async getMetaVal(user: def.IUserEntry, name: string, request?: http.ServerRequest, response?: http.ServerResponse): Promise { var that = this; - return new Promise(function (resolve, reject) - { - // There was no user - if (!user) - return resolve(false); + // There was no user + if (!user) + 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: def.IUserEntry) - { - return resolve(result.meta[name]); - }).catch(function(error: Error){ - return reject(error); - }); - }); + // Remove the user from the DB + var result: def.IUserEntry = await that._userCollection.find( { _id: user._id }).project({ _id: 0, meta: 1 }).limit(1).next(); + return result.meta[name]; } /** @@ -1111,25 +865,19 @@ export class UserManager * @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 */ - getMetaData(user: def.IUserEntry, request?: http.ServerRequest, response?: http.ServerResponse): Promise + async getMetaData(user: def.IUserEntry, request?: http.ServerRequest, response?: http.ServerResponse): Promise { var that = this; - return new Promise(function (resolve, reject) - { - // There was no user - if (!user) - return resolve(false); - - // Remove the user from the DB - that._userCollection.find({ _id: user._id }).project({ _id: 0, meta: 1 }).limit(1).next().then(function (result: def.IUserEntry) { - return resolve(result.meta); - }).catch(function(error: Error){ - return reject(error); - }); - }); + // There was no user + if (!user) + return false; + + // Remove the user from the DB + var result: def.IUserEntry = await that._userCollection.find({ _id: user._id }).project({ _id: 0, meta: 1 }).limit(1).next(); + return result.meta; } /** @@ -1137,21 +885,12 @@ export class UserManager * @param {RegExp} searchPhrases Search phrases * @returns {Promise} */ - numUsers(searchPhrases?: RegExp): Promise + async numUsers(searchPhrases?: RegExp): Promise { var that = this; - return new Promise(function (resolve, reject) - { - var findToken = { $or: [{ username: searchPhrases }, { email: searchPhrases }] }; - - that._userCollection.count(findToken, function (error: Error, result: number) - { - if (error) - return reject(error); - - resolve(result); - }); - }); + var findToken = { $or: [{ username: searchPhrases }, { email: searchPhrases }] }; + var result: number = await that._userCollection.count(findToken); + return result; } /** @@ -1161,23 +900,15 @@ export class UserManager * @param {RegExp} searchPhrases Search phrases * @returns {Promise>} */ - getUsers(startIndex: number = 0, limit: number = 0, searchPhrases?: RegExp): Promise> + async getUsers(startIndex: number = 0, limit: number = 0, searchPhrases?: RegExp): Promise> { - var that = this; - return new Promise>(function (resolve, reject) - { - var findToken = { $or: [{ username: searchPhrases }, { email: searchPhrases }] }; + var findToken = { $or: [{ username: searchPhrases }, { email: searchPhrases }] }; + var results : Array = await this._userCollection.find(findToken).skip(startIndex).limit(limit).toArray(); + var users: Array = []; + for (var i = 0, l = results.length; i < l; i++) + users.push(new User(results[i])); - that._userCollection.find(findToken).skip(startIndex).limit(limit).toArray().then(function(results: Array){ - var users: Array = []; - for (var i = 0, l = results.length; i < l; i++) - users.push(new User(results[i])); - - resolve(users); - }).catch(function(error: Error){ - return reject(error); - }); - }); + return users; } /**