diff --git a/auth-routes.lisp b/auth-routes.lisp index 559d99b..2043cac 100644 --- a/auth-routes.lisp +++ b/auth-routes.lisp @@ -157,3 +157,35 @@ (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")))))))))) diff --git a/static/js/users.js b/static/js/users.js index 33051b4..c1adabc 100644 --- a/static/js/users.js +++ b/static/js/users.js @@ -117,18 +117,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 +144,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")