diff options
| -rw-r--r-- | bucky/app/bucky.js | 69 | ||||
| -rw-r--r-- | bucky/app/router.js | 37 | ||||
| -rw-r--r-- | bucky/db/index.js | 10 | ||||
| -rw-r--r-- | public/assets/css/bucky.css | 10 | ||||
| -rw-r--r-- | public/assets/js/lib/router.js | 3 | ||||
| -rw-r--r-- | public/assets/js/lib/views/mail/compose.js | 2 | ||||
| -rw-r--r-- | public/assets/js/lib/views/mail/message.js | 7 | ||||
| -rw-r--r-- | views/pages/message.ejs | 9 |
8 files changed, 115 insertions, 32 deletions
diff --git a/bucky/app/bucky.js b/bucky/app/bucky.js index a31d50f..5fb58bf 100644 --- a/bucky/app/bucky.js +++ b/bucky/app/bucky.js @@ -400,6 +400,7 @@ var bucky = module.exports = { }, /* PRIVACY */ + checkThreadPrivacy: function(req, res, next) { if (req.user.get('ulevel') !== 3 && req.user.get('username') !== res.thread.get('username')) { return res.sendStatus(500) @@ -412,6 +413,13 @@ var bucky = module.exports = { } next() }, + checkMessagePrivacy: function(req, res, next) { + var username = req.user.get('username') + if (username !== res.message.get('sender') && username !== res.message.get('recipient')) { + return res.sendStatus(500) + } + next() + }, /* MAIL */ @@ -454,6 +462,9 @@ var bucky = module.exports = { }, ensureMessage: function(req, res, next){ db.getMessage(req.params.id).then(function(message){ + if (! message) { + return res.sendStatus(404) + } var username = req.user.get('username') if (username !== message.get('recipient') && username !== message.get('sender')) { res.sendStatus(404) @@ -462,5 +473,61 @@ var bucky = module.exports = { res.message = message next() }) - } + }, + markMessageUnread: function(req, res, next){ + if (res.message.get('unread')) { + res.message.set('unread', false) + res.message.save().then(() => next()) + } else { + next() + } + }, + ensureRecipient: function(req, res, next){ + db.getUserByUsername(util.sanitizeName(req.body.username)).then( (user) => { + if (! user) { + res.send({ error: "No such recipient" }) + return + } + next() + }) + }, + sendMessage: function(req, res, next){ + var recipient = util.sanitizeName(req.body.username) + var sender = req.user.get('username') + var subject = util.sanitize(req.body.subject) + var body = util.sanitize(req.body.body) + res.mail = { sender: sender, recipient: recipient } + var recipientMessage = { + mbox: recipient + ".inbox", + unread: true, + sender: sender, + recipient: recipient, + date: util.now(), + subject: subject, + body: body, + } + var senderMessage = { + mbox: sender + ".outbox", + unread: false, + sender: sender, + recipient: recipient, + date: util.now(), + subject: subject, + body: body, + } + Promise.all([ + db.createMessage(recipientMessage), + db.createMessage(senderMessage), + ]).then( () => next() ) + }, + deleteDraft: function(req, res, next){ + if (! req.body.draft_id) return next() + db.getMessage(req.body.draft_id).then( (message) => { + if (message.get('sender') === req.user.get('username')) { + return message.destroy().then( () => next() ) + } + // erroneous draft message?? + next() + }) + }, }
\ No newline at end of file diff --git a/bucky/app/router.js b/bucky/app/router.js index 4c94c19..8eb90e0 100644 --- a/bucky/app/router.js +++ b/bucky/app/router.js @@ -196,8 +196,7 @@ module.exports = function(app){ middleware.ensureAuthenticated, function(req, res){ res.render("pages/search", {title: "search" }) - } - ) + }) app.get("/api/search", middleware.ensureAuthenticated, search.search, @@ -215,8 +214,7 @@ module.exports = function(app){ res.json({ keywords: res.keywords, }) - } - ) + }) app.get("/api/keyword/:keyword", middleware.ensureAuthenticated, bucky.ensureKeyword, @@ -229,15 +227,13 @@ module.exports = function(app){ keyword: res.keyword, threads: res.threads, }) - } - ) + }) app.get("/mail/", middleware.ensureAuthenticated, function(req, res){ res.render("pages/mailbox", {title: "your inbox" }) - } - ) + }) app.get("/mail/compose", middleware.ensureAuthenticated, function(req, res){ @@ -245,14 +241,12 @@ module.exports = function(app){ title: "new message", subject: fortune("subjects"), }) - } - ) + }) app.get("/mail/:box", middleware.ensureAuthenticated, function(req, res){ res.render("pages/mailbox", { title: "your " + util.sanitize(req.params.box) }) - } - ) + }) app.get("/mail/compose/:username", middleware.ensureAuthenticated, function(req, res){ @@ -260,14 +254,12 @@ module.exports = function(app){ title: "new message", subject: fortune("subjects"), }) - } - ) + }) app.get("/mail/read/:id", middleware.ensureAuthenticated, function(req, res){ res.render("pages/message", { title: "read message" }) - } - ) + }) app.get("/api/mailbox/:box", middleware.ensureAuthenticated, bucky.ensureMailboxes, @@ -279,20 +271,23 @@ module.exports = function(app){ messages: res.messages, boxes: res.boxes, }) - } - ) + }) app.get("/api/message/:id", middleware.ensureAuthenticated, bucky.ensureMessage, + bucky.markMessageUnread, function(req, res){ res.json({ message: res.message, }) - }) - app.post("/mail/", + }) + app.post("/api/mail/send", middleware.ensureAuthenticated, + bucky.ensureRecipient, + bucky.sendMessage, + bucky.deleteDraft, function(req, res){ - // send new mail + res.sendStatus(200) } ) diff --git a/bucky/db/index.js b/bucky/db/index.js index c2cf947..8715125 100644 --- a/bucky/db/index.js +++ b/bucky/db/index.js @@ -51,8 +51,7 @@ db.getUser = function(id) { return model.fetch() } db.getUserByUsername = function(username) { - var model = new User({'username': username}) - return model.fetch() + return new User({'username': username}).fetch() } db.getLastlog = function(limit){ return knex.column('username').column('lastseen').select().from('users').orderBy('lastseen', 'desc').limit(limit || 10) @@ -188,12 +187,18 @@ db.destroyKeyword = function(id){ db.getMailboxes = function(username){ return Mailbox.query("where", "owner", "=", username).fetchAll() } +db.getMailbox = function(mbox){ + return new Mailbox({mbox: mbox}).fetch() +} db.getMailboxCounts = function(boxes){ return knex.column('mbox').count('* as count').select().from('messages').where('mbox', 'in', boxes).groupBy('mbox') } db.createMailbox = function(data){ return new db.Mailbox(data).save() } +db.bumpMailboxCount = function(mbox){ + new db.Mailbox({ mbox: mbox }).fetch() +} /* MESSAGES */ @@ -212,6 +217,7 @@ db.getMessages = function(username, box, limit, offset){ db.getMessage = function (id){ var model = new Message({'id': id}) return model.fetch().then(function(message){ + if (! message) return null message.set("body", message.get("body").toString() ) return message }) diff --git a/public/assets/css/bucky.css b/public/assets/css/bucky.css index cab7caa..d203c97 100644 --- a/public/assets/css/bucky.css +++ b/public/assets/css/bucky.css @@ -228,7 +228,6 @@ table, tr { padding-right: 4px; } .ledger .row td:nth-child(1) a { - margin-left: 10px; color: #444; text-decoration: none; } @@ -467,6 +466,7 @@ pre br { min-width: 50px; } #compose textarea { + margin-top: 5px; margin-left: 50px; } #compose input[name=subject] { @@ -794,11 +794,14 @@ pre br { #message { text-align: left; max-width: 500px; - margin: 0 auto; + margin-top: 10px; } #message .av { float: left; - margin-right: 10px; + margin: 4px 8px 4px 4px; + width: 40px; + height: 40px; + background: #fff; } #message span { display: inline-block; @@ -808,6 +811,7 @@ pre br { #message .subject { font-weight: bold; font-size: 15px; + display: block; } #message hr { clear: both; diff --git a/public/assets/js/lib/router.js b/public/assets/js/lib/router.js index 1419e81..388bdac 100644 --- a/public/assets/js/lib/router.js +++ b/public/assets/js/lib/router.js @@ -17,7 +17,8 @@ var SiteRouter = Router.extend({ "/mail/:mailbox": 'mailbox', "/mail/compose": 'compose', "/mail/compose/:username": 'compose', - "/message/:id": 'message', + "/mail/read/:id": 'message', + "/mail/reply/:id": 'compose', "/comment/:id/edit": 'editComment', "/profile": 'profile', "/profile/:username": 'profile', diff --git a/public/assets/js/lib/views/mail/compose.js b/public/assets/js/lib/views/mail/compose.js index 2c76b3f..b3e302e 100644 --- a/public/assets/js/lib/views/mail/compose.js +++ b/public/assets/js/lib/views/mail/compose.js @@ -5,7 +5,7 @@ var ComposeView = FormView.extend({ events: { }, - action: "", + action: "/api/mail/send", initialize: function(){ this.__super__.initialize.call(this) diff --git a/public/assets/js/lib/views/mail/message.js b/public/assets/js/lib/views/mail/message.js index da5e1b4..19293e5 100644 --- a/public/assets/js/lib/views/mail/message.js +++ b/public/assets/js/lib/views/mail/message.js @@ -10,7 +10,12 @@ var MessageView = View.extend({ load: function(name){ name = sanitize(name) || "inbox" - $.get(this.action + name, this.populate.bind(this)) + $.ajax({ + url: this.action + name, + method: 'get', + success: this.populate.bind(this), + error: app.router.error404 + }) }, populate: function(data){ diff --git a/views/pages/message.ejs b/views/pages/message.ejs index 0d1233d..1d76fdc 100644 --- a/views/pages/message.ejs +++ b/views/pages/message.ejs @@ -1,15 +1,20 @@ <% include ../partials/header %> +<div class="subtitle"> + <a href='/'>< Home</a> · + <a href='/mail/'>Inbox</a> +</div> <div class="bluebox" id="message"> <script class="template" type="text/html"> - <a href="/profile/{{sender}}" class="av"><img src="/data/profile/.thumb/al.{{sender}}.jpg"></a> + <a href="/profile/{{sender}}" class="av"><img src="/data/profile/{{sender}}.jpg"></a> <span class="subject">{{subject}}</span> <span class="sender"> sent by <a href="/profile/{{sender}}">{{sender}}</a> on {{date}} {{time}} + · + <a href="/mail/reply/{{id}}">reply</a> </span> - <hr> <div class="body"> {{body}} </div> |
