QRifying backwards
So we all know what a QR is I mean at this point you might even know how it works it has multiple versions and variying levels of redundancy and all of that.
The big thing about QR thought is that you can use it to scan data into somewhere, like accessing a link to a dinning menu or a whole ass game.
QR is a pretty cool technology but I decided, why not flip it on it's head.
The Idea
Okay if you have used WhatsApp, Telegram or Discord in their respective web or desktop platforms you might've noticed that you can pop out your phone, whip out their app and just scan a QR code to login.
Some time after Discord released that feature I was left pondering,
Wouldn't it be cool if I could do that but for other platforms? Heck even with just any data at all.
And so the journey begun.
Technology prefacing
So I am a WebDev by trait well WebDev is charged with a lot of bad connotation.
I am a Web Enthusiast by trait, I love me some JavaScript (even if the language kinda sucks), I like learning about the technologies that the Web platform has to offer.
So of course I made this project a web app, you will see later what challenges and benefits it brought to the table.
Flow
So my idea came up collapsing into one interesting flow:
There is a Mailer
(which wants to send data) and a Inbox
(which wants to receive the data),
let's say the Mailer
is a mobile phone with a camera, and the Inbox
it's a desktop computer.
Inbox
opens the web app and receives a QR code with a unique identifierMailer
opens the web app and sets the data to send, and that opens a QR scannerMailer
scans theInbox
QR codeMailer
uses the QR to get and send the unique identifier, along with the dataInbox
receives the data
PWA? What does Progressive Web Apps have to do with anything?
So I had the idea of implementing a sharing platform that would work from your phone, to your computer.
But I thought without native support for sharing links and stuff, the web app will be reduced to nothing.
So with my smart plug-in I decided to go browse if PWA had any option to use the native sharing menu, and I stumbled into this google article and demo With a lot of tinkering from my part I got it to work in a basic manner in my web app. And it had the benefit of making my app installable at least from Android and Chrome.
The implementation
Oh I HeArD YoU aRe A wEb dEv YoU sUreLy Used A fRaMeWork
I love me some good vanilla js, but at the time of building this I was very ingrained with TypeScript and and... yeah and gulp, which for today modern standards is not that good.
So off the races I took to scramble to find libraries for vanilla js. So at the end what I ended up using in the client was:
And as far as the server goes I just used good old express
in conjunction to express-ws
for some trickery.
So basically for my backend I just had 2 endpoints:
/ws
-> Which basically sent the QR code and finally the data to theInbox
/postid
-> Which theMailer
uses for sending the data + (QR) id for the server to relay toInbox
The implementation flow
At the end the implementation (adding the Server
for communication) looked something like:
Inbox
opens the web app and connects toServer
via WebSocketInbox
asks via WebSocket to get an idServer
generates unique identifier and associates it to the WebSocketServer
sends the ID toInbox
Inbox
gets the unique identifier and makes it into a QRMailer
opens the web app and sets the data to send, and that opens a QR scannerMailer
scans theInbox
QR codeMailer
uses the QR to get and sends the unique identifier to theServer
, along with the dataServer
receives the data and forwards the message toInbox
Inbox
receives the data and displays it
Clear text?
Wait you are telling me this isn't secure GET ME OUT, LEMME OUT NOOOOOOOOOOoooooooooooooooooooo.
Okay so as far as it goes my code is naive in all the ways possibles, it uses WS when well doesn't really need to but that's not the worst, it's not encrypted.
So to fix that I went hunting for yet another library, in this case I found the wonderful webcryptobox.
With a new tool under my arm I device this flow:
Inbox
opens the web app and connects toServer
via WebSocketInbox
asks via WebSocket to get an idServer
generates unique identifier and associates it to the WebSocketServer
sends the ID toInbox
Inbox
generates an asymmetric key pair, and saves the private key in memoryInbox
puts the identifier and the public key in a QRMailer
opens the web app and sets the data to send, and that opens a QR scannerMailer
scans theInbox
QR codeMailer
uses the public key in the QR to encrypt the dataMailer
send the encrypted data and the unique identifier toServer
Server
receives the data and forwards the message toInbox
Inbox
receives the encrypted data through the serverInbox
uses the private key to get the contents of the data
Oh wait we have another problem, when setting up the PWA we can only use URLParams for the data, meaning that our data gets exposed to the server.
I still haven't found a solution for that, but I do have made a clipboard option which basically makes it so the when you get to the scan page, it grabs your clipboard there. No unencrypted data is sent to the server.
Future
So I have quite the bit prepared for this web app going on the future:
- Migrating to Vite as the build engine
- Making UI very much nicer
- Adding the ability to stream encrypted files through WebRTC
- Adding a way to use the
Mailer
as a communicator between twoInbox
es
Hopefully some day I get with it, so far I will just enjoy the use of it at places like work and school, so I can privately share my passwords without a hassle.