Unify 2FA login boxes (#4506)

* Unify 2FA login boxes

* 2FA setup: Make auth code copyable
This commit is contained in:
d11n
2023-01-09 16:38:03 +01:00
committed by GitHub
parent ffeaf55c4e
commit bb733c5811
6 changed files with 33 additions and 30 deletions

View File

@@ -1,7 +1,7 @@
@model LoginWith2faViewModel
<div class="twoFaBox">
<h2 class="h3 mb-3">Two-factor authentication</h2>
<h2 class="h3 mb-3">Two-Factor Authentication</h2>
<form method="post" asp-route-returnUrl="@ViewData["ReturnUrl"]" asp-action="LoginWith2fa">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<input asp-for="RememberMe" type="hidden"/>

View File

@@ -9,14 +9,14 @@
</form>
<h2 class="h3 mb-3">FIDO2 Authentication</h2>
<p>Insert your security device and proceed.</p>
<div id="info-message" class="alert alert-info mb-3 d-none">
<div id="info-message" class="alert alert-info mb-0 d-none">
<div class="d-flex align-items-center">
<span id="spinner" class="fa fa-spinner fa-spin me-3 mt-1 fido-running" style="font-size:1.5rem"></span>
<span>If your security device has a button, tap on it.</span>
</div>
</div>
<button id="btn-start" class="btn btn-primary d-none" type="button">Start</button>
<p id="error-message" class="d-none alert alert-danger"></p>
<p id="error-message" class="d-none alert alert-danger mb-4"></p>
<button id="btn-retry" class="btn btn-secondary d-none" type="button">Retry</button>
<script>

View File

@@ -3,7 +3,7 @@
Dictionary<string, string> formats = new Dictionary<string, string>()
{
{ "Bech32", LNURL.LNURL.EncodeUri(Model.LNURLEndpoint, "login", true).ToString().ToUpperInvariant() },
{ "URI", LNURL.LNURL.EncodeUri(Model.LNURLEndpoint, "login", true).ToString().ToUpperInvariant() }
{ "URI", LNURL.LNURL.EncodeUri(Model.LNURLEndpoint, "login", false).ToString().ToUpperInvariant() }
};
}
@@ -12,28 +12,27 @@
<input type="hidden" asp-for="LNURLEndpoint"/>
<input type="hidden" asp-for="UserId"/>
</form>
<h2 class="h3 mb-3">LNURL Auth</h2>
<div class="align-items-center">
<ul class="nav justify-content-center my-2">
@for (int i = 0; i < formats.Count; i++)
<h2 class="h3 mb-3">LNURL Authentication</h2>
<p>Scan the QR code with your Lightning wallet to sign in.</p>
<div class="align-items-center" style="width:256px">
<ul class="nav my-3 btcpay-pills align-items-center gap-2">
@for (var i = 0; i < formats.Count; i++)
{
var mode = formats.ElementAt(i);
<li class="nav-item">
<a class="btcpay-pill @(i == 0 ? "active" : "")"
data-bs-toggle="tab" data-bs-target="#@mode.Key" role="tab"
href="#">
<a class="btcpay-pill @(i == 0 ? "active" : "")" data-bs-toggle="tab" data-bs-target="#@mode.Key" role="tab" href="#">
@mode.Key
</a>
</li>
}
</ul>
<div class="tab-content">
@for (int i = 0; i < formats.Count; i++)
@for (var i = 0; i < formats.Count; i++)
{
var mode = formats.ElementAt(i);
<div class="tab-pane text-center @(i == 0 ? "active" : "")" id="@mode.Key" role="tabpanel">
<div class="qr-container" style="min-height: 256px;">
<vc:qr-code data="@mode.Value"></vc:qr-code>
<div class="tab-pane @(i == 0 ? "active" : "")" id="@mode.Key" role="tabpanel">
<div class="qr-container" style="min-height:256px">
<vc:qr-code data="@mode.Value" />
</div>
<a href="@mode.Value" class="btn btn-primary mt-3" rel="noreferrer noopener">
Open in wallet
@@ -41,7 +40,6 @@
</div>
}
</div>
<p>Scan the QR code with your lightning wallet and link to your user account.</p>
</div>
</div>

View File

@@ -6,7 +6,7 @@
<div class="col-xl-8 col-xxl-constrain">
<h3>Enable Authenticator</h3>
<p class="my-3">To use an authenticator app go through the following steps:</p>
<ol class="list">
<ol class="ps-3">
<li class="mb-5">
<div class="mb-2">Download a two-factor authenticator app like …</div>
<ul>
@@ -29,10 +29,10 @@
</li>
<li class="mb-5">
<p class="mb-2">Scan the QR Code or enter the following key into your two-factor authenticator app:</p>
<p class="mb-4">
<code class="me-3">@Model.SharedKey</code>
<span class="text-secondary">(spaces and casing do not matter)</span>
</p>
<div class="input-group input-group-sm mb-4">
<input readonly class="form-control font-monospace" value="@Model.SharedKey" id="SharedKey" style="max-width:20rem">
<button type="button" class="btn btn-outline-secondary" data-clipboard-target="#SharedKey">Copy</button>
</div>
<div id="qrCode"></div>
<div id="qrCodeData" data-url="@Model.AuthenticatorUri"></div>
</li>

View File

@@ -4,9 +4,14 @@ function confirmCopy(el, message) {
el.style.minWidth = el.getBoundingClientRect().width + 'px';
}
el.innerHTML = `<span class="text-success">${message}</span>`;
setTimeout(function () {
if (el.dataset.clipboardHandler) {
clearTimeout(parseInt(el.dataset.clipboardHandler));
}
const timeoutId = setTimeout(function () {
el.innerHTML = el.dataset.clipboardInitial;
el.dataset.clipboardHandler = null;
}, 2500);
el.dataset.clipboardHandler = timeoutId.toString();
}
window.copyToClipboard = async function (e, data) {
@@ -48,13 +53,14 @@ window.copyUrlToClipboard = function (e) {
document.addEventListener("DOMContentLoaded", function () {
delegate('click', '[data-clipboard]', function (e) {
const data = e.target.closest('[data-clipboard]').getAttribute('data-clipboard')
const target = e.target.closest('[data-clipboard]');
const data = target.getAttribute('data-clipboard') || target.innerText || target.value;
window.copyToClipboard(e, data)
})
delegate('click', '[data-clipboard-target]', function (e) {
const selector = e.target.closest('[data-clipboard-target]').getAttribute('data-clipboard-target')
const selector = e.target.closest('[data-clipboard-target]').getAttribute('data-clipboard-target');
const target = document.querySelector(selector)
const data = target.innerText
const data = target.innerText || target.value;
window.copyToClipboard(e, data)
})
})

View File

@@ -82,16 +82,15 @@ function showErrorAlert(message, error) {
el.classList.add("d-none");
}
document.getElementById("error-message").classList.remove("d-none");
}
function detectFIDOSupport() {
if (window.PublicKeyCredential === undefined ||
typeof window.PublicKeyCredential !== "function") {
//$('#register-button').attr("disabled", true);
//$('#login-button').attr("disabled", true);
var el = document.getElementById("error-message");
el.textContent = "Your browser does not support FIDO2/WebAuthN";
const el = document.getElementById("error-message");
el.textContent = location.protocol === "http:"
? "FIDO2/WebAuthN requires HTTPS"
: "Your browser does not support FIDO2/WebAuthN";
el.classList.remove("d-none");
return false;
}