diff --git a/auth-routes.lisp b/auth-routes.lisp index 559d99b..362779f 100644 --- a/auth-routes.lisp +++ b/auth-routes.lisp @@ -157,3 +157,59 @@ (api-output `(("status" . "success") ("message" . ,(format nil "Password reset for user: ~a" username))))))) + +(define-api asteroid/user/activate (user-id active) () + "API endpoint for setting the active state of an user account" + (format t "Activation of user: #~a set to ~a~%" user-id active) + (require-role :admin) + (with-error-handling + (let ((user (when user-id + (find-user-by-id user-id))) + (active (if (stringp active) + (parse-integer active) + active))) + + (unless user + (error 'not-found-error :message "User not found")) + + ;; Change user active state + (let ((result (if (= 0 active) + (deactivate-user user-id) + (activate-user user-id)))) + (if result + (api-output `(("status" . "success") + ("message" . ,(format nil "User '~a' ~a." + (dm:field user "username") + (if (= 0 active) + "deactivated" + "activated"))))) + (api-output `(("status" . "error") + ("message" . ,(format nil "Could not ~a user '~a'." + (if (= 0 active) + "deactivated" + "activated") + (dm:field user "username")))))))))) + +(define-api asteroid/user/role (user-id role) () + "API endpoint for setting the access role of an user account" + (format t "Role of user: #~a set to ~a~%" user-id role) + (require-role :admin) + (with-error-handling + (let ((user (when user-id + (find-user-by-id user-id))) + (user-role (intern (string-upcase role) :keyword))) + + (unless user + (error 'not-found-error :message "User not found")) + + ;; Change user role + (let ((result (update-user-role user-id user-role))) + (if result + (api-output `(("status" . "success") + ("message" . ,(format nil "User '~a' is now a ~a." + (dm:field user "username") + role)))) + (api-output `(("status" . "error") + ("message" . ,(format nil "Could not set user '~a' as ~a." + (dm:field user "username") + role))))))))) diff --git a/static/js/users.js b/static/js/users.js index 33051b4..1bf3012 100644 --- a/static/js/users.js +++ b/static/js/users.js @@ -90,20 +90,23 @@ function hideUsersTable() { async function updateUserRole(userId, newRole) { try { const formData = new FormData(); + formData.append('user-id', userId); formData.append('role', newRole); - const response = await fetch(`/api/asteroid/users/${userId}/role`, { + const response = await fetch('/api/asteroid/user/role', { method: 'POST', body: formData }); const result = await response.json(); + // Handle Radiance API data wrapping + const data = result.data || result; - if (result.status === 'success') { + if (data.status === 'success') { loadUserStats(); - alert('User role updated successfully'); + alert(data.message); } else { - alert('Error updating user role: ' + result.message); + alert('Error updating user role: ' + data.message); } } catch (error) { console.error('Error updating user role:', error); @@ -117,18 +120,25 @@ async function deactivateUser(userId) { } try { - const response = await fetch(`/api/asteroid/users/${userId}/deactivate`, { - method: 'POST' + const formData = new FormData(); + formData.append('user-id', userId); + formData.append('active', 0); + + const response = await fetch('/api/asteroid/user/activate', { + method: 'POST', + body: formData }); const result = await response.json(); + // Handle Radiance API data wrapping + const data = result.data || result; - if (result.status === 'success') { + if (data.status === 'success') { loadUsers(); loadUserStats(); - alert('User deactivated successfully'); + alert(data.message); } else { - alert('Error deactivating user: ' + result.message); + alert('Error deactivating user: ' + data.message); } } catch (error) { console.error('Error deactivating user:', error); @@ -137,19 +147,31 @@ async function deactivateUser(userId) { } async function activateUser(userId) { + if (!confirm('Are you sure you want to activate this user?')) { + return; + } + try { - const response = await fetch(`/api/asteroid/users/${userId}/activate`, { - method: 'POST' + + const formData = new FormData(); + formData.append('user-id', userId); + formData.append('active', 1); + + const response = await fetch('/api/asteroid/user/activate', { + method: 'POST', + body: formData }); const result = await response.json(); + // Handle Radiance API data wrapping + const data = result.data || result; - if (result.status === 'success') { + if (data.status === 'success') { loadUsers(); loadUserStats(); - alert('User activated successfully'); + alert(data.message); } else { - alert('Error activating user: ' + result.message); + alert('Error activating user: ' + data.message); } } catch (error) { console.error('Error activating user:', error); diff --git a/user-management.lisp b/user-management.lisp index 2967604..a5b156c 100644 --- a/user-management.lisp +++ b/user-management.lisp @@ -40,7 +40,10 @@ (defun find-user-by-id (user-id) "Find a user by ID" (format t "Looking for user with ID: ~a (type: ~a)~%" user-id (type-of user-id)) - (let ((user (dm:get-one "USERS" (db:query (:= '_id user-id))))) + (let* ((user-id (if (stringp user-id) + (parse-integer user-id) + user-id)) + (user (dm:get-one "USERS" (db:query (:= '_id user-id))))) (when user (format t "Found user '~a' with id #~a~%" (dm:field user "username")