mail read

This commit is contained in:
神楽坂 白 2024-06-02 12:50:33 +08:00
parent 887ff34ff0
commit 01bc5af076
5 changed files with 95 additions and 24 deletions

View File

@ -0,0 +1,38 @@
<?php
namespace App\Console\Commands;
use App\Models\Mail;
use Illuminate\Console\Command;
use Illuminate\Support\Carbon;
class MarkTimeoutMail extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'app:mark-timeout-mail';
/**
* The console command description.
*
* @var string
*/
protected $description = '标记超时未读邮件';
/**
* Execute the console command.
*/
public function handle()
{
//
Mail::where([
['created_at', "<=", Carbon::now()->subSeconds(300)],
['is_read', '=', 0],
])->update([
'is_read' => 1,
]);
}
}

View File

@ -12,7 +12,7 @@ class Kernel extends ConsoleKernel
*/ */
protected function schedule(Schedule $schedule): void protected function schedule(Schedule $schedule): void
{ {
// $schedule->command('inspire')->hourly(); $schedule->command('app:mark-timeout-mail')->minutely();
} }
/** /**
@ -20,7 +20,7 @@ protected function schedule(Schedule $schedule): void
*/ */
protected function commands(): void protected function commands(): void
{ {
$this->load(__DIR__.'/Commands'); $this->load(__DIR__ . '/Commands');
require base_path('routes/console.php'); require base_path('routes/console.php');
} }

View File

@ -2,13 +2,13 @@
namespace App\Http\Controllers; namespace App\Http\Controllers;
use App\Http\Controllers\Controller;
use App\Models\Mail; use App\Models\Mail;
use Illuminate\Support\Str;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use Illuminate\Support\Carbon; use Illuminate\Support\Carbon;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Crypt; use Illuminate\Support\Facades\Crypt;
use Illuminate\Support\Facades\Validator; use Illuminate\Support\Facades\Validator;
use Illuminate\Support\Str;
class MailController extends Controller class MailController extends Controller
{ {
@ -17,8 +17,8 @@ public function index(Request $request)
{ {
$domain_list = config('mail.domain_list'); $domain_list = config('mail.domain_list');
$block_prefix = config('mail.block_prefix'); $block_prefix = config('mail.block_prefix');
$rand_prefix = Str::random(8); $rand_prefix = strtolower(Str::random(8));
$key = Crypt::encryptString(json_encode(['id' => 0, 'time' => time()])); $key = Crypt::encryptString(json_encode(['time' => time()]));
return view('welcome', [ return view('welcome', [
'domain_list' => $domain_list, 'domain_list' => $domain_list,
'block_prefix' => $block_prefix, 'block_prefix' => $block_prefix,
@ -64,20 +64,26 @@ function ($attribute, $value, $fail) {
return abort(400); return abort(400);
} }
$where = []; $where = [
$to_hash = hash('sha256', $email); 'to_hash' => hash('sha256', $email),
$where[] = ['to_hash', '=', $to_hash]; 'is_read' => 0,
];
// $to_hash = hash('sha256', $email);
// $where[] = ['to_hash', '=', $to_hash];
try { try {
$key = Crypt::decryptString($key); $key = Crypt::decryptString($key);
$key = json_decode($key, true); $key = json_decode($key, true);
if (!empty($key['id'])) { if (time() - $key['time'] > 300) {
$where[] = ['id', '>', $key['id']]; throw new Exception("The token has expired.", 400);
} elseif (time() - $key['time'] < 300) {
$where[] = ['received_at', '>', Carbon::parse($key['time'])];
} else {
$where[] = ['received_at', '>', Carbon::now()->subSeconds(60)];
} }
// if (!empty($key['id'])) {
// $where[] = ['id', '>', $key['id']];
// } elseif (time() - $key['time'] < 300) {
// $where[] = ['received_at', '>', Carbon::parse($key['time'])];
// } else {
// $where[] = ['received_at', '>', Carbon::now()->subSeconds(60)];
// }
} catch (\Throwable $th) { } catch (\Throwable $th) {
return abort(400, $th->getMessage()); return abort(400, $th->getMessage());
} }
@ -94,10 +100,7 @@ function ($attribute, $value, $fail) {
->orderBy('received_at', 'asc') ->orderBy('received_at', 'asc')
->get(); ->get();
$key = ['id' => $key['id'], 'time' => time()]; $key = ['time' => time()];
if ($new_email_list->count() > 0) {
$key['id'] = $new_email_list->last()->key;
}
foreach ($new_email_list as $value) { foreach ($new_email_list as $value) {
$value->key = Crypt::encryptString($value->key); $value->key = Crypt::encryptString($value->key);
@ -142,6 +145,7 @@ public function put(Request $request)
$mail->from_addr = $from_addr; $mail->from_addr = $from_addr;
$mail->from_protocol = $from_protocol; $mail->from_protocol = $from_protocol;
$mail->received_at = Carbon::parse($received_at); $mail->received_at = Carbon::parse($received_at);
$mail->is_read = 0;
$mail->save(); $mail->save();
return response()->json([ return response()->json([
@ -168,6 +172,9 @@ public function info(Request $request, $key)
return abort(404); return abort(404);
} }
$mail_info->is_read = 1;
$mail_info->save();
$title = str_replace(["\n", "\r", "\t"], '', strip_tags($mail_info->title)); $title = str_replace(["\n", "\r", "\t"], '', strip_tags($mail_info->title));
$body = preg_replace('/<script\b[^>]*>(.*?)<\/script>/is', "", $mail_info->body); $body = preg_replace('/<script\b[^>]*>(.*?)<\/script>/is', "", $mail_info->body);

View File

@ -0,0 +1,26 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::table('mails', function (Blueprint $table) {
$table->unsignedTinyInteger('is_read')->default(0)->index();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
$table->dropColumn('is_read');
}
};

View File

@ -7,7 +7,7 @@
<meta name="csrf-token" content="{{ csrf_token() }}"> <meta name="csrf-token" content="{{ csrf_token() }}">
<title>{{config('app.name')}}</title> <title>{{config('app.name')}}</title>
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" rel="stylesheet"> <link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.3.1/css/bootstrap.min.css" rel="stylesheet">
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.3/css/all.min.css" rel="stylesheet"> <link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.3/css/all.min.css" rel="stylesheet">
<link href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.13/css/select2.min.css" rel="stylesheet" /> <link href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.13/css/select2.min.css" rel="stylesheet" />
@ -192,7 +192,7 @@
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script> <script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.3.1/js/bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.13/js/select2.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.13/js/select2.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/clipboard@2.0.11/dist/clipboard.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/clipboard@2.0.11/dist/clipboard.min.js"></script>
@ -209,7 +209,7 @@
function isValidDomain(domain) { function isValidDomain(domain) {
console.log(domain); console.log(domain);
var pattern = /^(?!:\/\/)([a-zA-Z0-9-]+\.)*[a-zA-Z0-9-]+\.[a-zA-Z]{2,11}$/; var pattern = /^(?!:\/\/)([a-z0-9-]+\.)*[a-z0-9-]+\.[a-z]{2,11}$/;
return pattern.test(domain); return pattern.test(domain);
} }
@ -308,6 +308,7 @@ function fetchMail() {
}); });
$('#inputText').on('change keyup', function () { $('#inputText').on('change keyup', function () {
this.value = this.value.toLowerCase().replace(/[^a-z0-9]/g, '');
let textLength = $('#inputText').val().length; let textLength = $('#inputText').val().length;
if (textLength < 5 || textLength > 32) { if (textLength < 5 || textLength > 32) {
$('#inputText').addClass('is-invalid'); $('#inputText').addClass('is-invalid');
@ -409,7 +410,6 @@ function fetchMail() {
$('#myModal').modal('show'); $('#myModal').modal('show');
} catch (e) { } catch (e) {
console.error('Error parsing API response or decoding base64:', e); console.error('Error parsing API response or decoding base64:', e);
} }
@ -424,4 +424,4 @@ function fetchMail() {
</script> </script>
</body> </body>
</html> </html>