2 Commits

Author SHA1 Message Date
greenkeeper[bot]
f7df0b7f43 docs(readme): add Greenkeeper badge
https://greenkeeper.io/
2017-04-07 07:55:54 +00:00
greenkeeper[bot]
d11eab4038 chore(package): update dependencies
https://greenkeeper.io/
2017-04-07 07:55:51 +00:00
18 changed files with 68 additions and 170 deletions

View File

@@ -1,14 +0,0 @@
.DS_Store
.git
logs
*.log
scripts
pids
*.pid
*.seed
lib-cov
coverage
.grunt
.lock-wscript
build/Release
node_modules

View File

@@ -1,19 +0,0 @@
FROM spacedeck/docker-baseimage:latest
ENV NODE_ENV production
RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app
COPY package.json /usr/src/app/
RUN npm install
RUN npm install gulp-rev-replace gulp-clean gulp-fingerprint gulp-rev gulp-rev-all gulp-rev-replace
RUN npm install -g --save-dev gulp
COPY . /usr/src/app
RUN gulp styles
RUN npm cache clean
CMD [ "npm", "start" ]
EXPOSE 9666

View File

@@ -12,9 +12,10 @@ var uglify = require('gulp-uglify');
var fingerprint = require('gulp-fingerprint'); var fingerprint = require('gulp-fingerprint');
var rev = require('gulp-rev'); var rev = require('gulp-rev');
var revAll = require('gulp-rev-all'); var RevAll = require('gulp-rev-all');
gulp.task('rev', () => { gulp.task('rev', () => {
var revAll = new RevAll();
return gulp.src(['public/**']) return gulp.src(['public/**'])
.pipe(gulp.dest('build/assets')) .pipe(gulp.dest('build/assets'))
.pipe(revAll.revision()) .pipe(revAll.revision())

View File

@@ -1,5 +1,7 @@
# Spacedeck Open # Spacedeck Open
[![Greenkeeper badge](https://badges.greenkeeper.io/spacedeck/spacedeck-open.svg)](https://greenkeeper.io/)
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). All icons and large parts of the CSS were designed by Thomas Helbig (dergraph).
As we plan to retire the subscription based service at spacedeck.com in late 2017, we decided to open-source Spacedeck to allow educational and other organizations who currently rely on Spacedeck to migrate to a self-hosted version. As we plan to retire the subscription based service at spacedeck.com in late 2017, we decided to open-source Spacedeck to allow educational and other organizations who currently rely on Spacedeck to migrate to a self-hosted version.
@@ -23,16 +25,16 @@ We appreciate filed issues, pull requests and general discussion.
Spacedeck uses the following major building blocks: Spacedeck uses the following major building blocks:
- Vue.js (Frontend) - Node.js 4.x (Backend / API)
- Node.js 7.x (Backend / API)
- MongoDB 3.x (Datastore) - MongoDB 3.x (Datastore)
- Redis 3.x (Datastore for realtime channels) - Redis 3.x (Datastore for realtime channels)
- Vue.js (Frontend)
It also has some binary dependencies for media conversion and PDF export: It also has some binary dependencies for media conversion and PDF export:
- imagemagick, graphicsmagick, libav(+codecs, ffmpeg replacement), audiowaveform (https://github.com/bbcrd/audiowaveform), phantomjs (http://phantomjs.org/) - imagemagick
Currently, media files are stored in Amazon S3, so you need an Amazon AWS account and have the ```AWS_ACCESS_KEY_ID``` and ```AWS_SECRET_ACCESS_KEY``` environment variables defined. For sending emails in production, Amazon SES is required. Currently, media files are stored in Amazon S3, so you need an Amazon AWS account and have the ```AWS_ACCESS_KEY_ID``` and ```AWS_SECRET_ACCESS_KEY``` environment variables defined. For sending emails, Amazon SES is required.
To install Spacedeck, you need node.js 4.x and a running MongoDB instance. Then, to install all node dependencies, run To install Spacedeck, you need node.js 4.x and a running MongoDB instance. Then, to install all node dependencies, run
@@ -42,22 +44,10 @@ To rebuild the frontend CSS styles (you need to do this at least once):
gulp styles gulp styles
# Configuration
see: config/config.json
# Run # Run
export NODE_ENV=development export NODE_ENV=development
npm start npm start
open http://localhost:9666
# experimental docker(compose) support
We have a docker base image at https://github.com/spacedeck/docker-baseimage that includes all required binaries. Based on this image we can use Docker-Compose to bootstrap a Spacedeck including data storages.
docker-compose build
docker-compose run -e ENV=development -p 9666:9666 -e NODE_ENV=development spacedeck-open
# License # License

6
app.js
View File

@@ -47,7 +47,7 @@ swig.setFilter('cdn', function(input, idx) {
app.engine('html', swig.renderFile); app.engine('html', swig.renderFile);
app.set('view engine', 'html'); app.set('view engine', 'html');
if (isProduction) { if (app.get('env') != 'development') {
app.set('views', path.join(__dirname, 'build', 'views')); app.set('views', path.join(__dirname, 'build', 'views'));
app.use(favicon(path.join(__dirname, 'build', 'assets', 'images', 'favicon.png'))); app.use(favicon(path.join(__dirname, 'build', 'assets', 'images', 'favicon.png')));
app.use(express.static(path.join(__dirname, 'build', 'assets'))); app.use(express.static(path.join(__dirname, 'build', 'assets')));
@@ -121,11 +121,11 @@ if (app.get('env') == 'development') {
module.exports = app; module.exports = app;
// CONNECT TO DATABASE // CONNECT TO DATABASE
const mongoHost = process.env.MONGO_PORT_27017_TCP_ADDR || 'db'; const mongoHost = process.env.MONGO_PORT_27017_TCP_ADDR || 'localhost';
mongoose.connect('mongodb://' + mongoHost + '/spacedeck'); mongoose.connect('mongodb://' + mongoHost + '/spacedeck');
// START WEBSERVER // START WEBSERVER
const port = 9666; const port = 9000;
const server = http.Server(app).listen(port, () => { const server = http.Server(app).listen(port, () => {

View File

@@ -1,8 +1,7 @@
{ {
"endpoint": "http://localhost:9666", "endpoint": "http://localhost:9000",
"storage_bucket": "sdeck-development", "storage_bucket": "my_spacedeck_s3_bucket",
"storage_cdn": "http://localhost:9123/sdeck-development", "storage_cdn": "xyz.cloudfront.net",
"storage_endpoint": "http://storage:9000",
"google_access" : "", "google_access" : "",
"google_secret" : "", "google_secret" : "",
"admin_pass": "very_secret_admin_password", "admin_pass": "very_secret_admin_password",

View File

@@ -1,34 +0,0 @@
version: '2'
services:
sync:
image: redis
storage:
image: minio/minio
environment:
- MINIO_ACCESS_KEY=AKIAIOSFODNN7EXAMPLE
- MINIO_SECRET_KEY=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
ports:
- 9123:9000
command: server /export
db:
image: mongo
spacedeck-open:
environment:
- env=development
- MINIO_ACCESS_KEY=AKIAIOSFODNN7EXAMPLE
- MINIO_SECRET_KEY=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
build: .
volumes:
# - ./:/usr/src/app
- /usr/src/app/node_modules
command: npm start
ports:
- 9666:9666
depends_on:
- db
- sync
- storage
links:
- storage
- db
- sync

View File

@@ -32,36 +32,31 @@ module.exports = {
}; };
phantom.create({ path: require('phantomjs-prebuilt').path }, function (err, browser) { phantom.create({ path: require('phantomjs-prebuilt').path }, function (err, browser) {
if(err){ return browser.createPage(function (err, page) {
console.log(err); console.log("page created, opening ",space_url);
}else{
return browser.createPage(function (err, page) {
console.log("page created, opening ",space_url);
if (type=="pdf") { if (type=="pdf") {
var psz = { var psz = {
width: space.advanced.width+"px", width: space.advanced.width+"px",
height: space.advanced.height+"px" height: space.advanced.height+"px"
}; };
page.set('paperSize', psz); page.set('paperSize', psz);
} }
page.set('settings.resourceTimeout',timeout); page.set('settings.resourceTimeout',timeout);
page.set('settings.javascriptEnabled',false); page.set('settings.javascriptEnabled',false);
return page.open(space_url, function (err,status) { return page.open(space_url, function (err,status) {
page.render(export_path, function() { page.render(export_path, function() {
on_success_called = true; on_success_called = true;
if (on_success) { if (on_success) {
on_success(export_path); on_success(export_path);
} }
page.close(); page.close();
browser.exit(); browser.exit();
});
}); });
}); });
} });
}, { }, {
onExit: on_exit onExit: on_exit
}); });

View File

@@ -5,7 +5,7 @@ const websockets = require('./websockets');
module.exports = { module.exports = {
connectRedis(){ connectRedis(){
const redisHost = process.env.REDIS_PORT_6379_TCP_ADDR || 'sync'; const redisHost = process.env.REDIS_PORT_6379_TCP_ADDR || 'localhost';
this.connection = new RedisConnection(6379, redisHost); this.connection = new RedisConnection(6379, redisHost);
}, },
sendMessage(action, model, attributes, channelId) { sendMessage(action, model, attributes, channelId) {

View File

@@ -6,34 +6,11 @@ AWS.config.region = 'eu-central-1';
var fs = require('fs'); var fs = require('fs');
var config = require('config'); var config = require('config');
var cdn = config.get("storage_cdn");
var storage_endpoint = config.get("storage_endpoint");
const bucketName = "sdeck-fresh-development";
const ep = new AWS.Endpoint(storage_endpoint);
AWS.config.update(new AWS.Config({
accessKeyId: process.env.MINIO_ACCESS_KEY,
secretAccessKey: process.env.MINIO_SECRET_KEY,
region: 'us-east-1',
s3ForcePathStyle: true,
signatureVersion: 'v4'
}));
const s3 = new AWS.S3({
endpoint: ep
});
s3.createBucket({
Bucket: config.get("storage_bucket"),
ACL: "public-read",
GrantRead: "*"
}, (err,res) => {
console.log("createBucket",err,res);
});
module.exports = { module.exports = {
removeFile: (path, callback) => { removeFile: (path, callback) => {
const s3 = new AWS.S3({
region: 'eu-central-1'
});
const bucket = config.get("storage_bucket"); const bucket = config.get("storage_bucket");
s3.deleteObject({ s3.deleteObject({
Bucket: bucket, Key: path Bucket: bucket, Key: path
@@ -51,7 +28,7 @@ module.exports = {
callback({error:"missing path"}, null); callback({error:"missing path"}, null);
return; return;
} }
console.log("[storage] uploading", localFilePath, " to ", fileName); console.log("[s3] uploading", localFilePath, " to ", fileName);
const bucket = config.get("storage_bucket"); const bucket = config.get("storage_bucket");
const fileStream = fs.createReadStream(localFilePath); const fileStream = fs.createReadStream(localFilePath);
@@ -62,6 +39,11 @@ module.exports = {
} }
}); });
fileStream.on('open', function () { fileStream.on('open', function () {
// FIXME
var s3 = new AWS.S3({
region: 'eu-central-1'
});
s3.putObject({ s3.putObject({
Bucket: bucket, Bucket: bucket,
Key: fileName, Key: fileName,
@@ -72,7 +54,7 @@ module.exports = {
console.error(err); console.error(err);
callback(err); callback(err);
}else { }else {
const url = cdn + "/" + fileName; const url = "https://"+ config.get("storage_cdn") + "/" + fileName;
console.log("[s3]" + localFilePath + " to " + url); console.log("[s3]" + localFilePath + " to " + url);
callback(null, url); callback(null, url);
} }

View File

@@ -3,7 +3,7 @@ require('../models/schema');
const WebSocketServer = require('ws').Server; const WebSocketServer = require('ws').Server;
const RedisConnection = require('ioredis'); const Redis = require('ioredis');
const async = require('async'); const async = require('async');
const _ = require("underscore"); const _ = require("underscore");
const mongoose = require("mongoose"); const mongoose = require("mongoose");
@@ -12,7 +12,7 @@ const crypto = require('crypto');
module.exports = { module.exports = {
startWebsockets: function(server){ startWebsockets: function(server){
this.setupSubscription(); this.setupSubscription();
this.state = new RedisConnection(6379, process.env.REDIS_PORT_6379_TCP_ADDR || 'sync'); this.state = new Redis(6379, process.env.REDIS_PORT_6379_TCP_ADDR || 'localhost');
if(!this.current_websockets){ if(!this.current_websockets){
this.current_websockets = []; this.current_websockets = [];
@@ -117,7 +117,7 @@ module.exports = {
}, },
setupSubscription: function() { setupSubscription: function() {
this.cursorSubscriber = new RedisConnection(6379, process.env.REDIS_PORT_6379_TCP_ADDR || 'sync'); this.cursorSubscriber = new Redis(6379, process.env.REDIS_PORT_6379_TCP_ADDR || 'localhost');
this.cursorSubscriber.subscribe(['cursors', 'users', 'updates'], function (err, count) { this.cursorSubscriber.subscribe(['cursors', 'users', 'updates'], function (err, count) {
console.log("[redis] websockets to " + count + " topics." ); console.log("[redis] websockets to " + count + " topics." );
}); });

View File

@@ -3,7 +3,7 @@
var mongoose = require('mongoose'); var mongoose = require('mongoose');
var Schema = mongoose.Schema; var Schema = mongoose.Schema;
module.exports.artifactSchema = Schema({ module.exports.artifactSchema = mongoose.model('Artifact', {
mime: String, mime: String,
thumbnail_uri: String, thumbnail_uri: String,
space_id: Schema.Types.ObjectId, space_id: Schema.Types.ObjectId,

View File

@@ -45,7 +45,7 @@ module.exports.teamSchema.index({
module.exports.teamSchema.statics.getTeamForHost = (host, cb) => { module.exports.teamSchema.statics.getTeamForHost = (host, cb) => {
if (host != "127.0.0.1:9666") { //phantomjs check if (host != "127.0.0.1:9000") { //phantomjs check
let subDomainParts = host.split('.'); let subDomainParts = host.split('.');
if (subDomainParts.length > 2) { if (subDomainParts.length > 2) {

View File

@@ -6,15 +6,12 @@
"start": "nodemon -e .js,.html bin/www", "start": "nodemon -e .js,.html bin/www",
"test": "mocha" "test": "mocha"
}, },
"engines" : {
"node" : ">=7.8.0"
},
"dependencies": { "dependencies": {
"archiver": "1.3.0", "archiver": "1.3.0",
"async": "2.3.0", "async": "2.3.0",
"aws-sdk": "2.39.0", "aws-sdk": "2.39.0",
"basic-auth": "1.1.0", "basic-auth": "1.1.0",
"bcryptjs": "2.4.3", "bcrypt": "*",
"body-parser": "~1.17.1", "body-parser": "~1.17.1",
"cheerio": "0.22.0", "cheerio": "0.22.0",
"config": "1.25.1", "config": "1.25.1",
@@ -22,17 +19,17 @@
"csurf": "1.9.0", "csurf": "1.9.0",
"debug": "~2.6.3", "debug": "~2.6.3",
"execSync": "latest", "execSync": "latest",
"express": "~4.13.0", "express": "~4.15.2",
"glob": "7.1.1", "glob": "7.1.1",
"gm": "1.23.0", "gm": "1.23.0",
"googleapis": "18.0.0", "googleapis": "18.0.0",
"gulp": "^3.9.1", "gulp": "^3.9.0",
"gulp-concat": "2.6.0", "gulp-concat": "2.6.1",
"gulp-eslint": "*", "gulp-eslint": "*",
"gulp-express": "0.3.0", "gulp-express": "0.3.5",
"gulp-nodemon": "*", "gulp-nodemon": "*",
"gulp-sass": "^2.0.3", "gulp-sass": "^3.1.0",
"gulp-uglify": "^1.5.1", "gulp-uglify": "^2.1.2",
"gulp-util": "^3.0.6", "gulp-util": "^3.0.6",
"helmet": "^3.5.0", "helmet": "^3.5.0",
"i18n-2": "0.6.3", "i18n-2": "0.6.3",
@@ -62,7 +59,7 @@
}, },
"devDependencies": { "devDependencies": {
"express": "^4.13.3", "express": "^4.13.3",
"gulp": "^3.9.1", "gulp": "^3.9.0",
"gulp-clean": "^0.3.2", "gulp-clean": "^0.3.2",
"gulp-concat": "^2.6.0", "gulp-concat": "^2.6.0",
"gulp-eslint": "^3.0.1", "gulp-eslint": "^3.0.1",
@@ -74,7 +71,8 @@
"gulp-rev-replace": "^0.4.3", "gulp-rev-replace": "^0.4.3",
"gulp-sass": "^3.1.0", "gulp-sass": "^3.1.0",
"gulp-uglify": "^2.1.2", "gulp-uglify": "^2.1.2",
"nodemon": "1.11.0", "mocha": "*",
"nodemon": "*",
"should": "^11.2.1", "should": "^11.2.1",
"supertest": "^3.0.0", "supertest": "^3.0.0",
"winston": "^2.3.1" "winston": "^2.3.1"

View File

@@ -3,7 +3,7 @@
var config = require('config'); var config = require('config');
require('../../models/schema'); require('../../models/schema');
var bcrypt = require('bcryptjs'); var bcrypt = require('bcrypt');
var crypo = require('crypto'); var crypo = require('crypto');
var express = require('express'); var express = require('express');

View File

@@ -9,7 +9,7 @@ var mailer = require('../../helpers/mailer');
var fs = require('fs'); var fs = require('fs');
var _ = require('underscore'); var _ = require('underscore');
var crypto = require('crypto'); var crypto = require('crypto');
var bcrypt = require('bcryptjs'); var bcrypt = require('bcrypt');
var express = require('express'); var express = require('express');
var router = express.Router(); var router = express.Router();

View File

@@ -6,7 +6,7 @@ require('../../models/schema');
var mailer = require('../../helpers/mailer'); var mailer = require('../../helpers/mailer');
var uploader = require('../../helpers/uploader'); var uploader = require('../../helpers/uploader');
var bcrypt = require('bcryptjs'); var bcrypt = require('bcrypt');
var crypo = require('crypto'); var crypo = require('crypto');
var swig = require('swig'); var swig = require('swig');
var async = require('async'); var async = require('async');

View File

@@ -23,10 +23,10 @@
{% if process.env.NODE_ENV != "production" %} {% if process.env.NODE_ENV != "production" %}
var ENV = { var ENV = {
name: 'development', name: 'development',
webHost: "localhost:9666", webHost: "localhost:9000",
webEndpoint:"http://localhost:9666", webEndpoint:"http://localhost:9000",
apiEndpoint: "http://localhost:9666", apiEndpoint: "http://localhost:9000",
websocketsEndpoint: "ws://localhost:9666" websocketsEndpoint: "ws://localhost:9000"
}; };
{% endif %} {% endif %}