From 947d3d0694bf200f19df966965f545b8136997c0 Mon Sep 17 00:00:00 2001 From: "Torsten Schulz (local)" Date: Wed, 4 Mar 2026 22:44:15 +0100 Subject: [PATCH] Add validation and error handling for room creation form in MultiChatDialog: Implement input validation for room name, age restrictions, password, and access rights. Enhance UI with error messages and disable button when validation fails. --- .../src/dialogues/chat/MultiChatDialog.vue | 99 +++++++++++++++---- 1 file changed, 80 insertions(+), 19 deletions(-) diff --git a/frontend/src/dialogues/chat/MultiChatDialog.vue b/frontend/src/dialogues/chat/MultiChatDialog.vue index 4668afc..08a0ff3 100644 --- a/frontend/src/dialogues/chat/MultiChatDialog.vue +++ b/frontend/src/dialogues/chat/MultiChatDialog.vue @@ -63,7 +63,9 @@
- +
+
{{ roomCreateValidation.range }}
Kommando: {{ buildRoomCreateCommandPreview() || '/cr ' }}
@@ -200,6 +213,30 @@ export default { try { return !!(this.menu && this.menu.administration); } catch (_) { return false; } + }, + roomCreateValidation() { + const errors = {}; + const name = (this.roomCreateForm.roomName || '').trim(); + const minAge = this.parseOptionalInteger(this.roomCreateForm.minAge); + const maxAge = this.parseOptionalInteger(this.roomCreateForm.maxAge); + const rightId = this.parseOptionalInteger(this.roomCreateForm.rightId); + const typeId = this.parseOptionalInteger(this.roomCreateForm.typeId); + const password = this.roomCreateForm.password || ''; + + if (!name) errors.roomName = 'Raumname ist erforderlich.'; + if (minAge !== null && minAge < 0) errors.minAge = 'min_age muss >= 0 sein.'; + if (maxAge !== null && maxAge < 0) errors.maxAge = 'max_age muss >= 0 sein.'; + if (minAge !== null && maxAge !== null && minAge > maxAge) { + errors.range = 'min_age darf nicht größer als max_age sein.'; + } + if (password.includes(' ')) errors.password = 'Passwort darf keine Leerzeichen enthalten.'; + if (rightId !== null && rightId <= 0) errors.rightId = 'right_id muss > 0 sein.'; + if (typeId !== null && typeId <= 0) errors.typeId = 'type_id muss > 0 sein.'; + + return errors; + }, + canSendRoomCreate() { + return Object.keys(this.roomCreateValidation).length === 0; } }, mounted() { @@ -332,6 +369,12 @@ export default { buildRoomCreateCommandPreview() { return this.buildRoomCreateCommand(); }, + parseOptionalInteger(value) { + if (value === null || value === undefined || value === '') return null; + const num = Number(value); + if (!Number.isFinite(num)) return null; + return Math.trunc(num); + }, buildRoomCreateCommand() { const name = (this.roomCreateForm.roomName || '').trim(); if (!name) return ''; @@ -341,20 +384,24 @@ export default { parts.push(`public=${this.roomCreateForm.publicFlag}`); } if (this.roomCreateForm.gender) parts.push(`gender=${this.roomCreateForm.gender}`); - if (Number.isInteger(this.roomCreateForm.minAge) && this.roomCreateForm.minAge >= 0) { - parts.push(`min_age=${this.roomCreateForm.minAge}`); + const minAge = this.parseOptionalInteger(this.roomCreateForm.minAge); + if (minAge !== null && minAge >= 0) { + parts.push(`min_age=${minAge}`); } - if (Number.isInteger(this.roomCreateForm.maxAge) && this.roomCreateForm.maxAge >= 0) { - parts.push(`max_age=${this.roomCreateForm.maxAge}`); + const maxAge = this.parseOptionalInteger(this.roomCreateForm.maxAge); + if (maxAge !== null && maxAge >= 0) { + parts.push(`max_age=${maxAge}`); } const password = (this.roomCreateForm.password || '').trim(); if (password) parts.push(`password=${password}`); if (this.roomCreateForm.friendsOnly) parts.push('friends_only=true'); - if (Number.isInteger(this.roomCreateForm.rightId) && this.roomCreateForm.rightId > 0) { - parts.push(`right_id=${this.roomCreateForm.rightId}`); + const rightId = this.parseOptionalInteger(this.roomCreateForm.rightId); + if (rightId !== null && rightId > 0) { + parts.push(`right_id=${rightId}`); } - if (Number.isInteger(this.roomCreateForm.typeId) && this.roomCreateForm.typeId > 0) { - parts.push(`type_id=${this.roomCreateForm.typeId}`); + const typeId = this.parseOptionalInteger(this.roomCreateForm.typeId); + if (typeId !== null && typeId > 0) { + parts.push(`type_id=${typeId}`); } return parts.join(' '); }, @@ -371,15 +418,15 @@ export default { this.messages.push({ id: Date.now(), user: 'System', text: 'Keine Verbindung zum Chat-Server.' }); return; } + if (!this.canSendRoomCreate) { + this.messages.push({ id: Date.now(), user: 'System', text: 'Bitte Eingaben im Raum-Formular korrigieren.' }); + return; + } const command = this.buildRoomCreateCommand(); if (!command) { this.messages.push({ id: Date.now(), user: 'System', text: 'Bitte einen Raumnamen angeben.' }); return; } - if ((this.roomCreateForm.password || '').includes(' ')) { - this.messages.push({ id: Date.now(), user: 'System', text: 'Passwort darf keine Leerzeichen enthalten.' }); - return; - } const payload = { type: 'message', message: command }; if (this.debug) console.log('[Chat WS >>]', payload); this.sendWithToken(payload); @@ -1800,6 +1847,11 @@ export default { padding: 0.35em 0.5em; } +.invalid-input { + border-color: #c62828 !important; + background: #fff6f6; +} + .checkbox-label { flex-direction: row !important; align-items: center; @@ -1826,6 +1878,15 @@ export default { color: #444; } +.room-create-error { + color: #b00020; + font-size: 0.85em; +} + +.room-create-error-block { + margin-top: 0.5em; +} + .chat-message { margin-bottom: 0.3em; }