ReplayableErrors make it easy for the frontend to handle identity key
errors by wrapping the necessary steps into one convenient little
replay() callback function.
The frontend remains agnostic to what those steps are. It just calls
replay() once the user has acknowledged the key change.
The protocol layer is responsible for registering the callbacks needed
by the IncomingIdentityKeyError and OutgoingIdentityKeyError.
superfeedr has done a nice job with this backbone -> indexedDB adapter,
but their query interface is somewhat limited. This commit adds an
alternate interface that lets us specify the index and cursor bounds we
want. This interface requires deeper knowledge of indexedDB indices, but
is more powerful overall.
This was used to conditionally render messages in the group style, but
it's actually unnecessary. We can render the same markup in both cases
and change the appearance with css.
This commit provides the javascript complement to
[WebSocket-Resources](https://github.com/WhisperSystems/WebSocket-Resources),
allowing us to use a bi-directional request-response framework over
websockets.
See websocket-resources.js and websocket-resources_test.js
for usage details.
Along the way I also factored the websocket keepalive and reconnect
logic into its own file/wrapper object.
Move base64 encoding of attachments to an AttachmentView. This makes
image rendering an asynchronous task so we fire an update event to
indicate to the parent MessageListView that its content has changed
height and it is time to scroll down.
Register the runtime callback at the top level view rather than having
each conversation view register independently.
Also refactors Layout into InboxView.
After a message is saved asynchronsly, fire an event and pass the
message attributes to frontend listeners via the chrome-runtime API.
This behavior is similar to the 'storage' event fired by localStorage.
Getting up and running with IndexedDB was pretty easy, thanks to
backbone. The tricky part was making reads and writes asynchronous.
In that process I did some refactoring on Whisper.Threads, which
has been renamed Conversations for consistency with the view names.
This change also adds the unlimitedStorage permission.
Eliminates the global Whisper.Messages object and consolidates shared
send/receive logic in Whisper.Threads.
To the latter end, note that the decrypted array buffer on an attachment
pointer is now named data instead of decrypted, in order to match the
format of outgoing attachments presented by
FileReader.readAsArrayBuffers and let us use the same handler to base64
encode them.
This dependency may be a little heavy for our current use case, but we can
roll with it for now and find something slimmer if it turns out yagni.
Closes#77Closes#40
Runtime reload is overkill and causes a jarring ux. Instead, send and
receive messages across the runtime. Also, if we need to jump between
the main ui and options pages, simply navigate within the current tab
rather than spawning a new one.
We only depend on cryptojs for this webcrypto polyfill, so let Grunt
concatenate them into one file.
The reference in the getString helper isn't needed since we use the
built in string converters on CryptoJS's word arrays.
Rename methods on the curve25519 interface to be a bit more high level.
Cleanup emscripten wrapper class, wrap long lines and such. Also add a
grunt task alias for building the emscripten compiled curve
implementation.
Firstly, don't initialize textsecure.nativclient unless the browser
supports it. The mimetype-check trick is hewn from nacl-common.js.
Secondly, nativeclient crypto functions will all automatically wait for
the module to load before sending messages, so we needn't register any
onload callbacks outside nativeclient.js. (Previously, if you wanted to
do crypto with native client, you would have to register a call back and
wait for the module to load.) Now that the native client crypto is
encapsulated behind a nice interface, it can handle all that
onload-callback jazz internally: if the module isn't loaded when you
call a nativeclient function, return a promise that waits for the load
callback, and eventually resolves with the result of the requested
command. This removes the need for textsecure.registerOnLoadCallback.
Finally, although native client has its quirks, it's significantly
faster than the alternative (emscripten compiled js), so this commit
also lets the crypto backend use native client opportunistically, if
it's available, falling back to js if not, which should make us
compatible with older versions of chrome and chromium.