diff --git a/app/Http/Controllers/AppController.php b/app/Http/Controllers/AppController.php
index 94de456..db4430b 100644
--- a/app/Http/Controllers/AppController.php
+++ b/app/Http/Controllers/AppController.php
@@ -49,6 +49,14 @@ class AppController extends Controller
}
}
+ public function switchP($email) {
+ Premium::setEmailP($email);
+ if (json_decode(config('app.settings.configuration_settings'))->disable_mailbox_slug) {
+ return redirect()->route('dashboard');
+ }
+ return redirect()->route('dashboard.premium');
+ }
+
public function deleteP($email = null) {
if ($email) {
$emails = Premium::getEmails();
diff --git a/app/Livewire/Dashboard/Dashboard.php b/app/Livewire/Dashboard/Dashboard.php
index 06008ba..f8dd34f 100644
--- a/app/Livewire/Dashboard/Dashboard.php
+++ b/app/Livewire/Dashboard/Dashboard.php
@@ -2,12 +2,14 @@
namespace App\Livewire\Dashboard;
+use App\Models\UsageLog;
use Illuminate\Http\Request;
use Livewire\Component;
class Dashboard extends Component
{
public $message;
+ public $usageLog;
public $subscription;
public $plans;
@@ -61,7 +63,11 @@ class Dashboard extends Component
}
}
-
+ $usageLog = UsageLog::where('user_id', auth()->user()->id)->first();
+ $this->usageLog = [
+ 'emails_created_count' => $usageLog->emails_created_count ?? 0,
+ 'emails_received_count' => $usageLog->emails_received_count ?? 0,
+ ];
}
public function render()
diff --git a/app/Livewire/Dashboard/Mailbox/Inbox.php b/app/Livewire/Dashboard/Mailbox/Inbox.php
index 1c9916b..cf982d3 100644
--- a/app/Livewire/Dashboard/Mailbox/Inbox.php
+++ b/app/Livewire/Dashboard/Mailbox/Inbox.php
@@ -5,15 +5,18 @@ namespace App\Livewire\Dashboard\Mailbox;
use App\ColorPicker;
use App\Models\Log;
use App\Models\Premium;
+use App\Models\PremiumEmail;
+use App\Models\UsageLog;
+use Artisan;
use Carbon\Carbon;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Cookie;
use Livewire\Component;
+use Session;
class Inbox extends Component
{
use ColorPicker;
-
public $messages = [];
public $deleted = [];
public $error = '';
@@ -24,8 +27,11 @@ class Inbox extends Component
public $messageId;
public $list = false;
public $emails;
+ public $mailboxHistory;
+ public $emailsHistory;
public $username, $domain, $domains, $action;
public $email_limit = 20;
+ private $isSubscribed;
protected $listeners = ['updateEmail' => 'syncEmail', 'getEmail' => 'generateEmail', 'fetchMessages' => 'fetch', 'setMessageId' => 'setMessageId'];
@@ -38,8 +44,11 @@ class Inbox extends Component
$this->initial = false;
$this->checkMultipleEmails();
$this->validateDomainInEmail();
+ $this->emailsHistory = array_reverse(PremiumEmail::parseEmail(\auth()->user()->id)['data']) ?? [];
- if(auth()->user()->subscribedToProduct(config('app.plans')[0]['product_id'])) {
+ $subscriptionCheck = auth()->user()->subscribedToProduct(config('app.plans')[0]['product_id']);
+ Session::put('isSubscribed', $subscriptionCheck);
+ if($subscriptionCheck) {
try {
$result = auth()->user()->subscriptions()->where(['stripe_status' => 'active'])->orderByDesc('updated_at')->first();
$userPriceID = $result['items'][0]['stripe_price'];
@@ -57,6 +66,9 @@ class Inbox extends Component
\Log::error($e->getMessage());
}
}
+
+ $mailboxHistory = UsageLog::where(['user_id' => auth()->user()->id])->first();
+ $this->mailboxHistory = $mailboxHistory->emails_created_history ?? [];
}
private function checkMultipleEmails(): void
@@ -73,7 +85,22 @@ class Inbox extends Component
public function switchEmail($email)
{
- return redirect()->route('switch', ['email' => $email]);
+ try {
+ if ($email != null) {
+ $data = explode('@', $email);
+ if (isset($data[1])) {
+ $domain = $data[1];
+ $domains = json_decode(config('app.settings.configuration_settings'))->premium_domains ?? [];
+ if (!in_array($domain, $domains)) {
+ return $this->showAlert('error', __('This mailbox can not be recovered.'));
+ }
+ }
+ }
+ } catch (\Exception $exception) {
+ \Log::error($exception->getMessage());
+ }
+
+ return redirect()->route('switchP', ['email' => $email]);
}
public function syncEmail(): void
@@ -183,19 +210,25 @@ class Inbox extends Component
private function validateDomainInEmail(): void
{
- $data = explode('@', $this->email);
- if (isset($data[1])) {
- $domain = $data[1];
- $domains = json_decode(config('app.settings.configuration_settings'))->premium_domains ?? [];
- if (!in_array($domain, $domains)) {
- $key = array_search($this->email, $this->emails);
- Premium::removeEmail($this->email);
- if ($key == 0 && count($this->emails) == 1 && json_decode(config('app.settings.configuration_settings'))->after_last_email_delete == 'redirect_to_homepage') {
- redirect()->route('dashboard.premium');
- } else {
- redirect()->route('dashboard.premium');
+ try {
+ if ($this->email != null) {
+ $data = explode('@', $this->email);
+ if (isset($data[1])) {
+ $domain = $data[1];
+ $domains = json_decode(config('app.settings.configuration_settings'))->premium_domains ?? [];
+ if (!in_array($domain, $domains)) {
+ $key = array_search($this->email, $this->emails);
+ Premium::removeEmail($this->email);
+ if ($key == 0 && count($this->emails) == 1 && json_decode(config('app.settings.configuration_settings'))->after_last_email_delete == 'redirect_to_homepage') {
+ redirect()->route('dashboard.premium');
+ } else {
+ redirect()->route('dashboard.premium');
+ }
+ }
}
}
+ } catch (\Exception $exception) {
+ \Log::error($exception->getMessage());
}
}
@@ -241,6 +274,15 @@ class Inbox extends Component
$this->dispatch('showNewMailNotification', $notification);
}
Premium::incrementMessagesStats(count($notifications));
+
+ if ($this->email != null && count($this->messages) > 0) {
+ foreach ($this->messages as $message) {
+ PremiumEmail::createEmail($message, $this->email);
+ }
+ }
+
+ $this->emailsHistory = array_reverse(PremiumEmail::parseEmail(\auth()->user()->id)['data']) ?? [];
+
} catch (\Exception $e) {
if (Auth::check() && Auth::user()->level == 9) {
$this->error = $e->getMessage();
@@ -252,6 +294,17 @@ class Inbox extends Component
$this->initial = true;
}
+ public function processQueue(): void
+ {
+ try {
+ Artisan::call('queue:work', [
+ '--once' => true,
+ ]);
+ } catch (\Exception $exception) {
+ \Log::error($exception->getMessage());
+ }
+ }
+
public function delete($messageId) {
try {
@@ -274,7 +327,11 @@ class Inbox extends Component
public function render()
{
- return view('livewire.dashboard.mailbox.inbox')->layout('components.layouts.dashboard');
+ if (Session::get('isSubscribed')) {
+ return view('livewire.dashboard.mailbox.inbox')->layout('components.layouts.dashboard');
+ } else {
+ return view('livewire.dashboard.not-subscribed')->layout('components.layouts.dashboard');
+ }
}
private function rrmdir($dir): void
diff --git a/app/Livewire/Dashboard/NotSubscribed.php b/app/Livewire/Dashboard/NotSubscribed.php
new file mode 100644
index 0000000..91b9fa5
--- /dev/null
+++ b/app/Livewire/Dashboard/NotSubscribed.php
@@ -0,0 +1,13 @@
+layout('components.layouts.dashboard');
+ }
+}
diff --git a/app/Models/Premium.php b/app/Models/Premium.php
index 68f45ba..3b0c6a9 100644
--- a/app/Models/Premium.php
+++ b/app/Models/Premium.php
@@ -35,6 +35,12 @@ class Premium extends Model
public static function fetchMessages($email, $type = 'to', $deleted = []): array
{
+ if ($email == null) {
+ return [
+ "data" => [],
+ "notifications" => []
+ ];
+ }
$allowed = explode(',', 'doc,docx,xls,xlsx,ppt,pptx,xps,pdf,dxf,ai,psd,eps,ps,svg,ttf,zip,rar,tar,gzip,mp3,mpeg,wav,ogg,jpeg,jpg,png,gif,bmp,tif,webm,mpeg4,3gpp,mov,avi,mpegs,wmv,flx,txt');
$connection = self::connectMailBox();
@@ -91,6 +97,7 @@ class Premium extends Model
$obj['date'] = $date->format(json_decode(config('app.settings.configuration_settings'))->date_format ?? 'd M Y h:i A');
$obj['datediff'] = $datediff->diffForHumans();
$obj['id'] = $message->getNumber();
+ $obj['size'] = $message->getSize();
$obj['content'] = $content;
$obj['contentText'] = $contentText;
$obj['attachments'] = [];
@@ -191,6 +198,15 @@ class Premium extends Model
Cookie::queue('email', $email, 43800);
}
}
+
+ public static function setEmailP($email): void
+ {
+ $usageLogs = UsageLog::where(['user_id' => auth()->user()->id])->first();
+ $emails = $usageLogs->emails_created_history;
+ if (is_array($emails) && in_array($email, $emails)) {
+ Cookie::queue('email', $email, 43800);
+ }
+ }
public static function removeEmail($email): void
{
$emails = self::getEmails();
@@ -287,14 +303,14 @@ class Premium extends Model
if ($domain == "gmail.com") {
$rd = mt_rand(0,1);
if ($rd == 0) {
- $email = $zemail->generateRandomGmail();
+ $email = $zemail->generateRandomGmail(false);
} else {
$email = $zemail->getRandomGmailUser().'+'.$zemail->generateRandomUsername().'@gmail.com';
}
} elseif ($domain == "googlemail.com") {
$rd = mt_rand(0,1);
if ($rd == 0) {
- $email = $zemail->generateRandomGmail();
+ $email = $zemail->generateRandomGmail(false);
} else {
$email = $zemail->getRandomGmailUser().'+'.$zemail->generateRandomUsername().'@googlemail.com';
}
diff --git a/app/Models/PremiumEmail.php b/app/Models/PremiumEmail.php
new file mode 100644
index 0000000..0edf4ca
--- /dev/null
+++ b/app/Models/PremiumEmail.php
@@ -0,0 +1,160 @@
+ 'array',
+ 'cc' => 'array',
+ 'bcc' => 'array',
+ 'attachments' => 'array',
+ 'timestamp' => 'datetime'
+ ];
+
+ public static function createEmail($message, $email): void
+ {
+ $initialData = $message;
+ $utcTime = CarbonImmutable::instance($message['timestamp'])->setTimezone('UTC')->toDateTimeString();
+ $messageId = Carbon::parse($utcTime)->format('Ymd').$initialData['id'];
+ $userId = \auth()->user()->id;
+ $exists = PremiumEmail::where('user_id', $userId)->where('message_id', $messageId)->exists();
+
+ $data = [
+ 'user_id' => $userId,
+ 'message_id' => $messageId,
+ 'subject' => $initialData['subject'],
+ 'from_name' => $initialData['sender_name'],
+ 'from_email' => $initialData['sender_email'],
+ 'to' => ["$email"],
+ 'cc' => [],
+ 'bcc' => [],
+ 'timestamp' => $utcTime,
+ 'body_text' => $initialData['contentText'],
+ 'body_html' => $initialData['content'],
+ 'is_seen' => true,
+ 'is_flagged' => false,
+ 'size' => $initialData['size'],
+ 'mailbox' => 'INBOX',
+ 'raw_headers' => null,
+ 'raw_body' => null,
+ 'attachments' => $initialData['attachments'],
+ ];
+
+ if (!$exists) {
+ PremiumEmail::create($data);
+ }
+ }
+
+ public static function fetchEmailFromDB($userId) {
+
+ $validator = Validator::make(['user_id' => $userId], [
+ 'user_id' => 'required|integer'
+ ]);
+
+ if ($validator->fails()) {
+ return [];
+ }
+ return self::whereJsonContains('user_id', $userId)->orderBy('timestamp', 'desc')->get();
+ }
+
+ public static function parseEmail($userId, $deleted = []): array
+ {
+ $messages = self::fetchEmailFromDB($userId);
+ $limit = 50;
+ $count = 1;
+ $response = [
+ 'data' => [],
+ 'notifications' => []
+ ];
+
+ foreach ($messages as $message) {
+
+ if (in_array($message['message_id'], $deleted)) {
+ // If it exists, delete the matching record from the 'emails' table
+ Email::where('message_id', $message['message_id'])->delete();
+ continue;
+ }
+
+ $blocked = false;
+
+ $timestamp = $message['timestamp'];
+ $carbonTimestamp = Carbon::parse($timestamp, 'UTC');
+ $obj = [];
+ $obj['subject'] = $message['subject'];
+ $obj['to'] = $message['to'];
+ $obj['sender_name'] = $message['from_name'];
+ $obj['sender_email'] = $message['from_email'];
+ $obj['timestamp'] = $message['timestamp'];
+ $obj['date'] = $carbonTimestamp->format('d M Y h:i A');
+ $obj['datediff'] = $carbonTimestamp->diffForHumans(Carbon::now('UTC'));
+ $obj['id'] = $message['message_id'];
+ $obj['content'] = $message['body_html'];
+ $obj['contentText'] = $message['body_text'];
+ $obj['attachments'] = [];
+ $obj['is_seen'] = $message['is_seen'];
+ $obj['sender_photo'] = self::chooseColor(strtoupper(substr($message['from_name'] ?: $message['from_email'], 0, 1) ));
+
+
+ $domain = explode('@', $obj['sender_email'])[1];
+ $blocked = in_array($domain, json_decode(config('app.settings.configuration_settings'))->blocked_domains);
+ if ($blocked) {
+ $obj['subject'] = __('Blocked');
+ $obj['content'] = __('Emails from') . ' ' . $domain . ' ' . __('are blocked by Admin');
+ $obj['contentText'] = __('Emails from') . ' ' . $domain . ' ' . __('are blocked by Admin');
+ }
+
+ if (count($message['attachments']) > 0 && !$blocked) {
+ $obj['attachments'] = $message['attachments'];
+
+ }
+
+ $response['data'][] = $obj;
+ if (!$message['is_seen']) {
+ $response['notifications'][] = [
+ 'subject' => $obj['subject'],
+ 'sender_name' => $obj['sender_name'],
+ 'sender_email' => $obj['sender_email']
+ ];
+ if (config('app.zemail_log')) {
+ file_put_contents(storage_path('logs/zemail.csv'), request()->ip() . "," . date("Y-m-d h:i:s a") . "," . $obj['sender_email'] . "," . $email . PHP_EOL, FILE_APPEND);
+ }
+ }
+ PremiumEmail::where('message_id', $message['message_id'])->update(['is_seen' => true]);
+ if (++$count > $limit) {
+ break;
+ }
+ }
+ return $response;
+ }
+
+}
diff --git a/database/migrations/2025_05_05_212255_create_premium_emails_table.php b/database/migrations/2025_05_05_212255_create_premium_emails_table.php
new file mode 100644
index 0000000..85b6f95
--- /dev/null
+++ b/database/migrations/2025_05_05_212255_create_premium_emails_table.php
@@ -0,0 +1,47 @@
+id();
+ $table->unsignedBigInteger('user_id');
+ $table->string('message_id')->unique()->index();
+ $table->string('subject')->nullable();
+ $table->string('from_name')->nullable();
+ $table->string('from_email');
+ $table->text('to');
+ $table->text('cc')->nullable();
+ $table->text('bcc')->nullable();
+ $table->dateTime('timestamp')->nullable();
+ $table->longText('body_text')->nullable();
+ $table->longText('body_html')->nullable();
+ $table->boolean('is_seen')->default(false);
+ $table->boolean('is_flagged')->default(false);
+ $table->unsignedBigInteger('size')->nullable();
+ $table->string('mailbox')->default('INBOX');
+ $table->longText('raw_headers')->nullable();
+ $table->longText('raw_body')->nullable();
+ $table->json('attachments')->nullable();
+ $table->timestamps();
+
+ $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
+ });
+ }
+
+ /**
+ * Reverse the migrations.
+ */
+ public function down(): void
+ {
+ Schema::dropIfExists('premium_emails');
+ }
+};
diff --git a/resources/views/flux/icon/lock-keyhole.blade.php b/resources/views/flux/icon/lock-keyhole.blade.php
new file mode 100644
index 0000000..ba89d7f
--- /dev/null
+++ b/resources/views/flux/icon/lock-keyhole.blade.php
@@ -0,0 +1,43 @@
+{{-- Credit: Lucide (https://lucide.dev) --}}
+
+@props([
+ 'variant' => 'outline',
+])
+
+@php
+if ($variant === 'solid') {
+ throw new \Exception('The "solid" variant is not supported in Lucide.');
+}
+
+$classes = Flux::classes('shrink-0')
+ ->add(match($variant) {
+ 'outline' => '[:where(&)]:size-6',
+ 'solid' => '[:where(&)]:size-6',
+ 'mini' => '[:where(&)]:size-5',
+ 'micro' => '[:where(&)]:size-4',
+ });
+
+$strokeWidth = match ($variant) {
+ 'outline' => 2,
+ 'mini' => 2.25,
+ 'micro' => 2.5,
+};
+@endphp
+
+
diff --git a/resources/views/livewire/dashboard/dashboard.blade.php b/resources/views/livewire/dashboard/dashboard.blade.php
index 701ce90..195a91e 100644
--- a/resources/views/livewire/dashboard/dashboard.blade.php
+++ b/resources/views/livewire/dashboard/dashboard.blade.php
@@ -9,7 +9,7 @@
0
+{{ $usageLog['emails_created_count'] }}
Mailbox Created
0
+{{ $usageLog['emails_received_count'] }}
Emails Received
--}}
+
+ @if(!$message['is_seen'])
+
+ @endif
+
+
--}}
+ + To continue, you need to subscribe to a plan that grants access. +
+ + + + Subscribe now + +