Skip to content

Commit

Permalink
Refactor DELETE operations into separate handlers AND add POST-to-DEL…
Browse files Browse the repository at this point in the history
…ETE mapping to mws-server
  • Loading branch information
well-noted committed Dec 18, 2024
1 parent 1d3209e commit e59eba9
Show file tree
Hide file tree
Showing 6 changed files with 178 additions and 132 deletions.
56 changes: 31 additions & 25 deletions plugins/tiddlywiki/multiwikiserver/modules/mws-server.js
Original file line number Diff line number Diff line change
Expand Up @@ -317,31 +317,37 @@ Server.prototype.addAuthenticator = function(AuthenticatorClass) {
};

Server.prototype.findMatchingRoute = function(request,state) {
for(var t=0; t<this.routes.length; t++) {
var potentialRoute = this.routes[t],
pathRegExp = potentialRoute.path,
pathname = state.urlInfo.pathname,
match;
if(state.pathPrefix) {
if(pathname.substr(0,state.pathPrefix.length) === state.pathPrefix) {
pathname = pathname.substr(state.pathPrefix.length) || "/";
match = potentialRoute.path.exec(pathname);
} else {
match = false;
}
} else {
match = potentialRoute.path.exec(pathname);
}
// Allow POST as a synonym for PUT because HTML doesn't allow PUT forms
if(match && (request.method === potentialRoute.method || (request.method === "POST" && potentialRoute.method === "PUT"))) {
state.params = [];
for(var p=1; p<match.length; p++) {
state.params.push(match[p]);
}
return potentialRoute;
}
}
return null;
for(var t=0; t<this.routes.length; t++) {
var potentialRoute = this.routes[t],
pathRegExp = potentialRoute.path,
pathname = state.urlInfo.pathname,
match;
if(state.pathPrefix) {
if(pathname.substr(0,state.pathPrefix.length) === state.pathPrefix) {
pathname = pathname.substr(state.pathPrefix.length) || "/";
match = potentialRoute.path.exec(pathname);
} else {
match = false;
}
} else {
match = potentialRoute.path.exec(pathname);
}
// Allow POST as a synonym for PUT and DELETE because HTML doesn't allow these methods in forms
if(match && (
request.method === potentialRoute.method ||
(request.method === "POST" && (
potentialRoute.method === "PUT" ||
potentialRoute.method === "DELETE"
))
)) {
state.params = [];
for(var p=1; p<match.length; p++) {
state.params.push(match[p]);
}
return potentialRoute;
}
}
return null;
};

Server.prototype.methodMappings = {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/*\
title: $:/plugins/tiddlywiki/multiwikiserver/routes/handlers/delete-bag.js
type: application/javascript
module-type: mws-route
DELETE /bags/:bag-name
\*/
(function() {

/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";

exports.method = "DELETE";

exports.path = /^\/bags\/([^\/]+)$/;

exports.csrfDisable = true;

exports.useACL = true;

exports.entityName = "bag"

exports.handler = function(request,response,state) {
const bagName = state.params[0];
if(bagName) {
const result = $tw.mws.store.deleteBag(bagName);
if(!result) {
state.sendResponse(302,{
"Content-Type": "text/plain",
"Location": "/"
});
} else {
state.sendResponse(400,{
"Content-Type": "text/plain"
},
result.message,
"utf8");
}
} else {
state.sendResponse(400,{
"Content-Type": "text/plain"
});
}
};

}());
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/*\
title: $:/plugins/tiddlywiki/multiwikiserver/routes/handlers/delete-recipe.js
type: application/javascript
module-type: mws-route
DELETE /recipes/:recipe-name
\*/
(function() {

/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";

exports.method = "DELETE";

exports.path = /^\/recipes\/([^\/]+)$/;

exports.csrfDisable = true;

exports.useACL = true;

exports.entityName = "recipe"

exports.handler = function(request,response,state) {
const recipeName = state.params[0];
if(recipeName) {
const result = $tw.mws.store.deleteRecipe(recipeName);
if(!result) {
state.sendResponse(302,{
"Content-Type": "text/plain",
"Location": "/"
});
} else {
state.sendResponse(400,{
"Content-Type": "text/plain"
},
result.message,
"utf8");
}
} else {
state.sendResponse(400,{
"Content-Type": "text/plain"
});
}
};

}());
Original file line number Diff line number Diff line change
Expand Up @@ -30,52 +30,25 @@ exports.useACL = true;
exports.entityName = "bag"

exports.handler = function(request,response,state) {
var server = state.server,
sqlTiddlerDatabase = server.sqlTiddlerDatabase;

// Handle DELETE request
if(state.data._method === "DELETE") {
if(state.data.bag_name) {
const result = $tw.mws.store.deleteBag(state.data.bag_name);
if(!result) {
state.sendResponse(302,{
"Content-Type": "text/plain",
"Location": "/"
});
} else {
state.sendResponse(400,{
"Content-Type": "text/plain"
},
result.message,
"utf8");
}
} else {
state.sendResponse(400,{
"Content-Type": "text/plain"
});
}
return;
}

if(state.data.bag_name) {
const result = $tw.mws.store.createBag(state.data.bag_name,state.data.description);
if(!result) {
state.sendResponse(302,{
"Content-Type": "text/plain",
"Location": "/"
});
} else {
state.sendResponse(400,{
"Content-Type": "text/plain"
},
result.message,
"utf8");
}
} else {
state.sendResponse(400,{
"Content-Type": "text/plain"
});
}
if(state.data.bag_name) {
const result = $tw.mws.store.createBag(state.data.bag_name,state.data.description);
if(!result) {
state.sendResponse(302,{
"Content-Type": "text/plain",
"Location": "/"
});
} else {
state.sendResponse(400,{
"Content-Type": "text/plain"
},
result.message,
"utf8");
}
} else {
state.sendResponse(400,{
"Content-Type": "text/plain"
});
}
};

}());
}());
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ type: application/javascript
module-type: mws-route
POST /recipes
DELETE /recipes (via _method=DELETE)
Parameters:
recipe_name
Expand All @@ -31,56 +30,31 @@ exports.useACL = true;
exports.entityName = "recipe"

exports.handler = function(request,response,state) {
var server = state.server,
sqlTiddlerDatabase = server.sqlTiddlerDatabase;

// Check and handle if this is a DELETE request
if(state.data._method === "DELETE") {
if(state.data.recipe_name && state.data.bag_names) {
const result = sqlTiddlerDatabase.deleteRecipe(state.data.recipe_name);
if(!result) {
state.sendResponse(302,{
"Content-Type": "text/plain",
"Location": "/"
});
} else {
state.sendResponse(400,{
"Content-Type": "text/plain"
},
result.message,
"utf8");
}
} else {
state.sendResponse(400,{
"Content-Type": "text/plain"
});
}
return;
}

// Handle POST request (original code)
if(state.data.recipe_name && state.data.bag_names) {
const result = $tw.mws.store.createRecipe(state.data.recipe_name,$tw.utils.parseStringArray(state.data.bag_names),state.data.description);
if(!result) {
if(state.authenticatedUser) {
sqlTiddlerDatabase.assignRecipeToUser(state.data.recipe_name,state.authenticatedUser.user_id);
}
state.sendResponse(302,{
"Content-Type": "text/plain",
"Location": "/"
});
} else {
state.sendResponse(400,{
"Content-Type": "text/plain"
},
result.message,
"utf8");
}
} else {
state.sendResponse(400,{
"Content-Type": "text/plain"
});
}
var server = state.server,
sqlTiddlerDatabase = server.sqlTiddlerDatabase;

if(state.data.recipe_name && state.data.bag_names) {
const result = $tw.mws.store.createRecipe(state.data.recipe_name,$tw.utils.parseStringArray(state.data.bag_names),state.data.description);
if(!result) {
if(state.authenticatedUser) {
sqlTiddlerDatabase.assignRecipeToUser(state.data.recipe_name,state.authenticatedUser.user_id);
}
state.sendResponse(302,{
"Content-Type": "text/plain",
"Location": "/"
});
} else {
state.sendResponse(400,{
"Content-Type": "text/plain"
},
result.message,
"utf8");
}
} else {
state.sendResponse(400,{
"Content-Type": "text/plain"
});
}
};

}());
15 changes: 6 additions & 9 deletions plugins/tiddlywiki/multiwikiserver/templates/get-index.tid
Original file line number Diff line number Diff line change
Expand Up @@ -88,10 +88,8 @@ title: $:/plugins/tiddlywiki/multiwikiserver/templates/get-index
<$text text={{{ [<recipe-info>jsonget[description]] }}}/>
</div>
<div class="mws-wiki-card-actions">
<form action="/recipes" method="post">
<form action={{{ [<recipe-info>jsonget[recipe_name]addprefix[/recipes/]] }}} method="post" onsubmit="return confirmRecipeDelete(this)">
<input type="hidden" name="_method" value="DELETE"/>
<input type="hidden" name="recipe_name" value={{{ [<recipe-info>jsonget[recipe_name]] }}}/>
<input type="hidden" name="bag_names" value={{{ [<recipe-info>jsonget[bag_names]join[ ]] }}}/>
<button type="submit" class="mws-delete-button">Delete Recipe</button>
</form>
</div>
Expand Down Expand Up @@ -142,12 +140,11 @@ title: $:/plugins/tiddlywiki/multiwikiserver/templates/get-index
<$transclude $variable="bagPill"/>
<$text text={{{ [<bag-info>jsonget[description]] }}}/>
<div class="mws-wiki-card-actions">
<form action="/bags" method="post" onsubmit="return confirmBagDelete(this)">
<input type="hidden" name="_method" value="DELETE"/>
<input type="hidden" name="bag_name" value={{{ [<bag-info>jsonget[bag_name]] }}}/>
<button type="submit" class="mws-delete-button">Delete Bag</button>
</form>
</div>
<form action={{{ [<bag-info>jsonget[bag_name]addprefix[/bags/]] }}} method="post" onsubmit="return confirmBagDelete(this)">
<input type="hidden" name="_method" value="DELETE"/>
<button type="submit" class="mws-delete-button">Delete Bag</button>
</form>
</div>
</$let>
</li>
</$list>
Expand Down

0 comments on commit e59eba9

Please sign in to comment.