LiveView & End-to-end encryption

The situation

Hi there! I’m working on a live view app right now that encrypts sensitive user content (text and images) using the browser’s subtlecrypto Javascript APIs.

Showing Content

For text, I implemented a custom HTML element that can take a base64 string of encrypted text, decrypt it, and render it to the page. For images, it takes a link to the image, downloads it, decrypts it, and then renders and image tag with the decrypted data. This is working well!

Creating Content

This gets trickier. When the user writes text or uploads an image, I want to show the plain text, and a preview of the image in the browser. I’d love to do as little custom coding as possible around form interactions, meaning I’d love to just let Live View do its magic with form submission, validation, etc, but I’d love to have a Javascript Hook from Live View that would let me transform the form data before it reaches the server. I’d encrypt the body text and any uploaded images, and then let Live View continue on as if I hadn’t done anything at all.

The Question

I’m not aware of any existing LiveView JS hooks that would let me do something like this. What’s the cleanest and simplest architecture you can think of to put as much of the work as possible on Live View, while still encrypting text and images before they get sent to the server?

3 Likes

Corresponding tweet for this thread:

Share link for this tweet.

3 Likes

I believe Livebook does this. If I understood the developer correctly when I listened to #046 Livebook with Jonatan Kłosko - Thinking Elixir Livebook uses a custom editor that sends operational transforms to the server, not just the text itself.

Hopefully this puts you on a fruitful path.

3 Likes

Thanks for your response @jc00ke! I wanted to follow-up here and tell a little bit about what I actually ended up doing.

I’m using live view to deliver my encrypted content to the browser, which then uses custom HTML elements to decrypt the content and render it on-page.

The form for creating new content is not a live view form.

The screen accepting new content has faux inputs where the user can write plain text, and see the decrypted version of their images, but the actual form inputs, which are hidden, end up being the encrypted versions of the plain text content. I use alpine-js to bind to the change events on the faux inputs, and modify the values in the hidden ones. Then I use javascript and the fetch API to submit the form over AJAX outside of LiveView. Then, the endpoint that creates new content broadcasts the creation event over PubSub, so all viewers get live updates anyway.

Initially I tried using a LiveView form and just setting the content with Javascript, but I had a difficult time getting Live View to behave predictably when I was setting input values through JS, rather than plain user input. The traditional form cleared of all of the strange inconsistencies I was seeing.

2 Likes