Files
zemailnator/app/Models/PremiumEmail.php
idevakk c312ec3325 feat: Prepare Zemailnator for Dokploy deployment
- Add highly optimized Dockerfile with Nginx and PHP-FPM 8.4
- Add docker-compose.yml configured with Redis and MariaDB 10.11
- Implement entrypoint.sh and supervisord.conf for background workers
- Refactor legacy IMAP scripts into scheduled Artisan Commands
- Secure app by removing old routes with hardcoded basic auth credentials
- Configure email attachments to use Laravel Storage instead of insecure public/tmp
2026-02-28 23:17:39 +05:30

174 lines
5.7 KiB
PHP

<?php
namespace App\Models;
use App\ColorPicker;
use Carbon\CarbonImmutable;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Date;
use Illuminate\Support\Facades\Validator;
class PremiumEmail extends Model
{
use ColorPicker;
use HasFactory;
protected $fillable = [
'user_id',
'message_id',
'subject',
'from_name',
'from_email',
'to',
'cc',
'bcc',
'timestamp',
'body_text',
'body_html',
'is_seen',
'is_flagged',
'size',
'mailbox',
'raw_headers',
'raw_body',
'attachments',
];
protected $casts = [
'to' => 'array',
'cc' => 'array',
'bcc' => 'array',
'attachments' => 'array',
'timestamp' => 'datetime',
];
public function user()
{
return $this->belongsTo(User::class);
}
public static function createEmail(array $message, $email): void
{
$initialData = $message;
if (config('app.fetch_from_db') && config('app.fetch_from_remote_db')) {
$utcTime = CarbonImmutable::parse($message['timestamp'])->setTimezone('UTC')->toDateTimeString();
} else {
$utcTime = CarbonImmutable::instance($message['timestamp'])->setTimezone('UTC')->toDateTimeString();
}
$messageId = Date::parse($utcTime)->format('Ymd').$initialData['id'];
$userId = \auth()->user()->id;
$exists = PremiumEmail::query()->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'] ?? 0,
'mailbox' => 'INBOX',
'raw_headers' => null,
'raw_body' => null,
'attachments' => $initialData['attachments'],
];
if (! $exists) {
PremiumEmail::query()->create($data);
}
}
public static function fetchEmailFromDB($userId)
{
$validator = Validator::make(['user_id' => $userId], [
'user_id' => ['required', 'integer'],
]);
if ($validator->fails()) {
return [];
}
return self::query()->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::query()->where('message_id', $message['message_id'])->delete();
continue;
}
$blocked = false;
$timestamp = $message['timestamp'];
$carbonTimestamp = Date::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(Date::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((string) $message['from_name'] ?: (string) $message['from_email'], 0, 1)));
$domain = explode('@', (string) $obj['sender_email'])[1];
$blocked = in_array($domain, json_decode((string) 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::query()->where('message_id', $message['message_id'])->update(['is_seen' => true]);
if (++$count > $limit) {
break;
}
}
return $response;
}
}