Merge pull request #601 from vector-im/filter-token
Ensure unwanted data do not end up in logs
This commit is contained in:
commit
19827a0b5b
3 changed files with 55 additions and 12 deletions
|
@ -17,15 +17,17 @@ limitations under the License.
|
|||
|
||||
import {LogItem} from "./LogItem";
|
||||
import {LogLevel, LogFilter} from "./LogFilter";
|
||||
import type {ILogger, ILogExport, FilterCreator, LabelOrValues, LogCallback, ILogItem} from "./types";
|
||||
import type {ILogger, ILogExport, FilterCreator, LabelOrValues, LogCallback, ILogItem, ISerializedItem} from "./types";
|
||||
import type {Platform} from "../platform/web/Platform.js";
|
||||
|
||||
export abstract class BaseLogger implements ILogger {
|
||||
protected _openItems: Set<LogItem> = new Set();
|
||||
protected _platform: Platform;
|
||||
protected _serializedTransformer: (item: ISerializedItem) => ISerializedItem;
|
||||
|
||||
constructor({platform}) {
|
||||
constructor({platform, serializedTransformer = (item: ISerializedItem) => item}) {
|
||||
this._platform = platform;
|
||||
this._serializedTransformer = serializedTransformer;
|
||||
}
|
||||
|
||||
log(labelOrValues: LabelOrValues, logLevel: LogLevel = LogLevel.Info): void {
|
||||
|
|
|
@ -26,7 +26,7 @@ import {BaseLogger} from "./BaseLogger";
|
|||
import type {Interval} from "../platform/web/dom/Clock";
|
||||
import type {Platform} from "../platform/web/Platform.js";
|
||||
import type {BlobHandle} from "../platform/web/dom/BlobHandle.js";
|
||||
import type {ILogItem, ILogExport} from "./types";
|
||||
import type {ILogItem, ILogExport, ISerializedItem} from "./types";
|
||||
import type {LogFilter} from "./LogFilter";
|
||||
|
||||
type QueuedItem = {
|
||||
|
@ -40,7 +40,7 @@ export class IDBLogger extends BaseLogger {
|
|||
private readonly _flushInterval: Interval;
|
||||
private _queuedItems: QueuedItem[];
|
||||
|
||||
constructor(options: {name: string, flushInterval?: number, limit?: number, platform: Platform}) {
|
||||
constructor(options: {name: string, flushInterval?: number, limit?: number, platform: Platform, serializedTransformer?: (item: ISerializedItem) => ISerializedItem}) {
|
||||
super(options);
|
||||
const {name, flushInterval = 60 * 1000, limit = 3000} = options;
|
||||
this._name = name;
|
||||
|
@ -119,10 +119,13 @@ export class IDBLogger extends BaseLogger {
|
|||
|
||||
_persistItem(logItem: ILogItem, filter: LogFilter, forced: boolean): void {
|
||||
const serializedItem = logItem.serialize(filter, undefined, forced);
|
||||
if (serializedItem) {
|
||||
const transformedSerializedItem = this._serializedTransformer(serializedItem);
|
||||
this._queuedItems.push({
|
||||
json: JSON.stringify(serializedItem)
|
||||
json: JSON.stringify(transformedSerializedItem)
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
_persistQueuedItems(items: QueuedItem[]): void {
|
||||
try {
|
||||
|
|
|
@ -132,11 +132,7 @@ export class Platform {
|
|||
this.clock = new Clock();
|
||||
this.encoding = new Encoding();
|
||||
this.random = Math.random;
|
||||
if (options?.development) {
|
||||
this.logger = new ConsoleLogger({platform: this});
|
||||
} else {
|
||||
this.logger = new IDBLogger({name: "hydrogen_logs", platform: this});
|
||||
}
|
||||
this._createLogger(options?.development);
|
||||
this.history = new History();
|
||||
this.onlineStatus = new OnlineStatus();
|
||||
this._serviceWorkerHandler = null;
|
||||
|
@ -162,6 +158,21 @@ export class Platform {
|
|||
this._disposables = new Disposables();
|
||||
}
|
||||
|
||||
_createLogger(isDevelopment) {
|
||||
// Make sure that loginToken does not end up in the logs
|
||||
const transformer = (item) => {
|
||||
if (item.e?.stack) {
|
||||
item.e.stack = item.e.stack.replace(/(?<=\/\?loginToken=).+/, "<snip>");
|
||||
}
|
||||
return item;
|
||||
};
|
||||
if (isDevelopment) {
|
||||
this.logger = new ConsoleLogger({platform: this});
|
||||
} else {
|
||||
this.logger = new IDBLogger({name: "hydrogen_logs", platform: this, serializedTransformer: transformer});
|
||||
}
|
||||
}
|
||||
|
||||
get updateService() {
|
||||
return this._serviceWorkerHandler;
|
||||
}
|
||||
|
@ -272,3 +283,30 @@ export class Platform {
|
|||
this._disposables.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
import {LogItem} from "../../logging/LogItem";
|
||||
export function tests() {
|
||||
return {
|
||||
"loginToken should not be in logs": (assert) => {
|
||||
const transformer = (item) => {
|
||||
if (item.e?.stack) {
|
||||
item.e.stack = item.e.stack.replace(/(?<=\/\?loginToken=).+/, "<snip>");
|
||||
}
|
||||
return item;
|
||||
};
|
||||
const logger = {
|
||||
_queuedItems: [],
|
||||
_serializedTransformer: transformer,
|
||||
_now: () => {}
|
||||
};
|
||||
logger.persist = IDBLogger.prototype._persistItem.bind(logger);
|
||||
const logItem = new LogItem("test", 1, logger);
|
||||
logItem.error = new Error();
|
||||
logItem.error.stack = "main http://localhost:3000/src/main.js:55\n<anonymous> http://localhost:3000/?loginToken=secret:26"
|
||||
logger.persist(logItem, null, false);
|
||||
const item = logger._queuedItems.pop();
|
||||
console.log(item);
|
||||
assert.strictEqual(item.json.search("secret"), -1);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
Reference in a new issue