To address the user field issue, one way would be to accept a field optional argument in the motp_auth constructor and query the db data using the optional argument or a default value.
motp_auth(..., userfield="email") And in the custom authentication code's query: db(db.auth_user[userfield] == <value>)...