Skip to content
This repository has been archived by the owner on Jul 12, 2023. It is now read-only.

Commit

Permalink
Multi-factor selection at login (#633)
Browse files Browse the repository at this point in the history
* Multi-factor selection

* d-none

* use a div

* fixes

* fix button enable
  • Loading branch information
whaught authored Sep 22, 2020
1 parent ce15731 commit d904f0e
Show file tree
Hide file tree
Showing 3 changed files with 110 additions and 19 deletions.
24 changes: 20 additions & 4 deletions cmd/server/assets/login/_loginscripts.html
Original file line number Diff line number Diff line change
Expand Up @@ -52,14 +52,30 @@
<div class="form-label-group">
<input type="text" id="sms-code" name="sms-code" class="form-control" placeholder="Code" autocomplete="one-time-code" required autofocus />
<label for="sms-code">Code</label>
<small class="form-text text-muted">
Please enter the numerical code that was sent via SMS.
</small>
<div class='w-100'>
<small class="text-muted">
Please enter the numerical code that was sent via SMS.
</small>
</div>
<small class="text-muted" id='code-text'></small>
</div>

<button type="submit" id="sms-code-submit" class="btn btn-primary btn-block">Confirm code</button>
<a id="sms-code-resend" class="card-link btn-block disabled" disabled>Resend SMS</a>
<div class="btn-block">
<a id="sms-code-resend" class="card-link disabled" disabled>Resend SMS</a>
<a id="sms-change" class="card-link d-none" href="#">Change login factor</a>
</div>
</form>
</div>
</div>
{{end}}

{{define "login/factorsdiv"}}
<div class="card shadow-sm mb-3 d-none" id="registered-div">
<div class="card-header">Registered factors</div>
<div class="card-body">
<div id="factors" class="list-group list-group-flush">
</div>
</div>
</div>
{{end}}
92 changes: 86 additions & 6 deletions cmd/server/assets/login/login.html
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
</div>

{{template "login/pindiv" .}}
{{template "login/factorsdiv" .}}

</div>
</div>
Expand Down Expand Up @@ -69,13 +70,19 @@
let $password = $('#password');

let $pinDiv = $('#sms-code-div');
let $pinText = $('#code-text');
let $pinClose = $('#sms-code-close');
let $pinForm = $('#sms-code-form');
let $pin = $('#sms-code');
let $submitPin = $('#sms-code-submit');
let $resendPin = $('#sms-code-resend');
let $smsChange = $('#sms-change');

let $registeredDiv = $('#registered-div');
let $factors = $('#factors');

let verId = "";
let selectedFactorIndex = 0;

$form.on('submit', function(event) {
event.preventDefault();
Expand All @@ -90,10 +97,11 @@
.catch(function(error) {
if (error.code == 'auth/multi-factor-auth-required') {
resolver = error.resolver;
let selectedIndex = 0 // TODO: show list of factors
if (resolver.hints[selectedIndex].factorId === firebase.auth.PhoneMultiFactorGenerator.FACTOR_ID) {
populatePinText(resolver.hints);
populateFactors(resolver.hints);
if (resolver.hints[selectedFactorIndex].factorId === firebase.auth.PhoneMultiFactorGenerator.FACTOR_ID) {
let phoneInfoOptions = {
multiFactorHint: resolver.hints[selectedIndex],
multiFactorHint: resolver.hints[selectedFactorIndex],
session: resolver.session
};
let phoneAuthProvider = new firebase.auth.PhoneAuthProvider();
Expand Down Expand Up @@ -135,24 +143,38 @@
.catch(function(err) {
flash.clear();
flash.error(err.message);
$submit.prop('disabled', false);
$submitPin.prop('disabled', false);
});
});

$pinClose.on('click', function(event) {
event.preventDefault();
$submit.prop('disabled', false);
$factors.empty();
$loginDiv.show();
$pinDiv.addClass('d-none');
});

$resendPin.on('click', function(event) {
event.preventDefault();
resendPin();
});

$smsChange.on('click', function(event) {
event.preventDefault();
$pinDiv.addClass('d-none');
$registeredDiv.removeClass('d-none');
});

function resendPin() {
$resendPin.addClass('disabled');
setTimeout(function() { $resendPin.removeClass('disabled'); }, 15000);

let phoneInfoOptions = {
multiFactorHint: resolver.hints[0],
multiFactorHint: resolver.hints[selectedFactorIndex],
session: resolver.session
};
populatePinText(resolver.hints)
let phoneAuthProvider = new firebase.auth.PhoneAuthProvider();
phoneAuthProvider.verifyPhoneNumber(phoneInfoOptions, recaptchaVerifier)
.then(function(verificationId) {
Expand All @@ -162,7 +184,65 @@
flash.error(error.message);
$submit.prop('disabled', false);
});
});
}

function populatePinText(hints) {
let $displayName = $('<span/>');
$displayName.addClass('text-info');
$displayName.text(hints[selectedFactorIndex].displayName);

$pinText.empty();
$pinText.text('Code sent to ');
$pinText.append($displayName);
}

function populateFactors(hints) {
if (hints.length > 0) {
for (i = 0; i < hints.length; i++) {
appendAuthFactor(hints[i], i);
}
}
if (hints.length > 1) {
$smsChange.removeClass("d-none");
}
}

function appendAuthFactor(factor, i) {
let $li = $('<a/>');
$li.addClass('list-group-item list-group-item-action');
if (i == 0) {
$li.addClass('bg-light');
$li.attr('id', 'selected-factor');
}
let $row = $('<div/>').text(factor.displayName);
$li.append($row);

let $icon = $('<span/>');
$icon.addClass('oi oi-phone mr-1');
$icon.attr('aria-hidden','true');
$row.prepend($icon);

let $time = $('<small/>');
$time.addClass('row text-muted ml-1')
$time.text(`Phone number: ${factor.phoneNumber}`);
$row.append($time);

$li.on('click', function(event) {
$registeredDiv.addClass('d-none');
$pinDiv.removeClass('d-none');
if (selectedFactorIndex == i) {
return;
}

$('#selected-factor').removeClass('bg-light');
$li.addClass('bg-light');
$li.attr('id', 'selected-factor');
selectedFactorIndex = i;
resendPin();
});

$factors.append($li);
}
});
</script>
</body>
Expand Down
13 changes: 4 additions & 9 deletions cmd/server/assets/login/register-phone.html
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,7 @@
<div class="d-flex vh-100">
<div class="d-flex w-100 justify-content-center">
<div class="col-sm-6">
<div class="card shadow-sm mb-3 d-none" id="registered-div">
<div class="card-header">Registered factors</div>
<div class="card-body">
<ul id="factors" class="list-group list-group-flush">
</ul>
</div>
</div>
{{template "login/factorsdiv" .}}

<div class="card shadow-sm" id="register-div">
<div class="card-header">Multi-factor authentication</div>
Expand Down Expand Up @@ -81,7 +75,7 @@
</main>

{{template "scripts" .}}
<script>
<script type="text/javascript">
window.recaptchaVerifier = new firebase.auth.RecaptchaVerifier(
'recaptcha-container',
{ 'size': 'invisible' }
Expand Down Expand Up @@ -130,7 +124,7 @@
});

function appendAuthFactor(factor, i) {
let $li = $('<li/>');
let $li = $('<div/>');
$li.addClass('list-group-item');
$li.attr('id', `factor${factor.uid}`);

Expand Down Expand Up @@ -246,6 +240,7 @@
}).catch(function(err) {
flash.clear();
flash.error(err.message);
$submitPin.prop('disabled', false);
}).then(function() {
$submit.prop('disabled', false);
});
Expand Down

0 comments on commit d904f0e

Please sign in to comment.