feat: insecure room name warning
This commit is contained in:
parent
9525cab60f
commit
c08638da51
|
@ -0,0 +1,68 @@
|
|||
.large-video-labels {
|
||||
display: flex;
|
||||
position: absolute;
|
||||
top: 30px;
|
||||
right: 30px;
|
||||
transition: right 0.5s;
|
||||
z-index: $zindex3;
|
||||
|
||||
.circular-label {
|
||||
align-items: center;
|
||||
color: white;
|
||||
display: flex;
|
||||
font-weight: bold;
|
||||
justify-content: center;
|
||||
margin-left: 8px;
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
.circular-label {
|
||||
background: #B8C7E0;
|
||||
}
|
||||
|
||||
.circular-label.e2ee {
|
||||
align-items: center;
|
||||
background: #76CF9C;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.circular-label.file {
|
||||
background: #FF5630;
|
||||
}
|
||||
|
||||
.circular-label.local-rec {
|
||||
background: #FF5630;
|
||||
}
|
||||
|
||||
.circular-label.stream {
|
||||
background: #0065FF;
|
||||
}
|
||||
|
||||
.circular-label.insecure {
|
||||
background: $defaultWarningColor;
|
||||
}
|
||||
|
||||
.recording-label.center-message {
|
||||
background: $videoStateIndicatorBackground;
|
||||
bottom: 50%;
|
||||
display: block;
|
||||
left: 50%;
|
||||
padding: 10px;
|
||||
position: fixed;
|
||||
transform: translate(-50%, -50%);
|
||||
z-index: $centeredVideoLabelZ;
|
||||
}
|
||||
}
|
||||
|
||||
.circular-label {
|
||||
background: $videoStateIndicatorBackground;
|
||||
border-radius: 50%;
|
||||
box-sizing: border-box;
|
||||
cursor: default;
|
||||
font-size: 13px;
|
||||
height: $videoStateIndicatorSize;
|
||||
line-height: $videoStateIndicatorSize;
|
||||
text-align: center;
|
||||
min-width: $videoStateIndicatorSize;
|
||||
}
|
|
@ -71,9 +71,6 @@ body.welcome-page {
|
|||
text-align: left;
|
||||
color: #253858;
|
||||
height: fit-content;
|
||||
border-width: $welcomePageEnterRoomInputContainerBorderWidth;
|
||||
border-style: $welcomePageEnterRoomInputContainerBorderStyle;
|
||||
border-image: $welcomePageEnterRoomInputContainerBorderImage;
|
||||
|
||||
.enter-room-title {
|
||||
display: $welcomePageEnterRoomTitleDisplay;
|
||||
|
@ -83,12 +80,26 @@ body.welcome-page {
|
|||
}
|
||||
|
||||
.enter-room-input {
|
||||
border: none;
|
||||
border-width: $welcomePageEnterRoomInputContainerBorderWidth;
|
||||
border-style: $welcomePageEnterRoomInputContainerBorderStyle;
|
||||
border-image: $welcomePageEnterRoomInputContainerBorderImage;
|
||||
display: inline-block;
|
||||
width: 100%;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.insecure-room-name-warning {
|
||||
align-items: center;
|
||||
color: $defaultWarningColor;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
margin-top: 5px;
|
||||
|
||||
svg {
|
||||
fill: $defaultWarningColor
|
||||
}
|
||||
}
|
||||
|
||||
::placeholder {
|
||||
color: #253858;
|
||||
}
|
||||
|
|
|
@ -75,6 +75,7 @@ $flagsImagePath: "../images/";
|
|||
@import 'filmstrip/tile_view_overrides';
|
||||
@import 'filmstrip/vertical_filmstrip';
|
||||
@import 'filmstrip/vertical_filmstrip_overrides';
|
||||
@import 'labels';
|
||||
@import 'unsupported-browser/main';
|
||||
@import 'modals/invite/add-people';
|
||||
@import 'deep-linking/main';
|
||||
|
|
|
@ -144,65 +144,3 @@
|
|||
#videoResolutionLabel {
|
||||
z-index: $zindex3 + 1;
|
||||
}
|
||||
|
||||
.large-video-labels {
|
||||
display: flex;
|
||||
position: absolute;
|
||||
top: 30px;
|
||||
right: 30px;
|
||||
transition: right 0.5s;
|
||||
z-index: $zindex3;
|
||||
|
||||
.circular-label {
|
||||
color: white;
|
||||
font-weight: bold;
|
||||
margin-left: 8px;
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
.circular-label {
|
||||
background: #B8C7E0;
|
||||
}
|
||||
|
||||
.circular-label.e2ee {
|
||||
align-items: center;
|
||||
background: #76CF9C;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.circular-label.file {
|
||||
background: #FF5630;
|
||||
}
|
||||
|
||||
.circular-label.local-rec {
|
||||
background: #FF5630;
|
||||
}
|
||||
|
||||
.circular-label.stream {
|
||||
background: #0065FF;
|
||||
}
|
||||
|
||||
.recording-label.center-message {
|
||||
background: $videoStateIndicatorBackground;
|
||||
bottom: 50%;
|
||||
display: block;
|
||||
left: 50%;
|
||||
padding: 10px;
|
||||
position: fixed;
|
||||
transform: translate(-50%, -50%);
|
||||
z-index: $centeredVideoLabelZ;
|
||||
}
|
||||
}
|
||||
|
||||
.circular-label {
|
||||
background: $videoStateIndicatorBackground;
|
||||
border-radius: 50%;
|
||||
box-sizing: border-box;
|
||||
cursor: default;
|
||||
font-size: 13px;
|
||||
height: $videoStateIndicatorSize;
|
||||
line-height: $videoStateIndicatorSize;
|
||||
text-align: center;
|
||||
min-width: $videoStateIndicatorSize;
|
||||
}
|
||||
|
|
|
@ -561,6 +561,9 @@
|
|||
"sectionList": {
|
||||
"pullToRefresh": "Pull to refresh"
|
||||
},
|
||||
"security": {
|
||||
"insecureRoomNameWarning": "The room name is insecure. Unwanted participants may join your conference."
|
||||
},
|
||||
"settings": {
|
||||
"calendar": {
|
||||
"about": "The {{appName}} calendar integration is used to securely access your calendar so it can read upcoming events.",
|
||||
|
|
|
@ -19178,6 +19178,11 @@
|
|||
"integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"zxcvbn": {
|
||||
"version": "4.4.2",
|
||||
"resolved": "https://registry.npmjs.org/zxcvbn/-/zxcvbn-4.4.2.tgz",
|
||||
"integrity": "sha1-KOwXzwl0PtyrBW3dixsGJizHPDA="
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -93,7 +93,8 @@
|
|||
"util": "0.12.1",
|
||||
"uuid": "3.1.0",
|
||||
"windows-iana": "^3.1.0",
|
||||
"xmldom": "0.1.27"
|
||||
"xmldom": "0.1.27",
|
||||
"zxcvbn": "4.4.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "7.5.5",
|
||||
|
|
|
@ -86,3 +86,4 @@ export { default as IconVideoQualitySD } from './SD.svg';
|
|||
export { default as IconVolume } from './volume.svg';
|
||||
export { default as IconVolumeEmpty } from './volume-empty.svg';
|
||||
export { default as IconVolumeOff } from './volume-off.svg';
|
||||
export { default as IconWarning } from './warning.svg';
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 0 24 24" width="24"><path d="M0 0h24v24H0z" fill="none"/><path d="M1 21h22L12 2 1 21zm12-3h-2v-2h2v2zm0-4h-2v-4h2v4z"/></svg>
|
After Width: | Height: | Size: 188 B |
|
@ -1,5 +1,29 @@
|
|||
// @flow
|
||||
|
||||
/**
|
||||
* A helper function that behaves similar to Object.assign, but only reassigns a
|
||||
* property in target if it's defined in source.
|
||||
*
|
||||
* @param {Object} target - The target object to assign the values into.
|
||||
* @param {Object} source - The source object.
|
||||
* @returns {Object}
|
||||
*/
|
||||
export function assignIfDefined(target: Object, source: Object) {
|
||||
const to = Object(target);
|
||||
|
||||
for (const nextKey in source) {
|
||||
if (source.hasOwnProperty(nextKey)) {
|
||||
const value = source[nextKey];
|
||||
|
||||
if (typeof value !== 'undefined') {
|
||||
to[nextKey] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return to;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a deferred object.
|
||||
*
|
||||
|
@ -72,30 +96,6 @@ export function getJitsiMeetGlobalNS() {
|
|||
return window.JitsiMeetJS.app;
|
||||
}
|
||||
|
||||
/**
|
||||
* A helper function that behaves similar to Object.assign, but only reassigns a
|
||||
* property in target if it's defined in source.
|
||||
*
|
||||
* @param {Object} target - The target object to assign the values into.
|
||||
* @param {Object} source - The source object.
|
||||
* @returns {Object}
|
||||
*/
|
||||
export function assignIfDefined(target: Object, source: Object) {
|
||||
const to = Object(target);
|
||||
|
||||
for (const nextKey in source) {
|
||||
if (source.hasOwnProperty(nextKey)) {
|
||||
const value = source[nextKey];
|
||||
|
||||
if (typeof value !== 'undefined') {
|
||||
to[nextKey] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return to;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints the error and reports it to the global error handler.
|
||||
*
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
// @flow
|
||||
|
||||
import zxcvbn from 'zxcvbn';
|
||||
|
||||
/**
|
||||
* Returns true if the room name is considered a weak (insecure) one.
|
||||
*
|
||||
* @param {string} roomName - The room name.
|
||||
* @returns {boolean}
|
||||
*/
|
||||
export default function isInsecureRoomName(roomName: string = ''): boolean {
|
||||
return zxcvbn(roomName).score < 3;
|
||||
}
|
|
@ -0,0 +1,57 @@
|
|||
// @flow
|
||||
|
||||
import { PureComponent } from 'react';
|
||||
|
||||
import isInsecureRoomName from '../../base/util/isInsecureRoomName';
|
||||
|
||||
type Props = {
|
||||
|
||||
/**
|
||||
* True of the label should be visible.
|
||||
*/
|
||||
_visible: boolean;
|
||||
|
||||
/**
|
||||
* Function to be used to translate i18n labels.
|
||||
*/
|
||||
t: Function
|
||||
}
|
||||
|
||||
/**
|
||||
* Abstrsact class for the {@Code InsecureRoomNameLabel} component.
|
||||
*/
|
||||
export default class AbstractInsecureRoomNameLabel extends PureComponent<Props> {
|
||||
/**
|
||||
* Implements {@code Component#render}.
|
||||
*
|
||||
* @inheritdoc
|
||||
*/
|
||||
render() {
|
||||
if (!this.props._visible) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return this._render();
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the platform dependant content.
|
||||
*
|
||||
* @returns {ReactElement}
|
||||
*/
|
||||
_render: () => Object;
|
||||
}
|
||||
|
||||
/**
|
||||
* Maps part of the Redux state to the props of this component.
|
||||
*
|
||||
* @param {Object} state - The Redux state.
|
||||
* @returns {Props}
|
||||
*/
|
||||
export function _mapStateToProps(state: Object): $Shape<Props> {
|
||||
const { room } = state['features/base/conference'];
|
||||
|
||||
return {
|
||||
_visible: room && isInsecureRoomName(room)
|
||||
};
|
||||
}
|
|
@ -10,6 +10,8 @@ import { TranscribingLabel } from '../../transcribing';
|
|||
import { shouldDisplayTileView } from '../../video-layout';
|
||||
import { VideoQualityLabel } from '../../video-quality';
|
||||
|
||||
import { InsecureRoomNameLabel } from '.';
|
||||
|
||||
/**
|
||||
* The type of the React {@code Component} props of {@link AbstractLabels}.
|
||||
*/
|
||||
|
@ -84,6 +86,18 @@ export default class AbstractLabels<P: Props, S> extends Component<P, S> {
|
|||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the {@code InsecureRoomNameLabel}.
|
||||
*
|
||||
* @protected
|
||||
* @returns {React$Element}
|
||||
*/
|
||||
_renderInsecureRoomNameLabel() {
|
||||
return (
|
||||
<InsecureRoomNameLabel />
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the {@code VideoQualityLabel} that is platform independent.
|
||||
*
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
// @flow
|
||||
|
||||
import { translate } from '../../../base/i18n';
|
||||
import { ExpandedLabel, type Props as AbstractProps } from '../../../base/label';
|
||||
|
||||
import { INSECURE_ROOM_NAME_LABEL_COLOR } from './styles';
|
||||
|
||||
type Props = AbstractProps & {
|
||||
t: Function
|
||||
}
|
||||
|
||||
/**
|
||||
* A react {@code Component} that implements an expanded label as tooltip-like
|
||||
* component to explain the meaning of the {@code InsecureRoomNameExpandedLabel}.
|
||||
*/
|
||||
class InsecureRoomNameExpandedLabel extends ExpandedLabel<Props> {
|
||||
/**
|
||||
* Returns the color this expanded label should be rendered with.
|
||||
*
|
||||
* @returns {string}
|
||||
*/
|
||||
_getColor() {
|
||||
return INSECURE_ROOM_NAME_LABEL_COLOR;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the label specific text of this {@code ExpandedLabel}.
|
||||
*
|
||||
* @returns {string}
|
||||
*/
|
||||
_getLabel() {
|
||||
return this.props.t('security.insecureRoomNameWarning');
|
||||
}
|
||||
}
|
||||
|
||||
export default translate(InsecureRoomNameExpandedLabel);
|
|
@ -0,0 +1,31 @@
|
|||
// @flow
|
||||
|
||||
import React from 'react';
|
||||
|
||||
import { IconWarning } from '../../../base/icons';
|
||||
import { CircularLabel } from '../../../base/label';
|
||||
import { connect } from '../../../base/redux';
|
||||
|
||||
import AbstractInsecureRoomNameLabel, { _mapStateToProps } from '../AbstractInsecureRoomNameLabel';
|
||||
|
||||
import styles from './styles';
|
||||
|
||||
/**
|
||||
* Renders a label indicating that we are in a room with an insecure name.
|
||||
*/
|
||||
class InsecureRoomNameLabel extends AbstractInsecureRoomNameLabel {
|
||||
/**
|
||||
* Renders the platform dependant content.
|
||||
*
|
||||
* @inheritdoc
|
||||
*/
|
||||
_render() {
|
||||
return (
|
||||
<CircularLabel
|
||||
icon = { IconWarning }
|
||||
style = { styles.insecureRoomNameLabel } />
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default connect(_mapStateToProps)(InsecureRoomNameLabel);
|
|
@ -20,6 +20,8 @@ import AbstractLabels, {
|
|||
type Props as AbstractLabelsProps
|
||||
} from '../AbstractLabels';
|
||||
import { shouldDisplayNotifications } from '../../functions';
|
||||
|
||||
import InsecureRoomNameExpandedLabel from './InsecureRoomNameExpandedLabel';
|
||||
import styles from './styles';
|
||||
|
||||
/**
|
||||
|
@ -32,14 +34,6 @@ type Props = AbstractLabelsProps & {
|
|||
*/
|
||||
t: Function,
|
||||
|
||||
/**
|
||||
* The indicator which determines whether the UI is reduced (to accommodate
|
||||
* smaller display areas).
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
_reducedUI: boolean,
|
||||
|
||||
/**
|
||||
* True if the labels should be visible, false otherwise.
|
||||
*/
|
||||
|
@ -85,6 +79,7 @@ const LABEL_ID_QUALITY = 'quality';
|
|||
const LABEL_ID_RECORDING = 'recording';
|
||||
const LABEL_ID_STREAMING = 'streaming';
|
||||
const LABEL_ID_TRANSCRIBING = 'transcribing';
|
||||
const LABEL_ID_INSECURE_ROOM_NAME = 'insecure-room-name';
|
||||
|
||||
/**
|
||||
* The {@code ExpandedLabel} components to be rendered for the individual
|
||||
|
@ -104,7 +99,8 @@ const EXPANDED_LABELS = {
|
|||
mode: JitsiRecordingConstants.mode.STREAM
|
||||
}
|
||||
},
|
||||
transcribing: TranscribingExpandedLabel
|
||||
transcribing: TranscribingExpandedLabel,
|
||||
'insecure-room-name': InsecureRoomNameExpandedLabel
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -159,7 +155,7 @@ class Labels extends AbstractLabels<Props, State> {
|
|||
}
|
||||
|
||||
const wide = !isNarrowAspectRatio(this);
|
||||
const { _filmstripVisible, _reducedUI } = this.props;
|
||||
const { _filmstripVisible } = this.props;
|
||||
|
||||
return (
|
||||
<View
|
||||
|
@ -200,15 +196,17 @@ class Labels extends AbstractLabels<Props, State> {
|
|||
this._renderTranscribingLabel()
|
||||
}
|
||||
</TouchableOpacity>
|
||||
{/*
|
||||
* Emil, Lyubomir, Nichole, and Zoli said that the Labels
|
||||
* should not be rendered in Picture-in-Picture. Saul
|
||||
* argued that the recording Labels should be rendered. As
|
||||
* a temporary compromise, don't render the
|
||||
* VideoQualityLabel at least because it's not that
|
||||
* important.
|
||||
*/
|
||||
_reducedUI || (
|
||||
<TouchableOpacity
|
||||
onLayout = {
|
||||
this._createOnLayout(LABEL_ID_INSECURE_ROOM_NAME)
|
||||
}
|
||||
onPress = {
|
||||
this._createOnPress(LABEL_ID_INSECURE_ROOM_NAME)
|
||||
} >
|
||||
{
|
||||
this._renderInsecureRoomNameLabel()
|
||||
}
|
||||
</TouchableOpacity>
|
||||
<TouchableOpacity
|
||||
onLayout = {
|
||||
this._createOnLayout(LABEL_ID_QUALITY) }
|
||||
|
@ -216,8 +214,6 @@ class Labels extends AbstractLabels<Props, State> {
|
|||
this._createOnPress(LABEL_ID_QUALITY) } >
|
||||
{ this._renderVideoQualityLabel() }
|
||||
</TouchableOpacity>
|
||||
)
|
||||
}
|
||||
</View>
|
||||
<View
|
||||
style = { [
|
||||
|
@ -339,11 +335,13 @@ class Labels extends AbstractLabels<Props, State> {
|
|||
return null;
|
||||
}
|
||||
|
||||
_renderRecordingLabel: string => React$Element<*>;
|
||||
_renderRecordingLabel: string => React$Element<any>;
|
||||
|
||||
_renderTranscribingLabel: () => React$Element<*>
|
||||
_renderTranscribingLabel: () => React$Element<any>;
|
||||
|
||||
_renderVideoQualityLabel: () => React$Element<*>;
|
||||
_renderInsecureRoomNameLabel: () => React$Element<any>;
|
||||
|
||||
_renderVideoQualityLabel: () => React$Element<any>;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -352,16 +350,11 @@ class Labels extends AbstractLabels<Props, State> {
|
|||
*
|
||||
* @param {Object} state - The redux state.
|
||||
* @private
|
||||
* @returns {{
|
||||
* _filmstripVisible: boolean,
|
||||
* _reducedUI: boolean,
|
||||
* _visible: boolean
|
||||
* }}
|
||||
* @returns {Props}
|
||||
*/
|
||||
function _mapStateToProps(state) {
|
||||
return {
|
||||
..._abstractMapStateToProps(state),
|
||||
_reducedUI: state['features/base/responsive-ui'].reducedUI,
|
||||
_visible: !shouldDisplayNotifications(state)
|
||||
};
|
||||
}
|
||||
|
|
|
@ -2,3 +2,4 @@
|
|||
|
||||
export { default as Conference } from './Conference';
|
||||
export { default as renderConferenceTimer } from './ConferenceTimerDisplay';
|
||||
export { default as InsecureRoomNameLabel } from './InsecureRoomNameLabel';
|
||||
|
|
|
@ -3,6 +3,7 @@ import { ColorSchemeRegistry, schemeColor } from '../../../base/color-scheme';
|
|||
import { FILMSTRIP_SIZE } from '../../../filmstrip';
|
||||
|
||||
export const NAVBAR_GRADIENT_COLORS = [ '#000000FF', '#00000000' ];
|
||||
export const INSECURE_ROOM_NAME_LABEL_COLOR = ColorPalette.warning;
|
||||
|
||||
// From brand guideline
|
||||
const BOTTOM_GRADIENT_HEIGHT = 290;
|
||||
|
@ -167,6 +168,10 @@ export default {
|
|||
// On iPhone X there is the notch. In the two cases BoxModel.margin is
|
||||
// not enough.
|
||||
top: BoxModel.margin * 3
|
||||
},
|
||||
|
||||
insecureRoomNameLabel: {
|
||||
backgroundColor: INSECURE_ROOM_NAME_LABEL_COLOR
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
// @flow
|
||||
|
||||
import Tooltip from '@atlaskit/tooltip';
|
||||
import React from 'react';
|
||||
|
||||
import { translate } from '../../../base/i18n';
|
||||
import { IconWarning } from '../../../base/icons';
|
||||
import { CircularLabel } from '../../../base/label';
|
||||
import { connect } from '../../../base/redux';
|
||||
|
||||
import AbstractInsecureRoomNameLabel, { _mapStateToProps } from '../AbstractInsecureRoomNameLabel';
|
||||
|
||||
/**
|
||||
* Renders a label indicating that we are in a room with an insecure name.
|
||||
*/
|
||||
class InsecureRoomNameLabel extends AbstractInsecureRoomNameLabel {
|
||||
/**
|
||||
* Renders the platform dependant content.
|
||||
*
|
||||
* @inheritdoc
|
||||
*/
|
||||
_render() {
|
||||
return (
|
||||
<Tooltip
|
||||
content = { this.props.t('security.insecureRoomNameWarning') }
|
||||
position = 'left'>
|
||||
<CircularLabel
|
||||
className = 'insecure'
|
||||
icon = { IconWarning } />
|
||||
</Tooltip>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default translate(connect(_mapStateToProps)(InsecureRoomNameLabel));
|
|
@ -95,6 +95,9 @@ class Labels extends AbstractLabels<Props, State> {
|
|||
this.props._showVideoQualityLabel
|
||||
&& this._renderVideoQualityLabel()
|
||||
}
|
||||
{
|
||||
this._renderInsecureRoomNameLabel()
|
||||
}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
@ -107,6 +110,8 @@ class Labels extends AbstractLabels<Props, State> {
|
|||
|
||||
_renderTranscribingLabel: () => React$Element<*>;
|
||||
|
||||
_renderInsecureRoomNameLabel: () => React$Element<any>;
|
||||
|
||||
_renderVideoQualityLabel: () => React$Element<*>;
|
||||
}
|
||||
|
||||
|
|
|
@ -2,4 +2,4 @@
|
|||
|
||||
export { default as Conference } from './Conference';
|
||||
export { default as renderConferenceTimer } from './ConferenceTimerDisplay';
|
||||
|
||||
export { default as InsecureRoomNameLabel } from './InsecureRoomNameLabel';
|
||||
|
|
|
@ -6,6 +6,7 @@ import type { Dispatch } from 'redux';
|
|||
|
||||
import { createWelcomePageEvent, sendAnalytics } from '../../analytics';
|
||||
import { appNavigate } from '../../app';
|
||||
import isInsecureRoomName from '../../base/util/isInsecureRoomName';
|
||||
import { isCalendarEnabled } from '../../calendar-sync';
|
||||
import { isRecentListEnabled } from '../../recent-list/functions';
|
||||
|
||||
|
@ -75,6 +76,7 @@ export class AbstractWelcomePage extends Component<Props, *> {
|
|||
state = {
|
||||
animateTimeoutId: undefined,
|
||||
generatedRoomname: '',
|
||||
insecureRoomName: false,
|
||||
joining: false,
|
||||
room: '',
|
||||
roomPlaceholder: '',
|
||||
|
@ -95,6 +97,7 @@ export class AbstractWelcomePage extends Component<Props, *> {
|
|||
= this._animateRoomnameChanging.bind(this);
|
||||
this._onJoin = this._onJoin.bind(this);
|
||||
this._onRoomChange = this._onRoomChange.bind(this);
|
||||
this._renderInsecureRoomNameWarning = this._renderInsecureRoomNameWarning.bind(this);
|
||||
this._updateRoomname = this._updateRoomname.bind(this);
|
||||
}
|
||||
|
||||
|
@ -160,6 +163,13 @@ export class AbstractWelcomePage extends Component<Props, *> {
|
|||
clearTimeout(this.state.updateTimeoutId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the insecure room name warning.
|
||||
*
|
||||
* @returns {ReactElement}
|
||||
*/
|
||||
_doRenderInsecureRoomNameWarning: () => React$Component<any>;
|
||||
|
||||
_onJoin: () => void;
|
||||
|
||||
/**
|
||||
|
@ -202,7 +212,25 @@ export class AbstractWelcomePage extends Component<Props, *> {
|
|||
* @returns {void}
|
||||
*/
|
||||
_onRoomChange(value: string) {
|
||||
this.setState({ room: value });
|
||||
this.setState({
|
||||
room: value,
|
||||
insecureRoomName: value && isInsecureRoomName(value)
|
||||
});
|
||||
}
|
||||
|
||||
_renderInsecureRoomNameWarning: () => React$Component<any>;;
|
||||
|
||||
/**
|
||||
* Renders the insecure room name warning if needed.
|
||||
*
|
||||
* @returns {ReactElement}
|
||||
*/
|
||||
_renderInsecureRoomNameWarning() {
|
||||
if (this.state.insecureRoomName) {
|
||||
return this._doRenderInsecureRoomNameWarning();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
_updateRoomname: () => void;
|
||||
|
|
|
@ -13,7 +13,7 @@ import { getName } from '../../app';
|
|||
|
||||
import { ColorSchemeRegistry } from '../../base/color-scheme';
|
||||
import { translate } from '../../base/i18n';
|
||||
import { Icon, IconMenu } from '../../base/icons';
|
||||
import { Icon, IconMenu, IconWarning } from '../../base/icons';
|
||||
import { MEDIA_TYPE } from '../../base/media';
|
||||
import { Header, LoadingIndicator, Text } from '../../base/react';
|
||||
import { connect } from '../../base/redux';
|
||||
|
@ -119,6 +119,28 @@ class WelcomePage extends AbstractWelcomePage {
|
|||
return this._renderFullUI();
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the insecure room name warning.
|
||||
*
|
||||
* @inheritdoc
|
||||
*/
|
||||
_doRenderInsecureRoomNameWarning() {
|
||||
return (
|
||||
<View
|
||||
style = { [
|
||||
styles.messageContainer,
|
||||
styles.insecureRoomNameWarningContainer
|
||||
] }>
|
||||
<Icon
|
||||
src = { IconWarning }
|
||||
style = { styles.insecureRoomNameWarningIcon } />
|
||||
<Text style = { styles.insecureRoomNameWarningText }>
|
||||
{ this.props.t('security.insecureRoomNameWarning') }
|
||||
</Text>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a style array to handle the hint box animation.
|
||||
*
|
||||
|
@ -127,6 +149,7 @@ class WelcomePage extends AbstractWelcomePage {
|
|||
*/
|
||||
_getHintBoxStyle() {
|
||||
return [
|
||||
styles.messageContainer,
|
||||
styles.hintContainer,
|
||||
{
|
||||
opacity: this.state.hintBoxAnimation
|
||||
|
@ -283,6 +306,9 @@ class WelcomePage extends AbstractWelcomePage {
|
|||
style = { styles.textInput }
|
||||
underlineColorAndroid = 'transparent'
|
||||
value = { this.state.room } />
|
||||
{
|
||||
this._renderInsecureRoomNameWarning()
|
||||
}
|
||||
{
|
||||
this._renderHintBox()
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
import React from 'react';
|
||||
|
||||
import { translate } from '../../base/i18n';
|
||||
import { Icon, IconWarning } from '../../base/icons';
|
||||
import { Watermarks } from '../../base/react';
|
||||
import { connect } from '../../base/redux';
|
||||
import { isMobileBrowser } from '../../base/environment/utils';
|
||||
|
@ -209,6 +210,7 @@ class WelcomePage extends AbstractWelcomePage {
|
|||
title = { t('welcomepage.roomNameAllowedChars') }
|
||||
type = 'text'
|
||||
value = { this.state.room } />
|
||||
{ this._renderInsecureRoomNameWarning() }
|
||||
</form>
|
||||
</div>
|
||||
<div
|
||||
|
@ -233,6 +235,22 @@ class WelcomePage extends AbstractWelcomePage {
|
|||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the insecure room name warning.
|
||||
*
|
||||
* @inheritdoc
|
||||
*/
|
||||
_doRenderInsecureRoomNameWarning() {
|
||||
return (
|
||||
<div className = 'insecure-room-name-warning'>
|
||||
<Icon src = { IconWarning } />
|
||||
<span>
|
||||
{ this.props.t('security.insecureRoomNameWarning') }
|
||||
</span>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prevents submission of the form and delegates join logic.
|
||||
*
|
||||
|
|
|
@ -108,15 +108,8 @@ export default {
|
|||
* Container for the hint box.
|
||||
*/
|
||||
hintContainer: {
|
||||
backgroundColor: ColorPalette.white,
|
||||
borderColor: ColorPalette.white,
|
||||
borderRadius: 4,
|
||||
borderWidth: 1,
|
||||
flexDirection: 'column',
|
||||
marginVertical: 5,
|
||||
overflow: 'hidden',
|
||||
paddingHorizontal: BoxModel.padding,
|
||||
paddingVertical: 2 * BoxModel.padding
|
||||
overflow: 'hidden'
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -148,6 +141,16 @@ export default {
|
|||
padding: BoxModel.padding
|
||||
},
|
||||
|
||||
messageContainer: {
|
||||
backgroundColor: ColorPalette.white,
|
||||
borderColor: ColorPalette.white,
|
||||
borderRadius: 4,
|
||||
borderWidth: 1,
|
||||
marginVertical: 5,
|
||||
paddingHorizontal: BoxModel.padding,
|
||||
paddingVertical: 2 * BoxModel.padding
|
||||
},
|
||||
|
||||
/**
|
||||
* The style of the top-level container/{@code View} of
|
||||
* {@code LocalVideoTrackUnderlay}.
|
||||
|
@ -280,6 +283,23 @@ export default {
|
|||
textAlign: 'center'
|
||||
},
|
||||
|
||||
insecureRoomNameWarningContainer: {
|
||||
alignItems: 'center',
|
||||
flexDirection: 'row',
|
||||
paddingHorizontal: 5
|
||||
},
|
||||
|
||||
insecureRoomNameWarningIcon: {
|
||||
color: ColorPalette.warning,
|
||||
fontSize: 24,
|
||||
marginRight: 10
|
||||
},
|
||||
|
||||
insecureRoomNameWarningText: {
|
||||
color: ColorPalette.warning,
|
||||
flex: 1
|
||||
},
|
||||
|
||||
/**
|
||||
* The style of the top-level container of {@code WelcomePage}.
|
||||
*/
|
||||
|
|
|
@ -179,7 +179,7 @@ module.exports = [
|
|||
entry: {
|
||||
'app.bundle': './app.js'
|
||||
},
|
||||
performance: getPerformanceHints(3 * 1024 * 1024)
|
||||
performance: getPerformanceHints(4 * 1024 * 1024)
|
||||
}),
|
||||
Object.assign({}, config, {
|
||||
entry: {
|
||||
|
|
Loading…
Reference in New Issue