feat: dedicated login page for oauth2 logins

This commit is contained in:
fromme committed 2026-09-27 13:43:17 +02:00
1 parent 56adf72d12
commit 2aa98b81fe
8 files changed
+376 -69

No files matched your search

+1 -13
View File
@@ -1,18 +1,6 @@
<div class="flex items-center justify-between">
<a href="{{ path('app_account') }}" title="zu meinem Account">
{# The operating entity depends on where the accommodation is, so its logo wins over the host's #}
{% set country_logo = accommodation|default(null) and accommodation.country ? accommodation.country.logo : null %}
{% if country_logo %}
<img src="{{ asset('build/images/' ~ country_logo) }}" alt="" class="h-14 my-1 w-auto">
{% elseif booking_theme() == 'sbw' %}
<img src="{{ asset('build/images/logo_sbw.svg') }}" alt="" class="h-10 my-2 w-auto">
{% elseif booking_theme() == 'ser' %}
<img src="{{ asset('build/images/logo_ser.svg') }}" alt="" class="h-10 my-2 w-auto">
{% elseif booking_theme() == 'snz' %}
<img src="{{ asset('build/images/logo_snz.svg') }}" alt="" class="h-10 my-2 w-auto">
{% else %}
<img src="{{ asset('build/images/logo_ep.svg') }}" alt="" class="h-10 my-2 w-auto">
{% endif %}
{% include '_partials/_logo.html.twig' %}
</a>
<div class="flex items-center space-x-2">
{% if is_granted('ROLE_USER') %}
+47
View File
@@ -0,0 +1,47 @@
{# The login form itself, shared by security/login.html.twig and security/login_oauth2.html.twig so
the field names, the CSRF token id and the error rendering cannot drift between the two pages.
Expects `error` and `last_username` from the including template's context. #}
{% if error %}
{% include '_partials/_alert.html.twig' with { 'level': 'error', messages: [ error.messageKey|trans(error.messageData, 'security') ] } %}
{% endif %}
<div class="pb-4">
<form action="{{ path('app_login') }}" method="post">
<div class="mb-4">
<label for="username" class="mb-1 font-semibold text-white">
E-Mail:
</label>
<input type="email"
id="username"
name="_username"
value="{{ last_username }}"
class="form-field"
required
autocomplete="username">
</div>
<div class="mb-4" {{ stimulus_controller('password-reveal') }}>
<label for="password" class="mb-1 font-semibold text-white">
Passwort:
</label>
<div class="relative">
<input type="password"
id="password"
name="_password"
class="form-field"
{{ stimulus_target('password-reveal', 'field') }}
required
autocomplete="current-password">
<button type="button"
{{ stimulus_action('password-reveal', 'toggle') }}
class="absolute top-0 right-0 mt-2 mr-2">
{{ icon('eye', 'w-6 h-6 text-gray-500') }}
</button>
</div>
</div>
<div class="flex flex-col lg:flex-row space-y-2 lg:space-y-0 lg:space-x-2 mt-4">
<button type="submit" class="button button--primary">
Login
</button>
</div>
<input type="hidden" name="_csrf_token" value="{{ csrf_token('authenticate') }}">
</form>
</div>
+15
View File
@@ -0,0 +1,15 @@
{# The brand logo, extracted from _header.html.twig so the OAuth2 login chrome can show the same
logo without inheriting the account links that go with it. Takes an optional `accommodation`. #}
{# The operating entity depends on where the accommodation is, so its logo wins over the host's #}
{% set country_logo = accommodation|default(null) and accommodation.country ? accommodation.country.logo : null %}
{% if country_logo %}
<img src="{{ asset('build/images/' ~ country_logo) }}" alt="" class="h-14 my-1 w-auto">
{% elseif booking_theme() == 'sbw' %}
<img src="{{ asset('build/images/logo_sbw.svg') }}" alt="" class="h-10 my-2 w-auto">
{% elseif booking_theme() == 'ser' %}
<img src="{{ asset('build/images/logo_ser.svg') }}" alt="" class="h-10 my-2 w-auto">
{% elseif booking_theme() == 'snz' %}
<img src="{{ asset('build/images/logo_snz.svg') }}" alt="" class="h-10 my-2 w-auto">
{% else %}
<img src="{{ asset('build/images/logo_ep.svg') }}" alt="" class="h-10 my-2 w-auto">
{% endif %}
+14
View File
@@ -0,0 +1,14 @@
{# Chrome for a login that is serving an external OAuth2 authorization.
Only the logo survives from the normal header: the account and logout links are dead ends in the
middle of an authorization, and the marketing column of the standard login page is noise when the
user did not come here to read about MyE&P. The footer's legal links stay -- this page collects
credentials, so dropping them would be the wrong direction.
The background is inherited unchanged, which is why the shared form partial's `text-white`
styling still works here. #}
{% extends 'layout.html.twig' %}
{% block header %}
{% include '_partials/_logo.html.twig' %}
{% endblock %}
+1 -44
View File
@@ -7,50 +7,7 @@
Login<br>MyE&amp;P
</h1>
{% include '_partials/_flashes.html.twig' %}
{% if error %}
{% include '_partials/_alert.html.twig' with { 'level': 'error', messages: [ error.messageKey|trans(error.messageData, 'security') ] } %}
{% endif %}
<div class="pb-4">
<form action="{{ path('app_login') }}" method="post" hx-history="false">
<div class="mb-4">
<label for="username" class="mb-1 font-semibold text-white">
E-Mail:
</label>
<input type="email"
id="username"
name="_username"
value="{{ last_username }}"
class="form-field"
required
autocomplete="username">
</div>
<div class="mb-4" {{ stimulus_controller('password-reveal') }}>
<label for="password" class="mb-1 font-semibold text-white">
Passwort:
</label>
<div class="relative">
<input type="password"
id="password"
name="_password"
class="form-field"
{{ stimulus_target('password-reveal', 'field') }}
required
autocomplete="current-password">
<button type="button"
{{ stimulus_action('password-reveal', 'toggle') }}
class="absolute top-0 right-0 mt-2 mr-2">
{{ icon('eye', 'w-6 h-6 text-gray-500') }}
</button>
</div>
</div>
<div class="flex flex-col lg:flex-row space-y-2 lg:space-y-0 lg:space-x-2 mt-4">
<button type="submit" class="button button--primary">
Login
</button>
</div>
<input type="hidden" name="_csrf_token" value="{{ csrf_token('authenticate') }}">
</form>
</div>
{% include '_partials/_login_form.html.twig' %}
<div class="flex space-x-2">
<a href="{{ path('app_reset_password') }}"
class="text-white underline">
+37
View File
@@ -0,0 +1,37 @@
{# The login page as seen by someone who was sent here by another E&P application (ephub, myep-team)
to authorize it. Its job is to explain why they are suddenly on a different website and that they
will be sent back, which the standard login page never said.
The grid is the one from security/login.html.twig, minus its marketing column: that keeps the
form column at exactly the width it has on the standard login page. #}
{% extends 'layout_oauth2.html.twig' %}
{% block content %}
<div class="grid grid-cols-1 md:grid-cols-2 gap-8 px-4 lg:px-8 py-8 lg:py-16">
<div>
<h1 class="text-white uppercase pb-4 mb-8 border-b border-primary-bg/40">
{% if client_name %}
Anmelden für<br>{{ client_name }}
{% else %}
Login<br>MyE&amp;P
{% endif %}
</h1>
<p class="mb-6 text-white">
Melde dich mit deinem MyE&amp;P-Konto an. Anschließend wirst du automatisch
{% if client_name %}zu {{ client_name }} {% endif %}zurückgeleitet.
</p>
{% include '_partials/_login_form.html.twig' %}
<div class="flex space-x-2">
<a href="{{ path('app_reset_password') }}" class="text-white underline">
Passwort vergessen?
</a>
<a href="{{ path('app_registration') }}" class="text-white underline">
Jetzt registrieren
</a>
</div>
</div>
</div>
{% endblock %}