Skip to content

Commit

Permalink
invites & fixed files watching
Browse files Browse the repository at this point in the history
  • Loading branch information
Jes committed May 31, 2018
1 parent 0943b2f commit ef8c6ad
Show file tree
Hide file tree
Showing 11 changed files with 91 additions and 25 deletions.
4 changes: 3 additions & 1 deletion .npmignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
upload
sessions
projects.json
projects.json
github-release
build
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,7 @@ jesed config
sudo ./apache
```
open in your browser http://your-domain/jesed/ link

#### Troubleshooting
* for `ENOSPC` error - extend max watches amount
`echo fs.inotify.max_user_watches=524288 | sudo tee -a /etc/sysctl.conf && sudo sysctl -p`
25 changes: 23 additions & 2 deletions app/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,28 @@ app.set('view engine', 'ejs');
app.engine('.html', require('ejs').renderFile);

app.use(require('body-parser').urlencoded({ extended: false }));

const invites = {};
const tokens = {};
const checkAccess = (p, u) => p && u && p.editors && (p.editors.indexOf(u) >= 0 || p.editors.indexOf("*") >= 0);
const checkAccess = (p, u, l) => p && u && (invites[u] && invites[u].project == p.id || p.editors && p.editors.indexOf(u) >= 0 || p.editors.indexOf("*") >= 0);
const isInvited = (req) => {
var yes = req.user;
if ('invite' in req.query) {
yes = invites[req.query.invite];
if (yes)
req.login({id: req.query.invite, name: yes.name}, function(){})
else
req.logout();
}
return req.isAuthenticated();
}

const auth = p => (req, res, next) => {
req.project = p;
req.createInvite = function(name) {
const id = md5(req.sessionID + new Date().getTime());
invites[id] = {name: name, project: p.id};
return id;
}
req.session.tokens || (req.session.tokens = {});
if (req.isAuthenticated() && checkAccess(p, req.user.id)) {
tokens[p.id][req.sessionID] || (req.session.tokens[p.id] = tokens[p.id][req.sessionID] = {user: req.user.id, token: md5(req.sessionID + new Date().getTime())});
Expand Down Expand Up @@ -59,6 +76,7 @@ passport.serializeUser(function(user, done) {
done(null, user.id);
});
passport.deserializeUser(function(id, done) {
const name = invites[id] && invites[id].name || id;
done(null, {id: id, name: id });
});

Expand All @@ -85,6 +103,8 @@ app.use(passport.initialize());
app.use(passport.session());
const modAuth = (req, res, next) => {
const url = req.url;
if (isInvited(req))
return next();
const auth = passport.authenticate('digest', { session: true });
req.url = (config.baseURI || '') + req.url;
auth(req, res, () => {
Expand All @@ -98,6 +118,7 @@ app.use('/nm', express.static(path.join(__dirname, '..', 'node_modules')));
config.projects.map(exports.addProject)
app.get('/', function(req, res) {
if ('logout' in req.query) {
req.logout();
return res.status(401).send('<meta http-equiv="refresh" content="0; url=/">');
}
if (req.isAuthenticated()) {
Expand Down
12 changes: 12 additions & 0 deletions app/services/auth.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
const path = require('path');
const fs = require('fs');

const router = module.exports = require('express').Router();

const promisify = require('../helpers').promisify;

const safePath = val => decodeURI(val).replace(/|\.\.|\/\//g, '');
const getRoot = req => Promise.resolve(req.project.path);
const send = (p, res) => p.then(data => res.send(data)).catch(e => res.status(501).send(e.message));

router.get('/', (req, res) => send(Promise.resolve(req.createInvite('Anonymous')), res))
1 change: 1 addition & 0 deletions app/services/index.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
const router = module.exports = require('express').Router();

router.use('/s/editor', require('./editor'));
router.use('/s/auth', require('./auth'));
23 changes: 17 additions & 6 deletions app/services/ot.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,19 +14,29 @@ const getFile = (root, file) => promisify(fs.readFile)(path.join(root, file));
const setFile = (root, file, data) => promisify(fs.writeFile)(path.join(root, file), data);

module.exports = (server, project, tokens) => {
ns[project.ws] = {};
const pp = ns[project.ws] = {docs: {}, users: {}};
const io = new sio(server, {path: project.ws});
io.on('connection', connection)
function connection(socket) {
const sh = socket.handshake.headers
const user = pp.users[socket.id] = {ip: sh['x-forwarded-for'], auth: sh.authorization && sh.authorization.split(',')[0].split('=')[1].slice(1, -1)};
socket.on('ns', function (docId, token, name) {
if (Object.keys(tokens).map(i => tokens[i].token).indexOf(token) < 0) return;
var t = Object.keys(tokens).map(i => tokens[i]).filter(i => i.token == token)
if (!t.length) return;
user.auth || (user.auth = t[0].user);
socket.broadcast.emit('users', pp.users);
getDoc(io, project, docId, name)
.then(ob => socket.emit('ns', docId, ob.type))
.then(ob => socket.emit('ns', docId, ob.type),socket.emit('users', pp.users))
.catch(e => console.error(e))
});
socket.on('disconnect', function() {
delete pp.users[socket.id];
socket.broadcast.emit('users', pp.users);
})
}
chokidar.watch(project.path + '**', {
ignored: project.excludes || /node_modules/,
var host = chokidar.watch('**', {
cwd: path.resolve(project.path),
ignored: ['node_modules', '.git'].concat(project.excludes),
persistent: true,
})
.on('change', file => {
Expand All @@ -41,6 +51,7 @@ module.exports = (server, project, tokens) => {
)
})
return function() {
host.close();
io.removeListener('connection', connection);
io.path("recycled" + new Date().getTime());
delete io;
Expand All @@ -53,7 +64,7 @@ function canEdit(mime) {
}

function getDoc(io, project, docId, name) {
const pp = ns[project.ws];
const pp = ns[project.ws].docs;
if (pp[docId])
return Promise.resolve(pp[docId])
else {
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "jesed",
"version": "0.1.7",
"version": "0.1.8",
"description": "online instant collaborative editor",
"main": "./jesed",
"scripts": {
Expand Down Expand Up @@ -80,6 +80,7 @@
"body-parser": "^1.18.3",
"bootstrap": "^4.1.1",
"chokidar": "^2.0.3",
"clipboard": "^2.0.1",
"diff-match-patch": "^1.0.1",
"ejs": "^2.6.1",
"express": "^4.16.3",
Expand Down
13 changes: 13 additions & 0 deletions static/editor/editor.js
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,19 @@ var state;
editor.setReadOnly(true);
state.text(text)
});
otI.socket.on('users', function(users) {
var u = $('.jesed-users .dropdown-menu').empty();
var len = Object.keys(users).map(function(i) {
u.append('<a class="dropdown-item" href="#"> ' + users[i].auth + ' (' + users[i].ip +')</a>')
})
u.parent().find('button span').text(len.length);
});
$('.jesed-invite').on('click', function(){
$.get('s/auth')
.then(function(invite) {
prompt('invite url', location.origin + location.pathname + '?invite=' + invite);
})
})
0 && config.then(function(data){
otI.setName(data.name);
})
Expand Down
2 changes: 1 addition & 1 deletion static/editor/helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,4 @@ function toggleFullScreen() {
}
function isElectron() {
return navigator.userAgent.toLowerCase().indexOf(' electron/') >= 0;
}
}
11 changes: 11 additions & 0 deletions static/editor/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,11 @@
<link href="../nm/@fortawesome/fontawesome-free-webfonts/css/fontawesome.css" rel="stylesheet">
<link href="../nm/@fortawesome/fontawesome-free-webfonts/css/fa-solid.css" rel="stylesheet">
<!--<script src="/nm/tether/dist/js/tether.min.js"></script>-->
<script src="../nm/popper.js/dist/umd/popper.min.js"></script>
<script src="../nm/bootstrap/dist/js/bootstrap.min.js"></script>
<script src="../nm/socket.io-client/dist/socket.io.js"></script>
<script src="../nm/ot-jes/dist/ot.js"></script>
<script src="../nm/clipboard/dist/clipboard.js"></script>
<link href="../nm/vex-js/dist/css/vex.css" rel="stylesheet">
<link href="../nm/vex-js/dist/css/vex-theme-os.css" rel="stylesheet">
<script src="../nm/vex-js/dist/js/vex.combined.js"></script>
Expand All @@ -39,6 +41,15 @@
<div>
<button class="btn btn-sm m-1" onclick="$('.tree').toggle()" style="float: left;" title="toggle filebrowser window"><i class="fas fa-chevron-left"></i></button>
<button class="btn btn-sm m-1" onclick="toggleFullScreen()" style="float: left;" title="fullscreen"><i class="fas fa-arrows-alt"></i></button>
<button class="btn btn-sm m-1 jesed-invite" style="float: left;" title="create and copy to clipboard new invite"><i class="fas fa-user-plus"></i></button>
<div class="btn-group m-1 jesed-users" style="float: left;" >
<button class="btn btn-sm dropdown-toggle" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<i class="fas fa-users"></i> <span>0</span>
</button>
<div class="dropdown-menu">
<div class="dropdown-divider"></div>
</div>
</div>
<button type="button" class="btn btn-warning btn-sm m-1" style="float: left;display:none;" title="share workflow to friends">QR</button>
<ul class="nav nav-tabs nav-scroll" id="myTab" role="tablist" style="margin-left: 75px;">
<li class="nav-item">
Expand Down
18 changes: 4 additions & 14 deletions upload
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,11 @@ fi

TAG=v`./node_modules/.bin/json -f package.json -c 'console.log(this.version)'`
GH_TOKEN=`./node_modules/.bin/json -f ~/.github.json -c 'console.log(this.OAuth)'`
CRED="-s $GH_TOKEN --user akaJes --repo jesed --tag $TAG"

./github-release release \
-s $GH_TOKEN \
--user akaJes \
--repo jesed \
--tag $TAG \
--name "jesed"
./github-release release $CRED --name "jesed"

for file in `ls build`; do
echo "publicate file $file"
./github-release upload \
-s $GH_TOKEN \
--user akaJes \
--repo jesed \
--tag $TAG \
--name $file \
--file build/$file
echo "publicate file $file"
./github-release upload $CRED --name $file --file build/$file
done

0 comments on commit ef8c6ad

Please sign in to comment.