diff --git a/plugins/tiddlywiki/multiwikiserver/modules/routes/handlers/get-users.js b/plugins/tiddlywiki/multiwikiserver/modules/routes/handlers/get-users.js index fea50ba19..435c6546f 100644 --- a/plugins/tiddlywiki/multiwikiserver/modules/routes/handlers/get-users.js +++ b/plugins/tiddlywiki/multiwikiserver/modules/routes/handlers/get-users.js @@ -34,8 +34,6 @@ GET /admin/users last_login: user.last_login ? new Date(user.last_login).toISOString() : '' })); - console.log("Processed userList =>", userList); - response.writeHead(200, "OK", { "Content-Type": "text/html" }); @@ -45,10 +43,12 @@ GET /admin/users variables: { "page-content": "$:/plugins/tiddlywiki/multiwikiserver/templates/get-users", "user-list": JSON.stringify(userList), + "username": state.authenticatedUser ? state.authenticatedUser.username : "Guest", + "user-is-admin": state.authenticatedUser && state.authenticatedUser.isAdmin ? "yes" : "no" } }); response.write(html); response.end(); }; - }()); \ No newline at end of file +}()); \ No newline at end of file diff --git a/plugins/tiddlywiki/multiwikiserver/modules/routes/handlers/manage-roles.js b/plugins/tiddlywiki/multiwikiserver/modules/routes/handlers/manage-roles.js new file mode 100644 index 000000000..b1ec774b8 --- /dev/null +++ b/plugins/tiddlywiki/multiwikiserver/modules/routes/handlers/manage-roles.js @@ -0,0 +1,36 @@ +/*\ +title: $:/plugins/tiddlywiki/multiwikiserver/routes/handlers/manage-roles.js +type: application/javascript +module-type: mws-route + +GET /admin/roles + +\*/ +(function() { + +/*jslint node: true, browser: true */ +/*global $tw: false */ +"use strict"; + +exports.method = "GET"; + +exports.path = /^\/admin\/roles\/?$/; + +exports.handler = function(request, response, state) { + var roles = state.server.sqlTiddlerDatabase.listRoles(); + + response.writeHead(200, "OK", {"Content-Type": "text/html"}); + + var html = $tw.mws.store.adminWiki.renderTiddler("text/plain", "$:/plugins/tiddlywiki/multiwikiserver/templates/page", { + variables: { + "page-content": "$:/plugins/tiddlywiki/multiwikiserver/templates/manage-roles", + "roles-list": JSON.stringify(roles), + "username": state.authenticatedUser ? state.authenticatedUser.username : "Guest", + "user-is-admin": state.authenticatedUser && state.authenticatedUser.isAdmin ? "yes" : "no" + } + }); + response.write(html); + response.end(); +}; + +}()); \ No newline at end of file diff --git a/plugins/tiddlywiki/multiwikiserver/modules/routes/handlers/manage-user.js b/plugins/tiddlywiki/multiwikiserver/modules/routes/handlers/manage-user.js new file mode 100644 index 000000000..daff1f254 --- /dev/null +++ b/plugins/tiddlywiki/multiwikiserver/modules/routes/handlers/manage-user.js @@ -0,0 +1,70 @@ +/*\ +title: $:/plugins/tiddlywiki/multiwikiserver/routes/handlers/manage-user.js +type: application/javascript +module-type: mws-route + +GET /admin/users/:user_id + +\*/ +(function() { + +/*jslint node: true, browser: true */ +/*global $tw: false */ +"use strict"; + +exports.method = "GET"; + +exports.path = /^\/admin\/users\/([^\/]+)\/?$/; + + +exports.handler = function(request,response,state) { + var user_id = $tw.utils.decodeURIComponentSafe(state.params[0]); + console.log("user_id =>", user_id) + + var userData = state.server.sqlTiddlerDatabase.getUser(user_id); + + if(!userData) { + response.writeHead(404, "Not Found", {"Content-Type": "text/html"}); + var errorHtml = $tw.mws.store.adminWiki.renderTiddler("text/plain", "$:/plugins/tiddlywiki/multiwikiserver/templates/error", { + variables: { + "error-message": "User not found" + } + }); + response.write(errorHtml); + response.end(); + return; + } + + // Convert dates to strings and ensure all necessary fields are present + const user = { + user_id: userData.user_id || '', + username: userData.username || '', + email: userData.email || '', + created_at: userData.created_at ? new Date(userData.created_at).toISOString() : '', + last_login: userData.last_login ? new Date(userData.last_login).toISOString() : '' + }; + + // Get all roles which the user has been assigned + var userRoles = state.server.sqlTiddlerDatabase.getUserRoles(user_id); + var allRoles = state.server.sqlTiddlerDatabase.listRoles(); + + response.writeHead(200, "OK", { + "Content-Type": "text/html" + }); + + // Render the html + var html = $tw.mws.store.adminWiki.renderTiddler("text/plain", "$:/plugins/tiddlywiki/multiwikiserver/templates/page", { + variables: { + "page-content": "$:/plugins/tiddlywiki/multiwikiserver/templates/manage-user", + "user": JSON.stringify(user), + "user-roles": JSON.stringify(userRoles), + "all-roles": JSON.stringify(allRoles), + "username": state.authenticatedUser ? state.authenticatedUser.username : "Guest", + "user-is-admin": state.authenticatedUser && state.authenticatedUser.isAdmin ? "yes" : "no" + } + }); + response.write(html); + response.end(); +}; + +}()); \ No newline at end of file diff --git a/plugins/tiddlywiki/multiwikiserver/modules/store/sql-tiddler-database.js b/plugins/tiddlywiki/multiwikiserver/modules/store/sql-tiddler-database.js index 4f91f9375..cdf37d936 100644 --- a/plugins/tiddlywiki/multiwikiserver/modules/store/sql-tiddler-database.js +++ b/plugins/tiddlywiki/multiwikiserver/modules/store/sql-tiddler-database.js @@ -1156,6 +1156,17 @@ SqlTiddlerDatabase.prototype.removePermissionFromRole = function(roleId, permiss }); }; +SqlTiddlerDatabase.prototype.getUserRoles = function(userId) { + const query = ` + SELECT r.role_id, r.role_name + FROM user_roles ur + JOIN roles r ON ur.role_id = r.role_id + WHERE ur.user_id = $userId + `; + + return this.engine.runStatementGetAll(query, { $userId: userId }); +}; + exports.SqlTiddlerDatabase = SqlTiddlerDatabase; })(); \ No newline at end of file diff --git a/plugins/tiddlywiki/multiwikiserver/templates/add-user-modal.tid b/plugins/tiddlywiki/multiwikiserver/templates/add-user-modal.tid new file mode 100644 index 000000000..b4444f470 --- /dev/null +++ b/plugins/tiddlywiki/multiwikiserver/templates/add-user-modal.tid @@ -0,0 +1,40 @@ +title: $:/plugins/tiddlywiki/multiwikiserver/templates/add-user-modal + +\define add-user-actions() +<$action-sendmessage $message="tm-server-request" + method="POST" + url="/admin/users" + headers="Content-Type: application/json" + body={{{ [{"username": "$(newUsername)$", "email": "$(newEmail)$", "password": "$(newPassword)$"}jsonify[]] }}} + redirectAfterSuccess="/admin/users"/> +<$action-deletetiddler $tiddler="$:/temp/newUsername"/> +<$action-deletetiddler $tiddler="$:/temp/newEmail"/> +<$action-deletetiddler $tiddler="$:/temp/newPassword"/> +\end + +

Add New User

+ +
+ +
+
+ +
+
+ +
+ +<$button class="tc-btn-big-green"> + Add User + <> + <$action-sendmessage $message="tm-close-tiddler"/> + +<$button class="tc-btn-invisible" message="tm-close-tiddler"> + Cancel + \ No newline at end of file diff --git a/plugins/tiddlywiki/multiwikiserver/templates/edit-role-modal.tid b/plugins/tiddlywiki/multiwikiserver/templates/edit-role-modal.tid new file mode 100644 index 000000000..d56751342 --- /dev/null +++ b/plugins/tiddlywiki/multiwikiserver/templates/edit-role-modal.tid @@ -0,0 +1,27 @@ +title: $:/plugins/tiddlywiki/multiwikiserver/templates/edit-role-modal + +\define save-role-actions() +<> +\end + +

Edit Role

+ +
+ +
+
+ +
+ +<$button class="tc-btn-invisible"> + Save Changes + <> + <$action-sendmessage $message="tm-close-tiddler"/> + +<$button class="tc-btn-invisible" message="tm-close-tiddler"> + Cancel + \ No newline at end of file diff --git a/plugins/tiddlywiki/multiwikiserver/templates/edit-user-modal.tid b/plugins/tiddlywiki/multiwikiserver/templates/edit-user-modal.tid new file mode 100644 index 000000000..18adb24e7 --- /dev/null +++ b/plugins/tiddlywiki/multiwikiserver/templates/edit-user-modal.tid @@ -0,0 +1,32 @@ +title: $:/plugins/tiddlywiki/multiwikiserver/templates/edit-user-modal + +\define edit-user-actions() +<$action-sendmessage $message="tm-server-request" + method="PUT" + url={{{ [[$:/admin/users/]addsuffix{!!user-id}] }}} + headers="Content-Type: application/json" + body={{{ [{"username": "$(editUsername)$", "email": "$(editEmail)$"}jsonify[]] }}} + redirectAfterSuccess="/admin/users"/> +\end + +

Edit User

+ +
+ +
+
+ +
+ +<$button class="tc-btn-big-green"> + Save Changes + <> + <$action-sendmessage $message="tm-close-tiddler"/> + +<$button class="tc-btn-invisible" message="tm-close-tiddler"> + Cancel + \ No newline at end of file diff --git a/plugins/tiddlywiki/multiwikiserver/templates/get-index.tid b/plugins/tiddlywiki/multiwikiserver/templates/get-index.tid index d85e76428..897e54017 100644 --- a/plugins/tiddlywiki/multiwikiserver/templates/get-index.tid +++ b/plugins/tiddlywiki/multiwikiserver/templates/get-index.tid @@ -21,26 +21,11 @@ title: $:/plugins/tiddlywiki/multiwikiserver/templates/get-index \end -
-

Wikis Available Here

- -
+<$tiddler tiddler="$:/plugins/tiddlywiki/multiwikiserver/templates/mws-header"> + <$set name="page-title" value="Wikis Available Here"> + <$transclude/> + +
    <$list filter="[jsonindexes[]] :sort[jsonget[recipe_name]]" variable="recipe-index"> @@ -88,7 +73,6 @@ title: $:/plugins/tiddlywiki/multiwikiserver/templates/get-index
-
Create a new recipe or modify and existing one diff --git a/plugins/tiddlywiki/multiwikiserver/templates/get-users.tid b/plugins/tiddlywiki/multiwikiserver/templates/get-users.tid index 310312d61..4e5805308 100644 --- a/plugins/tiddlywiki/multiwikiserver/templates/get-users.tid +++ b/plugins/tiddlywiki/multiwikiserver/templates/get-users.tid @@ -1,89 +1,113 @@ - -\define lingo-base() $:/language/ControlPanel/Tools/ +\define edit-user-actions(user-id) + <$action-sendmessage $message="tm-modal" $param="$:/plugins/tiddlywiki/multiwikiserver/templates/edit-user-modal" user-id=<>/> +\end -

User Management

+\define delete-user-actions(user-id) + <$action-sendmessage $message="tm-server-request" + method="DELETE" + url={{{ [[$:/admin/users/]addsuffix] }}} + redirectAfterSuccess="/admin/users"/> +\end - -

Debug Info

-

Raw user list JSON: <$text text=<>/>

+<$tiddler tiddler="$:/plugins/tiddlywiki/multiwikiserver/templates/mws-header"> + <$set name="page-title" value="User Management"> + <$transclude/> + + - -<$set name="userList" value=<>> - - <$list filter="[!is[blank]]" emptyMessage="The user list is empty or not provided."> -

User list found: <$text text=<>/>

- - - <$set name="parsedUserList" value={{{ [jsonparse[]] }}}/> - - - <$list filter="[count[]compare:number:gt[0]]" emptyMessage="No users found or failed to parse user data"> - -

Parsed User List (as JSON): <$text text={{{ [jsonstringify[]] }}}/>

- - -

Total users: <$text text={{{ [count[]] }}}/>

- - - - - - - - - - - - - - <$list filter="[jsonindexes[]]" variable="userIndex"> - <$let currentUser={{{ [jsonget] }}}> - - - - - - - - - - -
UsernameEmailCreated AtLast LoginActions
<$text text={{{ [jsonget[username]] }}}/><$text text={{{ [jsonget[email]] }}}/><$text text={{{ [jsonget[created_at]] }}}/><$text text={{{ [jsonget[last_login]] }}}/> - <$button message="tm-server-command" param="edit-user" user_id={{{ [jsonget[user_id]] }}} class="tc-btn-invisible"> - {{$:/core/images/edit-button}} Edit - - <$button message="tm-server-command" param="delete-user" user_id={{{ [jsonget[user_id]] }}} class="tc-btn-invisible"> - {{$:/core/images/delete-button}} Delete - -
+
+
+ <$list filter="[jsonindexes[]]" variable="user-index"> + <$let currentUser={{{ [jsonextract] }}}> + <$set name="user-id" value={{{ [jsonget[user_id]] }}}> + ] }}} class="user-item"> + +
+ + Created: <$text text={{{ [jsonget[created_at]] }}}/> + + +
+
+ + - - - -<$button message="tm-modal" param="$:/plugins/tiddlywiki/multiwikiserver/templates/add-user-modal" class="tc-btn-big-green"> -Add New User - +
+ +
+ <$button class="tc-btn-big-green"> + Add New User + <$action-sendmessage $message="tm-modal" $param="$:/plugins/tiddlywiki/multiwikiserver/templates/add-user-modal"/> + +
+
diff --git a/plugins/tiddlywiki/multiwikiserver/templates/manage-roles.tid b/plugins/tiddlywiki/multiwikiserver/templates/manage-roles.tid new file mode 100644 index 000000000..c64840b85 --- /dev/null +++ b/plugins/tiddlywiki/multiwikiserver/templates/manage-roles.tid @@ -0,0 +1,123 @@ +title: $:/plugins/tiddlywiki/multiwikiserver/templates/manage-roles + +\define add-role-actions() + <$action-sendmessage $message="tm-server-request" + method="POST" + url="/admin/roles" + headers="Content-Type: application/json" + body={{{ [{"name": "$(newRoleName)$", "description": "$(newRoleDescription)$"}jsonify[]] }}} + redirectAfterSuccess="/admin/roles"/> + <$action-setfield $tiddler="$:/temp/newRoleName" text=""/> + <$action-setfield $tiddler="$:/temp/newRoleDescription" text=""/> +\end + +\define edit-role-actions(role-id) + <$action-sendmessage $message="tm-server-request" + method="PUT" + url={{{ [[$:/admin/roles/]addsuffix] }}} + headers="Content-Type: application/json" + body={{{ [{"name": "$(newRoleName)$", "description": "$(newRoleDescription)$"}jsonify[]] }}} + redirectAfterSuccess="/admin/roles"/> +\end + +\define delete-role-actions(role-id) + <$action-sendmessage $message="tm-server-request" + method="DELETE" + url={{{ [[$:/admin/roles/]addsuffix] }}} + redirectAfterSuccess="/admin/roles"/> +\end + +<$tiddler tiddler="$:/plugins/tiddlywiki/multiwikiserver/templates/mws-header"> + <$set name="page-title" value="Manage Roles"> + <$transclude/> + + + +
+
+ <$list filter="[jsonindexes[]]" variable="role-index"> + <$let role={{{ [jsonextract] }}}> +
+ + <$text text={{{ [jsonget[role_name]] }}}/> + + + <$text text={{{ [jsonget[description]] }}}/> + +
+ <$button class="tc-btn-invisible"> + Edit + <$action-setfield $tiddler="$:/temp/editRoleName" text={{{ [jsonget[role_name]] }}}/> + <$action-setfield $tiddler="$:/temp/editRoleDescription" text={{{ [jsonget[description]] }}}/> + <$action-sendmessage $message="tm-modal" $param="$:/plugins/tiddlywiki/multiwikiserver/templates/edit-role-modal" role-id={{{ [jsonget[role_id]] }}}/> + + <$button class="tc-btn-invisible"> + Delete + <$action-confirm $message="Are you sure you want to delete this role?"> + <jsonget[role_id]] }}}>> + + +
+
+ + +
+ +
+ <$edit-text tiddler="$:/temp/newRoleName" tag="input" default="" placeholder="Role Name"/> + <$edit-text tiddler="$:/temp/newRoleDescription" tag="input" default="" placeholder="Role Description"/> + <$button class="tc-btn-invisible"> + Add Role + <> + +
+
+ + diff --git a/plugins/tiddlywiki/multiwikiserver/templates/manage-user.tid b/plugins/tiddlywiki/multiwikiserver/templates/manage-user.tid new file mode 100644 index 000000000..e8876563d --- /dev/null +++ b/plugins/tiddlywiki/multiwikiserver/templates/manage-user.tid @@ -0,0 +1,198 @@ +title: $:/plugins/tiddlywiki/multiwikiserver/templates/manage-user + +<$tiddler tiddler="$:/plugins/tiddlywiki/multiwikiserver/templates/mws-header"> + <$set name="page-title" value="User Profile"> + <$transclude/> + + + + + + + + \ No newline at end of file diff --git a/plugins/tiddlywiki/multiwikiserver/templates/mws-header.tid b/plugins/tiddlywiki/multiwikiserver/templates/mws-header.tid new file mode 100644 index 000000000..3fb5f7f03 --- /dev/null +++ b/plugins/tiddlywiki/multiwikiserver/templates/mws-header.tid @@ -0,0 +1,96 @@ +title: $:/plugins/tiddlywiki/multiwikiserver/templates/mws-header + +
+

<$text text=<>/>

+ +
+ +