diff --git a/package-lock.json b/package-lock.json
index e88ac7464c..f7c3c8d1a2 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -6789,6 +6789,11 @@
"integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=",
"dev": true
},
+ "qrious": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/qrious/-/qrious-4.0.2.tgz",
+ "integrity": "sha512-xWPJIrK1zu5Ypn898fBp8RHkT/9ibquV2Kv24S/JY9VYEhMBMKur1gHVsOiNUh7PHP9uCgejjpZUHUIXXKoU/g=="
+ },
"qs": {
"version": "6.3.2",
"resolved": "https://registry.npmjs.org/qs/-/qs-6.3.2.tgz",
diff --git a/package.json b/package.json
index 80ba39f831..e855e6a6b9 100644
--- a/package.json
+++ b/package.json
@@ -71,6 +71,7 @@
"node-forge": "0.7.1",
"papaparse": "4.3.5",
"popper.js": "1.14.3",
+ "qrious": "4.0.2",
"rxjs": "5.5.6",
"sweetalert": "2.1.0",
"tldjs": "2.0.0",
diff --git a/src/app/settings/two-factor-authenticator.component.html b/src/app/settings/two-factor-authenticator.component.html
index 1eaa9b986a..4c768376da 100644
--- a/src/app/settings/two-factor-authenticator.component.html
+++ b/src/app/settings/two-factor-authenticator.component.html
@@ -49,8 +49,7 @@
-
-
+
{{key}}
diff --git a/src/app/settings/two-factor-authenticator.component.ts b/src/app/settings/two-factor-authenticator.component.ts
index ab52326733..fe6a100e35 100644
--- a/src/app/settings/two-factor-authenticator.component.ts
+++ b/src/app/settings/two-factor-authenticator.component.ts
@@ -1,4 +1,8 @@
-import { Component } from '@angular/core';
+import {
+ Component,
+ OnDestroy,
+ OnInit,
+} from '@angular/core';
import { ToasterService } from 'angular2-toaster';
import { Angulartics2 } from 'angulartics2';
@@ -19,17 +23,29 @@ import { TwoFactorBaseComponent } from './two-factor-base.component';
selector: 'app-two-factor-authenticator',
templateUrl: 'two-factor-authenticator.component.html',
})
-export class TwoFactorAuthenticatorComponent extends TwoFactorBaseComponent {
+export class TwoFactorAuthenticatorComponent extends TwoFactorBaseComponent implements OnInit, OnDestroy {
key: string;
- qr: string;
token: string;
formPromise: Promise;
+ private qrScript: HTMLScriptElement;
+
constructor(apiService: ApiService, i18nService: I18nService,
analytics: Angulartics2, toasterService: ToasterService,
private userService: UserService, platformUtilsService: PlatformUtilsService) {
super(apiService, i18nService, analytics, toasterService, platformUtilsService,
TwoFactorProviderType.Authenticator);
+ this.qrScript = window.document.createElement('script');
+ this.qrScript.src = 'scripts/qrious.min.js';
+ this.qrScript.async = true;
+ }
+
+ ngOnInit() {
+ window.document.body.appendChild(this.qrScript);
+ }
+
+ ngOnDestroy() {
+ window.document.body.removeChild(this.qrScript);
}
auth(authResponse: any) {
@@ -62,9 +78,14 @@ export class TwoFactorAuthenticatorComponent extends TwoFactorBaseComponent {
this.token = null;
this.enabled = response.enabled;
this.key = response.key;
- this.qr = 'https://chart.googleapis.com/chart?chs=160x160&chld=L|0&cht=qr&chl=otpauth://totp/' +
- 'Bitwarden:' + encodeURIComponent(await this.userService.getEmail()) +
- '%3Fsecret=' + encodeURIComponent(this.key) +
- '%26issuer=Bitwarden';
+ const email = await this.userService.getEmail();
+ window.setTimeout(() => {
+ const qr = new (window as any).QRious({
+ element: document.getElementById('qr'),
+ value: 'otpauth://totp/Bitwarden:' + encodeURIComponent(email) +
+ '?secret=' + encodeURIComponent(this.key) + '&issuer=Bitwarden',
+ size: 160,
+ });
+ }, 100);
}
}
diff --git a/webpack.config.js b/webpack.config.js
index a685a53451..8e5dd73104 100644
--- a/webpack.config.js
+++ b/webpack.config.js
@@ -103,6 +103,7 @@ const plugins = [
{ from: './src/images', to: 'images' },
{ from: './src/locales', to: 'locales' },
{ from: './src/scripts', to: 'scripts' },
+ { from: './node_modules/qrious/dist/qrious.min.js', to: 'scripts' },
]),
extractCss,
new webpack.DefinePlugin({