diff options
| author | Tyler Schicke <tyler_schicke@brown.edu> | 2019-04-05 01:41:22 -0400 |
|---|---|---|
| committer | Tyler Schicke <tyler_schicke@brown.edu> | 2019-04-05 01:41:22 -0400 |
| commit | 0fb53a4b5fb430e67ef4af2323c886e77985ca52 (patch) | |
| tree | ca2826992a817d9944ab0163717c7644b1216d69 /src/server | |
| parent | 8faacc6b8da0082823ec92cb1c862b6373596264 (diff) | |
| parent | 4fde212cd00bd2f8fc2fa122309af3bb71bba2fd (diff) | |
Merge branch 'master' of github-tsch-brown:browngraphicslab/Dash-Web
Diffstat (limited to 'src/server')
| -rw-r--r-- | src/server/Message.ts | 168 | ||||
| -rw-r--r-- | src/server/RouteStore.ts | 5 | ||||
| -rw-r--r-- | src/server/ServerUtil.ts | 96 | ||||
| -rw-r--r-- | src/server/authentication/controllers/WorkspacesMenu.tsx | 19 | ||||
| -rw-r--r-- | src/server/authentication/controllers/user_controller.ts | 3 | ||||
| -rw-r--r-- | src/server/authentication/models/current_user_utils.ts | 91 | ||||
| -rw-r--r-- | src/server/authentication/models/user_model.ts | 11 | ||||
| -rw-r--r-- | src/server/database.ts | 27 | ||||
| -rw-r--r-- | src/server/index.ts | 49 | ||||
| -rw-r--r-- | src/server/public/files/upload_a6a70d84ebb65febf7900e29f52cc86d.pdf | bin | 0 -> 1043556 bytes |
10 files changed, 266 insertions, 203 deletions
diff --git a/src/server/Message.ts b/src/server/Message.ts index a2d1ab829..29df57419 100644 --- a/src/server/Message.ts +++ b/src/server/Message.ts @@ -1,125 +1,145 @@ import { Utils } from "../Utils"; export class Message<T> { - private name: string; - private guid: string; + private name: string; + private guid: string; - get Name(): string { - return this.name; - } + get Name(): string { + return this.name; + } - get Message(): string { - return this.guid - } + get Message(): string { + return this.guid; + } - constructor(name: string) { - this.name = name; - this.guid = Utils.GenerateDeterministicGuid(name) - } + constructor(name: string) { + this.name = name; + this.guid = Utils.GenerateDeterministicGuid(name); + } - GetValue() { - return this.Name; - } + GetValue() { + return this.Name; + } } class TestMessageArgs { - hello: string = ""; + hello: string = ""; } export class SetFieldArgs { - field: string; - value: any; + field: string; + value: any; - constructor(f: string, v: any) { - this.field = f - this.value = v - } + constructor(f: string, v: any) { + this.field = f; + this.value = v; + } } export class GetFieldArgs { - field: string; + field: string; - constructor(f: string) { - this.field = f - } + constructor(f: string) { + this.field = f; + } } export enum Types { - Number, List, Key, Image, Web, Document, Text, RichText, DocumentReference, Html, Video, Audio, Ink, PDF, Tuple + Number, + List, + Key, + Image, + Web, + Document, + Text, + RichText, + DocumentReference, + Html, + Video, + Audio, + Ink, + PDF, + Tuple, + HistogramOp, + Minimized } 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 - } + 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 + readonly type = Types.Image; - constructor(readonly _id: string) { } + 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 - } + 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; + type = Types.List; - constructor(readonly _id: string) { } + constructor(readonly _id: string) {} } export class NumberTransfer implements Transferable { - readonly type = Types.Number + readonly type = Types.Number; - constructor(readonly value: number, readonly _id: string) { } + 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 - } + 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 - } + value: string; + readonly _id: string; + readonly type = Types.Text; + + constructor(t: string, i: string) { + this.value = t; + this._id = i; + } } export interface Transferable { - readonly _id: string - readonly type: Types + readonly _id: string; + readonly type: Types; } 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 GetDocument = new Message<string>("Get Document"); - export const DeleteAll = new Message<any>("Delete All"); -}
\ No newline at end of file + 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 GetDocument = new Message<string>("Get Document"); + export const DeleteAll = new Message<any>("Delete All"); +} diff --git a/src/server/RouteStore.ts b/src/server/RouteStore.ts index fb06b878b..fdf5b6a5c 100644 --- a/src/server/RouteStore.ts +++ b/src/server/RouteStore.ts @@ -15,10 +15,7 @@ export enum RouteStore { // USER AND WORKSPACES getCurrUser = "/getCurrentUser", - addWorkspace = "/addWorkspaceId", - getAllWorkspaces = "/getAllWorkspaceIds", - getActiveWorkspace = "/getActiveWorkspaceId", - setActiveWorkspace = "/setActiveWorkspaceId", + getUserDocumentId = "/getUserDocumentId", updateCursor = "/updateCursor", openDocumentWithId = "/doc/:docId", diff --git a/src/server/ServerUtil.ts b/src/server/ServerUtil.ts index f10f82deb..d3409abf4 100644 --- a/src/server/ServerUtil.ts +++ b/src/server/ServerUtil.ts @@ -1,76 +1,84 @@ - -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 { AudioField } from '../fields/AudioField'; -import { VideoField } from '../fields/VideoField'; -import { InkField } from '../fields/InkField'; -import { PDFField } from '../fields/PDFField'; -import { TupleField } from '../fields/TupleField'; - - - +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 { AudioField } from "../fields/AudioField"; +import { VideoField } from "../fields/VideoField"; +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"; export class ServerUtils { - public static prepend(extension: string): string { return window.location.origin + extension; } + 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 + let obj = json; + let data: any = obj.data; + let id: string = obj._id; + let type: Types = obj.type; if (!(data !== undefined && id && type !== undefined)) { - console.log("how did you manage to get an object that doesn't have a data or an id?") + 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.Minimized: + return new BooleanField(data, id, false); case Types.Number: - return new NumberField(data, id, false) + return new NumberField(data, id, false); case Types.Text: - return new TextField(data, id, false) + return new TextField(data, id, false); case Types.Html: - return new HtmlField(data, id, false) + return new HtmlField(data, id, false); case Types.Web: - return new WebField(new URL(data), id, false) + return new WebField(new URL(data), id, false); case Types.RichText: - return new RichTextField(data, id, false) + return new RichTextField(data, id, false); case Types.Key: - return new Key(data, id, false) + return new Key(data, id, false); case Types.Image: - return new ImageField(new URL(data), id, false) + 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) + return new PDFField(new URL(data), id, false); case Types.List: - return ListField.FromJson(id, data) + return ListField.FromJson(id, data); case Types.Audio: - return new AudioField(new URL(data), id, false) + return new AudioField(new URL(data), id, false); case Types.Video: - return new VideoField(new URL(data), id, false) + 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][] + 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 + return doc; default: - throw Error("Error, unrecognized field type received from server. If you just created a new field type, be sure to add it here"); + throw Error( + "Error, unrecognized field type received from server. If you just created a new field type, be sure to add it here" + ); } } -}
\ No newline at end of file +} diff --git a/src/server/authentication/controllers/WorkspacesMenu.tsx b/src/server/authentication/controllers/WorkspacesMenu.tsx index 1533b1e62..8e14cf98e 100644 --- a/src/server/authentication/controllers/WorkspacesMenu.tsx +++ b/src/server/authentication/controllers/WorkspacesMenu.tsx @@ -9,30 +9,23 @@ import { KeyStore } from '../../../fields/KeyStore'; export interface WorkspaceMenuProps { active: Document | undefined; open: (workspace: Document) => void; - new: (init: boolean) => void; + new: () => void; allWorkspaces: Document[]; + isShown: () => boolean; + toggle: () => void; } @observer export class WorkspacesMenu extends React.Component<WorkspaceMenuProps> { - static Instance: WorkspacesMenu; - @observable private workspacesExposed: boolean = false; - constructor(props: WorkspaceMenuProps) { super(props); - WorkspacesMenu.Instance = this; this.addNewWorkspace = this.addNewWorkspace.bind(this); } @action addNewWorkspace() { - this.props.new(false); - this.toggle(); - } - - @action - toggle() { - this.workspacesExposed = !this.workspacesExposed; + this.props.new(); + this.props.toggle(); } render() { @@ -45,7 +38,7 @@ export class WorkspacesMenu extends React.Component<WorkspaceMenuProps> { borderRadius: 5, position: "absolute", top: 78, - left: this.workspacesExposed ? 11 : -500, + left: this.props.isShown() ? 11 : -500, background: "white", border: "black solid 2px", transition: "all 1s ease", diff --git a/src/server/authentication/controllers/user_controller.ts b/src/server/authentication/controllers/user_controller.ts index 2cef958e8..e365b8dce 100644 --- a/src/server/authentication/controllers/user_controller.ts +++ b/src/server/authentication/controllers/user_controller.ts @@ -11,6 +11,7 @@ import * as async from 'async'; import * as nodemailer from 'nodemailer'; import c = require("crypto"); import { RouteStore } from "../../RouteStore"; +import { Utils } from "../../../Utils"; /** * GET /signup @@ -54,7 +55,7 @@ export let postSignup = (req: Request, res: Response, next: NextFunction) => { const user = new User({ email, password, - userDoc: "document here" + userDocumentId: Utils.GenerateGuid() }); User.findOne({ email }, (err, existingUser) => { diff --git a/src/server/authentication/models/current_user_utils.ts b/src/server/authentication/models/current_user_utils.ts index cc433eb73..0ac85b446 100644 --- a/src/server/authentication/models/current_user_utils.ts +++ b/src/server/authentication/models/current_user_utils.ts @@ -1,29 +1,102 @@ import { DashUserModel } from "./user_model"; -import * as request from 'request' +import * as rp from 'request-promise'; import { RouteStore } from "../../RouteStore"; import { ServerUtils } from "../../ServerUtil"; +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"; export class CurrentUserUtils { private static curr_email: string; private static curr_id: string; + 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() { - return CurrentUserUtils.curr_email; + public static get email(): string { + return this.curr_email; } - public static get id() { - return CurrentUserUtils.curr_id; + public static get id(): string { + return this.curr_id; } - public static loadCurrentUser() { - request.get(ServerUtils.prepend(RouteStore.getCurrUser), (error, response, body) => { - if (body) { - let obj = JSON.parse(body); + 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; + } + + 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) => { + if (response) { + let obj = JSON.parse(response); CurrentUserUtils.curr_id = obj.id as string; CurrentUserUtils.curr_email = obj.email as string; } else { throw new Error("There should be a user! Why does Dash think there isn't one?") } }); + 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); + } + }) + } else { + throw new Error("There should be a user id! Why does Dash think there isn't one?") + } + }); + return Promise.all([userPromise, userDocPromise]); } }
\ 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 3d4ed6896..81580aad5 100644 --- a/src/server/authentication/models/user_model.ts +++ b/src/server/authentication/models/user_model.ts @@ -21,9 +21,7 @@ export type DashUserModel = mongoose.Document & { passwordResetToken: string | undefined, passwordResetExpires: Date | undefined, - allWorkspaceIds: Array<String>, - activeWorkspaceId: String, - activeUsersId: String, + userDocumentId: string; profile: { name: string, @@ -49,12 +47,7 @@ const userSchema = new mongoose.Schema({ passwordResetToken: String, passwordResetExpires: Date, - allWorkspaceIds: { - type: Array, - default: [] - }, - activeWorkspaceId: String, - activeUsersId: String, + userDocumentId: String, facebook: String, twitter: String, diff --git a/src/server/database.ts b/src/server/database.ts index 99b13805e..616251c72 100644 --- a/src/server/database.ts +++ b/src/server/database.ts @@ -1,8 +1,4 @@ -import { action, configure } from 'mobx'; import * as mongodb from 'mongodb'; -import { ObjectID } from 'mongodb'; -import { Transferable } from './Message'; -import { Utils } from '../Utils'; export class Database { public static Instance = new Database() @@ -21,7 +17,16 @@ export class Database { let collection = this.db.collection('documents'); collection.updateOne({ _id: id }, { $set: value }, { upsert: true - }, callback); + }, (err, res) => { + if (err) { + console.log(err.message); + console.log(err.errmsg); + } + // if (res) { + // console.log(JSON.stringify(res.result)); + // } + callback() + }); } } @@ -32,11 +37,13 @@ export class Database { } } - public deleteAll(collectionName: string = 'documents') { - if (this.db) { - let collection = this.db.collection(collectionName); - collection.deleteMany({}); - } + public deleteAll(collectionName: string = 'documents'): Promise<any> { + return new Promise(res => { + if (this.db) { + let collection = this.db.collection(collectionName); + collection.deleteMany({}, res); + } + }) } public insert(kvpairs: any) { diff --git a/src/server/index.ts b/src/server/index.ts index d1eb6847d..17d7432e0 100644 --- a/src/server/index.ts +++ b/src/server/index.ts @@ -156,16 +156,9 @@ addSecureRoute( addSecureRoute( Method.GET, - (user, res) => res.send(user.activeWorkspaceId || ""), + (user, res) => res.send(user.userDocumentId || ""), undefined, - RouteStore.getActiveWorkspace, -); - -addSecureRoute( - Method.GET, - (user, res) => res.send(JSON.stringify(user.allWorkspaceIds)), - undefined, - RouteStore.getAllWorkspaces + RouteStore.getUserDocumentId, ); addSecureRoute( @@ -185,28 +178,6 @@ addSecureRoute( addSecureRoute( Method.POST, (user, res, req) => { - user.update({ $set: { activeWorkspaceId: req.body.target } }, (err, raw) => { - res.sendStatus(err ? 500 : 200); - }); - }, - undefined, - RouteStore.setActiveWorkspace -); - -addSecureRoute( - Method.POST, - (user, res, req) => { - user.update({ $push: { allWorkspaceIds: req.body.target } }, (err, raw) => { - res.sendStatus(err ? 500 : 200); - }); - }, - undefined, - RouteStore.addWorkspace -); - -addSecureRoute( - Method.POST, - (user, res, req) => { let form = new formidable.IncomingForm() form.uploadDir = __dirname + "/public/files/" form.keepExtensions = true @@ -252,13 +223,11 @@ app.use(RouteStore.corsProxy, (req, res) => { }); app.get(RouteStore.delete, (req, res) => { - deleteFields(); - res.redirect(RouteStore.home); + deleteFields().then(() => res.redirect(RouteStore.home)); }); app.get(RouteStore.deleteAll, (req, res) => { - deleteAll(); - res.redirect(RouteStore.home); + deleteAll().then(() => res.redirect(RouteStore.home)); }); app.use(wdm(compiler, { @@ -291,13 +260,15 @@ server.on("connection", function (socket: Socket) { }) function deleteFields() { - Database.Instance.deleteAll(); + return Database.Instance.deleteAll(); } function deleteAll() { - Database.Instance.deleteAll(); - Database.Instance.deleteAll('sessions'); - Database.Instance.deleteAll('users'); + return Database.Instance.deleteAll().then(() => { + return Database.Instance.deleteAll('sessions') + }).then(() => { + return Database.Instance.deleteAll('users') + }); } function barReceived(guid: String) { diff --git a/src/server/public/files/upload_a6a70d84ebb65febf7900e29f52cc86d.pdf b/src/server/public/files/upload_a6a70d84ebb65febf7900e29f52cc86d.pdf Binary files differnew file mode 100644 index 000000000..dfd6ab339 --- /dev/null +++ b/src/server/public/files/upload_a6a70d84ebb65febf7900e29f52cc86d.pdf |
