aboutsummaryrefslogtreecommitdiff
path: root/src/server
diff options
context:
space:
mode:
Diffstat (limited to 'src/server')
-rw-r--r--src/server/Message.ts168
-rw-r--r--src/server/RouteStore.ts5
-rw-r--r--src/server/ServerUtil.ts96
-rw-r--r--src/server/authentication/controllers/WorkspacesMenu.tsx19
-rw-r--r--src/server/authentication/controllers/user_controller.ts3
-rw-r--r--src/server/authentication/models/current_user_utils.ts91
-rw-r--r--src/server/authentication/models/user_model.ts11
-rw-r--r--src/server/database.ts27
-rw-r--r--src/server/index.ts49
-rw-r--r--src/server/public/files/upload_a6a70d84ebb65febf7900e29f52cc86d.pdfbin0 -> 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
new file mode 100644
index 000000000..dfd6ab339
--- /dev/null
+++ b/src/server/public/files/upload_a6a70d84ebb65febf7900e29f52cc86d.pdf
Binary files differ