Apply prettier formatting
This commit is contained in:
parent
1cac306093
commit
526645c791
1576 changed files with 65385 additions and 62478 deletions
|
@ -54,7 +54,7 @@ type LogFunctionName = "log" | "info" | "warn" | "error";
|
|||
// A class which monkey-patches the global console and stores log lines.
|
||||
export class ConsoleLogger {
|
||||
private logs = "";
|
||||
private originalFunctions: {[key in LogFunctionName]?: LogFunction} = {};
|
||||
private originalFunctions: { [key in LogFunctionName]?: LogFunction } = {};
|
||||
|
||||
public monkeyPatch(consoleObj: Console): void {
|
||||
// Monkey-patch console logging
|
||||
|
@ -75,10 +75,7 @@ export class ConsoleLogger {
|
|||
});
|
||||
}
|
||||
|
||||
public bypassRageshake(
|
||||
fnName: LogFunctionName,
|
||||
...args: (Error | DOMException | object | string)[]
|
||||
): void {
|
||||
public bypassRageshake(fnName: LogFunctionName, ...args: (Error | DOMException | object | string)[]): void {
|
||||
this.originalFunctions[fnName](...args);
|
||||
}
|
||||
|
||||
|
@ -91,8 +88,8 @@ export class ConsoleLogger {
|
|||
if (arg instanceof DOMException) {
|
||||
return arg.message + ` (${arg.name} | ${arg.code})`;
|
||||
} else if (arg instanceof Error) {
|
||||
return arg.message + (arg.stack ? `\n${arg.stack}` : '');
|
||||
} else if (typeof (arg) === 'object') {
|
||||
return arg.message + (arg.stack ? `\n${arg.stack}` : "");
|
||||
} else if (typeof arg === "object") {
|
||||
return JSON.stringify(arg, getCircularReplacer());
|
||||
} else {
|
||||
return arg;
|
||||
|
@ -104,9 +101,9 @@ export class ConsoleLogger {
|
|||
// run.
|
||||
// Example line:
|
||||
// 2017-01-18T11:23:53.214Z W Failed to set badge count
|
||||
let line = `${ts} ${level} ${args.join(' ')}\n`;
|
||||
let line = `${ts} ${level} ${args.join(" ")}\n`;
|
||||
// Do some cleanup
|
||||
line = line.replace(/token=[a-zA-Z0-9-]+/gm, 'token=xxxxx');
|
||||
line = line.replace(/token=[a-zA-Z0-9-]+/gm, "token=xxxxx");
|
||||
// Using + really is the quickest way in JS
|
||||
// http://jsperf.com/concat-vs-plus-vs-join
|
||||
this.logs += line;
|
||||
|
@ -137,10 +134,7 @@ export class IndexedDBLogStore {
|
|||
private flushPromise = null;
|
||||
private flushAgainPromise = null;
|
||||
|
||||
constructor(
|
||||
private indexedDB: IDBFactory,
|
||||
private logger: ConsoleLogger,
|
||||
) {
|
||||
constructor(private indexedDB: IDBFactory, private logger: ConsoleLogger) {
|
||||
this.id = "instance-" + randomString(16);
|
||||
}
|
||||
|
||||
|
@ -159,10 +153,9 @@ export class IndexedDBLogStore {
|
|||
};
|
||||
|
||||
req.onerror = (event) => {
|
||||
const err = (
|
||||
const err =
|
||||
// @ts-ignore
|
||||
"Failed to open log database: " + event.target.error.name
|
||||
);
|
||||
"Failed to open log database: " + event.target.error.name;
|
||||
logger.error(err);
|
||||
reject(new Error(err));
|
||||
};
|
||||
|
@ -179,11 +172,7 @@ export class IndexedDBLogStore {
|
|||
// In order to do this, we need to set up indexes "id".
|
||||
logObjStore.createIndex("id", "id", { unique: false });
|
||||
|
||||
logObjStore.add(
|
||||
this.generateLogEntry(
|
||||
new Date() + " ::: Log database was created.",
|
||||
),
|
||||
);
|
||||
logObjStore.add(this.generateLogEntry(new Date() + " ::: Log database was created."));
|
||||
|
||||
const lastModifiedStore = db.createObjectStore("logslastmod", {
|
||||
keyPath: "id",
|
||||
|
@ -220,11 +209,13 @@ export class IndexedDBLogStore {
|
|||
return this.flushAgainPromise;
|
||||
}
|
||||
// queue up a flush to occur immediately after the pending one completes.
|
||||
this.flushAgainPromise = this.flushPromise.then(() => {
|
||||
return this.flush();
|
||||
}).then(() => {
|
||||
this.flushAgainPromise = null;
|
||||
});
|
||||
this.flushAgainPromise = this.flushPromise
|
||||
.then(() => {
|
||||
return this.flush();
|
||||
})
|
||||
.then(() => {
|
||||
this.flushAgainPromise = null;
|
||||
});
|
||||
return this.flushAgainPromise;
|
||||
}
|
||||
// there is no flush promise or there was but it has finished, so do
|
||||
|
@ -246,12 +237,8 @@ export class IndexedDBLogStore {
|
|||
resolve();
|
||||
};
|
||||
txn.onerror = (event) => {
|
||||
logger.error(
|
||||
"Failed to flush logs : ", event,
|
||||
);
|
||||
reject(
|
||||
new Error("Failed to write logs: " + event.target.errorCode),
|
||||
);
|
||||
logger.error("Failed to flush logs : ", event);
|
||||
reject(new Error("Failed to write logs: " + event.target.errorCode));
|
||||
};
|
||||
objStore.add(this.generateLogEntry(lines));
|
||||
const lastModStore = txn.objectStore("logslastmod");
|
||||
|
@ -272,7 +259,7 @@ export class IndexedDBLogStore {
|
|||
* log ID). The objects have said log ID in an "id" field and "lines" which
|
||||
* is a big string with all the new-line delimited logs.
|
||||
*/
|
||||
public async consume(): Promise<{lines: string, id: string}[]> {
|
||||
public async consume(): Promise<{ lines: string; id: string }[]> {
|
||||
const db = this.db;
|
||||
|
||||
// Returns: a string representing the concatenated logs for this ID.
|
||||
|
@ -281,8 +268,8 @@ export class IndexedDBLogStore {
|
|||
const objectStore = db.transaction("logs", "readonly").objectStore("logs");
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
const query = objectStore.index("id").openCursor(IDBKeyRange.only(id), 'prev');
|
||||
let lines = '';
|
||||
const query = objectStore.index("id").openCursor(IDBKeyRange.only(id), "prev");
|
||||
let lines = "";
|
||||
query.onerror = (event) => {
|
||||
reject(new Error("Query failed: " + event.target.errorCode));
|
||||
};
|
||||
|
@ -305,9 +292,7 @@ export class IndexedDBLogStore {
|
|||
// Returns: A sorted array of log IDs. (newest first)
|
||||
function fetchLogIds(): Promise<string[]> {
|
||||
// To gather all the log IDs, query for all records in logslastmod.
|
||||
const o = db.transaction("logslastmod", "readonly").objectStore(
|
||||
"logslastmod",
|
||||
);
|
||||
const o = db.transaction("logslastmod", "readonly").objectStore("logslastmod");
|
||||
return selectQuery(o, undefined, (cursor) => {
|
||||
return {
|
||||
id: cursor.value.id,
|
||||
|
@ -315,17 +300,17 @@ export class IndexedDBLogStore {
|
|||
};
|
||||
}).then((res) => {
|
||||
// Sort IDs by timestamp (newest first)
|
||||
return res.sort((a, b) => {
|
||||
return b.ts - a.ts;
|
||||
}).map((a) => a.id);
|
||||
return res
|
||||
.sort((a, b) => {
|
||||
return b.ts - a.ts;
|
||||
})
|
||||
.map((a) => a.id);
|
||||
});
|
||||
}
|
||||
|
||||
function deleteLogs(id: number): Promise<void> {
|
||||
return new Promise<void>((resolve, reject) => {
|
||||
const txn = db.transaction(
|
||||
["logs", "logslastmod"], "readwrite",
|
||||
);
|
||||
const txn = db.transaction(["logs", "logslastmod"], "readwrite");
|
||||
const o = txn.objectStore("logs");
|
||||
// only load the key path, not the data which may be huge
|
||||
const query = o.index("id").openKeyCursor(IDBKeyRange.only(id));
|
||||
|
@ -341,12 +326,7 @@ export class IndexedDBLogStore {
|
|||
resolve();
|
||||
};
|
||||
txn.onerror = (event) => {
|
||||
reject(
|
||||
new Error(
|
||||
"Failed to delete logs for " +
|
||||
`'${id}' : ${event.target.errorCode}`,
|
||||
),
|
||||
);
|
||||
reject(new Error("Failed to delete logs for " + `'${id}' : ${event.target.errorCode}`));
|
||||
};
|
||||
// delete last modified entries
|
||||
const lastModStore = txn.objectStore("logslastmod");
|
||||
|
@ -382,16 +362,19 @@ export class IndexedDBLogStore {
|
|||
logger.log("Removing logs: ", removeLogIds);
|
||||
// Don't await this because it's non-fatal if we can't clean up
|
||||
// logs.
|
||||
Promise.all(removeLogIds.map((id) => deleteLogs(id))).then(() => {
|
||||
logger.log(`Removed ${removeLogIds.length} old logs.`);
|
||||
}, (err) => {
|
||||
logger.error(err);
|
||||
});
|
||||
Promise.all(removeLogIds.map((id) => deleteLogs(id))).then(
|
||||
() => {
|
||||
logger.log(`Removed ${removeLogIds.length} old logs.`);
|
||||
},
|
||||
(err) => {
|
||||
logger.error(err);
|
||||
},
|
||||
);
|
||||
}
|
||||
return logs;
|
||||
}
|
||||
|
||||
private generateLogEntry(lines: string): {id: string, lines: string, index: number} {
|
||||
private generateLogEntry(lines: string): { id: string; lines: string; index: number } {
|
||||
return {
|
||||
id: this.id,
|
||||
lines: lines,
|
||||
|
@ -399,7 +382,7 @@ export class IndexedDBLogStore {
|
|||
};
|
||||
}
|
||||
|
||||
private generateLastModifiedTime(): {id: string, ts: number} {
|
||||
private generateLastModifiedTime(): { id: string; ts: number } {
|
||||
return {
|
||||
id: this.id,
|
||||
ts: Date.now(),
|
||||
|
@ -418,7 +401,9 @@ export class IndexedDBLogStore {
|
|||
* resultMapper.
|
||||
*/
|
||||
function selectQuery<T>(
|
||||
store: IDBIndex, keyRange: IDBKeyRange, resultMapper: (cursor: IDBCursorWithValue) => T,
|
||||
store: IDBIndex,
|
||||
keyRange: IDBKeyRange,
|
||||
resultMapper: (cursor: IDBCursorWithValue) => T,
|
||||
): Promise<T[]> {
|
||||
const query = store.openCursor(keyRange);
|
||||
return new Promise((resolve, reject) => {
|
||||
|
@ -516,9 +501,7 @@ export async function cleanup() {
|
|||
*/
|
||||
export async function getLogsForReport() {
|
||||
if (!global.mx_rage_logger) {
|
||||
throw new Error(
|
||||
"No console logger, did you forget to call init()?",
|
||||
);
|
||||
throw new Error("No console logger, did you forget to call init()?");
|
||||
}
|
||||
// If in incognito mode, store is null, but we still want bug report
|
||||
// sending to work going off the in-memory console logs.
|
||||
|
@ -527,9 +510,11 @@ export async function getLogsForReport() {
|
|||
await global.mx_rage_store.flush();
|
||||
return global.mx_rage_store.consume();
|
||||
} else {
|
||||
return [{
|
||||
lines: global.mx_rage_logger.flush(true),
|
||||
id: "-",
|
||||
}];
|
||||
return [
|
||||
{
|
||||
lines: global.mx_rage_logger.flush(true),
|
||||
id: "-",
|
||||
},
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,14 +16,14 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
import pako from 'pako';
|
||||
import pako from "pako";
|
||||
import Tar from "tar-js";
|
||||
import { logger } from "matrix-js-sdk/src/logger";
|
||||
|
||||
import { MatrixClientPeg } from '../MatrixClientPeg';
|
||||
import PlatformPeg from '../PlatformPeg';
|
||||
import { _t } from '../languageHandler';
|
||||
import * as rageshake from './rageshake';
|
||||
import { MatrixClientPeg } from "../MatrixClientPeg";
|
||||
import PlatformPeg from "../PlatformPeg";
|
||||
import { _t } from "../languageHandler";
|
||||
import * as rageshake from "./rageshake";
|
||||
import SettingsStore from "../settings/SettingsStore";
|
||||
import SdkConfig from "../SdkConfig";
|
||||
|
||||
|
@ -53,26 +53,26 @@ async function collectBugReport(opts: IOpts = {}, gzipLogs = true) {
|
|||
let installedPWA = "UNKNOWN";
|
||||
try {
|
||||
// Known to work at least for desktop Chrome
|
||||
installedPWA = String(window.matchMedia('(display-mode: standalone)').matches);
|
||||
installedPWA = String(window.matchMedia("(display-mode: standalone)").matches);
|
||||
} catch (e) {}
|
||||
|
||||
let touchInput = "UNKNOWN";
|
||||
try {
|
||||
// MDN claims broad support across browsers
|
||||
touchInput = String(window.matchMedia('(pointer: coarse)').matches);
|
||||
} catch (e) { }
|
||||
touchInput = String(window.matchMedia("(pointer: coarse)").matches);
|
||||
} catch (e) {}
|
||||
|
||||
const client = MatrixClientPeg.get();
|
||||
|
||||
logger.log("Sending bug report.");
|
||||
|
||||
const body = new FormData();
|
||||
body.append('text', opts.userText || "User did not supply any additional text.");
|
||||
body.append('app', opts.customApp || 'element-web');
|
||||
body.append('version', version);
|
||||
body.append('user_agent', userAgent);
|
||||
body.append('installed_pwa', installedPWA);
|
||||
body.append('touch_input', touchInput);
|
||||
body.append("text", opts.userText || "User did not supply any additional text.");
|
||||
body.append("app", opts.customApp || "element-web");
|
||||
body.append("version", version);
|
||||
body.append("user_agent", userAgent);
|
||||
body.append("installed_pwa", installedPWA);
|
||||
body.append("touch_input", touchInput);
|
||||
|
||||
if (opts.customFields) {
|
||||
for (const key in opts.customFields) {
|
||||
|
@ -81,35 +81,45 @@ async function collectBugReport(opts: IOpts = {}, gzipLogs = true) {
|
|||
}
|
||||
|
||||
if (client) {
|
||||
body.append('user_id', client.credentials.userId);
|
||||
body.append('device_id', client.deviceId);
|
||||
body.append("user_id", client.credentials.userId);
|
||||
body.append("device_id", client.deviceId);
|
||||
|
||||
if (client.isCryptoEnabled()) {
|
||||
const keys = [`ed25519:${client.getDeviceEd25519Key()}`];
|
||||
if (client.getDeviceCurve25519Key) {
|
||||
keys.push(`curve25519:${client.getDeviceCurve25519Key()}`);
|
||||
}
|
||||
body.append('device_keys', keys.join(', '));
|
||||
body.append('cross_signing_key', client.getCrossSigningId());
|
||||
body.append("device_keys", keys.join(", "));
|
||||
body.append("cross_signing_key", client.getCrossSigningId());
|
||||
|
||||
// add cross-signing status information
|
||||
const crossSigning = client.crypto.crossSigningInfo;
|
||||
const secretStorage = client.crypto.secretStorage;
|
||||
|
||||
body.append("cross_signing_ready", String(await client.isCrossSigningReady()));
|
||||
body.append("cross_signing_supported_by_hs",
|
||||
String(await client.doesServerSupportUnstableFeature("org.matrix.e2e_cross_signing")));
|
||||
body.append(
|
||||
"cross_signing_supported_by_hs",
|
||||
String(await client.doesServerSupportUnstableFeature("org.matrix.e2e_cross_signing")),
|
||||
);
|
||||
body.append("cross_signing_key", crossSigning.getId());
|
||||
body.append("cross_signing_privkey_in_secret_storage",
|
||||
String(!!(await crossSigning.isStoredInSecretStorage(secretStorage))));
|
||||
body.append(
|
||||
"cross_signing_privkey_in_secret_storage",
|
||||
String(!!(await crossSigning.isStoredInSecretStorage(secretStorage))),
|
||||
);
|
||||
|
||||
const pkCache = client.getCrossSigningCacheCallbacks();
|
||||
body.append("cross_signing_master_privkey_cached",
|
||||
String(!!(pkCache && (await pkCache.getCrossSigningKeyCache("master")))));
|
||||
body.append("cross_signing_self_signing_privkey_cached",
|
||||
String(!!(pkCache && (await pkCache.getCrossSigningKeyCache("self_signing")))));
|
||||
body.append("cross_signing_user_signing_privkey_cached",
|
||||
String(!!(pkCache && (await pkCache.getCrossSigningKeyCache("user_signing")))));
|
||||
body.append(
|
||||
"cross_signing_master_privkey_cached",
|
||||
String(!!(pkCache && (await pkCache.getCrossSigningKeyCache("master")))),
|
||||
);
|
||||
body.append(
|
||||
"cross_signing_self_signing_privkey_cached",
|
||||
String(!!(pkCache && (await pkCache.getCrossSigningKeyCache("self_signing")))),
|
||||
);
|
||||
body.append(
|
||||
"cross_signing_user_signing_privkey_cached",
|
||||
String(!!(pkCache && (await pkCache.getCrossSigningKeyCache("user_signing")))),
|
||||
);
|
||||
|
||||
body.append("secret_storage_ready", String(await client.isSecretStorageReady()));
|
||||
body.append("secret_storage_key_in_account", String(!!(await secretStorage.hasKey())));
|
||||
|
@ -123,14 +133,14 @@ async function collectBugReport(opts: IOpts = {}, gzipLogs = true) {
|
|||
|
||||
if (opts.labels) {
|
||||
for (const label of opts.labels) {
|
||||
body.append('label', label);
|
||||
body.append("label", label);
|
||||
}
|
||||
}
|
||||
|
||||
// add labs options
|
||||
const enabledLabs = SettingsStore.getFeatureSettingNames().filter(f => SettingsStore.getValue(f));
|
||||
const enabledLabs = SettingsStore.getFeatureSettingNames().filter((f) => SettingsStore.getValue(f));
|
||||
if (enabledLabs.length) {
|
||||
body.append('enabled_labs', enabledLabs.join(', '));
|
||||
body.append("enabled_labs", enabledLabs.join(", "));
|
||||
}
|
||||
// if low bandwidth mode is enabled, say so over rageshake, it causes many issues
|
||||
if (SettingsStore.getValue("lowBandwidth")) {
|
||||
|
@ -142,7 +152,8 @@ async function collectBugReport(opts: IOpts = {}, gzipLogs = true) {
|
|||
try {
|
||||
body.append("storageManager_persisted", String(await navigator.storage.persisted()));
|
||||
} catch (e) {}
|
||||
} else if (document.hasStorageAccess) { // Safari
|
||||
} else if (document.hasStorageAccess) {
|
||||
// Safari
|
||||
try {
|
||||
body.append("storageManager_persisted", String(await document.hasStorageAccess()));
|
||||
} catch (e) {}
|
||||
|
@ -153,7 +164,7 @@ async function collectBugReport(opts: IOpts = {}, gzipLogs = true) {
|
|||
body.append("storageManager_quota", String(estimate.quota));
|
||||
body.append("storageManager_usage", String(estimate.usage));
|
||||
if (estimate.usageDetails) {
|
||||
Object.keys(estimate.usageDetails).forEach(k => {
|
||||
Object.keys(estimate.usageDetails).forEach((k) => {
|
||||
body.append(`storageManager_usage_${k}`, String(estimate.usageDetails[k]));
|
||||
});
|
||||
}
|
||||
|
@ -161,13 +172,13 @@ async function collectBugReport(opts: IOpts = {}, gzipLogs = true) {
|
|||
}
|
||||
|
||||
if (window.Modernizr) {
|
||||
const missingFeatures = Object.keys(window.Modernizr).filter(key => window.Modernizr[key] === false);
|
||||
const missingFeatures = Object.keys(window.Modernizr).filter((key) => window.Modernizr[key] === false);
|
||||
if (missingFeatures.length > 0) {
|
||||
body.append("modernizr_missing_features", missingFeatures.join(", "));
|
||||
}
|
||||
}
|
||||
|
||||
body.append("mx_local_settings", localStorage.getItem('mx_local_settings'));
|
||||
body.append("mx_local_settings", localStorage.getItem("mx_local_settings"));
|
||||
|
||||
if (opts.sendLogs) {
|
||||
progressCallback(_t("Collecting logs"));
|
||||
|
@ -181,7 +192,7 @@ async function collectBugReport(opts: IOpts = {}, gzipLogs = true) {
|
|||
buf = pako.gzip(buf);
|
||||
}
|
||||
|
||||
body.append('compressed-log', new Blob([buf]), entry.id);
|
||||
body.append("compressed-log", new Blob([buf]), entry.id);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -238,26 +249,26 @@ export async function downloadBugReport(opts: IOpts = {}) {
|
|||
const tape = new Tar();
|
||||
let i = 0;
|
||||
for (const [key, value] of body.entries()) {
|
||||
if (key === 'compressed-log') {
|
||||
await new Promise<void>((resolve => {
|
||||
if (key === "compressed-log") {
|
||||
await new Promise<void>((resolve) => {
|
||||
const reader = new FileReader();
|
||||
reader.addEventListener('loadend', ev => {
|
||||
reader.addEventListener("loadend", (ev) => {
|
||||
tape.append(`log-${i++}.log`, new TextDecoder().decode(ev.target.result as ArrayBuffer));
|
||||
resolve();
|
||||
});
|
||||
reader.readAsArrayBuffer(value as Blob);
|
||||
}));
|
||||
});
|
||||
} else {
|
||||
metadata += `${key} = ${value}\n`;
|
||||
}
|
||||
}
|
||||
tape.append('issue.txt', metadata);
|
||||
tape.append("issue.txt", metadata);
|
||||
|
||||
// We have to create a new anchor to download if we want a filename. Otherwise we could
|
||||
// just use window.open.
|
||||
const dl = document.createElement('a');
|
||||
const dl = document.createElement("a");
|
||||
dl.href = `data:application/octet-stream;base64,${btoa(uint8ToString(tape.out))}`;
|
||||
dl.download = 'rageshake.tar';
|
||||
dl.download = "rageshake.tar";
|
||||
document.body.appendChild(dl);
|
||||
dl.click();
|
||||
document.body.removeChild(dl);
|
||||
|
@ -265,7 +276,7 @@ export async function downloadBugReport(opts: IOpts = {}) {
|
|||
|
||||
// Source: https://github.com/beatgammit/tar-js/blob/master/examples/main.js
|
||||
function uint8ToString(buf: Buffer) {
|
||||
let out = '';
|
||||
let out = "";
|
||||
for (let i = 0; i < buf.length; i += 1) {
|
||||
out += String.fromCharCode(buf[i]);
|
||||
}
|
||||
|
@ -307,7 +318,7 @@ function submitReport(endpoint: string, body: FormData, progressCallback: (str:
|
|||
req.open("POST", endpoint);
|
||||
req.responseType = "json";
|
||||
req.timeout = 5 * 60 * 1000;
|
||||
req.onreadystatechange = function() {
|
||||
req.onreadystatechange = function () {
|
||||
if (req.readyState === XMLHttpRequest.LOADING) {
|
||||
progressCallback(_t("Waiting for response from server"));
|
||||
} else if (req.readyState === XMLHttpRequest.DONE) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue