mirror of
https://github.com/Jermolene/TiddlyWiki5
synced 2025-01-06 15:30:26 +00:00
Refactor DELETE operations into separate handlers AND add POST-to-DELETE mapping to mws-server
This commit is contained in:
parent
1d3209e9cf
commit
e59eba9086
@ -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 = {
|
||||
|
@ -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"
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
}());
|
@ -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"
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
}());
|
@ -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"
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
}());
|
||||
}());
|
@ -4,7 +4,6 @@ type: application/javascript
|
||||
module-type: mws-route
|
||||
|
||||
POST /recipes
|
||||
DELETE /recipes (via _method=DELETE)
|
||||
|
||||
Parameters:
|
||||
recipe_name
|
||||
@ -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"
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
}());
|
@ -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>
|
||||
@ -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>
|
||||
|
Loading…
Reference in New Issue
Block a user