From 0bd3143481bcecc3d09673c7c1b0c86e4d289bf2 Mon Sep 17 00:00:00 2001 From: Baptiste Grob <60621355+baptiste-grob@users.noreply.github.com> Date: Fri, 22 Jan 2021 15:31:56 +0100 Subject: [PATCH] feat: add random identifier to bugsnag reports --- app/assets/javascripts/crypto.ts | 2 +- .../directives/views/accountMenu.ts | 11 ++++++-- .../javascripts/services/errorReporting.ts | 27 ++++++++++++++++++- .../javascripts/services/localStorage.ts | 6 +++-- .../javascripts/ui_models/application.ts | 4 +-- .../templates/directives/account-menu.pug | 7 +++++ 6 files changed, 49 insertions(+), 8 deletions(-) diff --git a/app/assets/javascripts/crypto.ts b/app/assets/javascripts/crypto.ts index 28c1edb8d..d93163eac 100644 --- a/app/assets/javascripts/crypto.ts +++ b/app/assets/javascripts/crypto.ts @@ -1,3 +1,3 @@ import { SNWebCrypto } from "@standardnotes/sncrypto-web"; -export const Crypto = new SNWebCrypto(); +export const WebCrypto = new SNWebCrypto(); diff --git a/app/assets/javascripts/directives/views/accountMenu.ts b/app/assets/javascripts/directives/views/accountMenu.ts index 7c044bc51..10a9fd367 100644 --- a/app/assets/javascripts/directives/views/accountMenu.ts +++ b/app/assets/javascripts/directives/views/accountMenu.ts @@ -24,6 +24,11 @@ import { BackupFile, ContentType } from '@standardnotes/snjs'; import { confirmDialog, alertDialog } from '@/services/alertService'; import { autorun, IReactionDisposer } from 'mobx'; import { storage, StorageKey } from '@/services/localStorage'; +import { + disableErrorReporting, + enableErrorReporting, + errorReportingId +} from '@/services/errorReporting'; const ELEMENT_ID_IMPORT_PASSWORD_INPUT = 'import-password-request'; @@ -66,6 +71,7 @@ type AccountMenuState = { syncInProgress: boolean; syncError: string; showSessions: boolean; + errorReportingId: string | null; } class AccountMenuCtrl extends PureViewCtrl { @@ -99,6 +105,7 @@ class AccountMenuCtrl extends PureViewCtrl { showBetaWarning: false, errorReportingEnabled: storage.get(StorageKey.DisableErrorReporting) === false, showSessions: false, + errorReportingId: errorReportingId(), } as AccountMenuState; } @@ -550,9 +557,9 @@ class AccountMenuCtrl extends PureViewCtrl { toggleErrorReportingEnabled() { if (this.state.errorReportingEnabled) { - storage.set(StorageKey.DisableErrorReporting, true); + disableErrorReporting(); } else { - storage.set(StorageKey.DisableErrorReporting, false); + enableErrorReporting(); } if (!this.state.syncInProgress) { window.location.reload(); diff --git a/app/assets/javascripts/services/errorReporting.ts b/app/assets/javascripts/services/errorReporting.ts index 0a309e3ab..c3cd66a66 100644 --- a/app/assets/javascripts/services/errorReporting.ts +++ b/app/assets/javascripts/services/errorReporting.ts @@ -2,6 +2,7 @@ import { isNullOrUndefined, SNLog } from '@standardnotes/snjs'; import { isDesktopApplication, isDev } from '@/utils'; import { storage, StorageKey } from './localStorage'; import Bugsnag from '@bugsnag/js'; +import { WebCrypto } from '../crypto'; declare const __VERSION__: string; declare global { @@ -21,7 +22,7 @@ function redactFilePath(line: string): string { } } -export function startErrorReporting() { +export function startErrorReporting(): void { const disableErrorReporting = storage.get(StorageKey.DisableErrorReporting); if ( /** @@ -37,6 +38,15 @@ export function startErrorReporting() { return; } try { + const storedUserId = storage.get(StorageKey.AnonymousUserId); + let anonymousUserId: string; + if (storedUserId === null) { + anonymousUserId = WebCrypto.generateUUIDSync(); + storage.set(StorageKey.AnonymousUserId, anonymousUserId); + } else { + anonymousUserId = storedUserId; + } + Bugsnag.start({ apiKey: window._bugsnag_api_key, appType: isDesktopApplication() ? 'desktop' : 'web', @@ -46,6 +56,8 @@ export function startErrorReporting() { releaseStage: isDev ? 'development' : undefined, enabledBreadcrumbTypes: ['error', 'log'], onError(event) { + event.setUser(anonymousUserId); + /** * Redact any data that could be used to identify user, * such as file paths. @@ -95,3 +107,16 @@ export function startErrorReporting() { SNLog.onError = console.error; } } + +export function disableErrorReporting() { + storage.remove(StorageKey.AnonymousUserId); + storage.set(StorageKey.DisableErrorReporting, true); +} + +export function enableErrorReporting() { + storage.set(StorageKey.DisableErrorReporting, false); +} + +export function errorReportingId() { + return storage.get(StorageKey.AnonymousUserId); +} diff --git a/app/assets/javascripts/services/localStorage.ts b/app/assets/javascripts/services/localStorage.ts index ac20a5243..07e11fe5a 100644 --- a/app/assets/javascripts/services/localStorage.ts +++ b/app/assets/javascripts/services/localStorage.ts @@ -1,9 +1,11 @@ export enum StorageKey { DisableErrorReporting = 'DisableErrorReporting', + AnonymousUserId = 'AnonymousUserId', } export type StorageValue = { [StorageKey.DisableErrorReporting]: boolean; + [StorageKey.AnonymousUserId]: string; } export const storage = { @@ -11,10 +13,10 @@ export const storage = { const value = localStorage.getItem(key); return value ? JSON.parse(value) : null; }, - set(key: K, value: StorageValue[K]) { + set(key: K, value: StorageValue[K]): void { localStorage.setItem(key, JSON.stringify(value)); }, - remove(key: StorageKey) { + remove(key: StorageKey): void { localStorage.removeItem(key); }, }; diff --git a/app/assets/javascripts/ui_models/application.ts b/app/assets/javascripts/ui_models/application.ts index 7684cd9e6..b18f6dc3c 100644 --- a/app/assets/javascripts/ui_models/application.ts +++ b/app/assets/javascripts/ui_models/application.ts @@ -26,7 +26,7 @@ import { } from '@/services'; import { AppState } from '@/ui_models/app_state'; import { Bridge } from '@/services/bridge'; -import { Crypto } from '@/crypto'; +import { WebCrypto } from '@/crypto'; type WebServices = { appState: AppState; @@ -60,7 +60,7 @@ export class WebApplication extends SNApplication { bridge.environment, platformFromString(getPlatformString()), deviceInterface, - Crypto, + WebCrypto, new AlertService(), identifier, undefined, diff --git a/app/assets/templates/directives/account-menu.pug b/app/assets/templates/directives/account-menu.pug index 39953a61c..4dcddbdf2 100644 --- a/app/assets/templates/directives/account-menu.pug +++ b/app/assets/templates/directives/account-menu.pug @@ -293,6 +293,13 @@ p.sk-p | Help us improve Standard Notes by automatically submitting | anonymized error reports. + p.sk-p.selectable(ng-if="self.state.errorReportingId") + | Your random identifier is + strong {{ self.state.errorReportingId }} + p.sk-p(ng-if="self.state.errorReportingId") + | Disabling error reporting will remove that identifier from your + | local storage, and a new identifier will be created should you + | decide to enable error reporting again in the future. .sk-panel-row button(ng-click="self.toggleErrorReportingEnabled()").sk-button.info span.sk-label {{ self.state.errorReportingEnabled ? 'Disable' : 'Enable'}} Error Reporting