Start by requesting keys for only the master device, then handle 410 as
needed. Single-device users are the more common case and this strategy
lets us avoid requesting/expending one of our own device keys when
establishing a session with sibling devices.
// FREEBIE
After setting a new identity key as trusted, we retry decryption on all
pending conflicts for that contact. If their identity changed twice in a
row, we can still get a conflict the second time, and should handle it
appropriately.
This new endpoint should always issue a response to a provisioning
socket so if we don't receive one we should assume the connection has
been lost.
Closes#318
By default, automatically disconnect if no response. This is preferable
because we can sometimes lose connectivity without receiving a close
event from the socket, but it's also possible that the endpoint may not
support responses.
// FREEBIE
saveKeysToDeviceObject is the detector of outgoing identity key errors.
Catch these key errors closer to the source by pulling the
getKeysForNumber into the context of sendMessageToDevices, which lets
it access registerError and the message protobuf.
Previously identity key errors would be uncaught if all existing
sessions with a recipient were closed/deleted, since we would
preemptively fetch the new identity key. The old error handling only
kicked in after a 409/410 response from the server when posting a
message encrypted for a stale session.
// FREEBIE
Previously we would convert a bytebuffer to a string, pass it to
libaxolotl where it would be parsed back into a bytebuffer.
Ideally we would just pass the bytebuffer, but it turns out that
libaxolotl's bytebyffer class is identical but separate from
libtextsecure's bytebuffer class. ¯\_(ツ)_/¯
So instead we pass the underlying array buffer, which is handled
more or less the same way as a bytebuffer, and most importantly,
does not involve any copying.
// FREEBIE
We now disconnect ourselves if we don't get the server's response to a
keepalive request within 30s. This way we will eventually disconnect if
the network goes away but the socket is not closed.*
* See code.google.com/p/chromium/issues/detail?id=197841 and
https://stackoverflow.com/questions/11755605/chrome-websocket-connection-not-closed-when-browser-closed
We will then try to reconnect once a minute (See 8a10c96);
Keepalives belong at this level anyway, since the format is defined by
both the websocket resource protocol and our specific server url
structure.
// FREEBIE
The following are equivalent, except that the first is longer and
invokes an extra function call.
```
return new Promise(function(resolve, reject) {
reject(new Error("Unknown Group"));
});
return Promise.reject(new Error("Unknown Group"));
```
The avatar handler was being added to the list of promises too late,
so we were storing the raw avatar protobuf (Long id, bytes key) rather
than the downloaded/decrypted attachment data.
Fixes#280
Protocol and handling is all analogous to contact sync: Multiple
GroupDetails structs are packed into a single attachment blob and parsed
on our end. We don't display the synced groups in the conversation list
until a new message is sent to one of them.
// FREEBIE
Initializing a message receiver opens the socket and starts listening
right away rather than requiring a separate call to connect. The only
other publicly accessible method is to query the socket status.
// FREEBIE
Update protobuf definitions and refactor message receive and decrypt
codepath to support new protocol, including various flavors of sync
messages (sent messages, contacts, and groups).
Also cleans up background.js and lets libtextsecure internalize
textsecure.processDecrypted and ensure that it is called before handing
DataMessages off to the application.
The Envelope structure now has a generic content field and a
legacyMessage field for backwards compatibility. We'll send outgoing
messages as legacy messages, and sync messages as "content" while
continuing to support both legacy and non-legacy messages on the receive
side until old clients have a chance to transition.