fix(invite): decode the meeting name (#4411)

* fix(invite): decode the meeting name

* squash: try to make mobile join same encoded meeting name as web

* Decodes and generated texts for share and copy meeting info.

Decodes in all cases except when it contains a space, as it will generate wrong links when pasted/shared in external applications.
This commit is contained in:
virtuacoplenny 2019-07-10 10:27:11 -07:00 committed by GitHub
parent b31d7b4451
commit 249dd7b8b8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 50 additions and 26 deletions

View File

@ -160,7 +160,11 @@ export function getConferenceName(stateful: Function | Object): string {
const { callDisplayName } = state['features/base/config'];
const { pendingSubjectChange, room, subject } = state['features/base/conference'];
return pendingSubjectChange || subject || callDisplayName || (callee && callee.name) || _.startCase(room);
return pendingSubjectChange
|| subject
|| callDisplayName
|| (callee && callee.name)
|| _.startCase(decodeURIComponent(room));
}
/**

View File

@ -217,7 +217,7 @@ class DeepLinkingMobilePage extends Component<Props> {
*/
function _mapStateToProps(state) {
return {
_room: state['features/base/conference'].room
_room: decodeURIComponent(state['features/base/conference'].room)
};
}

View File

@ -21,7 +21,7 @@ document.addEventListener('DOMContentLoaded', () => {
? <DialInSummary
className = 'dial-in-page'
clickableNumbers = { isUsingMobileBrowser }
room = { room } />
room = { decodeURIComponent(room) } />
: <NoRoomError className = 'dial-in-page' /> }
</I18nextProvider>,
document.getElementById('react')

View File

@ -13,7 +13,11 @@ import {
getLocalParticipant
} from '../../../../base/participants';
import { _getDefaultPhoneNumber, getDialInfoPageURL } from '../../../functions';
import {
_decodeRoomURI,
_getDefaultPhoneNumber,
getDialInfoPageURL
} from '../../../functions';
import DialInNumber from './DialInNumber';
import PasswordForm from './PasswordForm';
@ -237,7 +241,7 @@ class InfoDialog extends Component<Props, State> {
className = 'info-dialog-url-text'
href = { this.props._inviteURL }
onClick = { this._onClickURLText } >
{ this._getURLToDisplay() }
{ decodeURI(this._getURLToDisplay()) }
</a>
</span>
</div>
@ -288,18 +292,6 @@ class InfoDialog extends Component<Props, State> {
);
}
/**
* Generates the URL for the static dial in info page.
*
* @private
* @returns {string}
*/
_getDialInfoPageURL() {
return getDialInfoPageURL(
encodeURIComponent(this.props._conferenceName),
this.props._locationURL);
}
/**
* Creates a message describing how to dial in to the conference.
*
@ -309,13 +301,14 @@ class InfoDialog extends Component<Props, State> {
_getTextToCopy() {
const { _localParticipant, liveStreamViewURL, t } = this.props;
const shouldDisplayDialIn = this._shouldDisplayDialIn();
const _inviteURL = _decodeRoomURI(this.props._inviteURL);
let invite = _localParticipant && _localParticipant.name
? t('info.inviteURLFirstPartPersonal', { name: _localParticipant.name })
: t('info.inviteURLFirstPartGeneral');
invite += t('info.inviteURLSecondPart', {
url: this.props._inviteURL
url: _inviteURL
});
if (liveStreamViewURL) {
@ -332,8 +325,11 @@ class InfoDialog extends Component<Props, State> {
conferenceID: this.props.dialIn.conferenceID
});
const moreNumbers = t('info.invitePhoneAlternatives', {
url: this._getDialInfoPageURL(),
silentUrl: `${this.props._inviteURL}#config.startSilent=true`
url: getDialInfoPageURL(
this.props._conferenceName,
this.props._locationURL
),
silentUrl: `${_inviteURL}#config.startSilent=true`
});
invite = `${invite}\n${dial}\n${moreNumbers}`;
@ -457,7 +453,12 @@ class InfoDialog extends Component<Props, State> {
phoneNumber = { this.state.phoneNumber } />
<a
className = 'more-numbers'
href = { this._getDialInfoPageURL() }
href = {
getDialInfoPageURL(
this.props._conferenceName,
this.props._locationURL
)
}
rel = 'noopener noreferrer'
target = '_blank'>
{ this.props.t('info.moreNumbers') }

View File

@ -401,7 +401,7 @@ export function searchDirectory( // eslint-disable-line max-params
*/
export function getShareInfoText(
state: Object, inviteUrl: string, useHtml: ?boolean): Promise<string> {
let roomUrl = inviteUrl;
let roomUrl = _decodeRoomURI(inviteUrl);
const includeDialInfo = state['features/base/config'] !== undefined;
if (useHtml) {
@ -505,7 +505,7 @@ export function getDialInfoPageURL(
return accumulator;
}, '');
return `${origin}${newPath}/static/dialInInfo.html?room=${conferenceName}`;
return `${origin}${newPath}/static/dialInInfo.html?room=${_decodeRoomURI(conferenceName)}`;
}
/**
@ -560,3 +560,22 @@ export function _getDefaultPhoneNumber(
return null;
}
/**
* Decodes URI only if doesn't contain a space(' ').
*
* @param {string} url - The string to decode.
* @returns {string} - It the string contains space, encoded value is '%20' returns
* same string, otherwise decoded one.
* @private
*/
export function _decodeRoomURI(url: string) {
let roomUrl = url;
// we want to decode urls when the do not contain space, ' ', which url encoded is %20
if (roomUrl && !roomUrl.includes('%20')) {
roomUrl = decodeURI(roomUrl);
}
return roomUrl;
}

View File

@ -31,7 +31,7 @@ function toDisplayableItem(item, defaultServerURL, t) {
_toDurationString(item.duration),
serverName
],
title: location.room,
title: decodeURIComponent(location.room),
url: item.conference
};
}

View File

@ -18,7 +18,7 @@ export function toDisplayableList(recentList) {
date: item.date,
duration: item.duration,
time: [ item.date ],
title: parseURIString(item.conference).room,
title: decodeURIComponent(parseURIString(item.conference).room),
url: item.conference
};
}));

View File

@ -192,7 +192,7 @@ export class AbstractWelcomePage extends Component<Props, *> {
const onAppNavigateSettled
= () => this._mounted && this.setState({ joining: false });
this.props.dispatch(appNavigate(room))
this.props.dispatch(appNavigate(encodeURI(room)))
.then(onAppNavigateSettled, onAppNavigateSettled);
}
}