Bläddra i källkod

feat: insecure room name warning

j8
Bettenbuk Zoltan 5 år sedan
förälder
incheckning
c08638da51

+ 68
- 0
css/_labels.scss Visa fil

1
+.large-video-labels {
2
+    display: flex;
3
+    position: absolute;
4
+    top: 30px;
5
+    right: 30px;
6
+    transition: right 0.5s;
7
+    z-index: $zindex3;
8
+
9
+    .circular-label {
10
+        align-items: center;
11
+        color: white;
12
+        display: flex;
13
+        font-weight: bold;
14
+        justify-content: center;
15
+        margin-left: 8px;
16
+        opacity: 0.8;
17
+    }
18
+
19
+    .circular-label {
20
+        background: #B8C7E0;
21
+    }
22
+
23
+    .circular-label.e2ee {
24
+        align-items: center;
25
+        background: #76CF9C;
26
+        display: flex;
27
+        justify-content: center;
28
+    }
29
+
30
+    .circular-label.file {
31
+        background: #FF5630;
32
+    }
33
+
34
+    .circular-label.local-rec {
35
+        background: #FF5630;
36
+    }
37
+
38
+    .circular-label.stream {
39
+        background: #0065FF;
40
+    }
41
+
42
+    .circular-label.insecure {
43
+        background: $defaultWarningColor;
44
+    }
45
+
46
+    .recording-label.center-message {
47
+        background: $videoStateIndicatorBackground;
48
+        bottom: 50%;
49
+        display: block;
50
+        left: 50%;
51
+        padding: 10px;
52
+        position: fixed;
53
+        transform: translate(-50%, -50%);
54
+        z-index: $centeredVideoLabelZ;
55
+    }
56
+}
57
+
58
+.circular-label {
59
+    background: $videoStateIndicatorBackground;
60
+    border-radius: 50%;
61
+    box-sizing: border-box;
62
+    cursor: default;
63
+    font-size: 13px;
64
+    height: $videoStateIndicatorSize;
65
+    line-height: $videoStateIndicatorSize;
66
+    text-align: center;
67
+    min-width: $videoStateIndicatorSize;
68
+}

+ 15
- 4
css/_welcome_page.scss Visa fil

71
                 text-align: left;
71
                 text-align: left;
72
                 color: #253858;
72
                 color: #253858;
73
                 height: fit-content;
73
                 height: fit-content;
74
-                border-width: $welcomePageEnterRoomInputContainerBorderWidth;
75
-                border-style: $welcomePageEnterRoomInputContainerBorderStyle;
76
-                border-image: $welcomePageEnterRoomInputContainerBorderImage;
77
 
74
 
78
                 .enter-room-title {
75
                 .enter-room-title {
79
                     display: $welcomePageEnterRoomTitleDisplay;
76
                     display: $welcomePageEnterRoomTitleDisplay;
83
                 }
80
                 }
84
 
81
 
85
                 .enter-room-input {
82
                 .enter-room-input {
86
-                    border: none;
83
+                    border-width: $welcomePageEnterRoomInputContainerBorderWidth;
84
+                    border-style: $welcomePageEnterRoomInputContainerBorderStyle;
85
+                    border-image: $welcomePageEnterRoomInputContainerBorderImage;
87
                     display: inline-block;
86
                     display: inline-block;
88
                     width: 100%;
87
                     width: 100%;
89
                     font-size: 14px;
88
                     font-size: 14px;
90
                 }
89
                 }
91
 
90
 
91
+                .insecure-room-name-warning {
92
+                    align-items: center;
93
+                    color: $defaultWarningColor;
94
+                    display: flex;
95
+                    flex-direction: row;
96
+                    margin-top: 5px;
97
+
98
+                    svg {
99
+                        fill: $defaultWarningColor
100
+                    }
101
+                }
102
+
92
                 ::placeholder {
103
                 ::placeholder {
93
                     color: #253858;
104
                     color: #253858;
94
                 }
105
                 }

+ 1
- 0
css/main.scss Visa fil

75
 @import 'filmstrip/tile_view_overrides';
75
 @import 'filmstrip/tile_view_overrides';
76
 @import 'filmstrip/vertical_filmstrip';
76
 @import 'filmstrip/vertical_filmstrip';
77
 @import 'filmstrip/vertical_filmstrip_overrides';
77
 @import 'filmstrip/vertical_filmstrip_overrides';
78
+@import 'labels';
78
 @import 'unsupported-browser/main';
79
 @import 'unsupported-browser/main';
79
 @import 'modals/invite/add-people';
80
 @import 'modals/invite/add-people';
80
 @import 'deep-linking/main';
81
 @import 'deep-linking/main';

+ 0
- 62
css/modals/video-quality/_video-quality.scss Visa fil

144
 #videoResolutionLabel {
144
 #videoResolutionLabel {
145
     z-index: $zindex3 + 1;
145
     z-index: $zindex3 + 1;
146
 }
146
 }
147
-
148
-.large-video-labels {
149
-    display: flex;
150
-    position: absolute;
151
-    top: 30px;
152
-    right: 30px;
153
-    transition: right 0.5s;
154
-    z-index: $zindex3;
155
-
156
-    .circular-label {
157
-        color: white;
158
-        font-weight: bold;
159
-        margin-left: 8px;
160
-        opacity: 0.8;
161
-    }
162
-
163
-    .circular-label {
164
-        background: #B8C7E0;
165
-    }
166
-
167
-    .circular-label.e2ee {
168
-        align-items: center;
169
-        background: #76CF9C;
170
-        display: flex;
171
-        justify-content: center;
172
-    }
173
-
174
-    .circular-label.file {
175
-        background: #FF5630;
176
-    }
177
-
178
-    .circular-label.local-rec {
179
-        background: #FF5630;
180
-    }
181
-
182
-    .circular-label.stream {
183
-        background: #0065FF;
184
-    }
185
-
186
-    .recording-label.center-message {
187
-        background: $videoStateIndicatorBackground;
188
-        bottom: 50%;
189
-        display: block;
190
-        left: 50%;
191
-        padding: 10px;
192
-        position: fixed;
193
-        transform: translate(-50%, -50%);
194
-        z-index: $centeredVideoLabelZ;
195
-    }
196
-}
197
-
198
-.circular-label {
199
-    background: $videoStateIndicatorBackground;
200
-    border-radius: 50%;
201
-    box-sizing: border-box;
202
-    cursor: default;
203
-    font-size: 13px;
204
-    height: $videoStateIndicatorSize;
205
-    line-height: $videoStateIndicatorSize;
206
-    text-align: center;
207
-    min-width: $videoStateIndicatorSize;
208
-}

+ 3
- 0
lang/main.json Visa fil

561
     "sectionList": {
561
     "sectionList": {
562
         "pullToRefresh": "Pull to refresh"
562
         "pullToRefresh": "Pull to refresh"
563
     },
563
     },
564
+    "security": {
565
+        "insecureRoomNameWarning": "The room name is insecure. Unwanted participants may join your conference."
566
+    },
564
     "settings": {
567
     "settings": {
565
         "calendar": {
568
         "calendar": {
566
             "about": "The {{appName}} calendar integration is used to securely access your calendar so it can read upcoming events.",
569
             "about": "The {{appName}} calendar integration is used to securely access your calendar so it can read upcoming events.",

+ 5
- 0
package-lock.json Visa fil

19178
           "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg=="
19178
           "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg=="
19179
         }
19179
         }
19180
       }
19180
       }
19181
+    },
19182
+    "zxcvbn": {
19183
+      "version": "4.4.2",
19184
+      "resolved": "https://registry.npmjs.org/zxcvbn/-/zxcvbn-4.4.2.tgz",
19185
+      "integrity": "sha1-KOwXzwl0PtyrBW3dixsGJizHPDA="
19181
     }
19186
     }
19182
   }
19187
   }
19183
 }
19188
 }

+ 2
- 1
package.json Visa fil

93
     "util": "0.12.1",
93
     "util": "0.12.1",
94
     "uuid": "3.1.0",
94
     "uuid": "3.1.0",
95
     "windows-iana": "^3.1.0",
95
     "windows-iana": "^3.1.0",
96
-    "xmldom": "0.1.27"
96
+    "xmldom": "0.1.27",
97
+    "zxcvbn": "4.4.2"
97
   },
98
   },
98
   "devDependencies": {
99
   "devDependencies": {
99
     "@babel/core": "7.5.5",
100
     "@babel/core": "7.5.5",

+ 1
- 0
react/features/base/icons/svg/index.js Visa fil

86
 export { default as IconVolume } from './volume.svg';
86
 export { default as IconVolume } from './volume.svg';
87
 export { default as IconVolumeEmpty } from './volume-empty.svg';
87
 export { default as IconVolumeEmpty } from './volume-empty.svg';
88
 export { default as IconVolumeOff } from './volume-off.svg';
88
 export { default as IconVolumeOff } from './volume-off.svg';
89
+export { default as IconWarning } from './warning.svg';

+ 1
- 0
react/features/base/icons/svg/warning.svg Visa fil

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>

+ 24
- 24
react/features/base/util/helpers.js Visa fil

1
 // @flow
1
 // @flow
2
 
2
 
3
+/**
4
+ * A helper function that behaves similar to Object.assign, but only reassigns a
5
+ * property in target if it's defined in source.
6
+ *
7
+ * @param {Object} target - The target object to assign the values into.
8
+ * @param {Object} source - The source object.
9
+ * @returns {Object}
10
+ */
11
+export function assignIfDefined(target: Object, source: Object) {
12
+    const to = Object(target);
13
+
14
+    for (const nextKey in source) {
15
+        if (source.hasOwnProperty(nextKey)) {
16
+            const value = source[nextKey];
17
+
18
+            if (typeof value !== 'undefined') {
19
+                to[nextKey] = value;
20
+            }
21
+        }
22
+    }
23
+
24
+    return to;
25
+}
26
+
3
 /**
27
 /**
4
  * Creates a deferred object.
28
  * Creates a deferred object.
5
  *
29
  *
72
     return window.JitsiMeetJS.app;
96
     return window.JitsiMeetJS.app;
73
 }
97
 }
74
 
98
 
75
-/**
76
- * A helper function that behaves similar to Object.assign, but only reassigns a
77
- * property in target if it's defined in source.
78
- *
79
- * @param {Object} target - The target object to assign the values into.
80
- * @param {Object} source - The source object.
81
- * @returns {Object}
82
- */
83
-export function assignIfDefined(target: Object, source: Object) {
84
-    const to = Object(target);
85
-
86
-    for (const nextKey in source) {
87
-        if (source.hasOwnProperty(nextKey)) {
88
-            const value = source[nextKey];
89
-
90
-            if (typeof value !== 'undefined') {
91
-                to[nextKey] = value;
92
-            }
93
-        }
94
-    }
95
-
96
-    return to;
97
-}
98
-
99
 /**
99
 /**
100
  * Prints the error and reports it to the global error handler.
100
  * Prints the error and reports it to the global error handler.
101
  *
101
  *

+ 13
- 0
react/features/base/util/isInsecureRoomName.js Visa fil

1
+// @flow
2
+
3
+import zxcvbn from 'zxcvbn';
4
+
5
+/**
6
+ * Returns true if the room name is considered a weak (insecure) one.
7
+ *
8
+ * @param {string} roomName - The room name.
9
+ * @returns {boolean}
10
+ */
11
+export default function isInsecureRoomName(roomName: string = ''): boolean {
12
+    return zxcvbn(roomName).score < 3;
13
+}

+ 57
- 0
react/features/conference/components/AbstractInsecureRoomNameLabel.js Visa fil

1
+// @flow
2
+
3
+import { PureComponent } from 'react';
4
+
5
+import isInsecureRoomName from '../../base/util/isInsecureRoomName';
6
+
7
+type Props = {
8
+
9
+    /**
10
+     * True of the label should be visible.
11
+     */
12
+    _visible: boolean;
13
+
14
+    /**
15
+     * Function to be used to translate i18n labels.
16
+     */
17
+    t: Function
18
+}
19
+
20
+/**
21
+ * Abstrsact class for the {@Code InsecureRoomNameLabel} component.
22
+ */
23
+export default class AbstractInsecureRoomNameLabel extends PureComponent<Props> {
24
+    /**
25
+     * Implements {@code Component#render}.
26
+     *
27
+     * @inheritdoc
28
+     */
29
+    render() {
30
+        if (!this.props._visible) {
31
+            return null;
32
+        }
33
+
34
+        return this._render();
35
+    }
36
+
37
+    /**
38
+     * Renders the platform dependant content.
39
+     *
40
+     * @returns {ReactElement}
41
+     */
42
+    _render: () => Object;
43
+}
44
+
45
+/**
46
+ * Maps part of the Redux state to the props of this component.
47
+ *
48
+ * @param {Object} state - The Redux state.
49
+ * @returns {Props}
50
+ */
51
+export function _mapStateToProps(state: Object): $Shape<Props> {
52
+    const { room } = state['features/base/conference'];
53
+
54
+    return {
55
+        _visible: room && isInsecureRoomName(room)
56
+    };
57
+}

+ 14
- 0
react/features/conference/components/AbstractLabels.js Visa fil

10
 import { shouldDisplayTileView } from '../../video-layout';
10
 import { shouldDisplayTileView } from '../../video-layout';
11
 import { VideoQualityLabel } from '../../video-quality';
11
 import { VideoQualityLabel } from '../../video-quality';
12
 
12
 
13
+import { InsecureRoomNameLabel } from '.';
14
+
13
 /**
15
 /**
14
  * The type of the React {@code Component} props of {@link AbstractLabels}.
16
  * The type of the React {@code Component} props of {@link AbstractLabels}.
15
  */
17
  */
84
         );
86
         );
85
     }
87
     }
86
 
88
 
89
+    /**
90
+     * Renders the {@code InsecureRoomNameLabel}.
91
+     *
92
+     * @protected
93
+     * @returns {React$Element}
94
+     */
95
+    _renderInsecureRoomNameLabel() {
96
+        return (
97
+            <InsecureRoomNameLabel />
98
+        );
99
+    }
100
+
87
     /**
101
     /**
88
      * Renders the {@code VideoQualityLabel} that is platform independent.
102
      * Renders the {@code VideoQualityLabel} that is platform independent.
89
      *
103
      *

+ 36
- 0
react/features/conference/components/native/InsecureRoomNameExpandedLabel.js Visa fil

1
+// @flow
2
+
3
+import { translate } from '../../../base/i18n';
4
+import { ExpandedLabel, type Props as AbstractProps } from '../../../base/label';
5
+
6
+import { INSECURE_ROOM_NAME_LABEL_COLOR } from './styles';
7
+
8
+type Props = AbstractProps & {
9
+    t: Function
10
+}
11
+
12
+/**
13
+ * A react {@code Component} that implements an expanded label as tooltip-like
14
+ * component to explain the meaning of the {@code InsecureRoomNameExpandedLabel}.
15
+ */
16
+class InsecureRoomNameExpandedLabel extends ExpandedLabel<Props> {
17
+    /**
18
+     * Returns the color this expanded label should be rendered with.
19
+     *
20
+     * @returns {string}
21
+     */
22
+    _getColor() {
23
+        return INSECURE_ROOM_NAME_LABEL_COLOR;
24
+    }
25
+
26
+    /**
27
+     * Returns the label specific text of this {@code ExpandedLabel}.
28
+     *
29
+     * @returns {string}
30
+     */
31
+    _getLabel() {
32
+        return this.props.t('security.insecureRoomNameWarning');
33
+    }
34
+}
35
+
36
+export default translate(InsecureRoomNameExpandedLabel);

+ 31
- 0
react/features/conference/components/native/InsecureRoomNameLabel.js Visa fil

1
+// @flow
2
+
3
+import React from 'react';
4
+
5
+import { IconWarning } from '../../../base/icons';
6
+import { CircularLabel } from '../../../base/label';
7
+import { connect } from '../../../base/redux';
8
+
9
+import AbstractInsecureRoomNameLabel, { _mapStateToProps } from '../AbstractInsecureRoomNameLabel';
10
+
11
+import styles from './styles';
12
+
13
+/**
14
+ * Renders a label indicating that we are in a room with an insecure name.
15
+ */
16
+class InsecureRoomNameLabel extends AbstractInsecureRoomNameLabel {
17
+    /**
18
+     * Renders the platform dependant content.
19
+     *
20
+     * @inheritdoc
21
+     */
22
+    _render() {
23
+        return (
24
+            <CircularLabel
25
+                icon = { IconWarning }
26
+                style = { styles.insecureRoomNameLabel } />
27
+        );
28
+    }
29
+}
30
+
31
+export default connect(_mapStateToProps)(InsecureRoomNameLabel);

+ 30
- 37
react/features/conference/components/native/Labels.js Visa fil

20
     type Props as AbstractLabelsProps
20
     type Props as AbstractLabelsProps
21
 } from '../AbstractLabels';
21
 } from '../AbstractLabels';
22
 import { shouldDisplayNotifications } from '../../functions';
22
 import { shouldDisplayNotifications } from '../../functions';
23
+
24
+import InsecureRoomNameExpandedLabel from './InsecureRoomNameExpandedLabel';
23
 import styles from './styles';
25
 import styles from './styles';
24
 
26
 
25
 /**
27
 /**
32
      */
34
      */
33
     t: Function,
35
     t: Function,
34
 
36
 
35
-    /**
36
-     * The indicator which determines whether the UI is reduced (to accommodate
37
-     * smaller display areas).
38
-     *
39
-     * @private
40
-     */
41
-    _reducedUI: boolean,
42
-
43
     /**
37
     /**
44
      * True if the labels should be visible, false otherwise.
38
      * True if the labels should be visible, false otherwise.
45
      */
39
      */
85
 const LABEL_ID_RECORDING = 'recording';
79
 const LABEL_ID_RECORDING = 'recording';
86
 const LABEL_ID_STREAMING = 'streaming';
80
 const LABEL_ID_STREAMING = 'streaming';
87
 const LABEL_ID_TRANSCRIBING = 'transcribing';
81
 const LABEL_ID_TRANSCRIBING = 'transcribing';
82
+const LABEL_ID_INSECURE_ROOM_NAME = 'insecure-room-name';
88
 
83
 
89
 /**
84
 /**
90
  * The {@code ExpandedLabel} components to be rendered for the individual
85
  * The {@code ExpandedLabel} components to be rendered for the individual
104
             mode: JitsiRecordingConstants.mode.STREAM
99
             mode: JitsiRecordingConstants.mode.STREAM
105
         }
100
         }
106
     },
101
     },
107
-    transcribing: TranscribingExpandedLabel
102
+    transcribing: TranscribingExpandedLabel,
103
+    'insecure-room-name': InsecureRoomNameExpandedLabel
108
 };
104
 };
109
 
105
 
110
 /**
106
 /**
159
         }
155
         }
160
 
156
 
161
         const wide = !isNarrowAspectRatio(this);
157
         const wide = !isNarrowAspectRatio(this);
162
-        const { _filmstripVisible, _reducedUI } = this.props;
158
+        const { _filmstripVisible } = this.props;
163
 
159
 
164
         return (
160
         return (
165
             <View
161
             <View
200
                             this._renderTranscribingLabel()
196
                             this._renderTranscribingLabel()
201
                         }
197
                         }
202
                     </TouchableOpacity>
198
                     </TouchableOpacity>
203
-                    {/*
204
-                      * Emil, Lyubomir, Nichole, and Zoli said that the Labels
205
-                      * should not be rendered in Picture-in-Picture. Saul
206
-                      * argued that the recording Labels should be rendered. As
207
-                      * a temporary compromise, don't render the
208
-                      * VideoQualityLabel at least because it's not that
209
-                      * important.
210
-                      */
211
-                        _reducedUI || (
212
-                            <TouchableOpacity
213
-                                onLayout = {
214
-                                    this._createOnLayout(LABEL_ID_QUALITY) }
215
-                                onPress = {
216
-                                    this._createOnPress(LABEL_ID_QUALITY) } >
217
-                                { this._renderVideoQualityLabel() }
218
-                            </TouchableOpacity>
219
-                        )
220
-                    }
199
+                    <TouchableOpacity
200
+                        onLayout = {
201
+                            this._createOnLayout(LABEL_ID_INSECURE_ROOM_NAME)
202
+                        }
203
+                        onPress = {
204
+                            this._createOnPress(LABEL_ID_INSECURE_ROOM_NAME)
205
+                        } >
206
+                        {
207
+                            this._renderInsecureRoomNameLabel()
208
+                        }
209
+                    </TouchableOpacity>
210
+                    <TouchableOpacity
211
+                        onLayout = {
212
+                            this._createOnLayout(LABEL_ID_QUALITY) }
213
+                        onPress = {
214
+                            this._createOnPress(LABEL_ID_QUALITY) } >
215
+                        { this._renderVideoQualityLabel() }
216
+                    </TouchableOpacity>
221
                 </View>
217
                 </View>
222
                 <View
218
                 <View
223
                     style = { [
219
                     style = { [
339
         return null;
335
         return null;
340
     }
336
     }
341
 
337
 
342
-    _renderRecordingLabel: string => React$Element<*>;
338
+    _renderRecordingLabel: string => React$Element<any>;
339
+
340
+    _renderTranscribingLabel: () => React$Element<any>;
343
 
341
 
344
-    _renderTranscribingLabel: () => React$Element<*>
342
+    _renderInsecureRoomNameLabel: () => React$Element<any>;
345
 
343
 
346
-    _renderVideoQualityLabel: () => React$Element<*>;
344
+    _renderVideoQualityLabel: () => React$Element<any>;
347
 }
345
 }
348
 
346
 
349
 /**
347
 /**
352
  *
350
  *
353
  * @param {Object} state - The redux state.
351
  * @param {Object} state - The redux state.
354
  * @private
352
  * @private
355
- * @returns {{
356
- *     _filmstripVisible: boolean,
357
- *     _reducedUI: boolean,
358
- *     _visible: boolean
359
- * }}
353
+ * @returns {Props}
360
  */
354
  */
361
 function _mapStateToProps(state) {
355
 function _mapStateToProps(state) {
362
     return {
356
     return {
363
         ..._abstractMapStateToProps(state),
357
         ..._abstractMapStateToProps(state),
364
-        _reducedUI: state['features/base/responsive-ui'].reducedUI,
365
         _visible: !shouldDisplayNotifications(state)
358
         _visible: !shouldDisplayNotifications(state)
366
     };
359
     };
367
 }
360
 }

+ 1
- 0
react/features/conference/components/native/index.js Visa fil

2
 
2
 
3
 export { default as Conference } from './Conference';
3
 export { default as Conference } from './Conference';
4
 export { default as renderConferenceTimer } from './ConferenceTimerDisplay';
4
 export { default as renderConferenceTimer } from './ConferenceTimerDisplay';
5
+export { default as InsecureRoomNameLabel } from './InsecureRoomNameLabel';

+ 5
- 0
react/features/conference/components/native/styles.js Visa fil

3
 import { FILMSTRIP_SIZE } from '../../../filmstrip';
3
 import { FILMSTRIP_SIZE } from '../../../filmstrip';
4
 
4
 
5
 export const NAVBAR_GRADIENT_COLORS = [ '#000000FF', '#00000000' ];
5
 export const NAVBAR_GRADIENT_COLORS = [ '#000000FF', '#00000000' ];
6
+export const INSECURE_ROOM_NAME_LABEL_COLOR = ColorPalette.warning;
6
 
7
 
7
 // From brand guideline
8
 // From brand guideline
8
 const BOTTOM_GRADIENT_HEIGHT = 290;
9
 const BOTTOM_GRADIENT_HEIGHT = 290;
167
         // On iPhone X there is the notch. In the two cases BoxModel.margin is
168
         // On iPhone X there is the notch. In the two cases BoxModel.margin is
168
         // not enough.
169
         // not enough.
169
         top: BoxModel.margin * 3
170
         top: BoxModel.margin * 3
171
+    },
172
+
173
+    insecureRoomNameLabel: {
174
+        backgroundColor: INSECURE_ROOM_NAME_LABEL_COLOR
170
     }
175
     }
171
 };
176
 };
172
 
177
 

+ 35
- 0
react/features/conference/components/web/InsecureRoomNameLabel.js Visa fil

1
+// @flow
2
+
3
+import Tooltip from '@atlaskit/tooltip';
4
+import React from 'react';
5
+
6
+import { translate } from '../../../base/i18n';
7
+import { IconWarning } from '../../../base/icons';
8
+import { CircularLabel } from '../../../base/label';
9
+import { connect } from '../../../base/redux';
10
+
11
+import AbstractInsecureRoomNameLabel, { _mapStateToProps } from '../AbstractInsecureRoomNameLabel';
12
+
13
+/**
14
+ * Renders a label indicating that we are in a room with an insecure name.
15
+ */
16
+class InsecureRoomNameLabel extends AbstractInsecureRoomNameLabel {
17
+    /**
18
+     * Renders the platform dependant content.
19
+     *
20
+     * @inheritdoc
21
+     */
22
+    _render() {
23
+        return (
24
+            <Tooltip
25
+                content = { this.props.t('security.insecureRoomNameWarning') }
26
+                position = 'left'>
27
+                <CircularLabel
28
+                    className = 'insecure'
29
+                    icon = { IconWarning } />
30
+            </Tooltip>
31
+        );
32
+    }
33
+}
34
+
35
+export default translate(connect(_mapStateToProps)(InsecureRoomNameLabel));

+ 5
- 0
react/features/conference/components/web/Labels.js Visa fil

95
                     this.props._showVideoQualityLabel
95
                     this.props._showVideoQualityLabel
96
                         && this._renderVideoQualityLabel()
96
                         && this._renderVideoQualityLabel()
97
                 }
97
                 }
98
+                {
99
+                    this._renderInsecureRoomNameLabel()
100
+                }
98
             </div>
101
             </div>
99
         );
102
         );
100
     }
103
     }
107
 
110
 
108
     _renderTranscribingLabel: () => React$Element<*>;
111
     _renderTranscribingLabel: () => React$Element<*>;
109
 
112
 
113
+    _renderInsecureRoomNameLabel: () => React$Element<any>;
114
+
110
     _renderVideoQualityLabel: () => React$Element<*>;
115
     _renderVideoQualityLabel: () => React$Element<*>;
111
 }
116
 }
112
 
117
 

+ 1
- 1
react/features/conference/components/web/index.js Visa fil

2
 
2
 
3
 export { default as Conference } from './Conference';
3
 export { default as Conference } from './Conference';
4
 export { default as renderConferenceTimer } from './ConferenceTimerDisplay';
4
 export { default as renderConferenceTimer } from './ConferenceTimerDisplay';
5
-
5
+export { default as InsecureRoomNameLabel } from './InsecureRoomNameLabel';

+ 29
- 1
react/features/welcome/components/AbstractWelcomePage.js Visa fil

6
 
6
 
7
 import { createWelcomePageEvent, sendAnalytics } from '../../analytics';
7
 import { createWelcomePageEvent, sendAnalytics } from '../../analytics';
8
 import { appNavigate } from '../../app';
8
 import { appNavigate } from '../../app';
9
+import isInsecureRoomName from '../../base/util/isInsecureRoomName';
9
 import { isCalendarEnabled } from '../../calendar-sync';
10
 import { isCalendarEnabled } from '../../calendar-sync';
10
 import { isRecentListEnabled } from '../../recent-list/functions';
11
 import { isRecentListEnabled } from '../../recent-list/functions';
11
 
12
 
75
     state = {
76
     state = {
76
         animateTimeoutId: undefined,
77
         animateTimeoutId: undefined,
77
         generatedRoomname: '',
78
         generatedRoomname: '',
79
+        insecureRoomName: false,
78
         joining: false,
80
         joining: false,
79
         room: '',
81
         room: '',
80
         roomPlaceholder: '',
82
         roomPlaceholder: '',
95
             = this._animateRoomnameChanging.bind(this);
97
             = this._animateRoomnameChanging.bind(this);
96
         this._onJoin = this._onJoin.bind(this);
98
         this._onJoin = this._onJoin.bind(this);
97
         this._onRoomChange = this._onRoomChange.bind(this);
99
         this._onRoomChange = this._onRoomChange.bind(this);
100
+        this._renderInsecureRoomNameWarning = this._renderInsecureRoomNameWarning.bind(this);
98
         this._updateRoomname = this._updateRoomname.bind(this);
101
         this._updateRoomname = this._updateRoomname.bind(this);
99
     }
102
     }
100
 
103
 
160
         clearTimeout(this.state.updateTimeoutId);
163
         clearTimeout(this.state.updateTimeoutId);
161
     }
164
     }
162
 
165
 
166
+    /**
167
+     * Renders the insecure room name warning.
168
+     *
169
+     * @returns {ReactElement}
170
+     */
171
+    _doRenderInsecureRoomNameWarning: () => React$Component<any>;
172
+
163
     _onJoin: () => void;
173
     _onJoin: () => void;
164
 
174
 
165
     /**
175
     /**
202
      * @returns {void}
212
      * @returns {void}
203
      */
213
      */
204
     _onRoomChange(value: string) {
214
     _onRoomChange(value: string) {
205
-        this.setState({ room: value });
215
+        this.setState({
216
+            room: value,
217
+            insecureRoomName: value && isInsecureRoomName(value)
218
+        });
219
+    }
220
+
221
+    _renderInsecureRoomNameWarning: () => React$Component<any>;;
222
+
223
+    /**
224
+     * Renders the insecure room name warning if needed.
225
+     *
226
+     * @returns {ReactElement}
227
+     */
228
+    _renderInsecureRoomNameWarning() {
229
+        if (this.state.insecureRoomName) {
230
+            return this._doRenderInsecureRoomNameWarning();
231
+        }
232
+
233
+        return null;
206
     }
234
     }
207
 
235
 
208
     _updateRoomname: () => void;
236
     _updateRoomname: () => void;

+ 27
- 1
react/features/welcome/components/WelcomePage.native.js Visa fil

13
 
13
 
14
 import { ColorSchemeRegistry } from '../../base/color-scheme';
14
 import { ColorSchemeRegistry } from '../../base/color-scheme';
15
 import { translate } from '../../base/i18n';
15
 import { translate } from '../../base/i18n';
16
-import { Icon, IconMenu } from '../../base/icons';
16
+import { Icon, IconMenu, IconWarning } from '../../base/icons';
17
 import { MEDIA_TYPE } from '../../base/media';
17
 import { MEDIA_TYPE } from '../../base/media';
18
 import { Header, LoadingIndicator, Text } from '../../base/react';
18
 import { Header, LoadingIndicator, Text } from '../../base/react';
19
 import { connect } from '../../base/redux';
19
 import { connect } from '../../base/redux';
119
         return this._renderFullUI();
119
         return this._renderFullUI();
120
     }
120
     }
121
 
121
 
122
+    /**
123
+     * Renders the insecure room name warning.
124
+     *
125
+     * @inheritdoc
126
+     */
127
+    _doRenderInsecureRoomNameWarning() {
128
+        return (
129
+            <View
130
+                style = { [
131
+                    styles.messageContainer,
132
+                    styles.insecureRoomNameWarningContainer
133
+                ] }>
134
+                <Icon
135
+                    src = { IconWarning }
136
+                    style = { styles.insecureRoomNameWarningIcon } />
137
+                <Text style = { styles.insecureRoomNameWarningText }>
138
+                    { this.props.t('security.insecureRoomNameWarning') }
139
+                </Text>
140
+            </View>
141
+        );
142
+    }
143
+
122
     /**
144
     /**
123
      * Constructs a style array to handle the hint box animation.
145
      * Constructs a style array to handle the hint box animation.
124
      *
146
      *
127
      */
149
      */
128
     _getHintBoxStyle() {
150
     _getHintBoxStyle() {
129
         return [
151
         return [
152
+            styles.messageContainer,
130
             styles.hintContainer,
153
             styles.hintContainer,
131
             {
154
             {
132
                 opacity: this.state.hintBoxAnimation
155
                 opacity: this.state.hintBoxAnimation
283
                                 style = { styles.textInput }
306
                                 style = { styles.textInput }
284
                                 underlineColorAndroid = 'transparent'
307
                                 underlineColorAndroid = 'transparent'
285
                                 value = { this.state.room } />
308
                                 value = { this.state.room } />
309
+                            {
310
+                                this._renderInsecureRoomNameWarning()
311
+                            }
286
                             {
312
                             {
287
                                 this._renderHintBox()
313
                                 this._renderHintBox()
288
                             }
314
                             }

+ 18
- 0
react/features/welcome/components/WelcomePage.web.js Visa fil

3
 import React from 'react';
3
 import React from 'react';
4
 
4
 
5
 import { translate } from '../../base/i18n';
5
 import { translate } from '../../base/i18n';
6
+import { Icon, IconWarning } from '../../base/icons';
6
 import { Watermarks } from '../../base/react';
7
 import { Watermarks } from '../../base/react';
7
 import { connect } from '../../base/redux';
8
 import { connect } from '../../base/redux';
8
 import { isMobileBrowser } from '../../base/environment/utils';
9
 import { isMobileBrowser } from '../../base/environment/utils';
209
                                     title = { t('welcomepage.roomNameAllowedChars') }
210
                                     title = { t('welcomepage.roomNameAllowedChars') }
210
                                     type = 'text'
211
                                     type = 'text'
211
                                     value = { this.state.room } />
212
                                     value = { this.state.room } />
213
+                                { this._renderInsecureRoomNameWarning() }
212
                             </form>
214
                             </form>
213
                         </div>
215
                         </div>
214
                         <div
216
                         <div
233
         );
235
         );
234
     }
236
     }
235
 
237
 
238
+    /**
239
+     * Renders the insecure room name warning.
240
+     *
241
+     * @inheritdoc
242
+     */
243
+    _doRenderInsecureRoomNameWarning() {
244
+        return (
245
+            <div className = 'insecure-room-name-warning'>
246
+                <Icon src = { IconWarning } />
247
+                <span>
248
+                    { this.props.t('security.insecureRoomNameWarning') }
249
+                </span>
250
+            </div>
251
+        );
252
+    }
253
+
236
     /**
254
     /**
237
      * Prevents submission of the form and delegates join logic.
255
      * Prevents submission of the form and delegates join logic.
238
      *
256
      *

+ 28
- 8
react/features/welcome/components/styles.js Visa fil

108
      * Container for the hint box.
108
      * Container for the hint box.
109
      */
109
      */
110
     hintContainer: {
110
     hintContainer: {
111
-        backgroundColor: ColorPalette.white,
112
-        borderColor: ColorPalette.white,
113
-        borderRadius: 4,
114
-        borderWidth: 1,
115
         flexDirection: 'column',
111
         flexDirection: 'column',
116
-        marginVertical: 5,
117
-        overflow: 'hidden',
118
-        paddingHorizontal: BoxModel.padding,
119
-        paddingVertical: 2 * BoxModel.padding
112
+        overflow: 'hidden'
120
     },
113
     },
121
 
114
 
122
     /**
115
     /**
148
         padding: BoxModel.padding
141
         padding: BoxModel.padding
149
     },
142
     },
150
 
143
 
144
+    messageContainer: {
145
+        backgroundColor: ColorPalette.white,
146
+        borderColor: ColorPalette.white,
147
+        borderRadius: 4,
148
+        borderWidth: 1,
149
+        marginVertical: 5,
150
+        paddingHorizontal: BoxModel.padding,
151
+        paddingVertical: 2 * BoxModel.padding
152
+    },
153
+
151
     /**
154
     /**
152
      * The style of the top-level container/{@code View} of
155
      * The style of the top-level container/{@code View} of
153
      * {@code LocalVideoTrackUnderlay}.
156
      * {@code LocalVideoTrackUnderlay}.
280
         textAlign: 'center'
283
         textAlign: 'center'
281
     },
284
     },
282
 
285
 
286
+    insecureRoomNameWarningContainer: {
287
+        alignItems: 'center',
288
+        flexDirection: 'row',
289
+        paddingHorizontal: 5
290
+    },
291
+
292
+    insecureRoomNameWarningIcon: {
293
+        color: ColorPalette.warning,
294
+        fontSize: 24,
295
+        marginRight: 10
296
+    },
297
+
298
+    insecureRoomNameWarningText: {
299
+        color: ColorPalette.warning,
300
+        flex: 1
301
+    },
302
+
283
     /**
303
     /**
284
      * The style of the top-level container of {@code WelcomePage}.
304
      * The style of the top-level container of {@code WelcomePage}.
285
      */
305
      */

+ 1
- 1
webpack.config.js Visa fil

179
         entry: {
179
         entry: {
180
             'app.bundle': './app.js'
180
             'app.bundle': './app.js'
181
         },
181
         },
182
-        performance: getPerformanceHints(3 * 1024 * 1024)
182
+        performance: getPerformanceHints(4 * 1024 * 1024)
183
     }),
183
     }),
184
     Object.assign({}, config, {
184
     Object.assign({}, config, {
185
         entry: {
185
         entry: {

Laddar…
Avbryt
Spara