Skip to content

Commit cfc7493

Browse files
committed
Update the demo app to support TOTP enrollment, use local firebase auth version.
The QR code image is generated using the qrserver api at https://goqr.me/api/doc/
1 parent 33a8222 commit cfc7493

File tree

4 files changed

+90
-2
lines changed

4 files changed

+90
-2
lines changed

packages/auth/demo/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
},
1919
"dependencies": {
2020
"@firebase/app": "0.7.24",
21-
"@firebase/auth": "0.20.1",
21+
"@firebase/auth": "file:..",
2222
"@firebase/logger": "0.3.2",
2323
"@firebase/util": "1.6.0",
2424
"tslib": "^2.1.0"

packages/auth/demo/public/index.html

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -483,6 +483,12 @@
483483
Phone
484484
</a>
485485
</li>
486+
<li role="presentation">
487+
<a href="#mfa-totp-section" aria-controls="mfa-totp-section"
488+
data-toggle="tab" role="tab">
489+
TOTP
490+
</a>
491+
</li>
486492
</ul>
487493
<div class="tab-content">
488494
<div class="tab-pane active" id="mfa-phone-section">
@@ -500,7 +506,27 @@
500506
class="form-control" placeholder="Display Name" />
501507
<button class="btn btn-block btn-primary"
502508
id="enroll-mfa-confirm-phone-verification">
503-
Complete Enrollment
509+
Complete Phone Enrollment
510+
</button>
511+
512+
</form>
513+
</div>
514+
<div class="tab-pane" id="mfa-totp-section">
515+
<form class="form form-bordered no-submit">
516+
<button class="btn btn-block btn-primary" id="enroll-mfa-totp-start">
517+
Start TOTP Enrollment
518+
</button>
519+
<br>
520+
<p hidden class="totp-text" id="totp-text"> Please scan the QR code below in a TOTP app </p>
521+
<br>
522+
<img hidden class="totp-qr-image" id="totp-qr-image"/>
523+
<br>
524+
<input type="text" id="enroll-mfa-totp-verification-code"
525+
class="form-control" placeholder="TOTP Verification Code(from App)" />
526+
<input type="text" id="enroll-mfa-totp-display-name"
527+
class="form-control" placeholder="Display Name" />
528+
<button class="btn btn-block btn-primary" id="enroll-mfa-totp-finalize">
529+
Complete TOTP Enrollment
504530
</button>
505531
</form>
506532
</div>

packages/auth/demo/public/style.css

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,17 @@ input + .form,
177177
margin-right: 10px;
178178
}
179179

180+
.totp-text {
181+
font-family: 'Courier New', Courier;
182+
}
183+
.totp-qr-image {
184+
height: 120px;
185+
margin-right: 10px;
186+
border: 1px solid #ddd;
187+
border-radius: 4px;
188+
width: 120px;
189+
}
190+
180191
.profile-email-not-verified {
181192
color: #d9534f;
182193
}

packages/auth/demo/src/index.js

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ import {
4949
signInWithCredential,
5050
signInWithCustomToken,
5151
signInWithEmailAndPassword,
52+
TotpMultiFactorGenerator,
53+
TotpSecret,
5254
unlink,
5355
updateEmail,
5456
updatePassword,
@@ -97,6 +99,7 @@ let multiFactorErrorResolver = null;
9799
let selectedMultiFactorHint = null;
98100
let recaptchaSize = 'normal';
99101
let webWorker = null;
102+
let totpSecret = null;
100103

101104
// The corresponding Font Awesome icons for each provider.
102105
const providersIcons = {
@@ -652,6 +655,50 @@ function onFinalizeEnrollWithPhoneMultiFactor() {
652655
}, onAuthError);
653656
}
654657

658+
async function onStartEnrollWithTotpMultiFactor() {
659+
console.log('Starting TOTP enrollment!');
660+
if (!activeUser()) {
661+
alertError('No active user found.');
662+
return;
663+
}
664+
try {
665+
multiFactorSession = await multiFactor(activeUser()).getSession();
666+
totpSecret = await TotpMultiFactorGenerator.generateSecret(
667+
multiFactorSession
668+
);
669+
const url = totpSecret.generateQrCodeUrl('test', 'testissuer');
670+
console.log('TOTP URL is ' + url);
671+
// Use the QRServer API documented at https://goqr.me/api/doc/
672+
const qrCodeUrl = `https://api.qrserver.com/v1/create-qr-code/?data=${url}&amp;size=30x30`;
673+
$('img.totp-qr-image').attr('src', qrCodeUrl).show();
674+
$('p.totp-text').show();
675+
} catch (e) {
676+
onAuthError(e);
677+
}
678+
}
679+
680+
async function onFinalizeEnrollWithTotpMultiFactor() {
681+
const verificationCode = $('#enroll-mfa-totp-verification-code').val();
682+
if (!activeUser() || !totpSecret || !verificationCode) {
683+
alertError(' Missing active user OR TOTP secret OR verification code.');
684+
return;
685+
}
686+
687+
const multiFactorAssertion = TotpMultiFactorGenerator.assertionForEnrollment(
688+
totpSecret,
689+
verificationCode
690+
);
691+
const displayName = $('#enroll-mfa-totp-display-name').val() || undefined;
692+
693+
try {
694+
await multiFactor(activeUser()).enroll(multiFactorAssertion, displayName);
695+
refreshUserData();
696+
alertSuccess('TOTP MFA enrolled!');
697+
} catch (e) {
698+
onAuthError(e);
699+
}
700+
}
701+
655702
/**
656703
* Signs in or links a provider's credential, based on current tab opened.
657704
* @param {!AuthCredential} credential The provider's credential.
@@ -1944,6 +1991,10 @@ function initApp() {
19441991
$('#enroll-mfa-confirm-phone-verification').click(
19451992
onFinalizeEnrollWithPhoneMultiFactor
19461993
);
1994+
// Starts multi-factor enrollment with TOTP.
1995+
$('#enroll-mfa-totp-start').click(onStartEnrollWithTotpMultiFactor);
1996+
// Completes multi-factor enrollment with supplied OTP(One-Time Password).
1997+
$('#enroll-mfa-totp-finalize').click(onFinalizeEnrollWithTotpMultiFactor);
19471998
}
19481999

19492000
$(initApp);

0 commit comments

Comments
 (0)