mirror of
https://github.com/dani-garcia/vaultwarden.git
synced 2025-09-10 18:55:57 +03:00
- Removed `unsafe-inline` for javascript from CSP. The admin interface now uses files instead of inline javascript. - Modified javascript to work not being inline. - Run eslint over javascript and fixed some items. - Added a `to_json` Handlebars helper. Used at the diagnostics page. - Changed `AdminTemplateData` struct to be smaller. The `config` was always added, but only used at one page. Same goes for `can_backup` and `version`. - Also inlined CSS. We can't remove the `unsafe-inline` from css, because that seems to break the web-vault currently. That might need some further checks. But for now the 404 page and all the admin pages are clear of inline scripts and styles.
246 lines
7.8 KiB
JavaScript
Vendored
246 lines
7.8 KiB
JavaScript
Vendored
"use strict";
|
|
|
|
function deleteUser() {
|
|
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 remove2fa() {
|
|
event.preventDefault();
|
|
event.stopPropagation();
|
|
const id = event.target.parentNode.dataset.vwUserUuid;
|
|
if (!id) {
|
|
alert("Required parameters not found!");
|
|
return false;
|
|
}
|
|
_post(`${BASE_URL}/admin/users/${id}/remove-2fa`,
|
|
"2FA removed correctly",
|
|
"Error removing 2FA"
|
|
);
|
|
}
|
|
|
|
function deauthUser() {
|
|
event.preventDefault();
|
|
event.stopPropagation();
|
|
const id = event.target.parentNode.dataset.vwUserUuid;
|
|
if (!id) {
|
|
alert("Required parameters not found!");
|
|
return false;
|
|
}
|
|
_post(`${BASE_URL}/admin/users/${id}/deauth`,
|
|
"Sessions deauthorized correctly",
|
|
"Error deauthorizing sessions"
|
|
);
|
|
}
|
|
|
|
function disableUser() {
|
|
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.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.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.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
|
|
);
|
|
}
|
|
|
|
const ORG_TYPES = {
|
|
"0": {
|
|
"name": "Owner",
|
|
"color": "orange"
|
|
},
|
|
"1": {
|
|
"name": "Admin",
|
|
"color": "blueviolet"
|
|
},
|
|
"2": {
|
|
"name": "User",
|
|
"color": "blue"
|
|
},
|
|
"3": {
|
|
"name": "Manager",
|
|
"color": "green"
|
|
},
|
|
};
|
|
|
|
// Special sort function to sort dates in ISO format
|
|
jQuery.extend(jQuery.fn.dataTableExt.oSort, {
|
|
"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;
|
|
},
|
|
|
|
"date-iso-asc": function(a, b) {
|
|
return a - b;
|
|
},
|
|
|
|
"date-iso-desc": function(a, b) {
|
|
return b - a;
|
|
}
|
|
});
|
|
|
|
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("userOrgTypeDialogTitle").innerHTML = `<b>Update User Type:</b><br><b>Organization:</b> ${orgName}<br><b>User:</b> ${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("userOrgTypeDialogTitle").innerHTML = "";
|
|
document.getElementById("userOrgTypeUserUuid").value = "";
|
|
document.getElementById("userOrgTypeOrgUuid").value = "";
|
|
}, false);
|
|
|
|
function updateUserOrgType() {
|
|
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
|
|
);
|
|
}
|
|
|
|
// onLoad events
|
|
document.addEventListener("DOMContentLoaded", (/*event*/) => {
|
|
jQuery("#users-table").DataTable({
|
|
"stateSave": true,
|
|
"responsive": true,
|
|
"lengthMenu": [
|
|
[-1, 5, 10, 25, 50],
|
|
["All", 5, 10, 25, 50]
|
|
],
|
|
"pageLength": -1, // Default show all
|
|
"columnDefs": [{
|
|
"targets": [1, 2],
|
|
"type": "date-iso"
|
|
}, {
|
|
"targets": 6,
|
|
"searchable": false,
|
|
"orderable": false
|
|
}]
|
|
});
|
|
|
|
// 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.color;
|
|
e.title = orgType.name;
|
|
});
|
|
|
|
// Add click events for user actions
|
|
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-disable-user]").forEach(btn => {
|
|
btn.addEventListener("click", disableUser);
|
|
});
|
|
document.querySelectorAll("button[vw-enable-user]").forEach(btn => {
|
|
btn.addEventListener("click", enableUser);
|
|
});
|
|
|
|
document.getElementById("updateRevisions").addEventListener("click", updateRevisions);
|
|
document.getElementById("reload").addEventListener("click", reload);
|
|
document.getElementById("userOrgTypeForm").addEventListener("submit", updateUserOrgType);
|
|
document.getElementById("inviteUserForm").addEventListener("submit", inviteUser);
|
|
}); |