2FA and passwordless are two different things. There are already some packages for 2FA. If we want to add one to core then we should focus on 2FA via email and/or via authenticator app. I think there are currently a lot of things scheduled for 2.0 (as much as I would like to see these things). I would propose that we focus on this in 2.1 or at latest in 3.0.
I think it is very important to keep the authentication system flexible and avoid any tight coupling to a specific strategy. However, I support the idea to make it easier to support 2FA.
But beware this: From a domain driven development point of view the Meteor core is the “infrastructure” part that keeps enough flexibility to ease development of “your” software design and your authentication strategy. Tight integration of specific technologies can have very serious consequences.
Integrating 2FA into the core accounts is something that requires careful and thorough design and implementation to prevent lock-ins or interference with other strategies and ensure backwards compatibility.
I used speakeasy and made use of account hooks to fail logins if they have 2fa enabled, then redirect them to another method that would verify 2FA before logging them in with their password.
I used a meteor 2FA package as a reference for doing that.
I recently added 2FA to one of my projects, I wrote it as a package, but it isn’t quite ready for public consumption, and it isn’t as simple as plug and play, but it is very simple (even without my package).
It uses https://www.npmjs.com/package/otplib and https://www.npmjs.com/package/qrcode (to generate the One Time Password and QRCode respectively), I then hook into a custom login handler via Accounts.registerLoginHandler - I had to do this anyway as I was building a multi-tenant system, so adding the extra piece at the end to require a TFA code was easy.
The package itself exposes an ensureTfa function, that is called on login, or account creation - and throws one of three errors:
tfa-requires-setup which has the dataUri of the QRCode as a detail - thrown when the user has no TFA and needs to set it up
tfa-code-missing if the user didn’t enter a TFA - this is useful for multi-tenant systems where a TFA isn’t always required, and we don’t know until after they try to log in whether we need one or not.
tfa-code-bad - self explanatory.
I also hooked it up so it can be called easily from meteor methods - in case one needs to add TFA to particularly sensitive methods (e.g, updating the password).
The entire package is < 100 LOC (including the configuration to encrypt the secret, which is 25 lines by itself). I say this because I’m not sure it’s worth trying to packagize something that is:
so easy to do
so dependent on each use case (SMS, OTP, login only, login and specific methods, multi-tenant? Optional/required?)
I could fairly easily publish the piece that validates the code/generates the secret and throws the relevant errors, but people would still need to hook it into their login handler (or overwrite the default) - I could also do this, but then it wouldn’t play nice with all the custom setups that are out there - which is why I haven’t published it yet!