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: '',
|
pendingRoomCreateName: '',
|
||||||
pendingRoomCreateAttempts: 0,
|
pendingRoomCreateAttempts: 0,
|
||||||
pendingRoomCreateTimer: null,
|
pendingRoomCreateTimer: null,
|
||||||
|
roomPasswords: {},
|
||||||
|
passwordPromptActive: false,
|
||||||
// Palette state
|
// Palette state
|
||||||
paletteWidth: 420,
|
paletteWidth: 420,
|
||||||
paletteHeight: 220,
|
paletteHeight: 220,
|
||||||
@@ -365,7 +367,7 @@ export default {
|
|||||||
selectedRoom(newVal, oldVal) {
|
selectedRoom(newVal, oldVal) {
|
||||||
if (newVal && this.transportConnected) {
|
if (newVal && this.transportConnected) {
|
||||||
const room = this.getSelectedRoomName();
|
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.messages = [];
|
||||||
this.usersInRoom = [];
|
this.usersInRoom = [];
|
||||||
this.selectedTargetUser = null;
|
this.selectedTargetUser = null;
|
||||||
@@ -405,6 +407,43 @@ export default {
|
|||||||
roomNamesEqual(a, b) {
|
roomNamesEqual(a, b) {
|
||||||
return (a || '').trim().toLowerCase() === (b || '').trim().toLowerCase();
|
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() {
|
tryConfirmRoomCreateSuccess() {
|
||||||
if (!this.pendingRoomCreateName) return false;
|
if (!this.pendingRoomCreateName) return false;
|
||||||
const created = this.ownRooms.find((r) => this.roomNamesEqual(r.title, this.pendingRoomCreateName));
|
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
|
// Drop references to losers so GC can collect
|
||||||
this.pendingWs = [];
|
this.pendingWs = [];
|
||||||
// Prepare handshake like before
|
// 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);
|
if (this.debug) console.log('[Chat WS >>]', init);
|
||||||
this.wsSend(init);
|
this.wsSend(init);
|
||||||
if (this.connectAttemptTimeout) clearTimeout(this.connectAttemptTimeout);
|
if (this.connectAttemptTimeout) clearTimeout(this.connectAttemptTimeout);
|
||||||
@@ -902,7 +942,8 @@ export default {
|
|||||||
this.transportConnected = true;
|
this.transportConnected = true;
|
||||||
const dt = Date.now() - (this.wsStartAt || Date.now());
|
const dt = Date.now() - (this.wsStartAt || Date.now());
|
||||||
console.log('[Chat WS] open in', dt, 'ms', '| protocol:', ws.protocol || '(none)', '| url:', url);
|
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);
|
if (this.debug) console.log('[Chat WS >>]', init);
|
||||||
this.wsSend(init);
|
this.wsSend(init);
|
||||||
if (this.connectOpenTimer) { clearTimeout(this.connectOpenTimer); this.connectOpenTimer = null; }
|
if (this.connectOpenTimer) { clearTimeout(this.connectOpenTimer); this.connectOpenTimer = null; }
|
||||||
@@ -1413,6 +1454,10 @@ export default {
|
|||||||
if (!obj) return;
|
if (!obj) return;
|
||||||
if (obj.type === 'error') {
|
if (obj.type === 'error') {
|
||||||
const text = obj.message || 'chat_error';
|
const text = obj.message || 'chat_error';
|
||||||
|
if (text === 'room_password_required' || text === 'room_password_invalid') {
|
||||||
|
this.handleRoomPasswordError(text);
|
||||||
|
return;
|
||||||
|
}
|
||||||
this.setStatus('error');
|
this.setStatus('error');
|
||||||
this.messages.push({ id: Date.now(), user: 'System', text: `Fehler: ${text}` });
|
this.messages.push({ id: Date.now(), user: 'System', text: `Fehler: ${text}` });
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -114,6 +114,12 @@
|
|||||||
"servicesStatus": "Service-Status"
|
"servicesStatus": "Service-Status"
|
||||||
},
|
},
|
||||||
"types": {}
|
"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": {
|
"randomchat": {
|
||||||
|
|||||||
@@ -114,6 +114,12 @@
|
|||||||
"servicesStatus": "Service status"
|
"servicesStatus": "Service status"
|
||||||
},
|
},
|
||||||
"types": {}
|
"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": {
|
"randomchat": {
|
||||||
|
|||||||
@@ -113,6 +113,12 @@
|
|||||||
"servicesStatus": "Estado de servicios"
|
"servicesStatus": "Estado de servicios"
|
||||||
},
|
},
|
||||||
"types": {}
|
"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": {
|
"randomchat": {
|
||||||
|
|||||||
Reference in New Issue
Block a user