mirror of
https://github.com/Kong/insomnia.git
synced 2026-04-22 23:28:33 -04:00
INS-1501: Sentry integration. (#4817)
* Install Sentry. * Improve fetch typings. * INS-1501: Sentry integration * Split Sentry logic between UI and main. * TSDoc * Move sentry DSN into config.json. * Fix doc comments. (Doc'ing code like it's 1997.) * Make long comments hilariously unreadable. * Remove unused segment event. * Re-export app environment. Co-authored-by: Dimitri Mitropoulos <dimitrimitropoulos@gmail.com>
This commit is contained in:
@@ -15,6 +15,7 @@
|
||||
"development": "rTOCSvGV23cHGJyb3HI9EUQDNA6ar7ay",
|
||||
"production": "4l7QUfACrIcqvC913hiIwAA2BDYP2OJ1"
|
||||
},
|
||||
"sentryDsn": "https://aaec2e800e644070a8daba5b7ad02c16@o1147619.ingest.sentry.io/6311804",
|
||||
"plugins": [
|
||||
"insomnia-plugin-base64",
|
||||
"insomnia-plugin-hash",
|
||||
|
||||
224
packages/insomnia/package-lock.json
generated
224
packages/insomnia/package-lock.json
generated
@@ -14,6 +14,7 @@
|
||||
"@grpc/proto-loader": "^0.5.5",
|
||||
"@hapi/hawk": "^8.0.0",
|
||||
"@jest/globals": "^28.1.0",
|
||||
"@sentry/electron": "^3.0.7",
|
||||
"@stoplight/spectral": "^5.9.0",
|
||||
"analytics-node": "^6.0.0",
|
||||
"aws4": "^1.11.0",
|
||||
@@ -3217,6 +3218,118 @@
|
||||
"join-component": "^1.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@sentry/browser": {
|
||||
"version": "6.19.2",
|
||||
"resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-6.19.2.tgz",
|
||||
"integrity": "sha512-5VC44p5Vu2eJhVT39nLAJFgha5MjHDYCyZRR1ieeZt3a++otojPGBBAKNAtrEMGV+A2Z9AoneD6ZnDVlyb3GKg==",
|
||||
"dependencies": {
|
||||
"@sentry/core": "6.19.2",
|
||||
"@sentry/types": "6.19.2",
|
||||
"@sentry/utils": "6.19.2",
|
||||
"tslib": "^1.9.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/@sentry/core": {
|
||||
"version": "6.19.2",
|
||||
"resolved": "https://registry.npmjs.org/@sentry/core/-/core-6.19.2.tgz",
|
||||
"integrity": "sha512-yu1R3ewBT4udmB4v7sc4biQZ0Z0rfB9+TzB5ZKoCftbe6kqXjFMMaFRYNUF9HicVldKAsBktgkWw3+yfqGkw/A==",
|
||||
"dependencies": {
|
||||
"@sentry/hub": "6.19.2",
|
||||
"@sentry/minimal": "6.19.2",
|
||||
"@sentry/types": "6.19.2",
|
||||
"@sentry/utils": "6.19.2",
|
||||
"tslib": "^1.9.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/@sentry/electron": {
|
||||
"version": "3.0.7",
|
||||
"resolved": "https://registry.npmjs.org/@sentry/electron/-/electron-3.0.7.tgz",
|
||||
"integrity": "sha512-Rahi1jgvjHnx1jGkkPPvDCxSCAME7xc2eBcFCLb4R/WDuNblR7tgJUuAtzv9JpxUgRHy1oLNct0wcvIu1mcXoA==",
|
||||
"dependencies": {
|
||||
"@sentry/browser": "6.19.2",
|
||||
"@sentry/core": "6.19.2",
|
||||
"@sentry/node": "6.19.2",
|
||||
"@sentry/types": "6.19.2",
|
||||
"@sentry/utils": "6.19.2",
|
||||
"deepmerge": "^4.2.2",
|
||||
"tslib": "^2.3.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@sentry/electron/node_modules/tslib": {
|
||||
"version": "2.4.0",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz",
|
||||
"integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ=="
|
||||
},
|
||||
"node_modules/@sentry/hub": {
|
||||
"version": "6.19.2",
|
||||
"resolved": "https://registry.npmjs.org/@sentry/hub/-/hub-6.19.2.tgz",
|
||||
"integrity": "sha512-W7KCgNBgdBIMagOxy5J5KQPe+maYxSqfE8a5ncQ3R8BcZDQEKnkW/1FplNbfRLZqA/tL/ndKb7pTPqVtzsbARw==",
|
||||
"dependencies": {
|
||||
"@sentry/types": "6.19.2",
|
||||
"@sentry/utils": "6.19.2",
|
||||
"tslib": "^1.9.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/@sentry/minimal": {
|
||||
"version": "6.19.2",
|
||||
"resolved": "https://registry.npmjs.org/@sentry/minimal/-/minimal-6.19.2.tgz",
|
||||
"integrity": "sha512-ClwxKm77iDHET7kpzv1JvzDx1er5DoNu+EUjst0kQzARIrXvu9xuZuE2/CnBWycQWqw8o3HoGoKz65uIhsUCzQ==",
|
||||
"dependencies": {
|
||||
"@sentry/hub": "6.19.2",
|
||||
"@sentry/types": "6.19.2",
|
||||
"tslib": "^1.9.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/@sentry/node": {
|
||||
"version": "6.19.2",
|
||||
"resolved": "https://registry.npmjs.org/@sentry/node/-/node-6.19.2.tgz",
|
||||
"integrity": "sha512-Z1qREpTpYHxaeWjc1zMUk8ZTAp1WbxMiI2TVNc+a14DVT19Z2xNXb06MiRfeLgNc9lVGdmzR62dPmMBjVgPJYg==",
|
||||
"dependencies": {
|
||||
"@sentry/core": "6.19.2",
|
||||
"@sentry/hub": "6.19.2",
|
||||
"@sentry/types": "6.19.2",
|
||||
"@sentry/utils": "6.19.2",
|
||||
"cookie": "^0.4.1",
|
||||
"https-proxy-agent": "^5.0.0",
|
||||
"lru_map": "^0.3.3",
|
||||
"tslib": "^1.9.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/@sentry/types": {
|
||||
"version": "6.19.2",
|
||||
"resolved": "https://registry.npmjs.org/@sentry/types/-/types-6.19.2.tgz",
|
||||
"integrity": "sha512-XO5qmVBdTs+7PdCz7fAwn1afWxSnRE2KLBFg5/vOdKosPSSHsSHUURSkxiEZc2QsR+JpRB4AeQ26AkIRX38qTg==",
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/@sentry/utils": {
|
||||
"version": "6.19.2",
|
||||
"resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-6.19.2.tgz",
|
||||
"integrity": "sha512-2DQQ2OJaxjtyxGq5FmMlqb6hptsqMs2xoBiVRMkTS/rvyTrk1oQdKZ8ePwjtgX3nJ728ni3IXIyXV+vfGp4EBw==",
|
||||
"dependencies": {
|
||||
"@sentry/types": "6.19.2",
|
||||
"tslib": "^1.9.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/@sideway/address": {
|
||||
"version": "4.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.2.tgz",
|
||||
@@ -6946,7 +7059,6 @@
|
||||
"version": "0.4.2",
|
||||
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz",
|
||||
"integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
@@ -7528,7 +7640,6 @@
|
||||
"version": "4.2.2",
|
||||
"resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz",
|
||||
"integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
@@ -15169,6 +15280,11 @@
|
||||
"node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/lru_map": {
|
||||
"version": "0.3.3",
|
||||
"resolved": "https://registry.npmjs.org/lru_map/-/lru_map-0.3.3.tgz",
|
||||
"integrity": "sha1-tcg1G5Rky9dQM1p5ZQoOwOVhGN0="
|
||||
},
|
||||
"node_modules/lru-cache": {
|
||||
"version": "5.1.1",
|
||||
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
|
||||
@@ -22677,6 +22793,99 @@
|
||||
"join-component": "^1.1.0"
|
||||
}
|
||||
},
|
||||
"@sentry/browser": {
|
||||
"version": "6.19.2",
|
||||
"resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-6.19.2.tgz",
|
||||
"integrity": "sha512-5VC44p5Vu2eJhVT39nLAJFgha5MjHDYCyZRR1ieeZt3a++otojPGBBAKNAtrEMGV+A2Z9AoneD6ZnDVlyb3GKg==",
|
||||
"requires": {
|
||||
"@sentry/core": "6.19.2",
|
||||
"@sentry/types": "6.19.2",
|
||||
"@sentry/utils": "6.19.2",
|
||||
"tslib": "^1.9.3"
|
||||
}
|
||||
},
|
||||
"@sentry/core": {
|
||||
"version": "6.19.2",
|
||||
"resolved": "https://registry.npmjs.org/@sentry/core/-/core-6.19.2.tgz",
|
||||
"integrity": "sha512-yu1R3ewBT4udmB4v7sc4biQZ0Z0rfB9+TzB5ZKoCftbe6kqXjFMMaFRYNUF9HicVldKAsBktgkWw3+yfqGkw/A==",
|
||||
"requires": {
|
||||
"@sentry/hub": "6.19.2",
|
||||
"@sentry/minimal": "6.19.2",
|
||||
"@sentry/types": "6.19.2",
|
||||
"@sentry/utils": "6.19.2",
|
||||
"tslib": "^1.9.3"
|
||||
}
|
||||
},
|
||||
"@sentry/electron": {
|
||||
"version": "3.0.7",
|
||||
"resolved": "https://registry.npmjs.org/@sentry/electron/-/electron-3.0.7.tgz",
|
||||
"integrity": "sha512-Rahi1jgvjHnx1jGkkPPvDCxSCAME7xc2eBcFCLb4R/WDuNblR7tgJUuAtzv9JpxUgRHy1oLNct0wcvIu1mcXoA==",
|
||||
"requires": {
|
||||
"@sentry/browser": "6.19.2",
|
||||
"@sentry/core": "6.19.2",
|
||||
"@sentry/node": "6.19.2",
|
||||
"@sentry/types": "6.19.2",
|
||||
"@sentry/utils": "6.19.2",
|
||||
"deepmerge": "^4.2.2",
|
||||
"tslib": "^2.3.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"tslib": {
|
||||
"version": "2.4.0",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz",
|
||||
"integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"@sentry/hub": {
|
||||
"version": "6.19.2",
|
||||
"resolved": "https://registry.npmjs.org/@sentry/hub/-/hub-6.19.2.tgz",
|
||||
"integrity": "sha512-W7KCgNBgdBIMagOxy5J5KQPe+maYxSqfE8a5ncQ3R8BcZDQEKnkW/1FplNbfRLZqA/tL/ndKb7pTPqVtzsbARw==",
|
||||
"requires": {
|
||||
"@sentry/types": "6.19.2",
|
||||
"@sentry/utils": "6.19.2",
|
||||
"tslib": "^1.9.3"
|
||||
}
|
||||
},
|
||||
"@sentry/minimal": {
|
||||
"version": "6.19.2",
|
||||
"resolved": "https://registry.npmjs.org/@sentry/minimal/-/minimal-6.19.2.tgz",
|
||||
"integrity": "sha512-ClwxKm77iDHET7kpzv1JvzDx1er5DoNu+EUjst0kQzARIrXvu9xuZuE2/CnBWycQWqw8o3HoGoKz65uIhsUCzQ==",
|
||||
"requires": {
|
||||
"@sentry/hub": "6.19.2",
|
||||
"@sentry/types": "6.19.2",
|
||||
"tslib": "^1.9.3"
|
||||
}
|
||||
},
|
||||
"@sentry/node": {
|
||||
"version": "6.19.2",
|
||||
"resolved": "https://registry.npmjs.org/@sentry/node/-/node-6.19.2.tgz",
|
||||
"integrity": "sha512-Z1qREpTpYHxaeWjc1zMUk8ZTAp1WbxMiI2TVNc+a14DVT19Z2xNXb06MiRfeLgNc9lVGdmzR62dPmMBjVgPJYg==",
|
||||
"requires": {
|
||||
"@sentry/core": "6.19.2",
|
||||
"@sentry/hub": "6.19.2",
|
||||
"@sentry/types": "6.19.2",
|
||||
"@sentry/utils": "6.19.2",
|
||||
"cookie": "^0.4.1",
|
||||
"https-proxy-agent": "^5.0.0",
|
||||
"lru_map": "^0.3.3",
|
||||
"tslib": "^1.9.3"
|
||||
}
|
||||
},
|
||||
"@sentry/types": {
|
||||
"version": "6.19.2",
|
||||
"resolved": "https://registry.npmjs.org/@sentry/types/-/types-6.19.2.tgz",
|
||||
"integrity": "sha512-XO5qmVBdTs+7PdCz7fAwn1afWxSnRE2KLBFg5/vOdKosPSSHsSHUURSkxiEZc2QsR+JpRB4AeQ26AkIRX38qTg=="
|
||||
},
|
||||
"@sentry/utils": {
|
||||
"version": "6.19.2",
|
||||
"resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-6.19.2.tgz",
|
||||
"integrity": "sha512-2DQQ2OJaxjtyxGq5FmMlqb6hptsqMs2xoBiVRMkTS/rvyTrk1oQdKZ8ePwjtgX3nJ728ni3IXIyXV+vfGp4EBw==",
|
||||
"requires": {
|
||||
"@sentry/types": "6.19.2",
|
||||
"tslib": "^1.9.3"
|
||||
}
|
||||
},
|
||||
"@sideway/address": {
|
||||
"version": "4.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.2.tgz",
|
||||
@@ -25672,8 +25881,7 @@
|
||||
"cookie": {
|
||||
"version": "0.4.2",
|
||||
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz",
|
||||
"integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==",
|
||||
"dev": true
|
||||
"integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA=="
|
||||
},
|
||||
"copy-to-clipboard": {
|
||||
"version": "3.3.1",
|
||||
@@ -26132,8 +26340,7 @@
|
||||
"deepmerge": {
|
||||
"version": "4.2.2",
|
||||
"resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz",
|
||||
"integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==",
|
||||
"dev": true
|
||||
"integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg=="
|
||||
},
|
||||
"defer-to-connect": {
|
||||
"version": "1.1.3",
|
||||
@@ -31959,6 +32166,11 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"lru_map": {
|
||||
"version": "0.3.3",
|
||||
"resolved": "https://registry.npmjs.org/lru_map/-/lru_map-0.3.3.tgz",
|
||||
"integrity": "sha1-tcg1G5Rky9dQM1p5ZQoOwOVhGN0="
|
||||
},
|
||||
"lru-cache": {
|
||||
"version": "5.1.1",
|
||||
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
|
||||
|
||||
@@ -45,6 +45,7 @@
|
||||
"@grpc/proto-loader": "^0.5.5",
|
||||
"@hapi/hawk": "^8.0.0",
|
||||
"@jest/globals": "^28.1.0",
|
||||
"@sentry/electron": "^3.0.7",
|
||||
"@stoplight/spectral": "^5.9.0",
|
||||
"analytics-node": "^6.0.0",
|
||||
"aws4": "^1.11.0",
|
||||
|
||||
@@ -15,19 +15,42 @@ export function onCommand(callback: Function) {
|
||||
_commandListeners.push(callback);
|
||||
}
|
||||
|
||||
export async function post(path, obj, sessionId, compressBody = false) {
|
||||
return _fetch('POST', path, obj, sessionId, compressBody);
|
||||
export async function post<T = any>(path: string, obj: unknown, sessionId: string | null, compressBody = false): Promise<T | string> {
|
||||
return _fetch<T>('POST', path, obj, sessionId, compressBody);
|
||||
}
|
||||
|
||||
export async function put(path, obj, sessionId, compressBody = false) {
|
||||
return _fetch('PUT', path, obj, sessionId, compressBody);
|
||||
export async function postJson<T = any>(path: string, obj: unknown, sessionId: string | null, compressBody = false): Promise<T> {
|
||||
const response = await post<T>(path, obj, sessionId, compressBody);
|
||||
if (typeof response === 'string') {
|
||||
throw new Error('Unexpected plaintext response');
|
||||
}
|
||||
return response;
|
||||
}
|
||||
|
||||
export async function get(path, sessionId) {
|
||||
return _fetch('GET', path, null, sessionId);
|
||||
export async function put<T = any>(path: string, obj: unknown, sessionId: string | null, compressBody = false): Promise<T | string> {
|
||||
return _fetch<T>('PUT', path, obj, sessionId, compressBody);
|
||||
}
|
||||
|
||||
async function _fetch(method, path, obj, sessionId, compressBody = false, retries = 0) {
|
||||
export async function get<T = any>(path: string, sessionId: string | null): Promise<T | string> {
|
||||
return _fetch<T>('GET', path, null, sessionId);
|
||||
}
|
||||
|
||||
export async function getJson<T = any>(path: string, sessionId: string | null): Promise<T> {
|
||||
const response = await get<T>(path, sessionId);
|
||||
if (typeof response === 'string') {
|
||||
throw new Error('Unexpected plaintext response');
|
||||
}
|
||||
return response;
|
||||
}
|
||||
|
||||
async function _fetch<T = any>(
|
||||
method: 'POST' | 'PUT' | 'GET',
|
||||
path: string,
|
||||
obj: unknown,
|
||||
sessionId: string | null,
|
||||
compressBody = false,
|
||||
retries = 0
|
||||
): Promise<T | string> {
|
||||
if (sessionId === undefined) {
|
||||
throw new Error(`No session ID provided to ${method}:${path}`);
|
||||
}
|
||||
@@ -59,7 +82,7 @@ async function _fetch(method, path, obj, sessionId, compressBody = false, retrie
|
||||
config.headers['X-Session-Id'] = sessionId;
|
||||
}
|
||||
|
||||
let response;
|
||||
let response: Response | undefined;
|
||||
|
||||
const url = _getUrl(path);
|
||||
|
||||
|
||||
@@ -5,6 +5,39 @@ import * as fetch from './fetch';
|
||||
|
||||
type LoginCallback = (isLoggedIn: boolean) => void;
|
||||
|
||||
export interface WhoamiResponse {
|
||||
sessionAge: number;
|
||||
accountId: string;
|
||||
email: string;
|
||||
firstName: string;
|
||||
lastName: string;
|
||||
created: number;
|
||||
publicKey: string;
|
||||
encSymmetricKey: string;
|
||||
encPrivateKey: string;
|
||||
saltEnc: string;
|
||||
isPaymentRequired: boolean;
|
||||
isTrialing: boolean;
|
||||
isVerified: boolean;
|
||||
isAdmin: boolean;
|
||||
trialEnd: string;
|
||||
planName: string;
|
||||
planId: string;
|
||||
canManageTeams: boolean;
|
||||
maxTeamMembers: number;
|
||||
}
|
||||
|
||||
export interface SessionData {
|
||||
accountId: string;
|
||||
id: string;
|
||||
email: string;
|
||||
firstName: string;
|
||||
lastName: string;
|
||||
symmetricKey: unknown;
|
||||
publicKey: unknown;
|
||||
encPrivateKey: unknown;
|
||||
}
|
||||
|
||||
const loginCallbacks: LoginCallback[] = [];
|
||||
|
||||
function _callCallbacks() {
|
||||
@@ -75,7 +108,7 @@ export async function login(rawEmail: string, rawPassphrase: string) {
|
||||
// Initialize the Session //
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~ //
|
||||
// Compute K (used for session ID)
|
||||
const sessionId = c.computeK().toString('hex');
|
||||
const sessionId = (c.computeK() as Buffer).toString('hex');
|
||||
// Get and store some extra info (salts and keys)
|
||||
const {
|
||||
publicKey,
|
||||
@@ -119,7 +152,7 @@ export async function changePasswordWithToken(rawNewPassphrase, confirmationCode
|
||||
.computeVerifier(
|
||||
_getSrpParams(),
|
||||
Buffer.from(saltAuth, 'hex'),
|
||||
Buffer.from(newEmail, 'utf8'),
|
||||
Buffer.from(newEmail || '', 'utf8'),
|
||||
Buffer.from(newAuthSecret, 'hex'),
|
||||
)
|
||||
.toString('hex');
|
||||
@@ -145,11 +178,11 @@ export function sendPasswordChangeCode() {
|
||||
}
|
||||
|
||||
export function getPublicKey() {
|
||||
return _getSessionData().publicKey;
|
||||
return _getSessionData()?.publicKey;
|
||||
}
|
||||
|
||||
export function getPrivateKey() {
|
||||
const { symmetricKey, encPrivateKey } = _getSessionData();
|
||||
const { symmetricKey, encPrivateKey } = _getSessionData() || {};
|
||||
|
||||
const privateKeyStr = crypt.decryptAES(symmetricKey, encPrivateKey);
|
||||
return JSON.parse(privateKeyStr);
|
||||
@@ -164,19 +197,19 @@ export function getCurrentSessionId() {
|
||||
}
|
||||
|
||||
export function getAccountId() {
|
||||
return _getSessionData().accountId;
|
||||
return _getSessionData()?.accountId;
|
||||
}
|
||||
|
||||
export function getEmail() {
|
||||
return _getSessionData().email;
|
||||
return _getSessionData()?.email;
|
||||
}
|
||||
|
||||
export function getFirstName() {
|
||||
return _getSessionData().firstName;
|
||||
return _getSessionData()?.firstName;
|
||||
}
|
||||
|
||||
export function getLastName() {
|
||||
return _getSessionData().lastName;
|
||||
return _getSessionData()?.lastName;
|
||||
}
|
||||
|
||||
export function getFullName() {
|
||||
@@ -205,16 +238,16 @@ export async function logout() {
|
||||
|
||||
/** Set data for the new session and store it encrypted with the sessionId */
|
||||
export function setSessionData(
|
||||
sessionId,
|
||||
accountId,
|
||||
firstName,
|
||||
lastName,
|
||||
email,
|
||||
sessionId: string,
|
||||
accountId: string,
|
||||
firstName: string,
|
||||
lastName: string,
|
||||
email: string,
|
||||
symmetricKey,
|
||||
publicKey,
|
||||
encPrivateKey,
|
||||
) {
|
||||
const dataStr = JSON.stringify({
|
||||
const sessionData: SessionData = {
|
||||
id: sessionId,
|
||||
accountId: accountId,
|
||||
symmetricKey: symmetricKey,
|
||||
@@ -223,7 +256,8 @@ export function setSessionData(
|
||||
email: email,
|
||||
firstName: firstName,
|
||||
lastName: lastName,
|
||||
});
|
||||
};
|
||||
const dataStr = JSON.stringify(sessionData);
|
||||
window.localStorage.setItem(_getSessionKey(sessionId), dataStr);
|
||||
// NOTE: We're setting this last because the stuff above might fail
|
||||
window.localStorage.setItem('currentSessionId', sessionId);
|
||||
@@ -236,13 +270,11 @@ export async function listTeams() {
|
||||
// Helper Functions //
|
||||
// ~~~~~~~~~~~~~~~~ //
|
||||
function _getSymmetricKey() {
|
||||
const sessionData = _getSessionData();
|
||||
|
||||
return sessionData.symmetricKey;
|
||||
return _getSessionData()?.symmetricKey;
|
||||
}
|
||||
|
||||
function _whoami(sessionId = null) {
|
||||
return fetch.get('/auth/whoami', sessionId || getCurrentSessionId());
|
||||
function _whoami(sessionId: string | null = null): Promise<WhoamiResponse> {
|
||||
return fetch.getJson<WhoamiResponse>('/auth/whoami', sessionId || getCurrentSessionId());
|
||||
}
|
||||
|
||||
function _getAuthSalts(email) {
|
||||
@@ -255,7 +287,7 @@ function _getAuthSalts(email) {
|
||||
);
|
||||
}
|
||||
|
||||
const _getSessionData = () => {
|
||||
const _getSessionData = (): Partial<SessionData> | null => {
|
||||
const sessionId = getCurrentSessionId();
|
||||
|
||||
if (!sessionId || !window) {
|
||||
@@ -266,7 +298,7 @@ const _getSessionData = () => {
|
||||
if (dataStr === null) {
|
||||
return null;
|
||||
}
|
||||
return JSON.parse(dataStr);
|
||||
return JSON.parse(dataStr) as SessionData;
|
||||
};
|
||||
|
||||
function _unsetSessionData() {
|
||||
|
||||
@@ -53,7 +53,6 @@ const sendSegment = async (segmentType: 'track' | 'page', options) => {
|
||||
export enum SegmentEvent {
|
||||
appStarted = 'App Started',
|
||||
collectionCreate = 'Collection Created',
|
||||
criticalError = 'Critical Error Encountered',
|
||||
dataExport = 'Data Exported',
|
||||
dataImport = 'Data Imported',
|
||||
documentCreate = 'Document Created',
|
||||
|
||||
@@ -20,9 +20,10 @@ export const getAppPlatform = () => process.platform;
|
||||
export const isMac = () => getAppPlatform() === 'darwin';
|
||||
export const isLinux = () => getAppPlatform() === 'linux';
|
||||
export const isWindows = () => getAppPlatform() === 'win32';
|
||||
const getAppEnvironment = () => process.env.INSOMNIA_ENV || 'production';
|
||||
export const getAppEnvironment = () => process.env.INSOMNIA_ENV || 'production';
|
||||
export const isDevelopment = () => getAppEnvironment() === 'development';
|
||||
export const getSegmentWriteKey = () => appConfig.segmentWriteKeys[(isDevelopment() || env.PLAYWRIGHT) ? 'development' : 'production'];
|
||||
export const getSentryDsn = () => appConfig.sentryDsn;
|
||||
export const getAppBuildDate = () => new Date(process.env.BUILD_DATE ?? '').toLocaleDateString();
|
||||
|
||||
export const getBrowserUserAgent = () => encodeURIComponent(
|
||||
|
||||
9
packages/insomnia/src/common/sentry.ts
Normal file
9
packages/insomnia/src/common/sentry.ts
Normal file
@@ -0,0 +1,9 @@
|
||||
import type { ElectronOptions } from '@sentry/electron';
|
||||
|
||||
import { getAppEnvironment, getAppVersion, getSentryDsn } from './constants';
|
||||
|
||||
export const SENTRY_OPTIONS: Partial<ElectronOptions> = {
|
||||
dsn: getSentryDsn(),
|
||||
environment: getAppEnvironment(),
|
||||
release: getAppVersion(),
|
||||
};
|
||||
@@ -11,8 +11,8 @@ import { database } from './common/database';
|
||||
import { disableSpellcheckerDownload } from './common/electron-helpers';
|
||||
import log, { initializeLogging } from './common/log';
|
||||
import { validateInsomniaConfig } from './common/validate-insomnia-config';
|
||||
import * as errorHandling from './main/error-handling';
|
||||
import * as grpcIpcMain from './main/grpc-ipc-main';
|
||||
import { initializeSentry, sentryWatchAnalyticsEnabled } from './main/sentry';
|
||||
import { checkIfRestartNeeded } from './main/squirrel-startup';
|
||||
import * as updates from './main/updates';
|
||||
import * as windowUtils from './main/window-utils';
|
||||
@@ -23,6 +23,8 @@ import { authorizeUserInWindow } from './network/o-auth-2/misc';
|
||||
import installPlugin from './plugins/install';
|
||||
import type { ToastNotification } from './ui/components/toast';
|
||||
|
||||
initializeSentry();
|
||||
|
||||
// Handle potential auto-update
|
||||
if (checkIfRestartNeeded()) {
|
||||
process.exit(0);
|
||||
@@ -84,7 +86,7 @@ app.on('ready', async () => {
|
||||
// Init some important things first
|
||||
await database.init(models.types());
|
||||
await _createModelInstances();
|
||||
errorHandling.init();
|
||||
sentryWatchAnalyticsEnabled();
|
||||
windowUtils.init();
|
||||
await _launchApp();
|
||||
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
export function init() {
|
||||
process.on('uncaughtException', err => {
|
||||
console.error('[catcher] Uncaught exception:', err.stack);
|
||||
});
|
||||
process.on('unhandledRejection', (err: Error) => {
|
||||
console.error('[catcher] Unhandled rejection:', err.stack);
|
||||
});
|
||||
}
|
||||
46
packages/insomnia/src/main/sentry.ts
Normal file
46
packages/insomnia/src/main/sentry.ts
Normal file
@@ -0,0 +1,46 @@
|
||||
import * as Sentry from '@sentry/electron/main';
|
||||
import type { SentryRequestType } from '@sentry/types';
|
||||
|
||||
import { database as db } from '../common/database';
|
||||
import { SENTRY_OPTIONS } from '../common/sentry';
|
||||
import * as models from '../models/index';
|
||||
import { isSettings } from '../models/settings';
|
||||
|
||||
let enabled = false;
|
||||
|
||||
/**
|
||||
* Watch setting for changes. This must be called after the DB is initialized.
|
||||
*/
|
||||
export function sentryWatchAnalyticsEnabled() {
|
||||
models.settings.getOrCreate().then(settings => {
|
||||
enabled = settings.enableAnalytics;
|
||||
});
|
||||
|
||||
db.onChange(async changes => {
|
||||
for (const change of changes) {
|
||||
const [event, doc] = change;
|
||||
if (isSettings(doc) && event === 'update') {
|
||||
enabled = doc.enableAnalytics;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// TODO(johnwchadwick): We are vendoring ElectronOfflineNetTransport just to be able to control whether or not sending is allowed, because we don't have a choice right now. We should work with the upstream library to get similar functionality upstream. See getsentry/sentry-electron#489.
|
||||
// https://github.com/getsentry/sentry-electron/issues/489
|
||||
class ElectronSwitchableTransport extends Sentry.ElectronOfflineNetTransport {
|
||||
protected _isRateLimited(requestType: SentryRequestType) {
|
||||
if (!enabled) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return super._isRateLimited(requestType);
|
||||
}
|
||||
}
|
||||
|
||||
export function initializeSentry() {
|
||||
Sentry.init({
|
||||
...SENTRY_OPTIONS,
|
||||
transport: ElectronSwitchableTransport,
|
||||
});
|
||||
}
|
||||
@@ -869,7 +869,7 @@ export class VCS {
|
||||
// the user created snapshots while not logged in
|
||||
for (const snapshot of snapshots) {
|
||||
if (snapshot.author === '') {
|
||||
snapshot.author = accountId;
|
||||
snapshot.author = accountId || '';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -145,7 +145,7 @@ export class Toast extends PureComponent<{}, State> {
|
||||
updatesNotSupported: !updatesSupported(),
|
||||
version: getAppVersion(),
|
||||
};
|
||||
notification = await fetch.post('/notification', data, session.getCurrentSessionId());
|
||||
notification = await fetch.postJson<ToastNotification>('/notification', data, session.getCurrentSessionId());
|
||||
} catch (err) {
|
||||
console.warn('[toast] Failed to fetch user notifications', err);
|
||||
}
|
||||
|
||||
@@ -4,7 +4,6 @@ import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import { Provider } from 'react-redux';
|
||||
|
||||
import { SegmentEvent, trackSegmentEvent } from '../common/analytics';
|
||||
import { getProductName, isDevelopment } from '../common/constants';
|
||||
import { database as db } from '../common/database';
|
||||
import { initializeLogging } from '../common/log';
|
||||
@@ -14,9 +13,11 @@ import { init as initPlugins } from '../plugins';
|
||||
import { applyColorScheme } from '../plugins/misc';
|
||||
import App from './containers/app';
|
||||
import { init as initStore } from './redux/modules';
|
||||
import { initializeSentry } from './sentry';
|
||||
|
||||
import './css/index.less'; // this import must come after `App`. the reason is not yet known.
|
||||
|
||||
initializeSentry();
|
||||
initializeLogging();
|
||||
// Handy little helper
|
||||
document.body.setAttribute('data-platform', process.platform);
|
||||
@@ -24,7 +25,9 @@ document.title = getProductName();
|
||||
|
||||
(async function() {
|
||||
await db.initClient();
|
||||
|
||||
await initPlugins();
|
||||
|
||||
const settings = await models.settings.getOrCreate();
|
||||
|
||||
if (settings.clearOAuth2SessionOnRestart) {
|
||||
@@ -56,18 +59,6 @@ if (isDevelopment()) {
|
||||
window.db = db;
|
||||
}
|
||||
|
||||
// Catch uncaught errors and report them
|
||||
if (window && !isDevelopment()) {
|
||||
window.addEventListener('error', e => {
|
||||
console.error('Uncaught Error', e.error || e);
|
||||
trackSegmentEvent(SegmentEvent.criticalError, { detail: e?.message });
|
||||
});
|
||||
window.addEventListener('unhandledrejection', e => {
|
||||
console.error('Unhandled Promise', e.reason);
|
||||
trackSegmentEvent(SegmentEvent.criticalError, { detail: e?.reason });
|
||||
});
|
||||
}
|
||||
|
||||
function showUpdateNotification() {
|
||||
console.log('[app] Update Available');
|
||||
// eslint-disable-next-line no-new
|
||||
|
||||
27
packages/insomnia/src/ui/sentry.ts
Normal file
27
packages/insomnia/src/ui/sentry.ts
Normal file
@@ -0,0 +1,27 @@
|
||||
import * as Sentry from '@sentry/electron';
|
||||
|
||||
import { getAccountId, onLoginLogout } from '../account/session';
|
||||
import { SENTRY_OPTIONS } from '../common/sentry';
|
||||
|
||||
/** Configures user info in Sentry scope. */
|
||||
function sentryConfigureUserInfo() {
|
||||
Sentry.configureScope(scope => {
|
||||
const id = getAccountId();
|
||||
if (id) {
|
||||
scope.setUser({ id });
|
||||
} else {
|
||||
scope.setUser(null);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/** Watches user info for changes. */
|
||||
function sentryWatchUserInfo() {
|
||||
sentryConfigureUserInfo();
|
||||
onLoginLogout(() => sentryConfigureUserInfo());
|
||||
}
|
||||
|
||||
export function initializeSentry() {
|
||||
Sentry.init(SENTRY_OPTIONS);
|
||||
sentryWatchUserInfo();
|
||||
}
|
||||
Reference in New Issue
Block a user