import { expect, tap } from '@git.zone/tstest/tapbundle'; import * as npmextra from '../ts/index.js'; // Test that sensitive values are properly redacted in logs tap.test('should redact sensitive values in console output', async () => { // Capture console.log output const originalLog = console.log; const logOutput: string[] = []; console.log = (...args: any[]) => { logOutput.push(args.join(' ')); }; try { // Set up environment variables with sensitive data process.env['API_KEY'] = 'super-secret-api-key-12345'; process.env['DATABASE_PASSWORD'] = 'myP@ssw0rd123'; process.env['AUTH_TOKEN'] = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ'; process.env['PUBLIC_URL'] = 'https://example.com'; process.env['DEBUG_MODE'] = 'true'; // Create AppData with sensitive environment mappings const appData = await npmextra.AppData.createAndInit({ ephemeral: true, envMapping: { apiKey: 'API_KEY', dbPassword: 'DATABASE_PASSWORD', authToken: 'AUTH_TOKEN', publicUrl: 'PUBLIC_URL', debugMode: 'boolean:DEBUG_MODE', nestedConfig: { secretKey: 'API_KEY', nonSecret: 'PUBLIC_URL' } } }); // Restore console.log console.log = originalLog; // Check that sensitive values were redacted in logs const combinedOutput = logOutput.join('\n'); // API_KEY should be redacted expect(combinedOutput).toContain('sup...[26 chars]'); expect(combinedOutput).not.toContain('super-secret-api-key-12345'); // DATABASE_PASSWORD should be redacted expect(combinedOutput).toContain('myP...[13 chars]'); expect(combinedOutput).not.toContain('myP@ssw0rd123'); // AUTH_TOKEN should be redacted (JWT tokens starting with eyJ) expect(combinedOutput).toContain('eyJ...['); expect(combinedOutput).not.toContain('eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9'); // PUBLIC_URL should not be redacted (not sensitive) expect(combinedOutput).toContain('https://example.com'); // DEBUG_MODE should not be redacted (not sensitive) expect(combinedOutput).toContain('true'); // Verify data is still stored correctly (not redacted in actual storage) const kvStore = await appData.getKvStore(); const apiKey = await kvStore.readKey('apiKey'); const dbPassword = await kvStore.readKey('dbPassword'); const publicUrl = await kvStore.readKey('publicUrl'); // Actual values should be stored correctly expect(apiKey).toEqual('super-secret-api-key-12345'); expect(dbPassword).toEqual('myP@ssw0rd123'); expect(publicUrl).toEqual('https://example.com'); } finally { // Restore console.log in case of test failure console.log = originalLog; // Clean up environment variables delete process.env['API_KEY']; delete process.env['DATABASE_PASSWORD']; delete process.env['AUTH_TOKEN']; delete process.env['PUBLIC_URL']; delete process.env['DEBUG_MODE']; } }); export default tap.start();