{"version":3,"sources":["webpack:///./u2f/authenticate.js","webpack:///./shared/sessions/u2f.js","webpack:///./u2f/util.js","webpack:///./u2f/error.js","webpack:////builds/gitlab/gitlabhq/vendor/assets/javascripts/u2f.js"],"names":["U2FAuthenticate","container","form","u2fParams","fallbackButton","fallbackUI","_classCallCheck","this","u2fUtils","renderAuthenticated","bind","renderError","renderInProgress","renderTemplate","authenticate","start","appId","app_id","challenge","addEventListener","switchToFallbackUI","signRequests","sign_requests","map","request","_","omit","templates","setup","inProgress","error","authenticated","_this","importU2FLibrary","then","utils","catch","_this2","sign","response","errorCode","U2FError","JSON","stringify","name","params","templateString","$","html","template","error_message","message","error_code","find","on","deviceResponse","querySelector","value","submit","classList","add","remove","__webpack_exports__","gon","u2f","u2fAuthenticate","document","gl","isOpera","userAgent","indexOf","canInjectU2fApi","isSupportedChrome","isChrome","match","parseInt","getChromeVersion","isSupportedOpera","getOperaVersion","isMobile","test","window","Promise","resolve","navigator","test_env","__webpack_require__","t","reject","d","u2fFlowType","httpsDisabled","location","protocol","ErrorCodes","BAD_REQUEST","DEVICE_INELIGIBLE","js_api_version","EXTENSION_ID","MessageTypes","U2F_REGISTER_REQUEST","U2F_REGISTER_RESPONSE","U2F_SIGN_REQUEST","U2F_SIGN_RESPONSE","U2F_GET_API_VERSION_REQUEST","U2F_GET_API_VERSION_RESPONSE","OK","OTHER_ERROR","CONFIGURATION_UNSUPPORTED","TIMEOUT","U2fRequest","U2fResponse","Error","Transport","Transports","SignRequest","SignResponse","RegisterRequest","RegisterResponse","RegisteredKey","GetJsApiVersionResponse","getMessagePort","callback","chrome","runtime","msg","type","sendMessage","lastError","getIframePort_","getChromeRuntimePort_","isAndroidChrome_","getAuthenticatorPort_","isIosChrome_","getIosPort_","inArray","platform","port","connect","includeTlsChannelId","setTimeout","WrappedChromeRuntimePort_","WrappedAuthenticatorPort_","WrappedIosPort_","port_","formatSignRequest_","registeredKeys","timeoutSeconds","reqId","undefined","i","length","version","keyHandle","requestId","formatRegisterRequest_","registerRequests","prototype","postMessage","eventName","handler","toLowerCase","onMessage","addListener","data","console","requestId_","requestObject_","intentUrl","INTENT_URL_BASE_","encodeURIComponent","getPortType","onRequestUpdate_","messageObject","parse","responseObject","hasOwnProperty","str","url","encodeURI","replace","iframeOrigin","iframe","createElement","src","setAttribute","body","appendChild","channel","MessageChannel","ready","port1","removeEventListener","contentWindow","port2","EXTENSION_TIMEOUT_SEC","waitingForPort_","reqCounter_","callbackMap_","getPortSingleton_","shift","push","responseHandler_","cb","opt_timeoutSeconds","getApiVersion","log","sendSignRequest","req","register","sendRegisterRequest","apiVersion"],"mappings":"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","file":"commons~pages.ldap.omniauth_callbacks~pages.omniauth_callbacks~pages.sessions~pages.sessions.new.275a13f8.chunk.js","sourcesContent":["import $ from 'jquery';\nimport _ from 'underscore';\nimport importU2FLibrary from './util';\nimport U2FError from './error';\n\n// Authenticate U2F (universal 2nd factor) devices for users to authenticate with.\n//\n// State Flow #1: setup -> in_progress -> authenticated -> POST to server\n// State Flow #2: setup -> in_progress -> error -> setup\nexport default class U2FAuthenticate {\n constructor(container, form, u2fParams, fallbackButton, fallbackUI) {\n this.u2fUtils = null;\n this.container = container;\n this.renderAuthenticated = this.renderAuthenticated.bind(this);\n this.renderError = this.renderError.bind(this);\n this.renderInProgress = this.renderInProgress.bind(this);\n this.renderTemplate = this.renderTemplate.bind(this);\n this.authenticate = this.authenticate.bind(this);\n this.start = this.start.bind(this);\n this.appId = u2fParams.app_id;\n this.challenge = u2fParams.challenge;\n this.form = form;\n this.fallbackButton = fallbackButton;\n this.fallbackUI = fallbackUI;\n if (this.fallbackButton) {\n this.fallbackButton.addEventListener('click', this.switchToFallbackUI.bind(this));\n }\n\n // The U2F Javascript API v1.1 requires a single challenge, with\n // _no challenges per-request_. The U2F Javascript API v1.0 requires a\n // challenge per-request, which is done by copying the single challenge\n // into every request.\n //\n // In either case, we don't need the per-request challenges that the server\n // has generated, so we can remove them.\n //\n // Note: The server library fixes this behaviour in (unreleased) version 1.0.0.\n // This can be removed once we upgrade.\n // https://github.com/castle/ruby-u2f/commit/103f428071a81cd3d5f80c2e77d522d5029946a4\n this.signRequests = u2fParams.sign_requests.map(request => _(request).omit('challenge'));\n\n this.templates = {\n setup: '#js-authenticate-u2f-setup',\n inProgress: '#js-authenticate-u2f-in-progress',\n error: '#js-authenticate-u2f-error',\n authenticated: '#js-authenticate-u2f-authenticated',\n };\n }\n\n start() {\n return importU2FLibrary()\n .then(utils => {\n this.u2fUtils = utils;\n this.renderInProgress();\n })\n .catch(() => this.switchToFallbackUI());\n }\n\n authenticate() {\n return this.u2fUtils.sign(\n this.appId,\n this.challenge,\n this.signRequests,\n response => {\n if (response.errorCode) {\n const error = new U2FError(response.errorCode, 'authenticate');\n return this.renderError(error);\n }\n return this.renderAuthenticated(JSON.stringify(response));\n },\n 10,\n );\n }\n\n renderTemplate(name, params) {\n const templateString = $(this.templates[name]).html();\n const template = _.template(templateString);\n return this.container.html(template(params));\n }\n\n renderInProgress() {\n this.renderTemplate('inProgress');\n return this.authenticate();\n }\n\n renderError(error) {\n this.renderTemplate('error', {\n error_message: error.message(),\n error_code: error.errorCode,\n });\n return this.container.find('#js-u2f-try-again').on('click', this.renderInProgress);\n }\n\n renderAuthenticated(deviceResponse) {\n this.renderTemplate('authenticated');\n const container = this.container[0];\n container.querySelector('#js-device-response').value = deviceResponse;\n container.querySelector(this.form).submit();\n this.fallbackButton.classList.add('hidden');\n }\n\n switchToFallbackUI() {\n this.fallbackButton.classList.add('hidden');\n this.container[0].classList.add('hidden');\n this.fallbackUI.classList.remove('hidden');\n }\n}\n","import $ from 'jquery';\nimport U2FAuthenticate from '../../u2f/authenticate';\n\nexport default () => {\n if (!gon.u2f) return;\n\n const u2fAuthenticate = new U2FAuthenticate(\n $('#js-authenticate-u2f'),\n '#js-login-u2f-form',\n gon.u2f,\n document.querySelector('#js-login-2fa-device'),\n document.querySelector('.js-2fa-form'),\n );\n u2fAuthenticate.start();\n // needed in rspec\n gl.u2fAuthenticate = u2fAuthenticate;\n};\n","function isOpera(userAgent) {\n return userAgent.indexOf('Opera') >= 0 || userAgent.indexOf('OPR') >= 0;\n}\n\nfunction getOperaVersion(userAgent) {\n const match = userAgent.match(/OPR[^0-9]*([0-9]+)[^0-9]+/);\n return match ? parseInt(match[1], 10) : false;\n}\n\nfunction isChrome(userAgent) {\n return userAgent.indexOf('Chrom') >= 0 && !isOpera(userAgent);\n}\n\nfunction getChromeVersion(userAgent) {\n const match = userAgent.match(/Chrom(?:e|ium)\\/([0-9]+)\\./);\n return match ? parseInt(match[1], 10) : false;\n}\n\nexport function canInjectU2fApi(userAgent) {\n const isSupportedChrome = isChrome(userAgent) && getChromeVersion(userAgent) >= 41;\n const isSupportedOpera = isOpera(userAgent) && getOperaVersion(userAgent) >= 40;\n const isMobile =\n userAgent.indexOf('droid') >= 0 ||\n userAgent.indexOf('CriOS') >= 0 ||\n /\\b(iPad|iPhone|iPod)(?=;)/.test(userAgent);\n return (isSupportedChrome || isSupportedOpera) && !isMobile;\n}\n\nexport default function importU2FLibrary() {\n if (window.u2f) {\n return Promise.resolve(window.u2f);\n }\n\n const userAgent = typeof navigator !== 'undefined' ? navigator.userAgent : '';\n if (canInjectU2fApi(userAgent) || (gon && gon.test_env)) {\n return import(/* webpackMode: \"eager\" */ 'vendor/u2f').then(() => window.u2f);\n }\n\n return Promise.reject();\n}\n","export default class U2FError {\n constructor(errorCode, u2fFlowType) {\n this.errorCode = errorCode;\n this.message = this.message.bind(this);\n this.httpsDisabled = window.location.protocol !== 'https:';\n this.u2fFlowType = u2fFlowType;\n }\n\n message() {\n if (this.errorCode === window.u2f.ErrorCodes.BAD_REQUEST && this.httpsDisabled) {\n return 'U2F only works with HTTPS-enabled websites. Contact your administrator for more details.';\n } else if (this.errorCode === window.u2f.ErrorCodes.DEVICE_INELIGIBLE) {\n if (this.u2fFlowType === 'authenticate') {\n return 'This device has not been registered with us.';\n }\n if (this.u2fFlowType === 'register') {\n return 'This device has already been registered with us.';\n }\n }\n return 'There was a problem communicating with your device.';\n }\n}\n","//Copyright 2014-2015 Google Inc. All rights reserved.\n\n//Use of this source code is governed by a BSD-style\n//license that can be found in the LICENSE file or at\n//https://developers.google.com/open-source/licenses/bsd\n\n/**\n * @fileoverview The U2F api.\n */\n'use strict';\n\n\n/**\n * Namespace for the U2F api.\n * @type {Object}\n */\nvar u2f = u2f || {};\n\n/**\n * FIDO U2F Javascript API Version\n * @number\n */\nvar js_api_version;\n\n/**\n * The U2F extension id\n * @const {string}\n */\n// The Chrome packaged app extension ID.\n// Uncomment this if you want to deploy a server instance that uses\n// the package Chrome app and does not require installing the U2F Chrome extension.\nu2f.EXTENSION_ID = 'kmendfapggjehodndflmmgagdbamhnfd';\n// The U2F Chrome extension ID.\n// Uncomment this if you want to deploy a server instance that uses\n// the U2F Chrome extension to authenticate.\n// u2f.EXTENSION_ID = 'pfboblefjcgdjicmnffhdgionmgcdmne';\n\n\n/**\n * Message types for messsages to/from the extension\n * @const\n * @enum {string}\n */\nu2f.MessageTypes = {\n 'U2F_REGISTER_REQUEST': 'u2f_register_request',\n 'U2F_REGISTER_RESPONSE': 'u2f_register_response',\n 'U2F_SIGN_REQUEST': 'u2f_sign_request',\n 'U2F_SIGN_RESPONSE': 'u2f_sign_response',\n 'U2F_GET_API_VERSION_REQUEST': 'u2f_get_api_version_request',\n 'U2F_GET_API_VERSION_RESPONSE': 'u2f_get_api_version_response'\n};\n\n\n/**\n * Response status codes\n * @const\n * @enum {number}\n */\nu2f.ErrorCodes = {\n 'OK': 0,\n 'OTHER_ERROR': 1,\n 'BAD_REQUEST': 2,\n 'CONFIGURATION_UNSUPPORTED': 3,\n 'DEVICE_INELIGIBLE': 4,\n 'TIMEOUT': 5\n};\n\n\n/**\n * A message for registration requests\n * @typedef {{\n * type: u2f.MessageTypes,\n * appId: ?string,\n * timeoutSeconds: ?number,\n * requestId: ?number\n * }}\n */\nu2f.U2fRequest;\n\n\n/**\n * A message for registration responses\n * @typedef {{\n * type: u2f.MessageTypes,\n * responseData: (u2f.Error | u2f.RegisterResponse | u2f.SignResponse),\n * requestId: ?number\n * }}\n */\nu2f.U2fResponse;\n\n\n/**\n * An error object for responses\n * @typedef {{\n * errorCode: u2f.ErrorCodes,\n * errorMessage: ?string\n * }}\n */\nu2f.Error;\n\n/**\n * Data object for a single sign request.\n * @typedef {enum {BLUETOOTH_RADIO, BLUETOOTH_LOW_ENERGY, USB, NFC}}\n */\nu2f.Transport;\n\n\n/**\n * Data object for a single sign request.\n * @typedef {Array}\n */\nu2f.Transports;\n\n/**\n * Data object for a single sign request.\n * @typedef {{\n * version: string,\n * challenge: string,\n * keyHandle: string,\n * appId: string\n * }}\n */\nu2f.SignRequest;\n\n\n/**\n * Data object for a sign response.\n * @typedef {{\n * keyHandle: string,\n * signatureData: string,\n * clientData: string\n * }}\n */\nu2f.SignResponse;\n\n\n/**\n * Data object for a registration request.\n * @typedef {{\n * version: string,\n * challenge: string\n * }}\n */\nu2f.RegisterRequest;\n\n\n/**\n * Data object for a registration response.\n * @typedef {{\n * version: string,\n * keyHandle: string,\n * transports: Transports,\n * appId: string\n * }}\n */\nu2f.RegisterResponse;\n\n\n/**\n * Data object for a registered key.\n * @typedef {{\n * version: string,\n * keyHandle: string,\n * transports: ?Transports,\n * appId: ?string\n * }}\n */\nu2f.RegisteredKey;\n\n\n/**\n * Data object for a get API register response.\n * @typedef {{\n * js_api_version: number\n * }}\n */\nu2f.GetJsApiVersionResponse;\n\n\n//Low level MessagePort API support\n\n/**\n * Sets up a MessagePort to the U2F extension using the\n * available mechanisms.\n * @param {function((MessagePort|u2f.WrappedChromeRuntimePort_))} callback\n */\nu2f.getMessagePort = function(callback) {\n if (typeof chrome != 'undefined' && chrome.runtime) {\n // The actual message here does not matter, but we need to get a reply\n // for the callback to run. Thus, send an empty signature request\n // in order to get a failure response.\n var msg = {\n type: u2f.MessageTypes.U2F_SIGN_REQUEST,\n signRequests: []\n };\n chrome.runtime.sendMessage(u2f.EXTENSION_ID, msg, function() {\n if (!chrome.runtime.lastError) {\n // We are on a whitelisted origin and can talk directly\n // with the extension.\n u2f.getChromeRuntimePort_(callback);\n } else {\n // chrome.runtime was available, but we couldn't message\n // the extension directly, use iframe\n u2f.getIframePort_(callback);\n }\n });\n } else if (u2f.isAndroidChrome_()) {\n u2f.getAuthenticatorPort_(callback);\n } else if (u2f.isIosChrome_()) {\n u2f.getIosPort_(callback);\n } else {\n // chrome.runtime was not available at all, which is normal\n // when this origin doesn't have access to any extensions.\n u2f.getIframePort_(callback);\n }\n};\n\n/**\n * Detect chrome running on android based on the browser's useragent.\n * @private\n */\nu2f.isAndroidChrome_ = function() {\n var userAgent = navigator.userAgent;\n return userAgent.indexOf('Chrome') != -1 &&\n userAgent.indexOf('Android') != -1;\n};\n\n/**\n * Detect chrome running on iOS based on the browser's platform.\n * @private\n */\nu2f.isIosChrome_ = function() {\n return $.inArray(navigator.platform, [\"iPhone\", \"iPad\", \"iPod\"]) > -1;\n};\n\n/**\n * Connects directly to the extension via chrome.runtime.connect.\n * @param {function(u2f.WrappedChromeRuntimePort_)} callback\n * @private\n */\nu2f.getChromeRuntimePort_ = function(callback) {\n var port = chrome.runtime.connect(u2f.EXTENSION_ID,\n {'includeTlsChannelId': true});\n setTimeout(function() {\n callback(new u2f.WrappedChromeRuntimePort_(port));\n }, 0);\n};\n\n/**\n * Return a 'port' abstraction to the Authenticator app.\n * @param {function(u2f.WrappedAuthenticatorPort_)} callback\n * @private\n */\nu2f.getAuthenticatorPort_ = function(callback) {\n setTimeout(function() {\n callback(new u2f.WrappedAuthenticatorPort_());\n }, 0);\n};\n\n/**\n * Return a 'port' abstraction to the iOS client app.\n * @param {function(u2f.WrappedIosPort_)} callback\n * @private\n */\nu2f.getIosPort_ = function(callback) {\n setTimeout(function() {\n callback(new u2f.WrappedIosPort_());\n }, 0);\n};\n\n/**\n * A wrapper for chrome.runtime.Port that is compatible with MessagePort.\n * @param {Port} port\n * @constructor\n * @private\n */\nu2f.WrappedChromeRuntimePort_ = function(port) {\n this.port_ = port;\n};\n\n/**\n * Format and return a sign request compliant with the JS API version supported by the extension.\n * @param {Array} signRequests\n * @param {number} timeoutSeconds\n * @param {number} reqId\n * @return {Object}\n */\nu2f.formatSignRequest_ =\n function(appId, challenge, registeredKeys, timeoutSeconds, reqId) {\n if (js_api_version === undefined || js_api_version < 1.1) {\n // Adapt request to the 1.0 JS API\n var signRequests = [];\n for (var i = 0; i < registeredKeys.length; i++) {\n signRequests[i] = {\n version: registeredKeys[i].version,\n challenge: challenge,\n keyHandle: registeredKeys[i].keyHandle,\n appId: appId\n };\n }\n return {\n type: u2f.MessageTypes.U2F_SIGN_REQUEST,\n signRequests: signRequests,\n timeoutSeconds: timeoutSeconds,\n requestId: reqId\n };\n }\n // JS 1.1 API\n return {\n type: u2f.MessageTypes.U2F_SIGN_REQUEST,\n appId: appId,\n challenge: challenge,\n registeredKeys: registeredKeys,\n timeoutSeconds: timeoutSeconds,\n requestId: reqId\n };\n };\n\n/**\n * Format and return a register request compliant with the JS API version supported by the extension..\n * @param {Array} signRequests\n * @param {Array} signRequests\n * @param {number} timeoutSeconds\n * @param {number} reqId\n * @return {Object}\n */\nu2f.formatRegisterRequest_ =\n function(appId, registeredKeys, registerRequests, timeoutSeconds, reqId) {\n if (js_api_version === undefined || js_api_version < 1.1) {\n // Adapt request to the 1.0 JS API\n for (var i = 0; i < registerRequests.length; i++) {\n registerRequests[i].appId = appId;\n }\n var signRequests = [];\n for (var i = 0; i < registeredKeys.length; i++) {\n signRequests[i] = {\n version: registeredKeys[i].version,\n challenge: registerRequests[0],\n keyHandle: registeredKeys[i].keyHandle,\n appId: appId\n };\n }\n return {\n type: u2f.MessageTypes.U2F_REGISTER_REQUEST,\n signRequests: signRequests,\n registerRequests: registerRequests,\n timeoutSeconds: timeoutSeconds,\n requestId: reqId\n };\n }\n // JS 1.1 API\n return {\n type: u2f.MessageTypes.U2F_REGISTER_REQUEST,\n appId: appId,\n registerRequests: registerRequests,\n registeredKeys: registeredKeys,\n timeoutSeconds: timeoutSeconds,\n requestId: reqId\n };\n };\n\n\n/**\n * Posts a message on the underlying channel.\n * @param {Object} message\n */\nu2f.WrappedChromeRuntimePort_.prototype.postMessage = function(message) {\n this.port_.postMessage(message);\n};\n\n\n/**\n * Emulates the HTML 5 addEventListener interface. Works only for the\n * onmessage event, which is hooked up to the chrome.runtime.Port.onMessage.\n * @param {string} eventName\n * @param {function({data: Object})} handler\n */\nu2f.WrappedChromeRuntimePort_.prototype.addEventListener =\n function(eventName, handler) {\n var name = eventName.toLowerCase();\n if (name == 'message' || name == 'onmessage') {\n this.port_.onMessage.addListener(function(message) {\n // Emulate a minimal MessageEvent object\n handler({'data': message});\n });\n } else {\n console.error('WrappedChromeRuntimePort only supports onMessage');\n }\n };\n\n/**\n * Wrap the Authenticator app with a MessagePort interface.\n * @constructor\n * @private\n */\nu2f.WrappedAuthenticatorPort_ = function() {\n this.requestId_ = -1;\n this.requestObject_ = null;\n}\n\n/**\n * Launch the Authenticator intent.\n * @param {Object} message\n */\nu2f.WrappedAuthenticatorPort_.prototype.postMessage = function(message) {\n var intentUrl =\n u2f.WrappedAuthenticatorPort_.INTENT_URL_BASE_ +\n ';S.request=' + encodeURIComponent(JSON.stringify(message)) +\n ';end';\n document.location = intentUrl;\n};\n\n/**\n * Tells what type of port this is.\n * @return {String} port type\n */\nu2f.WrappedAuthenticatorPort_.prototype.getPortType = function() {\n return \"WrappedAuthenticatorPort_\";\n};\n\n\n/**\n * Emulates the HTML 5 addEventListener interface.\n * @param {string} eventName\n * @param {function({data: Object})} handler\n */\nu2f.WrappedAuthenticatorPort_.prototype.addEventListener = function(eventName, handler) {\n var name = eventName.toLowerCase();\n if (name == 'message') {\n var self = this;\n /* Register a callback to that executes when\n * chrome injects the response. */\n window.addEventListener(\n 'message', self.onRequestUpdate_.bind(self, handler), false);\n } else {\n console.error('WrappedAuthenticatorPort only supports message');\n }\n};\n\n/**\n * Callback invoked when a response is received from the Authenticator.\n * @param function({data: Object}) callback\n * @param {Object} message message Object\n */\nu2f.WrappedAuthenticatorPort_.prototype.onRequestUpdate_ =\n function(callback, message) {\n var messageObject = JSON.parse(message.data);\n var intentUrl = messageObject['intentURL'];\n\n var errorCode = messageObject['errorCode'];\n var responseObject = null;\n if (messageObject.hasOwnProperty('data')) {\n responseObject = /** @type {Object} */ (\n JSON.parse(messageObject['data']));\n }\n\n callback({'data': responseObject});\n };\n\n/**\n * Base URL for intents to Authenticator.\n * @const\n * @private\n */\nu2f.WrappedAuthenticatorPort_.INTENT_URL_BASE_ =\n 'intent:#Intent;action=com.google.android.apps.authenticator.AUTHENTICATE';\n\n/**\n * Wrap the iOS client app with a MessagePort interface.\n * @constructor\n * @private\n */\nu2f.WrappedIosPort_ = function() {};\n\n/**\n * Launch the iOS client app request\n * @param {Object} message\n */\nu2f.WrappedIosPort_.prototype.postMessage = function(message) {\n var str = JSON.stringify(message);\n var url = \"u2f://auth?\" + encodeURI(str);\n location.replace(url);\n};\n\n/**\n * Tells what type of port this is.\n * @return {String} port type\n */\nu2f.WrappedIosPort_.prototype.getPortType = function() {\n return \"WrappedIosPort_\";\n};\n\n/**\n * Emulates the HTML 5 addEventListener interface.\n * @param {string} eventName\n * @param {function({data: Object})} handler\n */\nu2f.WrappedIosPort_.prototype.addEventListener = function(eventName, handler) {\n var name = eventName.toLowerCase();\n if (name !== 'message') {\n console.error('WrappedIosPort only supports message');\n }\n};\n\n/**\n * Sets up an embedded trampoline iframe, sourced from the extension.\n * @param {function(MessagePort)} callback\n * @private\n */\nu2f.getIframePort_ = function(callback) {\n // Create the iframe\n var iframeOrigin = 'chrome-extension://' + u2f.EXTENSION_ID;\n var iframe = document.createElement('iframe');\n iframe.src = iframeOrigin + '/u2f-comms.html';\n iframe.setAttribute('style', 'display:none');\n document.body.appendChild(iframe);\n\n var channel = new MessageChannel();\n var ready = function(message) {\n if (message.data == 'ready') {\n channel.port1.removeEventListener('message', ready);\n callback(channel.port1);\n } else {\n console.error('First event on iframe port was not \"ready\"');\n }\n };\n channel.port1.addEventListener('message', ready);\n channel.port1.start();\n\n iframe.addEventListener('load', function() {\n // Deliver the port to the iframe and initialize\n iframe.contentWindow.postMessage('init', iframeOrigin, [channel.port2]);\n });\n};\n\n\n//High-level JS API\n\n/**\n * Default extension response timeout in seconds.\n * @const\n */\nu2f.EXTENSION_TIMEOUT_SEC = 30;\n\n/**\n * A singleton instance for a MessagePort to the extension.\n * @type {MessagePort|u2f.WrappedChromeRuntimePort_}\n * @private\n */\nu2f.port_ = null;\n\n/**\n * Callbacks waiting for a port\n * @type {Array}\n * @private\n */\nu2f.waitingForPort_ = [];\n\n/**\n * A counter for requestIds.\n * @type {number}\n * @private\n */\nu2f.reqCounter_ = 0;\n\n/**\n * A map from requestIds to client callbacks\n * @type {Object.}\n * @private\n */\nu2f.callbackMap_ = {};\n\n/**\n * Creates or retrieves the MessagePort singleton to use.\n * @param {function((MessagePort|u2f.WrappedChromeRuntimePort_))} callback\n * @private\n */\nu2f.getPortSingleton_ = function(callback) {\n if (u2f.port_) {\n callback(u2f.port_);\n } else {\n if (u2f.waitingForPort_.length == 0) {\n u2f.getMessagePort(function(port) {\n u2f.port_ = port;\n u2f.port_.addEventListener('message',\n /** @type {function(Event)} */ (u2f.responseHandler_));\n\n // Careful, here be async callbacks. Maybe.\n while (u2f.waitingForPort_.length)\n u2f.waitingForPort_.shift()(u2f.port_);\n });\n }\n u2f.waitingForPort_.push(callback);\n }\n};\n\n/**\n * Handles response messages from the extension.\n * @param {MessageEvent.} message\n * @private\n */\nu2f.responseHandler_ = function(message) {\n var response = message.data;\n var reqId = response['requestId'];\n if (!reqId || !u2f.callbackMap_[reqId]) {\n console.error('Unknown or missing requestId in response.');\n return;\n }\n var cb = u2f.callbackMap_[reqId];\n delete u2f.callbackMap_[reqId];\n cb(response['responseData']);\n};\n\n/**\n * Dispatches an array of sign requests to available U2F tokens.\n * If the JS API version supported by the extension is unknown, it first sends a\n * message to the extension to find out the supported API version and then it sends\n * the sign request.\n * @param {string=} appId\n * @param {string=} challenge\n * @param {Array} registeredKeys\n * @param {function((u2f.Error|u2f.SignResponse))} callback\n * @param {number=} opt_timeoutSeconds\n */\nu2f.sign = function(appId, challenge, registeredKeys, callback, opt_timeoutSeconds) {\n if (js_api_version === undefined) {\n // Send a message to get the extension to JS API version, then send the actual sign request.\n u2f.getApiVersion(\n function (response) {\n js_api_version = response['js_api_version'] === undefined ? 0 : response['js_api_version'];\n console.log(\"Extension JS API Version: \", js_api_version);\n u2f.sendSignRequest(appId, challenge, registeredKeys, callback, opt_timeoutSeconds);\n });\n } else {\n // We know the JS API version. Send the actual sign request in the supported API version.\n u2f.sendSignRequest(appId, challenge, registeredKeys, callback, opt_timeoutSeconds);\n }\n};\n\n/**\n * Dispatches an array of sign requests to available U2F tokens.\n * @param {string=} appId\n * @param {string=} challenge\n * @param {Array} registeredKeys\n * @param {function((u2f.Error|u2f.SignResponse))} callback\n * @param {number=} opt_timeoutSeconds\n */\nu2f.sendSignRequest = function(appId, challenge, registeredKeys, callback, opt_timeoutSeconds) {\n u2f.getPortSingleton_(function(port) {\n var reqId = ++u2f.reqCounter_;\n u2f.callbackMap_[reqId] = callback;\n var timeoutSeconds = (typeof opt_timeoutSeconds !== 'undefined' ?\n opt_timeoutSeconds : u2f.EXTENSION_TIMEOUT_SEC);\n var req = u2f.formatSignRequest_(appId, challenge, registeredKeys, timeoutSeconds, reqId);\n port.postMessage(req);\n });\n};\n\n/**\n * Dispatches register requests to available U2F tokens. An array of sign\n * requests identifies already registered tokens.\n * If the JS API version supported by the extension is unknown, it first sends a\n * message to the extension to find out the supported API version and then it sends\n * the register request.\n * @param {string=} appId\n * @param {Array} registerRequests\n * @param {Array} registeredKeys\n * @param {function((u2f.Error|u2f.RegisterResponse))} callback\n * @param {number=} opt_timeoutSeconds\n */\nu2f.register = function(appId, registerRequests, registeredKeys, callback, opt_timeoutSeconds) {\n if (js_api_version === undefined) {\n // Send a message to get the extension to JS API version, then send the actual register request.\n u2f.getApiVersion(\n function (response) {\n js_api_version = response['js_api_version'] === undefined ? 0: response['js_api_version'];\n console.log(\"Extension JS API Version: \", js_api_version);\n u2f.sendRegisterRequest(appId, registerRequests, registeredKeys,\n callback, opt_timeoutSeconds);\n });\n } else {\n // We know the JS API version. Send the actual register request in the supported API version.\n u2f.sendRegisterRequest(appId, registerRequests, registeredKeys,\n callback, opt_timeoutSeconds);\n }\n};\n\n/**\n * Dispatches register requests to available U2F tokens. An array of sign\n * requests identifies already registered tokens.\n * @param {string=} appId\n * @param {Array} registerRequests\n * @param {Array} registeredKeys\n * @param {function((u2f.Error|u2f.RegisterResponse))} callback\n * @param {number=} opt_timeoutSeconds\n */\nu2f.sendRegisterRequest = function(appId, registerRequests, registeredKeys, callback, opt_timeoutSeconds) {\n u2f.getPortSingleton_(function(port) {\n var reqId = ++u2f.reqCounter_;\n u2f.callbackMap_[reqId] = callback;\n var timeoutSeconds = (typeof opt_timeoutSeconds !== 'undefined' ?\n opt_timeoutSeconds : u2f.EXTENSION_TIMEOUT_SEC);\n var req = u2f.formatRegisterRequest_(\n appId, registeredKeys, registerRequests, timeoutSeconds, reqId);\n port.postMessage(req);\n });\n};\n\n\n/**\n * Dispatches a message to the extension to find out the supported\n * JS API version.\n * If the user is on a mobile phone and is thus using Google Authenticator instead\n * of the Chrome extension, don't send the request and simply return 0.\n * @param {function((u2f.Error|u2f.GetJsApiVersionResponse))} callback\n * @param {number=} opt_timeoutSeconds\n */\nu2f.getApiVersion = function(callback, opt_timeoutSeconds) {\n u2f.getPortSingleton_(function(port) {\n // If we are using Android Google Authenticator or iOS client app,\n // do not fire an intent to ask which JS API version to use.\n if (port.getPortType) {\n var apiVersion;\n switch (port.getPortType()) {\n case 'WrappedIosPort_':\n case 'WrappedAuthenticatorPort_':\n apiVersion = 1.1;\n break;\n\n default:\n apiVersion = 0;\n break;\n }\n callback({ 'js_api_version': apiVersion });\n return;\n }\n var reqId = ++u2f.reqCounter_;\n u2f.callbackMap_[reqId] = callback;\n var req = {\n type: u2f.MessageTypes.U2F_GET_API_VERSION_REQUEST,\n timeoutSeconds: (typeof opt_timeoutSeconds !== 'undefined' ?\n opt_timeoutSeconds : u2f.EXTENSION_TIMEOUT_SEC),\n requestId: reqId\n };\n port.postMessage(req);\n });\n};\n\nwindow.u2f || (window.u2f = u2f);\n"],"sourceRoot":""}