Compare commits
11 Commits
v0.9
...
kaleidos-i
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2974caab1d | ||
|
|
f71081b15b | ||
|
|
c075c562d6 | ||
|
|
dc986dcc7e | ||
|
|
fc653e5ce5 | ||
|
|
4c5e6ea286 | ||
|
|
5f4d41f3a4 | ||
|
|
fb8d3ac654 | ||
|
|
c19f00b316 | ||
|
|
60ccedd840 | ||
|
|
d2f07a73cf |
10
README.md
10
README.md
@@ -1,13 +1,15 @@
|
||||
# Spacedeck Open
|
||||
|
||||
This is the free and open source version of Spacedeck, a web based, real time, collaborative whiteboard application with rich media support. Spacedeck was developed in 6 major releases during Autumn 2011 until the end of 2016 and was originally a commercial SaaS. The developers were Lukas F. Hartmann (mntmn) and Martin GĂĽther (magegu). All icons and large parts of the CSS were designed by Thomas Helbig (dergraph).
|
||||
This is the free and open source version of Spacedeck, a web based, real time, collaborative whiteboard application with rich media support. Spacedeck was developed in 6 major releases during Autumn 2011 until the end of 2016 and was originally a commercial SaaS. The developers were Lukas F. Hartmann (mntmn) and Martin GĂĽther (magegu).
|
||||
|
||||
As we plan to retire the subscription based service at spacedeck.com in May 2018, we decided to open-source Spacedeck to allow educational and other organizations who currently rely on Spacedeck to migrate to a self-hosted or local version.
|
||||
|
||||
Easy to use desktop releases with binaries for Linux, Mac and Windows will be published here soon. In the meantime, you have to install Node.JS.
|
||||
The spacedeck.com online service was shut down on May 1st 2018. We decided to open-source Spacedeck to allow educational and other organizations who currently rely on Spacedeck to migrate to a self-hosted or local version.
|
||||
|
||||
We appreciate filed issues, pull requests and general discussion.
|
||||
|
||||
**Windows users:** Try the one-click release at https://github.com/spacedeck/spacedeck-open/releases/tag/v0.9
|
||||
|
||||
Desktop releases for Linux and Mac will be published here soon. In the meantime, you have to install Node.JS to run Spacedeck.
|
||||
|
||||
# Features
|
||||
|
||||
- Create virtual whiteboards called *Spaces* with virtually unlimited size
|
||||
|
||||
@@ -92,14 +92,14 @@ function createWaveform(fileName, localFilePath, callback){
|
||||
});
|
||||
}
|
||||
|
||||
function convertVideo(fileName, filePath, codec, callback, progress_callback) {
|
||||
function convertVideo(fileName, filePath, codec, callback, progressCallback) {
|
||||
var ext = path.extname(fileName);
|
||||
var presetMime = mime.lookup(fileName);
|
||||
|
||||
var newExt = codec == "mp4" ? "mp4" : "ogv";
|
||||
var convertedPath = filePath + "." + newExt;
|
||||
|
||||
console.log("converting", filePath, "to", convertedPath, "progress_cb:",progress_callback);
|
||||
console.log("converting", filePath, "to", convertedPath);
|
||||
|
||||
var convertArgs = (codec == "mp4") ? [
|
||||
"-i", filePath,
|
||||
@@ -134,8 +134,8 @@ function convertVideo(fileName, filePath, codec, callback, progress_callback) {
|
||||
|
||||
ff.stderr.on('data', function (data) {
|
||||
console.log('[ffmpeg-video] stderr: ' + data);
|
||||
if (progress_callback) {
|
||||
progress_callback(data);
|
||||
if (progressCallback) {
|
||||
progressCallback(data);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -280,7 +280,7 @@ var resizeAndUploadImage = function(a, mimeType, size, fileName, fileNameOrg, im
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
convert: function(a, fileName, localFilePath, payloadCallback, progress_callback) {
|
||||
convert: function(a, fileName, localFilePath, payloadCallback, progressCallback) {
|
||||
getMime(fileName, localFilePath, function(err, mimeType){
|
||||
console.log("[convert] fn: "+fileName+" local: "+localFilePath+" mimeType:", mimeType);
|
||||
|
||||
@@ -311,8 +311,8 @@ module.exports = {
|
||||
var s3Key = "s"+ a.space_id.toString() + "/a" + a._id.toString() + "/" + fileName;
|
||||
|
||||
uploader.uploadFile(s3Key, "image/gif", localFilePath, function(err, url) {
|
||||
if(err)callback(err);
|
||||
else{
|
||||
if (err) payloadCallback(err);
|
||||
else {
|
||||
console.log(localFilePath);
|
||||
var stats = fs.statSync(localFilePath);
|
||||
|
||||
@@ -357,8 +357,8 @@ module.exports = {
|
||||
thumbnail: function(callback) {
|
||||
createThumbnailForVideo(fileName, localFilePath, function(err, created){
|
||||
console.log("thumbnail created: ", err, created);
|
||||
if(err) callback(err);
|
||||
else{
|
||||
if (err) callback(err);
|
||||
else {
|
||||
var keyName = "s" + a.space_id.toString() + "/a" + a._id.toString() + "/" + fileName + ".jpg" ;
|
||||
uploader.uploadFile(keyName, "image/jpeg", created, function(err, url){
|
||||
if (err) callback(err);
|
||||
@@ -380,7 +380,7 @@ module.exports = {
|
||||
else callback(null, url);
|
||||
});
|
||||
}
|
||||
}, progress_callback);
|
||||
}, progressCallback);
|
||||
}
|
||||
},
|
||||
mp4: function(callback) {
|
||||
@@ -396,7 +396,7 @@ module.exports = {
|
||||
else callback(null, url);
|
||||
});
|
||||
}
|
||||
}, progress_callback);
|
||||
}, progressCallback);
|
||||
}
|
||||
},
|
||||
original: function(callback){
|
||||
@@ -404,7 +404,7 @@ module.exports = {
|
||||
callback(null, url);
|
||||
});
|
||||
}
|
||||
}, function(err, results){
|
||||
}, function(err, results) {
|
||||
console.log(err, results);
|
||||
|
||||
if (err) payloadCallback(err, a);
|
||||
@@ -438,19 +438,16 @@ module.exports = {
|
||||
db.packArtifact(a);
|
||||
|
||||
a.updated_at = new Date();
|
||||
a.save(function(err) {
|
||||
if (err) payloadCallback(err, null);
|
||||
else {
|
||||
fs.unlink(localFilePath, function (err) {
|
||||
if (err){
|
||||
console.error(err);
|
||||
payloadCallback(err, null);
|
||||
} else {
|
||||
console.log('successfully deleted ' + localFilePath);
|
||||
payloadCallback(null, a);
|
||||
}
|
||||
});
|
||||
}
|
||||
a.save().then(function() {
|
||||
fs.unlink(localFilePath, function (err) {
|
||||
if (err) {
|
||||
console.error(err);
|
||||
payloadCallback(err, null);
|
||||
} else {
|
||||
console.log('successfully deleted ' + localFilePath);
|
||||
payloadCallback(null, a);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
@@ -16,7 +16,8 @@ module.exports = (req, res, next) => {
|
||||
else db.User.findOne({where: {_id: session.user_id}})
|
||||
.then(user => {
|
||||
if (!user) {
|
||||
res.clearCookie('sdsession');
|
||||
var domain = (process.env.NODE_ENV == "production") ? new URL(config.get('endpoint')).hostname : req.headers.hostname;
|
||||
res.clearCookie('sdsession', { domain: domain });
|
||||
|
||||
if (req.accepts("text/html")) {
|
||||
res.send("Please clear your cookies and try again.");
|
||||
|
||||
67
models/db.js
67
models/db.js
@@ -1,7 +1,4 @@
|
||||
//'use strict';
|
||||
|
||||
//var mongoose = require('mongoose');
|
||||
//const sqlite3 = require('sqlite3').verbose();
|
||||
const Umzug = require('umzug');
|
||||
|
||||
function sequel_log(a,b,c) {
|
||||
console.log(a);
|
||||
@@ -81,13 +78,13 @@ module.exports = {
|
||||
height: Sequelize.INTEGER,
|
||||
background_color: Sequelize.STRING,
|
||||
background_uri: Sequelize.STRING,
|
||||
|
||||
|
||||
created_at: {type: Sequelize.DATE, defaultValue: Sequelize.NOW},
|
||||
updated_at: {type: Sequelize.DATE, defaultValue: Sequelize.NOW},
|
||||
thumbnail_url: Sequelize.STRING,
|
||||
thumbnail_updated_at: {type: Sequelize.DATE}
|
||||
}),
|
||||
|
||||
|
||||
Membership: sequelize.define('membership', {
|
||||
_id: {type: Sequelize.STRING, primaryKey: true},
|
||||
space_id: Sequelize.STRING,
|
||||
@@ -98,7 +95,7 @@ module.exports = {
|
||||
created_at: {type: Sequelize.DATE, defaultValue: Sequelize.NOW},
|
||||
updated_at: {type: Sequelize.DATE, defaultValue: Sequelize.NOW}
|
||||
}),
|
||||
|
||||
|
||||
Message: sequelize.define('message', {
|
||||
_id: {type: Sequelize.STRING, primaryKey: true},
|
||||
space_id: Sequelize.STRING,
|
||||
@@ -108,7 +105,7 @@ module.exports = {
|
||||
created_at: {type: Sequelize.DATE, defaultValue: Sequelize.NOW},
|
||||
updated_at: {type: Sequelize.DATE, defaultValue: Sequelize.NOW}
|
||||
}),
|
||||
|
||||
|
||||
Artifact: sequelize.define('artifact', {
|
||||
_id: {type: Sequelize.STRING, primaryKey: true},
|
||||
space_id: Sequelize.STRING,
|
||||
@@ -121,7 +118,7 @@ module.exports = {
|
||||
last_update_editor_name: Sequelize.STRING,
|
||||
description: Sequelize.TEXT,
|
||||
state: {type: Sequelize.STRING, default: "idle"},
|
||||
|
||||
|
||||
//linked_to: Sequelize.STRING,
|
||||
title: Sequelize.STRING,
|
||||
tags: Sequelize.TEXT,
|
||||
@@ -142,16 +139,16 @@ module.exports = {
|
||||
//}],
|
||||
|
||||
control_points: Sequelize.TEXT,
|
||||
|
||||
|
||||
group: Sequelize.STRING,
|
||||
locked: {type: Sequelize.BOOLEAN, default: false},
|
||||
|
||||
|
||||
payload_uri: Sequelize.STRING,
|
||||
payload_thumbnail_web_uri: Sequelize.STRING,
|
||||
payload_thumbnail_medium_uri: Sequelize.STRING,
|
||||
payload_thumbnail_big_uri: Sequelize.STRING,
|
||||
payload_size: Sequelize.INTEGER, // file size in bytes
|
||||
|
||||
|
||||
fill_color: {type: Sequelize.STRING, default: "transparent"},
|
||||
stroke_color: {type: Sequelize.STRING, default: "#000000"},
|
||||
text_color: Sequelize.STRING,
|
||||
@@ -176,7 +173,7 @@ module.exports = {
|
||||
border_radius: Sequelize.INTEGER,
|
||||
align: {type: Sequelize.STRING, default: "left"},
|
||||
valign: {type: Sequelize.STRING, default: "top"},
|
||||
|
||||
|
||||
brightness: Sequelize.DECIMAL,
|
||||
contrast: Sequelize.DECIMAL,
|
||||
saturation: Sequelize.DECIMAL,
|
||||
@@ -185,7 +182,7 @@ module.exports = {
|
||||
opacity: Sequelize.DECIMAL,
|
||||
|
||||
payload_alternatives: Sequelize.TEXT,
|
||||
|
||||
|
||||
/*payload_alternatives: [{
|
||||
mime: String,
|
||||
payload_uri: String,
|
||||
@@ -194,12 +191,12 @@ module.exports = {
|
||||
payload_thumbnail_big_uri: String,
|
||||
payload_size: Number
|
||||
}],*/
|
||||
|
||||
|
||||
created_at: {type: Sequelize.DATE, defaultValue: Sequelize.NOW},
|
||||
updated_at: {type: Sequelize.DATE, defaultValue: Sequelize.NOW}
|
||||
}),
|
||||
|
||||
init: function() {
|
||||
|
||||
init: async function() {
|
||||
User = this.User;
|
||||
Session = this.Session;
|
||||
Space = this.Space;
|
||||
@@ -220,49 +217,69 @@ module.exports = {
|
||||
},
|
||||
as: 'user'
|
||||
});
|
||||
|
||||
|
||||
Membership.belongsTo(Space, {
|
||||
foreignKey: {
|
||||
name: 'space_id'
|
||||
},
|
||||
as: 'space'
|
||||
});
|
||||
|
||||
|
||||
Artifact.belongsTo(User, {
|
||||
foreignKey: {
|
||||
name: 'user_id'
|
||||
},
|
||||
as: 'user'
|
||||
});
|
||||
|
||||
|
||||
Artifact.belongsTo(Space, {
|
||||
foreignKey: {
|
||||
name: 'space_id'
|
||||
},
|
||||
as: 'space'
|
||||
});
|
||||
|
||||
|
||||
Message.belongsTo(User, {
|
||||
foreignKey: {
|
||||
name: 'user_id'
|
||||
},
|
||||
as: 'user'
|
||||
});
|
||||
|
||||
|
||||
Message.belongsTo(Space, {
|
||||
foreignKey: {
|
||||
name: 'space_id'
|
||||
},
|
||||
as: 'space'
|
||||
});
|
||||
|
||||
sequelize.sync();
|
||||
|
||||
await sequelize.sync();
|
||||
|
||||
var umzug = new Umzug({
|
||||
storage: 'sequelize',
|
||||
storageOptions: {
|
||||
sequelize: sequelize
|
||||
},
|
||||
migrations: {
|
||||
params: [
|
||||
sequelize.getQueryInterface(),
|
||||
Sequelize
|
||||
],
|
||||
path: './models/migrations',
|
||||
pattern: /\.js$/
|
||||
}
|
||||
});
|
||||
|
||||
umzug.up().then(function(migrations) {
|
||||
console.log('Migration complete up!');
|
||||
});
|
||||
|
||||
},
|
||||
|
||||
getUserRoleInSpace: (originalSpace, user, cb) => {
|
||||
originalSpace.path = [];
|
||||
console.log("getUserRoleInSpace",originalSpace._id,user._id,user.home_folder_id);
|
||||
|
||||
|
||||
if (originalSpace._id == user.home_folder_id || (originalSpace.creator_id && originalSpace.creator_id == user._id)) {
|
||||
cb("admin");
|
||||
} else {
|
||||
|
||||
80
models/migrations/01-spaces-delete-cascade.js
Normal file
80
models/migrations/01-spaces-delete-cascade.js
Normal file
@@ -0,0 +1,80 @@
|
||||
'use strict';
|
||||
|
||||
module.exports = {
|
||||
up: function(migration, DataTypes) {
|
||||
return [
|
||||
migration.changeColumn('memberships', 'space_id',
|
||||
{
|
||||
type: DataTypes.STRING,
|
||||
references: {
|
||||
model: 'spaces',
|
||||
key: '_id'
|
||||
},
|
||||
onDelete: 'CASCADE',
|
||||
onUpdate: 'CASCADE'
|
||||
}
|
||||
),
|
||||
migration.changeColumn('artifacts', 'space_id',
|
||||
{
|
||||
type: DataTypes.STRING,
|
||||
references: {
|
||||
model: 'spaces',
|
||||
key: '_id'
|
||||
},
|
||||
onDelete: 'CASCADE',
|
||||
onUpdate: 'CASCADE'
|
||||
}
|
||||
),
|
||||
migration.changeColumn('messages', 'space_id',
|
||||
{
|
||||
type: DataTypes.STRING,
|
||||
references: {
|
||||
model: 'spaces',
|
||||
key: '_id'
|
||||
},
|
||||
onDelete: 'CASCADE',
|
||||
onUpdate: 'CASCADE'
|
||||
}
|
||||
)
|
||||
]
|
||||
},
|
||||
|
||||
down: function(migration, DataTypes) {
|
||||
return [
|
||||
migration.changeColumn('memberships', 'space_id',
|
||||
{
|
||||
type: DataTypes.STRING,
|
||||
references: {
|
||||
model: 'spaces',
|
||||
key: '_id'
|
||||
},
|
||||
onDelete: 'CASCADE',
|
||||
onUpdate: 'NO ACTION'
|
||||
}
|
||||
),
|
||||
,
|
||||
migration.changeColumn('artifacts', 'space_id',
|
||||
{
|
||||
type: DataTypes.STRING,
|
||||
references: {
|
||||
model: 'spaces',
|
||||
key: '_id'
|
||||
},
|
||||
onDelete: 'CASCADE',
|
||||
onUpdate: 'NO ACTION'
|
||||
}
|
||||
),
|
||||
migration.changeColumn('messages', 'space_id',
|
||||
{
|
||||
type: DataTypes.STRING,
|
||||
references: {
|
||||
model: 'spaces',
|
||||
key: '_id'
|
||||
},
|
||||
onDelete: 'CASCADE',
|
||||
onUpdate: 'NO ACTION'
|
||||
}
|
||||
)
|
||||
]
|
||||
}
|
||||
};
|
||||
@@ -40,6 +40,7 @@
|
||||
"slug": "0.9.1",
|
||||
"sqlite3": "^4.0.0",
|
||||
"swig": "1.4.2",
|
||||
"umzug": "^2.1.0",
|
||||
"underscore": "1.8.3",
|
||||
"uuid": "^3.2.1",
|
||||
"validator": "7.0.0",
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -587,7 +587,7 @@ var SpacedeckBoardArtifacts = {
|
||||
var selected = this.selected_artifacts();
|
||||
if (selected.length<2) return;
|
||||
|
||||
var sorted = _.sortBy(selected, function(a) { return a.x+a.y*this.active_space.advanced.width }.bind(this));
|
||||
var sorted = _.sortBy(selected, function(a) { return a.x+a.y*this.active_space.width }.bind(this));
|
||||
|
||||
var minx = sorted[0].x;
|
||||
var miny = sorted[0].y;
|
||||
@@ -596,11 +596,13 @@ var SpacedeckBoardArtifacts = {
|
||||
|
||||
var blocks = [];
|
||||
|
||||
var padding = 10;
|
||||
|
||||
for (var i=0; i<sorted.length; i++) {
|
||||
var a = sorted[i];
|
||||
blocks.push({
|
||||
w: a.w,
|
||||
h: a.h,
|
||||
w: a.w+padding,
|
||||
h: a.h+padding,
|
||||
a: a
|
||||
});
|
||||
}
|
||||
|
||||
@@ -252,8 +252,6 @@ var SpacedeckRoutes = {
|
||||
// #hash
|
||||
if (event.currentTarget.hash && event.currentTarget.hash.length>1) return;
|
||||
|
||||
console.log("clicked", event.currentTarget.pathname);
|
||||
|
||||
// external link?
|
||||
if (event.currentTarget.host != location.host) return;
|
||||
|
||||
@@ -269,35 +267,6 @@ var SpacedeckRoutes = {
|
||||
event.preventDefault();
|
||||
}.bind(this));
|
||||
|
||||
if (location.host!=ENV.webHost) {
|
||||
if (!subdomainTeam) {
|
||||
location.href = ENV.webEndpoint;
|
||||
return;
|
||||
} else {
|
||||
if(subdomainTeam.subdomain) {
|
||||
var realHost = (subdomainTeam.subdomain + "." + ENV.webHost);
|
||||
if (location.host != realHost) {
|
||||
location.href = realHost;
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
location.href = ENV.webEndpoint;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (this.logged_in) {
|
||||
if (this.user.team) {
|
||||
if (this.user.team.subdomain && this.user.team.subdomain.length > 0) {
|
||||
var realHost = (this.user.team.subdomain + "." + ENV.webHost);
|
||||
if (location.host != realHost) {
|
||||
location.href = location.protocol + "//" + realHost + location.pathname;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
this.internal_route(location.pathname);
|
||||
},
|
||||
|
||||
|
||||
@@ -71,9 +71,7 @@ var SpacedeckSpaces = {
|
||||
methods: {
|
||||
search_spaces: function() {
|
||||
var query = this.folder_spaces_search;
|
||||
console.log("search query: ",query);
|
||||
load_spaces_search(query, function(spaces) {
|
||||
console.log("results: ",spaces);
|
||||
this.active_profile_spaces = spaces;
|
||||
}.bind(this));
|
||||
},
|
||||
@@ -85,14 +83,7 @@ var SpacedeckSpaces = {
|
||||
location.reload();
|
||||
},
|
||||
ask_guestname: function(dft, cb) {
|
||||
console.log("ask_guestname");
|
||||
|
||||
var team_name = "Spacedeck";
|
||||
|
||||
if(subdomainTeam) {
|
||||
team_name = subdomainTeam.name;
|
||||
}
|
||||
smoke.prompt(__('what_is_your_name', team_name) , function(content) {
|
||||
smoke.prompt(__('what_is_your_name', "Spacedeck") , function(content) {
|
||||
if (!content || (content.length === 0)) {
|
||||
this.ask_guestname(dft, cb);
|
||||
} else {
|
||||
@@ -101,7 +92,7 @@ var SpacedeckSpaces = {
|
||||
if ("localStorage" in window && localStorage) {
|
||||
try {
|
||||
localStorage['guest_nickname'] = this.guest_nickname;
|
||||
}catch(e) {
|
||||
} catch(e) {
|
||||
console.error(e);
|
||||
}
|
||||
}
|
||||
@@ -172,7 +163,6 @@ var SpacedeckSpaces = {
|
||||
this.space_embed_html = "<iframe width=\"1024\" height=\"768\" seamless src=\""+ENV.webEndpoint+"/spaces/"+space._id+"?embedded=1\"></iframe>";
|
||||
|
||||
if (!is_home) {
|
||||
//console.log(space);
|
||||
load_members(space, function(members) {
|
||||
this.active_space_memberships = members;
|
||||
}.bind(this));
|
||||
|
||||
@@ -48,10 +48,6 @@ SpacedeckUsers = {
|
||||
},
|
||||
|
||||
finalize_login: function(session_token, on_success) {
|
||||
if(!window.socket_auth || window.socket_auth == '' || window.socket_auth == 'null') {
|
||||
window.socket_auth = session_token;
|
||||
}
|
||||
|
||||
this.load_user(function(user) {
|
||||
if (this.invitation_token) {
|
||||
accept_invitation(this.invitation_token, function(memberships){
|
||||
|
||||
@@ -59,13 +59,13 @@ SpacedeckWebsockets = {
|
||||
else if (msg.action == "delete" && msg.object) {
|
||||
if (this.active_space) {
|
||||
var o = msg.object;
|
||||
if(o._id){
|
||||
if (o._id){
|
||||
var existing_artifact = this.find_artifact_by_id(o._id);
|
||||
if (existing_artifact) {
|
||||
var idx = this.active_space_artifacts.indexOf(existing_artifact);
|
||||
this.active_space_artifacts.splice(idx, 1);
|
||||
} else console.log("existing artifact to delete not found");
|
||||
}else console.error("object without _id");
|
||||
} else console.error("object without _id");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -101,11 +101,13 @@ SpacedeckWebsockets = {
|
||||
}
|
||||
|
||||
if (this.websocket && this.websocket.readyState==1) {
|
||||
var token = "";
|
||||
if (this.user) token = this.user.token;
|
||||
var auth_params = {
|
||||
action: "auth",
|
||||
editor_auth: space_auth,
|
||||
editor_name: this.guest_nickname,
|
||||
auth_token: window.socket_auth,
|
||||
auth_token: token,
|
||||
space_id: space._id
|
||||
};
|
||||
console.log("[websocket] auth space");
|
||||
|
||||
@@ -23,7 +23,6 @@ router.post('/', function(req, res) {
|
||||
db.User.findOne({where: {email: email}})
|
||||
.error(err => {
|
||||
res.sendStatus(404);
|
||||
//res.status(400).json({"error":"session.users"});
|
||||
})
|
||||
.then(user => {
|
||||
if (!user) {
|
||||
@@ -32,7 +31,6 @@ router.post('/', function(req, res) {
|
||||
else if (bcrypt.compareSync(password, user.password_hash)) {
|
||||
crypto.randomBytes(48, function(ex, buf) {
|
||||
var token = buf.toString('hex');
|
||||
console.log("!!! token: ",token);
|
||||
|
||||
var session = {
|
||||
user_id: user._id,
|
||||
@@ -48,7 +46,7 @@ router.post('/', function(req, res) {
|
||||
res.sendStatus(500);
|
||||
})
|
||||
.then(() => {
|
||||
var domain = (process.env.NODE_ENV == "production") ? new URL(config.get('endpoint')).hostname : "localhost";
|
||||
var domain = (process.env.NODE_ENV == "production") ? new URL(config.get('endpoint')).hostname : req.headers.hostname;
|
||||
res.cookie('sdsession', token, { domain: domain, httpOnly: true });
|
||||
res.status(201).json(session);
|
||||
});
|
||||
@@ -61,16 +59,14 @@ router.post('/', function(req, res) {
|
||||
|
||||
router.delete('/current', function(req, res, next) {
|
||||
if (req.user) {
|
||||
/*var user = req.user;
|
||||
var newSessions = user.sessions.filter( function(session){
|
||||
return session.token != req.token;
|
||||
});*/
|
||||
//user.sessions = newSessions;
|
||||
//user.save(function(err, result) {
|
||||
var domain = new URL(config.get('endpoint')).hostname;
|
||||
res.clearCookie('sdsession', { domain: domain });
|
||||
res.sendStatus(204);
|
||||
//});
|
||||
var token = req.cookies['sdsession'];
|
||||
db.Session.findOne({where: {token: token}})
|
||||
.then(session => {
|
||||
session.destroy();
|
||||
});
|
||||
var domain = (process.env.NODE_ENV == "production") ? new URL(config.get('endpoint')).hostname : req.headers.hostname;
|
||||
res.clearCookie('sdsession', { domain: domain });
|
||||
res.sendStatus(204);
|
||||
} else {
|
||||
res.sendStatus(404);
|
||||
}
|
||||
|
||||
@@ -123,11 +123,11 @@ router.post('/:artifact_id/payload', function(req, res, next) {
|
||||
var writeStream = fs.createWriteStream(localFilePath);
|
||||
var stream = req.pipe(writeStream);
|
||||
|
||||
var progress_callback = function(progress_msg) {
|
||||
a.description = progress_msg.toString();
|
||||
var progressCallback = function(progressMsg) {
|
||||
a.description = progressMsg.toString();
|
||||
db.packArtifact(a);
|
||||
a.save();
|
||||
redis.sendMessage("update", a, a.toJSON(), req.channelId);
|
||||
redis.sendMessage("update", "Artifact", a, req.channelId);
|
||||
};
|
||||
|
||||
stream.on('finish', function() {
|
||||
@@ -137,7 +137,7 @@ router.post('/:artifact_id/payload', function(req, res, next) {
|
||||
db.Space.update({ updated_at: new Date() }, {where: {_id: req.space._id}});
|
||||
res.distributeUpdate("Artifact", artifact);
|
||||
}
|
||||
}, progress_callback);
|
||||
}, progressCallback);
|
||||
});
|
||||
} else {
|
||||
res.status(401).json({
|
||||
@@ -165,6 +165,7 @@ router.put('/:artifact_id', function(req, res, next) {
|
||||
}}).then(rows => {
|
||||
db.unpackArtifact(newAttr);
|
||||
db.Space.update({ updated_at: new Date() }, {where: {_id: req.space._id} });
|
||||
newAttr._id = a._id;
|
||||
res.distributeUpdate("Artifact", newAttr);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -240,7 +240,6 @@ router.get('/zip', function(req, res, next) {
|
||||
});
|
||||
|
||||
router.get('/html', function(req, res) {
|
||||
console.log("!!!!! hello ");
|
||||
db.Artifact.findAll({where: {
|
||||
space_id: req.space._id
|
||||
}}).then(function(artifacts) {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
"use strict";
|
||||
var config = require('config');
|
||||
const os = require('os');
|
||||
const db = require('../../models/db');
|
||||
const Sequelize = require('sequelize');
|
||||
const Op = Sequelize.Op;
|
||||
@@ -422,17 +423,16 @@ router.post('/:id/artifacts-pdf', function(req, res, next) {
|
||||
|
||||
var withZones = (req.query.zones) ? req.query.zones == "true" : false;
|
||||
var fileName = (req.query.filename || "upload.bin").replace(/[^a-zA-Z0-9\.]/g, '');
|
||||
var localFilePath = "/tmp/" + fileName;
|
||||
var localFilePath = os.tmpdir() + "/" + fileName;
|
||||
var writeStream = fs.createWriteStream(localFilePath);
|
||||
var stream = req.pipe(writeStream);
|
||||
|
||||
req.on('end', function() {
|
||||
|
||||
var rawName = fileName.slice(0, fileName.length - 4);
|
||||
var outputFolder = "/tmp/" + rawName;
|
||||
var rights = 777;
|
||||
|
||||
fs.mkdir(outputFolder, function(db) {
|
||||
var outputFolder = os.tmpdir() + "/" + rawName;
|
||||
|
||||
fs.mkdir(outputFolder, function(err) {
|
||||
var images = outputFolder + "/" + rawName + "-page-%03d.jpeg";
|
||||
|
||||
// FIXME not portable
|
||||
@@ -455,7 +455,7 @@ router.post('/:id/artifacts-pdf', function(req, res, next) {
|
||||
|
||||
var number = parseInt(baseName.slice(baseName.length - 3, baseName.length), 10);
|
||||
|
||||
gm(localFilePath).size(function(err, size) {
|
||||
gm(localFilePath).size((err, size) => {
|
||||
var w = 350;
|
||||
var h = w;
|
||||
|
||||
@@ -463,56 +463,51 @@ router.post('/:id/artifacts-pdf', function(req, res, next) {
|
||||
var y = startY + ((parseInt(((number - 1) / limitPerRow), 10) + 1) * w);
|
||||
|
||||
var userId;
|
||||
if (req.user)
|
||||
userId = req.user._id;
|
||||
if (req.user) userId = req.user._id;
|
||||
|
||||
var a = new Artifact({
|
||||
var a = db.Artifact.create({
|
||||
_id: uuidv4(),
|
||||
mime: "image/jpg",
|
||||
space_id: req.space._id,
|
||||
user_id: userId,
|
||||
editor_name: req.guest_name,
|
||||
board: {
|
||||
w: w,
|
||||
h: h,
|
||||
x: x,
|
||||
y: y,
|
||||
z: (number + (count + 100))
|
||||
}
|
||||
});
|
||||
|
||||
payloadConverter.convert(a, fileName, localfilePath, (error, artifact) => {
|
||||
if (error) res.status(400).json(error);
|
||||
else {
|
||||
if (withZones) {
|
||||
var zone = new Artifact({
|
||||
mime: "x-spacedeck/zone",
|
||||
description: "Zone " + (number),
|
||||
space_id: req.space._id,
|
||||
user_id: userId,
|
||||
editor_name: req.guest_name,
|
||||
board: {
|
||||
w: artifact.board.w + 20,
|
||||
h: artifact.board.h + 40,
|
||||
w: w,
|
||||
h: h,
|
||||
x: x,
|
||||
y: y,
|
||||
z: (number + (count + 100))
|
||||
}).then(a => {
|
||||
payloadConverter.convert(a, fileName, localfilePath, (error, artifact) => {
|
||||
if (error) res.status(400).json(error);
|
||||
else {
|
||||
if (withZones) {
|
||||
var zone = {
|
||||
_id: uuidv4(),
|
||||
mime: "x-spacedeck/zone",
|
||||
description: "Zone " + (number),
|
||||
space_id: req.space._id,
|
||||
user_id: userId,
|
||||
editor_name: req.guest_name,
|
||||
w: artifact.w + 20,
|
||||
h: artifact.h + 40,
|
||||
x: x - 10,
|
||||
y: y - 30,
|
||||
z: number
|
||||
},
|
||||
style: {
|
||||
z: number,
|
||||
order: number,
|
||||
valign: "middle",
|
||||
align: "center"
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
zone.save((err) => {
|
||||
redis.sendMessage("create", "Artifact", zone.toJSON(), req.channelId);
|
||||
cb(null, [artifact, zone]);
|
||||
});
|
||||
db.Artifact.create(zone).then((z) => {
|
||||
redis.sendMessage("create", "Artifact", z.toJSON(), req.channelId);
|
||||
cb(null, [artifact, zone]);
|
||||
});
|
||||
|
||||
} else {
|
||||
cb(null, [artifact]);
|
||||
} else {
|
||||
cb(null, [artifact]);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
@@ -527,10 +522,10 @@ router.post('/:id/artifacts-pdf', function(req, res, next) {
|
||||
|
||||
if (artifact_or_artifacts instanceof Array) {
|
||||
_.each(artifact_or_artifacts, (a) => {
|
||||
redis.sendMessage("create", "Artifact", a.toJSON(), req.channelId);
|
||||
redis.sendMessage("create", "Artifact", JSON.stringify(a), req.channelId);
|
||||
});
|
||||
} else {
|
||||
redis.sendMessage("create", "Artifact", artifact_or_artifacts.toJSON(), req.channelId);
|
||||
redis.sendMessage("create", "Artifact", JSON.stringify(artifact_or_artifacts), req.channelId);
|
||||
}
|
||||
cb(null);
|
||||
});
|
||||
|
||||
@@ -26,8 +26,15 @@ var glob = require('glob');
|
||||
|
||||
router.get('/current', function(req, res, next) {
|
||||
if (req.user) {
|
||||
console.log(req.user.team);
|
||||
res.status(200).json(req.user);
|
||||
var u = _.clone(req.user.dataValues);
|
||||
delete u.password_hash;
|
||||
delete u.password_reset_token;
|
||||
delete u.confirmation_token;
|
||||
u.token = req.cookies['sdsession'];
|
||||
|
||||
console.log(u);
|
||||
|
||||
res.status(200).json(u);
|
||||
} else {
|
||||
res.status(401).json({"error":"user_not_found"});
|
||||
}
|
||||
|
||||
@@ -22,29 +22,13 @@
|
||||
window.browser_lang = '[[locale]]';
|
||||
window.csrf_token = '[[csrf_token]]';
|
||||
|
||||
{% if process.env.NODE_ENV != "production" %}
|
||||
var ENV = {
|
||||
name: 'development',
|
||||
webHost: "localhost:9666",
|
||||
webEndpoint:"http://localhost:9666",
|
||||
apiEndpoint: "http://localhost:9666",
|
||||
websocketsEndpoint: "ws://localhost:9666"
|
||||
};
|
||||
{% else %}
|
||||
var ENV = {
|
||||
name: 'production',
|
||||
webHost: location.host,
|
||||
webEndpoint: location.origin,
|
||||
apiEndpoint: location.origin,
|
||||
websocketsEndpoint: location.origin.replace("https:","wss:").replace("http:","ws:")
|
||||
};
|
||||
{% endif %}
|
||||
|
||||
{% if subdomain_team %}
|
||||
var subdomainTeam = [[ subdomain_team | json | safe ]];
|
||||
{% else %}
|
||||
var subdomainTeam = null;
|
||||
{% endif %}
|
||||
var ENV = {
|
||||
name: 'development',
|
||||
webHost: location.host,
|
||||
webEndpoint: location.origin,
|
||||
apiEndpoint: location.origin,
|
||||
websocketsEndpoint: location.origin.replace("https:","wss:").replace("http:","ws:")
|
||||
};
|
||||
</script>
|
||||
|
||||
{% if process.env.NODE_ENV == "production" %}
|
||||
|
||||
Reference in New Issue
Block a user