Implement basic two-factor (TOTP) authentication

The following 2FA features are **not** implemented in this pull request:
- invalidating used codes
- tolerance for out-of-sync client clocks

Also, please keep the following in mind:
- I have not audited `speakeasy`, the Node.js package used to generate the 2FA secrets and verify the one-time passwords.
- The secrets are stored unencrypted in the database. In itself that is not an issue since the server needs access to them in unencrypted form anyways, but a database leak would reveal the secrets. One possible solution is to encrypt the secrets with a key that is stored in a file that's not under version control.