diff --git a/app/Http/Controllers/AppController.php b/app/Http/Controllers/AppController.php new file mode 100644 index 0000000..c1e8bfe --- /dev/null +++ b/app/Http/Controllers/AppController.php @@ -0,0 +1,54 @@ +enable_create_from_url) { + ZEmail::createCustomEmailFull($email); + } + return redirect()->route('mailbox'); + } + if (!ZEmail::getEmail()) { + return redirect()->route('home'); + } + if (json_decode(config('app.settings.configuration_settings'))->disable_mailbox_slug) { + return redirect()->route('home'); + } + return $this->app(); + } + + public function app() { + return redirect()->route('home'); + } + + private function getStringBetween($string, $start, $end) { + $string = ' ' . $string; + $ini = strpos($string, $start); + if ($ini == 0) return ''; + $ini += strlen($start); + $len = strpos($string, $end, $ini) - $ini; + return substr($string, $ini, $len); + } + private function setHeaders($page) { + $header = $page->header; + foreach ($page->meta ? unserialize($page->meta) : [] as $meta) { + if ($meta['name'] == 'canonical') { + $header .= ''; + } else if (str_contains($meta['name'], 'og:')) { + $header .= ''; + } else { + $header .= ''; + } + } + $page->header = $header; + return $page; + } + + +} diff --git a/app/Livewire/Email.php b/app/Livewire/Email.php new file mode 100644 index 0000000..6b4f259 --- /dev/null +++ b/app/Livewire/Email.php @@ -0,0 +1,13 @@ +currentEmail = ZEmail::getEmail(); + $this->loadMessages(); + } + + public function loadMessages() + { + if ($this->currentEmail) { + $this->messages = ZEmail::getMessages($this->currentEmail); + } + } + + public function selectMessage($messageId) + { + $this->selectedMessage = $messageId; + } + + public function deleteMessage($messageId) + { + ZEmail::deleteMessage($messageId); + $this->loadMessages(); + $this->selectedMessage = null; + } + + public function generateNewEmail() + { + $this->currentEmail = ZEmail::generateRandomEmail(); + $this->loadMessages(); + } + + public function getPollingInterval() + { + return $this->refreshInterval * 1000; // Convert to milliseconds + } + + public function render() + { + return view('livewire.email-inbox', [ + 'messages' => $this->messages, + 'currentEmail' => $this->currentEmail + ]); + } +} diff --git a/app/Livewire/Frontend/Action.php b/app/Livewire/Frontend/Action.php new file mode 100644 index 0000000..626f823 --- /dev/null +++ b/app/Livewire/Frontend/Action.php @@ -0,0 +1,134 @@ +domains = json_decode(config('app.settings.configuration_settings'))->domains ?? []; + $this->email = ZEmail::getEmail(); + $this->emails = ZEmail::getEmails(); + $this->validateDomainInEmail(); + } + + public function create() { + if (!$this->username) { + return $this->showAlert('error', __('Please enter Username')); + } + $this->checkDomainInUsername(); + if (strlen($this->username) < json_decode(config('app.settings.configuration_settings'))->custom_username_length_min || strlen($this->username) > json_decode(config('app.settings.configuration_settings'))->custom_username_length_max) { + return $this->showAlert('error', __('Username length cannot be less than') . ' ' . json_decode(config('app.settings.configuration_settings'))->custom_username_length_min . ' ' . __('and greater than') . ' ' . json_decode(config('app.settings.configuration_settings'))->custom_username_length_max); + } + if (!$this->domain) { + return $this->showAlert('error', __('Please Select a Domain')); + } + if (in_array($this->username, json_decode(config('app.settings.configuration_settings'))->forbidden_ids)) { + return $this->showAlert('error', __('Username not allowed')); + } + if (!$this->checkEmailLimit()) { + return $this->showAlert('error', __('You have reached daily limit of MAX ') . json_decode(config('app.settings.configuration_settings'))->email_limit . __(' temp mail')); + } + if (!$this->checkUsedEmail()) { + return $this->showAlert('error', __('Sorry! That email is already been used by someone else. Please try a different email address.')); + } + + $this->email = ZEmail::createCustomEmail($this->username, $this->domain); + $this->dispatch('updateEmail'); + $this->dispatch('closeModal'); + + } + public function random() { + if (!$this->checkEmailLimit()) { + return $this->showAlert('error', __('You have reached daily limit of maximum ') . json_decode(config('app.settings.configuration_settings'))->email_limit . __(' temp mail addresses.')); + } + $this->email = ZEmail::generateRandomEmail(); + $this->dispatch('updateEmail'); + $this->dispatch('closeModal'); + + //$this->redirect(route('mailbox')); + } + + public function gmail() { + if (!$this->checkEmailLimit()) { + return $this->showAlert('error', __('You have reached daily limit of maximum ') . json_decode(config('app.settings.configuration_settings'))->email_limit . __(' temp mail addresses.')); + } + $this->email = ZEmail::generateRandomGmail(); + $this->dispatch('updateEmail'); + $this->dispatch('closeModal'); + } + + public function deleteEmail() { + ZEmail::removeEmail($this->email); +// if (count($this->emails) <= 1 && json_decode(config('app.settings.configuration_settings'))->after_last_email_delete == 'redirect_to_homepage') { +// return redirect()->route('home'); +// } + $this->email = ZEmail::getEmail(true); + $this->emails = ZEmail::getEmails(); + + $this->dispatch('updateEmail'); + $this->dispatch('closeModal'); + } + + private function showAlert($type, $message): void + { + $this->dispatch('showAlert', ['type' => $type, 'message' => $message]); + } + + private function checkEmailLimit() { + $logs = Log::select('ip', 'email')->where('ip', request()->ip())->where('created_at', '>', Carbon::now()->subDay())->groupBy('email')->groupBy('ip')->get(); + if (count($logs) >= json_decode(config('app.settings.configuration_settings'))->email_limit) { + return false; + } + return true; + } + + private function checkUsedEmail() { + if (json_decode(config('app.settings.configuration_settings'))->disable_used_email) { + $check = Log::where('email', $this->user . '@' . $this->domain)->where('ip', '<>', request()->ip())->count(); + if ($check > 0) { + return false; + } + return true; + } + return true; + } + + private function checkDomainInUsername() { + $parts = explode('@', $this->username); + if (isset($parts[1])) { + if (in_array($parts[1], $this->domains)) { + $this->domain = $parts[1]; + } + $this->username = $parts[0]; + } + } + + private function validateDomainInEmail(): void + { + $data = explode('@', $this->email); + if (isset($data[1])) { + $domain = $data[1]; + $domains = json_decode(config('app.settings.configuration_settings'))->domains ?? []; + if (!in_array($domain, $domains)) { + $key = array_search($this->email, $this->emails); + ZEmail::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('home'); + } else { + redirect()->route('mailbox'); + } + } + } + } + public function render() { + return view('livewire.frontend.action'); + } +} diff --git a/app/Livewire/Frontend/ActionOld.php b/app/Livewire/Frontend/ActionOld.php new file mode 100644 index 0000000..1931052 --- /dev/null +++ b/app/Livewire/Frontend/ActionOld.php @@ -0,0 +1,222 @@ +domains = config('app.settings.domains'); + $this->email = ZEmail::getEmail(); + $this->emails = ZEmail::getEmails(); + $this->validateDomainInEmail(); + } + + public function refreshMessages() + { + $this->emit('fetchMessages'); + } + + public function loadMsg($email) { + $this->email = $email; + if (count($this->emails) == 0) { + $this->emails = [$email]; + } + } + + public function syncEmail($email) { + $this->email = $email; + if (count($this->emails) == 0) { + $this->emails = [$email]; + } + } + + public function setDomain($domain) { + $this->domain = $domain; + } + + public function checkReCaptcha3($token, $action) { + $response = Http::post('https://www.google.com/recaptcha/api/siteverify?secret=' . config('app.settings.recaptcha3.secret_key') . '&response=' . $token); + $data = $response->json(); + if ($data['success']) { + $captcha = $data['score']; + if ($captcha > 0.5) { + if ($action == 'create') { + $this->create(); + } else { + $this->random(); + } + } else { + return $this->showAlert('error', __('Captcha Failed! Please try again')); + } + } else { + return $this->showAlert('error', __('Captcha Failed! Error: ') . json_encode($data['error-codes'])); + } + } + public function create() { + if (!$this->user) { + return $this->showAlert('error', __('Please enter Username')); + } + $this->checkDomainInUsername(); + if (strlen($this->user) < config('app.settings.custom.min') || strlen($this->user) > config('app.settings.custom.max')) { + return $this->showAlert('error', __('Username length cannot be less than') . ' ' . config('app.settings.custom.min') . ' ' . __('and greater than') . ' ' . config('app.settings.custom.max')); + } + if (!$this->domain) { + return $this->showAlert('error', __('Please Select a Domain')); + } + if (in_array($this->user, config('app.settings.forbidden_ids'))) { + return $this->showAlert('error', __('Username not allowed')); + } + if (!$this->checkEmailLimit()) { + return $this->showAlert('error', __('You have reached daily limit of MAX ') . config('app.settings.email_limit', 5) . __(' temp mail')); + } + if (!$this->checkUsedEmail()) { + return $this->showAlert('error', __('Sorry! That email is already been used by someone else. Please try a different email address.')); + } + if (!$this->validateCaptcha()) { + return $this->showAlert('error', __('Invalid Captcha. Please try again')); + } + $this->email = ZEmail::createCustomEmail($this->user, $this->domain); + $this->redirect(route('mailbox')); + } + + public function random() { + if (!$this->checkEmailLimit()) { + return $this->showAlert('error', __('You have reached daily limit of maximum ') . config('app.settings.email_limit', 5) . __(' temp mail addresses.')); + } + if (!$this->validateCaptcha()) { + return $this->showAlert('error', __('Invalid Captcha. Please try again')); + } + $this->email = ZEmail::generateRandomEmail(); + $this->redirect(route('mailbox')); + } + + public function tempgmail() { + if (!$this->checkEmailLimit()) { + return $this->showAlert('error', __('You have reached daily limit of maximum ') . config('app.settings.email_limit', 5) . __(' temp mail addresses.')); + } + if (!$this->validateCaptcha()) { + return $this->showAlert('error', __('Invalid Captcha. Please try again')); + } + $this->email = ZEmail::generateRandomGmail(); + $this->redirect(route('mailbox')); + } + + public function deleteEmail() { + ZEmail::removeEmail($this->email); + if (count($this->emails) == 1 && config('app.settings.after_last_email_delete') == 'redirect_to_homepage') { + return redirect()->route('home'); + } + $this->email = ZEmail::getEmail(true); + $this->emails = ZEmail::getEmails(); + return redirect()->route('mailbox'); + } + + public function render() { + if (count($this->emails) >= intval(config('app.settings.email_limit', 5))) { + for ($i = 0; $i < (count($this->emails) - intval(config('app.settings.email_limit', 5))); $i++) { + ZEmail::removeEmail($this->emails[$i]); + } + $this->emails = ZEmail::getEmails(); + ZEmail::setEmail($this->email); + } + return view('livewire.frontend.action'); + } + + /** + * Private Functions + */ + + private function showAlert($type, $message) { + $this->dispatchBrowserEvent('showAlert', ['type' => $type, 'message' => $message]); + } + + /** + * Don't allow used email + */ + private function checkUsedEmail() { + if (config('app.settings.disable_used_email', false)) { + $check = Log::where('email', $this->user . '@' . $this->domain)->where('ip', '<>', request()->ip())->count(); + if ($check > 0) { + return false; + } + return true; + } + return true; + } + + /** + * Validate Captcha + */ + private function validateCaptcha() { + if (config('app.settings.captcha') == 'hcaptcha') { + $response = Http::asForm()->post('https://hcaptcha.com/siteverify', [ + 'response' => $this->captcha, + 'secret' => config('app.settings.hcaptcha.secret_key') + ])->object(); + return $response->success; + } else if (config('app.settings.captcha') == 'recaptcha2') { + $response = Http::asForm()->post('https://www.google.com/recaptcha/api/siteverify', [ + 'response' => $this->captcha, + 'secret' => config('app.settings.recaptcha2.secret_key') + ])->object(); + return $response->success; + } + return true; + } + + /** + * Check if the user is crossing email limit + */ + private function checkEmailLimit() { + $logs = Log::select('ip', 'email')->where('ip', request()->ip())->where('created_at', '>', Carbon::now()->subDay())->groupBy('email')->groupBy('ip')->get(); + if (count($logs) >= config('app.settings.email_limit', 5)) { + return false; + } + return true; + } + + /** + * Check if Username already consist of Domain + */ + private function checkDomainInUsername() { + $parts = explode('@', $this->user); + if (isset($parts[1])) { + if (in_array($parts[1], $this->domains)) { + $this->domain = $parts[1]; + } + $this->user = $parts[0]; + } + } + + /** + * Validate if Domain in Email Exist + */ + private function validateDomainInEmail() { + $data = explode('@', $this->email); + if (isset($data[1])) { + $domain = $data[1]; + $domains = config('app.settings.domains'); + if (!in_array($domain, $domains)) { + $key = array_search($this->email, $this->emails); + TMail::removeEmail($this->email); + if ($key == 0 && count($this->emails) == 1 && config('app.settings.after_last_email_delete') == 'redirect_to_homepage') { + return redirect()->route('home'); + } else { + return redirect()->route('mailbox'); + } + } + } + } + +} diff --git a/app/Livewire/Frontend/App.php b/app/Livewire/Frontend/App.php new file mode 100644 index 0000000..66f643d --- /dev/null +++ b/app/Livewire/Frontend/App.php @@ -0,0 +1,109 @@ + 'fetch', 'syncEmail']; + + public function mount() + { + $this->email = ZEmail::getEmails(); + $this->initial = false; + } + + public function syncEmail($email) { + $this->email = $email; + } + + public function fetch() { + try { + $count = count($this->messages); + $responses = []; + if (config('app.beta_feature') || !json_decode(config('app.settings.imap_settings'))->cc_check) { + $responses = [ + 'to' => ZEmail::getMessages($this->email, 'to', $this->deleted), + 'cc' => [ + 'data' => [], + 'notifications' => [] + ] + ]; + } else { + $responses = [ + 'to' => ZEmail::getMessages($this->email, 'to', $this->deleted), + 'cc' => ZEmail::getMessages($this->email, 'cc', $this->deleted) + ]; + } + $this->deleted = []; + $this->messages = array_merge($responses['to']['data'], $responses['cc']['data']); + $notifications = array_merge($responses['to']['notifications'], $responses['cc']['notifications']); + if (count($notifications)) { + if ($this->overflow == false && count($this->messages) == $count) { + $this->overflow = true; + } + } else { + $this->overflow = false; + } + foreach ($notifications as $notification) { + $this->dispatchBrowserEvent('showNewMailNotification', $notification); + } + ZEmail::incrementMessagesStats(count($notifications)); + } catch (\Exception $e) { + if (Auth::check() && Auth::user()->level == 9) { + $this->error = $e->getMessage(); + } else { + $this->error = 'Not able to connect to Mail Server'; + } + } + $this->dispatchBrowserEvent('stopLoader'); + $this->dispatchBrowserEvent('loadDownload'); + $this->initial = true; + } + + public function delete($messageId) { + if (config('app.beta_feature')) { + Message::find($messageId)->delete(); + } + $this->deleted[] = $messageId; + foreach ($this->messages as $key => $message) { + if ($message['id'] == $messageId) { + $directory = './tmp/attachments/' . $messageId; + $this->rrmdir($directory); + unset($this->messages[$key]); + } + } + } + + public function render() + { + return view('livewire.frontend.app'); + } + private function rrmdir($dir): void + { + if (is_dir($dir)) { + $objects = scandir($dir); + foreach ($objects as $object) { + if ($object != "." && $object != "..") { + if (is_dir($dir . DIRECTORY_SEPARATOR . $object) && !is_link($dir . "/" . $object)) + $this->rrmdir($dir . DIRECTORY_SEPARATOR . $object); + else + unlink($dir . DIRECTORY_SEPARATOR . $object); + } + } + rmdir($dir); + } + } + +} diff --git a/app/Livewire/Frontend/Email.php b/app/Livewire/Frontend/Email.php new file mode 100644 index 0000000..22d34f8 --- /dev/null +++ b/app/Livewire/Frontend/Email.php @@ -0,0 +1,65 @@ + 'syncEmail', 'getEmail' => 'generateEmail']; + + public function mount(): void + { + $this->email = ZEmail::getEmail(); + $this->emails = ZEmail::getEmails(); + $this->initial = false; + $this->checkMultipleEmails(); + } + + private function checkMultipleEmails(): void + { + if (count($this->emails) == 0) { + $this->emails = [$this->email]; + } + if (count($this->emails) > 1) { + $this->list = true; + } else { + $this->list = false; + } + } + + public function switchEmail($email): void + { + ZEmail::setEmail($email); + $this->email = $email; + $this->dispatch('updateEmail'); + } + + public function syncEmail(): void + { + $this->email = ZEmail::getEmail(); + $this->emails = ZEmail::getEmails(); + if (count($this->emails) == 0) { + $this->dispatch('getEmail'); + } + $this->checkMultipleEmails(); + } + + public function generateEmail(): void + { + if ($this->email == null) { + ZEmail::generateRandomEmail(); + } + $this->checkMultipleEmails(); + $this->dispatch('updateEmail'); + } + + public function render() + { + return view('livewire.frontend.email')->with(['email' => $this->email, 'emails' => $this->emails, 'initial' => $this->initial, 'type' => $this->type, 'list' => $this->list]); + } +} diff --git a/app/Livewire/Home.php b/app/Livewire/Home.php new file mode 100644 index 0000000..0374ba4 --- /dev/null +++ b/app/Livewire/Home.php @@ -0,0 +1,13 @@ +created_at; - $obj['date'] = $message->created_at->format(json_decode(config('app.settings.configuration_settings'))->date_format, 'd M Y h:i A'); + $obj['date'] = $message->created_at->format(json_decode(config('app.settings.configuration_settings'))->date_format ?? 'd M Y h:i A'); $obj['datediff'] = $message->created_at->diffForHumans(); $obj['id'] = $message->id; $obj['content'] = $content; @@ -105,4 +110,239 @@ class Message extends Model } return $response; } + + public static function fetchMessages($email, $type = 'to', $deleted = []): array + { + $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 = ZEmail::connectMailBox(); + + $mailbox = $connection->getMailbox('INBOX'); + $search = new SearchExpression(); + if ($type == 'cc') { + $search->addCondition(new Cc($email)); + } else { + $search->addCondition(new To($email)); + } + $search->addCondition(new Since((new \DateTime('-1 day')))); + $messages = $mailbox->getMessages($search, \SORTDATE, true); + $limit = json_decode(config('app.settings.configuration_settings'))->fetch_messages_limit ?? 15; + $count = 1; + $response = [ + 'data' => [], + 'notifications' => [] + ]; + + foreach ($messages as $message) { + if (in_array($message->getNumber(), $deleted)) { + $message->delete(); + continue; + } + $blocked = false; + $sender = $message->getFrom(); + $date = $message->getDate(); + if (!$date) { + $date = new \DateTime(); + if ($message->getHeaders()->get('udate')) { + $date->setTimestamp($message->getHeaders()->get('udate')); + } + } + $datediff = new Carbon($date); + $content = ''; + $html = $message->getBodyHtml(); + if ($html) { + $content = str_replace('getBodyText(); + $content = str_replace('', $text)); + } + if (json_decode(config('app.settings.configuration_settings'))->enable_masking_external_link) { + $content = str_replace('href="', 'href="http://href.li/?', $content); + } + $obj = []; + $obj['subject'] = $message->getSubject(); + $obj['sender_name'] = $sender->getName(); + $obj['sender_email'] = $sender->getAddress(); + $obj['timestamp'] = $message->getDate(); + $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['content'] = $content; + $obj['attachments'] = []; + //Checking if Sender is Blocked + $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'); + } + if ($message->hasAttachments() && !$blocked) { + $attachments = $message->getAttachments(); + $directory = './tmp/attachments/' . $obj['id'] . '/'; + is_dir($directory) || mkdir($directory, 0777, true); + foreach ($attachments as $attachment) { + $filenameArray = explode('.', $attachment->getFilename()); + $extension = $filenameArray[count($filenameArray) - 1]; + if (in_array($extension, $allowed)) { + if (!file_exists($directory . $attachment->getFilename())) { + file_put_contents( + $directory . $attachment->getFilename(), + $attachment->getDecodedContent() + ); + } + if ($attachment->getFilename() !== 'undefined') { + $url = config('app.settings.app_base_url') . str_replace('./', '/', $directory . $attachment->getFilename()); + $structure = $attachment->getStructure(); + if (isset($structure->id) && str_contains($obj['content'], trim($structure->id, '<>'))) { + $obj['content'] = str_replace('cid:' . trim($structure->id, '<>'), $url, $obj['content']); + } + $obj['attachments'][] = [ + 'file' => $attachment->getFilename(), + 'url' => $url + ]; + } + } + } + } + $response['data'][] = $obj; + if (!$message->isSeen()) { + $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); + } + } + $message->markAsSeen(); + if (++$count > $limit) { + break; + } + } + + $response['data'] = array_reverse($response['data']); + $connection->expunge(); + return $response; + } + +// public static function fetchMessages($email, $type = 'to', $deleted = []): array +// { +// $startTime = microtime(true); +// $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 = ZEmail::connectMailBox(); +// +// $mailbox = $connection->getMailbox('INBOX'); +// $search = new SearchExpression(); +// if ($type == 'cc') { +// $search->addCondition(new Cc($email)); +// } else { +// $search->addCondition(new To($email)); +// } +// $search->addCondition(new Since((new \DateTime('-1 day')))); +// $stepStart = microtime(true); +// $messages = $mailbox->getMessages($search, \SORTDATE, true); +// \Log::info("1111 messages took: " . (microtime(true) - $stepStart)); +// +// $limit = json_decode(config('app.settings.configuration_settings'))->fetch_messages_limit ?? 15; +// $count = 1; +// $response = [ +// 'data' => [], +// 'notifications' => [] +// ]; +// +// foreach ($messages as $message) { +// if (in_array($message->getNumber(), $deleted)) { +// $message->delete(); +// continue; +// } +// $blocked = false; +// $sender = $message->getFrom(); +// $date = $message->getDate(); +// if (!$date) { +// $date = new \DateTime(); +// if ($message->getHeaders()->get('udate')) { +// $date->setTimestamp($message->getHeaders()->get('udate')); +// } +// } +// $datediff = new Carbon($date); +// $content = ''; +// $html = $message->getBodyHtml(); +// if ($html) { +// $content = str_replace('getBodyText(); +// $content = str_replace('', $text)); +// } +// if (json_decode(config('app.settings.configuration_settings'))->enable_masking_external_link) { +// $content = str_replace('href="', 'href="http://href.li/?', $content); +// } +// $obj = []; +// $obj['subject'] = $message->getSubject(); +// $obj['sender_name'] = $sender->getName(); +// $obj['sender_email'] = $sender->getAddress(); +// $obj['timestamp'] = $message->getDate(); +// $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['content'] = $content; +// $obj['attachments'] = []; +// //Checking if Sender is Blocked +// $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'); +// } +// if ($message->hasAttachments() && !$blocked) { +// $attachments = $message->getAttachments(); +// $directory = './tmp/attachments/' . $obj['id'] . '/'; +// is_dir($directory) || mkdir($directory, 0777, true); +// foreach ($attachments as $attachment) { +// $filenameArray = explode('.', $attachment->getFilename()); +// $extension = $filenameArray[count($filenameArray) - 1]; +// if (in_array($extension, $allowed)) { +// if (!file_exists($directory . $attachment->getFilename())) { +// file_put_contents( +// $directory . $attachment->getFilename(), +// $attachment->getDecodedContent() +// ); +// } +// if ($attachment->getFilename() !== 'undefined') { +// $url = config('app.settings.app_base_url') . str_replace('./', '/', $directory . $attachment->getFilename()); +// $structure = $attachment->getStructure(); +// if (isset($structure->id) && str_contains($obj['content'], trim($structure->id, '<>'))) { +// $obj['content'] = str_replace('cid:' . trim($structure->id, '<>'), $url, $obj['content']); +// } +// $obj['attachments'][] = [ +// 'file' => $attachment->getFilename(), +// 'url' => $url +// ]; +// } +// } +// } +// } +// $response['data'][] = $obj; +// if (!$message->isSeen()) { +// $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); +// } +// } +// $message->markAsSeen(); +// if (++$count > $limit) { +// break; +// } +// } +// +// $response['data'] = array_reverse($response['data']); +// $connection->expunge(); +// $endTime = microtime(true); +// $executionTime = $endTime - $startTime; +// \Log::info("getMessages execution time: {$executionTime} seconds"); +// return $response; +// } } diff --git a/app/Models/ZEmail.php b/app/Models/ZEmail.php index a971124..910cf9f 100644 --- a/app/Models/ZEmail.php +++ b/app/Models/ZEmail.php @@ -3,6 +3,7 @@ namespace App\Models; use Carbon\Carbon; +use Ddeboer\Imap\Search\Date\Since; use Ddeboer\Imap\Search\Email\Cc; use Ddeboer\Imap\Search\Email\To; use Ddeboer\Imap\SearchExpression; @@ -38,112 +39,7 @@ class ZEmail extends Model if (config('app.beta_feature')) { return Message::getMessages($email); } - $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 = ZEmail::connectMailBox(); - $mailbox = $connection->getMailbox('INBOX'); - $search = new SearchExpression(); - if ($type == 'cc') { - $search->addCondition(new Cc($email)); - } else { - $search->addCondition(new To($email)); - } - $messages = $mailbox->getMessages($search, \SORTDATE, true); - $limit = json_decode(config('app.settings.configuration_settings'))->fetch_messages_limit ?? 15; - $count = 1; - $response = [ - 'data' => [], - 'notifications' => [] - ]; - foreach ($messages as $message) { - if (in_array($message->getNumber(), $deleted)) { - $message->delete(); - continue; - } - $blocked = false; - $sender = $message->getFrom(); - $date = $message->getDate(); - if (!$date) { - $date = new \DateTime(); - if ($message->getHeaders()->get('udate')) { - $date->setTimestamp($message->getHeaders()->get('udate')); - } - } - $datediff = new Carbon($date); - $content = ''; - $html = $message->getBodyHtml(); - if ($html) { - $content = str_replace('getBodyText(); - $content = str_replace('', $text)); - } - if (json_decode(config('app.settings.configuration_settings'))->enable_masking_external_link) { - $content = str_replace('href="', 'href="http://href.li/?', $content); - } - $obj = []; - $obj['subject'] = $message->getSubject(); - $obj['sender_name'] = $sender->getName(); - $obj['sender_email'] = $sender->getAddress(); - $obj['timestamp'] = $message->getDate(); - $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['content'] = $content; - $obj['attachments'] = []; - //Checking if Sender is Blocked - $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'); - } - if ($message->hasAttachments() && !$blocked) { - $attachments = $message->getAttachments(); - $directory = './tmp/attachments/' . $obj['id'] . '/'; - is_dir($directory) || mkdir($directory, 0777, true); - foreach ($attachments as $attachment) { - $filenameArray = explode('.', $attachment->getFilename()); - $extension = $filenameArray[count($filenameArray) - 1]; - if (in_array($extension, $allowed)) { - if (!file_exists($directory . $attachment->getFilename())) { - file_put_contents( - $directory . $attachment->getFilename(), - $attachment->getDecodedContent() - ); - } - if ($attachment->getFilename() !== 'undefined') { - $url = config('app.settings.app_base_url') . str_replace('./', '/', $directory . $attachment->getFilename()); - $structure = $attachment->getStructure(); - if (isset($structure->id) && str_contains($obj['content'], trim($structure->id, '<>'))) { - $obj['content'] = str_replace('cid:' . trim($structure->id, '<>'), $url, $obj['content']); - } - $obj['attachments'][] = [ - 'file' => $attachment->getFilename(), - 'url' => $url - ]; - } - } - } - } - $response['data'][] = $obj; - if (!$message->isSeen()) { - $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); - } - } - $message->markAsSeen(); - if (++$count > $limit) { - break; - } - } - $response['data'] = array_reverse($response['data']); - $connection->expunge(); - return $response; + return Message::fetchMessages($email, $type, $deleted); } public static function deleteMessage($id): void diff --git a/composer.json b/composer.json index 03b7421..f51eba3 100644 --- a/composer.json +++ b/composer.json @@ -11,6 +11,7 @@ "filament/filament": "3.3", "laravel/framework": "^12.0", "laravel/tinker": "^2.10.1", + "livewire/flux": "^2.1", "livewire/livewire": "^3.6" }, "require-dev": { diff --git a/composer.lock b/composer.lock index c7f2dd0..2a4065e 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "3c178f04aa87a34364e767ad999d5889", + "content-hash": "8a5cd9a0ccf67c460d95ecb968192ef2", "packages": [ { "name": "anourvalar/eloquent-serialize", @@ -3143,6 +3143,69 @@ ], "time": "2024-12-08T08:18:47+00:00" }, + { + "name": "livewire/flux", + "version": "v2.1.4", + "source": { + "type": "git", + "url": "https://github.com/livewire/flux.git", + "reference": "a19709fc94f5a1b795ce24ad42662bd398c19371" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/livewire/flux/zipball/a19709fc94f5a1b795ce24ad42662bd398c19371", + "reference": "a19709fc94f5a1b795ce24ad42662bd398c19371", + "shasum": "" + }, + "require": { + "illuminate/console": "^10.0|^11.0|^12.0", + "illuminate/support": "^10.0|^11.0|^12.0", + "illuminate/view": "^10.0|^11.0|^12.0", + "laravel/prompts": "^0.1|^0.2|^0.3", + "livewire/livewire": "^3.5.19", + "php": "^8.1", + "symfony/console": "^6.0|^7.0" + }, + "type": "library", + "extra": { + "laravel": { + "aliases": { + "Flux": "Flux\\Flux" + }, + "providers": [ + "Flux\\FluxServiceProvider" + ] + } + }, + "autoload": { + "psr-4": { + "Flux\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "proprietary" + ], + "authors": [ + { + "name": "Caleb Porzio", + "email": "calebporzio@gmail.com" + } + ], + "description": "The official UI component library for Livewire.", + "keywords": [ + "components", + "flux", + "laravel", + "livewire", + "ui" + ], + "support": { + "issues": "https://github.com/livewire/flux/issues", + "source": "https://github.com/livewire/flux/tree/v2.1.4" + }, + "time": "2025-04-14T11:59:19+00:00" + }, { "name": "livewire/livewire", "version": "v3.6.3", diff --git a/public/images/logo.webp b/public/images/logo.webp new file mode 100644 index 0000000..942d56c Binary files /dev/null and b/public/images/logo.webp differ diff --git a/public/images/user.webp b/public/images/user.webp new file mode 100644 index 0000000..7c6ecba Binary files /dev/null and b/public/images/user.webp differ diff --git a/public/images/zemail-logo-dark.webp b/public/images/zemail-logo-dark.webp new file mode 100644 index 0000000..f124840 Binary files /dev/null and b/public/images/zemail-logo-dark.webp differ diff --git a/public/images/zemail-logo-light.webp b/public/images/zemail-logo-light.webp new file mode 100644 index 0000000..694131c Binary files /dev/null and b/public/images/zemail-logo-light.webp differ diff --git a/resources/css/app.css b/resources/css/app.css index 3e6abea..be63e5f 100644 --- a/resources/css/app.css +++ b/resources/css/app.css @@ -1,11 +1,52 @@ @import 'tailwindcss'; + +@import '../../vendor/livewire/flux/dist/flux.css'; @source '../../vendor/laravel/framework/src/Illuminate/Pagination/resources/views/*.blade.php'; @source '../../storage/framework/views/*.php'; @source '../**/*.blade.php'; @source '../**/*.js'; + +@custom-variant dark (&:where(.dark, .dark *)); + +/*@theme {*/ +/* --font-sans: 'Instrument Sans', ui-sans-serif, system-ui, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji',*/ +/* 'Segoe UI Symbol', 'Noto Color Emoji';*/ +/*}*/ + @theme { - --font-sans: 'Instrument Sans', ui-sans-serif, system-ui, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', - 'Segoe UI Symbol', 'Noto Color Emoji'; + --font-sans: Inter, sans-serif; } + +/* Re-assign Flux's gray of choice... */ +@theme { + --color-zinc-50: var(--color-gray-50); + --color-zinc-100: var(--color-gray-100); + --color-zinc-200: var(--color-gray-200); + --color-zinc-300: var(--color-gray-300); + --color-zinc-400: var(--color-gray-400); + --color-zinc-500: var(--color-gray-500); + --color-zinc-600: var(--color-gray-600); + --color-zinc-700: var(--color-gray-800); + --color-zinc-800: var(--color-gray-800); + --color-zinc-900: var(--color-gray-900); + --color-zinc-950: var(--color-gray-950); + /*--color-white: var(--color-gray-100);*/ +} + +@theme { + --color-accent: var(--color-gray-900); + --color-accent-content: var(--color-gray-900); + --color-accent-foreground: var(--color-white); +} + +@layer theme { + .dark { + --color-accent: var(--color-white); + --color-accent-content: var(--color-white); + --color-accent-foreground: var(--color-gray-900); + } +} + + diff --git a/resources/css/boil.css b/resources/css/boil.css index 44e66b5..345d9e2 100644 --- a/resources/css/boil.css +++ b/resources/css/boil.css @@ -1,3 +1,60 @@ -.art { - color: orange; +.inbox-btn { + background-color: #F14743; + color: white; + transition: background-color 0.3s ease; +} + +.inbox-btn:hover { + background-color: #f72a25; +} + +.btn-primary { + color: white; + background-color: #4361ee; +} + +.btn-warning { + color: white; + background-color: #e2a03f; +} +.btn-success { + background-color: #00AB55; + color: white; +} +.inbox-list { + margin-bottom: 10px; +} +.inbox-new { + background-color: #00AB55; +} + +.iframe-min-height { + min-height: 70vh; +} +@keyframes slide-in { + from { + transform: translateY(-1rem); + opacity: 0; + } + to { + transform: translateY(0); + opacity: 1; + } +} + +@keyframes progress { + from { + width: 100%; + } + to { + width: 0%; + } +} + +.animate-slide-in { + animation: slide-in 0.3s ease-out; +} + +.animate-progress { + animation: progress 4s linear forwards; } diff --git a/resources/js/boil.js b/resources/js/boil.js new file mode 100644 index 0000000..3470bab --- /dev/null +++ b/resources/js/boil.js @@ -0,0 +1,69 @@ +document.addEventListener('DOMContentLoaded', () => { + if (window.Livewire && typeof window.Livewire.dispatch === 'function') { + setTimeout(() => { + Livewire.dispatch('getEmail'); + }, 2000); + + document.addEventListener('closeModal', () => { + document.querySelectorAll('dialog[data-modal]').forEach(dialog => { + if (typeof dialog.close === 'function') { + dialog.close(); + console.log(`Closed dialog with data-modal="${dialog.getAttribute('data-modal')}"`); + } + }); + }); + + } else { + console.warn('Livewire is not loaded yet.'); + } +}); + + +function showToast({ type = 'success', message = '' }) { +const container = document.getElementById('toast-container'); + +const colors = { +success: { +icon: 'text-green-500 bg-green-100 dark:bg-green-800 dark:text-green-200', +svg: ``, +}, +error: { +icon: 'text-red-500 bg-red-100 dark:bg-red-800 dark:text-red-200', +svg: ``, +} +}; + +const toast = document.createElement('div'); +toast.className = `flex items-center w-full max-w-xs p-4 text-gray-500 bg-white rounded-lg shadow dark:text-gray-400 dark:bg-gray-800`; +toast.setAttribute('role', 'alert'); + +toast.innerHTML = ` +
+ ${colors[type].svg} +
+
${message}
+
+ + `; +container.appendChild(toast); + +setTimeout(() => { +toast.remove(); +}, 4000); +} + +function handleDispatches(dispatches) { +dispatches.forEach(dispatch => { + if (dispatch.name === "showAlert") { + const params = dispatch.params[0]; + showToast(params); + } +}); +} +window.addEventListener("showAlert", (event) => { + const detail = event.detail[0]; + showToast(detail); +}); diff --git a/resources/views/components/layouts/app.blade.php b/resources/views/components/layouts/app.blade.php new file mode 100644 index 0000000..8d20aa8 --- /dev/null +++ b/resources/views/components/layouts/app.blade.php @@ -0,0 +1,129 @@ + + + + + + + {{ $title ?? 'Page Title' }} + @if (file_exists(public_path('build/manifest.json')) || file_exists(public_path('hot'))) + @vite(['resources/css/app.css', 'resources/css/boil.css', 'resources/js/app.js', 'resources/js/boil.js']) + @endif + + @fluxAppearance + + + + +
+ logo + + +
+ + + Inbox + Refresh + + sideAds + + + API + FAQ + Privacy + Feedback + Contacts + + +

© {{ config('app.settings.app_name') }}

+
+ + + + + + + + + + + + + + + + + You are signed in as: +
+ +
+ +
+ + Create Account + + + + + + +
+
+
+
+ +
+ + + +
+
+ Generate Your Temporary Email +
+ + + + + + +
+
+ +
+
+ +
+
+ +
+
+ + +
+
+ Delete account? + +

You're about to delete this account.

+
+
+
+ + + Cancel + + +
+
+
+ + + {{ $slot }} + + + +
+ +
+ + @fluxScripts + + diff --git a/resources/views/filament/pages/setting.blade.php b/resources/views/filament/pages/setting.blade.php deleted file mode 100644 index cc61477..0000000 --- a/resources/views/filament/pages/setting.blade.php +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/resources/views/flux/icon/circle-user-round.blade.php b/resources/views/flux/icon/circle-user-round.blade.php new file mode 100644 index 0000000..b977980 --- /dev/null +++ b/resources/views/flux/icon/circle-user-round.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 + +class($classes) }} + data-flux-icon + xmlns="http://www.w3.org/2000/svg" + viewBox="0 0 24 24" + fill="none" + stroke="currentColor" + stroke-width="{{ $strokeWidth }}" + stroke-linecap="round" + stroke-linejoin="round" + aria-hidden="true" + data-slot="icon" +> + + + + diff --git a/resources/views/flux/icon/download.blade.php b/resources/views/flux/icon/download.blade.php new file mode 100644 index 0000000..1e455c1 --- /dev/null +++ b/resources/views/flux/icon/download.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 + +class($classes) }} + data-flux-icon + xmlns="http://www.w3.org/2000/svg" + viewBox="0 0 24 24" + fill="none" + stroke="currentColor" + stroke-width="{{ $strokeWidth }}" + stroke-linecap="round" + stroke-linejoin="round" + aria-hidden="true" + data-slot="icon" +> + + + + diff --git a/resources/views/flux/icon/file-down.blade.php b/resources/views/flux/icon/file-down.blade.php new file mode 100644 index 0000000..ee11c2e --- /dev/null +++ b/resources/views/flux/icon/file-down.blade.php @@ -0,0 +1,44 @@ +{{-- 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 + +class($classes) }} + data-flux-icon + xmlns="http://www.w3.org/2000/svg" + viewBox="0 0 24 24" + fill="none" + stroke="currentColor" + stroke-width="{{ $strokeWidth }}" + stroke-linecap="round" + stroke-linejoin="round" + aria-hidden="true" + data-slot="icon" +> + + + + + diff --git a/resources/views/flux/icon/file.blade.php b/resources/views/flux/icon/file.blade.php new file mode 100644 index 0000000..d906883 --- /dev/null +++ b/resources/views/flux/icon/file.blade.php @@ -0,0 +1,42 @@ +{{-- 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 + +class($classes) }} + data-flux-icon + xmlns="http://www.w3.org/2000/svg" + viewBox="0 0 24 24" + fill="none" + stroke="currentColor" + stroke-width="{{ $strokeWidth }}" + stroke-linecap="round" + stroke-linejoin="round" + aria-hidden="true" + data-slot="icon" +> + + + diff --git a/resources/views/flux/icon/mail-plus.blade.php b/resources/views/flux/icon/mail-plus.blade.php new file mode 100644 index 0000000..a8d8666 --- /dev/null +++ b/resources/views/flux/icon/mail-plus.blade.php @@ -0,0 +1,44 @@ +{{-- 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 + +class($classes) }} + data-flux-icon + xmlns="http://www.w3.org/2000/svg" + viewBox="0 0 24 24" + fill="none" + stroke="currentColor" + stroke-width="{{ $strokeWidth }}" + stroke-linecap="round" + stroke-linejoin="round" + aria-hidden="true" + data-slot="icon" +> + + + + + diff --git a/resources/views/flux/icon/mail.blade.php b/resources/views/flux/icon/mail.blade.php new file mode 100644 index 0000000..6d1583a --- /dev/null +++ b/resources/views/flux/icon/mail.blade.php @@ -0,0 +1,42 @@ +{{-- 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 + +class($classes) }} + data-flux-icon + xmlns="http://www.w3.org/2000/svg" + viewBox="0 0 24 24" + fill="none" + stroke="currentColor" + stroke-width="{{ $strokeWidth }}" + stroke-linecap="round" + stroke-linejoin="round" + aria-hidden="true" + data-slot="icon" +> + + + diff --git a/resources/views/flux/icon/refresh-cw.blade.php b/resources/views/flux/icon/refresh-cw.blade.php new file mode 100644 index 0000000..ae36ca2 --- /dev/null +++ b/resources/views/flux/icon/refresh-cw.blade.php @@ -0,0 +1,44 @@ +{{-- 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 + +class($classes) }} + data-flux-icon + xmlns="http://www.w3.org/2000/svg" + viewBox="0 0 24 24" + fill="none" + stroke="currentColor" + stroke-width="{{ $strokeWidth }}" + stroke-linecap="round" + stroke-linejoin="round" + aria-hidden="true" + data-slot="icon" +> + + + + + diff --git a/resources/views/flux/icon/sparkle.blade.php b/resources/views/flux/icon/sparkle.blade.php new file mode 100644 index 0000000..811b528 --- /dev/null +++ b/resources/views/flux/icon/sparkle.blade.php @@ -0,0 +1,41 @@ +{{-- 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 + +class($classes) }} + data-flux-icon + xmlns="http://www.w3.org/2000/svg" + viewBox="0 0 24 24" + fill="none" + stroke="currentColor" + stroke-width="{{ $strokeWidth }}" + stroke-linecap="round" + stroke-linejoin="round" + aria-hidden="true" + data-slot="icon" +> + + diff --git a/resources/views/livewire/email-inbox.blade.php b/resources/views/livewire/email-inbox.blade.php new file mode 100644 index 0000000..b73b28d --- /dev/null +++ b/resources/views/livewire/email-inbox.blade.php @@ -0,0 +1,51 @@ +
+
+ +
+

Your Disposable Email

+
+ + +
+
+ + +
+ @if(count($messages) > 0) + @foreach($messages as $message) +
+
+
+

{{ $message->subject }}

+

From: {{ $message->from }}

+

{{ $message->date }}

+
+ +
+
+ @endforeach + @else +
+ No messages yet. They will appear here automatically. +
+ @endif +
+
+ + + +
diff --git a/resources/views/livewire/email.blade.php b/resources/views/livewire/email.blade.php new file mode 100644 index 0000000..a8fb637 --- /dev/null +++ b/resources/views/livewire/email.blade.php @@ -0,0 +1,54 @@ +
+ + +
+
+

+ Resend Verification Email +

+
+
+ Download + Source + Print + Delete +
+
+
+
+
+
+
+ inbox-logo +
+
+
+ Fake-IT + register@receivefreesms.co.uk +
+ +
+
+
+
+ +
+
+
+ +
+
+
+ diff --git a/resources/views/livewire/frontend/action.blade.php b/resources/views/livewire/frontend/action.blade.php new file mode 100644 index 0000000..261a405 --- /dev/null +++ b/resources/views/livewire/frontend/action.blade.php @@ -0,0 +1,42 @@ + +@if($action == "random") + Random Email +@elseif($action == "gmail") + Disposable Gmail +@elseif($action == "delete") + Delete account +@elseif($action == "customEmail") +
+
+
+
+
+
+ +
+ +
+ + +
+
+
+
+ +
+
+ Cancel + Create Account +
+
+
+
+@endif +
diff --git a/resources/views/livewire/frontend/app.blade.php b/resources/views/livewire/frontend/app.blade.php new file mode 100644 index 0000000..a573dbb --- /dev/null +++ b/resources/views/livewire/frontend/app.blade.php @@ -0,0 +1,3 @@ +
+ {{-- Success is as dangerous as failure. --}} +
diff --git a/resources/views/livewire/frontend/email.blade.php b/resources/views/livewire/frontend/email.blade.php new file mode 100644 index 0000000..d6727a6 --- /dev/null +++ b/resources/views/livewire/frontend/email.blade.php @@ -0,0 +1,13 @@ + +@if($type === "header")

{{ $email ?? __('...') }}

+ @else{{ $email ?? __('...') }} + @if($list) + @foreach(array_reverse($emails) as $email_list_item) + + + {{ $email_list_item }} + + @endforeach + @endif + @endif +
diff --git a/resources/views/livewire/home.blade.php b/resources/views/livewire/home.blade.php new file mode 100644 index 0000000..7fbcbe9 --- /dev/null +++ b/resources/views/livewire/home.blade.php @@ -0,0 +1,11 @@ +
+Inbox +
+ @php + for ($i=0; $i<=10; $i++) { + @endphp + + @php + } + @endphp +
diff --git a/resources/views/livewire/inbox.blade.php b/resources/views/livewire/inbox.blade.php new file mode 100644 index 0000000..501990b --- /dev/null +++ b/resources/views/livewire/inbox.blade.php @@ -0,0 +1,48 @@ +
+
+
+
+
+ + inbox-logo + + +
+
+
+
+ Fake-IT +
+
+ + + + register@receivefreesms.co.uk
+
+ +
+
+
+ + + +
+
+
+
diff --git a/routes/web.php b/routes/web.php index f524a90..900f175 100644 --- a/routes/web.php +++ b/routes/web.php @@ -1,25 +1,13 @@ name('home'); +Route::get('/mailbox', Email::class)->name('mailbox'); +Route::get('/inbox', EmailInbox::class)->name('inbox'); -Route::get('ac', function () { - return json_decode(config('app.settings.configuration_settings'))->random_username_length_max ?? 0; - //return json_decode(config('app.settings.configuration_settings')) ?? []; -}); - -Route::get('bc', function (){ - return ZEmail::check(); -}); - -Route::get('zz', function (){ - try { - ZEmail::connectMailBox(); - } catch (Exception $ex) { - return $ex->getMessage(); - } -}); +//Route::get('/add/{email?}', [AppController::class, 'mailbox'])->name('mailbox'); diff --git a/vite.config.js b/vite.config.js index b12d7d2..bf9d553 100644 --- a/vite.config.js +++ b/vite.config.js @@ -5,7 +5,7 @@ import tailwindcss from '@tailwindcss/vite'; export default defineConfig({ plugins: [ laravel({ - input: ['resources/css/app.css', 'resources/css/boil.css', 'resources/js/app.js'], + input: ['resources/css/app.css', 'resources/css/boil.css', 'resources/js/app.js', 'resources/css/boil.js'], refresh: true, }), tailwindcss(),