mirror of
https://github.com/getnamingo/registry.git
synced 2025-05-30 01:10:09 +02:00
UI improvements, contact windows, fixed #196
This commit is contained in:
parent
5ac0e9f1fa
commit
184322e2d2
6 changed files with 493 additions and 360 deletions
|
@ -266,4 +266,30 @@ class ProfileController extends Controller
|
|||
Auth::logoutEverywhereElse();
|
||||
}
|
||||
|
||||
public function tokenWell(Request $request, Response $response)
|
||||
{
|
||||
global $container;
|
||||
$csrf = $container->get('csrf');
|
||||
|
||||
// Get CSRF token name and value
|
||||
$csrfTokenName = $csrf->getTokenName();
|
||||
$csrfTokenValue = $csrf->getTokenValue();
|
||||
|
||||
// Check if tokens exist
|
||||
if (!$csrfTokenName || !$csrfTokenValue) {
|
||||
$errorResponse = json_encode(['error' => 'CSRF tokens not found']);
|
||||
$response->getBody()->write($errorResponse);
|
||||
return $response->withHeader('Content-Type', 'application/json')->withStatus(400);
|
||||
}
|
||||
|
||||
// Create JSON response in the expected format
|
||||
$csrfResponse = json_encode([
|
||||
$csrfTokenName => $csrfTokenValue
|
||||
]);
|
||||
|
||||
// Write response body and return with JSON header
|
||||
$response->getBody()->write($csrfResponse);
|
||||
return $response->withHeader('Content-Type', 'application/json')->withStatus(200);
|
||||
}
|
||||
|
||||
}
|
|
@ -302,6 +302,10 @@ $csrfMiddleware = function ($request, $handler) use ($container) {
|
|||
if ($path && $path === '/clear-cache') {
|
||||
return $handler->handle($request);
|
||||
}
|
||||
if ($path && $path === '/token-well') {
|
||||
$csrf->generateToken();
|
||||
return $handler->handle($request);
|
||||
}
|
||||
|
||||
// If not skipped, apply the CSRF Guard
|
||||
return $csrf->process($request, $handler);
|
||||
|
|
|
@ -491,21 +491,17 @@
|
|||
<link href="/assets/css/tabulator.min.css" rel="stylesheet">
|
||||
<script src="/assets/js/tabulator.min.js" defer></script>
|
||||
<script>
|
||||
document.getElementById("cancelButton").addEventListener("click", function () {
|
||||
location.reload();
|
||||
});
|
||||
let addContactTargetInputId = null;
|
||||
|
||||
let addContactTargetInputId = null;
|
||||
|
||||
// Capture the target input when opening "Add Contact" modal
|
||||
document.addEventListener("click", function (e) {
|
||||
// Capture the target input when opening "Add Contact" modal
|
||||
document.addEventListener("click", function (e) {
|
||||
let openBtn = e.target.closest('.open-add-modal');
|
||||
if (openBtn) {
|
||||
addContactTargetInputId = openBtn.getAttribute('data-input');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
document.getElementById("addContactForm").addEventListener("submit", function (e) {
|
||||
document.getElementById("addContactForm").addEventListener("submit", function (e) {
|
||||
e.preventDefault(); // Prevent full-page reload
|
||||
|
||||
let form = this;
|
||||
|
@ -562,6 +558,8 @@ document.getElementById("addContactForm").addEventListener("submit", function (e
|
|||
console.error("❌ Error adding contact:", error.message);
|
||||
showErrorMessage(error.message);
|
||||
|
||||
refreshCsrfToken();
|
||||
|
||||
// ❌ Prevent modal from closing on error
|
||||
let modalElement = document.getElementById("addContactModal");
|
||||
let modalInstance = bootstrap.Modal.getInstance(modalElement);
|
||||
|
@ -569,10 +567,10 @@ document.getElementById("addContactForm").addEventListener("submit", function (e
|
|||
modalInstance._isShown = true; // Keep modal open
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// Function to show error messages inside the modal
|
||||
function showErrorMessage(message) {
|
||||
// Function to show error messages inside the modal
|
||||
function showErrorMessage(message) {
|
||||
let errorContainer = document.getElementById("addContactError");
|
||||
let submitButton = document.querySelector("#addContactModal button[type='submit']");
|
||||
|
||||
|
@ -593,11 +591,7 @@ function showErrorMessage(message) {
|
|||
modalBody.scrollTop = 0;
|
||||
}
|
||||
|
||||
// 🔹 Disable submit button on error
|
||||
if (submitButton) {
|
||||
submitButton.disabled = true;
|
||||
}
|
||||
}
|
||||
|
||||
let targetInputId = null;
|
||||
|
||||
|
@ -638,29 +632,6 @@ function showErrorMessage(message) {
|
|||
targetInputId = null;
|
||||
});
|
||||
|
||||
var table;
|
||||
|
||||
document.addEventListener("DOMContentLoaded", function(){
|
||||
|
||||
const toggleLocCheckbox = document.getElementById('toggleLoc');
|
||||
const localizedSection = document.getElementById('localizedInfo');
|
||||
|
||||
toggleLocCheckbox.addEventListener('change', function() {
|
||||
if (toggleLocCheckbox.checked) {
|
||||
localizedSection.style.display = "flex";
|
||||
} else {
|
||||
localizedSection.style.display = "none";
|
||||
}
|
||||
});
|
||||
|
||||
// Generate ID for Contact
|
||||
const contactidInput = document.getElementById('contactid');
|
||||
contactidInput.value = generateAuthInfoC();
|
||||
|
||||
// Generate authInfo for Contact
|
||||
const authInfoInput = document.getElementById('authInfoc');
|
||||
authInfoInput.value = generateAuthInfoC();
|
||||
|
||||
function generateAuthInfoC() {
|
||||
const length = 16;
|
||||
const charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
|
||||
|
@ -691,6 +662,69 @@ function showErrorMessage(message) {
|
|||
return retVal;
|
||||
}
|
||||
|
||||
async function refreshCsrfToken() {
|
||||
try {
|
||||
let response = await fetch('/token-well', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Accept': 'application/json',
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify({})
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
console.error("Failed to fetch CSRF token:", response.status);
|
||||
return;
|
||||
}
|
||||
|
||||
let data = await response.json();
|
||||
let csrfNameField = document.querySelector('#addContactModal input[name="csrf_name"]');
|
||||
let csrfValueField = document.querySelector('#addContactModal input[name="csrf_value"]');
|
||||
|
||||
if (csrfNameField && csrfValueField) {
|
||||
csrfNameField.value = Object.keys(data)[0]; // Set the token name
|
||||
csrfValueField.value = Object.values(data)[0]; // Set the token value
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Error refreshing CSRF token:", error);
|
||||
}
|
||||
}
|
||||
|
||||
document.getElementById("addContactModal").addEventListener("show.bs.modal", function () {
|
||||
document.getElementById('contactid').value = generateAuthInfoC();
|
||||
document.getElementById('authInfoc').value = generateAuthInfoC();
|
||||
});
|
||||
|
||||
var table;
|
||||
|
||||
document.addEventListener("DOMContentLoaded", function(){
|
||||
|
||||
// Only refresh CSRF token when opening the "Add Contact" modal
|
||||
let addContactModal = document.getElementById("addContactModal");
|
||||
if (addContactModal) {
|
||||
addContactModal.addEventListener("show.bs.modal", refreshCsrfToken);
|
||||
}
|
||||
|
||||
const toggleLocCheckbox = document.getElementById('toggleLoc');
|
||||
const localizedSection = document.getElementById('localizedInfo');
|
||||
|
||||
toggleLocCheckbox.addEventListener('change', function() {
|
||||
if (toggleLocCheckbox.checked) {
|
||||
localizedSection.style.display = "flex";
|
||||
} else {
|
||||
localizedSection.style.display = "none";
|
||||
}
|
||||
});
|
||||
|
||||
// Generate ID for Contact
|
||||
const contactidInput = document.getElementById('contactid');
|
||||
contactidInput.value = generateAuthInfoC();
|
||||
|
||||
// Generate authInfo for Contact
|
||||
const authInfoInput = document.getElementById('authInfoc');
|
||||
authInfoInput.value = generateAuthInfoC();
|
||||
|
||||
function contactLinkFormatter(cell){
|
||||
var value = cell.getValue();
|
||||
return `<a href="/contact/view/${value}" style="font-weight:bold;">${value}</a>`;
|
||||
|
|
|
@ -615,21 +615,17 @@
|
|||
<link href="/assets/css/tabulator.min.css" rel="stylesheet">
|
||||
<script src="/assets/js/tabulator.min.js" defer></script>
|
||||
<script>
|
||||
document.getElementById("cancelButton").addEventListener("click", function () {
|
||||
location.reload();
|
||||
});
|
||||
let addContactTargetInputId = null;
|
||||
|
||||
let addContactTargetInputId = null;
|
||||
|
||||
// Capture the target input when opening "Add Contact" modal
|
||||
document.addEventListener("click", function (e) {
|
||||
// Capture the target input when opening "Add Contact" modal
|
||||
document.addEventListener("click", function (e) {
|
||||
let openBtn = e.target.closest('.open-add-modal');
|
||||
if (openBtn) {
|
||||
addContactTargetInputId = openBtn.getAttribute('data-input');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
document.getElementById("addContactForm").addEventListener("submit", function (e) {
|
||||
document.getElementById("addContactForm").addEventListener("submit", function (e) {
|
||||
e.preventDefault(); // Prevent full-page reload
|
||||
|
||||
let form = this;
|
||||
|
@ -686,6 +682,8 @@ document.getElementById("addContactForm").addEventListener("submit", function (e
|
|||
console.error("❌ Error adding contact:", error.message);
|
||||
showErrorMessage(error.message);
|
||||
|
||||
refreshCsrfToken();
|
||||
|
||||
// ❌ Prevent modal from closing on error
|
||||
let modalElement = document.getElementById("addContactModal");
|
||||
let modalInstance = bootstrap.Modal.getInstance(modalElement);
|
||||
|
@ -693,10 +691,10 @@ document.getElementById("addContactForm").addEventListener("submit", function (e
|
|||
modalInstance._isShown = true; // Keep modal open
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// Function to show error messages inside the modal
|
||||
function showErrorMessage(message) {
|
||||
// Function to show error messages inside the modal
|
||||
function showErrorMessage(message) {
|
||||
let errorContainer = document.getElementById("addContactError");
|
||||
let submitButton = document.querySelector("#addContactModal button[type='submit']");
|
||||
|
||||
|
@ -717,11 +715,7 @@ function showErrorMessage(message) {
|
|||
modalBody.scrollTop = 0;
|
||||
}
|
||||
|
||||
// 🔹 Disable submit button on error
|
||||
if (submitButton) {
|
||||
submitButton.disabled = true;
|
||||
}
|
||||
}
|
||||
|
||||
let targetInputId = null;
|
||||
|
||||
|
@ -762,29 +756,6 @@ function showErrorMessage(message) {
|
|||
targetInputId = null;
|
||||
});
|
||||
|
||||
var table;
|
||||
|
||||
document.addEventListener("DOMContentLoaded", function(){
|
||||
|
||||
const toggleLocCheckbox = document.getElementById('toggleLoc');
|
||||
const localizedSection = document.getElementById('localizedInfo');
|
||||
|
||||
toggleLocCheckbox.addEventListener('change', function() {
|
||||
if (toggleLocCheckbox.checked) {
|
||||
localizedSection.style.display = "flex";
|
||||
} else {
|
||||
localizedSection.style.display = "none";
|
||||
}
|
||||
});
|
||||
|
||||
// Generate ID for Contact
|
||||
const contactidInput = document.getElementById('contactid');
|
||||
contactidInput.value = generateAuthInfoC();
|
||||
|
||||
// Generate authInfo for Contact
|
||||
const authInfoInput = document.getElementById('authInfoc');
|
||||
authInfoInput.value = generateAuthInfoC();
|
||||
|
||||
function generateAuthInfoC() {
|
||||
const length = 16;
|
||||
const charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
|
||||
|
@ -815,6 +786,69 @@ function showErrorMessage(message) {
|
|||
return retVal;
|
||||
}
|
||||
|
||||
async function refreshCsrfToken() {
|
||||
try {
|
||||
let response = await fetch('/token-well', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Accept': 'application/json',
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify({})
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
console.error("Failed to fetch CSRF token:", response.status);
|
||||
return;
|
||||
}
|
||||
|
||||
let data = await response.json();
|
||||
let csrfNameField = document.querySelector('#addContactModal input[name="csrf_name"]');
|
||||
let csrfValueField = document.querySelector('#addContactModal input[name="csrf_value"]');
|
||||
|
||||
if (csrfNameField && csrfValueField) {
|
||||
csrfNameField.value = Object.keys(data)[0]; // Set the token name
|
||||
csrfValueField.value = Object.values(data)[0]; // Set the token value
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Error refreshing CSRF token:", error);
|
||||
}
|
||||
}
|
||||
|
||||
document.getElementById("addContactModal").addEventListener("show.bs.modal", function () {
|
||||
document.getElementById('contactid').value = generateAuthInfoC();
|
||||
document.getElementById('authInfoc').value = generateAuthInfoC();
|
||||
});
|
||||
|
||||
var table;
|
||||
|
||||
document.addEventListener("DOMContentLoaded", function(){
|
||||
|
||||
// Only refresh CSRF token when opening the "Add Contact" modal
|
||||
let addContactModal = document.getElementById("addContactModal");
|
||||
if (addContactModal) {
|
||||
addContactModal.addEventListener("show.bs.modal", refreshCsrfToken);
|
||||
}
|
||||
|
||||
const toggleLocCheckbox = document.getElementById('toggleLoc');
|
||||
const localizedSection = document.getElementById('localizedInfo');
|
||||
|
||||
toggleLocCheckbox.addEventListener('change', function() {
|
||||
if (toggleLocCheckbox.checked) {
|
||||
localizedSection.style.display = "flex";
|
||||
} else {
|
||||
localizedSection.style.display = "none";
|
||||
}
|
||||
});
|
||||
|
||||
// Generate ID for Contact
|
||||
const contactidInput = document.getElementById('contactid');
|
||||
contactidInput.value = generateAuthInfoC();
|
||||
|
||||
// Generate authInfo for Contact
|
||||
const authInfoInput = document.getElementById('authInfoc');
|
||||
authInfoInput.value = generateAuthInfoC();
|
||||
|
||||
function contactLinkFormatter(cell){
|
||||
var value = cell.getValue();
|
||||
return `<a href="/contact/view/${value}" style="font-weight:bold;">${value}</a>`;
|
||||
|
|
|
@ -643,21 +643,17 @@
|
|||
<link href="/assets/css/tabulator.min.css" rel="stylesheet">
|
||||
<script src="/assets/js/tabulator.min.js" defer></script>
|
||||
<script>
|
||||
document.getElementById("cancelButton").addEventListener("click", function () {
|
||||
location.reload();
|
||||
});
|
||||
let addContactTargetInputId = null;
|
||||
|
||||
let addContactTargetInputId = null;
|
||||
|
||||
// Capture the target input when opening "Add Contact" modal
|
||||
document.addEventListener("click", function (e) {
|
||||
// Capture the target input when opening "Add Contact" modal
|
||||
document.addEventListener("click", function (e) {
|
||||
let openBtn = e.target.closest('.open-add-modal');
|
||||
if (openBtn) {
|
||||
addContactTargetInputId = openBtn.getAttribute('data-input');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
document.getElementById("addContactForm").addEventListener("submit", function (e) {
|
||||
document.getElementById("addContactForm").addEventListener("submit", function (e) {
|
||||
e.preventDefault(); // Prevent full-page reload
|
||||
|
||||
let form = this;
|
||||
|
@ -714,6 +710,8 @@ document.getElementById("addContactForm").addEventListener("submit", function (e
|
|||
console.error("❌ Error adding contact:", error.message);
|
||||
showErrorMessage(error.message);
|
||||
|
||||
refreshCsrfToken();
|
||||
|
||||
// ❌ Prevent modal from closing on error
|
||||
let modalElement = document.getElementById("addContactModal");
|
||||
let modalInstance = bootstrap.Modal.getInstance(modalElement);
|
||||
|
@ -721,10 +719,10 @@ document.getElementById("addContactForm").addEventListener("submit", function (e
|
|||
modalInstance._isShown = true; // Keep modal open
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// Function to show error messages inside the modal
|
||||
function showErrorMessage(message) {
|
||||
// Function to show error messages inside the modal
|
||||
function showErrorMessage(message) {
|
||||
let errorContainer = document.getElementById("addContactError");
|
||||
let submitButton = document.querySelector("#addContactModal button[type='submit']");
|
||||
|
||||
|
@ -745,11 +743,7 @@ function showErrorMessage(message) {
|
|||
modalBody.scrollTop = 0;
|
||||
}
|
||||
|
||||
// 🔹 Disable submit button on error
|
||||
if (submitButton) {
|
||||
submitButton.disabled = true;
|
||||
}
|
||||
}
|
||||
|
||||
let targetInputId = null;
|
||||
|
||||
|
@ -790,29 +784,6 @@ function showErrorMessage(message) {
|
|||
targetInputId = null;
|
||||
});
|
||||
|
||||
var table;
|
||||
|
||||
document.addEventListener("DOMContentLoaded", function(){
|
||||
|
||||
const toggleLocCheckbox = document.getElementById('toggleLoc');
|
||||
const localizedSection = document.getElementById('localizedInfo');
|
||||
|
||||
toggleLocCheckbox.addEventListener('change', function() {
|
||||
if (toggleLocCheckbox.checked) {
|
||||
localizedSection.style.display = "flex";
|
||||
} else {
|
||||
localizedSection.style.display = "none";
|
||||
}
|
||||
});
|
||||
|
||||
// Generate ID for Contact
|
||||
const contactidInput = document.getElementById('contactid');
|
||||
contactidInput.value = generateAuthInfoC();
|
||||
|
||||
// Generate authInfo for Contact
|
||||
const authInfoInput = document.getElementById('authInfoc');
|
||||
authInfoInput.value = generateAuthInfoC();
|
||||
|
||||
function generateAuthInfoC() {
|
||||
const length = 16;
|
||||
const charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
|
||||
|
@ -843,6 +814,69 @@ function showErrorMessage(message) {
|
|||
return retVal;
|
||||
}
|
||||
|
||||
async function refreshCsrfToken() {
|
||||
try {
|
||||
let response = await fetch('/token-well', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Accept': 'application/json',
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify({})
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
console.error("Failed to fetch CSRF token:", response.status);
|
||||
return;
|
||||
}
|
||||
|
||||
let data = await response.json();
|
||||
let csrfNameField = document.querySelector('#addContactModal input[name="csrf_name"]');
|
||||
let csrfValueField = document.querySelector('#addContactModal input[name="csrf_value"]');
|
||||
|
||||
if (csrfNameField && csrfValueField) {
|
||||
csrfNameField.value = Object.keys(data)[0]; // Set the token name
|
||||
csrfValueField.value = Object.values(data)[0]; // Set the token value
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Error refreshing CSRF token:", error);
|
||||
}
|
||||
}
|
||||
|
||||
document.getElementById("addContactModal").addEventListener("show.bs.modal", function () {
|
||||
document.getElementById('contactid').value = generateAuthInfoC();
|
||||
document.getElementById('authInfoc').value = generateAuthInfoC();
|
||||
});
|
||||
|
||||
var table;
|
||||
|
||||
document.addEventListener("DOMContentLoaded", function(){
|
||||
|
||||
// Only refresh CSRF token when opening the "Add Contact" modal
|
||||
let addContactModal = document.getElementById("addContactModal");
|
||||
if (addContactModal) {
|
||||
addContactModal.addEventListener("show.bs.modal", refreshCsrfToken);
|
||||
}
|
||||
|
||||
const toggleLocCheckbox = document.getElementById('toggleLoc');
|
||||
const localizedSection = document.getElementById('localizedInfo');
|
||||
|
||||
toggleLocCheckbox.addEventListener('change', function() {
|
||||
if (toggleLocCheckbox.checked) {
|
||||
localizedSection.style.display = "flex";
|
||||
} else {
|
||||
localizedSection.style.display = "none";
|
||||
}
|
||||
});
|
||||
|
||||
// Generate ID for Contact
|
||||
const contactidInput = document.getElementById('contactid');
|
||||
contactidInput.value = generateAuthInfoC();
|
||||
|
||||
// Generate authInfo for Contact
|
||||
const authInfoInput = document.getElementById('authInfoc');
|
||||
authInfoInput.value = generateAuthInfoC();
|
||||
|
||||
function contactLinkFormatter(cell){
|
||||
var value = cell.getValue();
|
||||
return `<a href="/contact/view/${value}" style="font-weight:bold;">${value}</a>`;
|
||||
|
|
|
@ -155,6 +155,7 @@ $app->group('', function ($route) {
|
|||
$route->post('/profile/logout-everywhere', ProfileController::class . ':logoutEverywhereElse')->setName('profile.logout.everywhere');
|
||||
$route->get('/webauthn/register/challenge', ProfileController::class . ':getRegistrationChallenge')->setName('webauthn.register.challenge');
|
||||
$route->post('/webauthn/register/verify', ProfileController::class . ':verifyRegistration')->setName('webauthn.register.verify');
|
||||
$route->post('/token-well', ProfileController::class .':tokenWell')->setName('tokenWell');
|
||||
|
||||
$route->get('/mode', HomeController::class .':mode')->setName('mode');
|
||||
$route->get('/lang', HomeController::class .':lang')->setName('lang');
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue