Hi there! This week I thought I'd take a step back and tell you more how authentication works in Lotus and what issues I need to solve to complete it.
When you start Lotus for the first time, you will see this window that asks you to "Log in with GitHub" to use the app. It's a standard OAuth flow, but inside the desktop app.
By the way, I should definitely animate the logo the same way it's done on getlotus.app.
After you click that button, it opens a modal window which loads a GitHub page to start the authentication flow.
You'll notice that it says "Authorizing will redirect to http://localhost:19952" at the bottom. This is where Lotus starts an HTTP server and where GitHub is going to redirect you after you authorize or deny Lotus access to your GitHub account. This local server lives until GitHub sends the user back to Lotus and authentication is done. When you're normally using the app, this server isn't running.
As you see, it's pretty simple, but I do have a few things I need to check off my list to call this part of the app "done".
Now this one is not so much a problem as just me being lazy. I still need to implement error handling for the OAuth flow, in case user denies access to Lotus. I also need to update the "main" part of the app to open the authentication flow when your access token has been expired or revoked (invalidated).
GitHub provides two keys that are necessary to initiate and complete the authentication flow
The problem is, I have to store these inside the source code, because all authentication happens inside the app, locally. Client ID is ok to expose, but client secret isn't. After all it's named "secret" for a reason. I remembered that there was an official GitHub desktop app, so I went to its repository to see how those folks did it. Turns out they were also storing these same keys in the source code, so I figured it's probably fine.
I can think of only one alternative path to avoid exposing the client secret key. I could launch a similar server in the cloud, which would handle the same authentication flow and somehow pass the final access token back to Lotus. Perhaps using window.postMessage API. Not a big fan of this idea, because I'd need to maintain that server all the time, but I'm going to keep that option in mind in case the local way to authenticate doesn't work out.
For now I'm storing access token inside a config file, which is unencrypted. That means, theoretically, that malware can scan your file system for any text that resembles an API key and send it somewhere. I'll definitely need to find a secure way to store the access token. On Mac, a keychain is probably the best place for such data and I'm 99% sure there's already a Node.js library to interact with it. Alternatively, I could encode the config file at the very least, so that user's access token is not in plain sight.
Overall I like how the authentication currently works. It's certainly better than asking users to go and create their personal access tokens and copy paste them into Lotus.
There are security concerns for sure, which I must handle before the launch. If you know of a better way to implement a local OAuth flow, please reach out, I'd appreciate it!
P.S. Replies to this email aren't currently working, but feel free to talk to me directly at email@example.com.
I'm building Lotus in the open and I'm sending out progress updates just like this one every Sunday.
I won't send spam and you can unsubscribe anytime.