Added new resource strings (prefix, link, suffix) for authenticator app setup instructions in German, English, and French resource files. Updated EnvelopeLocked.cshtml to assemble the instruction dynamically using these localized parts, ensuring correct grammar and flexibility across supported languages.
127 lines
6.6 KiB
Plaintext
127 lines
6.6 KiB
Plaintext
@using EnvelopeGenerator.Application.Common.Dto.EnvelopeReceiver;
|
|
@using Newtonsoft.Json
|
|
@using EnvelopeGenerator.Web.Extensions;
|
|
@model Auth;
|
|
@{
|
|
//TODO: Create view model
|
|
var nonce = _accessor.HttpContext?.Items["csp-nonce"] as string;
|
|
var cImg = _cImgOpt.Value;
|
|
string codeType = ViewData["CodeType"] is string _codeType ? _codeType : "accessCode";
|
|
string codeKeyName = (char.ToUpper(codeType[0]) + codeType.Substring(1)).Replace("Code", "");
|
|
ViewData["Title"] = _localizer.LockedTitle(codeKeyName);
|
|
bool viaSms = codeType == "smsCode";
|
|
bool viaAuthenticator = codeType == "authenticatorCode";
|
|
bool viaTFA = viaSms || viaAuthenticator;
|
|
DateTime? smsExpiration = ViewData["SmsExpiration"] is DateTime _smsExpiration ? _smsExpiration : null;
|
|
bool tfaEnabled = ViewData["TFAEnabled"] is bool _tfaEnabled && _tfaEnabled;
|
|
bool hasPhoneNumber = ViewData["HasPhoneNumber"] is bool _hasPhoneNumber && _hasPhoneNumber;
|
|
var envelopeKey = ViewData["EnvelopeKey"] as string;
|
|
DateTime? tfaRegDeadline = ViewData["TfaRegDeadline"] is DateTime _deadline ? _deadline : null;
|
|
var senderEmail = ViewData["SenderEmail"] as string ?? string.Empty;
|
|
var envelopeTitle = ViewData["EnvelopeTitle"] as string ?? string.Empty;
|
|
}
|
|
<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.WelcomeToTheESignPortal()</h3>
|
|
<img class="@cImg["Company"].GetClassIn("Locked")" src="@cImg["Company"].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.LockedTitle(codeKeyName)</h1>
|
|
</header>
|
|
@if (viaAuthenticator && (tfaRegDeadline is null || tfaRegDeadline > DateTime.Now))
|
|
{
|
|
<section class="text-center">
|
|
<p class="m-0 p-0">
|
|
@_localizer["AuthenticatorSetup_Prefix"]
|
|
<a class="icon-link m-0 p-0" href="/tfa/@envelopeKey" style="text-decoration: none;" target="_blank">
|
|
@_localizer["AuthenticatorSetup_Link"]
|
|
<i class="bi bi-box-arrow-up-right"></i>
|
|
</a>
|
|
@_localizer["AuthenticatorSetup_Suffix"]
|
|
</p>
|
|
</section>
|
|
}
|
|
<section class="text-center">
|
|
<p>@_localizer.LockedBody(codeKeyName)</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.LockedCodeLabel(codeKeyName)]" required="required">
|
|
<label for="access_code">@_localizer.LockedCodeLabel(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">
|
|
@errMsg
|
|
</div>
|
|
}
|
|
<section class="no-receiver-explanation text-center">
|
|
<details>
|
|
<summary>@_localizer.LockedFooterTitle(codeKeyName)</summary>
|
|
<p>@Html.Raw(_localizer.LockedFooterBody(codeKeyName).Format(senderEmail, "Envelope - " + envelopeTitle, string.Empty))</p>
|
|
</details>
|
|
</section>
|
|
</div>
|
|
@if (smsExpiration is not null)
|
|
{
|
|
<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>
|
|
} |