jstrieb / link-lock

Password-protect URLs using AES in the browser; create hidden bookmarks without a browser extension
https://jstrieb.github.io/link-lock
MIT License
860 stars 159 forks source link

TypeError: Cannot read property 'importKey' of undefined #3

Closed ghost closed 3 years ago

ghost commented 4 years ago

When I try to self-host the site I get this error when filling out the form and pressing the encrypt button on the main index.html page:

api.js:45 Uncaught (in promise) TypeError: Cannot read property 'importKey' of undefined
    at Object.deriveKey (api.js:45)
    at Object.encrypt (api.js:74)
    at generateFragment (create.js:70)
    at async onEncrypt (create.js:138)

Any idea what's going on?

jstrieb commented 4 years ago

I have not yet had time to run this locally and thus replicate the issue, but I suspect it has to do with the SubtleCrypto API requiring HTTPS in order to run in some browsers. See the top of this MDN reference page. (Personally, I think this requirement is stupid in this case.) My guess is that local files are not considered "secure contexts," which is why the browser prevents using the API. Note that when the API is not available, it is unintuitively left undefined as you have discovered.

Hopefully this weekend I will have the time to take a closer look and confirm that this is, in fact, the cause of your problem.

In the meantime, if you are on a Unix system and have Python installed, you can run the following from the command-line to generate an SSL certificate, and then run the subsequent Python code for a local HTTPS web server. That code and command were snatched from this StackOverflow answer.

Generate a certificate:

openssl req -new -x509 -keyout localhost.pem -out localhost.pem -days 365 -nodes

Run this Python code:

import http.server, ssl

server_address = ('localhost', 8000)
httpd = http.server.HTTPServer(server_address, http.server.SimpleHTTPRequestHandler)
httpd.socket = ssl.wrap_socket(httpd.socket,
                               server_side=True,
                               certfile='localhost.pem',
                               ssl_version=ssl.PROTOCOL_TLSv1)
httpd.serve_forever()