fix: wire up Regenerate Peer ID button + remove arbitrary MAX_CONTROLLERS cap

Two pre-existing issues surfaced during audit follow-up:

1. popup.js bound elements.regenId but never attached a click handler —
   the 'Regenerate Peer ID' button has been dead UI since it was added
   (verified across full git history). Wired it up to send REGENERATE_ID;
   the background handler already did the right thing (rotate peerId,
   persist, force reconnect). The button is functional (regen ID on
   duplicate-identity errors), not privacy-theater — username is already
   user-changeable in settings, so it stays out of scope.

2. MAX_CONTROLLERS=10 was arbitrary. Payload math (25 controllers ×
   16-char IDs ≈ 500 bytes) is well under the 4KB maxHttpBufferSize,
   controllers.has() is O(1) on a Set, and 'just use everyone mode' is
   not a real answer when a host wants 12 controllers + 3 guests in a
   15-person room. Removed the cap entirely; the only real upper bound
   is MAX_PEERS_PER_ROOM (25).

Added TOAST_ID_REGENERATED to en.json — the i18n fallback merge
(Object.assign({}, enDict, targetDict)) covers the other 14 locales
automatically with English until they're translated.
This commit is contained in:
KoalaDev
2026-06-28 14:03:59 +02:00
parent 77203fe8fd
commit e23f9ab226
3 changed files with 15 additions and 9 deletions
+1
View File
@@ -109,6 +109,7 @@
"BTN_REGEN_ID_TOOLTIP": "Regenerate your internal ID and reconnect",
"REGEN_ID_DESC": "Use this if you see \"Duplicate Identity\" errors.",
"REGEN_ID_OTHER_ISSUE": "Other issue? Open a GitHub Issue",
"TOAST_ID_REGENERATED": "Identity regenerated — reconnecting…",
"LABEL_CONN_STATUS": "Connection Status",
"LABEL_CONN_STATUS_TOOLTIP": "Current WebSocket connection state",
"CONN_STATUS_DISCONNECTED": "Disconnected",
+14
View File
@@ -1645,6 +1645,20 @@ elements.clearLogs.addEventListener('click', () => {
});
});
if (elements.regenId) {
elements.regenId.addEventListener('click', () => {
elements.regenId.disabled = true;
chrome.runtime.sendMessage({ type: 'REGENERATE_ID' }, (res) => {
elements.regenId.disabled = false;
if (chrome.runtime.lastError || !res || !res.peerId) {
showToast(getMessage('TOAST_ID_REGENERATED') || 'Failed to regenerate identity', 'error');
return;
}
showToast(getMessage('TOAST_ID_REGENERATED') || 'Identity regenerated — reconnecting…', 'success', 3000);
});
});
}
elements.copyInvite.addEventListener('click', () => {
navigator.clipboard.writeText(elements.inviteLink.value).then(() => {
const original = elements.copyInvite.textContent;
-9
View File
@@ -175,10 +175,6 @@ const SERVER_CAPABILITIES = [CAPABILITIES.HOST_CONTROL, CAPABILITIES.CO_HOST];
// from generating one broadcast per toggle across all peers.
const CONTROL_MODE_MIN_INTERVAL_MS = 500;
// Co-Host: max peers (incl. the owner) allowed to drive a 'host-only' room. Bounds
// the controller set + the CONTROL_MODE payload. Beyond this, just use 'everyone'.
const MAX_CONTROLLERS = 10;
// Canonical control-mode/role snapshot sent to clients. controllers always includes
// the owner (hostPeerId). Built in one place so every emit stays consistent.
function controlModePayload(room) {
@@ -748,11 +744,6 @@ io.on('connection', (socket) => {
if (makeController) {
if (room.controllers.has(targetPeerId)) return; // no-op
if (room.controllers.size >= MAX_CONTROLLERS) {
log('ROOM', `Controller cap (${MAX_CONTROLLERS}) reached in ${mapping.roomId.substring(0, 3)}***`);
socket.emit(EVENTS.CONTROL_MODE, controlModePayload(room)); // re-sync owner UI
return;
}
room.controllers.add(targetPeerId);
} else {
if (!room.controllers.has(targetPeerId)) return; // no-op