diff --git a/cmd/server/assets/login/_loginscripts.html b/cmd/server/assets/login/_loginscripts.html index 640c8bde3..0fbdc4076 100644 --- a/cmd/server/assets/login/_loginscripts.html +++ b/cmd/server/assets/login/_loginscripts.html @@ -52,14 +52,30 @@
- - Please enter the numerical code that was sent via SMS. - +
+ + Please enter the numerical code that was sent via SMS. + +
+
- Resend SMS +
+ Resend SMS + Change login factor +
{{end}} + +{{define "login/factorsdiv"}} +
+
Registered factors
+
+
+
+
+
+{{end}} \ No newline at end of file diff --git a/cmd/server/assets/login/login.html b/cmd/server/assets/login/login.html index 4527bf9f0..3845c2201 100644 --- a/cmd/server/assets/login/login.html +++ b/cmd/server/assets/login/login.html @@ -39,6 +39,7 @@ {{template "login/pindiv" .}} + {{template "login/factorsdiv" .}} @@ -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(); @@ -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(); @@ -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) { @@ -162,7 +184,65 @@ flash.error(error.message); $submit.prop('disabled', false); }); - }); + } + + function populatePinText(hints) { + let $displayName = $(''); + $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 = $(''); + $li.addClass('list-group-item list-group-item-action'); + if (i == 0) { + $li.addClass('bg-light'); + $li.attr('id', 'selected-factor'); + } + let $row = $('
').text(factor.displayName); + $li.append($row); + + let $icon = $(''); + $icon.addClass('oi oi-phone mr-1'); + $icon.attr('aria-hidden','true'); + $row.prepend($icon); + + let $time = $(''); + $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); + } }); diff --git a/cmd/server/assets/login/register-phone.html b/cmd/server/assets/login/register-phone.html index 1b4e5cd4e..dbf3a1ea3 100644 --- a/cmd/server/assets/login/register-phone.html +++ b/cmd/server/assets/login/register-phone.html @@ -19,13 +19,7 @@
-
-
Registered factors
-
-
    -
-
-
+ {{template "login/factorsdiv" .}}
Multi-factor authentication
@@ -81,7 +75,7 @@ {{template "scripts" .}} -