{"version":3,"sources":["webpack:///./u2f/authenticate.js","webpack:///./shared/sessions/u2f.js","webpack:///./u2f/error.js","webpack:///./u2f/util.js","webpack:////opt/gitlab/embedded/service/gitlab-rails/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","underscore_default","omit","templates","setup","inProgress","error","authenticated","_this","Object","util","then","utils","catch","_this2","sign","response","errorCode","u2f_error","JSON","stringify","name","params","templateString","jquery_default","html","template","a","error_message","message","error_code","find","on","deviceResponse","querySelector","value","submit","classList","add","remove","__webpack_exports__","gon","u2f","u2fAuthenticate","u2f_authenticate","document","gl","U2FError","u2fFlowType","httpsDisabled","window","location","protocol","ErrorCodes","BAD_REQUEST","DEVICE_INELIGIBLE","isOpera","userAgent","indexOf","canInjectU2fApi","isSupportedChrome","isChrome","match","parseInt","getChromeVersion","isSupportedOpera","getOperaVersion","isMobile","test","importU2FLibrary","Promise","resolve","navigator","test_env","__webpack_require__","t","reject","d","$","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.fe6e3e27.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(this.appId, this.challenge, 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 }, 10);\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}\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","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","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 );\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","//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":""}