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
{
// $schedule->command('inspire')->hourly();
$schedule->command('app:mark-timeout-mail')->minutely();
}
/**

View File

@ -2,13 +2,13 @@
namespace App\Http\Controllers;
use App\Http\Controllers\Controller;
use App\Models\Mail;
use Illuminate\Support\Str;
use Illuminate\Http\Request;
use Illuminate\Support\Carbon;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Crypt;
use Illuminate\Support\Facades\Validator;
use Illuminate\Support\Str;
class MailController extends Controller
{
@ -17,8 +17,8 @@ public function index(Request $request)
{
$domain_list = config('mail.domain_list');
$block_prefix = config('mail.block_prefix');
$rand_prefix = Str::random(8);
$key = Crypt::encryptString(json_encode(['id' => 0, 'time' => time()]));
$rand_prefix = strtolower(Str::random(8));
$key = Crypt::encryptString(json_encode(['time' => time()]));
return view('welcome', [
'domain_list' => $domain_list,
'block_prefix' => $block_prefix,
@ -64,20 +64,26 @@ function ($attribute, $value, $fail) {
return abort(400);
}
$where = [];
$to_hash = hash('sha256', $email);
$where[] = ['to_hash', '=', $to_hash];
$where = [
'to_hash' => hash('sha256', $email),
'is_read' => 0,
];
// $to_hash = hash('sha256', $email);
// $where[] = ['to_hash', '=', $to_hash];
try {
$key = Crypt::decryptString($key);
$key = json_decode($key, true);
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)];
if (time() - $key['time'] > 300) {
throw new Exception("The token has expired.", 400);
}
// 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) {
return abort(400, $th->getMessage());
}
@ -94,10 +100,7 @@ function ($attribute, $value, $fail) {
->orderBy('received_at', 'asc')
->get();
$key = ['id' => $key['id'], 'time' => time()];
if ($new_email_list->count() > 0) {
$key['id'] = $new_email_list->last()->key;
}
$key = ['time' => time()];
foreach ($new_email_list as $value) {
$value->key = Crypt::encryptString($value->key);
@ -142,6 +145,7 @@ public function put(Request $request)
$mail->from_addr = $from_addr;
$mail->from_protocol = $from_protocol;
$mail->received_at = Carbon::parse($received_at);
$mail->is_read = 0;
$mail->save();
return response()->json([
@ -168,6 +172,9 @@ public function info(Request $request, $key)
return abort(404);
}
$mail_info->is_read = 1;
$mail_info->save();
$title = str_replace(["\n", "\r", "\t"], '', strip_tags($mail_info->title));
$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() }}">
<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/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://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://cdn.jsdelivr.net/npm/clipboard@2.0.11/dist/clipboard.min.js"></script>
@ -209,7 +209,7 @@
function isValidDomain(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);
}
@ -308,6 +308,7 @@ function fetchMail() {
});
$('#inputText').on('change keyup', function () {
this.value = this.value.toLowerCase().replace(/[^a-z0-9]/g, '');
let textLength = $('#inputText').val().length;
if (textLength < 5 || textLength > 32) {
$('#inputText').addClass('is-invalid');
@ -409,7 +410,6 @@ function fetchMail() {
$('#myModal').modal('show');
} catch (e) {
console.error('Error parsing API response or decoding base64:', e);
}