"use strict"; /* global DataTable, _post:readable, _delete:readable, BASE_URL:readable, reload:readable, jdenticon:readable */ function deleteUser(event) { event.preventDefault(); event.stopPropagation(); const id = event.target.parentNode.dataset.vwUserUuid; const email = event.target.parentNode.dataset.vwUserEmail; if (!id || !email) { alert("Required parameters not found!"); return false; } const input_email = prompt(`To delete user "${email}", please type the email below`); if (input_email != null) { if (input_email == email) { _post(`${BASE_URL}/admin/users/${id}/delete`, "User deleted correctly", "Error deleting user" ); } else { alert("Wrong email, please try again"); } } } function deleteSSOUser(event) { event.preventDefault(); event.stopPropagation(); const id = event.target.parentNode.dataset.vwUserUuid; const email = event.target.parentNode.dataset.vwUserEmail; if (!id || !email) { alert("Required parameters not found!"); return false; } const input_email = prompt(`To delete user "${email}" SSO association, please type the email below`); if (input_email != null) { if (input_email == email) { _delete(`${BASE_URL}/admin/users/${id}/sso`, "User SSO association deleted correctly", "Error deleting user SSO association" ); } else { alert("Wrong email, please try again"); } } } function remove2fa(event) { event.preventDefault(); event.stopPropagation(); const id = event.target.parentNode.dataset.vwUserUuid; const email = event.target.parentNode.dataset.vwUserEmail; if (!id || !email) { alert("Required parameters not found!"); return false; } const confirmed = confirm(`Are you sure you want to remove 2FA for "${email}"?`); if (confirmed) { _post(`${BASE_URL}/admin/users/${id}/remove-2fa`, "2FA removed correctly", "Error removing 2FA" ); } } function deauthUser(event) { event.preventDefault(); event.stopPropagation(); const id = event.target.parentNode.dataset.vwUserUuid; const email = event.target.parentNode.dataset.vwUserEmail; if (!id || !email) { alert("Required parameters not found!"); return false; } const confirmed = confirm(`Are you sure you want to deauthorize sessions for "${email}"?`); if (confirmed) { _post(`${BASE_URL}/admin/users/${id}/deauth`, "Sessions deauthorized correctly", "Error deauthorizing sessions" ); } } function disableUser(event) { event.preventDefault(); event.stopPropagation(); const id = event.target.parentNode.dataset.vwUserUuid; const email = event.target.parentNode.dataset.vwUserEmail; if (!id || !email) { alert("Required parameters not found!"); return false; } const confirmed = confirm(`Are you sure you want to disable user "${email}"? This will also deauthorize their sessions.`); if (confirmed) { _post(`${BASE_URL}/admin/users/${id}/disable`, "User disabled successfully", "Error disabling user" ); } } function enableUser(event) { event.preventDefault(); event.stopPropagation(); const id = event.target.parentNode.dataset.vwUserUuid; const email = event.target.parentNode.dataset.vwUserEmail; if (!id || !email) { alert("Required parameters not found!"); return false; } const confirmed = confirm(`Are you sure you want to enable user "${email}"?`); if (confirmed) { _post(`${BASE_URL}/admin/users/${id}/enable`, "User enabled successfully", "Error enabling user" ); } } function updateRevisions(event) { event.preventDefault(); event.stopPropagation(); _post(`${BASE_URL}/admin/users/update_revision`, "Success, clients will sync next time they connect", "Error forcing clients to sync" ); } function inviteUser(event) { event.preventDefault(); event.stopPropagation(); const email = document.getElementById("inviteEmail"); const data = JSON.stringify({ "email": email.value }); email.value = ""; _post(`${BASE_URL}/admin/invite`, "User invited correctly", "Error inviting user", data ); } function resendUserInvite(event) { event.preventDefault(); event.stopPropagation(); const id = event.target.parentNode.dataset.vwUserUuid; const email = event.target.parentNode.dataset.vwUserEmail; if (!id || !email) { alert("Required parameters not found!"); return false; } const confirmed = confirm(`Are you sure you want to resend invitation for "${email}"?`); if (confirmed) { _post(`${BASE_URL}/admin/users/${id}/invite/resend`, "Invite sent successfully", "Error resend invite" ); } } const ORG_TYPES = { "0": { "name": "Owner", "bg": "orange", "font": "black" }, "1": { "name": "Admin", "bg": "blueviolet" }, "2": { "name": "User", "bg": "blue" }, "4": { "name": "Manager", "bg": "green" }, }; const userOrgTypeDialog = document.getElementById("userOrgTypeDialog"); // Fill the form and title userOrgTypeDialog.addEventListener("show.bs.modal", function (event) { // Get shared values const userEmail = event.relatedTarget.parentNode.dataset.vwUserEmail; const userUuid = event.relatedTarget.parentNode.dataset.vwUserUuid; // Get org specific values const userOrgType = event.relatedTarget.dataset.vwOrgType; const userOrgTypeName = ORG_TYPES[userOrgType]["name"]; const orgName = event.relatedTarget.dataset.vwOrgName; const orgUuid = event.relatedTarget.dataset.vwOrgUuid; document.getElementById("userOrgTypeDialogOrgName").textContent = orgName; document.getElementById("userOrgTypeDialogUserEmail").textContent = userEmail; document.getElementById("userOrgTypeUserUuid").value = userUuid; document.getElementById("userOrgTypeOrgUuid").value = orgUuid; document.getElementById(`userOrgType${userOrgTypeName}`).checked = true; }, false); // Prevent accidental submission of the form with valid elements after the modal has been hidden. userOrgTypeDialog.addEventListener("hide.bs.modal", function () { document.getElementById("userOrgTypeDialogOrgName").textContent = ""; document.getElementById("userOrgTypeDialogUserEmail").textContent = ""; document.getElementById("userOrgTypeUserUuid").value = ""; document.getElementById("userOrgTypeOrgUuid").value = ""; }, false); function updateUserOrgType(event) { event.preventDefault(); event.stopPropagation(); const data = JSON.stringify(Object.fromEntries(new FormData(event.target).entries())); _post(`${BASE_URL}/admin/users/org_type`, "Updated organization type of the user successfully", "Error updating organization type of the user", data ); } function initUserTable() { // Color all the org buttons per type document.querySelectorAll("button[data-vw-org-type]").forEach(function (e) { const orgType = ORG_TYPES[e.dataset.vwOrgType]; e.style.backgroundColor = orgType.bg; if (orgType.font !== undefined) { e.style.color = orgType.font; } e.title = orgType.name; }); document.querySelectorAll("button[vw-remove2fa]").forEach(btn => { btn.addEventListener("click", remove2fa); }); document.querySelectorAll("button[vw-deauth-user]").forEach(btn => { btn.addEventListener("click", deauthUser); }); document.querySelectorAll("button[vw-delete-user]").forEach(btn => { btn.addEventListener("click", deleteUser); }); document.querySelectorAll("button[vw-delete-sso-user]").forEach(btn => { btn.addEventListener("click", deleteSSOUser); }); document.querySelectorAll("button[vw-disable-user]").forEach(btn => { btn.addEventListener("click", disableUser); }); document.querySelectorAll("button[vw-enable-user]").forEach(btn => { btn.addEventListener("click", enableUser); }); document.querySelectorAll("button[vw-resend-user-invite]").forEach(btn => { btn.addEventListener("click", resendUserInvite); }); if (jdenticon) { jdenticon(); } } // Special sort function to sort dates in ISO format and have anything else as 0 DataTable.ext.type.order["date-iso-pre"] = function (a) { let x; const sortDate = a.replace(/(<([^>]+)>)/gi, "").trim(); if (sortDate !== "") { const dtParts = sortDate.split(" "); const timeParts = (undefined != dtParts[1]) ? dtParts[1].split(":") : ["00", "00", "00"]; const dateParts = dtParts[0].split("-"); x = (dateParts[0] + dateParts[1] + dateParts[2] + timeParts[0] + timeParts[1] + ((undefined != timeParts[2]) ? timeParts[2] : 0)) * 1; if (isNaN(x)) { x = 0; } } else { x = Infinity; } return x; }; // onLoad events document.addEventListener("DOMContentLoaded", (/*event*/) => { DataTable.ext.type.detect.unshift(function (data) { if (typeof data !== "string") { return null; } return data.indexOf("data-sort-type=\"date-iso\"") !== -1 ? "date-iso" : null; }); const columnCount = document.getElementById("users-table").querySelectorAll("thead th").length; new DataTable("#users-table", { "typeDetect": true, "drawCallback": function () { initUserTable(); }, "stateSave": true, "responsive": true, "lengthMenu": [ [-1, 2, 5, 10, 25, 50], ["All", 2, 5, 10, 25, 50] ], "pageLength": -1, // Default show all "columnDefs": [{ "targets": columnCount - 1, // Do not include the last column into the search/order features "searchable": false, "orderable": false }] }); // Add click events for user actions initUserTable(); const btnUpdateRevisions = document.getElementById("updateRevisions"); if (btnUpdateRevisions) { btnUpdateRevisions.addEventListener("click", updateRevisions); } const btnReload = document.getElementById("reload"); if (btnReload) { btnReload.addEventListener("click", reload); } const btnUserOrgTypeForm = document.getElementById("userOrgTypeForm"); if (btnUserOrgTypeForm) { btnUserOrgTypeForm.addEventListener("submit", updateUserOrgType); } const btnInviteUserForm = document.getElementById("inviteUserForm"); if (btnInviteUserForm) { btnInviteUserForm.addEventListener("submit", inviteUser); } });