aboutsummaryrefslogtreecommitdiff
path: root/src/server
diff options
context:
space:
mode:
Diffstat (limited to 'src/server')
-rw-r--r--src/server/ApiManagers/DeleteManager.ts36
-rw-r--r--src/server/ApiManagers/UserManager.ts5
-rw-r--r--src/server/DashUploadUtils.ts2
-rw-r--r--src/server/RouteManager.ts3
-rw-r--r--src/server/authentication/AuthenticationManager.ts117
-rw-r--r--src/server/authentication/DashUserModel.ts7
-rw-r--r--src/server/authentication/Passport.ts35
-rw-r--r--src/server/database.ts131
-rw-r--r--src/server/server_Initialization.ts34
-rw-r--r--src/server/websocket.ts35
10 files changed, 193 insertions, 212 deletions
diff --git a/src/server/ApiManagers/DeleteManager.ts b/src/server/ApiManagers/DeleteManager.ts
index 56d8aff60..c6c4ca464 100644
--- a/src/server/ApiManagers/DeleteManager.ts
+++ b/src/server/ApiManagers/DeleteManager.ts
@@ -1,21 +1,19 @@
-import ApiManager, { Registration } from "./ApiManager";
-import { Method, _permission_denied } from "../RouteManager";
-import { WebSocket } from "../websocket";
-import { Database } from "../database";
-import { rimraf } from "rimraf";
-import { filesDirectory } from "..";
-import { DashUploadUtils } from "../DashUploadUtils";
-import { mkdirSync } from "fs";
-import RouteSubscriber from "../RouteSubscriber";
+import ApiManager, { Registration } from './ApiManager';
+import { Method, _permission_denied } from '../RouteManager';
+import { WebSocket } from '../websocket';
+import { Database } from '../database';
+import { rimraf } from 'rimraf';
+import { filesDirectory } from '..';
+import { DashUploadUtils } from '../DashUploadUtils';
+import { mkdirSync } from 'fs';
+import RouteSubscriber from '../RouteSubscriber';
export default class DeleteManager extends ApiManager {
-
protected initialize(register: Registration): void {
-
register({
method: Method.GET,
requireAdminInRelease: true,
- subscription: new RouteSubscriber("delete").add("target?"),
+ subscription: new RouteSubscriber('delete').add('target?'),
secureHandler: async ({ req, res }) => {
const { target } = req.params;
@@ -24,12 +22,12 @@ export default class DeleteManager extends ApiManager {
} else {
let all = false;
switch (target) {
- case "all":
+ case 'all':
all = true;
- case "database":
+ case 'database':
await WebSocket.doDelete(false);
if (!all) break;
- case "files":
+ case 'files':
rimraf.sync(filesDirectory);
mkdirSync(filesDirectory);
await DashUploadUtils.buildFileDirectories();
@@ -39,10 +37,8 @@ export default class DeleteManager extends ApiManager {
}
}
- res.redirect("/home");
- }
+ res.redirect('/home');
+ },
});
-
}
-
-} \ No newline at end of file
+}
diff --git a/src/server/ApiManagers/UserManager.ts b/src/server/ApiManagers/UserManager.ts
index 9252202b0..0d36ee957 100644
--- a/src/server/ApiManagers/UserManager.ts
+++ b/src/server/ApiManagers/UserManager.ts
@@ -7,6 +7,7 @@ import { Opt } from '../../fields/Doc';
import { WebSocket } from '../websocket';
import { resolvedPorts } from '../server_Initialization';
import { DashVersion } from '../../fields/DocSymbols';
+import { Utils } from '../../Utils';
export const timeMap: { [id: string]: number } = {};
interface ActivityUnit {
@@ -49,7 +50,7 @@ export default class UserManager extends ApiManager {
method: Method.GET,
subscription: '/getUserDocumentIds',
secureHandler: ({ res, user }) => res.send({ userDocumentId: user.userDocumentId, linkDatabaseId: user.linkDatabaseId, sharingDocumentId: user.sharingDocumentId }),
- publicHandler: ({ res }) => res.send({ userDocumentId: '__guest__', linkDatabaseId: 3, sharingDocumentId: 2 }),
+ publicHandler: ({ res }) => res.send({ userDocumentId: Utils.GuestID(), linkDatabaseId: 3, sharingDocumentId: 2 }),
});
register({
@@ -81,7 +82,7 @@ export default class UserManager extends ApiManager {
resolvedPorts,
})
),
- publicHandler: ({ res }) => res.send(JSON.stringify({ id: '__guest__', email: 'guest' })),
+ publicHandler: ({ res }) => res.send(JSON.stringify({ userDocumentId: Utils.GuestID(), email: 'guest', resolvedPorts })),
});
register({
diff --git a/src/server/DashUploadUtils.ts b/src/server/DashUploadUtils.ts
index 643626ae9..2bea15915 100644
--- a/src/server/DashUploadUtils.ts
+++ b/src/server/DashUploadUtils.ts
@@ -200,7 +200,7 @@ export namespace DashUploadUtils {
const category = types[0];
let format = `.${types[1]}`;
- console.log(green(`Processing upload of file (${name}) and format (${format}) with upload type (${type}) in category (${category}).`));
+ console.log(green(`Processing upload of file (${originalFilename}) and format (${format}) with upload type (${type}) in category (${category}).`));
switch (category) {
case 'image':
diff --git a/src/server/RouteManager.ts b/src/server/RouteManager.ts
index 5683cd539..540bca776 100644
--- a/src/server/RouteManager.ts
+++ b/src/server/RouteManager.ts
@@ -1,6 +1,7 @@
import { cyan, green, red } from 'colors';
import { Express, Request, Response } from 'express';
import { AdminPriviliges } from '.';
+import { Utils } from '../Utils';
import { DashUserModel } from './authentication/DashUserModel';
import RouteSubscriber from './RouteSubscriber';
@@ -102,7 +103,7 @@ export default class RouteManager {
let user = req.user as Partial<DashUserModel> | undefined;
const { originalUrl: target } = req;
if (process.env.DB === 'MEM' && !user) {
- user = { id: 'guest', email: 'guest', userDocumentId: '__guest__' };
+ user = { id: 'guest', email: 'guest', userDocumentId: Utils.GuestID() };
}
const core = { req, res, isRelease };
const tryExecute = async (toExecute: (args: any) => any | Promise<any>, args: any) => {
diff --git a/src/server/authentication/AuthenticationManager.ts b/src/server/authentication/AuthenticationManager.ts
index 74d8d2523..5bc6e96b4 100644
--- a/src/server/authentication/AuthenticationManager.ts
+++ b/src/server/authentication/AuthenticationManager.ts
@@ -46,7 +46,7 @@ export let postSignup = (req: Request, res: Response, next: NextFunction) => {
const model = {
email,
password,
- userDocumentId: email === 'guest' ? '__guest__' : Utils.GenerateGuid(),
+ userDocumentId: email === 'guest' ? Utils.GuestID() : Utils.GenerateGuid(),
sharingDocumentId: email === 'guest' ? 2 : Utils.GenerateGuid(),
linkDatabaseId: email === 'guest' ? 3 : Utils.GenerateGuid(),
cacheDocumentIds: '',
@@ -54,25 +54,21 @@ export let postSignup = (req: Request, res: Response, next: NextFunction) => {
const user = new User(model);
- User.findOne({ email }, (err: any, existingUser: any) => {
- if (err) {
- return next(err);
- }
- if (existingUser) {
- return res.redirect('/login');
- }
- user.save().then(undefined, (err: any) => {
- if (err) {
- return next(err);
+ User.findOne({ email })
+ .then(existingUser => {
+ if (existingUser) {
+ return res.redirect('/login');
}
- req.logIn(user, err => {
- if (err) {
- return next(err);
- }
- tryRedirectToTarget(req, res);
- });
- });
- });
+ user.save()
+ .then(() => {
+ req.logIn(user, err => {
+ if (err) return next(err);
+ tryRedirectToTarget(req, res);
+ });
+ })
+ .catch(err => next(err));
+ })
+ .catch(err => next(err));
};
const tryRedirectToTarget = (req: Request, res: Response) => {
@@ -106,7 +102,9 @@ export let getLogin = (req: Request, res: Response) => {
*/
export let postLogin = (req: Request, res: Response, next: NextFunction) => {
if (req.body.email === '') {
- User.findOne({ email: 'guest' }, (err: any, user: DashUserModel) => !user && initializeGuest());
+ User.findOne({ email: 'guest' })
+ .then(user => !user && initializeGuest())
+ .catch(err => err);
req.body.email = 'guest';
req.body.password = 'guest';
} else {
@@ -146,14 +144,7 @@ export let postLogin = (req: Request, res: Response, next: NextFunction) => {
*/
export let getLogout = (req: Request, res: Response) => {
req.logout(emptyFunction);
- const sess = req.session;
- if (sess) {
- sess.destroy(err => {
- if (err) {
- console.log(err);
- }
- });
- }
+ req.session?.destroy(err => err && console.log(err));
res.redirect('/login');
};
@@ -178,7 +169,7 @@ export let postForgot = function (req: Request, res: Response, next: NextFunctio
});
},
function (token: string, done: any) {
- User.findOne({ email }, function (err: any, user: DashUserModel) {
+ User.findOne({ email }).then(user => {
if (!user) {
// NO ACCOUNT WITH SUBMITTED EMAIL
res.redirect('/forgotPassword');
@@ -186,9 +177,7 @@ export let postForgot = function (req: Request, res: Response, next: NextFunctio
}
user.passwordResetToken = token;
user.passwordResetExpires = new Date(Date.now() + 3600000); // 1 HOUR
- user.save().then(undefined, (err: any) => {
- done(null, token, user);
- });
+ user.save().then(() => done(null, token, user));
});
},
function (token: Uint16Array, user: DashUserModel, done: any) {
@@ -227,50 +216,43 @@ export let postForgot = function (req: Request, res: Response, next: NextFunctio
};
export let getReset = function (req: Request, res: Response) {
- User.findOne({ passwordResetToken: req.params.token, passwordResetExpires: { $gt: Date.now() } }, function (err: any, user: DashUserModel) {
- if (!user || err) {
- return res.redirect('/forgotPassword');
- }
- res.render('reset.pug', {
- title: 'Reset Password',
- user: req.user,
- });
- });
+ User.findOne({ passwordResetToken: req.params.token, passwordResetExpires: { $gt: Date.now() } })
+ .then(user => {
+ if (!user) return res.redirect('/forgotPassword');
+ res.render('reset.pug', {
+ title: 'Reset Password',
+ user: req.user,
+ });
+ })
+ .catch(err => res.redirect('/forgotPassword'));
};
export let postReset = function (req: Request, res: Response) {
async.waterfall(
[
function (done: any) {
- User.findOne({ passwordResetToken: req.params.token, passwordResetExpires: { $gt: Date.now() } }, function (err: any, user: DashUserModel) {
- if (!user || err) {
- return res.redirect('back');
- }
+ User.findOne({ passwordResetToken: req.params.token, passwordResetExpires: { $gt: Date.now() } })
+ .then(user => {
+ if (!user) return res.redirect('back');
- req.assert('password', 'Password must be at least 4 characters long').len({ min: 4 });
- req.assert('confirmPassword', 'Passwords do not match').equals(req.body.password);
+ req.assert('password', 'Password must be at least 4 characters long').len({ min: 4 });
+ req.assert('confirmPassword', 'Passwords do not match').equals(req.body.password);
- if (req.validationErrors()) {
- return res.redirect('back');
- }
+ if (req.validationErrors()) return res.redirect('back');
- user.password = req.body.password;
- user.passwordResetToken = undefined;
- user.passwordResetExpires = undefined;
+ user.password = req.body.password;
+ user.passwordResetToken = undefined;
+ user.passwordResetExpires = undefined;
- user.save().then(undefined, (err:any) => {
- if (err) {
- res.redirect('/login');
- return;
- }
- req.logIn(user, function (err) {
- if (err) {
- return;
- }
- });
+ user.save()
+ .then(
+ () => (req as any).logIn(user),
+ (err: any) => err
+ )
+ .catch(err => res.redirect('/login'));
done(null, user);
- });
- });
+ })
+ .catch(err => res.redirect('back'));
},
function (user: DashUserModel, done: any) {
const smtpTransport = nodemailer.createTransport({
@@ -286,9 +268,8 @@ export let postReset = function (req: Request, res: Response) {
subject: 'Your password has been changed',
text: 'Hello,\n\n' + 'This is a confirmation that the password for your account ' + user.email + ' has just been changed.\n',
} as MailOptions;
- smtpTransport.sendMail(mailOptions, function (err) {
- done(null, err);
- });
+
+ smtpTransport.sendMail(mailOptions, err => done(null, err));
},
],
function (err) {
diff --git a/src/server/authentication/DashUserModel.ts b/src/server/authentication/DashUserModel.ts
index a1883beab..dbb7a79ed 100644
--- a/src/server/authentication/DashUserModel.ts
+++ b/src/server/authentication/DashUserModel.ts
@@ -2,6 +2,7 @@
import * as bcrypt from 'bcrypt-nodejs';
//@ts-ignore
import * as mongoose from 'mongoose';
+import { Utils } from '../../Utils';
export type DashUserModel = mongoose.Document & {
email: String;
@@ -25,7 +26,7 @@ export type DashUserModel = mongoose.Document & {
comparePassword: comparePasswordFunction;
};
-type comparePasswordFunction = (candidatePassword: string, cb: (err: any, isMatch: any) => {}) => void;
+type comparePasswordFunction = (candidatePassword: string, cb: (err: any, isMatch: any) => void) => void;
export type AuthToken = {
accessToken: string;
@@ -63,7 +64,7 @@ const userSchema = new mongoose.Schema(
* Password hash middleware.
*/
userSchema.pre('save', function save(next) {
- const user = this as DashUserModel;
+ const user = this as any as DashUserModel;
if (!user.isModified('password')) {
return next();
}
@@ -101,7 +102,7 @@ export function initializeGuest() {
new User({
email: 'guest',
password: 'guest',
- userDocumentId: '__guest__',
+ userDocumentId: Utils.GuestID(),
sharingDocumentId: '2',
linkDatabaseId: '3',
cacheDocumentIds: '',
diff --git a/src/server/authentication/Passport.ts b/src/server/authentication/Passport.ts
index d7f891c34..a9cf6698b 100644
--- a/src/server/authentication/Passport.ts
+++ b/src/server/authentication/Passport.ts
@@ -1,6 +1,6 @@
import * as passport from 'passport';
import * as passportLocal from 'passport-local';
-import { default as User } from './DashUserModel';
+import { DashUserModel, default as User } from './DashUserModel';
const LocalStrategy = passportLocal.Strategy;
@@ -9,21 +9,24 @@ passport.serializeUser<any, any>((req, user, done) => {
});
passport.deserializeUser<any, any>((id, done) => {
- User.findById(id, (err: any, user: any) => {
- done(err, user);
- });
+ User.findById(id)
+ .exec()
+ .then(user => done(undefined, user));
});
// AUTHENTICATE JUST WITH EMAIL AND PASSWORD
-passport.use(new LocalStrategy({ usernameField: 'email', passReqToCallback: true }, (req, email, password, done) => {
- User.findOne({ email: email.toLowerCase() }, (error: any, user: any) => {
- if (error) return done(error);
- if (!user) return done(undefined, false, { message: "Invalid email or password" }); // invalid email
- user.comparePassword(password, (error: Error, isMatch: boolean) => {
- if (error) return done(error);
- if (!isMatch) return done(undefined, false, { message: "Invalid email or password" }); // invalid password
- // valid authentication HERE
- return done(undefined, user);
- });
- });
-})); \ No newline at end of file
+passport.use(
+ new LocalStrategy({ usernameField: 'email', passReqToCallback: true }, (req, email, password, done) => {
+ User.findOne({ email: email.toLowerCase() })
+ .then(user => {
+ if (!user) return done(undefined, false, { message: 'Invalid email or password' }); // invalid email
+ (user as any as DashUserModel).comparePassword(password, (error: Error, isMatch: boolean) => {
+ if (error) return done(error);
+ if (!isMatch) return done(undefined, false, { message: 'Invalid email or password' }); // invalid password
+ // valid authentication HERE
+ return done(undefined, user);
+ });
+ })
+ .catch(error => done(error));
+ })
+);
diff --git a/src/server/database.ts b/src/server/database.ts
index 37bc00a85..0893bfd35 100644
--- a/src/server/database.ts
+++ b/src/server/database.ts
@@ -7,11 +7,14 @@ import { DocumentsCollection, IDatabase } from './IDatabase';
import { MemoryDatabase } from './MemoryDatabase';
import { Transferable } from './Message';
import { Upload } from './SharedMediaTypes';
-import { ObjectId } from 'mongodb';
export namespace Database {
-
export let disconnect: Function;
+
+ class DocSchema implements mongodb.BSON.Document {
+ _id!: string;
+ id!: string;
+ }
const schema = 'Dash';
const port = 27017;
export const url = `mongodb://localhost:${port}/${schema}`;
@@ -36,11 +39,11 @@ export namespace Database {
resolve();
});
mongoose.connect(url, {
- //useNewUrlParser: true,
+ //useNewUrlParser: true,
dbName: schema,
// reconnectTries: Number.MAX_VALUE,
// reconnectInterval: 1000,
- });
+ });
});
}
} catch (e) {
@@ -60,10 +63,10 @@ export namespace Database {
async doConnect() {
console.error(`\nConnecting to Mongo with URL : ${url}\n`);
return new Promise<void>(resolve => {
- this.MongoClient.connect(url, { connectTimeoutMS: 30000, socketTimeoutMS: 30000, }).then(client => {
- console.error("mongo connect response\n");
+ this.MongoClient.connect(url, { connectTimeoutMS: 30000, socketTimeoutMS: 30000 }).then(client => {
+ console.error('mongo connect response\n');
if (!client) {
- console.error("\nMongo connect failed with the error:\n");
+ console.error('\nMongo connect failed with the error:\n');
process.exit(0);
}
this.db = client.db();
@@ -75,18 +78,18 @@ export namespace Database {
public async update(id: string, value: any, callback: (err: mongodb.MongoError, res: mongodb.UpdateResult) => void, upsert = true, collectionName = DocumentsCollection) {
if (this.db) {
- const collection = this.db.collection(collectionName);
+ const collection = this.db.collection<DocSchema>(collectionName);
const prom = this.currentWrites[id];
let newProm: Promise<void>;
const run = (): Promise<void> => {
return new Promise<void>(resolve => {
- collection.updateOne({ _id: new ObjectId(id) }, value, { upsert }).then(res => {
- if (this.currentWrites[id] === newProm) {
- delete this.currentWrites[id];
- }
- resolve();
- callback(undefined as any, res);
- });
+ collection.updateOne({ _id: id }, value, { upsert }).then(res => {
+ if (this.currentWrites[id] === newProm) {
+ delete this.currentWrites[id];
+ }
+ resolve();
+ callback(undefined as any, res);
+ });
});
};
newProm = prom ? prom.then(run) : run();
@@ -99,18 +102,18 @@ export namespace Database {
public replace(id: string, value: any, callback: (err: mongodb.MongoError, res: mongodb.UpdateResult<mongodb.Document>) => void, upsert = true, collectionName = DocumentsCollection) {
if (this.db) {
- const collection = this.db.collection(collectionName);
+ const collection = this.db.collection<DocSchema>(collectionName);
const prom = this.currentWrites[id];
let newProm: Promise<void>;
const run = (): Promise<void> => {
return new Promise<void>(resolve => {
- collection.replaceOne({ _id: new ObjectId(id)}, value, { upsert }).then( res => {
- if (this.currentWrites[id] === newProm) {
- delete this.currentWrites[id];
- }
- resolve();
- callback(undefined as any, res as any);
- });
+ collection.replaceOne({ _id: id }, value, { upsert }).then(res => {
+ if (this.currentWrites[id] === newProm) {
+ delete this.currentWrites[id];
+ }
+ resolve();
+ callback(undefined as any, res as any);
+ });
});
};
newProm = prom ? prom.then(run) : run();
@@ -135,12 +138,17 @@ export namespace Database {
public delete(query: any, collectionName?: string): Promise<mongodb.DeleteResult>;
public delete(id: string, collectionName?: string): Promise<mongodb.DeleteResult>;
public delete(id: any, collectionName = DocumentsCollection) {
- if (typeof id === "string") {
- id = { _id: new ObjectId(id) };
+ if (typeof id === 'string') {
+ id = { _id: id };
}
if (this.db) {
const db = this.db;
- return new Promise(res => db.collection(collectionName).deleteMany(id).then(result => res(result)));
+ return new Promise(res =>
+ db
+ .collection(collectionName)
+ .deleteMany(id)
+ .then(result => res(result))
+ );
} else {
return new Promise(res => this.onConnect.push(() => res(this.delete(id, collectionName))));
}
@@ -167,12 +175,12 @@ export namespace Database {
public async insert(value: any, collectionName = DocumentsCollection) {
if (this.db && value !== null) {
- if ("id" in value) {
+ if ('id' in value) {
value._id = value.id;
delete value.id;
}
const id = value._id;
- const collection = this.db.collection(collectionName);
+ const collection = this.db.collection<DocSchema>(collectionName);
const prom = this.currentWrites[id];
let newProm: Promise<void>;
const run = (): Promise<void> => {
@@ -195,11 +203,12 @@ export namespace Database {
public getDocument(id: string, fn: (result?: Transferable) => void, collectionName = DocumentsCollection) {
if (this.db) {
- this.db.collection(collectionName).findOne({ _id: new ObjectId(id) }).then(result => {
+ const collection = this.db.collection<DocSchema>(collectionName);
+ collection.findOne({ _id: id }).then(result => {
if (result) {
result.id = result._id;
//delete result._id;
- fn(result.id);
+ fn(result as any);
} else {
fn(undefined);
}
@@ -209,19 +218,19 @@ export namespace Database {
}
}
- public getDocuments(ids: string[], fn: (result: Transferable[]) => void, collectionName = DocumentsCollection) {
+ public async getDocuments(ids: string[], fn: (result: Transferable[]) => void, collectionName = DocumentsCollection) {
if (this.db) {
- this.db.collection(collectionName).find({ _id: { "$in": ids.map(id => new ObjectId(id)) } }).map(docs => {
- // if (err) {
- // console.log(err.message);
- // console.log(err.errmsg);
- // }
- fn(docs.map((doc:any) => {
+ const found = await this.db
+ .collection<DocSchema>(collectionName)
+ .find({ _id: { $in: ids } })
+ .toArray();
+ fn(
+ found.map((doc: any) => {
doc.id = doc._id;
delete doc._id;
return doc;
- }));
- });
+ })
+ );
} else {
this.onConnect.push(() => this.getDocuments(ids, fn, collectionName));
}
@@ -256,7 +265,7 @@ export namespace Database {
public query(query: { [key: string]: any }, projection?: { [key: string]: 0 | 1 }, collectionName = DocumentsCollection): Promise<mongodb.FindCursor> {
if (this.db) {
- let cursor = this.db.collection(collectionName).find(query);
+ let cursor = this.db.collection<DocSchema>(collectionName).find(query);
if (projection) {
cursor = cursor.project(projection);
}
@@ -271,7 +280,12 @@ export namespace Database {
public updateMany(query: any, update: any, collectionName = DocumentsCollection) {
if (this.db) {
const db = this.db;
- return new Promise<mongodb.UpdateResult>(res => db.collection(collectionName).updateMany(query, update).then(result => res(result)));
+ return new Promise<mongodb.UpdateResult>(res =>
+ db
+ .collection(collectionName)
+ .updateMany(query, update)
+ .then(result => res(result))
+ );
} else {
return new Promise<mongodb.UpdateResult>(res => {
this.onConnect.push(() => this.updateMany(query, update, collectionName).then(res));
@@ -280,13 +294,13 @@ export namespace Database {
}
public print() {
- console.log("db says hi!");
+ console.log('db says hi!');
}
}
function getDatabase() {
switch (process.env.DB) {
- case "MEM":
+ case 'MEM':
return new MemoryDatabase();
default:
return new Database();
@@ -301,13 +315,12 @@ export namespace Database {
* or Dash-internal user data.
*/
export namespace Auxiliary {
-
/**
* All the auxiliary MongoDB collections (schemas)
*/
export enum AuxiliaryCollections {
- GooglePhotosUploadHistory = "uploadedFromGooglePhotos",
- GoogleAccess = "googleAuthentication",
+ GooglePhotosUploadHistory = 'uploadedFromGooglePhotos',
+ GoogleAccess = 'googleAuthentication',
}
/**
@@ -319,16 +332,18 @@ export namespace Database {
const cursor = await Instance.query(query, undefined, collection);
const results = await cursor.toArray();
const slice = results.slice(0, Math.min(cap, results.length));
- return removeId ? slice.map((result:any) => {
- delete result._id;
- return result;
- }) : slice;
+ return removeId
+ ? slice.map((result: any) => {
+ delete result._id;
+ return result;
+ })
+ : slice;
};
/**
* Searches for the @param query in the specified @param collection,
* and returns at most the first result. If @param removeId is true,
- * as it is by default, each object will be stripped of its database id.
+ * as it is by default, each object will be stripped of its database id.
* Worth the special case since it converts the Array return type to a single
* object of the specified type.
*/
@@ -338,7 +353,7 @@ export namespace Database {
};
/**
- * Checks to see if an image with the given @param contentSize
+ * Checks to see if an image with the given @param contentSize
* already exists in the aux database, i.e. has already been downloaded from Google Photos.
*/
export const QueryUploadHistory = async (contentSize: number) => {
@@ -352,7 +367,7 @@ export namespace Database {
export const LogUpload = async (information: Upload.ImageInformation) => {
const bundle = {
_id: Utils.GenerateDeterministicGuid(String(information.contentSize)),
- ...information
+ ...information,
};
return Instance.insert(bundle, AuxiliaryCollections.GooglePhotosUploadHistory);
};
@@ -362,7 +377,6 @@ export namespace Database {
* facilitates interactions with all their APIs for a given account.
*/
export namespace GoogleAccessToken {
-
/**
* Format stored in database.
*/
@@ -370,7 +384,7 @@ export namespace Database {
/**
* Retrieves the credentials associaed with @param userId
- * and optionally removes their database id according to @param removeId.
+ * and optionally removes their database id according to @param removeId.
*/
export const Fetch = async (userId: string, removeId = true): Promise<Opt<StoredCredentials>> => {
return SanitizedSingletonQuery<StoredCredentials>({ userId }, AuxiliaryCollections.GoogleAccess, removeId);
@@ -378,7 +392,7 @@ export namespace Database {
/**
* Writes the @param enrichedCredentials to the database, associated
- * with @param userId for later retrieval and updating.
+ * with @param userId for later retrieval and updating.
*/
export const Write = async (userId: string, enrichedCredentials: GoogleApiServerUtils.EnrichedCredentials) => {
return Instance.insert({ userId, canAccess: [], ...enrichedCredentials }, AuxiliaryCollections.GoogleAccess);
@@ -397,7 +411,7 @@ export namespace Database {
};
/**
- * Revokes the credentials associated with @param userId.
+ * Revokes the credentials associated with @param userId.
*/
export const Revoke = async (userId: string) => {
const entry = await Fetch(userId, false);
@@ -405,9 +419,6 @@ export namespace Database {
Instance.delete({ _id: entry._id }, AuxiliaryCollections.GoogleAccess);
}
};
-
}
-
}
-
}
diff --git a/src/server/server_Initialization.ts b/src/server/server_Initialization.ts
index af8b8dfdd..a4deaa744 100644
--- a/src/server/server_Initialization.ts
+++ b/src/server/server_Initialization.ts
@@ -1,13 +1,10 @@
import * as bodyParser from 'body-parser';
import { blue, yellow } from 'colors';
-import * as cookieParser from 'cookie-parser';
import * as cors from 'cors';
import * as express from 'express';
import * as session from 'express-session';
import * as expressValidator from 'express-validator';
-import * as fs from 'fs';
-import { Server as HttpServer } from 'http';
-import { createServer, Server as HttpsServer } from 'https';
+import { createServer } from 'https';
import * as passport from 'passport';
import * as request from 'request';
import * as webpack from 'webpack';
@@ -22,10 +19,10 @@ import { Database } from './database';
import RouteManager from './RouteManager';
import RouteSubscriber from './RouteSubscriber';
import { WebSocket } from './websocket';
-import * as brotli from 'brotli';
import * as expressFlash from 'express-flash';
import * as flash from 'connect-flash';
-import * as MongoStoreConnect from 'connect-mongo';
+import * as brotli from 'brotli';
+import * as MongoStoreConnect from 'connect-mongo';
import * as config from '../../webpack.config';
/* RouteSetter is a wrapper around the server that prevents the server
@@ -41,29 +38,21 @@ export default async function InitializeServer(routeSetter: RouteSetter) {
const app = buildWithMiddleware(express());
const compiler = webpack(config as any);
- app.use(
- require('webpack-dev-middleware')(compiler, {
- publicPath: config.output.publicPath,
- })
- );
-
- app.use(require('webpack-hot-middleware')(compiler));
-
// route table managed by express. routes are tested sequentially against each of these map rules. when a match is found, the handler is called to process the request
+ app.use(wdm(compiler, { publicPath: config.output.publicPath }));
+ app.use(whm(compiler));
app.get(new RegExp(/^\/+$/), (req, res) => res.redirect(req.user ? '/home' : '/login')); // target urls that consist of one or more '/'s with nothing in between
app.use(express.static(publicDirectory, { setHeaders: res => res.setHeader('Access-Control-Allow-Origin', '*') })); //all urls that start with dash's public directory: /files/ (e.g., /files/images, /files/audio, etc)
app.use(cors({ origin: (_origin: any, callback: any) => callback(null, true) }));
- app.use(wdm(compiler, { publicPath: config.output.publicPath }));
- app.use(whm(compiler));
registerAuthenticationRoutes(app); // this adds routes to authenticate a user (login, etc)
registerCorsProxy(app); // this adds a /corsProxy/ route to allow clients to get to urls that would otherwise be blocked by cors policies
isRelease && !SSL.Loaded && SSL.exit();
routeSetter(new RouteManager(app, isRelease)); // this sets up all the regular supervised routes (things like /home, download/upload api's, pdf, search, session, etc)
registerEmbeddedBrowseRelativePathHandler(app); // this allows renered web pages which internally have relative paths to find their content
- let server: HttpServer | HttpsServer;
isRelease && process.env.serverPort && (resolvedPorts.server = Number(process.env.serverPort));
- await new Promise<void>(resolve => (server = isRelease ? createServer(SSL.Credentials, app).listen(resolvedPorts.server, resolve) : app.listen(resolvedPorts.server, resolve)));
+ const server = isRelease ? createServer(SSL.Credentials, app) : app;
+ await new Promise<void>(resolve => server.listen(resolvedPorts.server, resolve));
logPort('server', resolvedPorts.server);
resolvedServerUrl = `${isRelease && process.env.serverName ? `https://${process.env.serverName}.com` : 'http://localhost'}:${resolvedPorts.server}`;
@@ -78,26 +67,27 @@ export default async function InitializeServer(routeSetter: RouteSetter) {
const week = 7 * 24 * 60 * 60 * 1000;
const secret = '64d6866242d3b5a5503c675b32c9605e4e90478e9b77bcf2bc';
+const store = process.env.DB === 'MEM' || true ? new session.MemoryStore() : MongoStoreConnect.create({ mongoUrl: Database.url });
function buildWithMiddleware(server: express.Express) {
[
- cookieParser(),
session({
secret,
resave: true,
cookie: { maxAge: week },
saveUninitialized: true,
- store: process.env.DB === 'MEM' ? new session.MemoryStore() : MongoStoreConnect.create({ mongoUrl: Database.url }),
+ store,
}),
flash(),
expressFlash(),
bodyParser.json({ limit: '10mb' }),
bodyParser.urlencoded({ extended: true }),
- expressValidator.body,
+ expressValidator(), // adds functions (e.g., assert()) to 'req' that help validate the request in the route handling methods
passport.initialize(),
passport.session(),
(req: express.Request, res: express.Response, next: express.NextFunction) => {
res.locals.user = req.user;
+ console.log('HEADER:' + req.originalUrl + ' path = ' + req.path);
if ((req.originalUrl.endsWith('.png') || req.originalUrl.endsWith('.jpg') || (process.env.RELEASE === 'true' && req.originalUrl.endsWith('.js'))) && req.method === 'GET') {
const period = 30000;
res.set('Cache-control', `public, max-age=${period}`);
@@ -108,7 +98,7 @@ function buildWithMiddleware(server: express.Express) {
next();
},
].forEach(next => server.use(next));
-
+
return server;
}
diff --git a/src/server/websocket.ts b/src/server/websocket.ts
index 4453001b0..a26b81bdf 100644
--- a/src/server/websocket.ts
+++ b/src/server/websocket.ts
@@ -1,10 +1,8 @@
import { blue } from 'colors';
import * as express from 'express';
-import { createServer, Server } from 'https';
+import { createServer } from 'https';
+import { Server, Socket } from '../../node_modules/socket.io/dist/index';
import { networkInterfaces } from 'os';
-import * as sio from 'socket.io';
-import * as _socket from 'socket.io';
-import { Opt } from '../fields/Doc';
import { Utils } from '../Utils';
import { logPort } from './ActionUtilities';
import { timeMap } from './ApiManagers/UserManager';
@@ -18,32 +16,31 @@ import { DocumentsCollection } from './IDatabase';
import { Diff, GestureContent, MessageStore, MobileDocumentUploadContent, MobileInkOverlayContent, Transferable, Types, UpdateMobileInkOverlayPositionContent, YoutubeQueryInput, YoutubeQueryTypes } from './Message';
import { Search } from './Search';
import { resolvedPorts } from './server_Initialization';
-var _ = require('lodash');
-type Socket = typeof _socket;
+import * as _ from 'lodash';
export namespace WebSocket {
export let _socket: Socket;
export const clients: { [key: string]: Client } = {};
- export const socketMap = new Map<SocketIO.Socket, string>();
+ export const socketMap = new Map<Socket, string>();
export const userOperations = new Map<string, number>();
export let disconnect: Function;
export async function initialize(isRelease: boolean, app: express.Express) {
- let io: sio.Server;
+ let io: Server;
if (isRelease) {
const { socketPort } = process.env;
if (socketPort) {
resolvedPorts.socket = Number(socketPort);
}
- let socketEndpoint: Opt<Server>;
- await new Promise<void>(resolve => (socketEndpoint = createServer(SSL.Credentials, app).listen(resolvedPorts.socket, resolve)));
- io = sio(socketEndpoint!, SSL.Credentials as any);
+ io = new Server(createServer(SSL.Credentials, app), SSL.Credentials as any);
+ io.listen(resolvedPorts.socket);
} else {
- io = sio().listen(resolvedPorts.socket);
+ io = new Server();
+ io.listen(resolvedPorts.socket);
}
logPort('websocket', resolvedPorts.socket);
- io.on('connection', function (socket: Socket) {
+ io.on('connection', socket => {
_socket = socket;
socket.use((_packet, next) => {
const userEmail = socketMap.get(socket);
@@ -69,7 +66,7 @@ export namespace WebSocket {
console.log('Received request to create or join room ' + room);
const clientsInRoom = socket.rooms.has(room);
- const numClients = clientsInRoom ? Object.keys(clientsInRoom.sockets).length : 0;
+ const numClients = clientsInRoom ? Object.keys(room.sockets).length : 0;
console.log('Room ' + room + ' now has ' + numClients + ' client(s)');
if (numClients === 0) {
@@ -192,7 +189,7 @@ export namespace WebSocket {
initializeGuest();
}
- function barReceived(socket: SocketIO.Socket, userEmail: string) {
+ function barReceived(socket: Socket, userEmail: string) {
clients[userEmail] = new Client(userEmail.toString());
const currentdate = new Date();
const datetime = currentdate.getDate() + '/' + (currentdate.getMonth() + 1) + '/' + currentdate.getFullYear() + ' @ ' + currentdate.getHours() + ':' + currentdate.getMinutes() + ':' + currentdate.getSeconds();
@@ -309,9 +306,9 @@ export namespace WebSocket {
if (sendBack) {
console.log('Warning: list modified during update. Composite list is being returned.');
const id = socket.id;
- socket.id = '';
+ (socket as any).id = '';
socket.broadcast.emit(MessageStore.UpdateField.Message, diff);
- socket.id = id;
+ (socket as any).id = id;
} else socket.broadcast.emit(MessageStore.UpdateField.Message, diff);
dispatchNextOp(diff.id);
},
@@ -402,9 +399,9 @@ export namespace WebSocket {
// the two copies are different, so the server sends its copy.
console.log('SEND BACK');
const id = socket.id;
- socket.id = '';
+ (socket as any).id = '';
socket.broadcast.emit(MessageStore.UpdateField.Message, diff);
- socket.id = id;
+ (socket as any).id = id;
} else socket.broadcast.emit(MessageStore.UpdateField.Message, diff);
dispatchNextOp(diff.id);
},