@@ -61,6 +61,49 @@ export class BunGateLogger implements Logger {
6161 const pinoConfig : any = {
6262 level : this . config . level ,
6363 ...config ,
64+ // Redact sensitive information from logs
65+ redact : {
66+ paths : [
67+ // API Keys
68+ 'apiKey' ,
69+ 'api_key' ,
70+ '*.apiKey' ,
71+ '*.api_key' ,
72+ 'headers.apiKey' ,
73+ 'headers.api_key' ,
74+ 'headers["x-api-key"]' ,
75+ 'headers["X-API-Key"]' ,
76+ 'headers["X-Api-Key"]' ,
77+ 'headers.authorization' ,
78+ 'headers.Authorization' ,
79+ // JWT tokens
80+ 'token' ,
81+ 'accessToken' ,
82+ 'access_token' ,
83+ 'refreshToken' ,
84+ 'refresh_token' ,
85+ 'jwt' ,
86+ '*.token' ,
87+ '*.jwt' ,
88+ // Passwords and secrets
89+ 'password' ,
90+ 'passwd' ,
91+ 'secret' ,
92+ 'privateKey' ,
93+ 'private_key' ,
94+ '*.password' ,
95+ '*.secret' ,
96+ // Credit card data
97+ 'creditCard' ,
98+ 'cardNumber' ,
99+ 'cvv' ,
100+ 'ccv' ,
101+ // Other sensitive fields
102+ 'ssn' ,
103+ 'social_security' ,
104+ ] ,
105+ censor : '[REDACTED]' ,
106+ } ,
64107 }
65108
66109 // Configure pretty printing for development
@@ -88,6 +131,64 @@ export class BunGateLogger implements Logger {
88131 this . pino = pino ( pinoConfig )
89132 }
90133
134+ /**
135+ * Sanitizes sensitive data from objects before logging
136+ * Provides an additional layer of protection beyond Pino's redaction
137+ */
138+ private sanitizeData ( data : any ) : any {
139+ if ( ! data || typeof data !== 'object' ) {
140+ return data
141+ }
142+
143+ // Create a shallow copy to avoid mutating the original
144+ const sanitized = Array . isArray ( data ) ? [ ...data ] : { ...data }
145+
146+ // List of sensitive field names (case-insensitive patterns)
147+ const sensitiveKeys = [
148+ 'apikey' ,
149+ 'api_key' ,
150+ 'x-api-key' ,
151+ 'authorization' ,
152+ 'token' ,
153+ 'accesstoken' ,
154+ 'access_token' ,
155+ 'refreshtoken' ,
156+ 'refresh_token' ,
157+ 'jwt' ,
158+ 'password' ,
159+ 'passwd' ,
160+ 'secret' ,
161+ 'privatekey' ,
162+ 'private_key' ,
163+ 'creditcard' ,
164+ 'cardnumber' ,
165+ 'cvv' ,
166+ 'ccv' ,
167+ 'ssn' ,
168+ 'social_security' ,
169+ ]
170+
171+ for ( const key in sanitized ) {
172+ if ( Object . prototype . hasOwnProperty . call ( sanitized , key ) ) {
173+ const lowerKey = key . toLowerCase ( )
174+
175+ // Check if key matches sensitive patterns
176+ if ( sensitiveKeys . some ( ( pattern ) => lowerKey . includes ( pattern ) ) ) {
177+ sanitized [ key ] = '[REDACTED]'
178+ }
179+ // Recursively sanitize nested objects
180+ else if (
181+ typeof sanitized [ key ] === 'object' &&
182+ sanitized [ key ] !== null
183+ ) {
184+ sanitized [ key ] = this . sanitizeData ( sanitized [ key ] )
185+ }
186+ }
187+ }
188+
189+ return sanitized
190+ }
191+
91192 getSerializers ( ) : LoggerOptions [ 'serializers' ] | undefined {
92193 return this . config . serializers
93194 }
@@ -99,9 +200,11 @@ export class BunGateLogger implements Logger {
99200 dataOrMsg ?: Record < string , any > | string ,
100201 ) : void {
101202 if ( typeof msgOrObj === 'string' ) {
102- this . pino . info ( dataOrMsg || { } , msgOrObj )
203+ const sanitizedData = this . sanitizeData ( dataOrMsg || { } )
204+ this . pino . info ( sanitizedData , msgOrObj )
103205 } else {
104- this . pino . info ( msgOrObj , dataOrMsg as string )
206+ const sanitizedObj = this . sanitizeData ( msgOrObj )
207+ this . pino . info ( sanitizedObj , dataOrMsg as string )
105208 }
106209 }
107210
@@ -112,9 +215,11 @@ export class BunGateLogger implements Logger {
112215 dataOrMsg ?: Record < string , any > | string ,
113216 ) : void {
114217 if ( typeof msgOrObj === 'string' ) {
115- this . pino . debug ( dataOrMsg || { } , msgOrObj )
218+ const sanitizedData = this . sanitizeData ( dataOrMsg || { } )
219+ this . pino . debug ( sanitizedData , msgOrObj )
116220 } else {
117- this . pino . debug ( msgOrObj , dataOrMsg as string )
221+ const sanitizedObj = this . sanitizeData ( msgOrObj )
222+ this . pino . debug ( sanitizedObj , dataOrMsg as string )
118223 }
119224 }
120225
@@ -125,9 +230,11 @@ export class BunGateLogger implements Logger {
125230 dataOrMsg ?: Record < string , any > | string ,
126231 ) : void {
127232 if ( typeof msgOrObj === 'string' ) {
128- this . pino . warn ( dataOrMsg || { } , msgOrObj )
233+ const sanitizedData = this . sanitizeData ( dataOrMsg || { } )
234+ this . pino . warn ( sanitizedData , msgOrObj )
129235 } else {
130- this . pino . warn ( msgOrObj , dataOrMsg as string )
236+ const sanitizedObj = this . sanitizeData ( msgOrObj )
237+ this . pino . warn ( sanitizedObj , dataOrMsg as string )
131238 }
132239 }
133240
@@ -151,9 +258,11 @@ export class BunGateLogger implements Logger {
151258 }
152259 : { } ) ,
153260 }
154- this . pino . error ( errorData , msgOrObj )
261+ const sanitizedData = this . sanitizeData ( errorData )
262+ this . pino . error ( sanitizedData , msgOrObj )
155263 } else {
156- this . pino . error ( msgOrObj , errorOrMsg as string )
264+ const sanitizedObj = this . sanitizeData ( msgOrObj )
265+ this . pino . error ( sanitizedObj , errorOrMsg as string )
157266 }
158267 }
159268
0 commit comments