@webex/plugin-meetings 1.151.0 → 1.151.4
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/meeting/index.js +3 -1
- package/dist/meeting/index.js.map +1 -1
- package/dist/meeting-info/utilv2.js +81 -37
- package/dist/meeting-info/utilv2.js.map +1 -1
- package/dist/metrics/index.js +43 -48
- package/dist/metrics/index.js.map +1 -1
- package/package.json +6 -5
- package/src/meeting/index.js +1 -1
- package/src/meeting-info/utilv2.js +30 -5
- package/src/metrics/index.js +5 -15
- package/test/integration/spec/space-meeting.js +8 -3
- package/test/unit/spec/meeting/index.js +0 -1
- package/test/unit/spec/meeting-info/utilv2.js +65 -4
- package/test/unit/spec/metrics/index.js +42 -1
|
@@ -131,15 +131,56 @@ MeetingInfoUtil.getSipUriFromHydraPersonId = function (destination, webex) {
|
|
|
131
131
|
|
|
132
132
|
MeetingInfoUtil.getDestinationType = /*#__PURE__*/function () {
|
|
133
133
|
var _ref = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(from) {
|
|
134
|
-
var destination,
|
|
134
|
+
var type, webex, destination, _options, res, _res$items$, orgId, userId, options, hydraId, conversationUrl;
|
|
135
|
+
|
|
135
136
|
return _regenerator.default.wrap(function _callee$(_context) {
|
|
136
137
|
while (1) {
|
|
137
138
|
switch (_context.prev = _context.next) {
|
|
138
139
|
case 0:
|
|
139
|
-
|
|
140
|
+
type = from.type, webex = from.webex;
|
|
141
|
+
destination = from.destination;
|
|
142
|
+
|
|
143
|
+
if (!(type === _constants._PERSONAL_ROOM_)) {
|
|
144
|
+
_context.next = 15;
|
|
145
|
+
break;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
if (destination) {
|
|
149
|
+
_context.next = 7;
|
|
150
|
+
break;
|
|
151
|
+
}
|
|
140
152
|
|
|
153
|
+
// if we are not getting anything in desination we fetch org and user ids from webex instance
|
|
154
|
+
destination = {
|
|
155
|
+
userId: webex.internal.device.userId,
|
|
156
|
+
orgId: webex.internal.device.orgId
|
|
157
|
+
};
|
|
158
|
+
_context.next = 15;
|
|
159
|
+
break;
|
|
160
|
+
|
|
161
|
+
case 7:
|
|
162
|
+
_options = _constants.VALID_EMAIL_ADDRESS.test(destination) ? {
|
|
163
|
+
email: destination
|
|
164
|
+
} : {
|
|
165
|
+
id: destination
|
|
166
|
+
}; // we are assuming userId as default
|
|
167
|
+
|
|
168
|
+
_context.next = 10;
|
|
169
|
+
return webex.people.list(_options);
|
|
170
|
+
|
|
171
|
+
case 10:
|
|
172
|
+
res = _context.sent;
|
|
173
|
+
_res$items$ = res.items[0], orgId = _res$items$.orgId, userId = _res$items$.id;
|
|
174
|
+
userId = (0, _common.deconstructHydraId)(userId).id;
|
|
175
|
+
orgId = (0, _common.deconstructHydraId)(orgId).id;
|
|
176
|
+
destination = {
|
|
177
|
+
userId: userId,
|
|
178
|
+
orgId: orgId
|
|
179
|
+
};
|
|
180
|
+
|
|
181
|
+
case 15:
|
|
141
182
|
if (!type) {
|
|
142
|
-
_context.next =
|
|
183
|
+
_context.next = 17;
|
|
143
184
|
break;
|
|
144
185
|
}
|
|
145
186
|
|
|
@@ -148,12 +189,12 @@ MeetingInfoUtil.getDestinationType = /*#__PURE__*/function () {
|
|
|
148
189
|
type: type
|
|
149
190
|
});
|
|
150
191
|
|
|
151
|
-
case
|
|
192
|
+
case 17:
|
|
152
193
|
options = {};
|
|
153
194
|
hydraId = MeetingInfoUtil.getHydraId(destination);
|
|
154
195
|
|
|
155
196
|
if (!MeetingInfoUtil.isMeetingLink(destination)) {
|
|
156
|
-
_context.next =
|
|
197
|
+
_context.next = 25;
|
|
157
198
|
break;
|
|
158
199
|
}
|
|
159
200
|
|
|
@@ -161,45 +202,45 @@ MeetingInfoUtil.getDestinationType = /*#__PURE__*/function () {
|
|
|
161
202
|
|
|
162
203
|
options.type = _constants._MEETING_LINK_;
|
|
163
204
|
options.destination = destination;
|
|
164
|
-
_context.next =
|
|
205
|
+
_context.next = 62;
|
|
165
206
|
break;
|
|
166
207
|
|
|
167
|
-
case
|
|
208
|
+
case 25:
|
|
168
209
|
if (!MeetingInfoUtil.isSipUri(destination)) {
|
|
169
|
-
_context.next =
|
|
210
|
+
_context.next = 30;
|
|
170
211
|
break;
|
|
171
212
|
}
|
|
172
213
|
|
|
173
214
|
options.type = _constants._SIP_URI_;
|
|
174
215
|
options.destination = destination;
|
|
175
|
-
_context.next =
|
|
216
|
+
_context.next = 62;
|
|
176
217
|
break;
|
|
177
218
|
|
|
178
|
-
case
|
|
219
|
+
case 30:
|
|
179
220
|
if (!MeetingInfoUtil.isPhoneNumber(destination)) {
|
|
180
|
-
_context.next =
|
|
221
|
+
_context.next = 35;
|
|
181
222
|
break;
|
|
182
223
|
}
|
|
183
224
|
|
|
184
225
|
options.type = _constants._SIP_URI_;
|
|
185
226
|
options.destination = destination;
|
|
186
|
-
_context.next =
|
|
227
|
+
_context.next = 62;
|
|
187
228
|
break;
|
|
188
229
|
|
|
189
|
-
case
|
|
230
|
+
case 35:
|
|
190
231
|
if (!MeetingInfoUtil.isConversationUrl(destination, webex)) {
|
|
191
|
-
_context.next =
|
|
232
|
+
_context.next = 40;
|
|
192
233
|
break;
|
|
193
234
|
}
|
|
194
235
|
|
|
195
236
|
options.type = _constants._CONVERSATION_URL_;
|
|
196
237
|
options.destination = destination;
|
|
197
|
-
_context.next =
|
|
238
|
+
_context.next = 62;
|
|
198
239
|
break;
|
|
199
240
|
|
|
200
|
-
case
|
|
241
|
+
case 40:
|
|
201
242
|
if (!hydraId.people) {
|
|
202
|
-
_context.next =
|
|
243
|
+
_context.next = 45;
|
|
203
244
|
break;
|
|
204
245
|
}
|
|
205
246
|
|
|
@@ -216,52 +257,52 @@ MeetingInfoUtil.getDestinationType = /*#__PURE__*/function () {
|
|
|
216
257
|
return _promise.default.resolve(options);
|
|
217
258
|
}));
|
|
218
259
|
|
|
219
|
-
case
|
|
260
|
+
case 45:
|
|
220
261
|
if (!hydraId.room) {
|
|
221
|
-
_context.next =
|
|
262
|
+
_context.next = 60;
|
|
222
263
|
break;
|
|
223
264
|
}
|
|
224
265
|
|
|
225
266
|
options.type = _constants._CONVERSATION_URL_;
|
|
226
|
-
_context.prev =
|
|
227
|
-
_context.next =
|
|
267
|
+
_context.prev = 47;
|
|
268
|
+
_context.next = 50;
|
|
228
269
|
return webex.internal.services.waitForCatalog('postauth');
|
|
229
270
|
|
|
230
|
-
case
|
|
271
|
+
case 50:
|
|
231
272
|
conversationUrl = webex.internal.conversation.getUrlFromClusterId({
|
|
232
273
|
cluster: hydraId.cluster,
|
|
233
274
|
id: hydraId.destination
|
|
234
275
|
});
|
|
235
276
|
options.destination = conversationUrl;
|
|
236
|
-
_context.next =
|
|
277
|
+
_context.next = 58;
|
|
237
278
|
break;
|
|
238
279
|
|
|
239
|
-
case
|
|
240
|
-
_context.prev =
|
|
241
|
-
_context.t0 = _context["catch"](
|
|
280
|
+
case 54:
|
|
281
|
+
_context.prev = 54;
|
|
282
|
+
_context.t0 = _context["catch"](47);
|
|
242
283
|
|
|
243
284
|
_loggerProxy.default.logger.error("Meeting-info:util#getDestinationType --> ".concat(_context.t0));
|
|
244
285
|
|
|
245
286
|
throw _context.t0;
|
|
246
287
|
|
|
247
|
-
case
|
|
248
|
-
_context.next =
|
|
288
|
+
case 58:
|
|
289
|
+
_context.next = 62;
|
|
249
290
|
break;
|
|
250
291
|
|
|
251
|
-
case
|
|
292
|
+
case 60:
|
|
252
293
|
_loggerProxy.default.logger.warn('Meeting-info:util#getDestinationType --> (\'MeetingInfo is fetched with meeting link, sip uri, phone number, hydra room id, hydra people id, or a conversation url.');
|
|
253
294
|
|
|
254
295
|
throw new _parameter.default('MeetingInfo is fetched with meeting link, sip uri, phone number, hydra room id, hydra people id, or a conversation url.');
|
|
255
296
|
|
|
256
|
-
case
|
|
297
|
+
case 62:
|
|
257
298
|
return _context.abrupt("return", _promise.default.resolve(options));
|
|
258
299
|
|
|
259
|
-
case
|
|
300
|
+
case 63:
|
|
260
301
|
case "end":
|
|
261
302
|
return _context.stop();
|
|
262
303
|
}
|
|
263
304
|
}
|
|
264
|
-
}, _callee, null, [[
|
|
305
|
+
}, _callee, null, [[47, 54]]);
|
|
265
306
|
}));
|
|
266
307
|
|
|
267
308
|
return function (_x) {
|
|
@@ -278,11 +319,13 @@ MeetingInfoUtil.getDestinationType = /*#__PURE__*/function () {
|
|
|
278
319
|
|
|
279
320
|
|
|
280
321
|
MeetingInfoUtil.getRequestBody = function (options) {
|
|
281
|
-
var _destination$info;
|
|
322
|
+
var _destination$info, _destination$info2;
|
|
282
323
|
|
|
283
324
|
var type = options.type,
|
|
284
325
|
destination = options.destination;
|
|
285
|
-
var body = {
|
|
326
|
+
var body = {
|
|
327
|
+
supportHostKey: true
|
|
328
|
+
};
|
|
286
329
|
|
|
287
330
|
switch (type) {
|
|
288
331
|
case _constants._SIP_URI_:
|
|
@@ -290,9 +333,8 @@ MeetingInfoUtil.getRequestBody = function (options) {
|
|
|
290
333
|
break;
|
|
291
334
|
|
|
292
335
|
case _constants._PERSONAL_ROOM_:
|
|
293
|
-
body.userId = destination;
|
|
294
|
-
body.orgId =
|
|
295
|
-
|
|
336
|
+
body.userId = destination.userId;
|
|
337
|
+
body.orgId = destination.orgId;
|
|
296
338
|
break;
|
|
297
339
|
|
|
298
340
|
case _constants._MEETING_ID_:
|
|
@@ -307,6 +349,8 @@ MeetingInfoUtil.getRequestBody = function (options) {
|
|
|
307
349
|
// use meetingID for the completer meeting info for the already started meeting
|
|
308
350
|
if ((_destination$info = destination.info) !== null && _destination$info !== void 0 && _destination$info.webExMeetingId) {
|
|
309
351
|
body.meetingKey = destination.info.webExMeetingId;
|
|
352
|
+
} else if ((_destination$info2 = destination.info) !== null && _destination$info2 !== void 0 && _destination$info2.sipUri) {
|
|
353
|
+
body.sipUrl = destination.info.sipUri;
|
|
310
354
|
}
|
|
311
355
|
|
|
312
356
|
break;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["utilv2.js"],"names":["MeetingInfoUtil","getParsedUrl","link","parsedUrl","url","parse","protocol","HTTPS_PROTOCOL","error","LoggerProxy","logger","warn","isMeetingLink","value","hostNameBool","hostname","includes","WEBEX_DOT_COM","pathNameBool","pathname","MEET","MEET_M","JOIN","isConversationUrl","webex","clusterId","internal","services","getClusterId","endsWith","CONVERSATION_SERVICE","isSipUri","sipString","sipUri","DIALER_REGEX","SIP_ADDRESS","exec","isPhoneNumber","phoneNumber","isValidNumber","PHONE_NUMBER","test","getHydraId","destination","type","id","cluster","UUID_REG","_ROOM_","room","_PEOPLE_","people","getSipUriFromHydraPersonId","get","then","res","emails","length","ParameterError","catch","err","getDestinationType","from","options","hydraId","_MEETING_LINK_","_SIP_URI_","_CONVERSATION_URL_","wasHydraPerson","resolve","waitForCatalog","conversationUrl","conversation","getUrlFromClusterId","getRequestBody","body","sipUrl","_PERSONAL_ROOM_","userId","orgId","_MEETING_ID_","meetingKey","_LOCUS_ID_","info","webExMeetingId","meetingUrl","_MEETING_UUID_","meetingUUID"],"mappings":"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","sourcesContent":["import url from 'url';\n\nimport {\n deconstructHydraId\n} from '@webex/common';\n\nimport {\n _SIP_URI_,\n _PERSONAL_ROOM_,\n _MEETING_ID_,\n _CONVERSATION_URL_,\n _LOCUS_ID_,\n _MEETING_LINK_,\n _PEOPLE_,\n _ROOM_,\n _MEETING_UUID_,\n DIALER_REGEX,\n WEBEX_DOT_COM,\n CONVERSATION_SERVICE,\n JOIN,\n MEET,\n MEET_M,\n HTTPS_PROTOCOL,\n UUID_REG\n} from '../constants';\nimport ParameterError from '../common/errors/parameter';\nimport LoggerProxy from '../common/logs/logger-proxy';\n\nconst MeetingInfoUtil = {};\n\nMeetingInfoUtil.getParsedUrl = (link) => {\n try {\n let parsedUrl = url.parse(link);\n\n if (!parsedUrl) {\n return false;\n }\n // hack for links such as <company>.webex.com/meet/<user> without a protocol\n if (!parsedUrl.protocol) {\n parsedUrl = url.parse(`${HTTPS_PROTOCOL}${link}`);\n }\n\n return parsedUrl;\n }\n catch (error) {\n LoggerProxy.logger.warn(`Meeting-info:util#getParsedUrl --> unable to parse the URL, error: ${error}`);\n\n return null;\n }\n};\n\n/**\n * Helper function to check if a string matches a known meeting link pattern\n * @param {String} value string to parse and see if it matches a meeting link\n * @returns {Boolean}\n */\nMeetingInfoUtil.isMeetingLink = (value) => {\n const parsedUrl = MeetingInfoUtil.getParsedUrl(value);\n const hostNameBool = parsedUrl.hostname && parsedUrl.hostname.includes(WEBEX_DOT_COM);\n const pathNameBool = parsedUrl.pathname && (parsedUrl.pathname.includes(`/${MEET}`) || parsedUrl.pathname.includes(`/${MEET_M}`) || parsedUrl.pathname.includes(`/${JOIN}`));\n\n return hostNameBool && pathNameBool;\n};\n\nMeetingInfoUtil.isConversationUrl = (value, webex) => {\n const clusterId = webex.internal.services.getClusterId(value);\n\n if (clusterId) {\n return clusterId.endsWith(CONVERSATION_SERVICE);\n }\n\n return false;\n};\n\n\nMeetingInfoUtil.isSipUri = (sipString) => {\n // TODO: lets remove regex from this equation and user URI matchers and such\n // have not found a great sip uri parser library as of now\n const sipUri = DIALER_REGEX.SIP_ADDRESS.exec(sipString);\n\n return sipUri;\n};\n\nMeetingInfoUtil.isPhoneNumber = (phoneNumber) => {\n const isValidNumber = DIALER_REGEX.PHONE_NUMBER.test(phoneNumber);\n\n return isValidNumber;\n};\n\nMeetingInfoUtil.getHydraId = (destination) => {\n const {type, id, cluster} = deconstructHydraId(destination);\n\n if (id && UUID_REG.test(id)) {\n if (type === _ROOM_) {\n return {room: true, destination: id, cluster};\n }\n if (type === _PEOPLE_) {\n return {people: true, destination: id, cluster};\n }\n\n return {};\n }\n\n return {};\n};\n\nMeetingInfoUtil.getSipUriFromHydraPersonId = (destination, webex) => webex.people.get(destination).then((res) => {\n if (res.emails && res.emails.length) {\n return res.emails[0];\n }\n throw new ParameterError('Hydra Id Lookup was an invalid hydra person id.');\n}).catch((err) => {\n LoggerProxy.logger.error(`Meeting-info:util#MeetingInfoUtil.getSipUriFromHydraPersonId --> getSipUriFromHydraPersonId ${err} `);\n throw err;\n});\n\n\nMeetingInfoUtil.getDestinationType = async (from) => {\n const {destination, type, webex} = from;\n\n if (type) {\n return {\n destination,\n type\n };\n }\n const options = {};\n const hydraId = MeetingInfoUtil.getHydraId(destination);\n\n if (MeetingInfoUtil.isMeetingLink(destination)) {\n LoggerProxy.logger.warn('Meeting-info:util#generateOptions --> WARN, use of Meeting Link is deprecated, please use a SIP URI instead');\n\n options.type = _MEETING_LINK_;\n options.destination = destination;\n }\n else if (MeetingInfoUtil.isSipUri(destination)) {\n options.type = _SIP_URI_;\n options.destination = destination;\n }\n else if (MeetingInfoUtil.isPhoneNumber(destination)) {\n options.type = _SIP_URI_;\n options.destination = destination;\n }\n else if (MeetingInfoUtil.isConversationUrl(destination, webex)) {\n options.type = _CONVERSATION_URL_;\n options.destination = destination;\n }\n else if (hydraId.people) {\n options.type = _SIP_URI_;\n\n return MeetingInfoUtil.getSipUriFromHydraPersonId(hydraId.destination, webex).then((res) => {\n options.destination = res;\n\n // Since hydra person ids require a unique case in which they are\n // entirely converted to a SIP URI, we need to set a flag for detecting\n // this type of destination.\n options.wasHydraPerson = true;\n\n return Promise.resolve(options);\n });\n }\n else if (hydraId.room) {\n options.type = _CONVERSATION_URL_;\n try {\n await webex.internal.services.waitForCatalog('postauth');\n\n const conversationUrl = webex.internal.conversation.getUrlFromClusterId({\n cluster: hydraId.cluster,\n id: hydraId.destination\n });\n\n options.destination = conversationUrl;\n }\n catch (e) {\n LoggerProxy.logger.error(`Meeting-info:util#getDestinationType --> ${e}`);\n throw (e);\n }\n }\n else {\n LoggerProxy.logger.warn('Meeting-info:util#getDestinationType --> (\\'MeetingInfo is fetched with meeting link, sip uri, phone number, hydra room id, hydra people id, or a conversation url.');\n throw new ParameterError('MeetingInfo is fetched with meeting link, sip uri, phone number, hydra room id, hydra people id, or a conversation url.');\n }\n\n return Promise.resolve(options);\n};\n\n/**\n * Helper function to build up a correct locus url depending on the value passed\n * @param {Object} options type and value to fetch meeting info\n * @param {String} options.type One of [SIP_URI, PERSONAL_ROOM, MEETING_ID, CONVERSATION_URL, LOCUS_ID, MEETING_LINK]\n * @param {Object} options.destination ?? value.value\n * @returns {Object} returns an object with {resource, method}\n */\nMeetingInfoUtil.getRequestBody = (options) => {\n const {type, destination} = options;\n const body = {};\n\n switch (type) {\n case _SIP_URI_:\n body.sipUrl = destination;\n break;\n case _PERSONAL_ROOM_:\n body.userId = destination;\n body.orgId = ''; // TODO: when to use the org iD (fetch others PMR)\n break;\n case _MEETING_ID_:\n body.meetingKey = destination;\n break;\n case _CONVERSATION_URL_:\n body.conversationUrl = destination;\n break;\n case _LOCUS_ID_:\n // use meetingID for the completer meeting info for the already started meeting\n if (destination.info?.webExMeetingId) {\n body.meetingKey = destination.info.webExMeetingId;\n }\n break;\n case _MEETING_LINK_:\n body.meetingUrl = destination;\n break;\n case _MEETING_UUID_: {\n body.meetingUUID = destination;\n break;\n }\n default:\n }\n\n return body;\n};\n\nexport default MeetingInfoUtil;\n"]}
|
|
1
|
+
{"version":3,"sources":["utilv2.js"],"names":["MeetingInfoUtil","getParsedUrl","link","parsedUrl","url","parse","protocol","HTTPS_PROTOCOL","error","LoggerProxy","logger","warn","isMeetingLink","value","hostNameBool","hostname","includes","WEBEX_DOT_COM","pathNameBool","pathname","MEET","MEET_M","JOIN","isConversationUrl","webex","clusterId","internal","services","getClusterId","endsWith","CONVERSATION_SERVICE","isSipUri","sipString","sipUri","DIALER_REGEX","SIP_ADDRESS","exec","isPhoneNumber","phoneNumber","isValidNumber","PHONE_NUMBER","test","getHydraId","destination","type","id","cluster","UUID_REG","_ROOM_","room","_PEOPLE_","people","getSipUriFromHydraPersonId","get","then","res","emails","length","ParameterError","catch","err","getDestinationType","from","_PERSONAL_ROOM_","userId","device","orgId","options","VALID_EMAIL_ADDRESS","email","list","items","hydraId","_MEETING_LINK_","_SIP_URI_","_CONVERSATION_URL_","wasHydraPerson","resolve","waitForCatalog","conversationUrl","conversation","getUrlFromClusterId","getRequestBody","body","supportHostKey","sipUrl","_MEETING_ID_","meetingKey","_LOCUS_ID_","info","webExMeetingId","meetingUrl","_MEETING_UUID_","meetingUUID"],"mappings":"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","sourcesContent":["import url from 'url';\n\nimport {\n deconstructHydraId\n} from '@webex/common';\n\nimport {\n _SIP_URI_,\n _PERSONAL_ROOM_,\n _MEETING_ID_,\n _CONVERSATION_URL_,\n _LOCUS_ID_,\n _MEETING_LINK_,\n _PEOPLE_,\n _ROOM_,\n _MEETING_UUID_,\n DIALER_REGEX,\n WEBEX_DOT_COM,\n CONVERSATION_SERVICE,\n JOIN,\n MEET,\n MEET_M,\n HTTPS_PROTOCOL,\n UUID_REG,\n VALID_EMAIL_ADDRESS\n} from '../constants';\nimport ParameterError from '../common/errors/parameter';\nimport LoggerProxy from '../common/logs/logger-proxy';\n\nconst MeetingInfoUtil = {};\n\nMeetingInfoUtil.getParsedUrl = (link) => {\n try {\n let parsedUrl = url.parse(link);\n\n if (!parsedUrl) {\n return false;\n }\n // hack for links such as <company>.webex.com/meet/<user> without a protocol\n if (!parsedUrl.protocol) {\n parsedUrl = url.parse(`${HTTPS_PROTOCOL}${link}`);\n }\n\n return parsedUrl;\n }\n catch (error) {\n LoggerProxy.logger.warn(`Meeting-info:util#getParsedUrl --> unable to parse the URL, error: ${error}`);\n\n return null;\n }\n};\n\n/**\n * Helper function to check if a string matches a known meeting link pattern\n * @param {String} value string to parse and see if it matches a meeting link\n * @returns {Boolean}\n */\nMeetingInfoUtil.isMeetingLink = (value) => {\n const parsedUrl = MeetingInfoUtil.getParsedUrl(value);\n const hostNameBool = parsedUrl.hostname && parsedUrl.hostname.includes(WEBEX_DOT_COM);\n const pathNameBool = parsedUrl.pathname && (parsedUrl.pathname.includes(`/${MEET}`) || parsedUrl.pathname.includes(`/${MEET_M}`) || parsedUrl.pathname.includes(`/${JOIN}`));\n\n return hostNameBool && pathNameBool;\n};\n\nMeetingInfoUtil.isConversationUrl = (value, webex) => {\n const clusterId = webex.internal.services.getClusterId(value);\n\n if (clusterId) {\n return clusterId.endsWith(CONVERSATION_SERVICE);\n }\n\n return false;\n};\n\n\nMeetingInfoUtil.isSipUri = (sipString) => {\n // TODO: lets remove regex from this equation and user URI matchers and such\n // have not found a great sip uri parser library as of now\n const sipUri = DIALER_REGEX.SIP_ADDRESS.exec(sipString);\n\n return sipUri;\n};\n\nMeetingInfoUtil.isPhoneNumber = (phoneNumber) => {\n const isValidNumber = DIALER_REGEX.PHONE_NUMBER.test(phoneNumber);\n\n return isValidNumber;\n};\n\nMeetingInfoUtil.getHydraId = (destination) => {\n const {type, id, cluster} = deconstructHydraId(destination);\n\n if (id && UUID_REG.test(id)) {\n if (type === _ROOM_) {\n return {room: true, destination: id, cluster};\n }\n if (type === _PEOPLE_) {\n return {people: true, destination: id, cluster};\n }\n\n return {};\n }\n\n return {};\n};\n\nMeetingInfoUtil.getSipUriFromHydraPersonId = (destination, webex) => webex.people.get(destination).then((res) => {\n if (res.emails && res.emails.length) {\n return res.emails[0];\n }\n throw new ParameterError('Hydra Id Lookup was an invalid hydra person id.');\n}).catch((err) => {\n LoggerProxy.logger.error(`Meeting-info:util#MeetingInfoUtil.getSipUriFromHydraPersonId --> getSipUriFromHydraPersonId ${err} `);\n throw err;\n});\n\n\nMeetingInfoUtil.getDestinationType = async (from) => {\n const {type, webex} = from;\n let {destination} = from;\n\n if (type === _PERSONAL_ROOM_) { // this case checks if your type is personal room\n if (!destination) { // if we are not getting anything in desination we fetch org and user ids from webex instance\n destination = {\n userId: webex.internal.device.userId,\n orgId: webex.internal.device.orgId\n };\n }\n else {\n const options = VALID_EMAIL_ADDRESS.test(destination) ? {email: destination} : {id: destination};// we are assuming userId as default\n const res = await webex.people.list(options);\n\n let {orgId, id: userId} = res.items[0];\n\n userId = deconstructHydraId(userId).id;\n orgId = deconstructHydraId(orgId).id;\n destination = {userId, orgId};\n }\n }\n if (type) {\n return {\n destination,\n type\n };\n }\n const options = {};\n const hydraId = MeetingInfoUtil.getHydraId(destination);\n\n if (MeetingInfoUtil.isMeetingLink(destination)) {\n LoggerProxy.logger.warn('Meeting-info:util#generateOptions --> WARN, use of Meeting Link is deprecated, please use a SIP URI instead');\n\n options.type = _MEETING_LINK_;\n options.destination = destination;\n }\n else if (MeetingInfoUtil.isSipUri(destination)) {\n options.type = _SIP_URI_;\n options.destination = destination;\n }\n else if (MeetingInfoUtil.isPhoneNumber(destination)) {\n options.type = _SIP_URI_;\n options.destination = destination;\n }\n else if (MeetingInfoUtil.isConversationUrl(destination, webex)) {\n options.type = _CONVERSATION_URL_;\n options.destination = destination;\n }\n else if (hydraId.people) {\n options.type = _SIP_URI_;\n\n return MeetingInfoUtil.getSipUriFromHydraPersonId(hydraId.destination, webex).then((res) => {\n options.destination = res;\n\n // Since hydra person ids require a unique case in which they are\n // entirely converted to a SIP URI, we need to set a flag for detecting\n // this type of destination.\n options.wasHydraPerson = true;\n\n return Promise.resolve(options);\n });\n }\n else if (hydraId.room) {\n options.type = _CONVERSATION_URL_;\n try {\n await webex.internal.services.waitForCatalog('postauth');\n\n const conversationUrl = webex.internal.conversation.getUrlFromClusterId({\n cluster: hydraId.cluster,\n id: hydraId.destination\n });\n\n options.destination = conversationUrl;\n }\n catch (e) {\n LoggerProxy.logger.error(`Meeting-info:util#getDestinationType --> ${e}`);\n throw (e);\n }\n }\n else {\n LoggerProxy.logger.warn('Meeting-info:util#getDestinationType --> (\\'MeetingInfo is fetched with meeting link, sip uri, phone number, hydra room id, hydra people id, or a conversation url.');\n throw new ParameterError('MeetingInfo is fetched with meeting link, sip uri, phone number, hydra room id, hydra people id, or a conversation url.');\n }\n\n return Promise.resolve(options);\n};\n\n/**\n * Helper function to build up a correct locus url depending on the value passed\n * @param {Object} options type and value to fetch meeting info\n * @param {String} options.type One of [SIP_URI, PERSONAL_ROOM, MEETING_ID, CONVERSATION_URL, LOCUS_ID, MEETING_LINK]\n * @param {Object} options.destination ?? value.value\n * @returns {Object} returns an object with {resource, method}\n */\nMeetingInfoUtil.getRequestBody = (options) => {\n const {type, destination} = options;\n const body = {\n supportHostKey: true\n };\n\n switch (type) {\n case _SIP_URI_:\n body.sipUrl = destination;\n break;\n case _PERSONAL_ROOM_:\n body.userId = destination.userId;\n body.orgId = destination.orgId;\n break;\n case _MEETING_ID_:\n body.meetingKey = destination;\n break;\n case _CONVERSATION_URL_:\n body.conversationUrl = destination;\n break;\n case _LOCUS_ID_:\n // use meetingID for the completer meeting info for the already started meeting\n if (destination.info?.webExMeetingId) {\n body.meetingKey = destination.info.webExMeetingId;\n }\n else if (destination.info?.sipUri) {\n body.sipUrl = destination.info.sipUri;\n }\n break;\n case _MEETING_LINK_:\n body.meetingUrl = destination;\n break;\n case _MEETING_UUID_: {\n body.meetingUUID = destination;\n break;\n }\n default:\n }\n\n return body;\n};\n\nexport default MeetingInfoUtil;\n"]}
|
package/dist/metrics/index.js
CHANGED
|
@@ -36,27 +36,27 @@ var _uuid = _interopRequireDefault(require("uuid"));
|
|
|
36
36
|
|
|
37
37
|
var _window = _interopRequireDefault(require("global/window"));
|
|
38
38
|
|
|
39
|
+
var _ipAnonymize = _interopRequireDefault(require("ip-anonymize"));
|
|
40
|
+
|
|
39
41
|
var _loggerProxy = _interopRequireDefault(require("../common/logs/logger-proxy"));
|
|
40
42
|
|
|
41
43
|
var _constants = require("../constants");
|
|
42
44
|
|
|
43
|
-
var _config = _interopRequireDefault(require("../common/config"));
|
|
44
|
-
|
|
45
45
|
var _browserDetection = _interopRequireDefault(require("../common/browser-detection"));
|
|
46
46
|
|
|
47
|
-
var
|
|
47
|
+
var _config = require("./config");
|
|
48
48
|
|
|
49
49
|
function ownKeys(object, enumerableOnly) { var keys = _Object$keys(object); if (_Object$getOwnPropertySymbols) { var symbols = _Object$getOwnPropertySymbols(object); if (enumerableOnly) { symbols = symbols.filter(function (sym) { return _Object$getOwnPropertyDescriptor(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; }
|
|
50
50
|
|
|
51
51
|
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { (0, _defineProperty2.default)(target, key, source[key]); }); } else if (_Object$getOwnPropertyDescriptors) { _Object$defineProperties(target, _Object$getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { _Object$defineProperty(target, key, _Object$getOwnPropertyDescriptor(source, key)); }); } } return target; }
|
|
52
52
|
|
|
53
53
|
var OSMap = {
|
|
54
|
-
'Chrome OS':
|
|
55
|
-
macOS:
|
|
56
|
-
Windows:
|
|
57
|
-
iOS:
|
|
58
|
-
Android:
|
|
59
|
-
Linux:
|
|
54
|
+
'Chrome OS': _config.OS_NAME.chrome,
|
|
55
|
+
macOS: _config.OS_NAME.MAC,
|
|
56
|
+
Windows: _config.OS_NAME.WINDOWS,
|
|
57
|
+
iOS: _config.OS_NAME.IOS,
|
|
58
|
+
Android: _config.OS_NAME.ANDROID,
|
|
59
|
+
Linux: _config.OS_NAME.LINUX
|
|
60
60
|
};
|
|
61
61
|
|
|
62
62
|
var _BrowserDetection = (0, _browserDetection.default)(),
|
|
@@ -66,15 +66,8 @@ var _BrowserDetection = (0, _browserDetection.default)(),
|
|
|
66
66
|
getBrowserVersion = _BrowserDetection.getBrowserVersion; // Apply a CIDR /28 format to the IP address
|
|
67
67
|
|
|
68
68
|
|
|
69
|
-
var
|
|
70
|
-
|
|
71
|
-
return undefined;
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
var parts = localIp.split('.'); // eslint-disable-next-line no-bitwise
|
|
75
|
-
|
|
76
|
-
parts[3] &= 240;
|
|
77
|
-
return parts.join('.');
|
|
69
|
+
var anonymizeIPAddress = function anonymizeIPAddress(localIp) {
|
|
70
|
+
return (0, _ipAnonymize.default)(localIp);
|
|
78
71
|
};
|
|
79
72
|
|
|
80
73
|
var triggerTimers = function triggerTimers(_ref) {
|
|
@@ -83,36 +76,36 @@ var triggerTimers = function triggerTimers(_ref) {
|
|
|
83
76
|
data = _ref.data;
|
|
84
77
|
|
|
85
78
|
switch (event) {
|
|
86
|
-
case
|
|
79
|
+
case _config.eventType.CALL_INITIATED:
|
|
87
80
|
meeting.setStartCallInitiateJoinReq();
|
|
88
81
|
break;
|
|
89
82
|
|
|
90
|
-
case
|
|
83
|
+
case _config.eventType.LOCUS_JOIN_REQUEST:
|
|
91
84
|
meeting.setEndCallInitiateJoinReq();
|
|
92
85
|
meeting.setStartJoinReqResp();
|
|
93
86
|
break;
|
|
94
87
|
|
|
95
|
-
case
|
|
88
|
+
case _config.eventType.LOCUS_JOIN_RESPONSE:
|
|
96
89
|
meeting.setEndJoinReqResp();
|
|
97
|
-
meeting.setStartSetupDelay(
|
|
98
|
-
meeting.setStartSetupDelay(
|
|
99
|
-
meeting.setStartSendingMediaDelay(
|
|
100
|
-
meeting.setStartSendingMediaDelay(
|
|
90
|
+
meeting.setStartSetupDelay(_config.mediaType.AUDIO);
|
|
91
|
+
meeting.setStartSetupDelay(_config.mediaType.VIDEO);
|
|
92
|
+
meeting.setStartSendingMediaDelay(_config.mediaType.AUDIO);
|
|
93
|
+
meeting.setStartSendingMediaDelay(_config.mediaType.VIDEO);
|
|
101
94
|
break;
|
|
102
95
|
|
|
103
|
-
case
|
|
96
|
+
case _config.eventType.RECEIVING_MEDIA_START:
|
|
104
97
|
meeting.setEndSetupDelay(data.mediaType);
|
|
105
98
|
break;
|
|
106
99
|
|
|
107
|
-
case
|
|
100
|
+
case _config.eventType.SENDING_MEDIA_START:
|
|
108
101
|
meeting.setEndSendingMediaDelay(data.mediaType);
|
|
109
102
|
break;
|
|
110
103
|
|
|
111
|
-
case
|
|
104
|
+
case _config.eventType.LOCAL_SDP_GENERATED:
|
|
112
105
|
meeting.setStartLocalSDPGenRemoteSDPRecvDelay();
|
|
113
106
|
break;
|
|
114
107
|
|
|
115
|
-
case
|
|
108
|
+
case _config.eventType.REMOTE_SDP_RECEIVED:
|
|
116
109
|
meeting.setEndLocalSDPGenRemoteSDPRecvDelay();
|
|
117
110
|
break;
|
|
118
111
|
|
|
@@ -160,7 +153,7 @@ var Metrics = /*#__PURE__*/function () {
|
|
|
160
153
|
* @memberof Metrics
|
|
161
154
|
*/
|
|
162
155
|
|
|
163
|
-
this.keys = (0, _values.default)(
|
|
156
|
+
this.keys = (0, _values.default)(_config.eventType);
|
|
164
157
|
/**
|
|
165
158
|
* @instance
|
|
166
159
|
* @type {Metrics}
|
|
@@ -224,7 +217,7 @@ var Metrics = /*#__PURE__*/function () {
|
|
|
224
217
|
meeting.callEvents = [];
|
|
225
218
|
}
|
|
226
219
|
|
|
227
|
-
if (event ===
|
|
220
|
+
if (event === _config.eventType.MEDIA_QUALITY) {
|
|
228
221
|
data.event = event;
|
|
229
222
|
meeting.sendMediaQualityAnalyzerMetrics(data);
|
|
230
223
|
} else {
|
|
@@ -256,8 +249,8 @@ var Metrics = /*#__PURE__*/function () {
|
|
|
256
249
|
userAgent: this.userAgentToString(),
|
|
257
250
|
clientInfo: {
|
|
258
251
|
clientType: options.clientType,
|
|
259
|
-
clientVersion: "".concat(
|
|
260
|
-
localNetworkPrefix:
|
|
252
|
+
clientVersion: "".concat(_config.CLIENT_NAME, "/").concat(this.webex.version),
|
|
253
|
+
localNetworkPrefix: anonymizeIPAddress((_this$webex$meetings$ = this.webex.meetings.geoHintInfo) === null || _this$webex$meetings$ === void 0 ? void 0 : _this$webex$meetings$.clientAddress),
|
|
261
254
|
osVersion: getOSVersion() || 'unknown',
|
|
262
255
|
subClientType: options.subClientType,
|
|
263
256
|
os: this.getOsName(),
|
|
@@ -328,7 +321,7 @@ var Metrics = /*#__PURE__*/function () {
|
|
|
328
321
|
value: function getOsName() {
|
|
329
322
|
var _OSMap$getOSName;
|
|
330
323
|
|
|
331
|
-
return (_OSMap$getOSName = OSMap[getOSName()]) !== null && _OSMap$getOSName !== void 0 ? _OSMap$getOSName :
|
|
324
|
+
return (_OSMap$getOSName = OSMap[getOSName()]) !== null && _OSMap$getOSName !== void 0 ? _OSMap$getOSName : _config.OS_NAME.OTHERS;
|
|
332
325
|
}
|
|
333
326
|
/**
|
|
334
327
|
* get the payload specific for a media quality event through call analyzer
|
|
@@ -361,15 +354,15 @@ var Metrics = /*#__PURE__*/function () {
|
|
|
361
354
|
audioSetupDelay: audioSetupDelay,
|
|
362
355
|
videoSetupDelay: videoSetupDelay,
|
|
363
356
|
name: 'endpoint',
|
|
364
|
-
networkType: options.networkType ||
|
|
357
|
+
networkType: options.networkType || _config.UNKNOWN,
|
|
365
358
|
userAgent: this.userAgentToString(),
|
|
366
359
|
clientInfo: {
|
|
367
360
|
clientType: options.clientType,
|
|
368
361
|
// TODO: Only clientType: 'TEAMS_CLIENT' is whitelisted
|
|
369
|
-
clientVersion: "".concat(
|
|
370
|
-
localNetworkPrefix:
|
|
362
|
+
clientVersion: "".concat(_config.CLIENT_NAME, "/").concat(this.webex.version),
|
|
363
|
+
localNetworkPrefix: anonymizeIPAddress((_this$webex$meetings$3 = this.webex.meetings.geoHintInfo) === null || _this$webex$meetings$3 === void 0 ? void 0 : _this$webex$meetings$3.clientAddress),
|
|
371
364
|
os: this.getOsName(),
|
|
372
|
-
osVersion: getOSVersion() ||
|
|
365
|
+
osVersion: getOSVersion() || _config.UNKNOWN,
|
|
373
366
|
subClientType: options.subClientType,
|
|
374
367
|
browser: getBrowserName(),
|
|
375
368
|
browserVersion: getBrowserVersion()
|
|
@@ -389,10 +382,10 @@ var Metrics = /*#__PURE__*/function () {
|
|
|
389
382
|
webClientDomain: _window.default.location.hostname
|
|
390
383
|
},
|
|
391
384
|
sourceMetadata: {
|
|
392
|
-
applicationSoftwareType:
|
|
385
|
+
applicationSoftwareType: _config.CLIENT_NAME,
|
|
393
386
|
applicationSoftwareVersion: this.webex.version,
|
|
394
387
|
mediaEngineSoftwareType: getBrowserName() || 'browser',
|
|
395
|
-
mediaEngineSoftwareVersion: getOSVersion() ||
|
|
388
|
+
mediaEngineSoftwareVersion: getOSVersion() || _config.UNKNOWN,
|
|
396
389
|
startTime: new Date().toISOString()
|
|
397
390
|
}
|
|
398
391
|
}
|
|
@@ -416,7 +409,7 @@ var Metrics = /*#__PURE__*/function () {
|
|
|
416
409
|
var errorCode;
|
|
417
410
|
|
|
418
411
|
if (err && err.body && err.body.errorCode) {
|
|
419
|
-
switch (
|
|
412
|
+
switch (_config.errorCodes[err.body.errorCode]) {
|
|
420
413
|
case _constants.MEETING_ERRORS.FREE_USER_MAX_PARTICIPANTS_EXCEEDED:
|
|
421
414
|
errorCode = 3007;
|
|
422
415
|
break;
|
|
@@ -546,19 +539,19 @@ var Metrics = /*#__PURE__*/function () {
|
|
|
546
539
|
errorCode = 4008;
|
|
547
540
|
}
|
|
548
541
|
|
|
549
|
-
return this.generateErrorPayload(errorCode, showToUser,
|
|
542
|
+
return this.generateErrorPayload(errorCode, showToUser, _config.error.name.LOCUS_RESPONSE, err);
|
|
550
543
|
}
|
|
551
544
|
}, {
|
|
552
545
|
key: "generateErrorPayload",
|
|
553
546
|
value: function generateErrorPayload(errorCode, shownToUser, name, err) {
|
|
554
|
-
if (
|
|
547
|
+
if (_config.error.errors[errorCode]) {
|
|
555
548
|
var errorPayload = {
|
|
556
549
|
shownToUser: shownToUser || false,
|
|
557
|
-
category:
|
|
558
|
-
errorDescription:
|
|
550
|
+
category: _config.error.errors[errorCode][2],
|
|
551
|
+
errorDescription: _config.error.errors[errorCode][0],
|
|
559
552
|
errorCode: errorCode,
|
|
560
|
-
fatal: !(0, _includes2.default)(
|
|
561
|
-
name: name ||
|
|
553
|
+
fatal: !(0, _includes2.default)(_config.error.notFatalErrorList, errorCode),
|
|
554
|
+
name: name || _config.error.name.OTHER
|
|
562
555
|
};
|
|
563
556
|
|
|
564
557
|
if (err && err.body) {
|
|
@@ -579,10 +572,12 @@ var Metrics = /*#__PURE__*/function () {
|
|
|
579
572
|
}, {
|
|
580
573
|
key: "userAgentToString",
|
|
581
574
|
value: function userAgentToString() {
|
|
575
|
+
var _this$webex$meetings, _this$webex$meetings$5;
|
|
576
|
+
|
|
582
577
|
var userAgentOption;
|
|
583
578
|
var browserInfo;
|
|
584
579
|
|
|
585
|
-
var clientInfo = _util.default.format('client=%s', "".concat(
|
|
580
|
+
var clientInfo = _util.default.format('client=%s', "".concat((_this$webex$meetings = this.webex.meetings) === null || _this$webex$meetings === void 0 ? void 0 : (_this$webex$meetings$5 = _this$webex$meetings.metrics) === null || _this$webex$meetings$5 === void 0 ? void 0 : _this$webex$meetings$5.clientName));
|
|
586
581
|
|
|
587
582
|
if (['chrome', 'firefox', 'msie', 'msedge', 'safari'].indexOf(getBrowserName().toLowerCase()) !== -1) {
|
|
588
583
|
browserInfo = _util.default.format('browser=%s', "".concat(getBrowserName().toLowerCase(), "/").concat(getBrowserVersion().split('.')[0]));
|