Feature Description
Implement a hideEmail method that intelligently masks parts of an email address for privacy and data protection compliance (LGPD, GDPR). The method should obscure the local part (before @) and domain name while keeping the structure recognizable, e.g., [email protected] becomes jo***.*****@ex*****.com.
Use Case
This feature would solve privacy and compliance challenges when:
- Displaying user email addresses in admin panels, dashboards, or logs (LGPD/GDPR compliance)
- Showing partial email information for account verification ("We sent a code to jo***@em*****.com")
- Logging authentication attempts or security events without exposing full email addresses
- Displaying user lists in customer support tools while protecting PII (Personally Identifiable Information)
- Showing email preview in "forgot password" flows ("Reset link sent to j***@gm***.com")
- Exporting user data for analytics while maintaining privacy
- Audit trails and compliance reports that reference users without exposing full contact details
- Public-facing user profiles where email visibility is restricted
Current workaround limitations:
Developers currently need to manually implement email masking logic with complex string manipulation:
// Manual implementation (error-prone, inconsistent)
$email = 'joao.silva@example. com';
[$local, $domain] = explode('@', $email);
$maskedLocal = substr($local, 0, 2) . '***';
$maskedDomain = substr($domain, 0, 2) . '***.' . substr($domain, -3);
$masked = $maskedLocal . '@' . $maskedDomain;
// Result inconsistent, doesn't handle edge cases
This method would provide a standardized, tested, and reliable API for email masking that follows best practices.
Real-world scenarios:
// Admin dashboard - user list
$users = User::all();
foreach ($users as $user) {
echo SM::hideEmail($user->email);
// 'jo***@ex*****.com' instead of '[email protected]'
}
// Account verification flow
$message = "We sent a verification code to " . SM::hideEmail($user->email);
// "We sent a verification code to us****@gm***.com"
// Security logs (LGPD compliant)
Log::info('Failed login attempt', [
'email' => SM::hideEmail($request->email),
'ip' => $request->ip()
]);
// Logs: 'email' => 'ad***@co*****.com' (not full PII)
// Forgot password confirmation
flash()->success('If this email exists, reset link sent to ' . SM::hideEmail($email));
// "... sent to ma***@ya***.com"
// Customer support ticket view
$ticket->user_email = SM::hideEmail($ticket->user_email);
// Support sees 'su****@ho*****.com' instead of full email
// Analytics export (anonymized)
$export = User::select(['id', DB::raw('email')])->get()->map(function($user) {
return ['id' => $user->id, 'email_masked' => SM::hideEmail($user->email)];
});
// CSV contains 'us***@do*****.com' patterns
// Public profile display
$profile->public_email = $user->show_email
? $user->email
: SM::hideEmail($user->email);
// Shows 'co****@pr*****.org' if privacy enabled
Static Usage
use SSolWEB\StringMorpher\StringMorpher as SM;
// Basic email masking
$safe = SM::hideEmail('[email protected]');
echo $safe; // 'us****@em***.com'
// Long local part
$safe = SM::hideEmail('joao.silva. [email protected]');
echo $safe; // 'jo***.*****.*****@ex*****.com'
// Short email
$safe = SM::hideEmail('[email protected]');
echo $safe; // 'a*@c*. com'
// Complex domain
$safe = SM::hideEmail('[email protected]');
echo $safe; // 'us**@ma**. ex*****.co. uk'
// Corporate email
$safe = SM:: hideEmail('[email protected]');
echo $safe; // 'fi********.*******@co*****.com'
Fluent Usage
use SSolWEB\StringMorpher\StringMorpher as SM;
// Chain with trimming (user input)
$safeEmail = SM::make(' [email protected] ')
->trim()
->toLower()
->hideEmail();
echo $safeEmail; // 'us**@ex*****.com'
// Integrate in notification messages
$message = SM::make('Verification sent to: ')
->append($userEmail)
->hideEmail();
echo $message; // 'Verification sent to: jo***@gm***.com'
// Log formatting
$logEntry = SM::make($request->email)
->trim()
->toLower()
->hideEmail()
->prepend('[AUTH] Email: ')
->getString();
Log::info($logEntry); // '[AUTH] Email: ad***@do*****.com'
// Privacy-compliant export
$users->map(function($user) {
return [
'id' => $user->id,
'name' => SM::make($user->name)->capitalize(),
'email' => SM:: make($user->email)->hideEmail()->getString(),
'created' => $user->created_at
];
});
// Dynamic masking based on permission
$displayEmail = SM::make($email);
if (! auth()->user()->can('view_full_emails')) {
$displayEmail->hideEmail();
}
echo $displayEmail; // Masked or full based on permission
Technical Considerations
The implementation should:
- Validate email format before masking (basic structure check)
- Preserve email structure: keep
@ and . visible for context
- Mask local part: show first 2 chars, mask rest with
*** (or proportional to length)
- Mask domain: show first 2 chars of domain name, mask middle, preserve TLD
- Handle edge cases:
- Consistent masking pattern: same email always produces same mask (deterministic)
- No reversibility: masked output should not allow reconstruction of original
Algorithm suggestion:
- Split email by
@ into local and domain parts
- For local part:
- If length ≤ 3: show 1 char +
**
- If length > 3: show first 2 chars +
*** + (handle dots in between)
- For domain part:
- Extract TLD (last segment after final
.)
- Mask domain name (first segment): show 2 chars +
***
- Preserve structure:
[email protected]
- Combine:
local@domain
Privacy note:
This method supports LGPD (Lei Geral de Proteção de Dados - Brazil) and GDPR compliance by minimizing exposure of personal data in logs, displays, and exports while maintaining enough context for user recognition.
Checklist
Feature Description
Implement a
hideEmailmethod that intelligently masks parts of an email address for privacy and data protection compliance (LGPD, GDPR). The method should obscure the local part (before@) and domain name while keeping the structure recognizable, e.g.,[email protected]becomesjo***.*****@ex*****.com.Use Case
This feature would solve privacy and compliance challenges when:
Current workaround limitations:
Developers currently need to manually implement email masking logic with complex string manipulation:
This method would provide a standardized, tested, and reliable API for email masking that follows best practices.
Real-world scenarios:
Static Usage
Fluent Usage
Technical Considerations
The implementation should:
@and.visible for context***(or proportional to length)[email protected])[email protected])Algorithm suggestion:
@into local and domain parts*****+ (handle dots in between).)***[email protected]local@domainPrivacy note:
This method supports LGPD (Lei Geral de Proteção de Dados - Brazil) and GDPR compliance by minimizing exposure of personal data in logs, displays, and exports while maintaining enough context for user recognition.
Checklist