diff --git a/backend/MESSAGE_CODES b/backend/MESSAGE_CODES new file mode 100644 index 0000000000000000000000000000000000000000..bc46a5b8d21ecd96827b3e9a2c5f41f0d3c8bf30 --- /dev/null +++ b/backend/MESSAGE_CODES @@ -0,0 +1,21 @@ + + +List of message codes used in the frontend + + + +Kratos codes: +============= + +4000006 The provided credentials are invalid, check for spelling mistakes + in your password or username, email address, or phone number. + + +1010003 Please confirm this action by verifying that it is you. + + +Stackspin codes: +================ + +S_CONFIRM_CREDENTIALS Please confirm your credentials to complete this action. + diff --git a/backend/web/login/login.py b/backend/web/login/login.py index 99851d29d462201163971db83884eba015fb27b7..424767b3e98455004181b7d9d1ee4c02e28c518a 100644 --- a/backend/web/login/login.py +++ b/backend/web/login/login.py @@ -131,12 +131,52 @@ def login(): # Check if we are logged in: identity = get_auth() + # List to contain messages pushed to the frontend + messages = list() + + refresh = False flow = request.args.get("flow") if flow: cookies = request.headers['cookie'] flow = kratos_public_frontend_api.get_login_flow(flow, cookie=cookies) refresh = flow['refresh'] + if refresh: + message = { + "id": "S_CONFIRM_CREDENTIALS", + "message": "Please confirm your credentials to complete this action.", + "type": "info" + } + messages.append(message) + try: + for msg in flow.ui.messages.value: + current_app.logger.info("Kratos message:" + msg.text) + if msg.id == 4000006: + message = { + "id": msg.id, + "message": "The provided login e-mail address or password is incorrect. Please try again.", + "type": "error" + } + else: + message = { + "id": msg.id, + "message": msg.text, + } + + if msg.type == 'error': + message['type'] = 'error' + else: + message['type'] = 'info' + + messages.append(message) + + except ory_kratos_client.exceptions.ApiAttributeError as ex: + # This exception is expected when there are no messages + pass + except Exception as ex: + # An unkown exception happens, we log the error but continue as it + # only affects the messages part + current_app.logger.error("Unknown exception: " + str(ex)) if identity and not refresh: # We are already logged in, and don't need to refresh. @@ -164,7 +204,9 @@ def login(): # or `not identity` # User is not logged in yet. # In either case, we present the login screen now. - return render_template("login.html", api_url=KRATOS_PUBLIC_URL, dashboard_url=DASHBOARD_URL, refresh=refresh, demo=DEMO_INSTANCE) + return render_template("login.html", api_url=KRATOS_PUBLIC_URL, + dashboard_url=DASHBOARD_URL, messages=messages, + demo=DEMO_INSTANCE) @web.route("/auth", methods=["GET", "POST"]) diff --git a/backend/web/static/base.js b/backend/web/static/base.js index a2cf2f18a5dbde19742883e1de748804a8a997f1..3499d5fe83ee651be147a294349aa5584a0773a1 100644 --- a/backend/web/static/base.js +++ b/backend/web/static/base.js @@ -20,6 +20,24 @@ // before calling the scripts (and configured by the flask app var dashboard_url = ''; +// Render a message by appending the data to the messages box. The message id is +// availble, potentially for future translations/locale handling +// @param string id Message ID\ +// @param string message Message in the default language (English) +// @param string type Type of message, currently only "error" renders in +// 'danger'. Others render in 'info' +function renderMessage(id, message, type) { + // Default class for messages + var class_name = 'info'; + if (type == 'error') { + class_name = 'danger'; + } + let html = '<div class="alert alert-'+class_name+'">'; + html = html + message + html = html + "</div>"; + $("#messages").append( html ); +} + // Check if an auth flow is configured and redirect to auth page in that // case. function check_flow_auth() { diff --git a/backend/web/templates/base.html b/backend/web/templates/base.html index 081453028d4f0b389f77dbac03dbd0056cc2cb1b..e2db15b126e52964fe23d905c4d08a65f37ca77b 100644 --- a/backend/web/templates/base.html +++ b/backend/web/templates/base.html @@ -13,6 +13,7 @@ <body> + <script> var api_url = '{{ api_url }}'; @@ -34,6 +35,8 @@ <a href="{{ dashboard_url }}"><img src='static/logo.svg'/></a><br/><br/> + <div id='messages'></div> + {% block content %}{% endblock %} diff --git a/backend/web/templates/login.html b/backend/web/templates/login.html index 6b1f04731b972f72b969407dd05e02fdf5f9cee8..79db1512e62920d9c24866caf1c3f6be0c85ceb3 100644 --- a/backend/web/templates/login.html +++ b/backend/web/templates/login.html @@ -12,12 +12,12 @@ flow_login(); }); + // Render messages + {% for message in messages %} + renderMessage('{{ message['id'] }}', '{{ message['message'] }}', '{{ message['type'] }}'); + {% endfor %} </script> - -{% if refresh %} - <div class="alert alert-warning">Please confirm your credentials to complete this action.</div> -{% endif %} <div id="contentMessages"></div> <div id="contentLogin_password"></div> <div id="contentLogin_totp"></div>