From e310ed83b73e691bef88abeac97b45777096ecf5 Mon Sep 17 00:00:00 2001 From: TolaMironcenko Date: Fri, 24 May 2024 15:14:11 +0700 Subject: [PATCH] finally web interface --- src/users/users.cpp | 12 +++---- src/web/css/index.css | 2 +- src/web/css/loginform.css | 24 +++++++++++-- src/web/css/userstable.css | 22 +++++++++++- src/web/index.html | 63 +++++++++++++++++++++++++++++++++-- src/web/js/add_user.js | 41 +++++++++++++++++++++++ src/web/js/change_password.js | 29 ++++++++++++++++ src/web/js/del_user.js | 33 ++++++++++++++++++ src/web/js/get_all_users.js | 4 ++- src/web/js/login.js | 31 +++++------------ src/web/js/message.js | 18 ++++++++++ src/web/js/routes.js | 5 ++- src/web/js/window.js | 4 +++ 13 files changed, 249 insertions(+), 39 deletions(-) create mode 100644 src/web/js/add_user.js create mode 100644 src/web/js/change_password.js create mode 100644 src/web/js/del_user.js create mode 100644 src/web/js/message.js diff --git a/src/users/users.cpp b/src/users/users.cpp index 3cdec7f..42eb212 100644 --- a/src/users/users.cpp +++ b/src/users/users.cpp @@ -111,18 +111,18 @@ void add_user(const httplib::Request& request, httplib::Response& response) { const std::string password = json_body["password"]; for (auto& user : all_users) { - if ((user["username"] == username) && (user["password"] == password)) { + if ((user["username"] == username)) { response.set_content("{\"status\":\"user already exists\"}", "application/json");return; } } std::stringstream new_user_data; - new_user_data << "{\"id\":\"" << get_random_string(ALPHABET, 50) << "\",\"username\":\"" << username << "\",\"password\":\"" << password << "\",\"group\":\""; - (json_body["group"] != nullptr) ? new_user_data << json_body["group"] : new_user_data << "users"; - new_user_data << "\",\"is_superuser\":\""; - (json_body["is_superuser"] != nullptr) ? new_user_data << json_body["is_superuser"] : new_user_data << "0"; - new_user_data << "\"}"; + new_user_data << "{\"id\":\"" << get_random_string(ALPHABET, 50) << "\",\"username\":\"" << username << "\",\"password\":\"" << password << "\",\"group\":"; + (json_body["group"] != nullptr) ? new_user_data << json_body["group"] : new_user_data << "\"users\""; + new_user_data << ",\"is_superuser\":"; + (json_body["is_superuser"] != nullptr) ? new_user_data << json_body["is_superuser"] : new_user_data << "\"0\""; + new_user_data << "}"; all_users.push_back(nlohmann::json::parse(new_user_data)); std::ofstream usersfilew("users.json"); diff --git a/src/web/css/index.css b/src/web/css/index.css index 27ad75c..e811ff1 100644 --- a/src/web/css/index.css +++ b/src/web/css/index.css @@ -10,4 +10,4 @@ body { background-color: black; color: white; position: relative; -} \ No newline at end of file +} diff --git a/src/web/css/loginform.css b/src/web/css/loginform.css index 530eefb..37261fd 100644 --- a/src/web/css/loginform.css +++ b/src/web/css/loginform.css @@ -1,4 +1,4 @@ -.loginform { +.form { position: absolute; width: 100%; height: 0; @@ -11,14 +11,19 @@ pointer-events: none; transition: 0.3s; background-color: black; + z-index: 10; } -.loginform.active { +.form.confirmform { + background-color: transparent; +} + +.form.active { height: 100%; pointer-events: all; } -.loginformbody { +.formbody { padding: 10px; background-color: gray; border-radius: 10px; @@ -40,6 +45,18 @@ transition: 0.3s; } +.loginforminputbody { + +} + +.loginforminputbodyflex { + display: flex; +} + +.loginforminputbodyflex>button { + margin: 10px; +} + .loginformbutton { padding: 10px; border: none; @@ -50,6 +67,7 @@ background-color: rgb(59, 59, 197); color: white; transition: 0.3s; + margin: 5px 0; } .loginformbutton:hover { diff --git a/src/web/css/userstable.css b/src/web/css/userstable.css index fd55e27..edee8a8 100644 --- a/src/web/css/userstable.css +++ b/src/web/css/userstable.css @@ -24,9 +24,29 @@ tbody { } th { + position: relative; border-radius: 10px; padding: 10px; - width: 25%; + width: 16%; + text-overflow: auto; + overflow-x: auto; +} + +.thbutton { + position: absolute; + width: 100%; + height: 100%; + cursor: pointer; + left: 0; + top: 0; + background-color: rgb(48, 44, 44); + color: white; + border: none; + transition: 0.3s; +} + +.thbutton:hover { + background-color: rgb(145, 77, 77); } ::-webkit-scrollbar { diff --git a/src/web/index.html b/src/web/index.html index d61f2a2..888980c 100644 --- a/src/web/index.html +++ b/src/web/index.html @@ -13,17 +13,18 @@
+
-
-
+
+

Login

Username
-
Username
+
Passsword
@@ -32,6 +33,56 @@
+
+
+

Add User

+
+
Username
+ +
+
+
Password
+ +
+
+
Group
+ +
+
+
Is Superuser
+ +
+
+ + +
+
+
+ +
+
+

Are you sure?

+
+ + +
+
+
+ +
+
+

Change Password

+
+
New password
+ +
+
+ + +
+
+
+

@@ -44,6 +95,8 @@ username group is_superuser + delete + change password @@ -52,9 +105,13 @@
+ + + + \ No newline at end of file diff --git a/src/web/js/add_user.js b/src/web/js/add_user.js new file mode 100644 index 0000000..bb87e7a --- /dev/null +++ b/src/web/js/add_user.js @@ -0,0 +1,41 @@ +const adduserbutton = document.querySelector('.adduserbutton') +const adduserform = document.querySelector('.adduserform') +const canceladduserbutton = document.querySelector('.canceladduser') +const adduserformbody = document.querySelector('.adduserformbody') +const usernameinput = document.querySelector('#adduserformusername') +const passwordinput = document.querySelector('#adduserformpassword') +const groupinput = document.querySelector('#adduserformgroup') +const is_superuserinput = document.querySelector('#adduserformissuperuser') + +adduserbutton.addEventListener('click', () => { + adduserform.classList.add('active') +}) + +canceladduserbutton.addEventListener('click', (e) => { + e.preventDefault() + adduserform.classList.remove('active') +}) + +adduserformbody.addEventListener('submit', async (e) => { + e.preventDefault() + const new_user = { + username: usernameinput.value, + password: passwordinput.value, + group: groupinput.value, + is_superuser: is_superuserinput.checked?"1":"0" + } + console.log({...new_user, token: localStorage.getItem('token')}) + const status = await fetch(routes.adduser(), { + method: 'POST', + body: `{"token":"${localStorage.getItem('token')}","username":"${new_user.username}","password":"${new_user.password}","group":"${new_user.group}","is_superuser":"${new_user.is_superuser}"}` + }).then(data => data.json()).then(jsondata => jsondata) + console.log(status) + if (status.status === "ok") { + adduserform.classList.remove('active') + get_all_users() + notification("Пользователь успешно добавлен", "success") + } + if (status.status === "user already exists") { + notification("Пользователь с таким именем уже существует", "error") + } +}) diff --git a/src/web/js/change_password.js b/src/web/js/change_password.js new file mode 100644 index 0000000..61edb13 --- /dev/null +++ b/src/web/js/change_password.js @@ -0,0 +1,29 @@ +const changepasswordform = document.querySelector('.changepasswordform') +const cancelchangepassword = document.querySelector('.cancelchangepassword') +const changepasswordformbody = document.querySelector('.changepasswordformbody') +const changepasswordnewpassword = document.querySelector('#changepasswordnewpassword') + +var changepassuserid = "" + +const change_password = (userid) => { + changepasswordform.classList.add('active') + changepassuserid = userid +} + +cancelchangepassword.addEventListener('click', e => { + e.preventDefault() + changepasswordform.classList.remove('active') +}) + +changepasswordformbody.addEventListener('submit', async e => { + e.preventDefault() + const status = await fetch(routes.change_password_url(), { + method: 'POST', + body: `{"token":"${localStorage.getItem('token')}","userid":"${changepassuserid}","new_password":"${changepasswordnewpassword.value}"}` + }).then(data => data.json()).then(jsondata => jsondata) + console.log(status) + if (status.status === "ok") { + notification("Пароль успешно изменен", "success") + changepasswordform.classList.remove('active') + } +}) diff --git a/src/web/js/del_user.js b/src/web/js/del_user.js new file mode 100644 index 0000000..ff386f3 --- /dev/null +++ b/src/web/js/del_user.js @@ -0,0 +1,33 @@ +const userstablebody = document.querySelector('.alluserstablebody') +const confirmform = document.querySelector('.confirmform') +const confirmformcancel = document.querySelector('.no') +const confirmformok = document.querySelector('.yes') + +var useridtodelete = "" + +userstablebody.addEventListener('click', e => { + if (e.target.classList.contains('deleteuser')) { + useridtodelete = e.target.id + confirmform.classList.add("active") + } + if (e.target.classList.contains('changepassword')) { + change_password(e.target.id) + } +}) + +confirmformcancel.addEventListener('click', () => { + useridtodelete = "" + confirmform.classList.remove('active') +}) + +confirmformok.addEventListener('click', async () => { + const status = await fetch(routes.deluser(), { + method: 'POST', + body: `{"token":"${localStorage.getItem('token')}","userid":"${useridtodelete}"}` + }).then(data => data.json()).then(jsondata => jsondata) + + console.log(status) + if (status.status === "ok") { + notification("Пользователь успешно удален", "success") + } +}) diff --git a/src/web/js/get_all_users.js b/src/web/js/get_all_users.js index b207b1f..fa4cf1f 100644 --- a/src/web/js/get_all_users.js +++ b/src/web/js/get_all_users.js @@ -5,7 +5,7 @@ const get_all_users = async () => { }).then(data => data.json()).then(jsondata => jsondata) console.log(response) const alluserstablebody = document.querySelector('.alluserstablebody') - // alluserstablebody.innerHTML = "" + alluserstablebody.innerHTML = "" for (const user of response) { alluserstablebody.innerHTML += ` @@ -13,6 +13,8 @@ const get_all_users = async () => { ${user.username} ${user.group} ${user.is_superuser} + + ` } diff --git a/src/web/js/login.js b/src/web/js/login.js index f3556f4..7ed3c70 100644 --- a/src/web/js/login.js +++ b/src/web/js/login.js @@ -3,8 +3,6 @@ const loginformbody = document.querySelector('.loginformbody') const loginforminputusername = document.querySelector('#loginforminputusername') const loginforminputpassword = document.querySelector('#loginforminputpassword') const loginformbutton = document.querySelector('.loginformbutton') -const message = document.querySelector('.message') -const messagetext = document.querySelector('.messagetext') const exitbutton = document.querySelector('.exitbutton') // loginformbody.unbind('submit') @@ -27,22 +25,10 @@ const login = async (username, password) => { body: `{"username":"${username}","password":"${password}"}` }).then(data => data.json()).then(jsondata => jsondata) if (response.status === "403") { - messagetext.innerHTML = "Неправильный логин или пароль" - message.classList.remove('success') - message.classList.add("error") - message.classList.add("active") - setTimeout(() => { - message.classList.remove('active') - }, 2000) + notification("Неправильный логин или пароль", "error") } if (response.token) { - messagetext.innerHTML = "Успешно" - message.classList.remove('error') - message.classList.add("success") - message.classList.add("active") - setTimeout(() => { - message.classList.remove('active') - }, 2000) + notification("Успешно", "success") loginform.classList.remove("active") localStorage.setItem("token", response.token) get_user_data(response.token) @@ -56,6 +42,11 @@ const get_user_data = async (token) => { }).then(data => data.json()).then(jsondata => jsondata) if (response.is_superuser === "1") { get_all_users() + } else { + document.querySelector('.alluserstablebody').innerHTML = "" + loginform.classList.add("active") + notification("Вы не можете войти потому что не являетесь администратором", "error") + localStorage.clear() } if (response.id) { localStorage.setItem("userdata", JSON.stringify(response)) @@ -69,11 +60,5 @@ message.addEventListener('click', () => { exitbutton.addEventListener('click', () => { localStorage.clear() loginform.classList.add('active') - messagetext.innerHTML = 'Вы вышли' - message.classList.remove('error') - message.classList.add('.success') - message.classList.add('active') - setTimeout(() => { - message.classList.remove('active') - }, 2000) + notification('Вы вышли', "success") }) diff --git a/src/web/js/message.js b/src/web/js/message.js new file mode 100644 index 0000000..8014faa --- /dev/null +++ b/src/web/js/message.js @@ -0,0 +1,18 @@ +const message = document.querySelector('.message') +const messagetext = document.querySelector('.messagetext') + +const notification = (text, type) => { + if (type === "error") { + message.classList.remove('success') + message.classList.add('error') + } else { + message.classList.remove('error') + message.classList.add('success') + } + messagetext.innerHTML = text + message.classList.add('active') + setTimeout(() => { + message.classList.remove('active') + }, 2000) +} + diff --git a/src/web/js/routes.js b/src/web/js/routes.js index ca80b3d..ac97e52 100644 --- a/src/web/js/routes.js +++ b/src/web/js/routes.js @@ -5,5 +5,8 @@ const routes = { login: () => [host, prefix, 'token'].join('/'), user: () => [host, prefix, 'users', 'user'].join('/'), all_users: () => [host, prefix, 'users', 'all'].join('/'), - access: () => [host, prefix, 'access'].join('/') + access: () => [host, prefix, 'access'].join('/'), + adduser: () => [host, prefix, 'users', 'add'].join('/'), + deluser: () => [host, prefix, 'users', 'del'].join('/'), + change_password_url: () => [host, prefix, 'users', 'user', 'password', 'change'].join('/') } \ No newline at end of file diff --git a/src/web/js/window.js b/src/web/js/window.js index d5d6775..7a6f728 100644 --- a/src/web/js/window.js +++ b/src/web/js/window.js @@ -7,7 +7,11 @@ document.addEventListener("DOMContentLoaded", () => { if (jsondata.access === "success") { document.querySelector('.loginform').classList.remove('active') get_all_users() + } else { + document.querySelector('.loginform').classList.add('active') } }) + } else { + document.querySelector('.loginform').classList.add('active') } }) \ No newline at end of file