diff options
author | Mike Greiling <mike@pixelcog.com> | 2018-03-01 18:13:50 +0000 |
---|---|---|
committer | Jacob Schatz <jschatz@gitlab.com> | 2018-03-01 18:13:50 +0000 |
commit | d79df7baf7426ca865958b9a5fecb0690a6a6ba3 (patch) | |
tree | 5bc4853789ef922ba636ce502f6d912a56f2f56c /app/assets/javascripts/u2f | |
parent | 868c27def75dde446c22872ae9b2bfc1e7eba969 (diff) | |
download | gitlab-ce-d79df7baf7426ca865958b9a5fecb0690a6a6ba3.tar.gz |
Remove u2f webpack bundle
Diffstat (limited to 'app/assets/javascripts/u2f')
-rw-r--r-- | app/assets/javascripts/u2f/authenticate.js | 26 | ||||
-rw-r--r-- | app/assets/javascripts/u2f/register.js | 27 | ||||
-rw-r--r-- | app/assets/javascripts/u2f/util.js | 42 |
3 files changed, 66 insertions, 29 deletions
diff --git a/app/assets/javascripts/u2f/authenticate.js b/app/assets/javascripts/u2f/authenticate.js index a3cc04e35fe..fd42f9c3baa 100644 --- a/app/assets/javascripts/u2f/authenticate.js +++ b/app/assets/javascripts/u2f/authenticate.js @@ -1,7 +1,5 @@ -/* eslint-disable func-names, wrap-iife */ -/* global u2f */ import _ from 'underscore'; -import isU2FSupported from './util'; +import importU2FLibrary from './util'; import U2FError from './error'; // Authenticate U2F (universal 2nd factor) devices for users to authenticate with. @@ -10,6 +8,7 @@ import U2FError from './error'; // State Flow #2: setup -> in_progress -> error -> setup export default class U2FAuthenticate { constructor(container, form, u2fParams, fallbackButton, fallbackUI) { + this.u2fUtils = null; this.container = container; this.renderNotSupported = this.renderNotSupported.bind(this); this.renderAuthenticated = this.renderAuthenticated.bind(this); @@ -50,22 +49,23 @@ export default class U2FAuthenticate { } start() { - if (isU2FSupported()) { - return this.renderInProgress(); - } - return this.renderNotSupported(); + return importU2FLibrary() + .then((utils) => { + this.u2fUtils = utils; + this.renderInProgress(); + }) + .catch(() => this.renderNotSupported()); } authenticate() { - return u2f.sign(this.appId, this.challenge, this.signRequests, (function (_this) { - return function (response) { + return this.u2fUtils.sign(this.appId, this.challenge, this.signRequests, + (response) => { if (response.errorCode) { const error = new U2FError(response.errorCode, 'authenticate'); - return _this.renderError(error); + return this.renderError(error); } - return _this.renderAuthenticated(JSON.stringify(response)); - }; - })(this), 10); + return this.renderAuthenticated(JSON.stringify(response)); + }, 10); } renderTemplate(name, params) { diff --git a/app/assets/javascripts/u2f/register.js b/app/assets/javascripts/u2f/register.js index cc3f02e75f6..869fac658e8 100644 --- a/app/assets/javascripts/u2f/register.js +++ b/app/assets/javascripts/u2f/register.js @@ -1,8 +1,5 @@ -/* eslint-disable func-names, wrap-iife */ -/* global u2f */ - import _ from 'underscore'; -import isU2FSupported from './util'; +import importU2FLibrary from './util'; import U2FError from './error'; // Register U2F (universal 2nd factor) devices for users to authenticate with. @@ -11,6 +8,7 @@ import U2FError from './error'; // State Flow #2: setup -> in_progress -> error -> setup export default class U2FRegister { constructor(container, u2fParams) { + this.u2fUtils = null; this.container = container; this.renderNotSupported = this.renderNotSupported.bind(this); this.renderRegistered = this.renderRegistered.bind(this); @@ -34,22 +32,23 @@ export default class U2FRegister { } start() { - if (isU2FSupported()) { - return this.renderSetup(); - } - return this.renderNotSupported(); + return importU2FLibrary() + .then((utils) => { + this.u2fUtils = utils; + this.renderSetup(); + }) + .catch(() => this.renderNotSupported()); } register() { - return u2f.register(this.appId, this.registerRequests, this.signRequests, (function (_this) { - return function (response) { + return this.u2fUtils.register(this.appId, this.registerRequests, this.signRequests, + (response) => { if (response.errorCode) { const error = new U2FError(response.errorCode, 'register'); - return _this.renderError(error); + return this.renderError(error); } - return _this.renderRegistered(JSON.stringify(response)); - }; - })(this), 10); + return this.renderRegistered(JSON.stringify(response)); + }, 10); } renderTemplate(name, params) { diff --git a/app/assets/javascripts/u2f/util.js b/app/assets/javascripts/u2f/util.js index 9771ff935c2..5778f00332d 100644 --- a/app/assets/javascripts/u2f/util.js +++ b/app/assets/javascripts/u2f/util.js @@ -1,3 +1,41 @@ -export default function isU2FSupported() { - return window.u2f; +function isOpera(userAgent) { + return userAgent.indexOf('Opera') >= 0 || userAgent.indexOf('OPR') >= 0; +} + +function getOperaVersion(userAgent) { + const match = userAgent.match(/OPR[^0-9]*([0-9]+)[^0-9]+/); + return match ? parseInt(match[1], 10) : false; +} + +function isChrome(userAgent) { + return userAgent.indexOf('Chrom') >= 0 && !isOpera(userAgent); +} + +function getChromeVersion(userAgent) { + const match = userAgent.match(/Chrom(?:e|ium)\/([0-9]+)\./); + return match ? parseInt(match[1], 10) : false; +} + +export function canInjectU2fApi(userAgent) { + const isSupportedChrome = isChrome(userAgent) && getChromeVersion(userAgent) >= 41; + const isSupportedOpera = isOpera(userAgent) && getOperaVersion(userAgent) >= 40; + const isMobile = ( + userAgent.indexOf('droid') >= 0 || + userAgent.indexOf('CriOS') >= 0 || + /\b(iPad|iPhone|iPod)(?=;)/.test(userAgent) + ); + return (isSupportedChrome || isSupportedOpera) && !isMobile; +} + +export default function importU2FLibrary() { + if (window.u2f) { + return Promise.resolve(window.u2f); + } + + const userAgent = typeof navigator !== 'undefined' ? navigator.userAgent : ''; + if (canInjectU2fApi(userAgent) || (gon && gon.test_env)) { + return import(/* webpackMode: "eager" */ 'vendor/u2f').then(() => window.u2f); + } + + return Promise.reject(); } |