@webex/plugin-authorization-browser 3.8.0-next.1 → 3.8.0-next.10

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.
@@ -8,10 +8,13 @@ _Object$defineProperty(exports, "__esModule", {
8
8
  exports.default = void 0;
9
9
  var _regenerator = _interopRequireDefault(require("@babel/runtime-corejs2/regenerator"));
10
10
  var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/asyncToGenerator"));
11
+ var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/slicedToArray"));
12
+ var _typeof2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/typeof"));
11
13
  var _applyDecoratedDescriptor2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/applyDecoratedDescriptor"));
12
14
  var _stringify = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/json/stringify"));
13
15
  var _apply = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/reflect/apply"));
14
16
  var _assign = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/object/assign"));
17
+ var _entries = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/object/entries"));
15
18
  var _promise = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/promise"));
16
19
  var _deleteProperty = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/reflect/delete-property"));
17
20
  var _parseInt2 = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/parse-int"));
@@ -121,11 +124,24 @@ var Authorization = _webexCore.WebexPlugin.extend((_dec = (0, _common.whileInFli
121
124
  return ret;
122
125
  },
123
126
  /**
124
- * Kicks off an oauth flow
127
+ * Initiates the OAuth flow for user authentication.
128
+ * This function determines the type of OAuth flow to use based on the client type configuration.
129
+ * If the client is configured as "confidential", it will initiate the Authorization Code Grant flow;
130
+ * otherwise, it will initiate the Implicit Grant flow.
131
+ *
125
132
  * @instance
126
133
  * @memberof AuthorizationBrowser
127
- * @param {Object} options
128
- * @returns {Promise}
134
+ * @param {Object} options - The options to configure the OAuth flow.
135
+ * @param {Object} [options.state] - An optional state object that can be used to include additional
136
+ * information such as security tokens. A CSRF token will be automatically generated and added to
137
+ * this state object.
138
+ * @param {boolean|Object} [options.separateWindow] - Determines if the login should open in a separate window.
139
+ * This can be a boolean or an object specifying window features:
140
+ * - If `true`, a new window with default dimensions is opened.
141
+ * - If an object, custom window features can be specified (e.g., `{width: 800, height: 600}`).
142
+ * @returns {Promise<void>} - A promise that resolves when the appropriate OAuth flow has been initiated.
143
+ * The promise does not necessarily indicate the completion of the login process.
144
+ * @throws {Error} - Throws an error if there are issues initiating the OAuth flow.
129
145
  */
130
146
  initiateLogin: function initiateLogin() {
131
147
  var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
@@ -140,18 +156,48 @@ var Authorization = _webexCore.WebexPlugin.extend((_dec = (0, _common.whileInFli
140
156
  return this.initiateImplicitGrant(options);
141
157
  },
142
158
  /**
143
- * Kicks off the Authorization Code grant flow. Typically called via
144
- * {@link AuthorizationBrowser#initiateLogin}
159
+ * Initiates the Implicit Grant flow for authorization.
160
+ * This function constructs the login URL and either opens it in a new
161
+ * window or in the current window based on the provided options.
162
+ * Typically called via {@link AuthorizationBrowser#initiateLogin}.
163
+ *
145
164
  * @instance
146
165
  * @memberof AuthorizationBrowser
147
- * @param {Object} options
148
- * @returns {Promise}
166
+ * @param {Object} options - The options to configure the login flow.
167
+ * @param {Object} [options.separateWindow] - Determines if the login should open in a separate window.
168
+ * This can be a boolean or an object specifying window features:
169
+ * - If `true`, a new window with default dimensions is opened.
170
+ * - If an object, custom window features can be specified (e.g., `{width: 800, height: 600}`).
171
+ * @returns {Promise<void>} - A promise that resolves immediately after initiating the login flow.
172
+ * This promise does not indicate the completion of the login process.
173
+ * @throws {Error} - Throws an error if the login URL cannot be constructed or if window opening fails.
149
174
  */
150
175
  initiateImplicitGrant: function initiateImplicitGrant(options) {
151
176
  this.logger.info('authorization: initiating implicit grant flow');
152
- this.webex.getWindow().location = this.webex.credentials.buildLoginUrl((0, _assign.default)({
177
+ var loginUrl = this.webex.credentials.buildLoginUrl((0, _assign.default)({
153
178
  response_type: 'token'
154
179
  }, options));
180
+ if (options !== null && options !== void 0 && options.separateWindow) {
181
+ // Default window settings
182
+ var defaultWindowSettings = {
183
+ width: 600,
184
+ height: 800
185
+ };
186
+
187
+ // Merge user provided settings with defaults
188
+ var windowSettings = (0, _assign.default)(defaultWindowSettings, (0, _typeof2.default)(options.separateWindow) === 'object' ? options.separateWindow : {});
189
+ // Convert settings object to window.open features string
190
+ var windowFeatures = (0, _entries.default)(windowSettings).map(function (_ref) {
191
+ var _ref2 = (0, _slicedToArray2.default)(_ref, 2),
192
+ key = _ref2[0],
193
+ value = _ref2[1];
194
+ return "".concat(key, "=").concat(value);
195
+ }).join(',');
196
+ this.webex.getWindow().open(loginUrl, '_blank', windowFeatures);
197
+ } else {
198
+ // Default behavior - open in same window
199
+ this.webex.getWindow().location = loginUrl;
200
+ }
155
201
  return _promise.default.resolve();
156
202
  },
157
203
  /**
@@ -184,9 +230,9 @@ var Authorization = _webexCore.WebexPlugin.extend((_dec = (0, _common.whileInFli
184
230
  * identifies a user in your system
185
231
  * @returns {Promise}
186
232
  */
187
- requestAccessTokenFromJwt: function requestAccessTokenFromJwt(_ref) {
233
+ requestAccessTokenFromJwt: function requestAccessTokenFromJwt(_ref3) {
188
234
  var _this2 = this;
189
- var jwt = _ref.jwt;
235
+ var jwt = _ref3.jwt;
190
236
  var hydraUri = this.webex.internal.services.get('hydra', true);
191
237
  if (hydraUri && hydraUri.slice(-1) !== '/') {
192
238
  // add a `/` to hydra's uri from the services catalog so that
@@ -200,8 +246,8 @@ var Authorization = _webexCore.WebexPlugin.extend((_dec = (0, _common.whileInFli
200
246
  headers: {
201
247
  authorization: jwt
202
248
  }
203
- }).then(function (_ref2) {
204
- var body = _ref2.body;
249
+ }).then(function (_ref4) {
250
+ var body = _ref4.body;
205
251
  return {
206
252
  access_token: body.token,
207
253
  token_type: 'Bearer',
@@ -238,13 +284,13 @@ var Authorization = _webexCore.WebexPlugin.extend((_dec = (0, _common.whileInFli
238
284
  * @param {String} options.expiresIn
239
285
  * @returns {Promise<object>}
240
286
  */
241
- createJwt: function createJwt(_ref3) {
287
+ createJwt: function createJwt(_ref5) {
242
288
  return (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee() {
243
289
  var issuer, secretId, displayName, expiresIn, secret, payload, alg, jwtToken;
244
290
  return _regenerator.default.wrap(function _callee$(_context) {
245
291
  while (1) switch (_context.prev = _context.next) {
246
292
  case 0:
247
- issuer = _ref3.issuer, secretId = _ref3.secretId, displayName = _ref3.displayName, expiresIn = _ref3.expiresIn;
293
+ issuer = _ref5.issuer, secretId = _ref5.secretId, displayName = _ref5.displayName, expiresIn = _ref5.expiresIn;
248
294
  secret = Buffer.from(secretId, 'base64');
249
295
  payload = {
250
296
  "sub": "guest-user-".concat((0, _uuid.default)()),
@@ -375,7 +421,7 @@ var Authorization = _webexCore.WebexPlugin.extend((_dec = (0, _common.whileInFli
375
421
  throw new Error("CSRF token ".concat(token, " does not match stored token ").concat(sessionToken));
376
422
  }
377
423
  },
378
- version: "3.8.0-next.1"
424
+ version: "3.8.0-next.10"
379
425
  }, ((0, _applyDecoratedDescriptor2.default)(_obj, "initiateImplicitGrant", [_dec], (0, _getOwnPropertyDescriptor.default)(_obj, "initiateImplicitGrant"), _obj), (0, _applyDecoratedDescriptor2.default)(_obj, "initiateAuthorizationCodeGrant", [_dec2], (0, _getOwnPropertyDescriptor.default)(_obj, "initiateAuthorizationCodeGrant"), _obj), (0, _applyDecoratedDescriptor2.default)(_obj, "requestAccessTokenFromJwt", [_common.oneFlight], (0, _getOwnPropertyDescriptor.default)(_obj, "requestAccessTokenFromJwt"), _obj)), _obj)));
380
426
  var _default = exports.default = Authorization;
381
427
  //# sourceMappingURL=authorization.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["_querystring","_interopRequireDefault","require","_url","_common","_webexCore","_lodash","_uuid","_dec","_dec2","_obj","jwt","OAUTH2_CSRF_TOKEN","EMPTY_OBJECT_STRING","base64","encode","_stringify","default","Authorization","WebexPlugin","extend","whileInFlight","derived","isAuthenticating","deps","fn","isAuthorizing","session","type","ready","namespace","initialize","attrs","options","_this","ret","_apply","prototype","parse","location","url","webex","getWindow","href","_checkForErrors","hash","includes","substr","querystring","state","JSON","decode","tokenData","_parseHash","_cleanUrl","process","nextTick","credentials","set","supertoken","initiateLogin","arguments","length","undefined","csrf_token","_generateSecurityToken","config","clientType","initiateAuthorizationCodeGrant","initiateImplicitGrant","logger","info","buildLoginUrl","_assign","response_type","_promise","resolve","requestAccessTokenFromJwt","_ref","_this2","hydraUri","internal","services","get","slice","env","HYDRA_SERVICE_URL","request","method","uri","concat","headers","authorization","then","_ref2","body","access_token","token","token_type","expires_in","expiresIn","initServiceCatalogs","logout","noRedirect","buildLogoutUrl","createJwt","_ref3","_asyncToGenerator2","_regenerator","mark","_callee","issuer","secretId","displayName","secret","payload","alg","jwtToken","wrap","_callee$","_context","prev","next","Buffer","from","uuid","sign","abrupt","t0","reject","stop","query","error","ErrorConstructor","grantErrors","select","cloneDeep","history","replaceState","forEach","key","_deleteProperty","isEmpty","omit","stringify","format","v4","sessionStorage","setItem","_verifySecurityToken","_parseInt2","refresh_token_expires_in","sessionToken","getItem","removeItem","Error","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';\nconst jwt = require('jsonwebtoken');\n\nconst OAUTH2_CSRF_TOKEN = 'oauth2-csrf-token';\nconst EMPTY_OBJECT_STRING = base64.encode(JSON.stringify({}));\n\n/**\n * Browser support for OAuth2. Automatically parses the URL hash for an access\n * token\n * @class\n * @name AuthorizationBrowser\n */\nconst Authorization = WebexPlugin.extend({\n derived: {\n /**\n * Alias of {@link AuthorizationBrowser#isAuthorizing}\n * @instance\n * @memberof AuthorizationBrowser\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 AuthorizationBrowser\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 AuthorizationBrowser\n * @param {Object} attrs {@link AmpersandState}\n * @param {boolean} attrs.parse Controls whether or not the the url should get\n * parsed for an access token\n * @private\n * @returns {Authorization}\n */\n // eslint-disable-next-line complexity\n initialize(attrs, options) {\n const ret = Reflect.apply(WebexPlugin.prototype.initialize, this, [attrs, options]);\n\n // Reminder, we can't do parse based on config, because config is not\n // available until nextTick and we want to be able to throw errors found in\n // the url.\n if (attrs.parse === false) {\n this.ready = true;\n\n return ret;\n }\n const location = url.parse(this.webex.getWindow().location.href, true);\n\n this._checkForErrors(location);\n\n let {hash} = location;\n\n if (!hash) {\n this.ready = true;\n\n return ret;\n }\n if (hash.includes('#')) {\n hash = hash.substr(1);\n }\n location.hash = querystring.parse(hash);\n if (location.hash.state) {\n location.hash.state = JSON.parse(base64.decode(location.hash.state));\n }\n const tokenData = this._parseHash(location);\n\n if (!tokenData) {\n return ret;\n }\n this._cleanUrl(location);\n\n // Wait until nextTick in case `credentials` hasn't initialized yet\n process.nextTick(() => {\n this.webex.credentials.set({supertoken: tokenData});\n this.ready = true;\n });\n\n return ret;\n },\n\n /**\n * Kicks off an oauth flow\n * @instance\n * @memberof AuthorizationBrowser\n * @param {Object} options\n * @returns {Promise}\n */\n initiateLogin(options = {}) {\n options.state = options.state || {};\n options.state.csrf_token = this._generateSecurityToken();\n\n // If we're not explicitly a confidential client, assume we're a public\n // client\n if (this.config.clientType === 'confidential') {\n return this.initiateAuthorizationCodeGrant(options);\n }\n\n return this.initiateImplicitGrant(options);\n },\n\n @whileInFlight('isAuthorizing')\n /**\n * Kicks off the Authorization Code grant flow. Typically called via\n * {@link AuthorizationBrowser#initiateLogin}\n * @instance\n * @memberof AuthorizationBrowser\n * @param {Object} options\n * @returns {Promise}\n */\n initiateImplicitGrant(options) {\n this.logger.info('authorization: initiating implicit grant flow');\n this.webex.getWindow().location = this.webex.credentials.buildLoginUrl(\n Object.assign({response_type: 'token'}, options)\n );\n\n return Promise.resolve();\n },\n\n @whileInFlight('isAuthorizing')\n /**\n * Kicks off the Implicit Code grant flow. Typically called via\n * {@link AuthorizationBrowser#initiateLogin}\n * @instance\n * @memberof AuthorizationBrowser\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 @oneFlight\n /**\n * Requests a Webex access token for a user already authenticated into\n * your product.\n *\n * Note: You'll need to supply a jwtRefreshCallback of the form\n * `Promise<jwt> = jwtRefreshCallback(webex)` for automatic token refresh to\n * work.\n *\n * @instance\n * @memberof AuthorizationBrowser\n * @param {Object} options\n * @param {Object} options.jwt This is a jwt generated by your backend that\n * identifies a user in your system\n * @returns {Promise}\n */\n requestAccessTokenFromJwt({jwt}) {\n let hydraUri = this.webex.internal.services.get('hydra', true);\n\n if (hydraUri && hydraUri.slice(-1) !== '/') {\n // add a `/` to hydra's uri from the services catalog so that\n // it matches the current env service format.\n hydraUri += '/';\n }\n\n hydraUri = hydraUri || process.env.HYDRA_SERVICE_URL || 'https://api.ciscospark.com/v1/';\n\n return this.webex\n .request({\n method: 'POST',\n uri: `${hydraUri}jwt/login`,\n headers: {\n authorization: jwt,\n },\n })\n .then(({body}) => ({\n access_token: body.token,\n token_type: 'Bearer',\n expires_in: body.expiresIn,\n }))\n .then((token) => {\n this.webex.credentials.set({\n supertoken: token,\n });\n })\n .then(() => this.webex.internal.services.initServiceCatalogs());\n },\n\n /**\n * Called by {@link WebexCore#logout()}. Redirects to the logout page\n * @instance\n * @memberof AuthorizationBrowser\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 /**\n * Creates a jwt user token\n * @param {object} options\n * @param {String} options.issuer Guest Issuer ID\n * @param {String} options.secretId Guest Secret ID\n * @param {String} options.displayName Guest Display Name | optional\n * @param {String} options.expiresIn\n * @returns {Promise<object>}\n */\n async createJwt({issuer, secretId, displayName, expiresIn}) {\n const secret = Buffer.from(secretId, 'base64');\n const payload = {\n \"sub\": `guest-user-${uuid()}`,\n \"iss\": issuer,\n \"name\": displayName || `Guest User - ${uuid()}`\n };\n const alg = 'HS256';\n\n try {\n\n const jwtToken = jwt.sign(payload, secret, { expiresIn });\n\n return Promise.resolve({jwt: jwtToken});\n } catch (e) {\n return Promise.reject(e);\n }\n },\n\n /**\n * Checks if the result of the login redirect contains an error string\n * @instance\n * @memberof AuthorizationBrowser\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 AuthorizationBrowser\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 [\n 'access_token',\n 'token_type',\n 'expires_in',\n 'refresh_token',\n 'refresh_token_expires_in',\n ].forEach((key) => Reflect.deleteProperty(location.hash, key));\n if (!isEmpty(location.hash.state)) {\n location.hash.state = base64.encode(\n JSON.stringify(omit(location.hash.state, 'csrf_token'))\n );\n if (location.hash.state === EMPTY_OBJECT_STRING) {\n Reflect.deleteProperty(location.hash, 'state');\n }\n } else {\n Reflect.deleteProperty(location.hash, 'state');\n }\n location.hash = querystring.stringify(location.hash);\n this.webex.getWindow().history.replaceState({}, null, url.format(location));\n }\n },\n\n /**\n * Generates a CSRF token and sticks in in sessionStorage\n * @instance\n * @memberof AuthorizationBrowser\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 * Parses the url hash into an access token object\n * @instance\n * @memberof AuthorizationBrowser\n * @param {Object} location\n * @private\n * @returns {Object}\n */\n _parseHash(location) {\n const hash = cloneDeep(location.hash);\n\n if (hash) {\n this._verifySecurityToken(hash);\n }\n if (!hash.access_token) {\n this.ready = true;\n\n return undefined;\n }\n if (hash.expires_in) {\n hash.expires_in = parseInt(hash.expires_in, 10);\n }\n if (hash.refresh_token_expires_in) {\n hash.refresh_token_expires_in = parseInt(hash.refresh_token_expires_in, 10);\n }\n\n return hash;\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 AuthorizationBrowser\n * @param {Object} hash\n * @private\n * @returns {Promise}\n */\n _verifySecurityToken(hash) {\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 (!hash.state) {\n throw new Error(`Expected CSRF token ${sessionToken}, but not found in redirect hash`);\n }\n\n if (!hash.state.csrf_token) {\n throw new Error(`Expected CSRF token ${sessionToken}, but not found in redirect hash`);\n }\n\n const token = hash.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","_dec","_dec2","_obj","jwt","OAUTH2_CSRF_TOKEN","EMPTY_OBJECT_STRING","base64","encode","_stringify","default","Authorization","WebexPlugin","extend","whileInFlight","derived","isAuthenticating","deps","fn","isAuthorizing","session","type","ready","namespace","initialize","attrs","options","_this","ret","_apply","prototype","parse","location","url","webex","getWindow","href","_checkForErrors","hash","includes","substr","querystring","state","JSON","decode","tokenData","_parseHash","_cleanUrl","process","nextTick","credentials","set","supertoken","initiateLogin","arguments","length","undefined","csrf_token","_generateSecurityToken","config","clientType","initiateAuthorizationCodeGrant","initiateImplicitGrant","logger","info","loginUrl","buildLoginUrl","_assign","response_type","separateWindow","defaultWindowSettings","width","height","windowSettings","_typeof2","windowFeatures","_entries","map","_ref","_ref2","_slicedToArray2","key","value","concat","join","open","_promise","resolve","requestAccessTokenFromJwt","_ref3","_this2","hydraUri","internal","services","get","slice","env","HYDRA_SERVICE_URL","request","method","uri","headers","authorization","then","_ref4","body","access_token","token","token_type","expires_in","expiresIn","initServiceCatalogs","logout","noRedirect","buildLogoutUrl","createJwt","_ref5","_asyncToGenerator2","_regenerator","mark","_callee","issuer","secretId","displayName","secret","payload","alg","jwtToken","wrap","_callee$","_context","prev","next","Buffer","from","uuid","sign","abrupt","t0","reject","stop","query","error","ErrorConstructor","grantErrors","select","cloneDeep","history","replaceState","forEach","_deleteProperty","isEmpty","omit","stringify","format","v4","sessionStorage","setItem","_verifySecurityToken","_parseInt2","refresh_token_expires_in","sessionToken","getItem","removeItem","Error","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';\nconst jwt = require('jsonwebtoken');\n\nconst OAUTH2_CSRF_TOKEN = 'oauth2-csrf-token';\nconst EMPTY_OBJECT_STRING = base64.encode(JSON.stringify({}));\n\n/**\n * Browser support for OAuth2. Automatically parses the URL hash for an access\n * token\n * @class\n * @name AuthorizationBrowser\n */\nconst Authorization = WebexPlugin.extend({\n derived: {\n /**\n * Alias of {@link AuthorizationBrowser#isAuthorizing}\n * @instance\n * @memberof AuthorizationBrowser\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 AuthorizationBrowser\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 AuthorizationBrowser\n * @param {Object} attrs {@link AmpersandState}\n * @param {boolean} attrs.parse Controls whether or not the the url should get\n * parsed for an access token\n * @private\n * @returns {Authorization}\n */\n // eslint-disable-next-line complexity\n initialize(attrs, options) {\n const ret = Reflect.apply(WebexPlugin.prototype.initialize, this, [attrs, options]);\n\n // Reminder, we can't do parse based on config, because config is not\n // available until nextTick and we want to be able to throw errors found in\n // the url.\n if (attrs.parse === false) {\n this.ready = true;\n\n return ret;\n }\n const location = url.parse(this.webex.getWindow().location.href, true);\n\n this._checkForErrors(location);\n\n let {hash} = location;\n\n if (!hash) {\n this.ready = true;\n\n return ret;\n }\n if (hash.includes('#')) {\n hash = hash.substr(1);\n }\n location.hash = querystring.parse(hash);\n if (location.hash.state) {\n location.hash.state = JSON.parse(base64.decode(location.hash.state));\n }\n const tokenData = this._parseHash(location);\n\n if (!tokenData) {\n return ret;\n }\n this._cleanUrl(location);\n\n // Wait until nextTick in case `credentials` hasn't initialized yet\n process.nextTick(() => {\n this.webex.credentials.set({supertoken: tokenData});\n this.ready = true;\n });\n\n return ret;\n },\n\n/**\n * Initiates the OAuth flow for user authentication.\n * This function determines the type of OAuth flow to use based on the client type configuration.\n * If the client is configured as \"confidential\", it will initiate the Authorization Code Grant flow;\n * otherwise, it will initiate the Implicit Grant flow.\n *\n * @instance\n * @memberof AuthorizationBrowser\n * @param {Object} options - The options to configure the OAuth flow.\n * @param {Object} [options.state] - An optional state object that can be used to include additional\n * information such as security tokens. A CSRF token will be automatically generated and added to\n * this state object.\n * @param {boolean|Object} [options.separateWindow] - Determines if the login should open in a separate window.\n * This can be a boolean or an object specifying window features:\n * - If `true`, a new window with default dimensions is opened.\n * - If an object, custom window features can be specified (e.g., `{width: 800, height: 600}`).\n * @returns {Promise<void>} - A promise that resolves when the appropriate OAuth flow has been initiated.\n * The promise does not necessarily indicate the completion of the login process.\n * @throws {Error} - Throws an error if there are issues initiating the OAuth flow.\n */\n initiateLogin(options = {}) {\n options.state = options.state || {};\n options.state.csrf_token = this._generateSecurityToken();\n\n // If we're not explicitly a confidential client, assume we're a public\n // client\n if (this.config.clientType === 'confidential') {\n return this.initiateAuthorizationCodeGrant(options);\n }\n\n return this.initiateImplicitGrant(options);\n },\n\n @whileInFlight('isAuthorizing')\n/**\n * Initiates the Implicit Grant flow for authorization.\n * This function constructs the login URL and either opens it in a new\n * window or in the current window based on the provided options.\n * Typically called via {@link AuthorizationBrowser#initiateLogin}.\n *\n * @instance\n * @memberof AuthorizationBrowser\n * @param {Object} options - The options to configure the login flow.\n * @param {Object} [options.separateWindow] - Determines if the login should open in a separate window.\n * This can be a boolean or an object specifying window features:\n * - If `true`, a new window with default dimensions is opened.\n * - If an object, custom window features can be specified (e.g., `{width: 800, height: 600}`).\n * @returns {Promise<void>} - A promise that resolves immediately after initiating the login flow.\n * This promise does not indicate the completion of the login process.\n * @throws {Error} - Throws an error if the login URL cannot be constructed or if window opening fails.\n */\n initiateImplicitGrant(options) {\n\n this.logger.info('authorization: initiating implicit grant flow');\n const loginUrl = this.webex.credentials.buildLoginUrl(\n Object.assign({response_type: 'token'}, options)\n );\n\n if (options?.separateWindow) {\n // Default window settings\n const defaultWindowSettings = {\n width: 600,\n height: 800\n };\n\n // Merge user provided settings with defaults\n const windowSettings = Object.assign(\n defaultWindowSettings, \n typeof options.separateWindow === 'object' ? options.separateWindow : {}\n );\n // Convert settings object to window.open features string\n const windowFeatures = Object.entries(windowSettings)\n .map(([key, value]) => `${key}=${value}`)\n .join(',');\n this.webex.getWindow().open(loginUrl, '_blank', windowFeatures);\n } else {\n // Default behavior - open in same window\n this.webex.getWindow().location = loginUrl;\n }\n\n return Promise.resolve();\n },\n\n @whileInFlight('isAuthorizing')\n /**\n * Kicks off the Implicit Code grant flow. Typically called via\n * {@link AuthorizationBrowser#initiateLogin}\n * @instance\n * @memberof AuthorizationBrowser\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 @oneFlight\n /**\n * Requests a Webex access token for a user already authenticated into\n * your product.\n *\n * Note: You'll need to supply a jwtRefreshCallback of the form\n * `Promise<jwt> = jwtRefreshCallback(webex)` for automatic token refresh to\n * work.\n *\n * @instance\n * @memberof AuthorizationBrowser\n * @param {Object} options\n * @param {Object} options.jwt This is a jwt generated by your backend that\n * identifies a user in your system\n * @returns {Promise}\n */\n requestAccessTokenFromJwt({jwt}) {\n let hydraUri = this.webex.internal.services.get('hydra', true);\n\n if (hydraUri && hydraUri.slice(-1) !== '/') {\n // add a `/` to hydra's uri from the services catalog so that\n // it matches the current env service format.\n hydraUri += '/';\n }\n\n hydraUri = hydraUri || process.env.HYDRA_SERVICE_URL || 'https://api.ciscospark.com/v1/';\n\n return this.webex\n .request({\n method: 'POST',\n uri: `${hydraUri}jwt/login`,\n headers: {\n authorization: jwt,\n },\n })\n .then(({body}) => ({\n access_token: body.token,\n token_type: 'Bearer',\n expires_in: body.expiresIn,\n }))\n .then((token) => {\n this.webex.credentials.set({\n supertoken: token,\n });\n })\n .then(() => this.webex.internal.services.initServiceCatalogs());\n },\n\n /**\n * Called by {@link WebexCore#logout()}. Redirects to the logout page\n * @instance\n * @memberof AuthorizationBrowser\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 /**\n * Creates a jwt user token\n * @param {object} options\n * @param {String} options.issuer Guest Issuer ID\n * @param {String} options.secretId Guest Secret ID\n * @param {String} options.displayName Guest Display Name | optional\n * @param {String} options.expiresIn\n * @returns {Promise<object>}\n */\n async createJwt({issuer, secretId, displayName, expiresIn}) {\n const secret = Buffer.from(secretId, 'base64');\n const payload = {\n \"sub\": `guest-user-${uuid()}`,\n \"iss\": issuer,\n \"name\": displayName || `Guest User - ${uuid()}`\n };\n const alg = 'HS256';\n\n try {\n\n const jwtToken = jwt.sign(payload, secret, { expiresIn });\n\n return Promise.resolve({jwt: jwtToken});\n } catch (e) {\n return Promise.reject(e);\n }\n },\n\n /**\n * Checks if the result of the login redirect contains an error string\n * @instance\n * @memberof AuthorizationBrowser\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 AuthorizationBrowser\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 [\n 'access_token',\n 'token_type',\n 'expires_in',\n 'refresh_token',\n 'refresh_token_expires_in',\n ].forEach((key) => Reflect.deleteProperty(location.hash, key));\n if (!isEmpty(location.hash.state)) {\n location.hash.state = base64.encode(\n JSON.stringify(omit(location.hash.state, 'csrf_token'))\n );\n if (location.hash.state === EMPTY_OBJECT_STRING) {\n Reflect.deleteProperty(location.hash, 'state');\n }\n } else {\n Reflect.deleteProperty(location.hash, 'state');\n }\n location.hash = querystring.stringify(location.hash);\n this.webex.getWindow().history.replaceState({}, null, url.format(location));\n }\n },\n\n /**\n * Generates a CSRF token and sticks in in sessionStorage\n * @instance\n * @memberof AuthorizationBrowser\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 * Parses the url hash into an access token object\n * @instance\n * @memberof AuthorizationBrowser\n * @param {Object} location\n * @private\n * @returns {Object}\n */\n _parseHash(location) {\n const hash = cloneDeep(location.hash);\n\n if (hash) {\n this._verifySecurityToken(hash);\n }\n if (!hash.access_token) {\n this.ready = true;\n\n return undefined;\n }\n if (hash.expires_in) {\n hash.expires_in = parseInt(hash.expires_in, 10);\n }\n if (hash.refresh_token_expires_in) {\n hash.refresh_token_expires_in = parseInt(hash.refresh_token_expires_in, 10);\n }\n\n return hash;\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 AuthorizationBrowser\n * @param {Object} hash\n * @private\n * @returns {Promise}\n */\n _verifySecurityToken(hash) {\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 (!hash.state) {\n throw new Error(`Expected CSRF token ${sessionToken}, but not found in redirect hash`);\n }\n\n if (!hash.state.csrf_token) {\n throw new Error(`Expected CSRF token ${sessionToken}, but not found in redirect hash`);\n }\n\n const token = hash.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
@@ -24,23 +24,23 @@
24
24
  "@webex/eslint-config-legacy": "0.0.0",
25
25
  "@webex/jest-config-legacy": "0.0.0",
26
26
  "@webex/legacy-tools": "0.0.0",
27
- "@webex/test-helper-appid": "3.8.0-next.1",
28
- "@webex/test-helper-automation": "3.8.0-next.1",
29
- "@webex/test-helper-chai": "3.8.0-next.1",
30
- "@webex/test-helper-mocha": "3.8.0-next.1",
31
- "@webex/test-helper-mock-webex": "3.8.0-next.1",
32
- "@webex/test-helper-test-users": "3.8.0-next.1",
27
+ "@webex/test-helper-appid": "3.8.0-next.9",
28
+ "@webex/test-helper-automation": "3.8.0-next.9",
29
+ "@webex/test-helper-chai": "3.8.0-next.9",
30
+ "@webex/test-helper-mocha": "3.8.0-next.9",
31
+ "@webex/test-helper-mock-webex": "3.8.0-next.9",
32
+ "@webex/test-helper-test-users": "3.8.0-next.9",
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.8.0-next.1",
39
- "@webex/internal-plugin-device": "3.8.0-next.1",
40
- "@webex/plugin-authorization-node": "3.8.0-next.1",
41
- "@webex/storage-adapter-local-storage": "3.8.0-next.1",
42
- "@webex/storage-adapter-spec": "3.8.0-next.1",
43
- "@webex/webex-core": "3.8.0-next.1",
38
+ "@webex/common": "3.8.0-next.9",
39
+ "@webex/internal-plugin-device": "3.8.0-next.9",
40
+ "@webex/plugin-authorization-node": "3.8.0-next.9",
41
+ "@webex/storage-adapter-local-storage": "3.8.0-next.9",
42
+ "@webex/storage-adapter-spec": "3.8.0-next.9",
43
+ "@webex/webex-core": "3.8.0-next.9",
44
44
  "jsonwebtoken": "^9.0.2",
45
45
  "lodash": "^4.17.21",
46
46
  "uuid": "^3.3.2"
@@ -54,5 +54,5 @@
54
54
  "test:style": "eslint ./src/**/*.*",
55
55
  "test:unit": "webex-legacy-tools test --unit --runner jest"
56
56
  },
57
- "version": "3.8.0-next.1"
57
+ "version": "3.8.0-next.10"
58
58
  }
@@ -113,13 +113,26 @@ const Authorization = WebexPlugin.extend({
113
113
  return ret;
114
114
  },
115
115
 
116
- /**
117
- * Kicks off an oauth flow
118
- * @instance
119
- * @memberof AuthorizationBrowser
120
- * @param {Object} options
121
- * @returns {Promise}
122
- */
116
+ /**
117
+ * Initiates the OAuth flow for user authentication.
118
+ * This function determines the type of OAuth flow to use based on the client type configuration.
119
+ * If the client is configured as "confidential", it will initiate the Authorization Code Grant flow;
120
+ * otherwise, it will initiate the Implicit Grant flow.
121
+ *
122
+ * @instance
123
+ * @memberof AuthorizationBrowser
124
+ * @param {Object} options - The options to configure the OAuth flow.
125
+ * @param {Object} [options.state] - An optional state object that can be used to include additional
126
+ * information such as security tokens. A CSRF token will be automatically generated and added to
127
+ * this state object.
128
+ * @param {boolean|Object} [options.separateWindow] - Determines if the login should open in a separate window.
129
+ * This can be a boolean or an object specifying window features:
130
+ * - If `true`, a new window with default dimensions is opened.
131
+ * - If an object, custom window features can be specified (e.g., `{width: 800, height: 600}`).
132
+ * @returns {Promise<void>} - A promise that resolves when the appropriate OAuth flow has been initiated.
133
+ * The promise does not necessarily indicate the completion of the login process.
134
+ * @throws {Error} - Throws an error if there are issues initiating the OAuth flow.
135
+ */
123
136
  initiateLogin(options = {}) {
124
137
  options.state = options.state || {};
125
138
  options.state.csrf_token = this._generateSecurityToken();
@@ -134,20 +147,52 @@ const Authorization = WebexPlugin.extend({
134
147
  },
135
148
 
136
149
  @whileInFlight('isAuthorizing')
137
- /**
138
- * Kicks off the Authorization Code grant flow. Typically called via
139
- * {@link AuthorizationBrowser#initiateLogin}
140
- * @instance
141
- * @memberof AuthorizationBrowser
142
- * @param {Object} options
143
- * @returns {Promise}
144
- */
150
+ /**
151
+ * Initiates the Implicit Grant flow for authorization.
152
+ * This function constructs the login URL and either opens it in a new
153
+ * window or in the current window based on the provided options.
154
+ * Typically called via {@link AuthorizationBrowser#initiateLogin}.
155
+ *
156
+ * @instance
157
+ * @memberof AuthorizationBrowser
158
+ * @param {Object} options - The options to configure the login flow.
159
+ * @param {Object} [options.separateWindow] - Determines if the login should open in a separate window.
160
+ * This can be a boolean or an object specifying window features:
161
+ * - If `true`, a new window with default dimensions is opened.
162
+ * - If an object, custom window features can be specified (e.g., `{width: 800, height: 600}`).
163
+ * @returns {Promise<void>} - A promise that resolves immediately after initiating the login flow.
164
+ * This promise does not indicate the completion of the login process.
165
+ * @throws {Error} - Throws an error if the login URL cannot be constructed or if window opening fails.
166
+ */
145
167
  initiateImplicitGrant(options) {
168
+
146
169
  this.logger.info('authorization: initiating implicit grant flow');
147
- this.webex.getWindow().location = this.webex.credentials.buildLoginUrl(
170
+ const loginUrl = this.webex.credentials.buildLoginUrl(
148
171
  Object.assign({response_type: 'token'}, options)
149
172
  );
150
173
 
174
+ if (options?.separateWindow) {
175
+ // Default window settings
176
+ const defaultWindowSettings = {
177
+ width: 600,
178
+ height: 800
179
+ };
180
+
181
+ // Merge user provided settings with defaults
182
+ const windowSettings = Object.assign(
183
+ defaultWindowSettings,
184
+ typeof options.separateWindow === 'object' ? options.separateWindow : {}
185
+ );
186
+ // Convert settings object to window.open features string
187
+ const windowFeatures = Object.entries(windowSettings)
188
+ .map(([key, value]) => `${key}=${value}`)
189
+ .join(',');
190
+ this.webex.getWindow().open(loginUrl, '_blank', windowFeatures);
191
+ } else {
192
+ // Default behavior - open in same window
193
+ this.webex.getWindow().location = loginUrl;
194
+ }
195
+
151
196
  return Promise.resolve();
152
197
  },
153
198
 
@@ -408,6 +408,65 @@ describe('plugin-authorization-browser', () => {
408
408
  assert.include(webex.getWindow().location, 'response_type=token');
409
409
  });
410
410
  });
411
+
412
+ it('redirects to the login page in the same window by default', () => {
413
+ const webex = makeWebexCore();
414
+
415
+ return webex.authorization.initiateImplicitGrant().then(() => {
416
+ assert.isDefined(webex.getWindow().location);
417
+ assert.isUndefined(webex.getWindow().open);
418
+ });
419
+ });
420
+
421
+ it('opens login page in a new window when separateWindow is true', () => {
422
+ const webex = makeWebexCore();
423
+ webex.getWindow().open = sinon.spy();
424
+
425
+ return webex.authorization.initiateImplicitGrant({ separateWindow: true }).then(() => {
426
+ assert.called(webex.getWindow().open);
427
+ const openCall = webex.getWindow().open.getCall(0);
428
+ assert.equal(openCall.args[1], '_blank');
429
+ assert.equal(openCall.args[2], 'width=600,height=800');
430
+ });
431
+ });
432
+
433
+ it('opens login page in a new window with custom dimensions', () => {
434
+ const webex = makeWebexCore();
435
+ webex.getWindow().open = sinon.spy();
436
+
437
+ const customWindow = {
438
+ width: 800,
439
+ height: 600,
440
+ menubar: 'no',
441
+ toolbar: 'no'
442
+ };
443
+
444
+ return webex.authorization.initiateImplicitGrant({
445
+ separateWindow: customWindow
446
+ }).then(() => {
447
+ assert.called(webex.getWindow().open);
448
+ const openCall = webex.getWindow().open.getCall(0);
449
+ assert.equal(openCall.args[1], '_blank');
450
+ assert.equal(
451
+ openCall.args[2],
452
+ 'width=800,height=600,menubar=no,toolbar=no'
453
+ );
454
+ });
455
+ });
456
+
457
+ it('preserves other options when using separateWindow', () => {
458
+ const webex = makeWebexCore();
459
+ webex.getWindow().open = sinon.spy();
460
+
461
+ return webex.authorization.initiateImplicitGrant({
462
+ separateWindow: true,
463
+ state: {}
464
+ }).then(() => {
465
+ assert.called(webex.getWindow().open);
466
+ const url = webex.getWindow().open.getCall(0).args[0];
467
+ assert.include(url, "https://idbrokerbts.webex.com/idb/oauth2/v1/authorize?response_type=token&separateWindow=true&client_id=fake&redirect_uri=http%3A%2F%2Fexample.com&scope=scope%3Aone");
468
+ });
469
+ });
411
470
  });
412
471
 
413
472
  describe('#initiateAuthorizationCodeGrant()', () => {