From 069c75b72e9f889ef377d675cdbf190f99af6df6 Mon Sep 17 00:00:00 2001 From: Robin Malley Date: Mon, 11 Oct 2021 00:59:50 +0000 Subject: [PATCH] Add a delete button. Add a delete button to posts that will show up if the user is logged in and is the owner of a post. If javascript is enabled, the user will be prompted for conformation before deleting a post. --- assets/intervine_deletion.js | 36 +++++++++++++++++ conf/smr.conf.in | 5 +++ src/lua/endpoints/delete_post.lua | 64 +++++++++++++++++++++++++++++++ src/lua/endpoints/read_get.lua | 3 +- src/lua/init.lua | 5 +++ src/pages/read.etlua.in | 8 +++- src/smr.c | 36 +++++++++-------- src/sql/delete_post.sql | 3 ++ 8 files changed, 143 insertions(+), 17 deletions(-) create mode 100644 assets/intervine_deletion.js create mode 100644 src/lua/endpoints/delete_post.lua create mode 100644 src/sql/delete_post.sql diff --git a/assets/intervine_deletion.js b/assets/intervine_deletion.js new file mode 100644 index 0000000..a0a9dfb --- /dev/null +++ b/assets/intervine_deletion.js @@ -0,0 +1,36 @@ +/* +There's a delete buttotn to delete a post. If javascript is enabled, replace +the button with one that will ask for confirmation before deleting. +*/ + +function delete_intervine(){ + var forms = document.getElementsByTagName("form"); + if(forms.length == 0){return;}//Don't load if the story is missing. + var delete_form; + for(var i = 0; i < forms.length; i++){ + if(forms[i].action.endsWith("_delete")){ + delete_form = forms[i]; + break; + } + } + if(delete_form == null){return;}//Don't load if we're not logged in + var delete_parent = delete_form.parentNode; + delete_parent.removeChild(delete_form); + var delete_wrapper = document.createElement("div"); + var delete_button = document.createElement("button"); + delete_button.classList.add("button"); + delete_button.classList.add("column"); + delete_button.classList.add("column-0"); + delete_button.textContent = "Delete"; + delete_button.addEventListener("click",function(){ + if(confirm("Are you sure you want to delete this story?")){ + document.documentElement.appendChild(delete_form); + delete_form.submit(); + } + }); + delete_parent.appendChild(delete_wrapper); + delete_wrapper.appendChild(delete_button); + +} + +document.addEventListener("DOMContentLoaded",delete_intervine,false); diff --git a/conf/smr.conf.in b/conf/smr.conf.in index 9de3ed0..5d44c41 100644 --- a/conf/smr.conf.in +++ b/conf/smr.conf.in @@ -46,6 +46,7 @@ domain * { route /_faq asset_serve_faq_html route /_js/suggest_tags.js asset_serve_suggest_tags_js route /_js/bookmark.js asset_serve_bookmark_js + route /_js/intervine_deletion.js asset_serve_intervine_deletion_js route /favicon.ico asset_serve_favicon_ico route /_paste post_story route /_edit edit_story @@ -58,6 +59,7 @@ domain * { route /_search search route /_archive archive route /_api api + route /_delete delete # Leading ^ is needed for dynamic routes, kore says the route is dynamic if it does not start with '/' route ^/[^_].* read_story @@ -119,4 +121,7 @@ domain * { validate call v_any validate data v_any } + params post /_delete { + validate story v_storyid + } } diff --git a/src/lua/endpoints/delete_post.lua b/src/lua/endpoints/delete_post.lua new file mode 100644 index 0000000..f548b18 --- /dev/null +++ b/src/lua/endpoints/delete_post.lua @@ -0,0 +1,64 @@ +local tags = require("tags") +local util = require("util") +local pages = require("pages") +local config = require("config") +local session = require("session") +local db = require("db") +local queries = require("queries") +local sql = require("lsqlite3") +local cache = require("cache") + +local oldconfigure = configure +local stmnt_delete +function configure(...) + stmnt_delete = assert(db.conn:prepare(queries.delete_post),db.conn:errmsg()) + return oldconfigure(...) +end + +local function delete_post(req) + local host = http_request_get_host(req) + local path = http_request_get_path(req) + http_request_populate_post(req) + local storystr = assert(http_argument_get_string(req,"story")) + print("Looking at storystr:",storystr) + local storyid = util.decode_id(storystr) + local author, authorid = session.get(req) + if not author then + http_response(req, 401, pages.error{ + errcode = 401, + errcodemsg = "Not authorized", + explanation = "You must be logged in to delete posts. You are either not logged in or your session has expired.", + should_traceback = true + }) + return + end + log(LOG_DEBUG,string.format("Deleting post %d with proposed owner %d",storyid, authorid)) + stmnt_delete:bind_names{ + postid = storyid, + authorid = authorid + } + local err = util.do_sql(stmnt_delete) + if err ~= sql.DONE then + log(LOG_DEBUG,string.format("Failed to delete: %d:%s",err, db.conn:errmsg())) + http_response(req,500,pages.error{ + errcode = 500, + errcodemsg = "Internal error", + explanation = "Failed to delete posts from database:" .. db.conn:errmsg(), + should_traceback = true, + }) + stmnt_delete:reset() + else + local loc = string.format("https://%s/%s",config.domain,storystr) + http_response_header(req,"Location",loc) + http_response(req,303,"") + stmnt_delete:reset() + cache.dirty(string.format("%s",config.domain)) + cache.dirty(string.format("%s-logout",config.domain)) + cache.dirty(string.format("%s.%s",author,config.domain)) + cache.dirty(string.format("%s",storystr)) + cache.dirty(string.format("%s?comments=1",storystr)) + + end +end + +return delete_post diff --git a/src/lua/endpoints/read_get.lua b/src/lua/endpoints/read_get.lua index 877fe08..67ac4a7 100644 --- a/src/lua/endpoints/read_get.lua +++ b/src/lua/endpoints/read_get.lua @@ -99,7 +99,8 @@ local function read_get(req) path = http_request_get_path(req), method = http_method_text(req), extra_load = { - '' + '', + '', } } local err diff --git a/src/lua/init.lua b/src/lua/init.lua index 61aac35..d671694 100644 --- a/src/lua/init.lua +++ b/src/lua/init.lua @@ -35,6 +35,7 @@ local endpoint_names = { search = {"get"}, archive = {"get"}, api = {"get"}, + delete = {"post"}, } local endpoints = {} for name, methods in pairs(endpoint_names) do @@ -119,6 +120,10 @@ function edit(req) end end +function delete(req) + endpoints.delete_post(req) +end + --TODO function edit_bio() error("Not yet implemented") diff --git a/src/pages/read.etlua.in b/src/pages/read.etlua.in index 94e692b..4bed22a 100644 --- a/src/pages/read.etlua.in +++ b/src/pages/read.etlua.in @@ -3,10 +3,16 @@ <%= domain %>/<%= idp %> <% if owner then -%> +
- +
+
+ + +
+
<% end -%>

<%- title %>

diff --git a/src/smr.c b/src/smr.c index 69c1d13..1177521 100644 --- a/src/smr.c +++ b/src/smr.c @@ -29,6 +29,7 @@ int archive(struct http_request *); int api(struct http_request *); int style(struct http_request *); int miligram(struct http_request *); +int delete(struct http_request *); int do_lua(struct http_request *req, const char *name); int errhandeler(lua_State *); lua_State *L; @@ -56,26 +57,26 @@ KORE_SECCOMP_FILTER("app", ); int -errhandeler(lua_State *L){ - printf("Error: %s\n",lua_tostring(L,1));//"error" - lua_getglobal(L,"debug");//"error",{debug} - lua_getglobal(L,"print");//"error",{debug},print() - lua_getfield(L,-2,"traceback");//"error",{debug},print(),traceback() - lua_call(L,0,1);//"error",{debug},print(),"traceback" - lua_call(L,1,0);//"error",{debug} +errhandeler(lua_State *state){ + printf("Error: %s\n",lua_tostring(state,1));//"error" + lua_getglobal(state,"debug");//"error",{debug} + lua_getglobal(state,"print");//"error",{debug},print() + lua_getfield(state,-2,"traceback");//"error",{debug},print(),traceback() + lua_call(state,0,1);//"error",{debug},print(),"traceback" + lua_call(state,1,0);//"error",{debug} printf("Called print()\n"); - lua_getfield(L,-1,"traceback");//"error",{debug},traceback() + lua_getfield(state,-1,"traceback");//"error",{debug},traceback() printf("got traceback\n"); - lua_call(L,0,1);//"error",{debug},"traceback" - lua_pushstring(L,"\n"); + lua_call(state,0,1);//"error",{debug},"traceback" + lua_pushstring(state,"\n"); printf("called traceback\n"); - lua_pushvalue(L,-4);//"error",{debug},"traceback","error" + lua_pushvalue(state,-4);//"error",{debug},"traceback","error" printf("pushed error\n"); - lua_concat(L,3);//"error",{debug},"traceback .. error" + lua_concat(state,3);//"error",{debug},"traceback .. error" printf("concated\n"); - int ref = luaL_ref(L,LUA_REGISTRYINDEX);//"error",{debug} - lua_pop(L,2);// - lua_rawgeti(L,LUA_REGISTRYINDEX,ref);//"traceback .. error" + int ref = luaL_ref(state,LUA_REGISTRYINDEX);//"error",{debug} + lua_pop(state,2);// + lua_rawgeti(state,LUA_REGISTRYINDEX,ref);//"traceback .. error" return 1; } @@ -179,6 +180,11 @@ home(struct http_request *req){ return do_lua(req,"home"); } +int +delete(struct http_request *req){ + return do_lua(req,"delete"); +} + void kore_worker_configure(void){ printf("Configuring worker...\n"); diff --git a/src/sql/delete_post.sql b/src/sql/delete_post.sql new file mode 100644 index 0000000..381b599 --- /dev/null +++ b/src/sql/delete_post.sql @@ -0,0 +1,3 @@ +DELETE FROM posts +WHERE posts.id = :postid AND + posts.authorid = :authorid