@webex/plugin-authorization-browser-first-party 3.3.1-next.9 → 3.4.0
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.
- package/dist/authorization.js +26 -4
- package/dist/authorization.js.map +1 -1
- package/package.json +13 -13
- package/src/authorization.js +26 -2
- package/test/unit/spec/authorization.js +63 -2
package/dist/authorization.js
CHANGED
|
@@ -105,12 +105,21 @@ var Authorization = _webexCore.WebexPlugin.extend((_dec = (0, _common.whileInFli
|
|
|
105
105
|
var emailhash = location.query.state.emailhash;
|
|
106
106
|
this._verifySecurityToken(location.query);
|
|
107
107
|
this._cleanUrl(location);
|
|
108
|
+
var preauthCatalogParams;
|
|
109
|
+
var orgId = this._extractOrgIdFromCode(code);
|
|
110
|
+
if (emailhash) {
|
|
111
|
+
preauthCatalogParams = {
|
|
112
|
+
emailhash: emailhash
|
|
113
|
+
};
|
|
114
|
+
} else if (orgId) {
|
|
115
|
+
preauthCatalogParams = {
|
|
116
|
+
orgId: orgId
|
|
117
|
+
};
|
|
118
|
+
}
|
|
108
119
|
|
|
109
120
|
// Wait until nextTick in case `credentials` hasn't initialized yet
|
|
110
121
|
process.nextTick(function () {
|
|
111
|
-
_this.webex.internal.services.collectPreauthCatalog(
|
|
112
|
-
emailhash: emailhash
|
|
113
|
-
} : undefined).catch(function () {
|
|
122
|
+
_this.webex.internal.services.collectPreauthCatalog(preauthCatalogParams).catch(function () {
|
|
114
123
|
return _promise.default.resolve();
|
|
115
124
|
}).then(function () {
|
|
116
125
|
return _this.requestAuthorizationCodeGrant({
|
|
@@ -222,6 +231,19 @@ var Authorization = _webexCore.WebexPlugin.extend((_dec = (0, _common.whileInFli
|
|
|
222
231
|
return _promise.default.reject(new ErrorConstructor(res._res || res));
|
|
223
232
|
});
|
|
224
233
|
},
|
|
234
|
+
/**
|
|
235
|
+
* Extracts the orgId from the returned code from idbroker
|
|
236
|
+
* Description of how to parse the code can be found here:
|
|
237
|
+
* https://wiki.cisco.com/display/IDENTITY/Federated+Token+Validation
|
|
238
|
+
* @instance
|
|
239
|
+
* @memberof AuthorizationBrowserFirstParty
|
|
240
|
+
* @param {String} code
|
|
241
|
+
* @private
|
|
242
|
+
* @returns {String}
|
|
243
|
+
*/
|
|
244
|
+
_extractOrgIdFromCode: function _extractOrgIdFromCode(code) {
|
|
245
|
+
return (code === null || code === void 0 ? void 0 : code.split('_')[2]) || undefined;
|
|
246
|
+
},
|
|
225
247
|
/**
|
|
226
248
|
* Checks if the result of the login redirect contains an error string
|
|
227
249
|
* @instance
|
|
@@ -317,7 +339,7 @@ var Authorization = _webexCore.WebexPlugin.extend((_dec = (0, _common.whileInFli
|
|
|
317
339
|
throw new Error("CSRF token ".concat(token, " does not match stored token ").concat(sessionToken));
|
|
318
340
|
}
|
|
319
341
|
},
|
|
320
|
-
version: "3.
|
|
342
|
+
version: "3.4.0"
|
|
321
343
|
}, ((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)));
|
|
322
344
|
var _default = exports.default = Authorization;
|
|
323
345
|
//# sourceMappingURL=authorization.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["_querystring","_interopRequireDefault","require","_url","_common","_webexCore","_lodash","_uuid","_encBase64url","_cryptoJs","_dec","_dec2","_obj","lodash","OAUTH2_CSRF_TOKEN","OAUTH2_CODE_VERIFIER","Authorization","WebexPlugin","extend","whileInFlight","derived","isAuthenticating","deps","fn","isAuthorizing","session","default","type","ready","namespace","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","process","nextTick","internal","services","collectPreauthCatalog","undefined","catch","_promise","resolve","then","requestAuthorizationCodeGrant","error","logger","warn","initiateLogin","options","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","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","exports"],"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';\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 * 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 * 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 // Wait until nextTick in case `credentials` hasn't initialized yet\n process.nextTick(() => {\n this.webex.internal.services\n .collectPreauthCatalog(emailhash ? {emailhash}: undefined)\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 * 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","_common","_webexCore","_lodash","_uuid","_encBase64url","_cryptoJs","_dec","_dec2","_obj","lodash","OAUTH2_CSRF_TOKEN","OAUTH2_CODE_VERIFIER","Authorization","WebexPlugin","extend","whileInFlight","derived","isAuthenticating","deps","fn","isAuthorizing","session","default","type","ready","namespace","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","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","exports"],"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';\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 * 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 * 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 * 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":";;;;;;;;;;;;;;;AAMA,IAAAA,YAAA,GAAAC,sBAAA,CAAAC,OAAA;AACA,IAAAC,IAAA,GAAAF,sBAAA,CAAAC,OAAA;AAEA,IAAAE,OAAA,GAAAF,OAAA;AACA,IAAAG,UAAA,GAAAH,OAAA;AACA,IAAAI,OAAA,GAAAJ,OAAA;AACA,IAAAK,KAAA,GAAAN,sBAAA,CAAAC,OAAA;AACA,IAAAM,aAAA,GAAAP,sBAAA,CAAAC,OAAA;AACA,IAAAO,SAAA,GAAAR,sBAAA,CAAAC,OAAA;AAAiC,IAAAQ,IAAA,EAAAC,KAAA,EAAAC,IAAA;AAdjC;AACA;AACA;AAEA;AAYA;AACA;AACA,IAAMC,MAAM,GAAGX,OAAO,CAAC,QAAQ,CAAC;AAEhC,IAAMY,iBAAiB,GAAG,mBAAmB;AAC7C,IAAMC,oBAAoB,GAAG,sBAAsB;;AAEnD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAMC,aAAa,GAAGC,sBAAW,CAACC,MAAM,EAAAR,IAAA,GA2HrC,IAAAS,qBAAa,EAAC,eAAe,CAAC,EAAAR,KAAA,GAgC9B,IAAAQ,qBAAa,EAAC,eAAe,CAAC,GAAAP,IAAA,GA3JQ;EACvCQ,OAAO,EAAE;IACP;AACJ;AACA;AACA;AACA;AACA;IACIC,gBAAgB,EAAE;MAChBC,IAAI,EAAE,CAAC,eAAe,CAAC;MACvBC,EAAE,WAAAA,GAAA,EAAG;QACH,OAAO,IAAI,CAACC,aAAa;MAC3B;IACF;EACF,CAAC;EAEDC,OAAO,EAAE;IACP;AACJ;AACA;AACA;AACA;AACA;IACID,aAAa,EAAE;MACbE,OAAO,EAAE,KAAK;MACdC,IAAI,EAAE;IACR,CAAC;IACDC,KAAK,EAAE;MACLF,OAAO,EAAE,KAAK;MACdC,IAAI,EAAE;IACR;EACF,CAAC;EAEDE,SAAS,EAAE,aAAa;EAExB;AACF;AACA;AACA;AACA;AACA;AACA;EACE;EACAC,UAAU,WAAAA,WAAA,EAAW;IAAA,IAAAC,KAAA;IAAA,SAAAC,IAAA,GAAAC,SAAA,CAAAC,MAAA,EAAPC,KAAK,OAAAC,KAAA,CAAAJ,IAAA,GAAAK,IAAA,MAAAA,IAAA,GAAAL,IAAA,EAAAK,IAAA;MAALF,KAAK,CAAAE,IAAA,IAAAJ,SAAA,CAAAI,IAAA;IAAA;IACjB,IAAMC,GAAG,GAAG,IAAAC,MAAA,CAAAb,OAAA,EAAcT,sBAAW,CAACuB,SAAS,CAACV,UAAU,EAAE,IAAI,EAAEK,KAAK,CAAC;IACxE,IAAMM,QAAQ,GAAGC,YAAG,CAACC,KAAK,CAAC,IAAI,CAACC,KAAK,CAACC,SAAS,CAAC,CAAC,CAACJ,QAAQ,CAACK,IAAI,EAAE,IAAI,CAAC;IAEtE,IAAI,CAACC,eAAe,CAACN,QAAQ,CAAC;IAE9B,IAAOO,IAAI,GAAIP,QAAQ,CAACQ,KAAK,CAAtBD,IAAI;IAEX,IAAI,CAACA,IAAI,EAAE;MACT,IAAI,CAACpB,KAAK,GAAG,IAAI;MAEjB,OAAOU,GAAG;IACZ;IAEA,IAAIG,QAAQ,CAACQ,KAAK,CAACC,KAAK,EAAE;MACxBT,QAAQ,CAACQ,KAAK,CAACC,KAAK,GAAGC,IAAI,CAACR,KAAK,CAACS,cAAM,CAACC,MAAM,CAACZ,QAAQ,CAACQ,KAAK,CAACC,KAAK,CAAC,CAAC;IACxE,CAAC,MAAM;MACLT,QAAQ,CAACQ,KAAK,CAACC,KAAK,GAAG,CAAC,CAAC;IAC3B;IAEA,IAAMI,YAAY,GAAG,IAAI,CAACV,KAAK,CAACC,SAAS,CAAC,CAAC,CAACU,cAAc,CAACC,OAAO,CAACzC,oBAAoB,CAAC;IAExF,IAAI,CAAC6B,KAAK,CAACC,SAAS,CAAC,CAAC,CAACU,cAAc,CAACE,UAAU,CAAC1C,oBAAoB,CAAC;IAEtE,IAAO2C,SAAS,GAAIjB,QAAQ,CAACQ,KAAK,CAACC,KAAK,CAAjCQ,SAAS;IAEhB,IAAI,CAACC,oBAAoB,CAAClB,QAAQ,CAACQ,KAAK,CAAC;IACzC,IAAI,CAACW,SAAS,CAACnB,QAAQ,CAAC;IAExB,IAAIoB,oBAAoB;IAExB,IAAMC,KAAK,GAAG,IAAI,CAACC,qBAAqB,CAACf,IAAI,CAAC;IAE9C,IAAIU,SAAS,EAAE;MACbG,oBAAoB,GAAG;QAACH,SAAS,EAATA;MAAS,CAAC;IACpC,CAAC,MAAM,IAAII,KAAK,EAAE;MAChBD,oBAAoB,GAAG;QAACC,KAAK,EAALA;MAAK,CAAC;IAChC;;IAEA;IACAE,OAAO,CAACC,QAAQ,CAAC,YAAM;MACrBlC,KAAI,CAACa,KAAK,CAACsB,QAAQ,CAACC,QAAQ,CACzBC,qBAAqB,CAACP,oBAAoB,CAAC,CAC3CQ,KAAK,CAAC;QAAA,OAAMC,QAAA,CAAA5C,OAAA,CAAQ6C,OAAO,CAAC,CAAC;MAAA,EAAC,CAC9BC,IAAI,CAAC;QAAA,OAAMzC,KAAI,CAAC0C,6BAA6B,CAAC;UAACzB,IAAI,EAAJA,IAAI;UAAEM,YAAY,EAAZA;QAAY,CAAC,CAAC;MAAA,EAAC,CACpEe,KAAK,CAAC,UAACK,KAAK,EAAK;QAChB3C,KAAI,CAAC4C,MAAM,CAACC,IAAI,CAAC,gEAAgE,EAAEF,KAAK,CAAC;MAC3F,CAAC,CAAC,CACDF,IAAI,CAAC,YAAM;QACVzC,KAAI,CAACH,KAAK,GAAG,IAAI;MACnB,CAAC,CAAC;IACN,CAAC,CAAC;IAEF,OAAOU,GAAG;EACZ,CAAC;EAED;AACF;AACA;AACA;AACA;AACA;AACA;EACEuC,aAAa,WAAAA,cAAA,EAAe;IAAA,IAAdC,OAAO,GAAA7C,SAAA,CAAAC,MAAA,QAAAD,SAAA,QAAA8C,SAAA,GAAA9C,SAAA,MAAG,CAAC,CAAC;IACxB6C,OAAO,GAAG,IAAAE,iBAAS,EAACF,OAAO,CAAC;IAC5B,IAAIA,OAAO,CAACG,KAAK,EAAE;MACjBH,OAAO,CAACI,SAAS,GAAGC,iBAAQ,CAACC,MAAM,CAACN,OAAO,CAACG,KAAK,CAAC,CAACI,QAAQ,CAAC,CAAC;IAC/D;IACA,OAAOP,OAAO,CAACG,KAAK;IACpBH,OAAO,CAAC5B,KAAK,GAAG4B,OAAO,CAAC5B,KAAK,IAAI,CAAC,CAAC;IACnC4B,OAAO,CAAC5B,KAAK,CAACoC,UAAU,GAAG,IAAI,CAACC,sBAAsB,CAAC,CAAC;IACxD;IACAT,OAAO,CAAC5B,KAAK,CAACQ,SAAS,GAAGoB,OAAO,CAACI,SAAS;IAE3CJ,OAAO,CAACU,cAAc,GAAG,IAAI,CAACC,sBAAsB,CAAC,CAAC;IACtDX,OAAO,CAACY,qBAAqB,GAAG,MAAM;IAEtC,OAAO,IAAI,CAACC,8BAA8B,CAACb,OAAO,CAAC;EACrD,CAAC;EAGD;AACF;AACA;AACA;AACA;AACA;AACA;AACA;EACEa,8BAA8B,WAAAA,+BAACb,OAAO,EAAE;IACtC,IAAI,CAACH,MAAM,CAACiB,IAAI,CAAC,yDAAyD,CAAC;IAC3E,IAAI,CAAChD,KAAK,CAACC,SAAS,CAAC,CAAC,CAACJ,QAAQ,GAAG,IAAI,CAACG,KAAK,CAACiD,WAAW,CAACC,aAAa,CACpE,IAAAC,OAAA,CAAArE,OAAA,EAAc;MAACsE,aAAa,EAAE;IAAM,CAAC,EAAElB,OAAO,CAChD,CAAC;IAED,OAAOR,QAAA,CAAA5C,OAAA,CAAQ6C,OAAO,CAAC,CAAC;EAC1B,CAAC;EAED;AACF;AACA;AACA;AACA;AACA;AACA;AACA;EACE0B,MAAM,WAAAA,OAAA,EAAe;IAAA,IAAdnB,OAAO,GAAA7C,SAAA,CAAAC,MAAA,QAAAD,SAAA,QAAA8C,SAAA,GAAA9C,SAAA,MAAG,CAAC,CAAC;IACjB,IAAI,CAAC6C,OAAO,CAACoB,UAAU,EAAE;MACvB,IAAI,CAACtD,KAAK,CAACC,SAAS,CAAC,CAAC,CAACJ,QAAQ,GAAG,IAAI,CAACG,KAAK,CAACiD,WAAW,CAACM,cAAc,CAACrB,OAAO,CAAC;IAClF;EACF,CAAC;EAID;AACF;AACA;AACA;AACA;AACA;AACA;AACA;EACEL,6BAA6B,WAAAA,8BAAA,EAAe;IAAA,IAAA2B,MAAA;IAAA,IAAdtB,OAAO,GAAA7C,SAAA,CAAAC,MAAA,QAAAD,SAAA,QAAA8C,SAAA,GAAA9C,SAAA,MAAG,CAAC,CAAC;IACxC,IAAI,CAAC0C,MAAM,CAACiB,IAAI,CAAC,kDAAkD,CAAC;IAEpE,IAAI,CAACd,OAAO,CAAC9B,IAAI,EAAE;MACjB,OAAOsB,QAAA,CAAA5C,OAAA,CAAQ2E,MAAM,CAAC,IAAIC,KAAK,CAAC,4BAA4B,CAAC,CAAC;IAChE;IAEA,IAAMC,IAAI,GAAG;MACXC,UAAU,EAAE,oBAAoB;MAChCC,YAAY,EAAE,IAAI,CAACC,MAAM,CAACD,YAAY;MACtCzD,IAAI,EAAE8B,OAAO,CAAC9B,IAAI;MAClB2D,oBAAoB,EAAE;IACxB,CAAC;IAED,IAAI7B,OAAO,CAACxB,YAAY,EAAE;MACxBiD,IAAI,CAACK,aAAa,GAAG9B,OAAO,CAACxB,YAAY;IAC3C;IAEA,OAAO,IAAI,CAACV,KAAK,CACdiE,OAAO,CAAC;MACPC,MAAM,EAAE,MAAM;MACdC,GAAG,EAAE,IAAI,CAACL,MAAM,CAACM,QAAQ;MACzBT,IAAI,EAAJA,IAAI;MACJU,IAAI,EAAE;QACJC,IAAI,EAAE,IAAI,CAACR,MAAM,CAACS,SAAS;QAC3BC,IAAI,EAAE,IAAI,CAACV,MAAM,CAACW,aAAa;QAC/BC,eAAe,EAAE;MACnB,CAAC;MACDC,wBAAwB,EAAE;IAC5B,CAAC,CAAC,CACD/C,IAAI,CAAC,UAACgD,GAAG,EAAK;MACbpB,MAAI,CAACxD,KAAK,CAACiD,WAAW,CAAC4B,GAAG,CAAC;QAACC,UAAU,EAAEF,GAAG,CAACG;MAAI,CAAC,CAAC;IACpD,CAAC,CAAC,CACDtD,KAAK,CAAC,UAACmD,GAAG,EAAK;MACd,IAAIA,GAAG,CAACI,UAAU,KAAK,GAAG,EAAE;QAC1B,OAAOtD,QAAA,CAAA5C,OAAA,CAAQ2E,MAAM,CAACmB,GAAG,CAAC;MAC5B;MAEA,IAAMK,gBAAgB,GAAGC,sBAAW,CAACC,MAAM,CAACP,GAAG,CAACG,IAAI,CAACjD,KAAK,CAAC;MAE3D,OAAOJ,QAAA,CAAA5C,OAAA,CAAQ2E,MAAM,CAAC,IAAIwB,gBAAgB,CAACL,GAAG,CAACQ,IAAI,IAAIR,GAAG,CAAC,CAAC;IAC9D,CAAC,CAAC;EACN,CAAC;EAED;AACF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;EACEzD,qBAAqB,WAAAA,sBAACf,IAAI,EAAE;IAC1B,OAAO,CAAAA,IAAI,aAAJA,IAAI,uBAAJA,IAAI,CAAEiF,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,KAAIlD,SAAS;EACzC,CAAC;EAED;AACF;AACA;AACA;AACA;AACA;AACA;AACA;EACEhC,eAAe,WAAAA,gBAACN,QAAQ,EAAE;IACxB,IAAOQ,KAAK,GAAIR,QAAQ,CAAjBQ,KAAK;IAEZ,IAAIA,KAAK,IAAIA,KAAK,CAACyB,KAAK,EAAE;MACxB,IAAMmD,gBAAgB,GAAGC,sBAAW,CAACC,MAAM,CAAC9E,KAAK,CAACyB,KAAK,CAAC;MAExD,MAAM,IAAImD,gBAAgB,CAAC5E,KAAK,CAAC;IACnC;EACF,CAAC;EAED;AACF;AACA;AACA;AACA;AACA;AACA;AACA;EACEW,SAAS,WAAAA,UAACnB,QAAQ,EAAE;IAClBA,QAAQ,GAAG,IAAAuC,iBAAS,EAACvC,QAAQ,CAAC;IAC9B,IAAI,IAAI,CAACG,KAAK,CAACC,SAAS,CAAC,CAAC,CAACqF,OAAO,IAAI,IAAI,CAACtF,KAAK,CAACC,SAAS,CAAC,CAAC,CAACqF,OAAO,CAACC,YAAY,EAAE;MACjF,IAAAC,eAAA,CAAA1G,OAAA,EAAuBe,QAAQ,CAACQ,KAAK,EAAE,MAAM,CAAC;MAC9C,IAAI,IAAAoF,eAAO,EAAC,IAAAC,YAAI,EAAC7F,QAAQ,CAACQ,KAAK,CAACC,KAAK,EAAE,YAAY,CAAC,CAAC,EAAE;QACrD,IAAAkF,eAAA,CAAA1G,OAAA,EAAuBe,QAAQ,CAACQ,KAAK,EAAE,OAAO,CAAC;MACjD,CAAC,MAAM;QACLR,QAAQ,CAACQ,KAAK,CAACC,KAAK,GAAGE,cAAM,CAACmF,MAAM,CAClC,IAAAC,UAAA,CAAA9G,OAAA,EAAe,IAAA4G,YAAI,EAAC7F,QAAQ,CAACQ,KAAK,CAACC,KAAK,EAAE,YAAY,CAAC,CACzD,CAAC;MACH;MACAT,QAAQ,CAACgG,MAAM,GAAGC,oBAAW,CAACC,SAAS,CAAClG,QAAQ,CAACQ,KAAK,CAAC;MACvD,IAAAmF,eAAA,CAAA1G,OAAA,EAAuBe,QAAQ,EAAE,OAAO,CAAC;MACzC,IAAI,CAACG,KAAK,CAACC,SAAS,CAAC,CAAC,CAACqF,OAAO,CAACC,YAAY,CAAC,CAAC,CAAC,EAAE,IAAI,EAAEzF,YAAG,CAACkG,MAAM,CAACnG,QAAQ,CAAC,CAAC;IAC7E;EACF,CAAC;EAED;AACF;AACA;AACA;AACA;AACA;AACA;EACEgD,sBAAsB,WAAAA,uBAAA,EAAG;IACvB,IAAI,CAACd,MAAM,CAACiB,IAAI,CAAC,+CAA+C,CAAC;;IAEjE;IACA,IAAMiD,gBAAgB,GAAGC,qBAAS,CAACC,SAAS;IAE5C,IAAMzF,YAAY,GAAGzC,MAAM,CACxBmI,KAAK,CAAC,GAAG,EAAE;MAAA,OAAMH,gBAAgB,CAAChI,MAAM,CAACoI,MAAM,CAAC,CAAC,EAAEJ,gBAAgB,CAAC3G,MAAM,GAAG,CAAC,CAAC,CAAC;IAAA,EAAC,CACjFgH,IAAI,CAAC,EAAE,CAAC;IAEX,IAAMC,aAAa,GAAGhE,iBAAQ,CAACC,MAAM,CAAC9B,YAAY,CAAC,CAAC+B,QAAQ,CAACyD,qBAAS,CAAC;IAEvE,IAAI,CAAClG,KAAK,CAACC,SAAS,CAAC,CAAC,CAACU,cAAc,CAAC6F,OAAO,CAACrI,oBAAoB,EAAEuC,YAAY,CAAC;IAEjF,OAAO6F,aAAa;EACtB,CAAC;EAED;AACF;AACA;AACA;AACA;AACA;AACA;EACE5D,sBAAsB,WAAAA,uBAAA,EAAG;IACvB,IAAI,CAACZ,MAAM,CAACiB,IAAI,CAAC,sCAAsC,CAAC;IAExD,IAAMyD,KAAK,GAAGC,aAAI,CAACC,EAAE,CAAC,CAAC;IAEvB,IAAI,CAAC3G,KAAK,CAACC,SAAS,CAAC,CAAC,CAACU,cAAc,CAAC6F,OAAO,CAAC,mBAAmB,EAAEC,KAAK,CAAC;IAEzE,OAAOA,KAAK;EACd,CAAC;EAED;AACF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;EACE1F,oBAAoB,WAAAA,qBAACV,KAAK,EAAE;IAC1B,IAAMuG,YAAY,GAAG,IAAI,CAAC5G,KAAK,CAACC,SAAS,CAAC,CAAC,CAACU,cAAc,CAACC,OAAO,CAAC1C,iBAAiB,CAAC;IAErF,IAAI,CAAC8B,KAAK,CAACC,SAAS,CAAC,CAAC,CAACU,cAAc,CAACE,UAAU,CAAC3C,iBAAiB,CAAC;IACnE,IAAI,CAAC0I,YAAY,EAAE;MACjB;IACF;IAEA,IAAI,CAACvG,KAAK,CAACC,KAAK,EAAE;MAChB,MAAM,IAAIoD,KAAK,wBAAAmD,MAAA,CAAwBD,YAAY,sCAAmC,CAAC;IACzF;IAEA,IAAI,CAACvG,KAAK,CAACC,KAAK,CAACoC,UAAU,EAAE;MAC3B,MAAM,IAAIgB,KAAK,wBAAAmD,MAAA,CAAwBD,YAAY,sCAAmC,CAAC;IACzF;IAEA,IAAMH,KAAK,GAAGpG,KAAK,CAACC,KAAK,CAACoC,UAAU;IAEpC,IAAI+D,KAAK,KAAKG,YAAY,EAAE;MAC1B,MAAM,IAAIlD,KAAK,eAAAmD,MAAA,CAAeJ,KAAK,mCAAAI,MAAA,CAAgCD,YAAY,CAAE,CAAC;IACpF;EACF,CAAC;EAAAE,OAAA;AACH,CAAC,OAAAC,0BAAA,CAAAjI,OAAA,EAAAd,IAAA,qCAAAF,IAAA,OAAAkJ,yBAAA,CAAAlI,OAAA,EAAAd,IAAA,qCAAAA,IAAA,OAAA+I,0BAAA,CAAAjI,OAAA,EAAAd,IAAA,oCAAAD,KAAA,EAtLEkJ,iBAAS,OAAAD,yBAAA,CAAAlI,OAAA,EAAAd,IAAA,oCAAAA,IAAA,IAAAA,IAAA,EAsLX,CAAC;AAAC,IAAAkJ,QAAA,GAAAC,OAAA,CAAArI,OAAA,GAEYV,aAAa"}
|
package/package.json
CHANGED
|
@@ -26,23 +26,23 @@
|
|
|
26
26
|
"@webex/eslint-config-legacy": "0.0.0",
|
|
27
27
|
"@webex/jest-config-legacy": "0.0.0",
|
|
28
28
|
"@webex/legacy-tools": "0.0.0",
|
|
29
|
-
"@webex/test-helper-chai": "3.
|
|
30
|
-
"@webex/test-helper-mocha": "3.
|
|
31
|
-
"@webex/test-helper-mock-webex": "3.
|
|
32
|
-
"@webex/test-helper-test-users": "3.
|
|
29
|
+
"@webex/test-helper-chai": "3.4.0",
|
|
30
|
+
"@webex/test-helper-mocha": "3.4.0",
|
|
31
|
+
"@webex/test-helper-mock-webex": "3.4.0",
|
|
32
|
+
"@webex/test-helper-test-users": "3.4.0",
|
|
33
33
|
"eslint": "^8.24.0",
|
|
34
34
|
"prettier": "^2.7.1",
|
|
35
35
|
"sinon": "^9.2.4"
|
|
36
36
|
},
|
|
37
37
|
"dependencies": {
|
|
38
|
-
"@webex/common": "3.
|
|
39
|
-
"@webex/storage-adapter-local-storage": "3.
|
|
40
|
-
"@webex/test-helper-automation": "3.
|
|
41
|
-
"@webex/test-helper-chai": "3.
|
|
42
|
-
"@webex/test-helper-mocha": "3.
|
|
43
|
-
"@webex/test-helper-mock-webex": "3.
|
|
44
|
-
"@webex/test-helper-test-users": "3.
|
|
45
|
-
"@webex/webex-core": "3.
|
|
38
|
+
"@webex/common": "3.4.0",
|
|
39
|
+
"@webex/storage-adapter-local-storage": "3.4.0",
|
|
40
|
+
"@webex/test-helper-automation": "3.4.0",
|
|
41
|
+
"@webex/test-helper-chai": "3.4.0",
|
|
42
|
+
"@webex/test-helper-mocha": "3.4.0",
|
|
43
|
+
"@webex/test-helper-mock-webex": "3.4.0",
|
|
44
|
+
"@webex/test-helper-test-users": "3.4.0",
|
|
45
|
+
"@webex/webex-core": "3.4.0",
|
|
46
46
|
"crypto-js": "^4.1.1",
|
|
47
47
|
"lodash": "^4.17.21",
|
|
48
48
|
"uuid": "^3.3.2"
|
|
@@ -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.
|
|
59
|
+
"version": "3.4.0"
|
|
60
60
|
}
|
package/src/authorization.js
CHANGED
|
@@ -103,14 +103,24 @@ const Authorization = WebexPlugin.extend({
|
|
|
103
103
|
this._verifySecurityToken(location.query);
|
|
104
104
|
this._cleanUrl(location);
|
|
105
105
|
|
|
106
|
+
let preauthCatalogParams;
|
|
107
|
+
|
|
108
|
+
const orgId = this._extractOrgIdFromCode(code);
|
|
109
|
+
|
|
110
|
+
if (emailhash) {
|
|
111
|
+
preauthCatalogParams = {emailhash};
|
|
112
|
+
} else if (orgId) {
|
|
113
|
+
preauthCatalogParams = {orgId};
|
|
114
|
+
}
|
|
115
|
+
|
|
106
116
|
// Wait until nextTick in case `credentials` hasn't initialized yet
|
|
107
117
|
process.nextTick(() => {
|
|
108
118
|
this.webex.internal.services
|
|
109
|
-
.collectPreauthCatalog(
|
|
119
|
+
.collectPreauthCatalog(preauthCatalogParams)
|
|
110
120
|
.catch(() => Promise.resolve())
|
|
111
121
|
.then(() => this.requestAuthorizationCodeGrant({code, codeVerifier}))
|
|
112
122
|
.catch((error) => {
|
|
113
|
-
this.logger.warn('authorization: failed initial authorization code grant request', error)
|
|
123
|
+
this.logger.warn('authorization: failed initial authorization code grant request', error);
|
|
114
124
|
})
|
|
115
125
|
.then(() => {
|
|
116
126
|
this.ready = true;
|
|
@@ -230,6 +240,20 @@ const Authorization = WebexPlugin.extend({
|
|
|
230
240
|
});
|
|
231
241
|
},
|
|
232
242
|
|
|
243
|
+
/**
|
|
244
|
+
* Extracts the orgId from the returned code from idbroker
|
|
245
|
+
* Description of how to parse the code can be found here:
|
|
246
|
+
* https://wiki.cisco.com/display/IDENTITY/Federated+Token+Validation
|
|
247
|
+
* @instance
|
|
248
|
+
* @memberof AuthorizationBrowserFirstParty
|
|
249
|
+
* @param {String} code
|
|
250
|
+
* @private
|
|
251
|
+
* @returns {String}
|
|
252
|
+
*/
|
|
253
|
+
_extractOrgIdFromCode(code) {
|
|
254
|
+
return code?.split('_')[2] || undefined;
|
|
255
|
+
},
|
|
256
|
+
|
|
233
257
|
/**
|
|
234
258
|
* Checks if the result of the login redirect contains an error string
|
|
235
259
|
* @instance
|
|
@@ -183,7 +183,7 @@ describe('plugin-authorization-browser-first-party', () => {
|
|
|
183
183
|
});
|
|
184
184
|
|
|
185
185
|
it('collects the preauth catalog when emailhash is present in the state', async () => {
|
|
186
|
-
const code = '
|
|
186
|
+
const code = 'authcode_clusterid_theOrgId';
|
|
187
187
|
const webex = makeWebex(
|
|
188
188
|
`http://example.com/?code=${code}&state=${base64.encode(
|
|
189
189
|
JSON.stringify({emailhash: 'someemailhash'})
|
|
@@ -205,7 +205,7 @@ describe('plugin-authorization-browser-first-party', () => {
|
|
|
205
205
|
});
|
|
206
206
|
|
|
207
207
|
it('collects the preauth catalog no emailhash is present in the state', async () => {
|
|
208
|
-
const code = '
|
|
208
|
+
const code = 'authcode_clusterid_theOrgId';
|
|
209
209
|
const webex = makeWebex(
|
|
210
210
|
`http://example.com/?code=${code}`
|
|
211
211
|
);
|
|
@@ -220,6 +220,26 @@ describe('plugin-authorization-browser-first-party', () => {
|
|
|
220
220
|
|
|
221
221
|
await webex.authorization.when('change:ready');
|
|
222
222
|
|
|
223
|
+
assert.calledOnce(requestAuthorizationCodeGrantStub);
|
|
224
|
+
assert.calledWith(requestAuthorizationCodeGrantStub, {code, codeVerifier: undefined});
|
|
225
|
+
assert.calledOnce(collectPreauthCatalogStub);
|
|
226
|
+
assert.calledWith(collectPreauthCatalogStub, {orgId: 'theOrgId'});
|
|
227
|
+
});
|
|
228
|
+
|
|
229
|
+
it('collects the preauth catalog with no emailhash and no orgId', async () => {
|
|
230
|
+
const code = 'authcode_clusterid';
|
|
231
|
+
const webex = makeWebex(`http://example.com/?code=${code}`);
|
|
232
|
+
|
|
233
|
+
const requestAuthorizationCodeGrantStub = sinon.stub(
|
|
234
|
+
Authorization.prototype,
|
|
235
|
+
'requestAuthorizationCodeGrant'
|
|
236
|
+
);
|
|
237
|
+
const collectPreauthCatalogStub = sinon
|
|
238
|
+
.stub(Services.prototype, 'collectPreauthCatalog')
|
|
239
|
+
.resolves();
|
|
240
|
+
|
|
241
|
+
await webex.authorization.when('change:ready');
|
|
242
|
+
|
|
223
243
|
assert.calledOnce(requestAuthorizationCodeGrantStub);
|
|
224
244
|
assert.calledWith(requestAuthorizationCodeGrantStub, {code, codeVerifier: undefined});
|
|
225
245
|
assert.calledOnce(collectPreauthCatalogStub);
|
|
@@ -503,5 +523,46 @@ describe('plugin-authorization-browser-first-party', () => {
|
|
|
503
523
|
assert.notInclude(href, 'csrf_token');
|
|
504
524
|
});
|
|
505
525
|
});
|
|
526
|
+
|
|
527
|
+
describe('#_extractOrgIdFromCode', () => {
|
|
528
|
+
it('extracts the orgId from the code', () => {
|
|
529
|
+
const webex = makeWebex(undefined, undefined, {
|
|
530
|
+
credentials: {
|
|
531
|
+
clientType: 'confidential',
|
|
532
|
+
},
|
|
533
|
+
});
|
|
534
|
+
|
|
535
|
+
const code = 'authcode_clusterid_theOrgId';
|
|
536
|
+
const orgId = webex.authorization._extractOrgIdFromCode(code);
|
|
537
|
+
|
|
538
|
+
assert.equal(orgId, 'theOrgId');
|
|
539
|
+
});
|
|
540
|
+
|
|
541
|
+
it('handles an invalid code', () => {
|
|
542
|
+
const webex = makeWebex(undefined, undefined, {
|
|
543
|
+
credentials: {
|
|
544
|
+
clientType: 'confidential',
|
|
545
|
+
},
|
|
546
|
+
});
|
|
547
|
+
|
|
548
|
+
const code = 'authcode_clusterid_';
|
|
549
|
+
const orgId = webex.authorization._extractOrgIdFromCode(code);
|
|
550
|
+
|
|
551
|
+
assert.isUndefined(orgId);
|
|
552
|
+
});
|
|
553
|
+
|
|
554
|
+
it('handles an completely invalid code', () => {
|
|
555
|
+
const webex = makeWebex(undefined, undefined, {
|
|
556
|
+
credentials: {
|
|
557
|
+
clientType: 'confidential',
|
|
558
|
+
},
|
|
559
|
+
});
|
|
560
|
+
|
|
561
|
+
const code = 'authcode';
|
|
562
|
+
const orgId = webex.authorization._extractOrgIdFromCode(code);
|
|
563
|
+
|
|
564
|
+
assert.isUndefined(orgId);
|
|
565
|
+
})
|
|
566
|
+
});
|
|
506
567
|
});
|
|
507
568
|
});
|