|
|
|
|
@ -3,23 +3,134 @@ import { RouteRegistry } from '../base/react'; |
|
|
|
|
import { Conference } from '../conference'; |
|
|
|
|
import { WelcomePage } from '../welcome'; |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* The RegExp pattern of the authority of a URI. |
|
|
|
|
* |
|
|
|
|
* @private |
|
|
|
|
* @type {string} |
|
|
|
|
*/ |
|
|
|
|
const _URI_AUTHORITY_PATTERN = '(//[^/?#]+)'; |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* The RegExp pattern of the path of a URI. |
|
|
|
|
* |
|
|
|
|
* @private |
|
|
|
|
* @type {string} |
|
|
|
|
*/ |
|
|
|
|
const _URI_PATH_PATTERN = '([^?#]*)'; |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* The RegExp patther of the protocol of a URI. |
|
|
|
|
* |
|
|
|
|
* @private |
|
|
|
|
* @type {string} |
|
|
|
|
*/ |
|
|
|
|
const _URI_PROTOCOL_PATTERN = '([a-z][a-z0-9\\.\\+-]*:)'; |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Fixes the hier-part of a specific URI (string) so that the URI is well-known. |
|
|
|
|
* For example, certain Jitsi Meet deployments are not conventional but it is |
|
|
|
|
* possible to translate their URLs into conventional. |
|
|
|
|
* |
|
|
|
|
* @param {string} uri - The URI (string) to fix the hier-part of. |
|
|
|
|
* @private |
|
|
|
|
* @returns {string} |
|
|
|
|
*/ |
|
|
|
|
function _fixURIStringHierPart(uri) { |
|
|
|
|
// Rewrite the specified URL in order to handle special cases such as
|
|
|
|
|
// hipchat.com and enso.me which do not follow the common pattern of most
|
|
|
|
|
// Jitsi Meet deployments.
|
|
|
|
|
|
|
|
|
|
// hipchat.com
|
|
|
|
|
let regex |
|
|
|
|
= new RegExp( |
|
|
|
|
`^${_URI_PROTOCOL_PATTERN}//hipchat\\.com/video/call/`, |
|
|
|
|
'gi'); |
|
|
|
|
let match = regex.exec(uri); |
|
|
|
|
|
|
|
|
|
if (!match) { |
|
|
|
|
// enso.me
|
|
|
|
|
regex |
|
|
|
|
= new RegExp( |
|
|
|
|
`^${_URI_PROTOCOL_PATTERN}//enso\\.me/(?:call|meeting)/`, |
|
|
|
|
'gi'); |
|
|
|
|
match = regex.exec(uri); |
|
|
|
|
} |
|
|
|
|
if (match) { |
|
|
|
|
/* eslint-disable no-param-reassign, prefer-template */ |
|
|
|
|
|
|
|
|
|
uri |
|
|
|
|
= match[1] /* protocol */ |
|
|
|
|
+ '//enso.hipchat.me/' |
|
|
|
|
+ uri.substring(regex.lastIndex); /* room (name) */ |
|
|
|
|
|
|
|
|
|
/* eslint-enable no-param-reassign, prefer-template */ |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return uri; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Fixes the scheme part of a specific URI (string) so that it contains a |
|
|
|
|
* well-known scheme such as HTTP(S). For example, the mobile app implements an |
|
|
|
|
* app-specific URI scheme in addition to Universal Links. The app-specific |
|
|
|
|
* scheme may precede or replace the well-known scheme. In such a case, dealing |
|
|
|
|
* with the app-specific scheme only complicates the logic and it is simpler to |
|
|
|
|
* get rid of it (by translating the app-specific scheme into a well-known |
|
|
|
|
* scheme). |
|
|
|
|
* |
|
|
|
|
* @param {string} uri - The URI (string) to fix the scheme of. |
|
|
|
|
* @private |
|
|
|
|
* @returns {string} |
|
|
|
|
*/ |
|
|
|
|
function _fixURIStringScheme(uri) { |
|
|
|
|
const regex = new RegExp(`^${_URI_PROTOCOL_PATTERN}+`, 'gi'); |
|
|
|
|
const match = regex.exec(uri); |
|
|
|
|
|
|
|
|
|
if (match) { |
|
|
|
|
// As an implementation convenience, pick up the last scheme and make
|
|
|
|
|
// sure that it is a well-known one.
|
|
|
|
|
let protocol = match[match.length - 1].toLowerCase(); |
|
|
|
|
|
|
|
|
|
if (protocol !== 'http:' && protocol !== 'https:') { |
|
|
|
|
protocol = 'https:'; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* eslint-disable no-param-reassign */ |
|
|
|
|
|
|
|
|
|
uri = uri.substring(regex.lastIndex); |
|
|
|
|
if (uri.startsWith('//')) { |
|
|
|
|
// The specified URL was not a room name only, it contained an
|
|
|
|
|
// authority.
|
|
|
|
|
uri = protocol + uri; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* eslint-enable no-param-reassign */ |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return uri; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Gets room name and domain from URL object. |
|
|
|
|
* |
|
|
|
|
* @param {URL} url - URL object. |
|
|
|
|
* @private |
|
|
|
|
* @returns {{ |
|
|
|
|
* domain: (string|undefined), |
|
|
|
|
* room: (string|undefined) |
|
|
|
|
* }} |
|
|
|
|
* domain: (string|undefined), |
|
|
|
|
* room: (string|undefined) |
|
|
|
|
* }} |
|
|
|
|
*/ |
|
|
|
|
function _getRoomAndDomainFromUrlObject(url) { |
|
|
|
|
function _getRoomAndDomainFromURLObject(url) { |
|
|
|
|
let domain; |
|
|
|
|
let room; |
|
|
|
|
|
|
|
|
|
if (url) { |
|
|
|
|
domain = url.hostname; |
|
|
|
|
room = url.pathname.substr(1); |
|
|
|
|
|
|
|
|
|
// The room (name) is the last component of pathname.
|
|
|
|
|
room = url.pathname; |
|
|
|
|
room = room.substring(room.lastIndexOf('/') + 1); |
|
|
|
|
|
|
|
|
|
// Convert empty string to undefined to simplify checks.
|
|
|
|
|
if (room === '') { |
|
|
|
|
@ -36,44 +147,6 @@ function _getRoomAndDomainFromUrlObject(url) { |
|
|
|
|
}; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Gets conference room name and connection domain from URL. |
|
|
|
|
* |
|
|
|
|
* @param {(string|undefined)} url - URL. |
|
|
|
|
* @returns {{ |
|
|
|
|
* domain: (string|undefined), |
|
|
|
|
* room: (string|undefined) |
|
|
|
|
* }} |
|
|
|
|
*/ |
|
|
|
|
export function _getRoomAndDomainFromUrlString(url) { |
|
|
|
|
// Rewrite the specified URL in order to handle special cases such as
|
|
|
|
|
// hipchat.com and enso.me which do not follow the common pattern of most
|
|
|
|
|
// Jitsi Meet deployments.
|
|
|
|
|
if (typeof url === 'string') { |
|
|
|
|
// hipchat.com
|
|
|
|
|
let regex = /^(https?):\/\/hipchat.com\/video\/call\//gi; |
|
|
|
|
let match = regex.exec(url); |
|
|
|
|
|
|
|
|
|
if (!match) { |
|
|
|
|
// enso.me
|
|
|
|
|
regex = /^(https?):\/\/enso\.me\/(?:call|meeting)\//gi; |
|
|
|
|
match = regex.exec(url); |
|
|
|
|
} |
|
|
|
|
if (match && match.length > 1) { |
|
|
|
|
/* eslint-disable no-param-reassign, prefer-template */ |
|
|
|
|
|
|
|
|
|
url |
|
|
|
|
= match[1] /* URL protocol */ |
|
|
|
|
+ '://enso.hipchat.me/' |
|
|
|
|
+ url.substring(regex.lastIndex); |
|
|
|
|
|
|
|
|
|
/* eslint-enable no-param-reassign, prefer-template */ |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return _getRoomAndDomainFromUrlObject(_urlStringToObject(url)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Determines which route is to be rendered in order to depict a specific Redux |
|
|
|
|
* store. |
|
|
|
|
@ -94,24 +167,74 @@ export function _getRouteToRender(stateOrGetState) { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Parses a string into a URL (object). |
|
|
|
|
* Parses a specific URI which (supposedly) references a Jitsi Meet resource |
|
|
|
|
* (location). |
|
|
|
|
* |
|
|
|
|
* @param {(string|undefined)} url - The URL to parse. |
|
|
|
|
* @private |
|
|
|
|
* @returns {URL} |
|
|
|
|
* @param {(string|undefined)} uri - The URI to parse which (supposedly) |
|
|
|
|
* references a Jitsi Meet resource (location). |
|
|
|
|
* @returns {{ |
|
|
|
|
* domain: (string|undefined), |
|
|
|
|
* room: (string|undefined) |
|
|
|
|
* }} |
|
|
|
|
*/ |
|
|
|
|
function _urlStringToObject(url) { |
|
|
|
|
let urlObj; |
|
|
|
|
export function _parseURIString(uri) { |
|
|
|
|
let obj; |
|
|
|
|
|
|
|
|
|
if (url) { |
|
|
|
|
try { |
|
|
|
|
urlObj = new URL(url); |
|
|
|
|
} catch (ex) { |
|
|
|
|
// The return value will signal the failure & the logged exception
|
|
|
|
|
// will provide the details to the developers.
|
|
|
|
|
console.log(`${url} seems to be not a valid URL, but it's OK`, ex); |
|
|
|
|
if (typeof uri === 'string') { |
|
|
|
|
let str = uri; |
|
|
|
|
|
|
|
|
|
str = _fixURIStringScheme(str); |
|
|
|
|
str = _fixURIStringHierPart(str); |
|
|
|
|
|
|
|
|
|
obj = {}; |
|
|
|
|
|
|
|
|
|
let regex; |
|
|
|
|
let match; |
|
|
|
|
|
|
|
|
|
// protocol
|
|
|
|
|
regex = new RegExp(`^${_URI_PROTOCOL_PATTERN}`, 'gi'); |
|
|
|
|
match = regex.exec(str); |
|
|
|
|
if (match) { |
|
|
|
|
obj.protocol = match[1].toLowerCase(); |
|
|
|
|
str = str.substring(regex.lastIndex); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// authority
|
|
|
|
|
regex = new RegExp(`^${_URI_AUTHORITY_PATTERN}`, 'gi'); |
|
|
|
|
match = regex.exec(str); |
|
|
|
|
if (match) { |
|
|
|
|
let authority = match[1]; |
|
|
|
|
|
|
|
|
|
str = str.substring(regex.lastIndex); |
|
|
|
|
|
|
|
|
|
// userinfo
|
|
|
|
|
const userinfoEndIndex = authority.indexOf('@'); |
|
|
|
|
|
|
|
|
|
if (userinfoEndIndex !== -1) { |
|
|
|
|
authority = authority.substring(userinfoEndIndex + 1); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
obj.host = authority; |
|
|
|
|
|
|
|
|
|
// port
|
|
|
|
|
const portBeginIndex = authority.lastIndexOf(':'); |
|
|
|
|
|
|
|
|
|
if (portBeginIndex !== -1) { |
|
|
|
|
obj.port = authority.substring(portBeginIndex + 1); |
|
|
|
|
authority = authority.substring(0, portBeginIndex); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
obj.hostname = authority; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// pathname
|
|
|
|
|
regex = new RegExp(`^${_URI_PATH_PATTERN}`, 'gi'); |
|
|
|
|
match = regex.exec(str); |
|
|
|
|
if (match) { |
|
|
|
|
obj.pathname = match[1] || '/'; |
|
|
|
|
str = str.substring(regex.lastIndex); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return urlObj; |
|
|
|
|
return _getRoomAndDomainFromURLObject(obj); |
|
|
|
|
} |
|
|
|
|
|