feat: rework logging
This commit is contained in:
parent
87bdbeee05
commit
2d5991988d
22
app/Enums/LogAction.php
Normal file
22
app/Enums/LogAction.php
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Enums;
|
||||||
|
|
||||||
|
use App\Traits\EnumOptions;
|
||||||
|
use App\Traits\EnumValues;
|
||||||
|
|
||||||
|
enum LogAction: string
|
||||||
|
{
|
||||||
|
use EnumValues;
|
||||||
|
use EnumOptions;
|
||||||
|
|
||||||
|
case CREATE = 'create';
|
||||||
|
case DELETE = 'delete';
|
||||||
|
case REQUEST = 'request';
|
||||||
|
case REJECT = 'reject';
|
||||||
|
case APPROVE = 'approve';
|
||||||
|
case SEND = 'send';
|
||||||
|
case UPDATE = 'update';
|
||||||
|
case ACCESS = 'access';
|
||||||
|
|
||||||
|
}
|
||||||
@ -2,13 +2,13 @@
|
|||||||
|
|
||||||
namespace App\Http\Controllers\Api;
|
namespace App\Http\Controllers\Api;
|
||||||
|
|
||||||
|
use App\Enums\LogAction;
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
use App\Models\Log;
|
use App\Models\Log;
|
||||||
use App\Models\Quote;
|
use App\Models\Quote;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Support\Facades\Http;
|
use Illuminate\Support\Facades\Http;
|
||||||
|
|
||||||
|
|
||||||
class WebHookController extends Controller
|
class WebHookController extends Controller
|
||||||
{
|
{
|
||||||
public function webHookSend(string $payload)
|
public function webHookSend(string $payload)
|
||||||
@ -27,8 +27,12 @@ class WebHookController extends Controller
|
|||||||
}
|
}
|
||||||
|
|
||||||
Log::create([
|
Log::create([
|
||||||
'user_id' => auth()?->user()?->id,
|
'user_id' => auth()?->user()?->id ?? 1,
|
||||||
'content' => "Quote sent. {$quote}",
|
'loggable_type' => Quote::class,
|
||||||
|
'loggable_id' => null,
|
||||||
|
'action' => LogAction::SEND,
|
||||||
|
'content' => $quote,
|
||||||
|
'ip' => request()->ip(),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$this->webHookSend($quote);
|
$this->webHookSend($quote);
|
||||||
@ -39,9 +43,12 @@ class WebHookController extends Controller
|
|||||||
$quote = Quote::inRandomOrder()->first();
|
$quote = Quote::inRandomOrder()->first();
|
||||||
|
|
||||||
Log::create([
|
Log::create([
|
||||||
'user_id' => auth()?->user()?->id,
|
'user_id' => auth()?->user()?->id ?? 1,
|
||||||
'quote_id' => $quote->id,
|
'loggable_type' => Quote::class,
|
||||||
'content' => 'Quote sent.',
|
'loggable_id' => $quote->id,
|
||||||
|
'action' => LogAction::REQUEST,
|
||||||
|
'content' => 'Random quote requested',
|
||||||
|
'ip' => request()->ip(),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$this->webHookSend($quote->quote);
|
$this->webHookSend($quote->quote);
|
||||||
|
|||||||
@ -4,6 +4,7 @@ namespace App\Models;
|
|||||||
|
|
||||||
use Illuminate\Database\Eloquent\Model;
|
use Illuminate\Database\Eloquent\Model;
|
||||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||||
|
use Illuminate\Database\Eloquent\Relations\MorphTo;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @mixin IdeHelperLog
|
* @mixin IdeHelperLog
|
||||||
@ -12,9 +13,11 @@ class Log extends Model
|
|||||||
{
|
{
|
||||||
protected $fillable = [
|
protected $fillable = [
|
||||||
'user_id',
|
'user_id',
|
||||||
'quote_id',
|
'loggable_type',
|
||||||
'requested_quote_id',
|
'loggable_id',
|
||||||
|
'action',
|
||||||
'content',
|
'content',
|
||||||
|
'ip',
|
||||||
];
|
];
|
||||||
|
|
||||||
public function user(): BelongsTo
|
public function user(): BelongsTo
|
||||||
@ -22,13 +25,11 @@ class Log extends Model
|
|||||||
return $this->belongsTo(User::class);
|
return $this->belongsTo(User::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function quote(): BelongsTo
|
/**
|
||||||
|
* Get the parent loggable model (user, quote or requested quote).
|
||||||
|
*/
|
||||||
|
public function loggable(): MorphTo
|
||||||
{
|
{
|
||||||
return $this->belongsTo(Quote::class);
|
return $this->morphTo();
|
||||||
}
|
|
||||||
|
|
||||||
public function requestedQuote(): BelongsTo
|
|
||||||
{
|
|
||||||
return $this->belongsTo(RequestedQuote::class);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,8 +2,9 @@
|
|||||||
|
|
||||||
namespace App\Models;
|
namespace App\Models;
|
||||||
|
|
||||||
|
use App\Enums\LogAction;
|
||||||
use Illuminate\Database\Eloquent\Model;
|
use Illuminate\Database\Eloquent\Model;
|
||||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
use Illuminate\Database\Eloquent\Relations\MorphOne;
|
||||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -20,37 +21,47 @@ class Quote extends Model
|
|||||||
|
|
||||||
Log::create([
|
Log::create([
|
||||||
'user_id' => auth()?->user()?->id,
|
'user_id' => auth()?->user()?->id,
|
||||||
'quote_id' => $this->id,
|
'loggable_type' => self::class,
|
||||||
'content' => 'Quote requested.',
|
'loggable_id' => $this->id,
|
||||||
|
'action' => LogAction::REQUEST,
|
||||||
|
'content' => $this->quote,
|
||||||
|
'ip' => request()->ip(),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected $fillable = [
|
protected $fillable = [
|
||||||
|
'user_id',
|
||||||
'quote',
|
'quote',
|
||||||
];
|
];
|
||||||
|
|
||||||
public function logs(): hasMany
|
public function logs(): MorphOne
|
||||||
{
|
{
|
||||||
return $this->hasMany(Log::class);
|
return $this->morphOne(Log::class, 'loggable');
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function boot(): void
|
public static function boot(): void
|
||||||
{
|
{
|
||||||
parent::boot();
|
parent::boot();
|
||||||
|
|
||||||
self::created(function ($model) {
|
self::created(function (Quote $model) {
|
||||||
Log::create([
|
Log::create([
|
||||||
'user_id' => auth()?->user()?->id,
|
'user_id' => auth()?->user()?->id,
|
||||||
'quote_id' => $model->id,
|
'loggable_type' => self::class,
|
||||||
'content' => 'Quote created.',
|
'loggable_id' => $model->id,
|
||||||
|
'action' => LogAction::CREATE,
|
||||||
|
'content' => $model->quote,
|
||||||
|
'ip' => request()->ip(),
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
self::deleted(function ($model) {
|
self::deleted(function (Quote $model) {
|
||||||
Log::create([
|
Log::create([
|
||||||
'user_id' => auth()?->user()?->id,
|
'user_id' => auth()?->user()?->id,
|
||||||
'quote_id' => $model->id,
|
'loggable_type' => self::class,
|
||||||
'content' => 'Quote deleted.',
|
'loggable_id' => $model->id,
|
||||||
|
'action' => LogAction::DELETE,
|
||||||
|
'content' => $model->quote,
|
||||||
|
'ip' => request()->ip(),
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,8 +2,9 @@
|
|||||||
|
|
||||||
namespace App\Models;
|
namespace App\Models;
|
||||||
|
|
||||||
|
use App\Enums\LogAction;
|
||||||
use Illuminate\Database\Eloquent\Model;
|
use Illuminate\Database\Eloquent\Model;
|
||||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
use Illuminate\Database\Eloquent\Relations\MorphOne;
|
||||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -15,20 +16,22 @@ class RequestedQuote extends Model
|
|||||||
|
|
||||||
protected $fillable = [
|
protected $fillable = [
|
||||||
'quote',
|
'quote',
|
||||||
'user_id',
|
|
||||||
];
|
];
|
||||||
|
|
||||||
public function logs(): hasMany
|
public function logs(): MorphOne
|
||||||
{
|
{
|
||||||
return $this->hasMany(Log::class);
|
return $this->morphOne(Log::class, 'loggable');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function approve(): void
|
public function approve(): void
|
||||||
{
|
{
|
||||||
Log::create([
|
Log::create([
|
||||||
'user_id' => auth()?->user()?->id,
|
'user_id' => auth()?->user()?->id,
|
||||||
'requested_quote_id' => $this->id,
|
'loggable_type' => self::class,
|
||||||
'content' => 'Quote approved.',
|
'loggable_id' => $this->id,
|
||||||
|
'action' => LogAction::APPROVE,
|
||||||
|
'content' => $this->quote,
|
||||||
|
'ip' => request()->ip(),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
Quote::create([
|
Quote::create([
|
||||||
@ -42,8 +45,11 @@ class RequestedQuote extends Model
|
|||||||
{
|
{
|
||||||
Log::create([
|
Log::create([
|
||||||
'user_id' => auth()?->user()?->id,
|
'user_id' => auth()?->user()?->id,
|
||||||
'requested_quote_id' => $this->id,
|
'loggable_type' => self::class,
|
||||||
'content' => 'Quote rejected.',
|
'loggable_id' => $this->id,
|
||||||
|
'action' => LogAction::REJECT,
|
||||||
|
'content' => $this->quote,
|
||||||
|
'ip' => request()->ip(),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$this->delete();
|
$this->delete();
|
||||||
|
|||||||
@ -2,18 +2,20 @@
|
|||||||
|
|
||||||
namespace App\Models;
|
namespace App\Models;
|
||||||
|
|
||||||
|
use App\Enums\LogAction;
|
||||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
|
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||||
|
use Illuminate\Database\Eloquent\Relations\MorphOne;
|
||||||
use Illuminate\Foundation\Auth\User as Authenticatable;
|
use Illuminate\Foundation\Auth\User as Authenticatable;
|
||||||
use Illuminate\Notifications\Notifiable;
|
use Illuminate\Notifications\Notifiable;
|
||||||
use Laravel\Sanctum\HasApiTokens;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @mixin IdeHelperUser
|
* @mixin IdeHelperUser
|
||||||
*/
|
*/
|
||||||
class User extends Authenticatable
|
class User extends Authenticatable
|
||||||
{
|
{
|
||||||
use HasApiTokens, HasFactory, Notifiable;
|
use HasFactory, Notifiable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The model's default values for attributes.
|
* The model's default values for attributes.
|
||||||
@ -62,27 +64,33 @@ class User extends Authenticatable
|
|||||||
'password' => 'hashed',
|
'password' => 'hashed',
|
||||||
];
|
];
|
||||||
|
|
||||||
public function logs(): hasMany
|
public function logAction(): HasMany
|
||||||
{
|
{
|
||||||
return $this->hasMany(Log::class);
|
return $this->hasMany(Log::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function fullName(): string
|
public function logs(): MorphOne
|
||||||
{
|
{
|
||||||
return "{$this->firstname} {$this->lastname}";
|
return $this->morphOne(Log::class, 'loggable');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getFullNameAttribute(): string
|
||||||
|
{
|
||||||
|
return "$this->firstname $this->lastname";
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function boot(): void
|
public static function boot(): void
|
||||||
{
|
{
|
||||||
parent::boot();
|
parent::boot();
|
||||||
|
|
||||||
// These will only ever get created by the api/bot.
|
|
||||||
// If we want to add something like by whom later on,
|
|
||||||
// we can just append it to the content e.g auth()?->user()?->id ?? 'API'.
|
|
||||||
self::created(function ($model) {
|
self::created(function ($model) {
|
||||||
Log::create([
|
Log::create([
|
||||||
'user_id' => $model->id,
|
'user_id' => auth()?->user()?->id ?? 1,
|
||||||
'content' => 'User created.',
|
'loggable_type' => self::class,
|
||||||
|
'loggable_id' => $model->id,
|
||||||
|
'action' => LogAction::CREATE,
|
||||||
|
'content' => $model->full_name,
|
||||||
|
'ip' => request()->ip(),
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@ -14,9 +14,11 @@ return new class extends Migration
|
|||||||
Schema::create('logs', function (Blueprint $table) {
|
Schema::create('logs', function (Blueprint $table) {
|
||||||
$table->id();
|
$table->id();
|
||||||
$table->foreignIdFor(User::class)->nullable();
|
$table->foreignIdFor(User::class)->nullable();
|
||||||
$table->foreignIdFor(Quote::class)->nullable();
|
$table->string('loggable_type');
|
||||||
$table->foreignIdFor(RequestedQuote::class)->nullable();
|
$table->integer('loggable_id');
|
||||||
$table->string('content');
|
$table->string('action');
|
||||||
|
$table->text('content');
|
||||||
|
$table->string('ip');
|
||||||
$table->timestamps();
|
$table->timestamps();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@ -12,7 +12,7 @@ class DatabaseSeeder extends Seeder
|
|||||||
*/
|
*/
|
||||||
public function run(): void
|
public function run(): void
|
||||||
{
|
{
|
||||||
$this->call(BaseQuotesSeeder::class);
|
|
||||||
$this->call(PriceyBotSeeder::class);
|
$this->call(PriceyBotSeeder::class);
|
||||||
|
$this->call(BaseQuotesSeeder::class);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,9 +1,5 @@
|
|||||||
<x-app-layout>
|
<x-app-layout>
|
||||||
<div class="py-12">
|
<div class="max-w-7xl mx-auto sm:px-6 lg:px-8">
|
||||||
<div class="max-w-7xl mx-auto sm:px-6 lg:px-8">
|
<livewire:pages.admin.logs/>
|
||||||
<div class="p-6 text-nexi-black dark:text-gray-100">
|
|
||||||
<livewire:pages.admin.logs/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</x-app-layout>
|
</x-app-layout>
|
||||||
|
|||||||
@ -1,23 +1,23 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
use App\Models\Log;
|
use App\Models\Log;
|
||||||
use Illuminate\Database\Eloquent\Collection;
|
|
||||||
use Livewire\Attributes\Layout;
|
use Livewire\Attributes\Layout;
|
||||||
use Livewire\Volt\Component;
|
use Livewire\Volt\Component;
|
||||||
|
use Livewire\WithPagination;
|
||||||
|
|
||||||
new #[Layout('layouts.app')] class extends Component
|
new #[Layout('layouts.app')] class extends Component
|
||||||
{
|
{
|
||||||
public Collection $logs;
|
use WithPagination;
|
||||||
|
|
||||||
public function mount(): void
|
public function with(): array
|
||||||
{
|
{
|
||||||
$this->getLogs();
|
$logs = Log::with(['user', 'loggable'])
|
||||||
}
|
->orderByDesc('created_at')
|
||||||
|
->paginate(15);
|
||||||
|
|
||||||
public function getLogs(): void
|
return [
|
||||||
{
|
'logs' => $logs,
|
||||||
// TODO: look into pagination for this.
|
];
|
||||||
$this->logs = Log::with(['user', 'quote', 'requestedQuote'])->get()->sortByDesc('created_at');
|
|
||||||
}
|
}
|
||||||
}; ?>
|
}; ?>
|
||||||
|
|
||||||
@ -30,38 +30,56 @@ new #[Layout('layouts.app')] class extends Component
|
|||||||
class="py-3.5 pl-4 pr-3 text-left text-sm font-semibold text-nexi-black dark:text-gray-200 sm:pl-6">
|
class="py-3.5 pl-4 pr-3 text-left text-sm font-semibold text-nexi-black dark:text-gray-200 sm:pl-6">
|
||||||
User
|
User
|
||||||
</th>
|
</th>
|
||||||
|
<th scope="col"
|
||||||
|
class="px-3 py-3.5 text-left text-sm font-semibold text-nexi-black dark:text-gray-200">
|
||||||
|
Type
|
||||||
|
</th>
|
||||||
|
<th scope="col"
|
||||||
|
class="px-3 py-3.5 text-left text-sm font-semibold text-nexi-black dark:text-gray-200">
|
||||||
|
Entity ID
|
||||||
|
</th>
|
||||||
|
<th scope="col"
|
||||||
|
class="px-3 py-3.5 text-left text-sm font-semibold text-nexi-black dark:text-gray-200">
|
||||||
|
Action
|
||||||
|
</th>
|
||||||
<th scope="col"
|
<th scope="col"
|
||||||
class="px-3 py-3.5 text-left text-sm font-semibold text-nexi-black dark:text-gray-200">
|
class="px-3 py-3.5 text-left text-sm font-semibold text-nexi-black dark:text-gray-200">
|
||||||
Logs
|
Logs
|
||||||
</th>
|
</th>
|
||||||
<th scope="col"
|
<th scope="col"
|
||||||
class="px-3 py-3.5 text-left text-sm font-semibold text-nexi-black dark:text-gray-200">
|
class="px-3 py-3.5 text-left text-sm font-semibold text-nexi-black dark:text-gray-200">
|
||||||
Type
|
IP
|
||||||
</th>
|
</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
@foreach ($logs as $log)
|
@foreach ($logs as $log)
|
||||||
<tr>
|
<tr>
|
||||||
<td class="whitespace-nowrap py-4 pl-4 pr-3 text-sm text-nexi-black dark:text-gray-200 sm:pl-0">
|
<td class="relative py-4 px-4 pr-3 text-sm sm:pl-6 border-t text-nexi-black dark:text-gray-200">
|
||||||
{{ $log?->user->fullName() ?? 'N/A' }}
|
{{ $log?->user?->full_name ?? 'Anonymous' }}
|
||||||
</td>
|
</td>
|
||||||
<td class="whitespace-nowrap px-3 py-4 text-sm text-nexi-black dark:text-gray-200">
|
<td class="relative py-4 pr-3 text-sm sm:pl-6 border-t text-nexi-black dark:text-gray-200">
|
||||||
|
{{ str_replace('App\Models\\', '', $log->loggable_type) }}
|
||||||
|
</td>
|
||||||
|
<td class="relative py-4 pr-3 text-sm sm:pl-6 border-t text-nexi-black dark:text-gray-200">
|
||||||
|
{{ $log->loggable_id }}
|
||||||
|
</td>
|
||||||
|
<td class="relative py-4 pr-3 text-sm sm:pl-6 border-t text-nexi-black dark:text-gray-200">
|
||||||
|
{{ $log->action }}
|
||||||
|
</td>
|
||||||
|
<td class="relative py-4 pr-3 text-sm sm:pl-6 border-t text-nexi-black dark:text-gray-200">
|
||||||
{{ $log->content }}
|
{{ $log->content }}
|
||||||
</td>
|
</td>
|
||||||
<td class="whitespace-nowrap px-3 py-4 text-sm text-nexi-black dark:text-gray-200">
|
<td class="relative py-4 pr-3 text-sm sm:pl-6 border-t text-nexi-black dark:text-gray-200">
|
||||||
@if (!empty($log->quote_id))
|
{{ $log->ip }}
|
||||||
Quote - {{ $log->quote_id }}
|
|
||||||
@elseif (!empty($log->requested_quote_id))
|
|
||||||
Requsted Quote - ID: {{ $log->requested_quote_id }}
|
|
||||||
@else
|
|
||||||
N/A
|
|
||||||
@endif
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@endforeach
|
@endforeach
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="mt-4">
|
||||||
|
{{ $logs->links() }}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
use App\Enums\LogAction;
|
||||||
use App\Models\Log;
|
use App\Models\Log;
|
||||||
use Illuminate\Support\Facades\Http;
|
use Illuminate\Support\Facades\Http;
|
||||||
use Livewire\Attributes\Layout;
|
use Livewire\Attributes\Layout;
|
||||||
@ -19,8 +20,12 @@ new #[Layout('layouts.app')] class extends Component
|
|||||||
$response = Http::post(config('bot.webhook'), ['text' => $validated['quote']]);
|
$response = Http::post(config('bot.webhook'), ['text' => $validated['quote']]);
|
||||||
|
|
||||||
Log::create([
|
Log::create([
|
||||||
'user_id' => auth()?->user()?->id,
|
'user_id' => auth()->user()->id,
|
||||||
'content' => "Quote sent. {$validated['quote']}",
|
'loggable_type' => Log::class,
|
||||||
|
'loggable_id' => null,
|
||||||
|
'action' => LogAction::SEND,
|
||||||
|
'content' => $validated['quote'],
|
||||||
|
'ip' => request()->ip(),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$this->quote = '';
|
$this->quote = '';
|
||||||
|
|||||||
@ -1,6 +1,8 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
use App\Enums\LogAction;
|
||||||
use App\Models\Log;
|
use App\Models\Log;
|
||||||
|
use App\Models\User;
|
||||||
use App\Providers\RouteServiceProvider;
|
use App\Providers\RouteServiceProvider;
|
||||||
use Illuminate\Auth\Events\Lockout;
|
use Illuminate\Auth\Events\Lockout;
|
||||||
use Illuminate\Support\Facades\RateLimiter;
|
use Illuminate\Support\Facades\RateLimiter;
|
||||||
@ -41,8 +43,12 @@ new #[Layout('layouts.guest')] class extends Component
|
|||||||
session()->regenerate();
|
session()->regenerate();
|
||||||
|
|
||||||
Log::create([
|
Log::create([
|
||||||
'user_id' => auth()?->user()?->id,
|
'user_id' => auth()->user()->id,
|
||||||
'content' => "Quote sent. {$quote}",
|
'loggable_type' => User::class,
|
||||||
|
'loggable_id' => auth()->user()->id,
|
||||||
|
'action' => LogAction::ACCESS,
|
||||||
|
'content' => 'User logged in',
|
||||||
|
'ip' => request()->ip(),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$this->redirect(
|
$this->redirect(
|
||||||
|
|||||||
@ -1,5 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
use App\Enums\LogAction;
|
||||||
|
use App\Models\User;
|
||||||
use App\Models\Log;
|
use App\Models\Log;
|
||||||
use Illuminate\Auth\Events\PasswordReset;
|
use Illuminate\Auth\Events\PasswordReset;
|
||||||
use Illuminate\Support\Facades\Hash;
|
use Illuminate\Support\Facades\Hash;
|
||||||
@ -60,8 +62,12 @@ new #[Layout('layouts.guest')] class extends Component
|
|||||||
session()->flash('status', __($status));
|
session()->flash('status', __($status));
|
||||||
|
|
||||||
Log::create([
|
Log::create([
|
||||||
'user_id' => auth()?->user()?->id,
|
'user_id' => auth()->user()->id,
|
||||||
'content' => "Quote sent. {$quote}",
|
'loggable_type' => User::class,
|
||||||
|
'loggable_id' => auth()?->user()?->id,
|
||||||
|
'action' => LogAction::UPDATE,
|
||||||
|
'content' => 'User reset password via reset',
|
||||||
|
'ip' => request()->ip(),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$this->redirectRoute('login', navigate: true);
|
$this->redirectRoute('login', navigate: true);
|
||||||
|
|||||||
@ -1,6 +1,8 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
use App\Enums\LogAction;
|
||||||
use App\Models\Log;
|
use App\Models\Log;
|
||||||
|
use App\Models\User;
|
||||||
use Illuminate\Support\Facades\Hash;
|
use Illuminate\Support\Facades\Hash;
|
||||||
use Illuminate\Validation\Rules\Password;
|
use Illuminate\Validation\Rules\Password;
|
||||||
use Illuminate\Validation\ValidationException;
|
use Illuminate\Validation\ValidationException;
|
||||||
@ -30,8 +32,12 @@ new class extends Component
|
|||||||
]);
|
]);
|
||||||
|
|
||||||
Log::create([
|
Log::create([
|
||||||
'user_id' => auth()?->user()?->id,
|
'user_id' => auth()->user()->id,
|
||||||
'content' => "Quote sent. {$quote}",
|
'loggable_type' => User::class,
|
||||||
|
'loggable_id' => auth()?->user()?->id,
|
||||||
|
'action' => LogAction::UPDATE,
|
||||||
|
'content' => 'User updated password',
|
||||||
|
'ip' => request()->ip(),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$this->reset('current_password', 'password', 'password_confirmation');
|
$this->reset('current_password', 'password', 'password_confirmation');
|
||||||
@ -53,25 +59,41 @@ new class extends Component
|
|||||||
|
|
||||||
<form wire:submit="updatePassword" class="mt-6 space-y-6">
|
<form wire:submit="updatePassword" class="mt-6 space-y-6">
|
||||||
<div>
|
<div>
|
||||||
<x-input-label for="current_password" :value="__('Current Password')" />
|
<x-input-label for="current_password" :value="__('Current Password')"/>
|
||||||
<x-text-input wire:model="current_password" id="current_password" name="current_password" type="password" class="mt-1 block w-full" autocomplete="current-password" />
|
<x-text-input wire:model="current_password"
|
||||||
<x-input-error :messages="$errors->get('current_password')" class="mt-2" />
|
id="current_password"
|
||||||
|
name="current_password"
|
||||||
|
type="password"
|
||||||
|
class="mt-1 block w-full"
|
||||||
|
autocomplete="current-password"/>
|
||||||
|
<x-input-error :messages="$errors->get('current_password')" class="mt-2"/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<x-input-label for="password" :value="__('New Password')" />
|
<x-input-label for="password" :value="__('New Password')"/>
|
||||||
<x-text-input wire:model="password" id="password" name="password" type="password" class="mt-1 block w-full" autocomplete="new-password" />
|
<x-text-input wire:model="password"
|
||||||
<x-input-error :messages="$errors->get('password')" class="mt-2" />
|
id="password"
|
||||||
|
name="password"
|
||||||
|
type="password"
|
||||||
|
class="mt-1 block w-full"
|
||||||
|
autocomplete="new-password"/>
|
||||||
|
<x-input-error :messages="$errors->get('password')" class="mt-2"/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<x-input-label for="password_confirmation" :value="__('Confirm Password')" />
|
<x-input-label for="password_confirmation" :value="__('Confirm Password')"/>
|
||||||
<x-text-input wire:model="password_confirmation" id="password_confirmation" name="password_confirmation" type="password" class="mt-1 block w-full" autocomplete="new-password" />
|
<x-text-input wire:model="password_confirmation"
|
||||||
<x-input-error :messages="$errors->get('password_confirmation')" class="mt-2" />
|
id="password_confirmation"
|
||||||
|
name="password_confirmation"
|
||||||
|
type="password"
|
||||||
|
class="mt-1 block w-full"
|
||||||
|
autocomplete="new-password"/>
|
||||||
|
<x-input-error :messages="$errors->get('password_confirmation')" class="mt-2"/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flex items-center gap-4">
|
<div class="flex items-center gap-4">
|
||||||
<x-primary-button wire:loading.attr="disabled" wire:loading.class="opacity-50">{{ __('Save') }}</x-primary-button>
|
<x-primary-button wire:loading.attr="disabled"
|
||||||
|
wire:loading.class="opacity-50">{{ __('Save') }}</x-primary-button>
|
||||||
|
|
||||||
<x-action-message class="mr-3" on="password-updated">
|
<x-action-message class="mr-3" on="password-updated">
|
||||||
{{ __('Saved.') }}
|
{{ __('Saved.') }}
|
||||||
|
|||||||
@ -7,8 +7,7 @@ export default defineConfig({
|
|||||||
input: [
|
input: [
|
||||||
'resources/css/app.css',
|
'resources/css/app.css',
|
||||||
'resources/js/app.js',
|
'resources/js/app.js',
|
||||||
],
|
]
|
||||||
refresh: true,
|
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user