Developer 02 3e6e2078bb feat(auth): Unterstützung für Authenticator-App-Setup-Link hinzugefügt
- Es wurde ein neuer Abschnitt eingeführt, der einen Link für Benutzer anzeigt, um ihre Authenticator-App einzurichten, wenn viaAuthenticator aktiviert ist.
 - Abruf von envelopeKey aus ViewData hinzugefügt, um den Einrichtungslink zu erstellen.
 - Refactored codeKeyName Initialisierung für saubereren Code.
2025-02-06 15:49:05 +01:00

122 lines
6.4 KiB
Plaintext

@using EnvelopeGenerator.Application.DTOs.EnvelopeReceiver;
@using Newtonsoft.Json
@model Auth;
@{
var nonce = _accessor.HttpContext?.Items["csp-nonce"] as string;
var logo = _logoOpt.Value;
ViewData["Title"] = _localizer[WebKey.DocProtected];
var userCulture = ViewData["UserCulture"] as Culture;
string codeType = ViewData["CodeType"] is string _codeType ? _codeType : "accessCode";
string codeKeyName = (char.ToUpper(codeType[0]) + codeType.Substring(1)).Replace("Code", "");
bool viaSms = codeType == "smsCode";
bool viaAuthenticator = codeType == "authenticatorCode";
bool viaTFA = viaSms || viaAuthenticator;
DateTime? smsExpiration = ViewData["SmsExpiration"] is DateTime _smsExpiration ? _smsExpiration : null;
DateTime? qrCodeExpiration = ViewData["QRCodeExpiration"] is DateTime _qrCodeExpiration ? _qrCodeExpiration : null;
bool tfaEnabled = ViewData["TFAEnabled"] is bool _tfaEnabled && _tfaEnabled;
bool hasPhoneNumber = ViewData["HasPhoneNumber"] is bool _hasPhoneNumber && _hasPhoneNumber;
var envelopeKey = ViewData["EnvelopeKey"] as string;
}
<div class="page container py-4 px-4">
<header class="text-center">
<div class="header-1 alert alert-secondary" role="alert">
<h3 class="text">@_localizer[WebKey.WelcomeToTheESignPortal]</h3>
<img class="@logo.LockedPageClass" src="@logo.Src" />
</div>
<div class="icon locked @(viaTFA ? "tfa" : "") mt-4 mb-1">
<svg xmlns="http://www.w3.org/2000/svg" width="72" height="72" fill="currentColor" class="bi bi-shield-lock" viewBox="0 0 16 16">
<path d="M5.338 1.59a61 61 0 0 0-2.837.856.48.48 0 0 0-.328.39c-.554 4.157.726 7.19 2.253 9.188a10.7 10.7 0 0 0 2.287 2.233c.346.244.652.42.893.533q.18.085.293.118a1 1 0 0 0 .101.025 1 1 0 0 0 .1-.025q.114-.034.294-.118c.24-.113.547-.29.893-.533a10.7 10.7 0 0 0 2.287-2.233c1.527-1.997 2.807-5.031 2.253-9.188a.48.48 0 0 0-.328-.39c-.651-.213-1.75-.56-2.837-.855C9.552 1.29 8.531 1.067 8 1.067c-.53 0-1.552.223-2.662.524zM5.072.56C6.157.265 7.31 0 8 0s1.843.265 2.928.56c1.11.3 2.229.655 2.887.87a1.54 1.54 0 0 1 1.044 1.262c.596 4.477-.787 7.795-2.465 9.99a11.8 11.8 0 0 1-2.517 2.453 7 7 0 0 1-1.048.625c-.28.132-.581.24-.829.24s-.548-.108-.829-.24a7 7 0 0 1-1.048-.625 11.8 11.8 0 0 1-2.517-2.453C1.928 10.487.545 7.169 1.141 2.692A1.54 1.54 0 0 1 2.185 1.43 63 63 0 0 1 5.072.56" />
<path d="M9.5 6.5a1.5 1.5 0 0 1-1 1.415l.385 1.99a.5.5 0 0 1-.491.595h-.788a.5.5 0 0 1-.49-.595l.384-1.99a1.5 1.5 0 1 1 2-1.415" />
</svg>
</div>
<h1>@_localizer[WebKey.Formats.LockedTitle.Format(codeKeyName)]</h1>
</header>
@if (viaAuthenticator)
{
<section class="text-center">
<p class="m-0 p-0">
Klicken Sie auf den
<a class="icon-link m-0 p-0" href="/tfa/@envelopeKey" style="text-decoration: none;" target="_blank">
Link
<i class="bi bi-box-arrow-up-right"></i>
</a>
um Ihre Authenticator-App einzurichten.
</p>
</section>
}
<section class="text-center">
<p>@_localizer[WebKey.Formats.LockedBody.Format(codeKeyName)].Value.Format(qrCodeExpiration.ToString())</p>
</section>
<div class="row m-0 p-0">
<div class="access-code-panel justify-content-center align-items-center p-0 m-0">
<form id="form-access-code" class="form form-floating mb-0" method="post">
<div class="form-floating access-code-form-floating">
<input type="password" id="access_code" class="form-control" name="@codeType" placeholder="@_localizer[WebKey.Formats.LockedCodeLabel.Format(codeKeyName)]" required="required">
<label for="access_code">@_localizer[WebKey.Formats.LockedCodeLabel.Format(codeKeyName)]</label>
<button type="submit" class="btn btn-primary">
<span class="material-symbols-outlined">
login
</span>
</button>
@if (tfaEnabled)
{
<div class="form-check form-switch tfa-sms">
@if(hasPhoneNumber)
{
<input asp-for="UserSelectSMS" class="form-check-input" name="userSelectSMS" type="checkbox" role="switch" id="flexSwitchCheckChecked">
}
else
{
<input asp-for="UserSelectSMS" class="form-check-input" name="userSelectSMS" type="checkbox" role="switch" id="flexSwitchCheckChecked" disabled>
}
<label class="form-check-label" for="flexSwitchCheckChecked">2FA per SMS</label>
</div>
}
@if (smsExpiration is not null)
{
<div id="sms-timer" class="alert alert-primary" role="alert">00:00</div>
}
</div>
</form>
</div>
</div>
@if (ViewData["ErrorMessage"] is string errMsg)
{
<div id="access-code-error-message" class="alert alert-danger row" role="alert">
@_sanitizer.Sanitize(errMsg)
</div>
}
<section class="no-receiver-explanation text-center">
<details>
<summary>@_localizer[WebKey.Formats.LockedFooterTitle.Format(codeKeyName)]</summary>
<p>@_localizer[WebKey.Formats.LockedFooterBody.Format(codeKeyName)]</p>
</details>
</section>
</div>
<script nonce="@nonce">
var expiration = new Date(@Html.Raw(JsonConvert.SerializeObject(smsExpiration)));
const element = document.getElementById("sms-timer");
const interval = setInterval(function () {
var now = new Date();
var diffInMillis = expiration - now;
if (diffInMillis <= 0) {
element.textContent = "00:00";
clearInterval(interval);
return;
}
var minutes = Math.floor(diffInMillis / 1000 / 60);
var seconds = Math.floor((diffInMillis / 1000) % 60);
var formattedMinutes = minutes.toString().padStart(2, '0');
var formattedSeconds = seconds.toString().padStart(2, '0');
var remainingTime = `${formattedMinutes}:${formattedSeconds}`;
element.textContent = remainingTime;
}, 1000);
</script>