This repository has been archived by the owner. It is now read-only.
Permalink
Browse files

Make share page public to whoever has the link.

  • Loading branch information...
Karthik Viswanathan
Karthik Viswanathan committed Jul 19, 2012
1 parent eefcf34 commit d3f1b43b9d0686cba6a8fb5927e97844a8252590
Showing with 121 additions and 9 deletions.
  1. +1 −1 app.js
  2. +27 −2 lib/scaffold.js
  3. +68 −0 lib/users.js
  4. +13 −3 routes/auth.js
  5. +9 −1 routes/index.js
  6. +2 −1 todo.txt
  7. +1 −1 views/templates/layouts/layout.jade
View
2 app.js
@@ -15,6 +15,6 @@ nconf.argv().env().file({ file: 'local.json' });
// routes
require('./routes')(app, nconf, db);
-require('./routes/auth')(app, nconf);
+require('./routes/auth')(app, nconf, db);
app.listen(process.env.PORT || nconf.get('port'));
View
@@ -1,5 +1,6 @@
var crud = require('./crud');
var utils = require('./utils');
+var users = require('./users');
/* Generate a CRUD scaffold for an object
*
@@ -36,7 +37,10 @@ exports.generate = function(parents, children, name, getDefault,
* Returns: database key for objects hash
*/
function getHashKey(req) {
- var key = req.session.email + ':';
+ // sharedEmail is not stored in the client session for security purposes;
+ // users should not be able to see the e-mail of others
+ var key = req.sharedEmail || req.session.email;
+ key = key + ':';
var parentKeys = parents.map(function(parentName) {
var singularName = parentName.substring(0, parentName.length - 1);
@@ -223,7 +227,7 @@ exports.generate = function(parents, children, name, getDefault,
var that = this;
// GET should read
- app.get(baseRoute + '/:id?', function(req, res) {
+ app.get(baseRoute + '/:id?', extractSharedEmail, function(req, res) {
if (!req.params.id) {
// if no id is specified, then return a list of all objects
that.list(req, db, function(err, objectList) {
@@ -291,6 +295,27 @@ exports.generate = function(parents, children, name, getDefault,
}
});
});
+
+ /* Extract a shared screen e-mail for use in REST requests. This acts as
+ * Express route middleware.
+ * Requires: web request, web response, next function to be called when done
+ */
+ function extractSharedEmail(req, res, next) {
+ if (req.session.sharedId) {
+ // get shared e-mail from shared id
+ users.getEmail(db, req.session.sharedId, function(err, email) {
+ // TODO: handle error
+ if (err) {
+ next(err);
+ } else {
+ req.sharedEmail = email;
+ next();
+ }
+ });
+ } else {
+ next();
+ }
+ }
};
return scaffold;
View
@@ -0,0 +1,68 @@
+/*globals exports:true*/
+
+/* Gets user id. If one doesn't exist, adds an id for this user.
+ * Requires: email
+ * Calls: callback(error, id):
+ * error - null if the id was retrieved or an error otherwise
+ * id - if error is null, the id of the user
+ */
+exports.getId = function(db, email, callback) {
+ db.get('user:id:' + email, function(err, id) {
+ if (err) {
+ callback(err);
+ } else if (!id) {
+ addUserId(db, email, callback);
+ } else {
+ callback(null, id);
+ }
+ });
+};
+
+/* Gets user email.
+ * Requires: user id
+ * Calls: callback(error, id):
+ * error - null if the id was retrieved or an error otherwise
+ * id - if error is null, the id of the user
+ */
+exports.getEmail = function(db, id, callback) {
+ db.get('user:email:' + id, function(err, email) {
+ if (err) {
+ callback(err);
+ } else {
+ callback(null, email);
+ }
+ });
+};
+
+/* Adds user id.
+ * Requires: email
+ * Calls: callback(error, id):
+ * error - null if the id was added or an error otherwise
+ * id - if error is null, the id of the user
+ */
+function addUserId(email, callback) {
+ db.incr('user:id:id', function(err, id) {
+ if (err) {
+ callback(err);
+ } else {
+ // redis values must be strings
+ id = String(id);
+
+ // user:id:[userEmail] => [userId]
+ db.set('user:id:' + email, id, function(err, status) {
+ if (err) {
+ callback(err);
+ } else {
+ // user:email:[userId] => [userEmail]
+ db.set('user:email:' + id, email, function(err, status) {
+ if (err) {
+ callback(err);
+ } else {
+ callback(null, id);
+ }
+ });
+ }
+ });
+ }
+ });
+}
View
@@ -1,21 +1,31 @@
var auth = require('../lib/authenticate');
+var users = require('../lib/users');
-module.exports = function(app, nconf) {
+module.exports = function(app, nconf, db) {
// Login
app.post('/login', function(req, res) {
auth.verify(req, nconf, function(error, email) {
if (email) {
req.session.email = email;
+ users.getId(db, email, function(err, id) {
+ // TODO: handle error
+ if (err) {
+ throw err;
+ }
+
+ req.session.id = id;
+ res.redirect('/');
+ });
}
- res.redirect('/');
});
});
// Logout
app.get('/logout', function(req, res) {
if (req.session) {
delete req.session.email;
+ delete req.session.id;
}
- res.redirect('/?logged_out=1', 303);
+ res.redirect('/', 303);
});
};
View
@@ -2,10 +2,12 @@ var projects = require('../lib/projects');
var screens = require('../lib/screens');
var components = require('../lib/components');
var elements = require('../lib/elements');
+var users = require('../lib/users');
module.exports = function(app, nconf, db) {
app.get('/', function (req, res) {
if (req.session.email) {
+ delete req.session.sharedId;
res.render('index', {
pageId: 'index'
});
@@ -22,7 +24,11 @@ module.exports = function(app, nconf, db) {
var projectId = req.params.projectId;
var screenId = req.params.screenId;
+ // delete sharedId becuase this user is no longer viewing a shared screen
+ delete req.session.sharedId;
+
screens.list(req, db, function(err, screenList) {
+ // TODO: handle error
if (err) {
throw err;
}
@@ -42,10 +48,12 @@ module.exports = function(app, nconf, db) {
});
});
- app.get('/share/project/:projectId/screen/:screenId',
+ app.get('/share/:userId/project/:projectId/screen/:screenId',
function(req, res) {
var projectId = req.params.projectId;
var screenId = req.params.screenId;
+ req.session.sharedId = req.params.userId;
+
res.render('prototype', {
pageId: 'share',
projectId: projectId,
View
@@ -5,13 +5,13 @@
| / Task completed |
======================
-- Permissions for share page
- Permissions for editing project + screen
- Ensure project and screen exist to prototype screen page
- Validate action is an actual screen ID
- Add validation for projectId and screenId paramters in route // 404 page for invalid?
- Should auth be implemented for screen sharing page?
- Improve sharing page sidebar
+- Add links on sharing page for visibility and return to prototype
- Add screen flag for being logged in to view it
- For all forms on the page, make sure their field ids are by default in the usedIds hash
@@ -27,3 +27,4 @@
/ Add form action
/ Link Napkin logo to home page
/ Create element function (prototype.js:~120)
+/ Permissions for share page
@@ -2,7 +2,7 @@ script#layout-template(type='text/template')
if !sharing
#prototype-header
h2 ‘#{screenHash[screenId].title}’ Screen Prototype
- a(href='/share/project/#{projectId}/screen/#{screenId}')
+ a(href='/share/#{session.id}/project/#{projectId}/screen/#{screenId}')
i.icon-globe
| Share Screen

0 comments on commit d3f1b43

Please sign in to comment.