diff options
| author | laurawilsonri <laura_wilson@brown.edu> | 2019-04-15 20:20:46 -0400 |
|---|---|---|
| committer | laurawilsonri <laura_wilson@brown.edu> | 2019-04-15 20:20:46 -0400 |
| commit | b7a766aa5d53686e032b34d7213ad543108f12c3 (patch) | |
| tree | d71854e091fa24997a30856d9ac9c937a6cd45d2 /src/server | |
| parent | 8b1026d357dd40fc4a00010739d99ffc9db08641 (diff) | |
| parent | ff6ba4107aa33e021803399180b0d2844fc19d84 (diff) | |
Merge branch 'master' of https://github.com/browngraphicslab/Dash-Web into richTextEditor
Diffstat (limited to 'src/server')
| -rw-r--r-- | src/server/Client.ts | 1 | ||||
| -rw-r--r-- | src/server/Message.ts | 137 | ||||
| -rw-r--r-- | src/server/ServerUtil.ts | 99 | ||||
| -rw-r--r-- | src/server/authentication/models/current_user_utils.ts | 101 | ||||
| -rw-r--r-- | src/server/authentication/models/user_model.ts | 21 | ||||
| -rw-r--r-- | src/server/database.ts | 21 | ||||
| -rw-r--r-- | src/server/index.ts | 16 |
7 files changed, 119 insertions, 277 deletions
diff --git a/src/server/Client.ts b/src/server/Client.ts index b4c419438..e6f953712 100644 --- a/src/server/Client.ts +++ b/src/server/Client.ts @@ -8,5 +8,4 @@ export class Client { } @computed public get GUID(): string { return this._guid; } - }
\ No newline at end of file diff --git a/src/server/Message.ts b/src/server/Message.ts index d22e5c17c..bbe4ffcad 100644 --- a/src/server/Message.ts +++ b/src/server/Message.ts @@ -1,146 +1,35 @@ import { Utils } from "../Utils"; export class Message<T> { - private name: string; - private guid: string; - - get Name(): string { - return this.name; - } - - get Message(): string { - return this.guid; - } + private _name: string; + private _guid: string; constructor(name: string) { - this.name = name; - this.guid = Utils.GenerateDeterministicGuid(name); - } - - GetValue() { - return this.Name; - } -} - -class TestMessageArgs { - hello: string = ""; -} - -export class SetFieldArgs { - field: string; - value: any; - - constructor(f: string, v: any) { - this.field = f; - this.value = v; + this._name = name; + this._guid = Utils.GenerateDeterministicGuid(name); } -} -export class GetFieldArgs { - field: string; - - constructor(f: string) { - this.field = f; - } + get Name(): string { return this._name; } + get Message(): string { return this._guid; } } export enum Types { - Number, - List, - Key, - Image, - Web, - Document, - Text, - RichText, - DocumentReference, - Html, - Video, - Audio, - Ink, - PDF, - Tuple, - HistogramOp, - Boolean, - Script, -} - -export class DocumentTransfer implements Transferable { - readonly type = Types.Document; - _id: string; - - constructor( - readonly obj: { type: Types; data: [string, string][]; _id: string } - ) { - this._id = obj._id; - } -} - -export class ImageTransfer implements Transferable { - readonly type = Types.Image; - - constructor(readonly _id: string) { } -} - -export class KeyTransfer implements Transferable { - name: string; - readonly _id: string; - readonly type = Types.Key; - - constructor(i: string, n: string) { - this.name = n; - this._id = i; - } -} - -export class ListTransfer implements Transferable { - type = Types.List; - - constructor(readonly _id: string) { } -} - -export class NumberTransfer implements Transferable { - readonly type = Types.Number; - - constructor(readonly value: number, readonly _id: string) { } -} - -export class TextTransfer implements Transferable { - value: string; - readonly _id: string; - readonly type = Types.Text; - - constructor(t: string, i: string) { - this.value = t; - this._id = i; - } -} - -export class RichTextTransfer implements Transferable { - value: string; - readonly _id: string; - readonly type = Types.Text; - - constructor(t: string, i: string) { - this.value = t; - this._id = i; - } + Number, List, Key, Image, Web, Document, Text, RichText, DocumentReference, + Html, Video, Audio, Ink, PDF, Tuple, HistogramOp, Boolean, Script, } export interface Transferable { - readonly _id: string; + readonly id: string; readonly type: Types; + readonly data?: any; } export namespace MessageStore { export const Foo = new Message<string>("Foo"); export const Bar = new Message<string>("Bar"); - export const AddDocument = new Message<DocumentTransfer>("Add Document"); - export const SetField = new Message<{ _id: string; data: any; type: Types }>( - "Set Field" - ); - export const GetField = new Message<string>("Get Field"); - export const GetFields = new Message<string[]>("Get Fields"); + export const SetField = new Message<Transferable>("Set Field"); // send Transferable (no reply) + export const GetField = new Message<string>("Get Field"); // send string 'id' get Transferable back + export const GetFields = new Message<string[]>("Get Fields"); // send string[] of 'id' get Transferable[] back export const GetDocument = new Message<string>("Get Document"); export const DeleteAll = new Message<any>("Delete All"); } diff --git a/src/server/ServerUtil.ts b/src/server/ServerUtil.ts index 0973f82b1..818230c1a 100644 --- a/src/server/ServerUtil.ts +++ b/src/server/ServerUtil.ts @@ -1,83 +1,56 @@ -import { Field } from "./../fields/Field"; -import { TextField } from "./../fields/TextField"; -import { NumberField } from "./../fields/NumberField"; -import { RichTextField } from "./../fields/RichTextField"; -import { Key } from "./../fields/Key"; -import { ImageField } from "./../fields/ImageField"; -import { ListField } from "./../fields/ListField"; -import { Document } from "./../fields/Document"; -import { Server } from "./../client/Server"; -import { Types } from "./Message"; -import { Utils } from "../Utils"; -import { HtmlField } from "../fields/HtmlField"; -import { WebField } from "../fields/WebField"; +import { HistogramField } from "../client/northstar/dash-fields/HistogramField"; import { AudioField } from "../fields/AudioField"; -import { VideoField } from "../fields/VideoField"; +import { BooleanField } from "../fields/BooleanField"; +import { HtmlField } from "../fields/HtmlField"; import { InkField } from "../fields/InkField"; import { PDFField } from "../fields/PDFField"; -import { TupleField } from "../fields/TupleField"; -import { BooleanField } from "../fields/BooleanField"; -import { HistogramField } from "../client/northstar/dash-fields/HistogramField"; import { ScriptField } from "../fields/ScriptField"; +import { TupleField } from "../fields/TupleField"; +import { VideoField } from "../fields/VideoField"; +import { WebField } from "../fields/WebField"; +import { Utils } from "../Utils"; +import { Document } from "./../fields/Document"; +import { Field } from "./../fields/Field"; +import { ImageField } from "./../fields/ImageField"; +import { Key } from "./../fields/Key"; +import { ListField } from "./../fields/ListField"; +import { NumberField } from "./../fields/NumberField"; +import { RichTextField } from "./../fields/RichTextField"; +import { TextField } from "./../fields/TextField"; +import { Transferable, Types } from "./Message"; export class ServerUtils { public static prepend(extension: string): string { return window.location.origin + extension; } - public static FromJson(json: any): Field { - let obj = json; - let data: any = obj.data; - let id: string = obj._id; - let type: Types = obj.type; + public static FromJson(json: Transferable): Field { - if (!(data !== undefined && id && type !== undefined)) { + if (!(json.data !== undefined && json.id && json.type !== undefined)) { console.log( "how did you manage to get an object that doesn't have a data or an id?" ); return new TextField("Something to fill the space", Utils.GenerateGuid()); } - switch (type) { - case Types.Boolean: - return new BooleanField(data, id, false); - case Types.Number: - return new NumberField(data, id, false); - case Types.Text: - return new TextField(data, id, false); - case Types.Html: - return new HtmlField(data, id, false); - case Types.Web: - return new WebField(new URL(data), id, false); - case Types.RichText: - return new RichTextField(data, id, false); - case Types.Key: - return new Key(data, id, false); - case Types.Image: - return new ImageField(new URL(data), id, false); - case Types.HistogramOp: - return HistogramField.FromJson(id, data); - case Types.PDF: - return new PDFField(new URL(data), id, false); - case Types.List: - return ListField.FromJson(id, data); - case Types.Script: - return ScriptField.FromJson(id, data); - case Types.Audio: - return new AudioField(new URL(data), id, false); - case Types.Video: - return new VideoField(new URL(data), id, false); - case Types.Tuple: - return new TupleField(data, id, false); - case Types.Ink: - return InkField.FromJson(id, data); - case Types.Document: - let doc: Document = new Document(id, false); - let fields: [string, string][] = data as [string, string][]; - fields.forEach(element => { - doc._proxies.set(element[0], element[1]); - }); - return doc; + switch (json.type) { + case Types.Boolean: return new BooleanField(json.data, json.id, false); + case Types.Number: return new NumberField(json.data, json.id, false); + case Types.Text: return new TextField(json.data, json.id, false); + case Types.Html: return new HtmlField(json.data, json.id, false); + case Types.Web: return new WebField(new URL(json.data), json.id, false); + case Types.RichText: return new RichTextField(json.data, json.id, false); + case Types.Key: return new Key(json.data, json.id, false); + case Types.Image: return new ImageField(new URL(json.data), json.id, false); + case Types.HistogramOp: return HistogramField.FromJson(json.id, json.data); + case Types.PDF: return new PDFField(new URL(json.data), json.id, false); + case Types.List: return ListField.FromJson(json.id, json.data); + case Types.Script: return ScriptField.FromJson(json.id, json.data); + case Types.Audio: return new AudioField(new URL(json.data), json.id, false); + case Types.Video: return new VideoField(new URL(json.data), json.id, false); + case Types.Tuple: return new TupleField(json.data, json.id, false); + case Types.Ink: return InkField.FromJson(json.id, json.data); + case Types.Document: return Document.FromJson(json.data, json.id, false); default: throw Error( "Error, unrecognized field type received from server. If you just created a new field type, be sure to add it here" diff --git a/src/server/authentication/models/current_user_utils.ts b/src/server/authentication/models/current_user_utils.ts index 13eddafbf..5d4479c88 100644 --- a/src/server/authentication/models/current_user_utils.ts +++ b/src/server/authentication/models/current_user_utils.ts @@ -1,81 +1,37 @@ -import { DashUserModel } from "./user_model"; +import { computed, observable, action, runInAction } from "mobx"; import * as rp from 'request-promise'; -import { RouteStore } from "../../RouteStore"; -import { ServerUtils } from "../../ServerUtil"; +import { Documents } from "../../../client/documents/Documents"; +import { Attribute, AttributeGroup, Catalog, Schema } from "../../../client/northstar/model/idea/idea"; +import { ArrayUtil } from "../../../client/northstar/utils/ArrayUtil"; import { Server } from "../../../client/Server"; import { Document } from "../../../fields/Document"; import { KeyStore } from "../../../fields/KeyStore"; import { ListField } from "../../../fields/ListField"; -import { Documents } from "../../../client/documents/Documents"; -import { Schema, Attribute, AttributeGroup, Catalog } from "../../../client/northstar/model/idea/idea"; -import { observable, computed, action } from "mobx"; -import { ArrayUtil } from "../../../client/northstar/utils/ArrayUtil"; +import { RouteStore } from "../../RouteStore"; +import { ServerUtils } from "../../ServerUtil"; export class CurrentUserUtils { private static curr_email: string; private static curr_id: string; - private static user_document: Document; + @observable private static user_document: Document; //TODO tfs: these should be temporary... private static mainDocId: string | undefined; - @observable private static catalog?: Catalog; - - public static get email(): string { - return this.curr_email; - } - - public static get id(): string { - return this.curr_id; - } - - public static get UserDocument(): Document { - return this.user_document; - } - public static get MainDocId(): string | undefined { - return this.mainDocId; - } - - public static set MainDocId(id: string | undefined) { - this.mainDocId = id; - } - - @computed public static get NorthstarDBCatalog(): Catalog | undefined { - return this.catalog; - } - public static set NorthstarDBCatalog(ctlog: Catalog | undefined) { - this.catalog = ctlog; - } - public static GetNorthstarSchema(name: string): Schema | undefined { - return !this.catalog || !this.catalog.schemas ? undefined : - ArrayUtil.FirstOrDefault<Schema>(this.catalog.schemas, (s: Schema) => s.displayName === name); - } - public static GetAllNorthstarColumnAttributes(schema: Schema) { - if (!schema || !schema.rootAttributeGroup) { - return []; - } - const recurs = (attrs: Attribute[], g: AttributeGroup) => { - if (g.attributes) { - attrs.push.apply(attrs, g.attributes); - if (g.attributeGroups) { - g.attributeGroups.forEach(ng => recurs(attrs, ng)); - } - } - }; - const allAttributes: Attribute[] = new Array<Attribute>(); - recurs(allAttributes, schema.rootAttributeGroup); - return allAttributes; - } + public static get email() { return this.curr_email; } + public static get id() { return this.curr_id; } + @computed public static get UserDocument() { return this.user_document; } + public static get MainDocId() { return this.mainDocId; } + public static set MainDocId(id: string | undefined) { this.mainDocId = id; } private static createUserDocument(id: string): Document { let doc = new Document(id); - doc.Set(KeyStore.Workspaces, new ListField<Document>()); doc.Set(KeyStore.OptionalRightCollection, Documents.SchemaDocument([], { title: "Pending documents" })); return doc; } public static loadCurrentUser(): Promise<any> { - let userPromise = rp.get(ServerUtils.prepend(RouteStore.getCurrUser)).then((response) => { + let userPromise = rp.get(ServerUtils.prepend(RouteStore.getCurrUser)).then(response => { if (response) { let obj = JSON.parse(response); CurrentUserUtils.curr_id = obj.id as string; @@ -86,17 +42,34 @@ export class CurrentUserUtils { }); let userDocPromise = rp.get(ServerUtils.prepend(RouteStore.getUserDocumentId)).then(id => { if (id) { - return Server.GetField(id).then(field => { - if (field instanceof Document) { - this.user_document = field; - } else { - this.user_document = this.createUserDocument(id); - } - }); + return Server.GetField(id).then(field => + runInAction(() => this.user_document = field instanceof Document ? field : this.createUserDocument(id))); } else { throw new Error("There should be a user id! Why does Dash think there isn't one?"); } }); return Promise.all([userPromise, userDocPromise]); } + + /* Northstar catalog ... really just for testing so this should eventually go away */ + @observable private static _northstarCatalog?: Catalog; + @computed public static get NorthstarDBCatalog() { return this._northstarCatalog; } + public static set NorthstarDBCatalog(ctlog: Catalog | undefined) { this._northstarCatalog = ctlog; } + + public static GetNorthstarSchema(name: string): Schema | undefined { + return !this._northstarCatalog || !this._northstarCatalog.schemas ? undefined : + ArrayUtil.FirstOrDefault<Schema>(this._northstarCatalog.schemas, (s: Schema) => s.displayName === name); + } + public static GetAllNorthstarColumnAttributes(schema: Schema) { + const recurs = (attrs: Attribute[], g?: AttributeGroup) => { + if (g && g.attributes) { + attrs.push.apply(attrs, g.attributes); + if (g.attributeGroups) { + g.attributeGroups.forEach(ng => recurs(attrs, ng)); + } + } + return attrs; + }; + return recurs([] as Attribute[], schema ? schema.rootAttributeGroup : undefined); + } }
\ No newline at end of file diff --git a/src/server/authentication/models/user_model.ts b/src/server/authentication/models/user_model.ts index 1c6926517..d5c84c311 100644 --- a/src/server/authentication/models/user_model.ts +++ b/src/server/authentication/models/user_model.ts @@ -18,8 +18,8 @@ mongoose.connection.on('disconnected', function () { export type DashUserModel = mongoose.Document & { email: string, password: string, - passwordResetToken: string | undefined, - passwordResetExpires: Date | undefined, + passwordResetToken?: string, + passwordResetExpires?: Date, userDocumentId: string; @@ -67,11 +67,17 @@ const userSchema = new mongoose.Schema({ */ userSchema.pre("save", function save(next) { const user = this as DashUserModel; - if (!user.isModified("password")) { return next(); } + if (!user.isModified("password")) { + return next(); + } bcrypt.genSalt(10, (err, salt) => { - if (err) { return next(err); } + if (err) { + return next(err); + } bcrypt.hash(user.password, salt, () => void {}, (err: mongoose.Error, hash) => { - if (err) { return next(err); } + if (err) { + return next(err); + } user.password = hash; next(); }); @@ -79,9 +85,8 @@ userSchema.pre("save", function save(next) { }); const comparePassword: comparePasswordFunction = function (this: DashUserModel, candidatePassword, cb) { - bcrypt.compare(candidatePassword, this.password, (err: mongoose.Error, isMatch: boolean) => { - cb(err, isMatch); - }); + bcrypt.compare(candidatePassword, this.password, (err: mongoose.Error, isMatch: boolean) => + cb(err, isMatch)); }; userSchema.methods.comparePassword = comparePassword; diff --git a/src/server/database.ts b/src/server/database.ts index 3290edde0..7914febf8 100644 --- a/src/server/database.ts +++ b/src/server/database.ts @@ -1,20 +1,21 @@ import * as mongodb from 'mongodb'; +import { Transferable } from './Message'; export class Database { public static DocumentsCollection = 'documents'; public static Instance = new Database(); private MongoClient = mongodb.MongoClient; private url = 'mongodb://localhost:27017/Dash'; - private currentWrites: { [_id: string]: Promise<void> } = {}; + private currentWrites: { [id: string]: Promise<void> } = {}; private db?: mongodb.Db; constructor() { this.MongoClient.connect(this.url, (err, client) => this.db = client.db()); } - public update(id: string, value: any, callback: () => void, collectionName = Database.DocumentsCollection) { + public update(id: string, value: any, callback: () => void) { if (this.db) { - let collection = this.db.collection(collectionName); + let collection = this.db.collection('documents'); const prom = this.currentWrites[id]; let newProm: Promise<void>; const run = (): Promise<void> => { @@ -42,7 +43,7 @@ export class Database { } public delete(id: string, collectionName = Database.DocumentsCollection) { - this.db && this.db.collection(collectionName).remove({ _id: id }); + this.db && this.db.collection(collectionName).remove({ id: id }); } public deleteAll(collectionName = Database.DocumentsCollection): Promise<any> { @@ -56,18 +57,18 @@ export class Database { ); } - public getDocument(id: string, fn: (res: any) => void, collectionName = Database.DocumentsCollection) { - this.db && this.db.collection(collectionName).findOne({ _id: id }, (err, result) => - fn(result ? result : undefined)); + public getDocument(id: string, fn: (result?: Transferable) => void, collectionName = Database.DocumentsCollection) { + this.db && this.db.collection(collectionName).findOne({ id: id }, (err, result) => + fn(result ? ({ id: result._id, type: result.type, data: result.data }) : undefined)) } - public getDocuments(ids: string[], fn: (res: any) => void, collectionName = Database.DocumentsCollection) { - this.db && this.db.collection(collectionName).find({ _id: { "$in": ids } }).toArray((err, docs) => { + public getDocuments(ids: string[], fn: (result: Transferable[]) => void, collectionName = Database.DocumentsCollection) { + this.db && this.db.collection(collectionName).find({ id: { "$in": ids } }).toArray((err, docs) => { if (err) { console.log(err.message); console.log(err.errmsg); } - fn(docs); + fn(docs.map(doc => ({ id: doc._id, type: doc.type, data: doc.data }))); }); } diff --git a/src/server/index.ts b/src/server/index.ts index a6fe6fa2c..3cbe1ca76 100644 --- a/src/server/index.ts +++ b/src/server/index.ts @@ -87,9 +87,11 @@ function addSecureRoute(method: Method, ...subscribers: string[] ) { let abstracted = (req: express.Request, res: express.Response) => { - const dashUser: DashUserModel = req.user; - if (!dashUser) return onRejection(res); - handler(dashUser, res, req); + if (req.user) { + handler(req.user, res, req); + } else { + onRejection(res); + } }; subscribers.forEach(route => { switch (method) { @@ -246,17 +248,17 @@ function barReceived(guid: String) { clients[guid.toString()] = new Client(guid.toString()); } -function getField([id, callback]: [string, (result: any) => void]) { - Database.Instance.getDocument(id, (result: any) => +function getField([id, callback]: [string, (result?: Transferable) => void]) { + Database.Instance.getDocument(id, (result?: Transferable) => callback(result ? result : undefined)); } -function getFields([ids, callback]: [string[], (result: any) => void]) { +function getFields([ids, callback]: [string[], (result: Transferable[]) => void]) { Database.Instance.getDocuments(ids, callback); } function setField(socket: Socket, newValue: Transferable) { - Database.Instance.update(newValue._id, newValue, () => + Database.Instance.update(newValue.id, newValue, () => socket.broadcast.emit(MessageStore.SetField.Message, newValue)); } |
