diff --git a/management/daemon.py b/management/daemon.py index 2752593..f4f972d 100755 --- a/management/daemon.py +++ b/management/daemon.py @@ -128,12 +128,18 @@ def me(): try: email, privs = auth_service.authenticate(request, env) except ValueError as e: - # Log the failed login - log_failed_login(request) - return json_response({ - "status": "invalid", - "reason": str(e), - }) + if "missing-totp-token" in str(e): + return json_response({ + "status": "missing-totp-token", + "reason": str(e), + }) + else: + # Log the failed login + log_failed_login(request) + return json_response({ + "status": "invalid", + "reason": str(e), + }) resp = { "status": "ok", @@ -408,11 +414,12 @@ def mfa_get_status(): def totp_post_enable(): secret = request.form.get('secret') token = request.form.get('token') + label = request.form.get('label') if type(token) != str: return json_response({ "error": 'bad_input' }, 400) try: validate_totp_secret(secret) - enable_mfa(request.user_email, "totp", secret, token, env) + enable_mfa(request.user_email, "totp", secret, token, label, env) except ValueError as e: return str(e) return "OK" diff --git a/management/mfa.py b/management/mfa.py index af696ac..4db0ac9 100644 --- a/management/mfa.py +++ b/management/mfa.py @@ -15,13 +15,13 @@ def get_user_id(email, c): def get_mfa_state(email, env): c = open_database(env) - c.execute('SELECT id, type, secret, mru_token FROM mfa WHERE user_id=?', (get_user_id(email, c),)) + c.execute('SELECT id, type, secret, mru_token, label FROM mfa WHERE user_id=?', (get_user_id(email, c),)) return [ - { "id": r[0], "type": r[1], "secret": r[2], "mru_token": r[3] } + { "id": r[0], "type": r[1], "secret": r[2], "mru_token": r[3], "label": r[4] } for r in c.fetchall() ] -def enable_mfa(email, type, secret, token, env): +def enable_mfa(email, type, secret, token, label, env): if type == "totp": validate_totp_secret(secret) # Sanity check with the provide current token. @@ -32,7 +32,7 @@ def enable_mfa(email, type, secret, token, env): raise ValueError("Invalid MFA type.") conn, c = open_database(env, with_connection=True) - c.execute('INSERT INTO mfa (user_id, type, secret) VALUES (?, ?, ?)', (get_user_id(email, c), type, secret)) + c.execute('INSERT INTO mfa (user_id, type, secret, label) VALUES (?, ?, ?, ?)', (get_user_id(email, c), type, secret, label)) conn.commit() def set_mru_token(email, token, env): diff --git a/management/templates/index.html b/management/templates/index.html index 8fdb7c2..12f6ad8 100644 --- a/management/templates/index.html +++ b/management/templates/index.html @@ -93,16 +93,18 @@
When two-factor authentication is enabled, you will be prompted to enter a six digit code from an +authenticator app (usually on your phone) when you log into this control panel.
+ +