fix(database): keep SQL trace values private

This commit is contained in:
4gray committed 2026-07-30 12:07:46 +02:00
1 parent 1e027b8e40
commit 6bb7e764d8
11 files changed
+220 -25

No files matched your search

@@ -18,6 +18,10 @@ function createdObjectNames(prefix: string, statements: readonly string[]) {
}
describe('database schema statements', () => {
afterEach(() => {
jest.restoreAllMocks();
});
const {
createTableStatements,
columnMigrationStatements,
@@ -37,6 +41,26 @@ describe('database schema statements', () => {
}
).ensureDownloadsPauseResumeSchema;
it('records only the statement type for expanded main-process SQL', () => {
jest.spyOn(console, 'log').mockImplementation(() => undefined);
const secrets = [
'main-user-secret',
'main-password-secret',
'https://main-user:main-password@example.com/live?token=main-token-secret',
];
__databaseConnectionTestHooks.traceSqlStatement(
`UPDATE playlists SET username = '${secrets[0]}', password = '${secrets[1]}', url = '${secrets[2]}'`
);
const output = (console.log as jest.Mock).mock.calls.flat().join('\n');
expect(output).toContain('"statementType":"UPDATE"');
expect(output).not.toContain('UPDATE playlists');
for (const secret of secrets) {
expect(output).not.toContain(secret);
}
});
function createRebuildSqlite(legacyTableSql: string | undefined) {
const statements: string[] = [];
const transaction = jest.fn((callback: () => void) => callback);
+13 -13
View File
@@ -12,6 +12,10 @@
import Database from 'better-sqlite3';
import type { BetterSQLite3Database } from 'drizzle-orm/better-sqlite3';
import { drizzle } from 'drizzle-orm/better-sqlite3';
import {
redactSensitiveData,
summarizeSqlStatementForTrace,
} from '@iptvnator/shared/logging';
import * as schema from './schema';
import { getIptvnatorDatabasePath } from './path-utils';
@@ -49,13 +53,6 @@ function isSqlTraceEnabled(): boolean {
);
}
function compactSqlForTrace(sql: string): string {
const compactSql = sql.replace(/\s+/g, ' ').trim();
return compactSql.length <= 180
? compactSql
: `${compactSql.slice(0, 177)}...`;
}
function traceSql(scope: string, message: string, payload?: unknown): void {
if (payload === undefined) {
console.log(`[IPTVnator Trace][${scope}] ${message}`);
@@ -63,10 +60,16 @@ function traceSql(scope: string, message: string, payload?: unknown): void {
}
console.log(
`[IPTVnator Trace][${scope}] ${message} ${JSON.stringify(payload)}`
`[IPTVnator Trace][${scope}] ${message} ${JSON.stringify(
redactSensitiveData(payload)
)}`
);
}
function traceSqlStatement(sql: unknown): void {
traceSql('sql-main', 'query', summarizeSqlStatementForTrace(sql));
}
/**
* Get the database file path
*/
@@ -402,6 +405,7 @@ export const __databaseConnectionTestHooks = {
backfillEpgProgramSourceUrls,
cleanupLegacyTmdbSearchCache,
runMigrations,
traceSqlStatement,
} as const;
/**
@@ -1119,11 +1123,7 @@ export async function initDatabase(
sqlite = new Database(filePath, {
readonly,
verbose: isSqlTraceEnabled()
? (message?: unknown) => {
traceSql('sql-main', 'query', {
sql: compactSqlForTrace(String(message ?? '')),
});
}
? (message?: unknown) => traceSqlStatement(message)
: undefined,
});