diff --git a/litelist-api/dub.json b/litelist-api/dub.json
index 41adfc7..97b373e 100644
--- a/litelist-api/dub.json
+++ b/litelist-api/dub.json
@@ -7,7 +7,7 @@
"botan": "~>1.13.5",
"d-properties": "~>1.0.5",
"d2sqlite3": "~>1.0.0",
- "handy-httpd": "~>7.10.4",
+ "handy-httpd": "~>7.13.0",
"jwt": "~>0.4.0",
"resusage": "~>0.3.2",
"slf4d": "~>2.4.3"
diff --git a/litelist-api/dub.selections.json b/litelist-api/dub.selections.json
index 22c3754..b94ee22 100644
--- a/litelist-api/dub.selections.json
+++ b/litelist-api/dub.selections.json
@@ -1,14 +1,15 @@
{
"fileVersion": 1,
"versions": {
- "botan": "1.13.5",
+ "botan": "1.13.6",
"botan-math": "1.0.4",
"d-properties": "1.0.5",
"d2sqlite3": "1.0.0",
- "handy-httpd": "7.10.4",
+ "handy-httpd": "7.13.0",
"httparsed": "1.2.1",
"jwt": "0.4.0",
"memutils": "1.0.9",
+ "path-matcher": "1.1.3",
"resusage": "0.3.2",
"slf4d": "2.4.3",
"streams": "3.5.0"
diff --git a/litelist-api/source/app.d b/litelist-api/source/app.d
index 1887416..73fb864 100644
--- a/litelist-api/source/app.d
+++ b/litelist-api/source/app.d
@@ -16,7 +16,7 @@ void main() {
* Returns: The HTTP server to use.
*/
private HttpServer initServer() {
- import handy_httpd.handlers.path_delegating_handler;
+ import handy_httpd.handlers.path_handler;
import handy_httpd.handlers.filtered_handler;
import d_properties;
import endpoints.auth;
@@ -59,7 +59,7 @@ private HttpServer initServer() {
immutable string API_PATH = "/api";
- PathDelegatingHandler mainHandler = new PathDelegatingHandler();
+ PathHandler mainHandler = new PathHandler();
mainHandler.addMapping(Method.GET, API_PATH ~ "/status", &handleStatus);
mainHandler.addMapping(Method.POST, API_PATH ~ "/register", &createNewUser);
mainHandler.addMapping(Method.POST, API_PATH ~ "/login", &handleLogin);
@@ -74,22 +74,23 @@ private HttpServer initServer() {
mainHandler.addMapping(Method.OPTIONS, API_PATH ~ "/**", optionsHandler);
// Separate handler for authenticated paths, protected by a TokenFilter.
- PathDelegatingHandler authHandler = new PathDelegatingHandler();
+ PathHandler authHandler = new PathHandler();
authHandler.addMapping(Method.GET, API_PATH ~ "/me", &getMyUser);
authHandler.addMapping(Method.DELETE, API_PATH ~ "/me", &deleteMyUser);
authHandler.addMapping(Method.GET, API_PATH ~ "/renew-token", &renewToken);
authHandler.addMapping(Method.GET, API_PATH ~ "/lists", &getNoteLists);
authHandler.addMapping(Method.POST, API_PATH ~ "/lists", &createNoteList);
- authHandler.addMapping(Method.GET, API_PATH ~ "/lists/{id}", &getNoteList);
- authHandler.addMapping(Method.DELETE, API_PATH ~ "/lists/{id}", &deleteNoteList);
- authHandler.addMapping(Method.POST, API_PATH ~ "/lists/{listId}/notes", &createNote);
- authHandler.addMapping(Method.DELETE, API_PATH ~ "/lists/{listId}/notes/{noteId}", &deleteNote);
+ authHandler.addMapping(Method.GET, API_PATH ~ "/lists/:id:ulong", &getNoteList);
+ authHandler.addMapping(Method.DELETE, API_PATH ~ "/lists/:id:ulong", &deleteNoteList);
+ authHandler.addMapping(Method.POST, API_PATH ~ "/lists/:listId:ulong/notes", &createNote);
+ authHandler.addMapping(Method.DELETE, API_PATH ~ "/lists/:listId:ulong/notes/:noteId:ulong", &deleteNote);
+ authHandler.addMapping(Method.DELETE, API_PATH ~ "/lists/:listId:ulong/notes", &deleteAllNotes);
HttpRequestFilter tokenFilter = new TokenFilter(loadTokenSecret());
HttpRequestFilter adminFilter = new AdminFilter();
// Separate handler for admin paths, protected by an AdminFilter.
- PathDelegatingHandler adminHandler = new PathDelegatingHandler();
+ PathHandler adminHandler = new PathHandler();
adminHandler.addMapping(Method.GET, API_PATH ~ "/admin/users", &getAllUsers);
mainHandler.addMapping(API_PATH ~ "/admin/**", new FilteredRequestHandler(adminHandler, [tokenFilter, adminFilter]));
diff --git a/litelist-api/source/data/impl/list.d b/litelist-api/source/data/impl/list.d
index 3b4da46..5c86763 100644
--- a/litelist-api/source/data/impl/list.d
+++ b/litelist-api/source/data/impl/list.d
@@ -72,6 +72,13 @@ class SqliteNoteListDataSource : NoteListDataSource {
db.commit();
}
+ void deleteAllNotes(string username, ulong id) {
+ Database db = getDb(username);
+ db.begin();
+ db.execute("DELETE FROM note WHERE note_list_id = ?", id);
+ db.commit();
+ }
+
NoteList updateNoteList(string username, ulong id, NoteList newData) {
Database db = getDb(username);
ResultRange result = db.execute("SELECT * FROM note_list WHERE id = ?", id);
diff --git a/litelist-api/source/data/list.d b/litelist-api/source/data/list.d
index 3b33791..e919369 100644
--- a/litelist-api/source/data/list.d
+++ b/litelist-api/source/data/list.d
@@ -9,6 +9,7 @@ interface NoteListDataSource {
Nullable!NoteList getList(string username, ulong id);
NoteList createNoteList(string username, string name, string description = null);
void deleteNoteList(string username, ulong id);
+ void deleteAllNotes(string username, ulong id);
NoteList updateNoteList(string username, ulong id, NoteList newData);
ulong countLists(string username);
}
diff --git a/litelist-api/source/endpoints/lists.d b/litelist-api/source/endpoints/lists.d
index 0054845..5911471 100644
--- a/litelist-api/source/endpoints/lists.d
+++ b/litelist-api/source/endpoints/lists.d
@@ -81,6 +81,12 @@ void deleteNote(ref HttpRequestContext ctx) {
noteDataSource.deleteNote(auth.user.username, noteId);
}
+void deleteAllNotes(ref HttpRequestContext ctx) {
+ AuthContext auth = getAuthContextOrThrow(ctx);
+ ulong listId = ctx.request.getPathParamAs!ulong("listId");
+ noteListDataSource.deleteAllNotes(auth.user.username, listId);
+}
+
private JSONValue serializeList(NoteList list) {
JSONValue listObj = JSONValue(string[string].init);
listObj.object["id"] = JSONValue(list.id);
diff --git a/litelist-app/src/api/lists.ts b/litelist-app/src/api/lists.ts
index 1a1d772..0af6502 100644
--- a/litelist-app/src/api/lists.ts
+++ b/litelist-app/src/api/lists.ts
@@ -77,3 +77,10 @@ export async function deleteNote(token: string, listId: number, id: number): Pro
headers: {"Authorization": "Bearer " + token}
})
}
+
+export async function deleteAllNotes(token: string, listId: number): Promise ${l.description}
@@ -113,6 +154,10 @@ async function createNoteAndRefresh() {
There are no notes in this list.
${l.name}
`
+ const description = `
`
+ }
+ checkboxList += `