feat: auditable (#933)

This commit is contained in:
Kyrch
2025-08-27 01:30:42 -03:00
committed by GitHub
parent 5614c0d4c6
commit 7382ed4a37
22 changed files with 421 additions and 4 deletions
+1
View File
@@ -8,6 +8,7 @@ APP_ENV=local
APP_DEBUG=true
DEBUGBAR_ENABLED=true
DEBUGBAR_EDITOR=
AUDITING_ENABLED=true
APP_URL=http://localhost
ASSET_URL=null
APP_KEY=
+1
View File
@@ -8,6 +8,7 @@ APP_ENV=local
APP_DEBUG=true
DEBUGBAR_ENABLED=true
DEBUGBAR_EDITOR=
AUDITING_ENABLED=true
APP_URL=http://localhost
ASSET_URL=null
APP_KEY=
+7
View File
@@ -35,6 +35,13 @@ class Dump extends BaseModel
final public const ATTRIBUTE_PATH = 'path';
final public const ATTRIBUTE_LINK = 'link';
/**
* Is auditing disabled?
*
* @var bool
*/
public static $auditingDisabled = true;
/**
* The attributes that are mass assignable.
*
+7
View File
@@ -36,6 +36,13 @@ class Feature extends BaseModel
final public const ATTRIBUTE_SCOPE = 'scope';
final public const ATTRIBUTE_VALUE = 'value';
/**
* Is auditing disabled?
*
* @var bool
*/
public static $auditingDisabled = true;
/**
* The attributes that are mass assignable.
*
+4 -1
View File
@@ -11,6 +11,8 @@ use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\Config;
use Illuminate\Support\Str;
use OwenIt\Auditing\Auditable as HasAudits;
use OwenIt\Auditing\Contracts\Auditable;
/**
* Class BaseModel.
@@ -18,8 +20,9 @@ use Illuminate\Support\Str;
* @property Carbon $created_at
* @property Carbon $updated_at
*/
abstract class BaseModel extends Model implements HasSubtitle, Nameable
abstract class BaseModel extends Model implements Auditable, HasSubtitle, Nameable
{
use HasAudits;
use ModelHasActionLogs;
/**
+7
View File
@@ -34,6 +34,13 @@ class DiscordThread extends BaseModel
final public const RELATION_ANIME = 'anime';
/**
* Is auditing disabled?
*
* @var bool
*/
public static $auditingDisabled = true;
/**
* The attributes that are mass assignable.
*
+7
View File
@@ -43,6 +43,13 @@ class ExternalEntry extends BaseModel
final public const RELATION_PROFILE = 'externalprofile';
final public const RELATION_USER = 'externalprofile.user';
/**
* Is auditing disabled?
*
* @var bool
*/
public static $auditingDisabled = true;
/**
* The attributes that are mass assignable.
*
+7
View File
@@ -42,6 +42,13 @@ class ExternalToken extends BaseModel
final public const RELATION_USER = 'externalprofile.user';
final public const RELATION_USER_SHALLOW = 'user';
/**
* Is auditing disabled?
*
* @var bool
*/
public static $auditingDisabled = true;
/**
* The attributes that are mass assignable.
*
+7
View File
@@ -64,6 +64,13 @@ class ExternalProfile extends BaseModel
final public const RELATION_EXTERNAL_TOKEN = 'externaltoken';
final public const RELATION_USER = 'user';
/**
* Is auditing disabled?
*
* @var bool
*/
public static $auditingDisabled = true;
/**
* The attributes that are mass assignable.
*
+7
View File
@@ -69,6 +69,13 @@ class Playlist extends BaseModel implements HasAggregateLikes, HasHashids, HasIm
final public const RELATION_USER = 'user';
final public const RELATION_VIEWS = 'views';
/**
* Is auditing disabled?
*
* @var bool
*/
public static $auditingDisabled = true;
/**
* The attributes that are mass assignable.
*
@@ -62,6 +62,13 @@ class PlaylistTrack extends BaseModel implements HasHashids, InteractsWithSchema
final public const RELATION_THEME_GROUP = 'animethemeentry.animetheme.group';
final public const RELATION_VIDEO = 'video';
/**
* Is auditing disabled?
*
* @var bool
*/
public static $auditingDisabled = true;
/**
* The attributes that are mass assignable.
*
+7
View File
@@ -34,6 +34,13 @@ class Encode extends BaseModel
final public const RELATION_USER = 'user';
final public const RELATION_VIDEO = 'video';
/**
* Is auditing disabled?
*
* @var bool
*/
public static $auditingDisabled = true;
/**
* The table associated with the model.
*
+7
View File
@@ -33,6 +33,13 @@ class Like extends BaseModel
final public const RELATION_USER = 'user';
final public const RELATION_LIKEABLE = 'likeable';
/**
* Is auditing disabled?
*
* @var bool
*/
public static $auditingDisabled = true;
/**
* The table associated with the model.
*
+7
View File
@@ -51,6 +51,13 @@ class Report extends BaseModel
final public const RELATION_STEPS = 'steps';
final public const RELATION_USER = 'user';
/**
* Is auditing disabled?
*
* @var bool
*/
public static $auditingDisabled = true;
/**
* The attributes that are mass assignable.
*
+7
View File
@@ -58,6 +58,13 @@ class ReportStep extends BaseModel
final public const RELATION_TARGET = 'target';
final public const RELATION_REPORT = 'report';
/**
* Is auditing disabled?
*
* @var bool
*/
public static $auditingDisabled = true;
/**
* The attributes that are mass assignable.
*
+2 -1
View File
@@ -19,6 +19,7 @@ use Database\Factories\Wiki\Song\PerformanceFactory;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\MorphTo;
use Illuminate\Database\Eloquent\Relations\Relation;
/**
* Class Performance.
@@ -132,7 +133,7 @@ class Performance extends BaseModel implements SoftDeletable
*/
public function isMembership(): bool
{
return $this->artist_type === Membership::class;
return $this->artist_type === Relation::getMorphAlias(Membership::class);
}
/**
-1
View File
@@ -12,7 +12,6 @@ use App\Events\Wiki\Video\Script\VideoScriptDeleted;
use App\Events\Wiki\Video\Script\VideoScriptForceDeleting;
use App\Events\Wiki\Video\Script\VideoScriptRestored;
use App\Events\Wiki\Video\Script\VideoScriptUpdated;
use App\Http\Api\Schema\Schema;
use App\Http\Api\Schema\Wiki\Video\ScriptSchema;
use App\Models\BaseModel;
use App\Models\Wiki\Video;
+1
View File
@@ -47,6 +47,7 @@
"leandrocfe/filament-apex-charts": "4.0-beta1",
"mll-lab/graphql-php-scalars": "^6.4.1",
"mll-lab/laravel-graphiql": "^3.3.4",
"owen-it/laravel-auditing": "^14.0",
"propaganistas/laravel-disposable-email": "^2.4.17",
"rebing/graphql-laravel": "^9.10",
"spatie/db-dumper": "^3.8.0",
Generated
+85 -1
View File
@@ -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": "d5988605c29dfd384eb615972e5fc3fd",
"content-hash": "cdde89d37d3b79f71315942ac1dccf16",
"packages": [
{
"name": "anourvalar/eloquent-serialize",
@@ -6487,6 +6487,90 @@
],
"time": "2025-07-07T06:15:55+00:00"
},
{
"name": "owen-it/laravel-auditing",
"version": "v14.0.0",
"source": {
"type": "git",
"url": "https://github.com/owen-it/laravel-auditing.git",
"reference": "f92602d1b3f53df29ddd577290e9d735ea707c53"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/owen-it/laravel-auditing/zipball/f92602d1b3f53df29ddd577290e9d735ea707c53",
"reference": "f92602d1b3f53df29ddd577290e9d735ea707c53",
"shasum": ""
},
"require": {
"ext-json": "*",
"illuminate/console": "^11.0|^12.0",
"illuminate/database": "^11.0|^12.0",
"illuminate/filesystem": "^11.0|^12.0",
"php": "^8.2"
},
"require-dev": {
"mockery/mockery": "^1.5.1",
"orchestra/testbench": "^9.0|^10.0",
"phpunit/phpunit": "^11.0"
},
"type": "package",
"extra": {
"laravel": {
"providers": [
"OwenIt\\Auditing\\AuditingServiceProvider"
]
},
"branch-alias": {
"dev-master": "v14-dev"
}
},
"autoload": {
"psr-4": {
"OwenIt\\Auditing\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Antério Vieira",
"email": "anteriovieira@gmail.com"
},
{
"name": "Raphael França",
"email": "raphaelfrancabsb@gmail.com"
},
{
"name": "Morten D. Hansen",
"email": "morten@visia.dk"
}
],
"description": "Audit changes of your Eloquent models in Laravel",
"homepage": "https://laravel-auditing.com",
"keywords": [
"Accountability",
"Audit",
"auditing",
"changes",
"eloquent",
"history",
"laravel",
"log",
"logging",
"lumen",
"observer",
"record",
"revision",
"tracking"
],
"support": {
"issues": "https://github.com/owen-it/laravel-auditing/issues",
"source": "https://github.com/owen-it/laravel-auditing"
},
"time": "2025-02-26T16:40:54+00:00"
},
{
"name": "paragonie/constant_time_encoding",
"version": "v3.0.0",
+1
View File
@@ -214,6 +214,7 @@ return [
/*
* Package Service Providers...
*/
OwenIt\Auditing\AuditingServiceProvider::class,
/*
* Application Service Providers...
+196
View File
@@ -0,0 +1,196 @@
<?php
declare(strict_types=1);
return [
'enabled' => env('AUDITING_ENABLED', true),
/*
|--------------------------------------------------------------------------
| Audit Implementation
|--------------------------------------------------------------------------
|
| Define which Audit model implementation should be used.
|
*/
'implementation' => OwenIt\Auditing\Models\Audit::class,
/*
|--------------------------------------------------------------------------
| User Morph prefix & Guards
|--------------------------------------------------------------------------
|
| Define the morph prefix and authentication guards for the User resolver.
|
*/
'user' => [
'morph_prefix' => 'user',
'guards' => [
'web',
'api',
],
'resolver' => OwenIt\Auditing\Resolvers\UserResolver::class,
],
/*
|--------------------------------------------------------------------------
| Audit Resolvers
|--------------------------------------------------------------------------
|
| Define the IP Address, User Agent and URL resolver implementations.
|
*/
'resolvers' => [],
/*
|--------------------------------------------------------------------------
| Audit Events
|--------------------------------------------------------------------------
|
| The Eloquent events that trigger an Audit.
|
*/
'events' => [
'created',
'updated',
'deleted',
'restored',
],
/*
|--------------------------------------------------------------------------
| Strict Mode
|--------------------------------------------------------------------------
|
| Enable the strict mode when auditing?
|
*/
'strict' => false,
/*
|--------------------------------------------------------------------------
| Global exclude
|--------------------------------------------------------------------------
|
| Have something you always want to exclude by default? - add it here.
| Note that this is overwritten (not merged) with local exclude
|
*/
'exclude' => [],
/*
|--------------------------------------------------------------------------
| Empty Values
|--------------------------------------------------------------------------
|
| Should Audit records be stored when the recorded old_values & new_values
| are both empty?
|
| Some events may be empty on purpose. Use allowed_empty_values to exclude
| those from the empty values check. For example when auditing
| model retrieved events which will never have new and old values.
|
|
*/
'empty_values' => true,
'allowed_empty_values' => [
'retrieved',
],
/*
|--------------------------------------------------------------------------
| Allowed Array Values
|--------------------------------------------------------------------------
|
| Should the array values be audited?
|
| By default, array values are not allowed. This is to prevent performance
| issues when storing large amounts of data. You can override this by
| setting allow_array_values to true.
*/
'allowed_array_values' => false,
/*
|--------------------------------------------------------------------------
| Audit Timestamps
|--------------------------------------------------------------------------
|
| Should the created_at, updated_at and deleted_at timestamps be audited?
|
*/
'timestamps' => false,
/*
|--------------------------------------------------------------------------
| Audit Threshold
|--------------------------------------------------------------------------
|
| Specify a threshold for the amount of Audit records a model can have.
| Zero means no limit.
|
*/
'threshold' => 0,
/*
|--------------------------------------------------------------------------
| Audit Driver
|--------------------------------------------------------------------------
|
| The default audit driver used to keep track of changes.
|
*/
'driver' => 'database',
/*
|--------------------------------------------------------------------------
| Audit Driver Configurations
|--------------------------------------------------------------------------
|
| Available audit drivers and respective configurations.
|
*/
'drivers' => [
'database' => [
'table' => 'audits',
'connection' => null,
],
],
/*
|--------------------------------------------------------------------------
| Audit Queue Configurations
|--------------------------------------------------------------------------
|
| Available audit queue configurations.
|
*/
'queue' => [
'enable' => false,
'connection' => 'sync',
'queue' => 'default',
'delay' => 0,
],
/*
|--------------------------------------------------------------------------
| Audit Console
|--------------------------------------------------------------------------
|
| Whether console events should be audited (eg. php artisan db:seed).
|
*/
'console' => false,
];
@@ -0,0 +1,46 @@
<?php
declare(strict_types=1);
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
{
$connection = config('audit.drivers.database.connection', config('database.default'));
$table = config('audit.drivers.database.table', 'audits');
Schema::connection($connection)->create($table, function (Blueprint $table) {
$morphPrefix = config('audit.user.morph_prefix', 'user');
$table->bigIncrements('id');
$table->string($morphPrefix.'_type')->nullable();
$table->unsignedBigInteger($morphPrefix.'_id')->nullable();
$table->string('event');
$table->morphs('auditable');
$table->text('old_values')->nullable();
$table->text('new_values')->nullable();
$table->string('tags')->nullable();
$table->timestamps();
$table->index([$morphPrefix.'_id', $morphPrefix.'_type']);
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
$connection = config('audit.drivers.database.connection', config('database.default'));
$table = config('audit.drivers.database.table', 'audits');
Schema::connection($connection)->dropIfExists($table);
}
};