summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bucky/app/api.js18
-rw-r--r--bucky/app/bucky.js30
-rw-r--r--bucky/db/index.js3
-rw-r--r--public/assets/js/lib/views/details/commentform.js3
-rw-r--r--public/assets/js/lib/views/details/settings.js33
-rw-r--r--views/partials/settings.ejs2
6 files changed, 81 insertions, 8 deletions
diff --git a/bucky/app/api.js b/bucky/app/api.js
index 5635ce9..ff17626 100644
--- a/bucky/app/api.js
+++ b/bucky/app/api.js
@@ -121,15 +121,16 @@ function route (app){
bucky.ensureFilesForThread,
bucky.destroyThread,
function(req, res){
- res.sendStatus(200)
+ res.send({ status: 'ok' })
})
/* comments */
-
+
+ // one endpoint handles comments + files
app.post("/api/thread/:id/comment",
middleware.ensureAuthenticated,
bucky.ensureThread,
- // ensure thread privacy
+ bucky.checkThreadPrivacy,
multer.array("files"),
bucky.verifyFilesOrComment,
bucky.createOptionalFiles,
@@ -164,7 +165,16 @@ function route (app){
bucky.checkCommentPrivacy,
bucky.destroyComment,
function(req, res){
- res.sendStatus(200)
+ res.send({ status: 'ok' })
+ })
+ // delete a file
+ app.delete("/api/file/:id",
+ middleware.ensureAuthenticated,
+ bucky.ensureFile,
+ bucky.checkFilePrivacy,
+ bucky.destroyFile,
+ function(req, res){
+ res.send({ status: 'ok' })
})
/* search */
diff --git a/bucky/app/bucky.js b/bucky/app/bucky.js
index 295a813..dbb980d 100644
--- a/bucky/app/bucky.js
+++ b/bucky/app/bucky.js
@@ -371,7 +371,23 @@ var bucky = module.exports = {
},
/* FILES */
-
+
+ ensureFile: function (req, res, next){
+ var id = req.params.id.replace(/\D/g, "")
+ if (! id) {
+ return res.sendStatus(404)
+ }
+ db.getFileById(id).then(function(file){
+ console.log(file)
+ if (file) {
+ res.file = file
+ next()
+ }
+ else {
+ res.sendStatus(404)
+ }
+ })
+ },
createOptionalFiles: function(req, res, next){
if (! req.files || ! req.files.length) {
return next()
@@ -418,6 +434,11 @@ var bucky = module.exports = {
console.log(err)
})
},
+ destroyFile: function(req,res,next){
+ var filePromises = db.destroyFiles([res.file])
+ Promise.all(filePromises).then( () => next() )
+ .catch(err => { console.error(err); next() })
+ },
/* PROFILE / USER */
@@ -499,6 +520,13 @@ var bucky = module.exports = {
}
next()
},
+ checkFilePrivacy: function(req, res, next) {
+ console.log(res.file)
+ if (req.user.get('ulevel') !== 3 && req.user.get('username') !== res.file.get('username')) {
+ return res.sendStatus(500)
+ }
+ next()
+ },
checkMessagePrivacy: function(req, res, next) {
var username = req.user.get('username')
if (username !== res.message.get('sender') && username !== res.message.get('recipient')) {
diff --git a/bucky/db/index.js b/bucky/db/index.js
index 20628bb..e26124a 100644
--- a/bucky/db/index.js
+++ b/bucky/db/index.js
@@ -132,6 +132,9 @@ db.getUserThreadIds = function(user_id){
/* FILES */
+db.getFileById = function(id){
+ return (new File({'id': id})).fetch()
+}
db.getFilesForThread = function (id){
return File.query("where", "thread", "=", id).fetchAll()
}
diff --git a/public/assets/js/lib/views/details/commentform.js b/public/assets/js/lib/views/details/commentform.js
index e30193d..a14caa3 100644
--- a/public/assets/js/lib/views/details/commentform.js
+++ b/public/assets/js/lib/views/details/commentform.js
@@ -4,7 +4,7 @@ var CommentForm = FormView.extend({
events: {
"focus textarea": 'focus',
- "focus input[type=file]": 'focus',
+ "mouseup input[type=file]": 'focus',
},
action: "",
@@ -24,6 +24,7 @@ var CommentForm = FormView.extend({
focus: function(){
this.$el.addClass('focused')
+ $("[name=comment]").prop("required", false)
},
validate: function(){
diff --git a/public/assets/js/lib/views/details/settings.js b/public/assets/js/lib/views/details/settings.js
index eac1520..1d048ab 100644
--- a/public/assets/js/lib/views/details/settings.js
+++ b/public/assets/js/lib/views/details/settings.js
@@ -6,6 +6,7 @@ var ThreadSettingsForm = FormView.extend({
"click": "hide",
"click .inner": "stopPropagation",
"click .thread_delete": "deleteThread",
+ "click .file_delete": "deleteFile",
"click .close_link": "hide",
"change [name=color]": "changeColor",
"change [name=privacy]": "toggleAllowed",
@@ -35,6 +36,7 @@ var ThreadSettingsForm = FormView.extend({
var display = thread.display
this.thread = thread
+ this.files = data.files
this.action = "/api/thread/" + thread.id
this.allowed = (this.thread.allowed || "").split(" ").map(s => s.trim()).filter(s => !! s)
@@ -67,7 +69,6 @@ var ThreadSettingsForm = FormView.extend({
var datetime = verbose_date(file.date, true)
var date_class = carbon_date(file.date)
var link = make_link(file)
-
var t = this.filesTemplate.replace(/{{username}}/g, file.username)
.replace(/{{link}}/g, link)
.replace(/{{filename}}/g, file.filename)
@@ -233,4 +234,34 @@ var ThreadSettingsForm = FormView.extend({
}
},
+ deleteFile: function(e){
+ e.preventDefault()
+ e.stopPropagation()
+ var $el = $(e.currentTarget)
+ var $parent = $el.closest('.file')
+ var file_id = $el.data('id')
+ if (! file_id) return
+ var data = this.options.parent.data
+ var file = data.files.find(f => f.id === file_id)
+ if (! file) return
+ var msg = "Are you sure you want to delete this file?\n\n#" + file_id + ' "' + sanitize(file.filename) + '"'
+ var should_remove = confirm(msg)
+ if (should_remove) {
+ $.ajax({
+ method: "DELETE",
+ url: "/api/file/" + file_id,
+ headers: { "csrf-token": $("[name=_csrf]").attr("value") },
+ data: JSON.stringify({ csrf: csrf() }),
+ dataType: "application/json",
+ success: function(data){
+ console.log(data)
+ $parent.remove()
+ },
+ error: function(data){
+ $parent.remove()
+ },
+ })
+ }
+ },
+
}) \ No newline at end of file
diff --git a/views/partials/settings.ejs b/views/partials/settings.ejs
index d74d557..27ddfa8 100644
--- a/views/partials/settings.ejs
+++ b/views/partials/settings.ejs
@@ -93,7 +93,7 @@
<a href="/profile/{{username}}">{{username}}</a>
</td>
<td>
- <a href="#" class="delete" id={{id}}>delete</a>
+ <a href="#" class="file_delete" data-id={{id}}>delete</a>
</td>
</tr>
</script>