Skip to content

Commit 13212bb

Browse files
committed
feat: Add NameRedaction and PasswordRedaction classes with usage examples in README.md.
1 parent 3bd6e1d commit 13212bb

File tree

4 files changed

+387
-4
lines changed

4 files changed

+387
-4
lines changed

README.md

Lines changed: 65 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -170,33 +170,94 @@ use TinyBlocks\Logger\Redactions\PhoneRedaction;
170170
PhoneRedaction::from(fields: ['phone', 'mobile', 'whatsapp'], visibleSuffixLength: 4);
171171
```
172172

173+
#### Password redaction
174+
175+
Masks the entire value. No characters are preserved.
176+
177+
```php
178+
use TinyBlocks\Logger\StructuredLogger;
179+
use TinyBlocks\Logger\Redactions\PasswordRedaction;
180+
181+
$logger = StructuredLogger::create()
182+
->withComponent(component: 'auth-service')
183+
->withRedactions(PasswordRedaction::default())
184+
->build();
185+
186+
$logger->info(message: 'login.attempt', context: ['password' => 's3cr3t!']);
187+
# password → "*******"
188+
```
189+
190+
With custom fields:
191+
192+
```php
193+
use TinyBlocks\Logger\Redactions\PasswordRedaction;
194+
195+
PasswordRedaction::from(fields: ['password', 'secret', 'token']);
196+
```
197+
198+
#### Name redaction
199+
200+
Preserves the first N characters (default: 2) and masks the rest.
201+
202+
```php
203+
use TinyBlocks\Logger\StructuredLogger;
204+
use TinyBlocks\Logger\Redactions\NameRedaction;
205+
206+
$logger = StructuredLogger::create()
207+
->withComponent(component: 'user-service')
208+
->withRedactions(NameRedaction::default())
209+
->build();
210+
211+
$logger->info(message: 'user.created', context: ['name' => 'Gustavo']);
212+
# name → "Gu*****"
213+
```
214+
215+
With custom fields and visible length:
216+
217+
```php
218+
use TinyBlocks\Logger\Redactions\NameRedaction;
219+
220+
NameRedaction::from(fields: ['name', 'full_name', 'firstName'], visiblePrefixLength: 3);
221+
# "Gustavo" → "Gus****"
222+
# "Gustavo Freze" → "Gus**********"
223+
# "Maria" → "Mar**"
224+
```
225+
173226
#### Composing multiple redactions
174227

175228
```php
176229
use TinyBlocks\Logger\StructuredLogger;
177230
use TinyBlocks\Logger\Redactions\DocumentRedaction;
178231
use TinyBlocks\Logger\Redactions\EmailRedaction;
232+
use TinyBlocks\Logger\Redactions\NameRedaction;
233+
use TinyBlocks\Logger\Redactions\PasswordRedaction;
179234
use TinyBlocks\Logger\Redactions\PhoneRedaction;
180235

181236
$logger = StructuredLogger::create()
182237
->withComponent(component: 'user-service')
183238
->withRedactions(
184239
DocumentRedaction::default(),
185240
EmailRedaction::default(),
186-
PhoneRedaction::default()
241+
PhoneRedaction::default(),
242+
PasswordRedaction::default(),
243+
NameRedaction::default()
187244
)
188245
->build();
189246

190247
$logger->info(message: 'user.registered', context: [
191248
'document' => '12345678900',
192249
'email' => 'john@example.com',
193250
'phone' => '+5511999887766',
194-
'name' => 'John'
251+
'password' => 's3cr3t!',
252+
'name' => 'John',
253+
'status' => 'active'
195254
]);
196255
# document → "********900"
197256
# email → "jo**@example.com"
198257
# phone → "**********7766"
199-
# name → "John" (unchanged)
258+
# password → "*******"
259+
# name → "Jo**"
260+
# status → "active" (unchanged)
200261
```
201262

202263
#### Custom redaction
@@ -274,4 +335,4 @@ Logger is licensed under [MIT](LICENSE).
274335
## Contributing
275336

276337
Please follow the [contributing guidelines](https://github.com/tiny-blocks/tiny-blocks/blob/main/CONTRIBUTING.md) to
277-
contribute to the project.
338+
contribute to the project.

src/Redactions/NameRedaction.php

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace TinyBlocks\Logger\Redactions;
6+
7+
use TinyBlocks\Logger\Internal\Redactor\Redactor;
8+
use TinyBlocks\Logger\Redaction;
9+
10+
final readonly class NameRedaction implements Redaction
11+
{
12+
private const int DEFAULT_VISIBLE_PREFIX_LENGTH = 2;
13+
14+
private Redactor $redactor;
15+
16+
private function __construct(array $fields, int $visiblePrefixLength)
17+
{
18+
$this->redactor = new Redactor(
19+
fields: $fields,
20+
maskingFunction: static function (string $value) use ($visiblePrefixLength): string {
21+
$maskedLength = max(0, strlen($value) - $visiblePrefixLength);
22+
return sprintf('%s%s', substr($value, 0, $visiblePrefixLength), str_repeat('*', $maskedLength));
23+
}
24+
);
25+
}
26+
27+
public static function from(array $fields, int $visiblePrefixLength): NameRedaction
28+
{
29+
return new NameRedaction(fields: $fields, visiblePrefixLength: $visiblePrefixLength);
30+
}
31+
32+
public static function default(): NameRedaction
33+
{
34+
return self::from(fields: ['name'], visiblePrefixLength: self::DEFAULT_VISIBLE_PREFIX_LENGTH);
35+
}
36+
37+
public function redact(array $data): array
38+
{
39+
return $this->redactor->redact(data: $data);
40+
}
41+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace TinyBlocks\Logger\Redactions;
6+
7+
use TinyBlocks\Logger\Internal\Redactor\Redactor;
8+
use TinyBlocks\Logger\Redaction;
9+
10+
final readonly class PasswordRedaction implements Redaction
11+
{
12+
private Redactor $redactor;
13+
14+
private function __construct(array $fields)
15+
{
16+
$this->redactor = new Redactor(
17+
fields: $fields,
18+
maskingFunction: static function (string $value): string {
19+
return str_repeat('*', strlen($value));
20+
}
21+
);
22+
}
23+
24+
public static function from(array $fields): PasswordRedaction
25+
{
26+
return new PasswordRedaction(fields: $fields);
27+
}
28+
29+
public static function default(): PasswordRedaction
30+
{
31+
return self::from(fields: ['password']);
32+
}
33+
34+
public function redact(array $data): array
35+
{
36+
return $this->redactor->redact(data: $data);
37+
}
38+
}

0 commit comments

Comments
 (0)