feat: add random identifier to bugsnag reports

This commit is contained in:
Baptiste Grob 2021-01-22 15:31:56 +01:00
parent 2c4742a91d
commit 0bd3143481
No known key found for this signature in database
GPG key ID: 4CC6BD922C8AF137
6 changed files with 49 additions and 8 deletions

View file

@ -1,3 +1,3 @@
import { SNWebCrypto } from "@standardnotes/sncrypto-web";
export const Crypto = new SNWebCrypto();
export const WebCrypto = new SNWebCrypto();

View file

@ -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<unknown, AccountMenuState> {
@ -99,6 +105,7 @@ class AccountMenuCtrl extends PureViewCtrl<unknown, AccountMenuState> {
showBetaWarning: false,
errorReportingEnabled: storage.get(StorageKey.DisableErrorReporting) === false,
showSessions: false,
errorReportingId: errorReportingId(),
} as AccountMenuState;
}
@ -550,9 +557,9 @@ class AccountMenuCtrl extends PureViewCtrl<unknown, AccountMenuState> {
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();

View file

@ -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);
}

View file

@ -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<K extends StorageKey>(key: K, value: StorageValue[K]) {
set<K extends StorageKey>(key: K, value: StorageValue[K]): void {
localStorage.setItem(key, JSON.stringify(value));
},
remove(key: StorageKey) {
remove(key: StorageKey): void {
localStorage.removeItem(key);
},
};

View file

@ -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,

View file

@ -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