Second factor landing page, register multiple TOTP keys

During some flight time, I got curious about how web authentication and auth schemas worked, since I know we want to start to support it as a factor method, and started to investigate how it was implemented in certain spaces.

One thing that stands out to me is that all implementations have a landing page listing out all second factor forms - our implementation of TOTP codes currently does not have this page because we had initially only offered a single second factor method. I’d like to propose adding a second factor landing page to Discourse, to allow a central space for second factors to be registered.

With the landing page, we would then be able to list all types and instances of a user’s second factors, edit/remove existing factors, and register new ones.

I’d like to also take advantage of this page to and add support for multiple TOTP keys. It would be nice to be able to register new devices without unregistering all previous TOTP devices. (Curiously, few other sites allow for multiple TOTP registrations, and I’m not sure why. We can leave keep TOTP keys restricted to one per user if this is concerning.)

The resulting landing page (at /preferences/second-factor, after password confirmation) would look something like this (apologies for the ms paint work):

Adding a new authenticator app would deliver a similar modal with the same registration we’ve had before:

Other notes:
No other implementations I’ve seen ask for a confirmation before disabling the key, and I suggest we allow a signed in user to be able to remove keys at will with no additional confirmation.

Editing an existing key would allow a user to name the key, so a user can manage+delete keys semantically.

Disabling second factor will delete all a user’s tokens.

The work here would also make room for other types of second factors, such as managing web authn support. Yubico’s demo page has a pretty nice example of a page showing multiple types of tokens, and I suggest we adopt a similar stance on managing a user’s factors to help us get going in that direction.