diff --git a/app/actions/actionsTypes.js b/app/actions/actionsTypes.js
index 0790b7bad..70555acb8 100644
--- a/app/actions/actionsTypes.js
+++ b/app/actions/actionsTypes.js
@@ -53,8 +53,6 @@ export const LOGOUT = 'LOGOUT'; // logout is always success
export const SNIPPETED_MESSAGES = createRequestTypes('SNIPPETED_MESSAGES', ['OPEN', 'READY', 'CLOSE', 'MESSAGES_RECEIVED']);
export const DEEP_LINKING = createRequestTypes('DEEP_LINKING', ['OPEN']);
export const SORT_PREFERENCES = createRequestTypes('SORT_PREFERENCES', ['SET_ALL', 'SET']);
-export const TOGGLE_CRASH_REPORT = 'TOGGLE_CRASH_REPORT';
-export const TOGGLE_ANALYTICS_EVENTS = 'TOGGLE_ANALYTICS_EVENTS';
export const SET_CUSTOM_EMOJIS = 'SET_CUSTOM_EMOJIS';
export const SET_ACTIVE_USERS = 'SET_ACTIVE_USERS';
export const USERS_TYPING = createRequestTypes('USERS_TYPING', ['ADD', 'REMOVE', 'CLEAR']);
diff --git a/app/actions/crashReport.js b/app/actions/crashReport.js
deleted file mode 100644
index 8577b33e7..000000000
--- a/app/actions/crashReport.js
+++ /dev/null
@@ -1,15 +0,0 @@
-import * as types from './actionsTypes';
-
-export function toggleCrashReport(value) {
- return {
- type: types.TOGGLE_CRASH_REPORT,
- payload: value
- };
-}
-
-export function toggleAnalyticsEvents(value) {
- return {
- type: types.TOGGLE_ANALYTICS_EVENTS,
- payload: value
- };
-}
diff --git a/app/containers/UIKit/MultiSelect/index.js b/app/containers/UIKit/MultiSelect/index.js
index 0d366b6d7..d1e42aaa5 100644
--- a/app/containers/UIKit/MultiSelect/index.js
+++ b/app/containers/UIKit/MultiSelect/index.js
@@ -157,7 +157,7 @@ export const MultiSelect = React.memo(({
disabled={disabled}
inputStyle={inputStyle}
>
- {items.length ? : {placeholder.text}}
+ {items.length ? (disabled ? {} : onSelect(item))} theme={theme} /> : {placeholder.text}}
);
}
diff --git a/app/index.js b/app/index.js
index efcf1557e..54985c3c5 100644
--- a/app/index.js
+++ b/app/index.js
@@ -19,7 +19,7 @@ import { deepLinkingOpen } from './actions/deepLinking';
import parseQuery from './lib/methods/helpers/parseQuery';
import { initializePushNotifications, onNotification } from './notifications/push';
import store from './lib/createStore';
-import { loggerConfig, analytics } from './utils/log';
+import { toggleAnalyticsEventsReport, toggleCrashErrorsReport } from './utils/log';
import { ThemeContext } from './theme';
import { DimensionsContext } from './dimensions';
import RocketChat, { THEME_PREFERENCES_KEY } from './lib/rocketchat';
@@ -188,11 +188,11 @@ export default class Root extends React.Component {
initCrashReport = () => {
RocketChat.getAllowCrashReport()
.then((allowCrashReport) => {
- if (!allowCrashReport) {
- loggerConfig.autoNotify = false;
- loggerConfig.registerBeforeSendCallback(() => false);
- analytics().setAnalyticsCollectionEnabled(false);
- }
+ toggleCrashErrorsReport(allowCrashReport);
+ });
+ RocketChat.getAllowAnalyticsEvents()
+ .then((allowAnalyticsEvents) => {
+ toggleAnalyticsEventsReport(allowAnalyticsEvents);
});
}
diff --git a/app/lib/methods/getPermissions.js b/app/lib/methods/getPermissions.js
index 1c4c56b46..764b725e0 100644
--- a/app/lib/methods/getPermissions.js
+++ b/app/lib/methods/getPermissions.js
@@ -48,7 +48,9 @@ const PERMISSIONS = [
'view-user-administration',
'view-all-teams',
'view-all-team-channels',
- 'convert-team'
+ 'convert-team',
+ 'edit-omnichannel-contact',
+ 'edit-livechat-room-customfields'
];
export async function setPermissions() {
diff --git a/app/reducers/crashReport.js b/app/reducers/crashReport.js
deleted file mode 100644
index 8465897e3..000000000
--- a/app/reducers/crashReport.js
+++ /dev/null
@@ -1,25 +0,0 @@
-import { TOGGLE_CRASH_REPORT, TOGGLE_ANALYTICS_EVENTS } from '../actions/actionsTypes';
-
-const initialState = {
- allowCrashReport: false,
- allowAnalyticsEvents: false
-};
-
-
-export default (state = initialState, action) => {
- switch (action.type) {
- case TOGGLE_CRASH_REPORT:
- return {
- ...state,
- allowCrashReport: action.payload
- };
-
- case TOGGLE_ANALYTICS_EVENTS:
- return {
- ...state,
- allowAnalyticsEvents: action.payload
- };
- default:
- return state;
- }
-};
diff --git a/app/reducers/index.js b/app/reducers/index.js
index eb8f09d82..c0f5a9953 100644
--- a/app/reducers/index.js
+++ b/app/reducers/index.js
@@ -10,7 +10,6 @@ import createChannel from './createChannel';
import app from './app';
import sortPreferences from './sortPreferences';
import share from './share';
-import crashReport from './crashReport';
import customEmojis from './customEmojis';
import activeUsers from './activeUsers';
import usersTyping from './usersTyping';
@@ -35,7 +34,6 @@ export default combineReducers({
rooms,
sortPreferences,
share,
- crashReport,
customEmojis,
activeUsers,
usersTyping,
diff --git a/app/sagas/init.js b/app/sagas/init.js
index 57bc33423..f8cce6804 100644
--- a/app/sagas/init.js
+++ b/app/sagas/init.js
@@ -4,7 +4,6 @@ import RNBootSplash from 'react-native-bootsplash';
import UserPreferences from '../lib/userPreferences';
import { selectServerRequest } from '../actions/server';
import { setAllPreferences } from '../actions/sortPreferences';
-import { toggleCrashReport, toggleAnalyticsEvents } from '../actions/crashReport';
import { APP } from '../actions/actionsTypes';
import RocketChat from '../lib/rocketchat';
import log from '../utils/log';
@@ -15,12 +14,6 @@ import { appStart, ROOT_OUTSIDE, appReady } from '../actions/app';
export const initLocalSettings = function* initLocalSettings() {
const sortPreferences = yield RocketChat.getSortPreferences();
yield put(setAllPreferences(sortPreferences));
-
- const allowCrashReport = yield RocketChat.getAllowCrashReport();
- yield put(toggleCrashReport(allowCrashReport));
-
- const allowAnalyticsEvents = yield RocketChat.getAllowAnalyticsEvents();
- yield put(toggleAnalyticsEvents(allowAnalyticsEvents));
};
const restore = function* restore() {
diff --git a/app/utils/log/index.js b/app/utils/log/index.js
index 361ce7055..266f4bd44 100644
--- a/app/utils/log/index.js
+++ b/app/utils/log/index.js
@@ -5,10 +5,24 @@ import events from './events';
const analytics = firebaseAnalytics || '';
let bugsnag = '';
let crashlytics;
+let reportCrashErrors = true;
+let reportAnalyticsEvents = true;
+
+export const getReportCrashErrorsValue = () => reportCrashErrors;
+export const getReportAnalyticsEventsValue = () => reportAnalyticsEvents;
+
if (!isFDroidBuild) {
bugsnag = require('@bugsnag/react-native').default;
- bugsnag.start();
+ bugsnag.start({
+ onBreadcrumb() {
+ return reportAnalyticsEvents;
+ },
+ onError(error) {
+ if (!reportAnalyticsEvents) { error.breadcrumbs = []; }
+ return reportCrashErrors;
+ }
+ });
crashlytics = require('@react-native-firebase/crashlytics').default;
}
@@ -42,6 +56,16 @@ export const setCurrentScreen = (currentScreen) => {
}
};
+export const toggleCrashErrorsReport = (value) => {
+ crashlytics().setCrashlyticsCollectionEnabled(value);
+ return reportCrashErrors = value;
+};
+
+export const toggleAnalyticsEventsReport = (value) => {
+ analytics().setAnalyticsCollectionEnabled(value);
+ return reportAnalyticsEvents = value;
+};
+
export default (e) => {
if (e instanceof Error && bugsnag && e.message !== 'Aborted' && !__DEV__) {
bugsnag.notify(e, (event) => {
diff --git a/app/views/LivechatEditView.js b/app/views/LivechatEditView.js
index 6ba4143e7..d5bae1a15 100644
--- a/app/views/LivechatEditView.js
+++ b/app/views/LivechatEditView.js
@@ -2,6 +2,7 @@ import React, { useState, useEffect } from 'react';
import PropTypes from 'prop-types';
import { Text, StyleSheet, ScrollView } from 'react-native';
import { connect } from 'react-redux';
+import { BLOCK_CONTEXT } from '@rocket.chat/ui-kit';
import { withTheme } from '../theme';
import { themes } from '../constants/colors';
@@ -15,9 +16,9 @@ import { LISTENER } from '../containers/Toast';
import EventEmitter from '../utils/events';
import scrollPersistTaps from '../utils/scrollPersistTaps';
import { getUserSelector } from '../selectors/login';
-import Chips from '../containers/UIKit/MultiSelect/Chips';
import Button from '../containers/Button';
import SafeAreaView from '../containers/SafeAreaView';
+import { MultiSelect } from '../containers/UIKit/MultiSelect';
const styles = StyleSheet.create({
container: {
@@ -27,6 +28,14 @@ const styles = StyleSheet.create({
fontSize: 20,
paddingVertical: 10,
...sharedStyles.textMedium
+ },
+ label: {
+ marginBottom: 10,
+ fontSize: 14,
+ ...sharedStyles.textSemibold
+ },
+ multiSelect: {
+ marginBottom: 10
}
});
@@ -37,10 +46,11 @@ Title.propTypes = {
};
const LivechatEditView = ({
- user, navigation, route, theme
+ user, navigation, route, theme, editOmnichannelContact, editLivechatRoomCustomfields
}) => {
const [customFields, setCustomFields] = useState({});
const [availableUserTags, setAvailableUserTags] = useState([]);
+ const [permissions, setPermissions] = useState([]);
const params = {};
const inputs = {};
@@ -54,21 +64,24 @@ const LivechatEditView = ({
const visitorCustomFields = result.customFields
.filter(field => field.visibility !== 'hidden' && field.scope === 'visitor')
.map(field => ({ [field._id]: (visitor.livechatData && visitor.livechatData[field._id]) || '' }))
- .reduce((ret, field) => ({ [field]: field, ...ret }));
+ .reduce((ret, field) => ({ ...field, ...ret }));
const livechatCustomFields = result.customFields
.filter(field => field.visibility !== 'hidden' && field.scope === 'room')
.map(field => ({ [field._id]: (livechat.livechatData && livechat.livechatData[field._id]) || '' }))
- .reduce((ret, field) => ({ [field]: field, ...ret }));
+ .reduce((ret, field) => ({ ...field, ...ret }));
return setCustomFields({ visitor: visitorCustomFields, livechat: livechatCustomFields });
}
};
const [tagParam, setTags] = useState(livechat?.tags || []);
+ const [tagParamSelected, setTagParamSelected] = useState(livechat?.tags || []);
useEffect(() => {
- setTags([...tagParam, ...availableUserTags]);
+ const arr = [...tagParam, ...availableUserTags];
+ const uniqueArray = arr.filter((val, i) => arr.indexOf(val) === i);
+ setTags(uniqueArray);
}, [availableUserTags]);
const getTagsList = async(agentDepartments) => {
@@ -115,7 +128,7 @@ const LivechatEditView = ({
roomData.topic = params.topic;
}
- roomData.tags = tagParam;
+ roomData.tags = tagParamSelected;
roomData.livechatData = {};
Object.entries(customFields?.livechat || {}).forEach(([key]) => {
@@ -139,9 +152,15 @@ const LivechatEditView = ({
const onChangeText = (key, text) => { params[key] = text; };
+ const getPermissions = async() => {
+ const permissionsArray = await RocketChat.hasPermission([editOmnichannelContact, editLivechatRoomCustomfields], livechat.rid);
+ setPermissions(permissionsArray);
+ };
+
useEffect(() => {
getAgentDepartments();
getCustomFields();
+ getPermissions();
}, []);
return (
@@ -162,6 +181,7 @@ const LivechatEditView = ({
onChangeText={text => onChangeText('name', text)}
onSubmitEditing={() => { inputs.name.focus(); }}
theme={theme}
+ editable={!!permissions[0]}
/>
onChangeText('email', text)}
onSubmitEditing={() => { inputs.phone.focus(); }}
theme={theme}
+ editable={!!permissions[0]}
/>
{
const keys = Object.keys(customFields?.visitor || {});
if (keys.length > 0) {
- const key = keys.pop();
+ const key = keys[0];
inputs[key].focus();
} else {
inputs.topic.focus();
}
}}
theme={theme}
+ editable={!!permissions[0]}
/>
{Object.entries(customFields?.visitor || {}).map(([key, value], index, array) => (
onChangeText(key, text)}
onSubmitEditing={() => {
if (array.length - 1 > index) {
- return inputs[array[index + 1]].focus();
+ return inputs[array[index + 1][0]].focus();
}
inputs.topic.focus();
}}
theme={theme}
+ editable={!!permissions[0]}
/>
))}
onChangeText('topic', text)}
onSubmitEditing={() => inputs.tags.focus()}
theme={theme}
+ editable={!!permissions[1]}
/>
- { inputs.tags = e; }}
- label={I18n.t('Tags')}
- iconRight='add'
- onIconRightPress={() => {
- const lastText = inputs.tags._lastNativeText || '';
- if (lastText.length) {
- setTags([...tagParam.filter(t => t !== lastText), lastText]);
- inputs.tags.clear();
- }
- }}
- onSubmitEditing={() => {
- const keys = Object.keys(customFields?.livechat || {});
- if (keys.length > 0) {
- const key = keys.pop();
- inputs[key].focus();
- } else {
- submit();
- }
+
+ { I18n.t('Tags') }
+
+ ({ text: { text: tag }, value: tag }))}
+ onChange={({ value }) => {
+ setTagParamSelected([...value]);
}}
+ placeholder={{ text: I18n.t('Tags') }}
+ value={tagParamSelected}
+ context={BLOCK_CONTEXT.FORM}
+ multiselect
theme={theme}
- />
- ({ text: { text: tag }, value: tag }))}
- onSelect={tag => setTags(tagParam.filter(t => t !== tag.value) || [])}
- style={{ backgroundColor: themes[theme].backgroundColor }}
- theme={theme}
+ disabled={!permissions[1]}
+ inputStyle={styles.multiSelect}
/>
{Object.entries(customFields?.livechat || {}).map(([key, value], index, array) => (
@@ -257,6 +274,7 @@ const LivechatEditView = ({
submit();
}}
theme={theme}
+ editable={!!permissions[1]}
/>
))}
@@ -274,15 +292,19 @@ LivechatEditView.propTypes = {
user: PropTypes.object,
navigation: PropTypes.object,
route: PropTypes.object,
- theme: PropTypes.string
+ theme: PropTypes.string,
+ editOmnichannelContact: PropTypes.array,
+ editLivechatRoomCustomfields: PropTypes.array
};
LivechatEditView.navigationOptions = ({
- title: I18n.t('Livechat_edit')
+ title: I18n.t('Edit')
});
const mapStateToProps = state => ({
server: state.server.server,
- user: getUserSelector(state)
+ user: getUserSelector(state),
+ editOmnichannelContact: state.permissions['edit-omnichannel-contact'],
+ editLivechatRoomCustomfields: state.permissions['edit-livechat-room-customfields']
});
export default connect(mapStateToProps)(withTheme(LivechatEditView));
diff --git a/app/views/RoomInfoView/index.js b/app/views/RoomInfoView/index.js
index a966463bf..6d0918f16 100644
--- a/app/views/RoomInfoView/index.js
+++ b/app/views/RoomInfoView/index.js
@@ -55,6 +55,8 @@ class RoomInfoView extends React.Component {
isMasterDetail: PropTypes.bool,
jitsiEnabled: PropTypes.bool,
editRoomPermission: PropTypes.array,
+ editOmnichannelContact: PropTypes.array,
+ editLivechatRoomCustomfields: PropTypes.array,
roles: PropTypes.array
}
@@ -184,7 +186,9 @@ class RoomInfoView extends React.Component {
loadRoom = async() => {
const { room: roomState } = this.state;
- const { route, editRoomPermission } = this.props;
+ const {
+ route, editRoomPermission, editOmnichannelContact, editLivechatRoomCustomfields
+ } = this.props;
let room = route.params?.room;
if (room && room.observe) {
this.roomObservable = room.observe();
@@ -204,8 +208,10 @@ class RoomInfoView extends React.Component {
}
}
- const permissions = await RocketChat.hasPermission([editRoomPermission], room.rid);
- if (permissions[0]) {
+ const permissionToEdit = this.isLivechat ? [editOmnichannelContact, editLivechatRoomCustomfields] : [editRoomPermission];
+
+ const permissions = await RocketChat.hasPermission(permissionToEdit, room.rid);
+ if (permissions.some(Boolean)) {
this.setState({ showEdit: true }, () => this.setHeader());
}
}
@@ -370,6 +376,8 @@ const mapStateToProps = state => ({
isMasterDetail: state.app.isMasterDetail,
jitsiEnabled: state.settings.Jitsi_Enabled || false,
editRoomPermission: state.permissions['edit-room'],
+ editOmnichannelContact: state.permissions['edit-omnichannel-contact'],
+ editLivechatRoomCustomfields: state.permissions['edit-livechat-room-customfields'],
roles: state.roles
});
diff --git a/app/views/RoomView/index.js b/app/views/RoomView/index.js
index d6e94a9a0..d03d4488a 100644
--- a/app/views/RoomView/index.js
+++ b/app/views/RoomView/index.js
@@ -739,7 +739,7 @@ class RoomView extends React.Component {
const { room } = this.state;
if (rid === this.rid) {
Navigation.navigate('RoomsListView');
- showErrorAlert(I18n.t('You_were_removed_from_channel', { channel: RocketChat.getRoomTitle(room) }), I18n.t('Oops'));
+ !this.isOmnichannel && showErrorAlert(I18n.t('You_were_removed_from_channel', { channel: RocketChat.getRoomTitle(room) }), I18n.t('Oops'));
}
}
@@ -786,6 +786,7 @@ class RoomView extends React.Component {
if (this.isOmnichannel) {
await takeInquiry(room._id);
+ this.onJoin();
} else {
const { joinCodeRequired } = room;
if (joinCodeRequired) {
diff --git a/app/views/SecurityPrivacyView.js b/app/views/SecurityPrivacyView.js
index 937a02504..a21ae00fd 100644
--- a/app/views/SecurityPrivacyView.js
+++ b/app/views/SecurityPrivacyView.js
@@ -1,158 +1,119 @@
-import React from 'react';
+import React, { useEffect, useState } from 'react';
import { Switch } from 'react-native';
import PropTypes from 'prop-types';
-import { connect } from 'react-redux';
import AsyncStorage from '@react-native-community/async-storage';
+import { useSelector } from 'react-redux';
-import { toggleCrashReport as toggleCrashReportAction, toggleAnalyticsEvents as toggleAnalyticsEventsAction } from '../actions/crashReport';
import { SWITCH_TRACK_COLOR } from '../constants/colors';
import StatusBar from '../containers/StatusBar';
import * as List from '../containers/List';
import I18n from '../i18n';
import { CRASH_REPORT_KEY, ANALYTICS_EVENTS_KEY } from '../lib/rocketchat';
import {
- loggerConfig, analytics, logEvent, events
+ logEvent, events, toggleCrashErrorsReport, toggleAnalyticsEventsReport, getReportCrashErrorsValue, getReportAnalyticsEventsValue
} from '../utils/log';
import SafeAreaView from '../containers/SafeAreaView';
import { isFDroidBuild } from '../constants/environment';
-import { getUserSelector } from '../selectors/login';
-class SecurityPrivacyView extends React.Component {
- static navigationOptions = () => ({
- title: I18n.t('Security_and_privacy')
- });
+const SecurityPrivacyView = ({ navigation }) => {
+ const [crashReportState, setCrashReportState] = useState(getReportCrashErrorsValue());
+ const [analyticsEventsState, setAnalyticsEventsState] = useState(getReportAnalyticsEventsValue());
- static propTypes = {
- navigation: PropTypes.object,
- allowCrashReport: PropTypes.bool,
- allowAnalyticsEvents: PropTypes.bool,
- e2eEnabled: PropTypes.bool,
- toggleCrashReport: PropTypes.func,
- toggleAnalyticsEvents: PropTypes.func,
- user: PropTypes.shape({
- roles: PropTypes.array,
- id: PropTypes.string
- })
- }
+ const { e2eEnabled } = useSelector(state => state.settings);
- toggleCrashReport = (value) => {
+ useEffect(() => {
+ navigation.setOptions({
+ title: I18n.t('Security_and_privacy')
+ });
+ }, []);
+
+ const toggleCrashReport = (value) => {
logEvent(events.SE_TOGGLE_CRASH_REPORT);
AsyncStorage.setItem(CRASH_REPORT_KEY, JSON.stringify(value));
- const { toggleCrashReport } = this.props;
- toggleCrashReport(value);
- if (!isFDroidBuild) {
- loggerConfig.autoNotify = value;
- if (value) {
- loggerConfig.clearBeforeSendCallbacks();
- } else {
- loggerConfig.registerBeforeSendCallback(() => false);
- }
- }
- }
+ setCrashReportState(value);
+ toggleCrashErrorsReport(value);
+ };
- toggleAnalyticsEvents = (value) => {
+ const toggleAnalyticsEvents = (value) => {
logEvent(events.SE_TOGGLE_ANALYTICS_EVENTS);
- const { toggleAnalyticsEvents } = this.props;
AsyncStorage.setItem(ANALYTICS_EVENTS_KEY, JSON.stringify(value));
- toggleAnalyticsEvents(value);
- analytics().setAnalyticsCollectionEnabled(value);
- }
+ setAnalyticsEventsState(value);
+ toggleAnalyticsEventsReport(value);
+ };
- navigateToScreen = (screen) => {
+ const navigateToScreen = (screen) => {
logEvent(events[`SP_GO_${ screen.replace('View', '').toUpperCase() }`]);
- const { navigation } = this.props;
navigation.navigate(screen);
- }
+ };
- renderCrashReportSwitch = () => {
- const { allowCrashReport } = this.props;
- return (
-
- );
- }
+ return (
+
+
+
+
+
+ {e2eEnabled
+ ? (
+ <>
+ navigateToScreen('E2EEncryptionSecurityView')}
+ testID='security-privacy-view-e2e-encryption'
+ />
+
+ >
+ )
+ : null
+ }
+ navigateToScreen('ScreenLockConfigView')}
+ testID='security-privacy-view-screen-lock'
+ />
+
+
- renderAnalyticsEventsSwitch = () => {
- const { allowAnalyticsEvents } = this.props;
- return (
-
- );
- }
-
- render() {
- const { e2eEnabled } = this.props;
- return (
-
-
-
-
-
- {e2eEnabled
- ? (
- <>
- this.navigateToScreen('E2EEncryptionSecurityView')}
- testID='security-privacy-view-e2e-encryption'
+ {!isFDroidBuild ? (
+ <>
+
+
+ (
+
-
- >
- )
- : null
- }
- this.navigateToScreen('ScreenLockConfigView')}
- testID='security-privacy-view-screen-lock'
- />
-
-
+ )}
+ />
+
+ (
+
+ )}
+ />
+
+
+
+ >
+ ) : null}
+
+
+ );
+};
- {!isFDroidBuild ? (
- <>
-
-
- this.renderAnalyticsEventsSwitch()}
- />
-
- this.renderCrashReportSwitch()}
- />
-
-
-
- >
- ) : null}
-
-
- );
- }
-}
+SecurityPrivacyView.propTypes = {
+ navigation: PropTypes.object
+};
-const mapStateToProps = state => ({
- user: getUserSelector(state),
- allowCrashReport: state.crashReport.allowCrashReport,
- allowAnalyticsEvents: state.crashReport.allowAnalyticsEvents,
- e2eEnabled: state.settings.E2E_Enable
-});
-
-const mapDispatchToProps = dispatch => ({
- toggleCrashReport: params => dispatch(toggleCrashReportAction(params)),
- toggleAnalyticsEvents: params => dispatch(toggleAnalyticsEventsAction(params))
-});
-
-export default connect(mapStateToProps, mapDispatchToProps)(SecurityPrivacyView);
+export default SecurityPrivacyView;