release: v4.8.12 chat notification & file-transfer UI fixes
CodeQL Analysis / Analyze CodeQL (push) Has been cancelled
Deploy Application / deploy (push) Has been cancelled
Mirror to Codeberg / mirror (push) Has been cancelled
Mirror to PrivacyGuides / mirror (push) Has been cancelled

fix(file-transfer): announce received file once, not many times

The per-transfer lock used a single `if` check, so when 3+ chunk
operations queued on the same fileId they awaited the same in-flight
lock and then ran concurrently, breaking assembly atomicity. The lock
now loops until the slot is free (true serialization) and file assembly
is idempotent, so `File received` shows exactly once per file.

fix(verification): stop duplicate connection-setup system messages

handleVerificationBothConfirmed had no guard, so when both peers sent
verification_both_confirmed symmetrically one side ran both the local
detection path and the peer-notification path, emitting "Both parties
confirmed!" and the verified transition (and "Secure connection
established") twice. It now bails out if both confirmations are already
recorded.

fix(ui): wrap long DTLS fingerprint inside the chat bubble

The message text column is a flex child with default min-width:auto, so
the long unbroken fingerprint overflowed. Added min-w-0 so break-words
can wrap it.

chore(release): bump version to 4.8.12 in header, init banner, manifest
This commit is contained in:
lockbitchat
2026-06-17 17:51:09 -04:00
parent be1d02f1f7
commit 6f36fce8c6
14 changed files with 84 additions and 44 deletions
+19 -10
View File
@@ -4340,18 +4340,20 @@ var AtomicOperations = class {
this.locks = /* @__PURE__ */ new Map();
}
async withLock(key, operation) {
if (this.locks.has(key)) {
while (this.locks.has(key)) {
await this.locks.get(key);
}
const lockPromise = (async () => {
try {
return await operation();
} finally {
this.locks.delete(key);
}
})();
let releaseLock;
const lockPromise = new Promise((resolve) => {
releaseLock = resolve;
});
this.locks.set(key, lockPromise);
return lockPromise;
try {
return await operation();
} finally {
this.locks.delete(key);
releaseLock();
}
}
};
var RateLimiter = class {
@@ -5297,6 +5299,10 @@ var EnhancedSecureFileTransfer = class {
return true;
}
async assembleFile(receivingState) {
if (receivingState._assembled) {
return;
}
receivingState._assembled = true;
try {
receivingState.status = "assembling";
for (let i = 0; i < receivingState.totalChunks; i++) {
@@ -14873,6 +14879,9 @@ var EnhancedSecureWebRTCManager = class _EnhancedSecureWebRTCManager {
this._checkBothVerificationsConfirmed();
}
handleVerificationBothConfirmed(data) {
if (this.bothVerificationsConfirmed) {
return;
}
this.bothVerificationsConfirmed = true;
if (this.onVerificationStateChange) {
this.onVerificationStateChange({
@@ -17493,7 +17502,7 @@ Right-click or Ctrl+click to disconnect`,
React.createElement("p", {
key: "subtitle",
className: "text-xs sm:text-sm text-muted hidden sm:block"
}, "End-to-end freedom v4.8.10")
}, "End-to-end freedom v4.8.12")
])
]),
// Status and Controls - Responsive
+2 -2
View File
File diff suppressed because one or more lines are too long
Vendored
+2 -2
View File
@@ -414,7 +414,7 @@ var EnhancedChatMessage = ({ message, type, timestamp }) => {
}),
React.createElement("div", {
key: "text",
className: "flex-1"
className: "flex-1 min-w-0"
}, [
React.createElement("div", {
key: "message",
@@ -1987,7 +1987,7 @@ var EnhancedSecureP2PChat = () => {
} catch (error) {
}
}
handleMessage(" SecureBit.chat Enhanced Security Edition v4.8.10 - ECDH + DTLS + SAS initialized. Ready to establish a secure connection with ECDH key exchange, DTLS fingerprint verification, and SAS authentication to prevent MITM attacks.", "system");
handleMessage(" SecureBit.chat Enhanced Security Edition v4.8.12 - ECDH + DTLS + SAS initialized. Ready to establish a secure connection with ECDH key exchange, DTLS fingerprint verification, and SAS authentication to prevent MITM attacks.", "system");
const handleBeforeUnload = (event) => {
if (event.type === "beforeunload" && !isTabSwitching) {
if (webrtcManagerRef.current && webrtcManagerRef.current.isConnected()) {
+1 -1
View File
File diff suppressed because one or more lines are too long