Merge remote-tracking branch 'origin/develop'
This commit is contained in:
+10
-1
@@ -6,6 +6,8 @@ use App\Models\Setting;
|
||||
use App\Notifications\AuditNotification;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\Support\Str;
|
||||
use Osama\LaravelTeamsNotification\TeamsNotification;
|
||||
|
||||
trait Loggable
|
||||
{
|
||||
@@ -242,7 +244,14 @@ trait Loggable
|
||||
'location' => ($location) ? $location->name : '',
|
||||
'note' => $note,
|
||||
];
|
||||
Setting::getSettings()->notify(new AuditNotification($params));
|
||||
if(Setting::getSettings()->webhook_selected === 'microsoft' && Str::contains(Setting::getSettings()->webhook_endpoint, 'workflows')){
|
||||
$message = AuditNotification::toMicrosoftTeams($params);
|
||||
$notification = new TeamsNotification(Setting::getSettings()->webhook_endpoint);
|
||||
$notification->success()->sendMessage($message[0], $message[1]);
|
||||
}
|
||||
else {
|
||||
Setting::getSettings()->notify(new AuditNotification($params));
|
||||
}
|
||||
|
||||
return $log;
|
||||
}
|
||||
|
||||
@@ -44,44 +44,6 @@ class ReportTemplate extends Model
|
||||
$builder->where('created_by', auth()->id());
|
||||
}
|
||||
});
|
||||
|
||||
static::created(function (ReportTemplate $reportTemplate) {
|
||||
$logAction = new Actionlog([
|
||||
'item_type' => ReportTemplate::class,
|
||||
'item_id' => $reportTemplate->id,
|
||||
'created_by' => auth()->id(),
|
||||
]);
|
||||
|
||||
$logAction->logaction('create');
|
||||
});
|
||||
|
||||
static::updated(function (ReportTemplate $reportTemplate) {
|
||||
$changed = [];
|
||||
|
||||
foreach ($reportTemplate->getDirty() as $key => $value) {
|
||||
$changed[$key] = [
|
||||
'old' => $reportTemplate->getOriginal($key),
|
||||
'new' => $reportTemplate->getAttribute($key),
|
||||
];
|
||||
}
|
||||
|
||||
$logAction = new Actionlog();
|
||||
$logAction->item_type = ReportTemplate::class;
|
||||
$logAction->item_id = $reportTemplate->id;
|
||||
$logAction->created_by = auth()->id();
|
||||
$logAction->log_meta = json_encode($changed);
|
||||
$logAction->logaction('update');
|
||||
});
|
||||
|
||||
static::deleted(function (ReportTemplate $reportTemplate) {
|
||||
$logAction = new Actionlog([
|
||||
'item_type' => ReportTemplate::class,
|
||||
'item_id' => $reportTemplate->id,
|
||||
'created_by' => auth()->id(),
|
||||
]);
|
||||
|
||||
$logAction->logaction('delete');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -4,8 +4,13 @@ namespace App\Notifications;
|
||||
|
||||
use App\Models\Setting;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Notifications\Channels\SlackWebhookChannel;
|
||||
use Illuminate\Notifications\Messages\SlackMessage;
|
||||
use Illuminate\Notifications\Notification;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\Support\Str;
|
||||
use NotificationChannels\MicrosoftTeams\MicrosoftTeamsChannel;
|
||||
use NotificationChannels\MicrosoftTeams\MicrosoftTeamsMessage;
|
||||
|
||||
class AuditNotification extends Notification
|
||||
{
|
||||
@@ -35,10 +40,14 @@ class AuditNotification extends Notification
|
||||
public function via()
|
||||
{
|
||||
$notifyBy = [];
|
||||
if (Setting::getSettings()->webhook_endpoint) {
|
||||
$notifyBy[] = 'slack';
|
||||
if (Setting::getSettings()->webhook_selected == 'slack' || Setting::getSettings()->webhook_selected == 'general' ) {
|
||||
Log::debug('use webhook');
|
||||
$notifyBy[] = SlackWebhookChannel::class;
|
||||
}
|
||||
if (Setting::getSettings()->webhook_selected == 'microsoft' && Setting::getSettings()->webhook_endpoint) {
|
||||
|
||||
$notifyBy[] = MicrosoftTeamsChannel::class;
|
||||
}
|
||||
return $notifyBy;
|
||||
}
|
||||
|
||||
@@ -63,4 +72,30 @@ class AuditNotification extends Notification
|
||||
->fields($fields);
|
||||
});
|
||||
}
|
||||
|
||||
public static function toMicrosoftTeams($params)
|
||||
{
|
||||
$item = $params['item'];
|
||||
$admin_user = $params['admin'];
|
||||
$note = $params['note'];
|
||||
$location = $params['location'];
|
||||
$setting = Setting::getSettings();
|
||||
|
||||
if(!Str::contains($setting->webhook_endpoint, 'workflows')) {
|
||||
return MicrosoftTeamsMessage::create()
|
||||
->to($setting->webhook_endpoint)
|
||||
->type('success')
|
||||
->title(class_basename(get_class($params['item'])) . ' Audited')
|
||||
->addStartGroupToSection('activityText')
|
||||
->fact(trans('mail.asset'), $item)
|
||||
->fact(trans('general.administrator'), $admin_user->present()->viewUrl() . '|' . $admin_user->present()->fullName());
|
||||
}
|
||||
$message = class_basename(get_class($params['item'])) . ' Audited By '.$admin_user->present()->fullName();
|
||||
$details = [
|
||||
trans('mail.asset') => htmlspecialchars_decode($item->present()->name),
|
||||
trans('mail.notes') => $note ?: '',
|
||||
trans('general.location') => $location ?: '',
|
||||
];
|
||||
return [$message, $details];
|
||||
}
|
||||
}
|
||||
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
use App\Models\ReportTemplate;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
return new class extends Migration {
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
DB::table("action_logs")
|
||||
->where("item_type", ReportTemplate::class)
|
||||
->whereIn("action_type", ["create", "update", "delete"])
|
||||
->delete();
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
// nothing to do here...
|
||||
}
|
||||
};
|
||||
Vendored
+2
-2
@@ -966,9 +966,9 @@ a.btn-default:hover,
|
||||
/* Use same as Header picker */
|
||||
--text-main: #BBB;
|
||||
--text-sub: #9b9b9b;
|
||||
--link: #296282;
|
||||
--link: #003366;
|
||||
/* Use same as Header picker, lighten by 70% */
|
||||
--visited-link: #5fa4cc;
|
||||
--visited-link: #0066cc;
|
||||
/* Use same as Header picker, lighten by 70% */
|
||||
--hover-link: #86bad8;
|
||||
/* Use same as Header picker, lighten by 70% */
|
||||
|
||||
+2
-2
@@ -966,9 +966,9 @@ a.btn-default:hover,
|
||||
/* Use same as Header picker */
|
||||
--text-main: #BBB;
|
||||
--text-sub: #9b9b9b;
|
||||
--link: #296282;
|
||||
--link: #003366;
|
||||
/* Use same as Header picker, lighten by 70% */
|
||||
--visited-link: #5fa4cc;
|
||||
--visited-link: #0066cc;
|
||||
/* Use same as Header picker, lighten by 70% */
|
||||
--hover-link: #86bad8;
|
||||
/* Use same as Header picker, lighten by 70% */
|
||||
|
||||
Vendored
+2
-2
@@ -185,9 +185,9 @@ a.btn-default:hover,
|
||||
/* Use same as Header picker */
|
||||
--text-main: #BBB;
|
||||
--text-sub: #9b9b9b;
|
||||
--link: #296282;
|
||||
--link: #003366;
|
||||
/* Use same as Header picker, lighten by 70% */
|
||||
--visited-link: #5fa4cc;
|
||||
--visited-link: #0066cc;
|
||||
/* Use same as Header picker, lighten by 70% */
|
||||
--hover-link: #86bad8;
|
||||
/* Use same as Header picker, lighten by 70% */
|
||||
|
||||
+2
-2
@@ -185,9 +185,9 @@ a.btn-default:hover,
|
||||
/* Use same as Header picker */
|
||||
--text-main: #BBB;
|
||||
--text-sub: #9b9b9b;
|
||||
--link: #296282;
|
||||
--link: #003366;
|
||||
/* Use same as Header picker, lighten by 70% */
|
||||
--visited-link: #5fa4cc;
|
||||
--visited-link: #0066cc;
|
||||
/* Use same as Header picker, lighten by 70% */
|
||||
--hover-link: #86bad8;
|
||||
/* Use same as Header picker, lighten by 70% */
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"/js/build/app.js": "/js/build/app.js?id=65d7af7b9fa7fd0e05737526a0d1d282",
|
||||
"/css/dist/skins/skin-black-dark.css": "/css/dist/skins/skin-black-dark.css?id=06c13e817cc022028b3f4a33c0ca303a",
|
||||
"/css/dist/skins/_all-skins.css": "/css/dist/skins/_all-skins.css?id=e71ef4171dee5da63af390966ac60ffc",
|
||||
"/css/dist/skins/_all-skins.css": "/css/dist/skins/_all-skins.css?id=a134dd4a0ba684f97088d0698e3e5b78",
|
||||
"/css/build/overrides.css": "/css/build/overrides.css?id=6528155ed5ed8fddf4047de7f0d0298d",
|
||||
"/css/build/app.css": "/css/build/app.css?id=3422f2ca2056b952c3c361adf00c10b8",
|
||||
"/css/build/AdminLTE.css": "/css/build/AdminLTE.css?id=4ea0068716c1bb2434d87a16d51b98c9",
|
||||
@@ -16,7 +16,7 @@
|
||||
"/css/dist/skins/skin-green.css": "/css/dist/skins/skin-green.css?id=0a82a6ae6bb4e58fe62d162c4fb50397",
|
||||
"/css/dist/skins/skin-green-dark.css": "/css/dist/skins/skin-green-dark.css?id=bb302302d9566adf783a2b7dc31e840c",
|
||||
"/css/dist/skins/skin-contrast.css": "/css/dist/skins/skin-contrast.css?id=da6c7997d9de2f8329142399f0ce50da",
|
||||
"/css/dist/skins/skin-blue.css": "/css/dist/skins/skin-blue.css?id=f677207c6cf9678eb539abecb408c374",
|
||||
"/css/dist/skins/skin-blue.css": "/css/dist/skins/skin-blue.css?id=00459cc19228b28e7a4d70ce6a2ae1df",
|
||||
"/css/dist/skins/skin-blue-dark.css": "/css/dist/skins/skin-blue-dark.css?id=6ea836d8126de101081c49abbdb89417",
|
||||
"/css/dist/skins/skin-black.css": "/css/dist/skins/skin-black.css?id=76482123f6c70e866d6b971ba91de7bb",
|
||||
"/css/dist/all.css": "/css/dist/all.css?id=18ebb9c284b49dcf6c8e4fdb923ad923",
|
||||
@@ -92,11 +92,11 @@
|
||||
"/css/webfonts/fa-v4compatibility.woff2": "/css/webfonts/fa-v4compatibility.woff2?id=331c85bd61ffa93af09273d1bc2add5a",
|
||||
"/js/dist/bootstrap-table-locale-all.min.js": "/js/dist/bootstrap-table-locale-all.min.js?id=02dfc50d5b951dc6d260bd508968d319",
|
||||
"/js/dist/bootstrap-table-en-US.min.js": "/js/dist/bootstrap-table-en-US.min.js?id=1c350eabf064c309f67d6779e5cc4afa",
|
||||
"/css/dist/skins/_all-skins.min.css": "/css/dist/skins/_all-skins.min.css?id=e71ef4171dee5da63af390966ac60ffc",
|
||||
"/css/dist/skins/_all-skins.min.css": "/css/dist/skins/_all-skins.min.css?id=a134dd4a0ba684f97088d0698e3e5b78",
|
||||
"/css/dist/skins/skin-black-dark.min.css": "/css/dist/skins/skin-black-dark.min.css?id=06c13e817cc022028b3f4a33c0ca303a",
|
||||
"/css/dist/skins/skin-black.min.css": "/css/dist/skins/skin-black.min.css?id=76482123f6c70e866d6b971ba91de7bb",
|
||||
"/css/dist/skins/skin-blue-dark.min.css": "/css/dist/skins/skin-blue-dark.min.css?id=6ea836d8126de101081c49abbdb89417",
|
||||
"/css/dist/skins/skin-blue.min.css": "/css/dist/skins/skin-blue.min.css?id=f677207c6cf9678eb539abecb408c374",
|
||||
"/css/dist/skins/skin-blue.min.css": "/css/dist/skins/skin-blue.min.css?id=00459cc19228b28e7a4d70ce6a2ae1df",
|
||||
"/css/dist/skins/skin-contrast.min.css": "/css/dist/skins/skin-contrast.min.css?id=da6c7997d9de2f8329142399f0ce50da",
|
||||
"/css/dist/skins/skin-green-dark.min.css": "/css/dist/skins/skin-green-dark.min.css?id=bb302302d9566adf783a2b7dc31e840c",
|
||||
"/css/dist/skins/skin-green.min.css": "/css/dist/skins/skin-green.min.css?id=0a82a6ae6bb4e58fe62d162c4fb50397",
|
||||
|
||||
@@ -111,8 +111,8 @@
|
||||
--header: @blue; /* Use same as Header picker */
|
||||
--text-main: #BBB;
|
||||
--text-sub: #9b9b9b;
|
||||
--link:darken(@blue, 15%); /* Use same as Header picker, lighten by 70% */
|
||||
--visited-link: lighten(@blue,10%); /* Use same as Header picker, lighten by 70% */
|
||||
--link: #003366; /* Use same as Header picker, lighten by 70% */
|
||||
--visited-link: lighten(#003366,20%); /* Use same as Header picker, lighten by 70% */
|
||||
--hover-link: lighten(@blue,20%); /* Use same as Header picker, lighten by 70% */
|
||||
--nav-link: #FFF; /* Use same as Header picker */
|
||||
--light-link: #fff; /* Use same as Header picker */
|
||||
|
||||
@@ -1,71 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Unit\ActionLogTransformer;
|
||||
|
||||
use App\Http\Transformers\ActionlogsTransformer;
|
||||
use App\Models\Actionlog;
|
||||
use App\Models\ReportTemplate;
|
||||
use PHPUnit\Framework\Attributes\Group;
|
||||
use Tests\TestCase;
|
||||
|
||||
#[Group('activity-logging')]
|
||||
class ReportTemplateActionLogTransformerTest extends TestCase
|
||||
{
|
||||
public function testLogEntryForCreatingReportTemplateCanBeTransformed()
|
||||
{
|
||||
ReportTemplate::factory()->create();
|
||||
|
||||
$actionLogs = Actionlog::query()
|
||||
->whereMorphedTo('item', ReportTemplate::class)
|
||||
->where('action_type', 'create')
|
||||
->get();
|
||||
|
||||
// should be created when ActionLog is created
|
||||
$this->assertCount(1, $actionLogs);
|
||||
|
||||
$results = (new ActionlogsTransformer())->transformActionlogs($actionLogs, 10);
|
||||
|
||||
$this->assertArrayHasKey('rows', $results);
|
||||
$this->assertCount(1, $results['rows']);
|
||||
}
|
||||
|
||||
public function testLogEntryForUpdatingReportTemplateCanBeDisplayedTransformed()
|
||||
{
|
||||
$reportTemplate = ReportTemplate::factory()->create();
|
||||
|
||||
$reportTemplate->update([
|
||||
'options' => ['new' => 'value']
|
||||
]);
|
||||
|
||||
$actionLogs = Actionlog::query()
|
||||
->whereMorphedTo('item', ReportTemplate::class)
|
||||
->where('action_type', 'update')
|
||||
->get();
|
||||
|
||||
$this->assertCount(1, $actionLogs);
|
||||
|
||||
$results = (new ActionlogsTransformer())->transformActionlogs($actionLogs, 10);
|
||||
|
||||
$this->assertArrayHasKey('rows', $results);
|
||||
$this->assertCount(1, $results['rows']);
|
||||
}
|
||||
|
||||
public function testLogEntryForDeletingReportTemplateCanBeDisplayedTransformed()
|
||||
{
|
||||
$reportTemplate = ReportTemplate::factory()->create();
|
||||
|
||||
$reportTemplate->delete();
|
||||
|
||||
$actionLogs = Actionlog::query()
|
||||
->whereMorphedTo('item', ReportTemplate::class)
|
||||
->where('action_type', 'delete')
|
||||
->get();
|
||||
|
||||
$this->assertCount(1, $actionLogs);
|
||||
|
||||
$results = (new ActionlogsTransformer())->transformActionlogs($actionLogs, 10);
|
||||
|
||||
$this->assertArrayHasKey('rows', $results);
|
||||
$this->assertCount(1, $results['rows']);
|
||||
}
|
||||
}
|
||||
@@ -1,100 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Unit\Models\ReportTemplates;
|
||||
|
||||
use App\Models\ReportTemplate;
|
||||
use App\Models\User;
|
||||
use PHPUnit\Framework\Attributes\Group;
|
||||
use Tests\TestCase;
|
||||
|
||||
#[Group('custom-reporting')]
|
||||
#[Group('activity-logging')]
|
||||
class ReportTemplateActivityLoggingTest extends TestCase
|
||||
{
|
||||
public function testCreatingReportTemplateIsLogged()
|
||||
{
|
||||
$user = User::factory()->create();
|
||||
$this->actingAs($user);
|
||||
|
||||
$reportTemplate = ReportTemplate::factory()->create();
|
||||
|
||||
$this->assertDatabaseHas('action_logs', [
|
||||
'created_by' => $user->id,
|
||||
'action_type' => 'create',
|
||||
'target_id' => null,
|
||||
'target_type' => null,
|
||||
'item_type' => ReportTemplate::class,
|
||||
'item_id' => $reportTemplate->id,
|
||||
]);
|
||||
}
|
||||
|
||||
public function testUpdatingReportTemplateIsLogged()
|
||||
{
|
||||
$user = User::factory()->create();
|
||||
$this->actingAs($user);
|
||||
|
||||
$reportTemplate = ReportTemplate::factory()->create([
|
||||
'name' => 'Name A',
|
||||
'options' => [
|
||||
'company' => '1',
|
||||
'location' => '1',
|
||||
'by_company_id' => ['1'],
|
||||
'by_location_id' => ['17'],
|
||||
],
|
||||
]);
|
||||
|
||||
$reportTemplate->update([
|
||||
'name' => 'Another Name',
|
||||
'options' => [
|
||||
'company' => '1',
|
||||
'by_company_id' => ['1'],
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertDatabaseHas('action_logs', [
|
||||
'created_by' => $user->id,
|
||||
'action_type' => 'update',
|
||||
'target_id' => null,
|
||||
'target_type' => null,
|
||||
'item_type' => ReportTemplate::class,
|
||||
'item_id' => $reportTemplate->id,
|
||||
'log_meta' => json_encode([
|
||||
'name' => [
|
||||
'old' => 'Name A',
|
||||
'new' => 'Another Name'
|
||||
],
|
||||
'options' => [
|
||||
'old' => [
|
||||
'company' => '1',
|
||||
'location' => '1',
|
||||
'by_company_id' => ['1'],
|
||||
'by_location_id' => ['17'],
|
||||
],
|
||||
'new' => [
|
||||
'company' => '1',
|
||||
'by_company_id' => ['1'],
|
||||
],
|
||||
],
|
||||
]),
|
||||
]);
|
||||
}
|
||||
|
||||
public function testDeletingReportTemplateIsLogged()
|
||||
{
|
||||
$user = User::factory()->create();
|
||||
$this->actingAs($user);
|
||||
|
||||
$reportTemplate = ReportTemplate::factory()->create();
|
||||
|
||||
$reportTemplate->delete();
|
||||
|
||||
$this->assertDatabaseHas('action_logs', [
|
||||
'created_by' => $user->id,
|
||||
'action_type' => 'delete',
|
||||
'target_id' => null,
|
||||
'target_type' => null,
|
||||
'item_type' => ReportTemplate::class,
|
||||
'item_id' => $reportTemplate->id,
|
||||
]);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user