diff --git a/application/single_app/app.py b/application/single_app/app.py index 5c77d1b17..40a7c59c3 100644 --- a/application/single_app/app.py +++ b/application/single_app/app.py @@ -1149,8 +1149,14 @@ def index(): # Convert Markdown to HTML safely landing_html = markdown_filter(landing_text) + signed_in_account = get_signed_in_account_display(session.get("user")) - return render_template('index.html', app_settings=public_settings, landing_html=landing_html) + return render_template( + 'index.html', + app_settings=public_settings, + landing_html=landing_html, + signed_in_account=signed_in_account, + ) @public_app_bp.route('/robots933456.txt') @swagger_route(security=get_auth_security()) diff --git a/application/single_app/functions_authentication.py b/application/single_app/functions_authentication.py index 1062a86b1..2d68194f5 100644 --- a/application/single_app/functions_authentication.py +++ b/application/single_app/functions_authentication.py @@ -1095,6 +1095,26 @@ def get_current_user_info(): } +def get_signed_in_account_display(user): + """Return safe identity labels for the access-denied account display.""" + if not isinstance(user, dict): + return {"name": "", "account": ""} + + name = user.get("name") if isinstance(user.get("name"), str) else "" + account = "" + for claim_name in ("email", "mail", "preferred_username"): + claim_value = user.get(claim_name) + if not isinstance(claim_value, str): + continue + + candidate = claim_value.strip() + if candidate and "#ext#" not in candidate.lower(): + account = candidate + break + + return {"name": name.strip(), "account": account} + + def _normalize_authority(authority_base, tenant_id): """Normalize an authority URL and append tenant when appropriate.""" base = (authority_base or "").strip().rstrip("/") diff --git a/application/single_app/route_frontend_authentication.py b/application/single_app/route_frontend_authentication.py index db795d249..857e02b2b 100644 --- a/application/single_app/route_frontend_authentication.py +++ b/application/single_app/route_frontend_authentication.py @@ -172,6 +172,7 @@ def login(): session.pop("last_activity_epoch", None) clear_requested_oauth_scopes() + select_account = request.args.get('select_account') == '1' is_teams_login = request.args.get('teams', 'false').lower() == 'true' if is_teams_login and ENABLE_TEAMS_SSO: settings = get_settings() or {} @@ -213,10 +214,14 @@ def login(): debug_print(f"Front Door enabled: {settings.get('enable_front_door', False)}") debug_print(f"Using redirect_uri for Azure AD: {redirect_uri}") - auth_url = msal_app.get_authorization_request_url( - scopes=SCOPE, # Use SCOPE from config (includes offline_access) - redirect_uri=redirect_uri - ) + authorization_request = { + "scopes": SCOPE, + "redirect_uri": redirect_uri, + } + if select_account: + authorization_request["prompt"] = "select_account" + + auth_url = msal_app.get_authorization_request_url(**authorization_request) print("Redirecting to Azure AD for authentication.") #auth_url= auth_url.replace('https://', 'http://') # Ensure HTTPS for security return redirect(auth_url) diff --git a/application/single_app/static/css/styles.css b/application/single_app/static/css/styles.css index 5e35e2b01..611092e26 100644 --- a/application/single_app/static/css/styles.css +++ b/application/single_app/static/css/styles.css @@ -46,6 +46,44 @@ main { --bs-body-color: #e9ecef; } +.account-switch-button, +.account-switch-button:visited { + color: #495057; + border-color: #495057; +} + +.account-switch-button:hover, +.account-switch-button:focus-visible { + color: #ffffff; + background-color: #495057; + border-color: #495057; +} + +.account-switch-button:active { + color: #ffffff; + background-color: #343a40; + border-color: #343a40; +} + +[data-bs-theme="dark"] .account-switch-button, +[data-bs-theme="dark"] .account-switch-button:visited { + color: #f8f9fa; + border-color: #f8f9fa; +} + +[data-bs-theme="dark"] .account-switch-button:hover, +[data-bs-theme="dark"] .account-switch-button:focus-visible { + color: #212529; + background-color: #f8f9fa; + border-color: #f8f9fa; +} + +[data-bs-theme="dark"] .account-switch-button:active { + color: #212529; + background-color: #e9ecef; + border-color: #e9ecef; +} + /* Theme-based logo visibility */ [data-bs-theme="light"] .d-dark-mode-only { display: none !important; diff --git a/application/single_app/templates/index.html b/application/single_app/templates/index.html index 2e32b5ff0..b624c30f9 100644 --- a/application/single_app/templates/index.html +++ b/application/single_app/templates/index.html @@ -65,11 +65,26 @@
{{ app_settings.access_denied_message | nl2br }}
- {% if app_settings.access_request_button_enabled and app_settings.access_request_page_url %} - - {{ app_settings.access_request_button_text or 'Request Access' }} +Signed in as
++ {{ signed_in_account.name or 'Microsoft account' }} +
+ {% if signed_in_account.account %} +{{ signed_in_account.account }}
+ {% endif %} +