@webex/plugin-authorization-browser-first-party 3.6.0-next.6 → 3.6.0-next.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -282,6 +282,28 @@ var Authorization = _webexCore.WebexPlugin.extend((_dec = (0, _common.whileInFli
282
282
  return _promise.default.reject(new ErrorConstructor(res._res || res));
283
283
  });
284
284
  },
285
+ /**
286
+ * Generate a QR code URL to launch the Webex app when scanning with the camera
287
+ * @instance
288
+ * @memberof AuthorizationBrowserFirstParty
289
+ * @param {String} verificationUrl
290
+ * @returns {String}
291
+ */
292
+ _generateQRCodeVerificationUrl: function _generateQRCodeVerificationUrl(verificationUrl) {
293
+ var baseUrl = 'https://web.webex.com/deviceAuth';
294
+ var urlParams = new URLSearchParams(new URL(verificationUrl).search);
295
+ var userCode = urlParams.get('userCode');
296
+ if (userCode) {
297
+ var services = this.webex.internal.services;
298
+ var oauthHelperUrl = services.get('oauth-helper');
299
+ var newVerificationUrl = new URL(baseUrl);
300
+ newVerificationUrl.searchParams.set('usercode', userCode);
301
+ newVerificationUrl.searchParams.set('oauthhelper', oauthHelperUrl);
302
+ return newVerificationUrl.toString();
303
+ } else {
304
+ return verificationUrl;
305
+ }
306
+ },
285
307
  /**
286
308
  * Get an OAuth Login URL for QRCode. Generate QR code based on the returned URL.
287
309
  * @instance
@@ -317,12 +339,13 @@ var Authorization = _webexCore.WebexPlugin.extend((_dec = (0, _common.whileInFli
317
339
  user_code = _res$body.user_code,
318
340
  verification_uri = _res$body.verification_uri,
319
341
  verification_uri_complete = _res$body.verification_uri_complete;
342
+ var verificationUriComplete = _this3._generateQRCodeVerificationUrl(verification_uri_complete);
320
343
  _this3.eventEmitter.emit(Events.qRCodeLogin, {
321
344
  eventType: 'getUserCodeSuccess',
322
345
  userData: {
323
346
  userCode: user_code,
324
347
  verificationUri: verification_uri,
325
- verificationUriComplete: verification_uri_complete
348
+ verificationUriComplete: verificationUriComplete
326
349
  }
327
350
  });
328
351
  // if device authorization success, then start to poll server to check whether the user has completed authorization
@@ -561,7 +584,7 @@ var Authorization = _webexCore.WebexPlugin.extend((_dec = (0, _common.whileInFli
561
584
  throw new Error("CSRF token ".concat(token, " does not match stored token ").concat(sessionToken));
562
585
  }
563
586
  },
564
- version: "3.6.0-next.6"
587
+ version: "3.6.0-next.7"
565
588
  }, ((0, _applyDecoratedDescriptor2.default)(_obj, "initiateAuthorizationCodeGrant", [_dec], (0, _getOwnPropertyDescriptor.default)(_obj, "initiateAuthorizationCodeGrant"), _obj), (0, _applyDecoratedDescriptor2.default)(_obj, "requestAuthorizationCodeGrant", [_dec2, _common.oneFlight], (0, _getOwnPropertyDescriptor.default)(_obj, "requestAuthorizationCodeGrant"), _obj)), _obj)));
566
589
  var _default = exports.default = Authorization;
567
590
  //# sourceMappingURL=authorization.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["_querystring","_interopRequireDefault","require","_url","_events","_common","_webexCore","_lodash","_uuid","_encBase64url","_cryptoJs","_dec","_dec2","_obj","lodash","OAUTH2_CSRF_TOKEN","OAUTH2_CODE_VERIFIER","Events","exports","qRCodeLogin","Authorization","WebexPlugin","extend","whileInFlight","derived","isAuthenticating","deps","fn","isAuthorizing","session","default","type","ready","namespace","eventEmitter","EventEmitter","pollingTimer","pollingExpirationTimer","pollingId","currentPollingId","initialize","_this","_len","arguments","length","attrs","Array","_key","ret","_apply","prototype","location","url","parse","webex","getWindow","href","_checkForErrors","code","query","state","JSON","base64","decode","codeVerifier","sessionStorage","getItem","removeItem","emailhash","_verifySecurityToken","_cleanUrl","preauthCatalogParams","orgId","_extractOrgIdFromCode","process","nextTick","internal","services","collectPreauthCatalog","catch","_promise","resolve","then","requestAuthorizationCodeGrant","error","logger","warn","initiateLogin","options","undefined","cloneDeep","email","emailHash","CryptoJS","SHA256","toString","csrf_token","_generateSecurityToken","code_challenge","_generateCodeChallenge","code_challenge_method","initiateAuthorizationCodeGrant","info","credentials","buildLoginUrl","_assign","response_type","logout","noRedirect","buildLogoutUrl","_this2","reject","Error","form","grant_type","redirect_uri","config","self_contained_token","code_verifier","request","method","uri","tokenUrl","auth","user","client_id","pass","client_secret","sendImmediately","shouldRefreshAccessToken","res","set","supertoken","body","statusCode","ErrorConstructor","grantErrors","select","_res","initQRCodeLogin","_this3","emit","eventType","data","message","service","resource","scope","_res$body","user_code","verification_uri","verification_uri_complete","userData","userCode","verificationUri","verificationUriComplete","_startQRCodePolling","_options$interval","_this4","device_code","deviceCode","_options$expires_in","expires_in","expiresIn","interval","setTimeout","cancelQRCodePolling","polling","schedulePolling","withCancelEvent","clearTimeout","split","history","replaceState","_deleteProperty","isEmpty","omit","encode","_stringify","search","querystring","stringify","format","safeCharacterMap","base64url","_safe_map","times","random","join","codeChallenge","setItem","token","uuid","v4","sessionToken","concat","version","_applyDecoratedDescriptor2","_getOwnPropertyDescriptor","oneFlight","_default"],"sources":["authorization.js"],"sourcesContent":["/*!\n * Copyright (c) 2015-2020 Cisco Systems, Inc. See LICENSE file.\n */\n\n/* eslint camelcase: [0] */\n\nimport querystring from 'querystring';\nimport url from 'url';\nimport {EventEmitter} from 'events';\n\nimport {base64, oneFlight, whileInFlight} from '@webex/common';\nimport {grantErrors, WebexPlugin} from '@webex/webex-core';\nimport {cloneDeep, isEmpty, omit} from 'lodash';\nimport uuid from 'uuid';\nimport base64url from 'crypto-js/enc-base64url';\nimport CryptoJS from 'crypto-js';\n\n// Necessary to require lodash this way in order to stub\n// methods in the unit test\nconst lodash = require('lodash');\n\nconst OAUTH2_CSRF_TOKEN = 'oauth2-csrf-token';\nconst OAUTH2_CODE_VERIFIER = 'oauth2-code-verifier';\n\n/**\n * Authorization plugin events\n */\nexport const Events = {\n /**\n * QR code login events\n */\n qRCodeLogin: 'qRCodeLogin',\n};\n\n/**\n * Browser support for OAuth2. Automatically parses the URL query for an\n * authorization code\n *\n * Use of this plugin for anything other than the Webex Web Client is strongly\n * discouraged and may be broken at any time\n * @class\n * @name AuthorizationBrowserFirstParty\n * @private\n */\nconst Authorization = WebexPlugin.extend({\n derived: {\n /**\n * Alias of {@link AuthorizationBrowserFirstParty#isAuthorizing}\n * @instance\n * @memberof AuthorizationBrowserFirstParty\n * @type {boolean}\n */\n isAuthenticating: {\n deps: ['isAuthorizing'],\n fn() {\n return this.isAuthorizing;\n },\n },\n },\n\n session: {\n /**\n * Indicates if an Authorization Code exchange is inflight\n * @instance\n * @memberof AuthorizationBrowserFirstParty\n * @type {boolean}\n */\n isAuthorizing: {\n default: false,\n type: 'boolean',\n },\n ready: {\n default: false,\n type: 'boolean',\n },\n },\n\n namespace: 'Credentials',\n\n /**\n * EventEmitter for authorization events\n * @instance\n * @memberof AuthorizationBrowserFirstParty\n * @type {EventEmitter}\n * @public\n */\n eventEmitter: new EventEmitter(),\n\n /**\n * Stores the timer ID for QR code polling\n * @instance\n * @memberof AuthorizationBrowserFirstParty\n * @type {?number}\n * @private\n */\n pollingTimer: null,\n /**\n * Stores the expiration timer ID for QR code polling\n * @instance\n * @memberof AuthorizationBrowserFirstParty\n * @type {?number}\n * @private\n */\n pollingExpirationTimer: null,\n\n /**\n * Monotonically increasing id to identify the current polling request\n * @instance\n * @memberof AuthorizationBrowserFirstParty\n * @type {number}\n * @private\n */\n pollingId: 0,\n\n /**\n * Identifier for the current polling request\n * @instance\n * @memberof AuthorizationBrowserFirstParty\n * @type {?number}\n * @private\n */\n currentPollingId: null,\n\n /**\n * Initializer\n * @instance\n * @memberof AuthorizationBrowserFirstParty\n * @private\n * @returns {Authorization}\n */\n // eslint-disable-next-line complexity\n initialize(...attrs) {\n const ret = Reflect.apply(WebexPlugin.prototype.initialize, this, attrs);\n const location = url.parse(this.webex.getWindow().location.href, true);\n\n this._checkForErrors(location);\n\n const {code} = location.query;\n\n if (!code) {\n this.ready = true;\n\n return ret;\n }\n\n if (location.query.state) {\n location.query.state = JSON.parse(base64.decode(location.query.state));\n } else {\n location.query.state = {};\n }\n\n const codeVerifier = this.webex.getWindow().sessionStorage.getItem(OAUTH2_CODE_VERIFIER);\n\n this.webex.getWindow().sessionStorage.removeItem(OAUTH2_CODE_VERIFIER);\n\n const {emailhash} = location.query.state;\n\n this._verifySecurityToken(location.query);\n this._cleanUrl(location);\n\n let preauthCatalogParams;\n\n const orgId = this._extractOrgIdFromCode(code);\n\n if (emailhash) {\n preauthCatalogParams = {emailhash};\n } else if (orgId) {\n preauthCatalogParams = {orgId};\n }\n\n // Wait until nextTick in case `credentials` hasn't initialized yet\n process.nextTick(() => {\n this.webex.internal.services\n .collectPreauthCatalog(preauthCatalogParams)\n .catch(() => Promise.resolve())\n .then(() => this.requestAuthorizationCodeGrant({code, codeVerifier}))\n .catch((error) => {\n this.logger.warn('authorization: failed initial authorization code grant request', error);\n })\n .then(() => {\n this.ready = true;\n });\n });\n\n return ret;\n },\n\n /**\n * Kicks off an oauth flow\n * @instance\n * @memberof AuthorizationBrowserFirstParty\n * @param {Object} options\n * @returns {Promise}\n */\n initiateLogin(options = {}) {\n options = cloneDeep(options);\n if (options.email) {\n options.emailHash = CryptoJS.SHA256(options.email).toString();\n }\n delete options.email;\n options.state = options.state || {};\n options.state.csrf_token = this._generateSecurityToken();\n // catalog uses emailhash and redirectCI uses emailHash\n options.state.emailhash = options.emailHash;\n\n options.code_challenge = this._generateCodeChallenge();\n options.code_challenge_method = 'S256';\n\n return this.initiateAuthorizationCodeGrant(options);\n },\n\n @whileInFlight('isAuthorizing')\n /**\n * Kicks off the Implicit Code grant flow. Typically called via\n * {@link AuthorizationBrowserFirstParty#initiateLogin}\n * @instance\n * @memberof AuthorizationBrowserFirstParty\n * @param {Object} options\n * @returns {Promise}\n */\n initiateAuthorizationCodeGrant(options) {\n this.logger.info('authorization: initiating authorization code grant flow');\n this.webex.getWindow().location = this.webex.credentials.buildLoginUrl(\n Object.assign({response_type: 'code'}, options)\n );\n\n return Promise.resolve();\n },\n\n /**\n * Called by {@link WebexCore#logout()}. Redirects to the logout page\n * @instance\n * @memberof AuthorizationBrowserFirstParty\n * @param {Object} options\n * @param {boolean} options.noRedirect if true, does not redirect\n * @returns {Promise}\n */\n logout(options = {}) {\n if (!options.noRedirect) {\n this.webex.getWindow().location = this.webex.credentials.buildLogoutUrl(options);\n }\n },\n\n @whileInFlight('isAuthorizing')\n @oneFlight\n /**\n * Exchanges an authorization code for an access token\n * @instance\n * @memberof AuthorizationBrowserFirstParty\n * @param {Object} options\n * @param {Object} options.code\n * @returns {Promise}\n */\n requestAuthorizationCodeGrant(options = {}) {\n this.logger.info('credentials: requesting authorization code grant');\n\n if (!options.code) {\n return Promise.reject(new Error('`options.code` is required'));\n }\n\n const form = {\n grant_type: 'authorization_code',\n redirect_uri: this.config.redirect_uri,\n code: options.code,\n self_contained_token: true,\n };\n\n if (options.codeVerifier) {\n form.code_verifier = options.codeVerifier;\n }\n\n return this.webex\n .request({\n method: 'POST',\n uri: this.config.tokenUrl,\n form,\n auth: {\n user: this.config.client_id,\n pass: this.config.client_secret,\n sendImmediately: true,\n },\n shouldRefreshAccessToken: false,\n })\n .then((res) => {\n this.webex.credentials.set({supertoken: res.body});\n })\n .catch((res) => {\n if (res.statusCode !== 400) {\n return Promise.reject(res);\n }\n\n const ErrorConstructor = grantErrors.select(res.body.error);\n\n return Promise.reject(new ErrorConstructor(res._res || res));\n });\n },\n\n /**\n * Get an OAuth Login URL for QRCode. Generate QR code based on the returned URL.\n * @instance\n * @memberof AuthorizationBrowserFirstParty\n * @emits #qRCodeLogin\n */\n initQRCodeLogin() {\n if (this.pollingTimer) {\n this.eventEmitter.emit(Events.qRCodeLogin, {\n eventType: 'getUserCodeFailure',\n data: {message: 'There is already a polling request'},\n });\n return;\n }\n\n this.webex\n .request({\n method: 'POST',\n service: 'oauth-helper',\n resource: '/actions/device/authorize',\n form: {\n client_id: this.config.client_id,\n scope: this.config.scope,\n },\n auth: {\n user: this.config.client_id,\n pass: this.config.client_secret,\n sendImmediately: true,\n },\n })\n .then((res) => {\n const {user_code, verification_uri, verification_uri_complete} = res.body;\n this.eventEmitter.emit(Events.qRCodeLogin, {\n eventType: 'getUserCodeSuccess',\n userData: {\n userCode: user_code,\n verificationUri: verification_uri,\n verificationUriComplete: verification_uri_complete,\n },\n });\n // if device authorization success, then start to poll server to check whether the user has completed authorization\n this._startQRCodePolling(res.body);\n })\n .catch((res) => {\n this.eventEmitter.emit(Events.qRCodeLogin, {\n eventType: 'getUserCodeFailure',\n data: res.body,\n });\n });\n },\n\n /**\n * Polling the server to check whether the user has completed authorization\n * @instance\n * @memberof AuthorizationBrowserFirstParty\n * @param {Object} options\n * @emits #qRCodeLogin\n */\n _startQRCodePolling(options = {}) {\n if (!options.device_code) {\n this.eventEmitter.emit(Events.qRCodeLogin, {\n eventType: 'authorizationFailure',\n data: {message: 'A deviceCode is required'},\n });\n return;\n }\n\n if (this.pollingTimer) {\n this.eventEmitter.emit(Events.qRCodeLogin, {\n eventType: 'authorizationFailure',\n data: {message: 'There is already a polling request'},\n });\n return;\n }\n\n const {device_code: deviceCode, expires_in: expiresIn = 300} = options;\n let interval = options.interval ?? 2;\n\n this.pollingExpirationTimer = setTimeout(() => {\n this.cancelQRCodePolling(false);\n this.eventEmitter.emit(Events.qRCodeLogin, {\n eventType: 'authorizationFailure',\n data: {message: 'Authorization timed out'},\n });\n }, expiresIn * 1000);\n\n const polling = () => {\n this.pollingId += 1;\n this.currentPollingId = this.pollingId;\n\n this.webex\n .request({\n method: 'POST',\n service: 'oauth-helper',\n resource: '/actions/device/token',\n form: {\n grant_type: 'urn:ietf:params:oauth:grant-type:device_code',\n device_code: deviceCode,\n client_id: this.config.client_id,\n },\n auth: {\n user: this.config.client_id,\n pass: this.config.client_secret,\n sendImmediately: true,\n },\n })\n .then((res) => {\n // if the pollingId has changed, it means that the polling request has been canceled\n if (this.currentPollingId !== this.pollingId) return;\n\n this.eventEmitter.emit(Events.qRCodeLogin, {\n eventType: 'authorizationSuccess',\n data: res.body,\n });\n this.cancelQRCodePolling();\n })\n .catch((res) => {\n // if the pollingId has changed, it means that the polling request has been canceled\n if (this.currentPollingId !== this.pollingId) return;\n\n // When server sends 400 status code with message 'slow_down', it means that last request happened too soon.\n // So, skip one interval and then poll again.\n if (res.statusCode === 400 && res.body.message === 'slow_down') {\n schedulePolling(interval * 2);\n return;\n }\n\n // if the statusCode is 428 which means that the authorization request is still pending\n // as the end user hasn't yet completed the user-interaction steps. So keep polling.\n if (res.statusCode === 428) {\n this.eventEmitter.emit(Events.qRCodeLogin, {\n eventType: 'authorizationPending',\n data: res.body,\n });\n schedulePolling(interval);\n return;\n }\n\n this.cancelQRCodePolling();\n\n this.eventEmitter.emit(Events.qRCodeLogin, {\n eventType: 'authorizationFailure',\n data: res.body,\n });\n });\n };\n\n const schedulePolling = (interval) =>\n (this.pollingTimer = setTimeout(polling, interval * 1000));\n\n schedulePolling(interval);\n },\n\n /**\n * cancel polling request\n * @instance\n * @memberof AuthorizationBrowserFirstParty\n * @returns {void}\n */\n cancelQRCodePolling(withCancelEvent = true) {\n if (this.pollingTimer && withCancelEvent) {\n this.eventEmitter.emit(Events.qRCodeLogin, {\n eventType: 'pollingCanceled',\n });\n }\n\n this.currentPollingId = null;\n\n clearTimeout(this.pollingExpirationTimer);\n this.pollingExpirationTimer = null;\n clearTimeout(this.pollingTimer);\n this.pollingTimer = null;\n },\n\n /**\n * Extracts the orgId from the returned code from idbroker\n * Description of how to parse the code can be found here:\n * https://wiki.cisco.com/display/IDENTITY/Federated+Token+Validation\n * @instance\n * @memberof AuthorizationBrowserFirstParty\n * @param {String} code\n * @private\n * @returns {String}\n */\n _extractOrgIdFromCode(code) {\n return code?.split('_')[2] || undefined;\n },\n\n /**\n * Checks if the result of the login redirect contains an error string\n * @instance\n * @memberof AuthorizationBrowserFirstParty\n * @param {Object} location\n * @private\n * @returns {Promise}\n */\n _checkForErrors(location) {\n const {query} = location;\n\n if (query && query.error) {\n const ErrorConstructor = grantErrors.select(query.error);\n\n throw new ErrorConstructor(query);\n }\n },\n\n /**\n * Removes no-longer needed values from the url (access token, csrf token, etc)\n * @instance\n * @memberof AuthorizationBrowserFirstParty\n * @param {Object} location\n * @private\n * @returns {Promise}\n */\n _cleanUrl(location) {\n location = cloneDeep(location);\n if (this.webex.getWindow().history && this.webex.getWindow().history.replaceState) {\n Reflect.deleteProperty(location.query, 'code');\n if (isEmpty(omit(location.query.state, 'csrf_token'))) {\n Reflect.deleteProperty(location.query, 'state');\n } else {\n location.query.state = base64.encode(\n JSON.stringify(omit(location.query.state, 'csrf_token'))\n );\n }\n location.search = querystring.stringify(location.query);\n Reflect.deleteProperty(location, 'query');\n this.webex.getWindow().history.replaceState({}, null, url.format(location));\n }\n },\n\n /**\n * Generates PKCE code verifier and code challenge and sets the the code verifier in sessionStorage\n * @instance\n * @memberof AuthorizationBrowserFirstParty\n * @private\n * @returns {string}\n */\n _generateCodeChallenge() {\n this.logger.info('authorization: generating PKCE code challenge');\n\n // eslint-disable-next-line no-underscore-dangle\n const safeCharacterMap = base64url._safe_map;\n\n const codeVerifier = lodash\n .times(128, () => safeCharacterMap[lodash.random(0, safeCharacterMap.length - 1)])\n .join('');\n\n const codeChallenge = CryptoJS.SHA256(codeVerifier).toString(base64url);\n\n this.webex.getWindow().sessionStorage.setItem(OAUTH2_CODE_VERIFIER, codeVerifier);\n\n return codeChallenge;\n },\n\n /**\n * Generates a CSRF token and sticks in in sessionStorage\n * @instance\n * @memberof AuthorizationBrowserFirstParty\n * @private\n * @returns {Promise}\n */\n _generateSecurityToken() {\n this.logger.info('authorization: generating csrf token');\n\n const token = uuid.v4();\n\n this.webex.getWindow().sessionStorage.setItem('oauth2-csrf-token', token);\n\n return token;\n },\n\n /**\n * Checks if the CSRF token in sessionStorage is the same as the one returned\n * in the url.\n * @instance\n * @memberof AuthorizationBrowserFirstParty\n * @param {Object} query\n * @private\n * @returns {Promise}\n */\n _verifySecurityToken(query) {\n const sessionToken = this.webex.getWindow().sessionStorage.getItem(OAUTH2_CSRF_TOKEN);\n\n this.webex.getWindow().sessionStorage.removeItem(OAUTH2_CSRF_TOKEN);\n if (!sessionToken) {\n return;\n }\n\n if (!query.state) {\n throw new Error(`Expected CSRF token ${sessionToken}, but not found in redirect query`);\n }\n\n if (!query.state.csrf_token) {\n throw new Error(`Expected CSRF token ${sessionToken}, but not found in redirect query`);\n }\n\n const token = query.state.csrf_token;\n\n if (token !== sessionToken) {\n throw new Error(`CSRF token ${token} does not match stored token ${sessionToken}`);\n }\n },\n});\n\nexport default Authorization;\n"],"mappings":"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"}
1
+ {"version":3,"names":["_querystring","_interopRequireDefault","require","_url","_events","_common","_webexCore","_lodash","_uuid","_encBase64url","_cryptoJs","_dec","_dec2","_obj","lodash","OAUTH2_CSRF_TOKEN","OAUTH2_CODE_VERIFIER","Events","exports","qRCodeLogin","Authorization","WebexPlugin","extend","whileInFlight","derived","isAuthenticating","deps","fn","isAuthorizing","session","default","type","ready","namespace","eventEmitter","EventEmitter","pollingTimer","pollingExpirationTimer","pollingId","currentPollingId","initialize","_this","_len","arguments","length","attrs","Array","_key","ret","_apply","prototype","location","url","parse","webex","getWindow","href","_checkForErrors","code","query","state","JSON","base64","decode","codeVerifier","sessionStorage","getItem","removeItem","emailhash","_verifySecurityToken","_cleanUrl","preauthCatalogParams","orgId","_extractOrgIdFromCode","process","nextTick","internal","services","collectPreauthCatalog","catch","_promise","resolve","then","requestAuthorizationCodeGrant","error","logger","warn","initiateLogin","options","undefined","cloneDeep","email","emailHash","CryptoJS","SHA256","toString","csrf_token","_generateSecurityToken","code_challenge","_generateCodeChallenge","code_challenge_method","initiateAuthorizationCodeGrant","info","credentials","buildLoginUrl","_assign","response_type","logout","noRedirect","buildLogoutUrl","_this2","reject","Error","form","grant_type","redirect_uri","config","self_contained_token","code_verifier","request","method","uri","tokenUrl","auth","user","client_id","pass","client_secret","sendImmediately","shouldRefreshAccessToken","res","set","supertoken","body","statusCode","ErrorConstructor","grantErrors","select","_res","_generateQRCodeVerificationUrl","verificationUrl","baseUrl","urlParams","URLSearchParams","URL","search","userCode","get","oauthHelperUrl","newVerificationUrl","searchParams","initQRCodeLogin","_this3","emit","eventType","data","message","service","resource","scope","_res$body","user_code","verification_uri","verification_uri_complete","verificationUriComplete","userData","verificationUri","_startQRCodePolling","_options$interval","_this4","device_code","deviceCode","_options$expires_in","expires_in","expiresIn","interval","setTimeout","cancelQRCodePolling","polling","schedulePolling","withCancelEvent","clearTimeout","split","history","replaceState","_deleteProperty","isEmpty","omit","encode","_stringify","querystring","stringify","format","safeCharacterMap","base64url","_safe_map","times","random","join","codeChallenge","setItem","token","uuid","v4","sessionToken","concat","version","_applyDecoratedDescriptor2","_getOwnPropertyDescriptor","oneFlight","_default"],"sources":["authorization.js"],"sourcesContent":["/*!\n * Copyright (c) 2015-2020 Cisco Systems, Inc. See LICENSE file.\n */\n\n/* eslint camelcase: [0] */\n\nimport querystring from 'querystring';\nimport url from 'url';\nimport {EventEmitter} from 'events';\n\nimport {base64, oneFlight, whileInFlight} from '@webex/common';\nimport {grantErrors, WebexPlugin} from '@webex/webex-core';\nimport {cloneDeep, isEmpty, omit} from 'lodash';\nimport uuid from 'uuid';\nimport base64url from 'crypto-js/enc-base64url';\nimport CryptoJS from 'crypto-js';\n\n// Necessary to require lodash this way in order to stub\n// methods in the unit test\nconst lodash = require('lodash');\n\nconst OAUTH2_CSRF_TOKEN = 'oauth2-csrf-token';\nconst OAUTH2_CODE_VERIFIER = 'oauth2-code-verifier';\n\n/**\n * Authorization plugin events\n */\nexport const Events = {\n /**\n * QR code login events\n */\n qRCodeLogin: 'qRCodeLogin',\n};\n\n/**\n * Browser support for OAuth2. Automatically parses the URL query for an\n * authorization code\n *\n * Use of this plugin for anything other than the Webex Web Client is strongly\n * discouraged and may be broken at any time\n * @class\n * @name AuthorizationBrowserFirstParty\n * @private\n */\nconst Authorization = WebexPlugin.extend({\n derived: {\n /**\n * Alias of {@link AuthorizationBrowserFirstParty#isAuthorizing}\n * @instance\n * @memberof AuthorizationBrowserFirstParty\n * @type {boolean}\n */\n isAuthenticating: {\n deps: ['isAuthorizing'],\n fn() {\n return this.isAuthorizing;\n },\n },\n },\n\n session: {\n /**\n * Indicates if an Authorization Code exchange is inflight\n * @instance\n * @memberof AuthorizationBrowserFirstParty\n * @type {boolean}\n */\n isAuthorizing: {\n default: false,\n type: 'boolean',\n },\n ready: {\n default: false,\n type: 'boolean',\n },\n },\n\n namespace: 'Credentials',\n\n /**\n * EventEmitter for authorization events\n * @instance\n * @memberof AuthorizationBrowserFirstParty\n * @type {EventEmitter}\n * @public\n */\n eventEmitter: new EventEmitter(),\n\n /**\n * Stores the timer ID for QR code polling\n * @instance\n * @memberof AuthorizationBrowserFirstParty\n * @type {?number}\n * @private\n */\n pollingTimer: null,\n /**\n * Stores the expiration timer ID for QR code polling\n * @instance\n * @memberof AuthorizationBrowserFirstParty\n * @type {?number}\n * @private\n */\n pollingExpirationTimer: null,\n\n /**\n * Monotonically increasing id to identify the current polling request\n * @instance\n * @memberof AuthorizationBrowserFirstParty\n * @type {number}\n * @private\n */\n pollingId: 0,\n\n /**\n * Identifier for the current polling request\n * @instance\n * @memberof AuthorizationBrowserFirstParty\n * @type {?number}\n * @private\n */\n currentPollingId: null,\n\n /**\n * Initializer\n * @instance\n * @memberof AuthorizationBrowserFirstParty\n * @private\n * @returns {Authorization}\n */\n // eslint-disable-next-line complexity\n initialize(...attrs) {\n const ret = Reflect.apply(WebexPlugin.prototype.initialize, this, attrs);\n const location = url.parse(this.webex.getWindow().location.href, true);\n\n this._checkForErrors(location);\n\n const {code} = location.query;\n\n if (!code) {\n this.ready = true;\n\n return ret;\n }\n\n if (location.query.state) {\n location.query.state = JSON.parse(base64.decode(location.query.state));\n } else {\n location.query.state = {};\n }\n\n const codeVerifier = this.webex.getWindow().sessionStorage.getItem(OAUTH2_CODE_VERIFIER);\n\n this.webex.getWindow().sessionStorage.removeItem(OAUTH2_CODE_VERIFIER);\n\n const {emailhash} = location.query.state;\n\n this._verifySecurityToken(location.query);\n this._cleanUrl(location);\n\n let preauthCatalogParams;\n\n const orgId = this._extractOrgIdFromCode(code);\n\n if (emailhash) {\n preauthCatalogParams = {emailhash};\n } else if (orgId) {\n preauthCatalogParams = {orgId};\n }\n\n // Wait until nextTick in case `credentials` hasn't initialized yet\n process.nextTick(() => {\n this.webex.internal.services\n .collectPreauthCatalog(preauthCatalogParams)\n .catch(() => Promise.resolve())\n .then(() => this.requestAuthorizationCodeGrant({code, codeVerifier}))\n .catch((error) => {\n this.logger.warn('authorization: failed initial authorization code grant request', error);\n })\n .then(() => {\n this.ready = true;\n });\n });\n\n return ret;\n },\n\n /**\n * Kicks off an oauth flow\n * @instance\n * @memberof AuthorizationBrowserFirstParty\n * @param {Object} options\n * @returns {Promise}\n */\n initiateLogin(options = {}) {\n options = cloneDeep(options);\n if (options.email) {\n options.emailHash = CryptoJS.SHA256(options.email).toString();\n }\n delete options.email;\n options.state = options.state || {};\n options.state.csrf_token = this._generateSecurityToken();\n // catalog uses emailhash and redirectCI uses emailHash\n options.state.emailhash = options.emailHash;\n\n options.code_challenge = this._generateCodeChallenge();\n options.code_challenge_method = 'S256';\n\n return this.initiateAuthorizationCodeGrant(options);\n },\n\n @whileInFlight('isAuthorizing')\n /**\n * Kicks off the Implicit Code grant flow. Typically called via\n * {@link AuthorizationBrowserFirstParty#initiateLogin}\n * @instance\n * @memberof AuthorizationBrowserFirstParty\n * @param {Object} options\n * @returns {Promise}\n */\n initiateAuthorizationCodeGrant(options) {\n this.logger.info('authorization: initiating authorization code grant flow');\n this.webex.getWindow().location = this.webex.credentials.buildLoginUrl(\n Object.assign({response_type: 'code'}, options)\n );\n\n return Promise.resolve();\n },\n\n /**\n * Called by {@link WebexCore#logout()}. Redirects to the logout page\n * @instance\n * @memberof AuthorizationBrowserFirstParty\n * @param {Object} options\n * @param {boolean} options.noRedirect if true, does not redirect\n * @returns {Promise}\n */\n logout(options = {}) {\n if (!options.noRedirect) {\n this.webex.getWindow().location = this.webex.credentials.buildLogoutUrl(options);\n }\n },\n\n @whileInFlight('isAuthorizing')\n @oneFlight\n /**\n * Exchanges an authorization code for an access token\n * @instance\n * @memberof AuthorizationBrowserFirstParty\n * @param {Object} options\n * @param {Object} options.code\n * @returns {Promise}\n */\n requestAuthorizationCodeGrant(options = {}) {\n this.logger.info('credentials: requesting authorization code grant');\n\n if (!options.code) {\n return Promise.reject(new Error('`options.code` is required'));\n }\n\n const form = {\n grant_type: 'authorization_code',\n redirect_uri: this.config.redirect_uri,\n code: options.code,\n self_contained_token: true,\n };\n\n if (options.codeVerifier) {\n form.code_verifier = options.codeVerifier;\n }\n\n return this.webex\n .request({\n method: 'POST',\n uri: this.config.tokenUrl,\n form,\n auth: {\n user: this.config.client_id,\n pass: this.config.client_secret,\n sendImmediately: true,\n },\n shouldRefreshAccessToken: false,\n })\n .then((res) => {\n this.webex.credentials.set({supertoken: res.body});\n })\n .catch((res) => {\n if (res.statusCode !== 400) {\n return Promise.reject(res);\n }\n\n const ErrorConstructor = grantErrors.select(res.body.error);\n\n return Promise.reject(new ErrorConstructor(res._res || res));\n });\n },\n\n /**\n * Generate a QR code URL to launch the Webex app when scanning with the camera\n * @instance\n * @memberof AuthorizationBrowserFirstParty\n * @param {String} verificationUrl\n * @returns {String}\n */\n _generateQRCodeVerificationUrl(verificationUrl) {\n const baseUrl = 'https://web.webex.com/deviceAuth';\n const urlParams = new URLSearchParams(new URL(verificationUrl).search);\n const userCode = urlParams.get('userCode');\n\n if (userCode) {\n const {services} = this.webex.internal;\n const oauthHelperUrl = services.get('oauth-helper');\n const newVerificationUrl = new URL(baseUrl);\n newVerificationUrl.searchParams.set('usercode', userCode);\n newVerificationUrl.searchParams.set('oauthhelper', oauthHelperUrl);\n return newVerificationUrl.toString();\n } else {\n return verificationUrl;\n }\n },\n\n /**\n * Get an OAuth Login URL for QRCode. Generate QR code based on the returned URL.\n * @instance\n * @memberof AuthorizationBrowserFirstParty\n * @emits #qRCodeLogin\n */\n initQRCodeLogin() {\n if (this.pollingTimer) {\n this.eventEmitter.emit(Events.qRCodeLogin, {\n eventType: 'getUserCodeFailure',\n data: {message: 'There is already a polling request'},\n });\n return;\n }\n\n this.webex\n .request({\n method: 'POST',\n service: 'oauth-helper',\n resource: '/actions/device/authorize',\n form: {\n client_id: this.config.client_id,\n scope: this.config.scope,\n },\n auth: {\n user: this.config.client_id,\n pass: this.config.client_secret,\n sendImmediately: true,\n },\n })\n .then((res) => {\n const {user_code, verification_uri, verification_uri_complete} = res.body;\n const verificationUriComplete = this._generateQRCodeVerificationUrl(verification_uri_complete);\n this.eventEmitter.emit(Events.qRCodeLogin, {\n eventType: 'getUserCodeSuccess',\n userData: {\n userCode: user_code,\n verificationUri: verification_uri,\n verificationUriComplete,\n },\n });\n // if device authorization success, then start to poll server to check whether the user has completed authorization\n this._startQRCodePolling(res.body);\n })\n .catch((res) => {\n this.eventEmitter.emit(Events.qRCodeLogin, {\n eventType: 'getUserCodeFailure',\n data: res.body,\n });\n });\n },\n\n /**\n * Polling the server to check whether the user has completed authorization\n * @instance\n * @memberof AuthorizationBrowserFirstParty\n * @param {Object} options\n * @emits #qRCodeLogin\n */\n _startQRCodePolling(options = {}) {\n if (!options.device_code) {\n this.eventEmitter.emit(Events.qRCodeLogin, {\n eventType: 'authorizationFailure',\n data: {message: 'A deviceCode is required'},\n });\n return;\n }\n\n if (this.pollingTimer) {\n this.eventEmitter.emit(Events.qRCodeLogin, {\n eventType: 'authorizationFailure',\n data: {message: 'There is already a polling request'},\n });\n return;\n }\n\n const {device_code: deviceCode, expires_in: expiresIn = 300} = options;\n let interval = options.interval ?? 2;\n\n this.pollingExpirationTimer = setTimeout(() => {\n this.cancelQRCodePolling(false);\n this.eventEmitter.emit(Events.qRCodeLogin, {\n eventType: 'authorizationFailure',\n data: {message: 'Authorization timed out'},\n });\n }, expiresIn * 1000);\n\n const polling = () => {\n this.pollingId += 1;\n this.currentPollingId = this.pollingId;\n\n this.webex\n .request({\n method: 'POST',\n service: 'oauth-helper',\n resource: '/actions/device/token',\n form: {\n grant_type: 'urn:ietf:params:oauth:grant-type:device_code',\n device_code: deviceCode,\n client_id: this.config.client_id,\n },\n auth: {\n user: this.config.client_id,\n pass: this.config.client_secret,\n sendImmediately: true,\n },\n })\n .then((res) => {\n // if the pollingId has changed, it means that the polling request has been canceled\n if (this.currentPollingId !== this.pollingId) return;\n\n this.eventEmitter.emit(Events.qRCodeLogin, {\n eventType: 'authorizationSuccess',\n data: res.body,\n });\n this.cancelQRCodePolling();\n })\n .catch((res) => {\n // if the pollingId has changed, it means that the polling request has been canceled\n if (this.currentPollingId !== this.pollingId) return;\n\n // When server sends 400 status code with message 'slow_down', it means that last request happened too soon.\n // So, skip one interval and then poll again.\n if (res.statusCode === 400 && res.body.message === 'slow_down') {\n schedulePolling(interval * 2);\n return;\n }\n\n // if the statusCode is 428 which means that the authorization request is still pending\n // as the end user hasn't yet completed the user-interaction steps. So keep polling.\n if (res.statusCode === 428) {\n this.eventEmitter.emit(Events.qRCodeLogin, {\n eventType: 'authorizationPending',\n data: res.body,\n });\n schedulePolling(interval);\n return;\n }\n\n this.cancelQRCodePolling();\n\n this.eventEmitter.emit(Events.qRCodeLogin, {\n eventType: 'authorizationFailure',\n data: res.body,\n });\n });\n };\n\n const schedulePolling = (interval) =>\n (this.pollingTimer = setTimeout(polling, interval * 1000));\n\n schedulePolling(interval);\n },\n\n /**\n * cancel polling request\n * @instance\n * @memberof AuthorizationBrowserFirstParty\n * @returns {void}\n */\n cancelQRCodePolling(withCancelEvent = true) {\n if (this.pollingTimer && withCancelEvent) {\n this.eventEmitter.emit(Events.qRCodeLogin, {\n eventType: 'pollingCanceled',\n });\n }\n\n this.currentPollingId = null;\n\n clearTimeout(this.pollingExpirationTimer);\n this.pollingExpirationTimer = null;\n clearTimeout(this.pollingTimer);\n this.pollingTimer = null;\n },\n\n /**\n * Extracts the orgId from the returned code from idbroker\n * Description of how to parse the code can be found here:\n * https://wiki.cisco.com/display/IDENTITY/Federated+Token+Validation\n * @instance\n * @memberof AuthorizationBrowserFirstParty\n * @param {String} code\n * @private\n * @returns {String}\n */\n _extractOrgIdFromCode(code) {\n return code?.split('_')[2] || undefined;\n },\n\n /**\n * Checks if the result of the login redirect contains an error string\n * @instance\n * @memberof AuthorizationBrowserFirstParty\n * @param {Object} location\n * @private\n * @returns {Promise}\n */\n _checkForErrors(location) {\n const {query} = location;\n\n if (query && query.error) {\n const ErrorConstructor = grantErrors.select(query.error);\n\n throw new ErrorConstructor(query);\n }\n },\n\n /**\n * Removes no-longer needed values from the url (access token, csrf token, etc)\n * @instance\n * @memberof AuthorizationBrowserFirstParty\n * @param {Object} location\n * @private\n * @returns {Promise}\n */\n _cleanUrl(location) {\n location = cloneDeep(location);\n if (this.webex.getWindow().history && this.webex.getWindow().history.replaceState) {\n Reflect.deleteProperty(location.query, 'code');\n if (isEmpty(omit(location.query.state, 'csrf_token'))) {\n Reflect.deleteProperty(location.query, 'state');\n } else {\n location.query.state = base64.encode(\n JSON.stringify(omit(location.query.state, 'csrf_token'))\n );\n }\n location.search = querystring.stringify(location.query);\n Reflect.deleteProperty(location, 'query');\n this.webex.getWindow().history.replaceState({}, null, url.format(location));\n }\n },\n\n /**\n * Generates PKCE code verifier and code challenge and sets the the code verifier in sessionStorage\n * @instance\n * @memberof AuthorizationBrowserFirstParty\n * @private\n * @returns {string}\n */\n _generateCodeChallenge() {\n this.logger.info('authorization: generating PKCE code challenge');\n\n // eslint-disable-next-line no-underscore-dangle\n const safeCharacterMap = base64url._safe_map;\n\n const codeVerifier = lodash\n .times(128, () => safeCharacterMap[lodash.random(0, safeCharacterMap.length - 1)])\n .join('');\n\n const codeChallenge = CryptoJS.SHA256(codeVerifier).toString(base64url);\n\n this.webex.getWindow().sessionStorage.setItem(OAUTH2_CODE_VERIFIER, codeVerifier);\n\n return codeChallenge;\n },\n\n /**\n * Generates a CSRF token and sticks in in sessionStorage\n * @instance\n * @memberof AuthorizationBrowserFirstParty\n * @private\n * @returns {Promise}\n */\n _generateSecurityToken() {\n this.logger.info('authorization: generating csrf token');\n\n const token = uuid.v4();\n\n this.webex.getWindow().sessionStorage.setItem('oauth2-csrf-token', token);\n\n return token;\n },\n\n /**\n * Checks if the CSRF token in sessionStorage is the same as the one returned\n * in the url.\n * @instance\n * @memberof AuthorizationBrowserFirstParty\n * @param {Object} query\n * @private\n * @returns {Promise}\n */\n _verifySecurityToken(query) {\n const sessionToken = this.webex.getWindow().sessionStorage.getItem(OAUTH2_CSRF_TOKEN);\n\n this.webex.getWindow().sessionStorage.removeItem(OAUTH2_CSRF_TOKEN);\n if (!sessionToken) {\n return;\n }\n\n if (!query.state) {\n throw new Error(`Expected CSRF token ${sessionToken}, but not found in redirect query`);\n }\n\n if (!query.state.csrf_token) {\n throw new Error(`Expected CSRF token ${sessionToken}, but not found in redirect query`);\n }\n\n const token = query.state.csrf_token;\n\n if (token !== sessionToken) {\n throw new Error(`CSRF token ${token} does not match stored token ${sessionToken}`);\n }\n },\n});\n\nexport default Authorization;\n"],"mappings":"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"}
package/package.json CHANGED
@@ -56,5 +56,5 @@
56
56
  "test:style": "eslint ./src/**/*.*",
57
57
  "test:unit": "webex-legacy-tools test --unit --runner jest"
58
58
  },
59
- "version": "3.6.0-next.6"
59
+ "version": "3.6.0-next.7"
60
60
  }
@@ -295,6 +295,30 @@ const Authorization = WebexPlugin.extend({
295
295
  });
296
296
  },
297
297
 
298
+ /**
299
+ * Generate a QR code URL to launch the Webex app when scanning with the camera
300
+ * @instance
301
+ * @memberof AuthorizationBrowserFirstParty
302
+ * @param {String} verificationUrl
303
+ * @returns {String}
304
+ */
305
+ _generateQRCodeVerificationUrl(verificationUrl) {
306
+ const baseUrl = 'https://web.webex.com/deviceAuth';
307
+ const urlParams = new URLSearchParams(new URL(verificationUrl).search);
308
+ const userCode = urlParams.get('userCode');
309
+
310
+ if (userCode) {
311
+ const {services} = this.webex.internal;
312
+ const oauthHelperUrl = services.get('oauth-helper');
313
+ const newVerificationUrl = new URL(baseUrl);
314
+ newVerificationUrl.searchParams.set('usercode', userCode);
315
+ newVerificationUrl.searchParams.set('oauthhelper', oauthHelperUrl);
316
+ return newVerificationUrl.toString();
317
+ } else {
318
+ return verificationUrl;
319
+ }
320
+ },
321
+
298
322
  /**
299
323
  * Get an OAuth Login URL for QRCode. Generate QR code based on the returned URL.
300
324
  * @instance
@@ -327,12 +351,13 @@ const Authorization = WebexPlugin.extend({
327
351
  })
328
352
  .then((res) => {
329
353
  const {user_code, verification_uri, verification_uri_complete} = res.body;
354
+ const verificationUriComplete = this._generateQRCodeVerificationUrl(verification_uri_complete);
330
355
  this.eventEmitter.emit(Events.qRCodeLogin, {
331
356
  eventType: 'getUserCodeSuccess',
332
357
  userData: {
333
358
  userCode: user_code,
334
359
  verificationUri: verification_uri,
335
- verificationUriComplete: verification_uri_complete,
360
+ verificationUriComplete,
336
361
  },
337
362
  });
338
363
  // if device authorization success, then start to poll server to check whether the user has completed authorization
@@ -443,6 +443,38 @@ describe('plugin-authorization-browser-first-party', () => {
443
443
  });
444
444
  });
445
445
 
446
+ describe('#_generateQRCodeVerificationUrl()', () => {
447
+ it('should generate a QR code URL when a userCode is present', () => {
448
+ const verificationUrl = 'https://example.com/verify?userCode=123456';
449
+ const oauthHelperUrl = 'https://oauth-helper-a.wbx2.com/helperservice/v1';
450
+ const expectedUrl = 'https://web.webex.com/deviceAuth?usercode=123456&oauthhelper=https%3A%2F%2Foauth-helper-a.wbx2.com%2Fhelperservice%2Fv1';
451
+
452
+ const webex = makeWebex('http://example.com');
453
+
454
+ const oauthHelperSpy = sinon.stub(webex.internal.services, 'get').returns(oauthHelperUrl);
455
+ const result = webex.authorization._generateQRCodeVerificationUrl(verificationUrl);
456
+
457
+ assert.calledOnce(oauthHelperSpy);
458
+ assert.calledWithExactly(oauthHelperSpy, 'oauth-helper');
459
+ assert.equal(result, expectedUrl);
460
+
461
+ oauthHelperSpy.restore();
462
+ });
463
+
464
+ it('should return the original verificationUrl when userCode is not present', () => {
465
+ const verificationUrl = 'https://example.com/verify';
466
+ const webex = makeWebex('http://example.com');
467
+
468
+ const oauthHelperSpy = sinon.stub(webex.internal.services, 'get');
469
+ const result = webex.authorization._generateQRCodeVerificationUrl(verificationUrl);
470
+
471
+ assert.notCalled(oauthHelperSpy);
472
+ assert.equal(result, verificationUrl);
473
+
474
+ oauthHelperSpy.restore();
475
+ });
476
+ });
477
+
446
478
  describe('#initQRCodeLogin()', () => {
447
479
  it('should prevent concurrent request if there is already a polling request', async () => {
448
480
  const webex = makeWebex('http://example.com');
@@ -477,6 +509,7 @@ describe('plugin-authorization-browser-first-party', () => {
477
509
  });
478
510
  webex.request.onFirstCall().resolves({statusCode: 200, body: sampleData});
479
511
  sinon.spy(webex.authorization, '_startQRCodePolling');
512
+ sinon.spy(webex.authorization, '_generateQRCodeVerificationUrl');
480
513
  const emitSpy = sinon.spy(webex.authorization.eventEmitter, 'emit');
481
514
 
482
515
  webex.authorization.initQRCodeLogin();
@@ -485,6 +518,7 @@ describe('plugin-authorization-browser-first-party', () => {
485
518
 
486
519
  assert.calledTwice(webex.request);
487
520
  assert.calledOnce(webex.authorization._startQRCodePolling);
521
+ assert.calledOnce(webex.authorization._generateQRCodeVerificationUrl);
488
522
  assert.equal(emitSpy.getCall(0).args[1].eventType, 'getUserCodeSuccess');
489
523
 
490
524
  const request = webex.request.getCall(0);