ADD: opt-out of analytics tracking in settings/privacy (rel #3084)

This commit is contained in:
Overtorment 2021-05-07 16:55:17 +01:00
parent 954a35f79d
commit d7911fcfe2
8 changed files with 62 additions and 6 deletions

View file

@ -1,5 +1,5 @@
function WidgetCommunication(props) { function WidgetCommunication(props) {
WidgetCommunication.isBalanceDisplayAllowed = false; WidgetCommunication.isBalanceDisplayAllowed = () => {};
WidgetCommunication.setBalanceDisplayAllowed = () => {}; WidgetCommunication.setBalanceDisplayAllowed = () => {};
return null; return null;
} }

View file

@ -1,6 +1,8 @@
import * as Sentry from '@sentry/react-native';
import amplitude from 'amplitude-js'; import amplitude from 'amplitude-js';
import { getVersion, getSystemName } from 'react-native-device-info'; import { getVersion, getSystemName } from 'react-native-device-info';
import { Platform } from 'react-native'; import { Platform } from 'react-native';
const BlueApp = require('../BlueApp');
amplitude.getInstance().init('8b7cf19e8eea3cdcf16340f5fbf16330', null, { amplitude.getInstance().init('8b7cf19e8eea3cdcf16340f5fbf16330', null, {
useNativeDeviceInfo: true, useNativeDeviceInfo: true,
@ -8,6 +10,10 @@ amplitude.getInstance().init('8b7cf19e8eea3cdcf16340f5fbf16330', null, {
}); });
amplitude.getInstance().setVersionName(getVersion()); amplitude.getInstance().setVersionName(getVersion());
amplitude.getInstance().options.apiEndpoint = 'api2.amplitude.com'; amplitude.getInstance().options.apiEndpoint = 'api2.amplitude.com';
BlueApp.isDoNotTrackEnabled().then(value => {
if (value) Sentry.close();
amplitude.getInstance().setOptOut(value);
});
const A = async event => { const A = async event => {
console.log('posting analytics...', event); console.log('posting analytics...', event);
@ -28,4 +34,9 @@ A.ENUM = {
NAVIGATED_TO_WALLETS_HODLHODL: 'NAVIGATED_TO_WALLETS_HODLHODL', NAVIGATED_TO_WALLETS_HODLHODL: 'NAVIGATED_TO_WALLETS_HODLHODL',
}; };
A.setOptOut = value => {
if (value) Sentry.close();
return amplitude.getInstance().setOptOut(value);
};
module.exports = A; module.exports = A;

View file

@ -175,6 +175,8 @@ export const BlueStorageProvider = ({ children }) => {
const getHodlHodlSignatureKey = BlueApp.getHodlHodlSignatureKey; const getHodlHodlSignatureKey = BlueApp.getHodlHodlSignatureKey;
const addHodlHodlContract = BlueApp.addHodlHodlContract; const addHodlHodlContract = BlueApp.addHodlHodlContract;
const getHodlHodlContracts = BlueApp.getHodlHodlContracts; const getHodlHodlContracts = BlueApp.getHodlHodlContracts;
const setDoNotTrack = BlueApp.setDoNotTrack;
const isDoNotTrackEnabled = BlueApp.isDoNotTrackEnabled;
const getItem = BlueApp.getItem; const getItem = BlueApp.getItem;
const setItem = BlueApp.setItem; const setItem = BlueApp.setItem;
@ -227,6 +229,8 @@ export const BlueStorageProvider = ({ children }) => {
setWalletTransactionUpdateStatus, setWalletTransactionUpdateStatus,
isDrawerListBlurred, isDrawerListBlurred,
setIsDrawerListBlurred, setIsDrawerListBlurred,
setDoNotTrack,
isDoNotTrackEnabled,
}} }}
> >
{children} {children}

View file

@ -36,6 +36,7 @@ export class AppStorage {
static ELECTRUM_SERVER_HISTORY = 'electrum_server_history'; static ELECTRUM_SERVER_HISTORY = 'electrum_server_history';
static PREFERRED_CURRENCY = 'preferredCurrency'; static PREFERRED_CURRENCY = 'preferredCurrency';
static ADVANCED_MODE_ENABLED = 'advancedmodeenabled'; static ADVANCED_MODE_ENABLED = 'advancedmodeenabled';
static DO_NOT_TRACK = 'donottrack';
static HODL_HODL_API_KEY = 'HODL_HODL_API_KEY'; static HODL_HODL_API_KEY = 'HODL_HODL_API_KEY';
static HODL_HODL_SIGNATURE_KEY = 'HODL_HODL_SIGNATURE_KEY'; static HODL_HODL_SIGNATURE_KEY = 'HODL_HODL_SIGNATURE_KEY';
static HODL_HODL_CONTRACTS = 'HODL_HODL_CONTRACTS'; static HODL_HODL_CONTRACTS = 'HODL_HODL_CONTRACTS';
@ -653,6 +654,17 @@ export class AppStorage {
await this.setItem(AppStorage.ADVANCED_MODE_ENABLED, value ? '1' : ''); await this.setItem(AppStorage.ADVANCED_MODE_ENABLED, value ? '1' : '');
}; };
isDoNotTrackEnabled = async () => {
try {
return !!(await this.getItem(AppStorage.DO_NOT_TRACK));
} catch (_) {}
return false;
};
setDoNotTrack = async value => {
await this.setItem(AppStorage.DO_NOT_TRACK, value ? '1' : '');
};
/** /**
* Simple async sleeper function * Simple async sleeper function
* *

View file

@ -316,6 +316,8 @@
"privacy_quickactions": "Wallet Shortcuts", "privacy_quickactions": "Wallet Shortcuts",
"privacy_quickactions_explanation": "Touch and hold the BlueWallet app icon on your Home Screen to quickly view your wallets balance.", "privacy_quickactions_explanation": "Touch and hold the BlueWallet app icon on your Home Screen to quickly view your wallets balance.",
"privacy_clipboard_explanation": "Provide shortcuts if an address or invoice is found in your clipboard.", "privacy_clipboard_explanation": "Provide shortcuts if an address or invoice is found in your clipboard.",
"privacy_do_not_track": "Do Not Track",
"privacy_do_not_track_explanation": "Some anonymized analytics and debug data won't be sent to analytics service.",
"push_notifications": "Push Notifications", "push_notifications": "Push Notifications",
"retype_password": "Re-type password", "retype_password": "Re-type password",
"selfTest": "Self-Test", "selfTest": "Self-Test",

6
package-lock.json generated
View file

@ -3564,9 +3564,9 @@
} }
}, },
"@sentry/react-native": { "@sentry/react-native": {
"version": "2.4.0", "version": "2.5.0-beta.1",
"resolved": "https://registry.npmjs.org/@sentry/react-native/-/react-native-2.4.0.tgz", "resolved": "https://registry.npmjs.org/@sentry/react-native/-/react-native-2.5.0-beta.1.tgz",
"integrity": "sha512-yRUN36tKRSsGEtNHihEzl0KqGh7pmWfNV0h3jf5Q1VKXNHA9iO2ABcmr47wScrbrK2MDL1umO1AQNq2+6z24QA==", "integrity": "sha512-q+WQwFRBl/3uKIdB+NExfPMoDzQzdHuA+W3p9ZPfBdsNX3t3iHa3JHT6t0EYRf46NlAmFmnHaQNqHxP7u9I6LQ==",
"requires": { "requires": {
"@sentry/browser": "6.2.1", "@sentry/browser": "6.2.1",
"@sentry/core": "6.2.1", "@sentry/core": "6.2.1",

View file

@ -79,7 +79,7 @@
"@react-navigation/drawer": "5.12.5", "@react-navigation/drawer": "5.12.5",
"@react-navigation/stack": "5.14.3", "@react-navigation/stack": "5.14.3",
"@remobile/react-native-qrcode-local-image": "https://github.com/BlueWallet/react-native-qrcode-local-image", "@remobile/react-native-qrcode-local-image": "https://github.com/BlueWallet/react-native-qrcode-local-image",
"@sentry/react-native": "2.4.0", "@sentry/react-native": "2.5.0-beta.1",
"aez": "1.0.1", "aez": "1.0.1",
"amplitude-js": "7.4.4", "amplitude-js": "7.4.4",
"assert": "1.5.0", "assert": "1.5.0",

View file

@ -10,12 +10,15 @@ import BlueClipboard from '../../blue_modules/clipboard';
import { BlueStorageContext } from '../../blue_modules/storage-context'; import { BlueStorageContext } from '../../blue_modules/storage-context';
import WidgetCommunication from '../../blue_modules/WidgetCommunication'; import WidgetCommunication from '../../blue_modules/WidgetCommunication';
const A = require('../../blue_modules/analytics');
const SettingsPrivacy = () => { const SettingsPrivacy = () => {
const { colors } = useTheme(); const { colors } = useTheme();
const { isStorageEncrypted } = useContext(BlueStorageContext); const { isStorageEncrypted, setDoNotTrack, isDoNotTrackEnabled } = useContext(BlueStorageContext);
const sections = Object.freeze({ ALL: 0, CLIPBOARDREAD: 1, QUICKACTION: 2, WIDGETS: 3 }); const sections = Object.freeze({ ALL: 0, CLIPBOARDREAD: 1, QUICKACTION: 2, WIDGETS: 3 });
const [isLoading, setIsLoading] = useState(sections.ALL); const [isLoading, setIsLoading] = useState(sections.ALL);
const [isReadClipboardAllowed, setIsReadClipboardAllowed] = useState(false); const [isReadClipboardAllowed, setIsReadClipboardAllowed] = useState(false);
const [doNotTrackSwitchValue, setDoNotTrackSwitchValue] = useState(false);
const [isDisplayWidgetBalanceAllowed, setIsDisplayWidgetBalanceAllowed] = useState(false); const [isDisplayWidgetBalanceAllowed, setIsDisplayWidgetBalanceAllowed] = useState(false);
const [isQuickActionsEnabled, setIsQuickActionsEnabled] = useState(false); const [isQuickActionsEnabled, setIsQuickActionsEnabled] = useState(false);
@ -24,6 +27,7 @@ const SettingsPrivacy = () => {
useEffect(() => { useEffect(() => {
(async () => { (async () => {
try { try {
setDoNotTrackSwitchValue(await isDoNotTrackEnabled());
setIsReadClipboardAllowed(await BlueClipboard.isReadClipboardAllowed()); setIsReadClipboardAllowed(await BlueClipboard.isReadClipboardAllowed());
setStorageIsEncrypted(await isStorageEncrypted()); setStorageIsEncrypted(await isStorageEncrypted());
setIsQuickActionsEnabled(await DeviceQuickActions.getEnabled()); setIsQuickActionsEnabled(await DeviceQuickActions.getEnabled());
@ -47,6 +51,18 @@ const SettingsPrivacy = () => {
setIsLoading(false); setIsLoading(false);
}; };
const onDoNotTrackValueChange = async value => {
setIsLoading(sections.ALL);
try {
setDoNotTrackSwitchValue(value);
A.setOptOut(value);
await setDoNotTrack(value);
} catch (e) {
console.log(e);
}
setIsLoading(false);
};
const onQuickActionsValueChange = async value => { const onQuickActionsValueChange = async value => {
setIsLoading(sections.QUICKACTION); setIsLoading(sections.QUICKACTION);
try { try {
@ -129,6 +145,17 @@ const SettingsPrivacy = () => {
</> </>
)} )}
<BlueSpacing20 /> <BlueSpacing20 />
<BlueListItem
hideChevron
title={loc.settings.privacy_do_not_track}
Component={TouchableWithoutFeedback}
switch={{ onValueChange: onDoNotTrackValueChange, value: doNotTrackSwitchValue, disabled: isLoading === sections.ALL }}
/>
<BlueCard>
<BlueText>{loc.settings.privacy_do_not_track_explanation}</BlueText>
</BlueCard>
<BlueSpacing20 />
<BlueListItem title={loc.settings.privacy_system_settings} chevron onPress={openApplicationSettings} testID="PrivacySystemSettings" /> <BlueListItem title={loc.settings.privacy_system_settings} chevron onPress={openApplicationSettings} testID="PrivacySystemSettings" />
<BlueSpacing20 /> <BlueSpacing20 />
</ScrollView> </ScrollView>