Add password protection feature in MultiChatDialog: Implement room password management, including prompts for password entry and error handling for invalid passwords. Update i18n files with localized messages for password prompts in English, German, and Spanish.
This commit is contained in:
@@ -321,6 +321,8 @@ export default {
|
||||
pendingRoomCreateName: '',
|
||||
pendingRoomCreateAttempts: 0,
|
||||
pendingRoomCreateTimer: null,
|
||||
roomPasswords: {},
|
||||
passwordPromptActive: false,
|
||||
// Palette state
|
||||
paletteWidth: 420,
|
||||
paletteHeight: 220,
|
||||
@@ -365,7 +367,7 @@ export default {
|
||||
selectedRoom(newVal, oldVal) {
|
||||
if (newVal && this.transportConnected) {
|
||||
const room = this.getSelectedRoomName();
|
||||
if (room) this.sendWithToken({ type: 'join', room, password: '' });
|
||||
if (room) this.sendWithToken({ type: 'join', room, password: this.getRoomPassword(room) });
|
||||
this.messages = [];
|
||||
this.usersInRoom = [];
|
||||
this.selectedTargetUser = null;
|
||||
@@ -405,6 +407,43 @@ export default {
|
||||
roomNamesEqual(a, b) {
|
||||
return (a || '').trim().toLowerCase() === (b || '').trim().toLowerCase();
|
||||
},
|
||||
getRoomPassword(roomName) {
|
||||
if (!roomName) return '';
|
||||
return this.roomPasswords[roomName] || '';
|
||||
},
|
||||
async handleRoomPasswordError(errorCode) {
|
||||
const room = this.getSelectedRoomName();
|
||||
if (!room || this.passwordPromptActive) return;
|
||||
this.passwordPromptActive = true;
|
||||
try {
|
||||
const isInvalid = errorCode === 'room_password_invalid';
|
||||
const promptText = isInvalid
|
||||
? this.$t('chat.multichat.password.invalidPrompt', { room })
|
||||
: this.$t('chat.multichat.password.requiredPrompt', { room });
|
||||
const entered = window.prompt(promptText, '');
|
||||
if (entered === null) {
|
||||
this.messages.push({
|
||||
id: Date.now(),
|
||||
user: 'System',
|
||||
text: this.$t('chat.multichat.password.cancelled', { room })
|
||||
});
|
||||
return;
|
||||
}
|
||||
const password = entered.trim();
|
||||
if (!password) {
|
||||
this.messages.push({
|
||||
id: Date.now(),
|
||||
user: 'System',
|
||||
text: this.$t('chat.multichat.password.empty')
|
||||
});
|
||||
return;
|
||||
}
|
||||
this.roomPasswords[room] = password;
|
||||
this.sendWithToken({ type: 'join', room, password });
|
||||
} finally {
|
||||
this.passwordPromptActive = false;
|
||||
}
|
||||
},
|
||||
tryConfirmRoomCreateSuccess() {
|
||||
if (!this.pendingRoomCreateName) return false;
|
||||
const created = this.ownRooms.find((r) => this.roomNamesEqual(r.title, this.pendingRoomCreateName));
|
||||
@@ -805,7 +844,8 @@ export default {
|
||||
// Drop references to losers so GC can collect
|
||||
this.pendingWs = [];
|
||||
// Prepare handshake like before
|
||||
const init = { type: 'init', name: this.user?.username || '', room: this.getSelectedRoomName() || '', password: '' };
|
||||
const initRoom = this.getSelectedRoomName() || '';
|
||||
const init = { type: 'init', name: this.user?.username || '', room: initRoom, password: this.getRoomPassword(initRoom) };
|
||||
if (this.debug) console.log('[Chat WS >>]', init);
|
||||
this.wsSend(init);
|
||||
if (this.connectAttemptTimeout) clearTimeout(this.connectAttemptTimeout);
|
||||
@@ -902,7 +942,8 @@ export default {
|
||||
this.transportConnected = true;
|
||||
const dt = Date.now() - (this.wsStartAt || Date.now());
|
||||
console.log('[Chat WS] open in', dt, 'ms', '| protocol:', ws.protocol || '(none)', '| url:', url);
|
||||
const init = { type: 'init', name: this.user?.username || '', room: this.getSelectedRoomName() || '', password: '' };
|
||||
const initRoom = this.getSelectedRoomName() || '';
|
||||
const init = { type: 'init', name: this.user?.username || '', room: initRoom, password: this.getRoomPassword(initRoom) };
|
||||
if (this.debug) console.log('[Chat WS >>]', init);
|
||||
this.wsSend(init);
|
||||
if (this.connectOpenTimer) { clearTimeout(this.connectOpenTimer); this.connectOpenTimer = null; }
|
||||
@@ -1413,6 +1454,10 @@ export default {
|
||||
if (!obj) return;
|
||||
if (obj.type === 'error') {
|
||||
const text = obj.message || 'chat_error';
|
||||
if (text === 'room_password_required' || text === 'room_password_invalid') {
|
||||
this.handleRoomPasswordError(text);
|
||||
return;
|
||||
}
|
||||
this.setStatus('error');
|
||||
this.messages.push({ id: Date.now(), user: 'System', text: `Fehler: ${text}` });
|
||||
return;
|
||||
|
||||
@@ -114,6 +114,12 @@
|
||||
"servicesStatus": "Service-Status"
|
||||
},
|
||||
"types": {}
|
||||
},
|
||||
"password": {
|
||||
"requiredPrompt": "Der Raum \"{room}\" ist passwortgeschützt. Bitte Passwort eingeben:",
|
||||
"invalidPrompt": "Falsches Passwort für \"{room}\". Bitte erneut eingeben:",
|
||||
"cancelled": "Beitritt zu \"{room}\" abgebrochen.",
|
||||
"empty": "Passwort darf nicht leer sein."
|
||||
}
|
||||
},
|
||||
"randomchat": {
|
||||
|
||||
@@ -114,6 +114,12 @@
|
||||
"servicesStatus": "Service status"
|
||||
},
|
||||
"types": {}
|
||||
},
|
||||
"password": {
|
||||
"requiredPrompt": "Room \"{room}\" is password-protected. Please enter password:",
|
||||
"invalidPrompt": "Wrong password for \"{room}\". Please try again:",
|
||||
"cancelled": "Join to \"{room}\" was cancelled.",
|
||||
"empty": "Password must not be empty."
|
||||
}
|
||||
},
|
||||
"randomchat": {
|
||||
|
||||
@@ -113,6 +113,12 @@
|
||||
"servicesStatus": "Estado de servicios"
|
||||
},
|
||||
"types": {}
|
||||
},
|
||||
"password": {
|
||||
"requiredPrompt": "La sala \"{room}\" está protegida por contraseña. Introduce la contraseña:",
|
||||
"invalidPrompt": "Contraseña incorrecta para \"{room}\". Inténtalo de nuevo:",
|
||||
"cancelled": "Se canceló el acceso a \"{room}\".",
|
||||
"empty": "La contraseña no puede estar vacía."
|
||||
}
|
||||
},
|
||||
"randomchat": {
|
||||
|
||||
Reference in New Issue
Block a user