Merge pull request #3167 from BlackDex/issue-3166

Fix Javascript issue on non sqlite databases
pull/3210/head^2
Daniel García 2 years ago committed by GitHub
commit 0c295d5e6e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -118,8 +118,8 @@ pub fn static_files(filename: String) -> Result<(ContentType, &'static [u8]), Er
"jdenticon.js" => Ok((ContentType::JavaScript, include_bytes!("../static/scripts/jdenticon.js"))), "jdenticon.js" => Ok((ContentType::JavaScript, include_bytes!("../static/scripts/jdenticon.js"))),
"datatables.js" => Ok((ContentType::JavaScript, include_bytes!("../static/scripts/datatables.js"))), "datatables.js" => Ok((ContentType::JavaScript, include_bytes!("../static/scripts/datatables.js"))),
"datatables.css" => Ok((ContentType::CSS, include_bytes!("../static/scripts/datatables.css"))), "datatables.css" => Ok((ContentType::CSS, include_bytes!("../static/scripts/datatables.css"))),
"jquery-3.6.2.slim.js" => { "jquery-3.6.3.slim.js" => {
Ok((ContentType::JavaScript, include_bytes!("../static/scripts/jquery-3.6.2.slim.js"))) Ok((ContentType::JavaScript, include_bytes!("../static/scripts/jquery-3.6.3.slim.js")))
} }
_ => err!(format!("Static file not found: {filename}")), _ => err!(format!("Static file not found: {filename}")),
} }

@ -18,24 +18,31 @@ img {
border: var(--bs-alert-border); border: var(--bs-alert-border);
} }
#users-table .vw-account-details {
min-width: 250px;
}
#users-table .vw-created-at, #users-table .vw-last-active { #users-table .vw-created-at, #users-table .vw-last-active {
width: 85px; min-width: 85px;
min-width: 70px; max-width: 85px;
} }
#users-table .vw-items { #users-table .vw-items, #orgs-table .vw-items, #orgs-table .vw-users {
width: 35px;
min-width: 35px; min-width: 35px;
max-width: 40px;
} }
#users-table .vw-organizations { #users-table .vw-attachments, #orgs-table .vw-attachments {
min-width: 120px; min-width: 100px;
max-width: 130px;
} }
#users-table .vw-actions, #orgs-table .vw-actions { #users-table .vw-actions, #orgs-table .vw-actions {
width: 130px;
min-width: 130px; min-width: 130px;
max-width: 130px;
} }
#users-table .vw-org-cell { #users-table .vw-org-cell {
max-height: 120px; max-height: 120px;
} }
#orgs-table .vw-org-details {
min-width: 285px;
}
#support-string { #support-string {
height: 16rem; height: 16rem;

@ -1,4 +1,6 @@
"use strict"; "use strict";
/* eslint-env es2017, browser */
/* exported BASE_URL, _post */
function getBaseUrl() { function getBaseUrl() {
// If the base URL is `https://vaultwarden.example.com/base/path/`, // If the base URL is `https://vaultwarden.example.com/base/path/`,
@ -26,6 +28,8 @@ function msg(text, reload_page = true) {
} }
function _post(url, successMsg, errMsg, body, reload_page = true) { function _post(url, successMsg, errMsg, body, reload_page = true) {
let respStatus;
let respStatusText;
fetch(url, { fetch(url, {
method: "POST", method: "POST",
body: body, body: body,
@ -33,22 +37,30 @@ function _post(url, successMsg, errMsg, body, reload_page = true) {
credentials: "same-origin", credentials: "same-origin",
headers: { "Content-Type": "application/json" } headers: { "Content-Type": "application/json" }
}).then( resp => { }).then( resp => {
if (resp.ok) { msg(successMsg, reload_page); return Promise.reject({error: false}); } if (resp.ok) {
const respStatus = resp.status; msg(successMsg, reload_page);
const respStatusText = resp.statusText; // Abuse the catch handler by setting error to false and continue
return Promise.reject({error: false});
}
respStatus = resp.status;
respStatusText = resp.statusText;
return resp.text(); return resp.text();
}).then( respText => { }).then( respText => {
try { try {
const respJson = JSON.parse(respText); const respJson = JSON.parse(respText);
return respJson ? respJson.ErrorModel.Message : "Unknown error"; if (respJson.ErrorModel && respJson.ErrorModel.Message) {
return respJson.ErrorModel.Message;
} else {
return Promise.reject({body:`${respStatus} - ${respStatusText}\n\nUnknown error`, error: true});
}
} catch (e) { } catch (e) {
return Promise.reject({body:respStatus + " - " + respStatusText, error: true}); return Promise.reject({body:`${respStatus} - ${respStatusText}\n\n[Catch] ${e}`, error: true});
} }
}).then( apiMsg => { }).then( apiMsg => {
msg(errMsg + "\n" + apiMsg, reload_page); msg(`${errMsg}\n${apiMsg}`, reload_page);
}).catch( e => { }).catch( e => {
if (e.error === false) { return true; } if (e.error === false) { return true; }
else { msg(errMsg + "\n" + e.body, reload_page); } else { msg(`${errMsg}\n${e.body}`, reload_page); }
}); });
} }

@ -1,4 +1,6 @@
"use strict"; "use strict";
/* eslint-env es2017, browser */
/* global BASE_URL:readable, BSN:readable */
var dnsCheck = false; var dnsCheck = false;
var timeCheck = false; var timeCheck = false;
@ -65,7 +67,7 @@ function checkVersions(platform, installed, latest, commit=null) {
// ================================ // ================================
// Generate support string to be pasted on github or the forum // Generate support string to be pasted on github or the forum
async function generateSupportString(dj) { async function generateSupportString(event, dj) {
event.preventDefault(); event.preventDefault();
event.stopPropagation(); event.stopPropagation();
@ -114,7 +116,7 @@ async function generateSupportString(dj) {
document.getElementById("copy-support").classList.remove("d-none"); document.getElementById("copy-support").classList.remove("d-none");
} }
function copyToClipboard() { function copyToClipboard(event) {
event.preventDefault(); event.preventDefault();
event.stopPropagation(); event.stopPropagation();
@ -208,12 +210,18 @@ function init(dj) {
} }
// onLoad events // onLoad events
document.addEventListener("DOMContentLoaded", (/*event*/) => { document.addEventListener("DOMContentLoaded", (event) => {
const diag_json = JSON.parse(document.getElementById("diagnostics_json").innerText); const diag_json = JSON.parse(document.getElementById("diagnostics_json").innerText);
init(diag_json); init(diag_json);
document.getElementById("gen-support").addEventListener("click", () => { const btnGenSupport = document.getElementById("gen-support");
generateSupportString(diag_json); if (btnGenSupport) {
}); btnGenSupport.addEventListener("click", () => {
document.getElementById("copy-support").addEventListener("click", copyToClipboard); generateSupportString(event, diag_json);
});
}
const btnCopySupport = document.getElementById("copy-support");
if (btnCopySupport) {
btnCopySupport.addEventListener("click", copyToClipboard);
}
}); });

@ -1,6 +1,8 @@
"use strict"; "use strict";
/* eslint-env es2017, browser, jquery */
/* global _post:readable, BASE_URL:readable, reload:readable, jdenticon:readable */
function deleteOrganization() { function deleteOrganization(event) {
event.preventDefault(); event.preventDefault();
event.stopPropagation(); event.stopPropagation();
const org_uuid = event.target.dataset.vwOrgUuid; const org_uuid = event.target.dataset.vwOrgUuid;
@ -28,9 +30,22 @@ function deleteOrganization() {
} }
} }
function initActions() {
document.querySelectorAll("button[vw-delete-organization]").forEach(btn => {
btn.addEventListener("click", deleteOrganization);
});
if (jdenticon) {
jdenticon();
}
}
// onLoad events // onLoad events
document.addEventListener("DOMContentLoaded", (/*event*/) => { document.addEventListener("DOMContentLoaded", (/*event*/) => {
jQuery("#orgs-table").DataTable({ jQuery("#orgs-table").DataTable({
"drawCallback": function() {
initActions();
},
"stateSave": true, "stateSave": true,
"responsive": true, "responsive": true,
"lengthMenu": [ "lengthMenu": [
@ -46,9 +61,10 @@ document.addEventListener("DOMContentLoaded", (/*event*/) => {
}); });
// Add click events for organization actions // Add click events for organization actions
document.querySelectorAll("button[vw-delete-organization]").forEach(btn => { initActions();
btn.addEventListener("click", deleteOrganization);
});
document.getElementById("reload").addEventListener("click", reload); const btnReload = document.getElementById("reload");
if (btnReload) {
btnReload.addEventListener("click", reload);
}
}); });

@ -1,6 +1,8 @@
"use strict"; "use strict";
/* eslint-env es2017, browser */
/* global _post:readable, BASE_URL:readable */
function smtpTest() { function smtpTest(event) {
event.preventDefault(); event.preventDefault();
event.stopPropagation(); event.stopPropagation();
if (formHasChanges(config_form)) { if (formHasChanges(config_form)) {
@ -41,7 +43,7 @@ function getFormData() {
return data; return data;
} }
function saveConfig() { function saveConfig(event) {
const data = JSON.stringify(getFormData()); const data = JSON.stringify(getFormData());
_post(`${BASE_URL}/admin/config/`, _post(`${BASE_URL}/admin/config/`,
"Config saved correctly", "Config saved correctly",
@ -51,7 +53,7 @@ function saveConfig() {
event.preventDefault(); event.preventDefault();
} }
function deleteConf() { function deleteConf(event) {
event.preventDefault(); event.preventDefault();
event.stopPropagation(); event.stopPropagation();
const input = prompt( const input = prompt(
@ -68,7 +70,7 @@ function deleteConf() {
} }
} }
function backupDatabase() { function backupDatabase(event) {
event.preventDefault(); event.preventDefault();
event.stopPropagation(); event.stopPropagation();
_post(`${BASE_URL}/admin/config/backup_db`, _post(`${BASE_URL}/admin/config/backup_db`,
@ -94,24 +96,26 @@ function formHasChanges(form) {
// This function will prevent submitting a from when someone presses enter. // This function will prevent submitting a from when someone presses enter.
function preventFormSubmitOnEnter(form) { function preventFormSubmitOnEnter(form) {
form.onkeypress = function(e) { if (form) {
const key = e.charCode || e.keyCode || 0; form.addEventListener("keypress", (event) => {
if (key == 13) { if (event.key == "Enter") {
e.preventDefault(); event.preventDefault();
} }
}; });
}
} }
// This function will hook into the smtp-test-email input field and will call the smtpTest() function when enter is pressed. // This function will hook into the smtp-test-email input field and will call the smtpTest() function when enter is pressed.
function submitTestEmailOnEnter() { function submitTestEmailOnEnter() {
const smtp_test_email_input = document.getElementById("smtp-test-email"); const smtp_test_email_input = document.getElementById("smtp-test-email");
smtp_test_email_input.onkeypress = function(e) { if (smtp_test_email_input) {
const key = e.charCode || e.keyCode || 0; smtp_test_email_input.addEventListener("keypress", (event) => {
if (key == 13) { if (event.key == "Enter") {
e.preventDefault(); event.preventDefault();
smtpTest(); smtpTest(event);
} }
}; });
}
} }
// Colorize some settings which are high risk // Colorize some settings which are high risk
@ -124,11 +128,11 @@ function colorRiskSettings() {
}); });
} }
function toggleVis(evt) { function toggleVis(event) {
event.preventDefault(); event.preventDefault();
event.stopPropagation(); event.stopPropagation();
const elem = document.getElementById(evt.target.dataset.vwPwToggle); const elem = document.getElementById(event.target.dataset.vwPwToggle);
const type = elem.getAttribute("type"); const type = elem.getAttribute("type");
if (type === "text") { if (type === "text") {
elem.setAttribute("type", "password"); elem.setAttribute("type", "password");
@ -146,9 +150,11 @@ function masterCheck(check_id, inputs_query) {
} }
const checkbox = document.getElementById(check_id); const checkbox = document.getElementById(check_id);
const onChange = onChanged(checkbox, inputs_query); if (checkbox) {
onChange(); // Trigger the event initially const onChange = onChanged(checkbox, inputs_query);
checkbox.addEventListener("change", onChange); onChange(); // Trigger the event initially
checkbox.addEventListener("change", onChange);
}
} }
const config_form = document.getElementById("config-form"); const config_form = document.getElementById("config-form");
@ -172,9 +178,18 @@ document.addEventListener("DOMContentLoaded", (/*event*/) => {
password_toggle_btn.addEventListener("click", toggleVis); password_toggle_btn.addEventListener("click", toggleVis);
}); });
document.getElementById("backupDatabase").addEventListener("click", backupDatabase); const btnBackupDatabase = document.getElementById("backupDatabase");
document.getElementById("deleteConf").addEventListener("click", deleteConf); if (btnBackupDatabase) {
document.getElementById("smtpTest").addEventListener("click", smtpTest); btnBackupDatabase.addEventListener("click", backupDatabase);
}
const btnDeleteConf = document.getElementById("deleteConf");
if (btnDeleteConf) {
btnDeleteConf.addEventListener("click", deleteConf);
}
const btnSmtpTest = document.getElementById("smtpTest");
if (btnSmtpTest) {
btnSmtpTest.addEventListener("click", smtpTest);
}
config_form.addEventListener("submit", saveConfig); config_form.addEventListener("submit", saveConfig);
}); });

@ -1,6 +1,8 @@
"use strict"; "use strict";
/* eslint-env es2017, browser, jquery */
/* global _post:readable, BASE_URL:readable, reload:readable, jdenticon:readable */
function deleteUser() { function deleteUser(event) {
event.preventDefault(); event.preventDefault();
event.stopPropagation(); event.stopPropagation();
const id = event.target.parentNode.dataset.vwUserUuid; const id = event.target.parentNode.dataset.vwUserUuid;
@ -22,7 +24,7 @@ function deleteUser() {
} }
} }
function remove2fa() { function remove2fa(event) {
event.preventDefault(); event.preventDefault();
event.stopPropagation(); event.stopPropagation();
const id = event.target.parentNode.dataset.vwUserUuid; const id = event.target.parentNode.dataset.vwUserUuid;
@ -36,7 +38,7 @@ function remove2fa() {
); );
} }
function deauthUser() { function deauthUser(event) {
event.preventDefault(); event.preventDefault();
event.stopPropagation(); event.stopPropagation();
const id = event.target.parentNode.dataset.vwUserUuid; const id = event.target.parentNode.dataset.vwUserUuid;
@ -50,7 +52,7 @@ function deauthUser() {
); );
} }
function disableUser() { function disableUser(event) {
event.preventDefault(); event.preventDefault();
event.stopPropagation(); event.stopPropagation();
const id = event.target.parentNode.dataset.vwUserUuid; const id = event.target.parentNode.dataset.vwUserUuid;
@ -68,7 +70,7 @@ function disableUser() {
} }
} }
function enableUser() { function enableUser(event) {
event.preventDefault(); event.preventDefault();
event.stopPropagation(); event.stopPropagation();
const id = event.target.parentNode.dataset.vwUserUuid; const id = event.target.parentNode.dataset.vwUserUuid;
@ -86,7 +88,7 @@ function enableUser() {
} }
} }
function updateRevisions() { function updateRevisions(event) {
event.preventDefault(); event.preventDefault();
event.stopPropagation(); event.stopPropagation();
_post(`${BASE_URL}/admin/users/update_revision`, _post(`${BASE_URL}/admin/users/update_revision`,
@ -95,7 +97,7 @@ function updateRevisions() {
); );
} }
function inviteUser() { function inviteUser(event) {
event.preventDefault(); event.preventDefault();
event.stopPropagation(); event.stopPropagation();
const email = document.getElementById("inviteEmail"); const email = document.getElementById("inviteEmail");
@ -182,7 +184,7 @@ userOrgTypeDialog.addEventListener("hide.bs.modal", function() {
document.getElementById("userOrgTypeOrgUuid").value = ""; document.getElementById("userOrgTypeOrgUuid").value = "";
}, false); }, false);
function updateUserOrgType() { function updateUserOrgType(event) {
event.preventDefault(); event.preventDefault();
event.stopPropagation(); event.stopPropagation();
@ -195,26 +197,7 @@ function updateUserOrgType() {
); );
} }
// onLoad events function initUserTable() {
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 // Color all the org buttons per type
document.querySelectorAll("button[data-vw-org-type]").forEach(function(e) { document.querySelectorAll("button[data-vw-org-type]").forEach(function(e) {
const orgType = ORG_TYPES[e.dataset.vwOrgType]; const orgType = ORG_TYPES[e.dataset.vwOrgType];
@ -222,7 +205,6 @@ document.addEventListener("DOMContentLoaded", (/*event*/) => {
e.title = orgType.name; e.title = orgType.name;
}); });
// Add click events for user actions
document.querySelectorAll("button[vw-remove2fa]").forEach(btn => { document.querySelectorAll("button[vw-remove2fa]").forEach(btn => {
btn.addEventListener("click", remove2fa); btn.addEventListener("click", remove2fa);
}); });
@ -239,8 +221,51 @@ document.addEventListener("DOMContentLoaded", (/*event*/) => {
btn.addEventListener("click", enableUser); btn.addEventListener("click", enableUser);
}); });
document.getElementById("updateRevisions").addEventListener("click", updateRevisions); if (jdenticon) {
document.getElementById("reload").addEventListener("click", reload); jdenticon();
document.getElementById("userOrgTypeForm").addEventListener("submit", updateUserOrgType); }
document.getElementById("inviteUserForm").addEventListener("submit", inviteUser); }
// onLoad events
document.addEventListener("DOMContentLoaded", (/*event*/) => {
jQuery("#users-table").DataTable({
"drawCallback": function() {
initUserTable();
},
"stateSave": true,
"responsive": true,
"lengthMenu": [
[-1, 2, 5, 10, 25, 50],
["All", 2, 5, 10, 25, 50]
],
"pageLength": 2, // Default show all
"columnDefs": [{
"targets": [1, 2],
"type": "date-iso"
}, {
"targets": 6,
"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);
}
}); });

@ -1,5 +1,5 @@
/*! /*!
* jQuery JavaScript Library v3.6.2 -ajax,-ajax/jsonp,-ajax/load,-ajax/script,-ajax/var/location,-ajax/var/nonce,-ajax/var/rquery,-ajax/xhr,-manipulation/_evalUrl,-deprecated/ajax-event-alias,-effects,-effects/Tween,-effects/animatedSelector * jQuery JavaScript Library v3.6.3 -ajax,-ajax/jsonp,-ajax/load,-ajax/script,-ajax/var/location,-ajax/var/nonce,-ajax/var/rquery,-ajax/xhr,-manipulation/_evalUrl,-deprecated/ajax-event-alias,-effects,-effects/Tween,-effects/animatedSelector
* https://jquery.com/ * https://jquery.com/
* *
* Includes Sizzle.js * Includes Sizzle.js
@ -9,7 +9,7 @@
* Released under the MIT license * Released under the MIT license
* https://jquery.org/license * https://jquery.org/license
* *
* Date: 2022-12-13T14:56Z * Date: 2022-12-20T21:28Z
*/ */
( function( global, factory ) { ( function( global, factory ) {
@ -151,7 +151,7 @@ function toType( obj ) {
var var
version = "3.6.2 -ajax,-ajax/jsonp,-ajax/load,-ajax/script,-ajax/var/location,-ajax/var/nonce,-ajax/var/rquery,-ajax/xhr,-manipulation/_evalUrl,-deprecated/ajax-event-alias,-effects,-effects/Tween,-effects/animatedSelector", version = "3.6.3 -ajax,-ajax/jsonp,-ajax/load,-ajax/script,-ajax/var/location,-ajax/var/nonce,-ajax/var/rquery,-ajax/xhr,-manipulation/_evalUrl,-deprecated/ajax-event-alias,-effects,-effects/Tween,-effects/animatedSelector",
// Define a local copy of jQuery // Define a local copy of jQuery
jQuery = function( selector, context ) { jQuery = function( selector, context ) {
@ -522,14 +522,14 @@ function isArrayLike( obj ) {
} }
var Sizzle = var Sizzle =
/*! /*!
* Sizzle CSS Selector Engine v2.3.8 * Sizzle CSS Selector Engine v2.3.9
* https://sizzlejs.com/ * https://sizzlejs.com/
* *
* Copyright JS Foundation and other contributors * Copyright JS Foundation and other contributors
* Released under the MIT license * Released under the MIT license
* https://js.foundation/ * https://js.foundation/
* *
* Date: 2022-11-16 * Date: 2022-12-19
*/ */
( function( window ) { ( function( window ) {
var i, var i,
@ -890,7 +890,7 @@ function Sizzle( selector, context, results, seed ) {
if ( support.cssSupportsSelector && if ( support.cssSupportsSelector &&
// eslint-disable-next-line no-undef // eslint-disable-next-line no-undef
!CSS.supports( "selector(" + newSelector + ")" ) ) { !CSS.supports( "selector(:is(" + newSelector + "))" ) ) {
// Support: IE 11+ // Support: IE 11+
// Throw to get to the same code path as an error directly in qSA. // Throw to get to the same code path as an error directly in qSA.
@ -1492,9 +1492,8 @@ setDocument = Sizzle.setDocument = function( node ) {
// `:has()` uses a forgiving selector list as an argument so our regular // `:has()` uses a forgiving selector list as an argument so our regular
// `try-catch` mechanism fails to catch `:has()` with arguments not supported // `try-catch` mechanism fails to catch `:has()` with arguments not supported
// natively like `:has(:contains("Foo"))`. Where supported & spec-compliant, // natively like `:has(:contains("Foo"))`. Where supported & spec-compliant,
// we now use `CSS.supports("selector(SELECTOR_TO_BE_TESTED)")` but outside // we now use `CSS.supports("selector(:is(SELECTOR_TO_BE_TESTED))")`, but
// that, let's mark `:has` as buggy to always use jQuery traversal for // outside that we mark `:has` as buggy.
// `:has()`.
rbuggyQSA.push( ":has" ); rbuggyQSA.push( ":has" );
} }

@ -5,10 +5,10 @@
<table id="orgs-table" class="table table-sm table-striped table-hover"> <table id="orgs-table" class="table table-sm table-striped table-hover">
<thead> <thead>
<tr> <tr>
<th>Organization</th> <th class="vw-org-details">Organization</th>
<th>Users</th> <th class="vw-users">Users</th>
<th>Items</th> <th class="vw-items">Items</th>
<th>Attachments</th> <th class="vw-attachments">Attachments</th>
<th class="vw-actions">Actions</th> <th class="vw-actions">Actions</th>
</tr> </tr>
</thead> </thead>
@ -38,7 +38,7 @@
{{/if}} {{/if}}
</td> </td>
<td class="text-end px-0 small"> <td class="text-end px-0 small">
<button type="button" class="btn btn-sm btn-link p-0 border-0" vw-delete-organization data-vw-org-uuid="{{jsesc Id no_quote}}" data-vw-org-name="{{jsesc Name no_quote}}" data-vw-billing-email="{{jsesc BillingEmail no_quote}}">Delete Organization</button> <button type="button" class="btn btn-sm btn-link p-0 border-0 float-right" vw-delete-organization data-vw-org-uuid="{{jsesc Id no_quote}}" data-vw-org-name="{{jsesc Name no_quote}}" data-vw-billing-email="{{jsesc BillingEmail no_quote}}">Delete Organization</button>
</td> </td>
</tr> </tr>
{{/each}} {{/each}}
@ -53,7 +53,7 @@
</main> </main>
<link rel="stylesheet" href="{{urlpath}}/vw_static/datatables.css" /> <link rel="stylesheet" href="{{urlpath}}/vw_static/datatables.css" />
<script src="{{urlpath}}/vw_static/jquery-3.6.2.slim.js"></script> <script src="{{urlpath}}/vw_static/jquery-3.6.3.slim.js"></script>
<script src="{{urlpath}}/vw_static/datatables.js"></script> <script src="{{urlpath}}/vw_static/datatables.js"></script>
<script src="{{urlpath}}/vw_static/admin_organizations.js"></script> <script src="{{urlpath}}/vw_static/admin_organizations.js"></script>
<script src="{{urlpath}}/vw_static/jdenticon.js"></script> <script src="{{urlpath}}/vw_static/jdenticon.js"></script>

@ -5,7 +5,7 @@
<table id="users-table" class="table table-sm table-striped table-hover"> <table id="users-table" class="table table-sm table-striped table-hover">
<thead> <thead>
<tr> <tr>
<th>User</th> <th class="vw-account-details">User</th>
<th class="vw-created-at">Created at</th> <th class="vw-created-at">Created at</th>
<th class="vw-last-active">Last Active</th> <th class="vw-last-active">Last Active</th>
<th class="vw-items">Items</th> <th class="vw-items">Items</th>
@ -63,14 +63,14 @@
<td class="text-end px-0 small"> <td class="text-end px-0 small">
<span data-vw-user-uuid="{{jsesc Id no_quote}}" data-vw-user-email="{{jsesc Email no_quote}}"> <span data-vw-user-uuid="{{jsesc Id no_quote}}" data-vw-user-email="{{jsesc Email no_quote}}">
{{#if TwoFactorEnabled}} {{#if TwoFactorEnabled}}
<button type="button" class="btn btn-sm btn-link p-0 border-0" vw-remove2fa>Remove all 2FA</button> <button type="button" class="btn btn-sm btn-link p-0 border-0 float-right" vw-remove2fa>Remove all 2FA</button>
{{/if}} {{/if}}
<button type="button" class="btn btn-sm btn-link p-0 border-0" vw-deauth-user>Deauthorize sessions</button> <button type="button" class="btn btn-sm btn-link p-0 border-0 float-right" vw-deauth-user>Deauthorize sessions</button>
<button type="button" class="btn btn-sm btn-link p-0 border-0" vw-delete-user>Delete User</button> <button type="button" class="btn btn-sm btn-link p-0 border-0 float-right" vw-delete-user>Delete User</button>
{{#if user_enabled}} {{#if user_enabled}}
<button type="button" class="btn btn-sm btn-link p-0 border-0" vw-disable-user>Disable User</button> <button type="button" class="btn btn-sm btn-link p-0 border-0 float-right" vw-disable-user>Disable User</button>
{{else}} {{else}}
<button type="button" class="btn btn-sm btn-link p-0 border-0" vw-enable-user>Enable User</button> <button type="button" class="btn btn-sm btn-link p-0 border-0 float-right" vw-enable-user>Enable User</button>
{{/if}} {{/if}}
</span> </span>
</td> </td>
@ -137,7 +137,7 @@
</main> </main>
<link rel="stylesheet" href="{{urlpath}}/vw_static/datatables.css" /> <link rel="stylesheet" href="{{urlpath}}/vw_static/datatables.css" />
<script src="{{urlpath}}/vw_static/jquery-3.6.2.slim.js"></script> <script src="{{urlpath}}/vw_static/jquery-3.6.3.slim.js"></script>
<script src="{{urlpath}}/vw_static/datatables.js"></script> <script src="{{urlpath}}/vw_static/datatables.js"></script>
<script src="{{urlpath}}/vw_static/admin_users.js"></script> <script src="{{urlpath}}/vw_static/admin_users.js"></script>
<script src="{{urlpath}}/vw_static/jdenticon.js"></script> <script src="{{urlpath}}/vw_static/jdenticon.js"></script>

Loading…
Cancel
Save