feat: implement soft deletes, mailbox reclaims, cooldowns, and auto-cleanup
This commit is contained in:
@@ -209,9 +209,77 @@ class Mailbox extends Component
|
||||
return;
|
||||
}
|
||||
|
||||
$address = $this->createType === 'random'
|
||||
? fake()->userName().'_'.rand(10, 99).'@'.$this->customDomain
|
||||
: $this->customUsername.'@'.$this->customDomain;
|
||||
if ($this->createType === 'random') {
|
||||
do {
|
||||
$address = fake()->userName().rand(10, 99).'@'.$this->customDomain;
|
||||
} while (MailboxModel::withTrashed()->where('address', $address)->exists());
|
||||
} else {
|
||||
$address = $this->customUsername.'@'.$this->customDomain;
|
||||
|
||||
// Check if address already exists
|
||||
$existing = MailboxModel::withTrashed()->where('address', $address)->first();
|
||||
|
||||
if ($existing) {
|
||||
// Scenario A: Same User Reclaiming
|
||||
$isOwner = (auth()->check() && $existing->user_id === auth()->id())
|
||||
|| ($existing->session_id === Session::getId());
|
||||
|
||||
if ($isOwner) {
|
||||
if ($existing->trashed()) {
|
||||
$existing->restore();
|
||||
}
|
||||
if (now() > $existing->expires_at) {
|
||||
$existing->update([
|
||||
'expires_at' => now()->addDays($this->getValidityDays()),
|
||||
'last_accessed_at' => now(),
|
||||
]);
|
||||
}
|
||||
|
||||
$this->currentMailboxId = $existing->id;
|
||||
$this->showCreateModal = false;
|
||||
$this->customUsername = '';
|
||||
Session::put('last_mailbox_id', $existing->id);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Scenario B: Different User Claiming
|
||||
if (! $existing->trashed()) {
|
||||
$this->dispatch('notify', message: 'Address already in use.', type: 'danger');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Address is soft-deleted. Check Tier-based Cooldown
|
||||
$user = auth()->user();
|
||||
$hoursRequired = match (true) {
|
||||
! $user => 24, // Guest
|
||||
$user->isEnterprise() || $user->isAdmin() => 0,
|
||||
$user->isPro() => 6,
|
||||
$user->isFree() => 12,
|
||||
default => 12,
|
||||
};
|
||||
|
||||
$cooldownEndsAt = $existing->deleted_at->copy()->addHours($hoursRequired);
|
||||
|
||||
if (now()->lessThan($cooldownEndsAt)) {
|
||||
$diff = now()->diff($cooldownEndsAt);
|
||||
$parts = [];
|
||||
if ($diff->d > 0) $parts[] = $diff->d . 'd';
|
||||
if ($diff->h > 0) $parts[] = $diff->h . 'h';
|
||||
if ($diff->i > 0) $parts[] = $diff->i . 'm';
|
||||
if ($diff->s > 0 || empty($parts)) $parts[] = $diff->s . 's';
|
||||
$remaining = implode(' ', $parts);
|
||||
|
||||
$this->dispatch('notify', message: "Address is in cooldown. Try again in {$remaining}.", type: 'warning');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Cooldown passed. Permanently delete the old record to sever email history.
|
||||
$existing->forceDelete();
|
||||
}
|
||||
}
|
||||
|
||||
$mailbox = MailboxModel::create([
|
||||
'mailbox_hash' => bin2hex(random_bytes(32)),
|
||||
@@ -250,7 +318,9 @@ class Mailbox extends Component
|
||||
return;
|
||||
}
|
||||
|
||||
$address = fake()->userName().'_'.rand(10, 99).'@'.$domain->name;
|
||||
do {
|
||||
$address = fake()->userName().rand(10, 99).'@'.$domain->name;
|
||||
} while (MailboxModel::withTrashed()->where('address', $address)->exists());
|
||||
|
||||
$mailbox = MailboxModel::create([
|
||||
'mailbox_hash' => bin2hex(random_bytes(32)),
|
||||
@@ -297,7 +367,7 @@ class Mailbox extends Component
|
||||
$this->autoCreateRandomMailbox();
|
||||
}
|
||||
$this->isCreatingFirstMailbox = false;
|
||||
|
||||
|
||||
// Ensure the component re-renders fully with the new data
|
||||
$this->dispatch('$refresh');
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user