Compare commits

...

5 Commits

Author SHA1 Message Date
44a8a72219 upd: home
Add input-error style for validation feedback
2025-06-03 13:01:47 -04:00
c933e6b91b upd: registration
Add CSRF protection to registration form
2025-06-03 13:00:34 -04:00
573b8b1d26 upd: notes
add validation feedback if user doesn't fill out all required fields.
2025-06-03 12:58:42 -04:00
1aed314ae3 fix: registration
Fix a couple typos in registration JS
2025-06-03 12:44:03 -04:00
135a03f8d1 upd: data.db
Updates to starting database
2025-04-28 00:09:22 -04:00
5 changed files with 37 additions and 25 deletions

View File

@ -1,8 +1,7 @@
// Get references to the form elements // Get references to the form elements
const nameInput = document.getElementById("name"); const nameInput = document.getElementById("registration_form_name");
const emailInput = document.getElementById("emailAddress"); const emailInput = document.getElementById("registration_form_email");
const passwordInput = document.getElementById("password"); const passwordInput = document.getElementById("registration_form_plainPassword");
const confirmPasswordInput = document.getElementById("confirmPassword");
const csrfToken = document.getElementById("registration_form__token").value; const csrfToken = document.getElementById("registration_form__token").value;
// Add event listeners to the form // Add event listeners to the form
@ -18,25 +17,18 @@ function handleSubmit(event) {
const name = nameInput.value; const name = nameInput.value;
const email = emailInput.value; const email = emailInput.value;
const password = passwordInput.value; const password = passwordInput.value;
const confirmPassword = confirmPasswordInput.value;
if (name === "" || email === "" || password === "") { if (name === "" || email === "" || password === "") {
alert("Please fill in all fields."); alert("Please fill in all fields.");
return; return;
} }
if (password !== confirmPassword) {
alert("Passwords do not match.");
return;
}
// Send data to server for processing // Send data to server for processing
const data = { const data = {
"name": name, "name": name,
"email": email, "email": email,
"password": password,
"plainPassword": password, "plainPassword": password,
"csrf_token": csrfToken "_token": csrfToken
}; };
fetch("/register", { fetch("/register", {

View File

@ -95,6 +95,13 @@ function saveNote(event) {
event.preventDefault(); event.preventDefault();
} }
document.querySelector('#noteTitle').classList.remove('input-error');
document.querySelector('#noteDate').classList.remove('input-error');
document.querySelector('#speaker').classList.remove('input-error');
document.querySelector('#series').classList.remove('input-error');
document.querySelector('#passage').classList.remove('input-error');
document.querySelector('#notes').classList.remove('input-error');
if (!textDirty || !validateNote()) { if (!textDirty || !validateNote()) {
clearTimeout(to); clearTimeout(to);
to = setTimeout(saveNote, saveInterval); to = setTimeout(saveNote, saveInterval);
@ -174,14 +181,20 @@ function validateNote() {
const title = document.querySelector('#noteTitle'); const title = document.querySelector('#noteTitle');
const psg = document.querySelector('#passage'); const psg = document.querySelector('#passage');
if (!title.value.length) { return false; } let ret = true;
if (!date.value) { return false; }
if (!parseInt(speaker.value)) { return false; }
if (!parseInt(series.value)) { return false; }
if (!psg.value) { return false; }
if (!note.value.length) { return false; }
return true; if (!title.value.length) { title.classList.add('input-error'); ret = false; }
if (!date.value) { date.classList.add('input-error'); ret = false; }
if (!parseInt(speaker.value)) { speaker.classList.add('input-error'); ret = false; }
if (!parseInt(series.value)) { series.classList.add('input-error'); ret = false; }
if (!psg.value) { psg.classList.add('input-error'); ret = false; }
if (!note.value.length) { note.classList.add('input-error'); ret = false; }
if (!ret) {
toggleFields(true);
}
return ret;
} }
/** /**
@ -506,20 +519,21 @@ function removeActiveRef() {
/** /**
* Toggles the visibility of the fields container and updates the active state of the show/hide button. * Toggles the visibility of the fields container and updates the active state of the show/hide button.
* *
* @param boolean show
* @return {void} * @return {void}
*/ */
function toggleFields() { function toggleFields(show = false) {
const fieldsContainer = document.getElementById('fields-container'); const fieldsContainer = document.getElementById('fields-container');
const showHideBtn = document.getElementById('show-hide-btn'); const showHideBtn = document.getElementById('show-hide-btn');
if (fieldsContainer.classList.contains('show')) { if (show || !fieldsContainer.classList.contains('show')) {
fieldsContainer.classList.remove('show');
fieldsContainer.style.display = 'none';
showHideBtn.classList.remove('active');
} else {
fieldsContainer.classList.add('show'); fieldsContainer.classList.add('show');
fieldsContainer.style.display = 'block'; fieldsContainer.style.display = 'block';
showHideBtn.classList.add('active'); showHideBtn.classList.add('active');
} else {
fieldsContainer.classList.remove('show');
fieldsContainer.style.display = 'none';
showHideBtn.classList.remove('active');
} }
setHeight(); setHeight();

Binary file not shown.

View File

@ -43,6 +43,9 @@ class RegistrationFormType extends AbstractType
{ {
$resolver->setDefaults([ $resolver->setDefaults([
'data_class' => User::class, 'data_class' => User::class,
'csrf_protection' => true,
'csrf_field_name' => '_token',
'csrf_token_id' => 'registration',
]); ]);
} }
} }

View File

@ -16,6 +16,9 @@
button.button i { button.button i {
font-size: 1.5em; font-size: 1.5em;
} }
.input-error {
border: solid 2px red !important;
}
</style> </style>
{% endblock %} {% endblock %}