mirror of
https://github.com/Part-DB/Part-DB-server.git
synced 2025-07-23 20:35:03 +02:00
Added 2FA with U2F keys.
This commit is contained in:
parent
47fa8b04e5
commit
069293a843
18 changed files with 512 additions and 157 deletions
|
@ -16,6 +16,10 @@
|
|||
<a class="nav-link" id="backup-tab" data-toggle="tab" href="#tfa-backup" role="tab"
|
||||
aria-controls="profile" aria-selected="false">{% trans %}tfa.settings.bakup.tab{% endtrans %}</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" id="u2f-tab" data-toggle="tab" href="#tfa-u2f" role="tab"
|
||||
aria-controls="profile" aria-selected="false">{% trans %}tfa.settings.u2f.tab{% endtrans %}</a>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="tab-content mt-3 mb-3" id="tfa-tabs-content">
|
||||
<div class="tab-pane fade show active" id="tfa-google" role="tabpanel" aria-labelledby="google-tab">
|
||||
|
@ -90,6 +94,37 @@
|
|||
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<div class="tab-pane fade" id="tfa-u2f" role="tabpanel" aria-labelledby="u2f-tab">
|
||||
<p>{% trans %}tfa_u2f.explanation{% endtrans %}</p>
|
||||
|
||||
{% if user.u2FKeys is not empty %}
|
||||
<b>{% trans %}tfa_u2f.table_caption{% endtrans %}:</b>
|
||||
<table class="table table-striped table-bordered table-sm mt-2">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>#</th>
|
||||
<th>{% trans %}tfa_u2f.keys.name{% endtrans %}</th>
|
||||
<th>{% trans %}tfa_u2f.keys.added_date{% endtrans %}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for key in user.u2FKeys %}
|
||||
<tr>
|
||||
<td>{{ loop.index }}</td>
|
||||
<td>{{ key.name }}</td>
|
||||
<td>{{ key.addedDate | format_datetime }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
{% else %}
|
||||
<p><b>{% trans %}tfa_u2f.no_keys_registered{% endtrans %}</b></p>
|
||||
{% endif %}
|
||||
|
||||
<a href="{{ url('club_base_register_u2f') }}" class="btn btn-success"><i class="fas fa-plus-square fa-fw"></i> {% trans %}tfa_u2f.add_new_key{% endtrans %}</a>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
|
|
@ -123,6 +123,10 @@
|
|||
<script src="{{ preload(asset(js), {as: 'script'}) }}"></script>
|
||||
{% endfor %}
|
||||
|
||||
{% for js in encore_entry_js_files('ru2ftwofactor') %}
|
||||
<script src="{{ preload(asset(js), {as: 'script'}) }}"></script>
|
||||
{% endfor %}
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block scripts %}
|
||||
|
|
58
templates/security/2fa_base_form.html.twig
Normal file
58
templates/security/2fa_base_form.html.twig
Normal file
|
@ -0,0 +1,58 @@
|
|||
{% extends "main_card.html.twig" %}
|
||||
|
||||
{% block title %}{% trans %}tfa.check.title{% endtrans %}{% endblock %}
|
||||
|
||||
{% block card_title %}<i class="fas fa-shield-alt"></i> {% trans %}tfa.check.title{% endtrans %}{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
{% if authenticationError %}
|
||||
<div class="alert alert-danger" role="alert">
|
||||
<strong>{{ authenticationError|trans(authenticationErrorData, 'SchebTwoFactorBundle') }}}</strong>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{{ parent() }}
|
||||
{% endblock %}
|
||||
|
||||
{% block card_content %}
|
||||
<ul class="nav nav-pills mb-4">
|
||||
{% for provider in availableTwoFactorProviders %}
|
||||
<li class="nav-item">
|
||||
<a class="nav-link {% if provider == twoFactorProvider %}active{% endif %}"
|
||||
href="{{ path("2fa_login", {"preferProvider": provider}) }}">{{ 'tfa.provider.'~provider | trans }}</a>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
|
||||
{# Display current two-factor provider #}
|
||||
|
||||
<form class="form form-horizontal" action="{{ path("2fa_login_check") }}" method="post" {% block form_attributes %}{% endblock %}>
|
||||
{% block form %}
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% if displayTrustedOption %}
|
||||
<div class="form-group row mt-3">
|
||||
<div class="offset-3">
|
||||
<div class="custom-checkbox custom-control ml-2">
|
||||
<input id="_trusted" class="custom-control-input" type="checkbox" name="{{ trustedParameterName }}" />
|
||||
<label class="custom-control-label" for="_trusted">{% trans %}tfa.code.trusted_pc{% endtrans %}</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if isCsrfProtectionEnabled %}
|
||||
<input type="hidden" name="{{ csrfParameterName }}" value="{{ csrf_token(csrfTokenId) }}">
|
||||
{% endif %}
|
||||
|
||||
{% block submit_btn %}
|
||||
<div class="form-group-row">
|
||||
<div class="offset-3">
|
||||
<button type="submit" class="btn btn-primary" value="{{ "login"|trans({}, 'SchebTwoFactorBundle') }}">{% trans %}login.btn{% endtrans %}</button>
|
||||
<a class="ml-2" href="{{ logoutPath }}">{% trans %}user.logout{% endtrans %}</a>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
</form>
|
||||
{% endblock %}
|
|
@ -1,61 +1,14 @@
|
|||
{% extends "main_card.html.twig" %}
|
||||
{% extends "security/2fa_base_form.html.twig" %}
|
||||
|
||||
{% block title %}{% trans %}tfa.check.title{% endtrans %}{% endblock %}
|
||||
|
||||
{% block card_title %}<i class="fas fa-shield-alt"></i> {% trans %}tfa.check.title{% endtrans %}{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
{% if authenticationError %}
|
||||
<div class="alert alert-danger" role="alert">
|
||||
<strong>{{ authenticationError|trans(authenticationErrorData, 'SchebTwoFactorBundle') }}}</strong>
|
||||
{% block form %}
|
||||
<div class="form-group row">
|
||||
<label for="_auth_code" class="col-form-label col-3">{% trans %}tfa.check.code.label{% endtrans %}</label>
|
||||
<div class="col-9">
|
||||
<input id="_auth_code" class="form-control" type="text" autocomplete="off" name="{{ authCodeParameterName }}" autofocus />
|
||||
<small id="passwordHelpBlock" class="form-text text-muted">
|
||||
{% trans %}tfa.check.code.help{% endtrans %}
|
||||
</small>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{{ parent() }}
|
||||
{% endblock %}
|
||||
|
||||
{% block card_content %}
|
||||
<ul class="nav nav-pills mb-4">
|
||||
{% for provider in availableTwoFactorProviders %}
|
||||
<li class="nav-item">
|
||||
<a class="nav-link {% if provider == twoFactorProvider %}active{% endif %}"
|
||||
href="{{ path("2fa_login", {"preferProvider": provider}) }}">{{ 'tfa.provider.'~provider | trans }}</a>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
|
||||
{# Display current two-factor provider #}
|
||||
|
||||
<form class="form form-horizontal" action="{{ path("2fa_login_check") }}" method="post">
|
||||
<div class="form-group row">
|
||||
<label for="_auth_code" class="col-form-label col-3">{% trans %}tfa.check.code.label{% endtrans %}</label>
|
||||
<div class="col-9">
|
||||
<input id="_auth_code" class="form-control" type="text" autocomplete="off" name="{{ authCodeParameterName }}" autofocus />
|
||||
<small id="passwordHelpBlock" class="form-text text-muted">
|
||||
{% trans %}tfa.check.code.help{% endtrans %}
|
||||
</small>
|
||||
</div>
|
||||
</div>
|
||||
{% if displayTrustedOption %}
|
||||
<div class="form-group row mt-3">
|
||||
<div class="offset-3">
|
||||
<div class="custom-checkbox custom-control ml-2">
|
||||
<input id="_trusted" class="custom-control-input" type="checkbox" name="{{ trustedParameterName }}" />
|
||||
<label class="custom-control-label" for="_trusted">{% trans %}tfa.code.trusted_pc{% endtrans %}</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
|
||||
{% if isCsrfProtectionEnabled %}
|
||||
<input type="hidden" name="{{ csrfParameterName }}" value="{{ csrf_token(csrfTokenId) }}">
|
||||
{% endif %}
|
||||
<div class="form-group-row">
|
||||
<div class="offset-3">
|
||||
<button type="submit" class="btn btn-primary" value="{{ "login"|trans({}, 'SchebTwoFactorBundle') }}">{% trans %}login.btn{% endtrans %}</button>
|
||||
<a class="ml-2" href="{{ logoutPath }}">{% trans %}user.logout{% endtrans %}</a>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
{% endblock %}
|
16
templates/security/U2F/u2f_login.html.twig
Normal file
16
templates/security/U2F/u2f_login.html.twig
Normal file
|
@ -0,0 +1,16 @@
|
|||
{% extends "security/2fa_base_form.html.twig" %}
|
||||
|
||||
{% block form_attributes %}id="u2fForm" data-action="auth" data-request='{{ authenticationData|raw }}'{% endblock %}
|
||||
|
||||
{% block form %}
|
||||
{% if not app.request.secure %}
|
||||
<p class="text-warning"><b><i class="fas fa-exclamation-triangle fa-fw"></i> {% trans %}tfa_u2f.http_warning{% endtrans %}</b></p>
|
||||
{% endif %}
|
||||
|
||||
<div id="u2fpressbutton" style="display: none;" class="h4 text-center">{{ 'r_u2f_two_factor.pressbutton'|trans }}</div>
|
||||
<div id="u2fError"></div>
|
||||
<p class="widget"><input id="_auth_code" type="hidden" autocomplete="off" name="_auth_code" /></p>
|
||||
{% endblock %}
|
||||
|
||||
{% block submit_btn %}
|
||||
{% endblock %}
|
28
templates/security/U2F/u2f_register.html.twig
Normal file
28
templates/security/U2F/u2f_register.html.twig
Normal file
|
@ -0,0 +1,28 @@
|
|||
{% extends "main_card.html.twig" %}
|
||||
|
||||
{% block card_title %}<i class="fas fa-plus-square fa-fw"></i> {% trans %}tfa_u2f.add_key.title{% endtrans %}{% endblock %}
|
||||
|
||||
{% block card_content %}
|
||||
<p>{% trans %}tfa_u2f.explanation{% endtrans %}</p>
|
||||
<p><b>{% trans %}tfa_u2f.add_key.backup_hint{% endtrans %}</b></p>
|
||||
|
||||
{% if not app.request.secure %}
|
||||
<p class="text-warning"><b><i class="fas fa-exclamation-triangle fa-fw"></i> {% trans %}tfa_u2f.http_warning{% endtrans %}</b></p>
|
||||
{% endif %}
|
||||
|
||||
<form method="post" class="form" action="{{ path('club_base_register_u2f') }}" id="u2fForm" data-action="reg" data-request='{{ registrationRequest|raw }}'>
|
||||
<div id="u2fkeyname" class="form-group row">
|
||||
<div class="col-9">
|
||||
<input type="text" class="form-control " name="keyName" id="keyName" placeholder="{{ 'r_u2f_two_factor.name'|trans }}"/>
|
||||
</div>
|
||||
<div class="col-3">
|
||||
<button type="button" class="btn btn-success" onclick="u2fauth.register()">{% trans %}tfa_u2f.add_key.add_button{% endtrans %}</button>
|
||||
</div>
|
||||
</div>
|
||||
<div id="u2fpressbutton" style="display: none;" class="text-center h4">{{ 'r_u2f_two_factor.pressbutton'|trans }}</div>
|
||||
<input type="hidden" name="_auth_code" id="_auth_code" />
|
||||
<div id="u2fError" style="display: none;" class="text-center h4"></div>
|
||||
</form>
|
||||
|
||||
<a href="{{ url('user_settings') }}">{% trans %}tfa_u2f.add_key.back_to_settings{% endtrans %}</a>
|
||||
{% endblock %}
|
Loading…
Add table
Add a link
Reference in a new issue