various two factor auth improvements

(not to be merged yet)

* [x] implement TOTP checking in postgres
* [ ] move two factor auth verification to postgres
* [ ] remove the frontend's direct access to read TOTP secrets, but still let it set them
* [ ] require 2fa at the database level for protected actions like login, withdrawal and turning off 2fa
* [ ] make one time use codes in case of lost TOTP secrets
Should we check for null? If the id is used only after a successful authentication check, maybe it's not necessary to explicitly check for null but we could have `select into strict` so it throws if no secret is returned, making the function return either true or false.