You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

functions.native.js 6.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240
  1. import { isRoomValid } from '../base/conference';
  2. import { RouteRegistry } from '../base/react';
  3. import { Conference } from '../conference';
  4. import { WelcomePage } from '../welcome';
  5. /**
  6. * The RegExp pattern of the authority of a URI.
  7. *
  8. * @private
  9. * @type {string}
  10. */
  11. const _URI_AUTHORITY_PATTERN = '(//[^/?#]+)';
  12. /**
  13. * The RegExp pattern of the path of a URI.
  14. *
  15. * @private
  16. * @type {string}
  17. */
  18. const _URI_PATH_PATTERN = '([^?#]*)';
  19. /**
  20. * The RegExp patther of the protocol of a URI.
  21. *
  22. * @private
  23. * @type {string}
  24. */
  25. const _URI_PROTOCOL_PATTERN = '([a-z][a-z0-9\\.\\+-]*:)';
  26. /**
  27. * Fixes the hier-part of a specific URI (string) so that the URI is well-known.
  28. * For example, certain Jitsi Meet deployments are not conventional but it is
  29. * possible to translate their URLs into conventional.
  30. *
  31. * @param {string} uri - The URI (string) to fix the hier-part of.
  32. * @private
  33. * @returns {string}
  34. */
  35. function _fixURIStringHierPart(uri) {
  36. // Rewrite the specified URL in order to handle special cases such as
  37. // hipchat.com and enso.me which do not follow the common pattern of most
  38. // Jitsi Meet deployments.
  39. // hipchat.com
  40. let regex
  41. = new RegExp(
  42. `^${_URI_PROTOCOL_PATTERN}//hipchat\\.com/video/call/`,
  43. 'gi');
  44. let match = regex.exec(uri);
  45. if (!match) {
  46. // enso.me
  47. regex
  48. = new RegExp(
  49. `^${_URI_PROTOCOL_PATTERN}//enso\\.me/(?:call|meeting)/`,
  50. 'gi');
  51. match = regex.exec(uri);
  52. }
  53. if (match) {
  54. /* eslint-disable no-param-reassign, prefer-template */
  55. uri
  56. = match[1] /* protocol */
  57. + '//enso.hipchat.me/'
  58. + uri.substring(regex.lastIndex); /* room (name) */
  59. /* eslint-enable no-param-reassign, prefer-template */
  60. }
  61. return uri;
  62. }
  63. /**
  64. * Fixes the scheme part of a specific URI (string) so that it contains a
  65. * well-known scheme such as HTTP(S). For example, the mobile app implements an
  66. * app-specific URI scheme in addition to Universal Links. The app-specific
  67. * scheme may precede or replace the well-known scheme. In such a case, dealing
  68. * with the app-specific scheme only complicates the logic and it is simpler to
  69. * get rid of it (by translating the app-specific scheme into a well-known
  70. * scheme).
  71. *
  72. * @param {string} uri - The URI (string) to fix the scheme of.
  73. * @private
  74. * @returns {string}
  75. */
  76. function _fixURIStringScheme(uri) {
  77. const regex = new RegExp(`^${_URI_PROTOCOL_PATTERN}+`, 'gi');
  78. const match = regex.exec(uri);
  79. if (match) {
  80. // As an implementation convenience, pick up the last scheme and make
  81. // sure that it is a well-known one.
  82. let protocol = match[match.length - 1].toLowerCase();
  83. if (protocol !== 'http:' && protocol !== 'https:') {
  84. protocol = 'https:';
  85. }
  86. /* eslint-disable no-param-reassign */
  87. uri = uri.substring(regex.lastIndex);
  88. if (uri.startsWith('//')) {
  89. // The specified URL was not a room name only, it contained an
  90. // authority.
  91. uri = protocol + uri;
  92. }
  93. /* eslint-enable no-param-reassign */
  94. }
  95. return uri;
  96. }
  97. /**
  98. * Gets room name and domain from URL object.
  99. *
  100. * @param {URL} url - URL object.
  101. * @private
  102. * @returns {{
  103. * domain: (string|undefined),
  104. * room: (string|undefined)
  105. * }}
  106. */
  107. function _getRoomAndDomainFromURLObject(url) {
  108. let domain;
  109. let room;
  110. if (url) {
  111. domain = url.host;
  112. // The room (name) is the last component of pathname.
  113. room = url.pathname;
  114. room = room.substring(room.lastIndexOf('/') + 1);
  115. // Convert empty string to undefined to simplify checks.
  116. if (room === '') {
  117. room = undefined;
  118. }
  119. if (domain === '') {
  120. domain = undefined;
  121. }
  122. }
  123. return {
  124. domain,
  125. room
  126. };
  127. }
  128. /**
  129. * Determines which route is to be rendered in order to depict a specific Redux
  130. * store.
  131. *
  132. * @param {(Object|Function)} stateOrGetState - Redux state or Regux getState()
  133. * method.
  134. * @returns {Route}
  135. */
  136. export function _getRouteToRender(stateOrGetState) {
  137. const state
  138. = typeof stateOrGetState === 'function'
  139. ? stateOrGetState()
  140. : stateOrGetState;
  141. const room = state['features/base/conference'].room;
  142. const component = isRoomValid(room) ? Conference : WelcomePage;
  143. return RouteRegistry.getRouteByComponent(component);
  144. }
  145. /**
  146. * Parses a specific URI which (supposedly) references a Jitsi Meet resource
  147. * (location).
  148. *
  149. * @param {(string|undefined)} uri - The URI to parse which (supposedly)
  150. * references a Jitsi Meet resource (location).
  151. * @returns {{
  152. * domain: (string|undefined),
  153. * room: (string|undefined)
  154. * }}
  155. */
  156. export function _parseURIString(uri) {
  157. let obj;
  158. if (typeof uri === 'string') {
  159. let str = uri;
  160. str = _fixURIStringScheme(str);
  161. str = _fixURIStringHierPart(str);
  162. obj = {};
  163. let regex;
  164. let match;
  165. // protocol
  166. regex = new RegExp(`^${_URI_PROTOCOL_PATTERN}`, 'gi');
  167. match = regex.exec(str);
  168. if (match) {
  169. obj.protocol = match[1].toLowerCase();
  170. str = str.substring(regex.lastIndex);
  171. }
  172. // authority
  173. regex = new RegExp(`^${_URI_AUTHORITY_PATTERN}`, 'gi');
  174. match = regex.exec(str);
  175. if (match) {
  176. let authority = match[1].substring(/* // */ 2);
  177. str = str.substring(regex.lastIndex);
  178. // userinfo
  179. const userinfoEndIndex = authority.indexOf('@');
  180. if (userinfoEndIndex !== -1) {
  181. authority = authority.substring(userinfoEndIndex + 1);
  182. }
  183. obj.host = authority;
  184. // port
  185. const portBeginIndex = authority.lastIndexOf(':');
  186. if (portBeginIndex !== -1) {
  187. obj.port = authority.substring(portBeginIndex + 1);
  188. authority = authority.substring(0, portBeginIndex);
  189. }
  190. obj.hostname = authority;
  191. }
  192. // pathname
  193. regex = new RegExp(`^${_URI_PATH_PATTERN}`, 'gi');
  194. match = regex.exec(str);
  195. if (match) {
  196. obj.pathname = match[1] || '/';
  197. str = str.substring(regex.lastIndex);
  198. }
  199. }
  200. return _getRoomAndDomainFromURLObject(obj);
  201. }