When using 2-factor-authentication using plain TOTP, the secret is stored on both the client and the server. This in turn means, that anyone with access to the database (and a key for it) knows the 2fa-secret of all the users. Why is this acceptable? Storing plaintext passwords has been deemed unacceptable a long time ago.
Public key cryptography is a perfect solution for this; one could combine it with TOTP. The client generates a private/public-key pair and the TOTP-secret and sends the public key and the secret to the server. The client then generates a TOTP-token, encrypts it with the private key and sends it to the server which can then verify it. Note that this encryption could also be implemented inside an app like "Google Authenticator" in a way that the user would just have to type it out as well.
This solution seems a lot better to me as nobody on the server-side can know the private key. Why is it, or any other such alternative, not used in practice?