Merge remote-tracking branch 'origin/develop'
Some checks failed
CodeQL Security Scan / CodeQL Security Scan (javascript) (push) Has been cancelled
Codacy Security Scan / Codacy Security Scan (push) Has been cancelled
Docker images (Alpine) / docker (push) Has been cancelled
Docker images / docker (push) Has been cancelled
Tests in MySQL / PHP ${{ matrix.php-version }} (8.1) (push) Has been cancelled
Tests in MySQL / PHP ${{ matrix.php-version }} (8.2) (push) Has been cancelled
Tests in MySQL / PHP ${{ matrix.php-version }} (8.3) (push) Has been cancelled
Tests in SQLite / PHP ${{ matrix.php-version }} (8.1.1) (push) Has been cancelled

This commit is contained in:
snipe 2024-10-31 21:06:59 +00:00
commit 95dba6c426
18 changed files with 331 additions and 124 deletions

View file

@ -16,6 +16,7 @@ use Illuminate\Support\Facades\Crypt;
use Illuminate\Contracts\Encryption\DecryptException; use Illuminate\Contracts\Encryption\DecryptException;
use Carbon\Carbon; use Carbon\Carbon;
use Illuminate\Support\Facades\Log; use Illuminate\Support\Facades\Log;
use Illuminate\Support\Str;
use Intervention\Image\ImageManagerStatic as Image; use Intervention\Image\ImageManagerStatic as Image;
use Illuminate\Support\Facades\Session; use Illuminate\Support\Facades\Session;
@ -708,6 +709,28 @@ class Helper
return $randomString; return $randomString;
} }
/**
* A method to be used to handle deprecations notifications, currently handling MS Teams. more can be added when needed.
*
*
* @author [Godfrey Martinez]
* @since [v7.0.14]
* @return array
*/
public static function deprecationCheck() : array {
// The check and message that the user is still using the deprecated version
$deprecations = [
'ms_teams_deprecated' => array(
'check' => !Str::contains(Setting::getSettings()->webhook_endpoint, 'workflows'),
'message' => 'The Microsoft Teams webhook URL being used will be deprecated Jan 31st, 2025. <a class="btn btn-primary" href="' . route('settings.slack.index') . '">Change webhook endpoint</a>'),
];
// if item of concern is being used and its being used with the deprecated values return the notification array.
if(Setting::getSettings()->webhook_selected === 'microsoft' && $deprecations['ms_teams_deprecated']['check']) {
return $deprecations;
}
return [];
}
/** /**
* This nasty little method gets the low inventory info for the * This nasty little method gets the low inventory info for the

View file

@ -25,7 +25,7 @@ class StoreNotificationSettings extends FormRequest
{ {
return [ return [
'alert_email' => 'email_array|nullable', 'alert_email' => 'email_array|nullable',
'admin_cc_email' => 'email|nullable', 'admin_cc_email' => 'email_array|nullable',
'alert_threshold' => 'numeric|nullable|gt:0', 'alert_threshold' => 'numeric|nullable|gt:0',
'alert_interval' => 'numeric|nullable|gt:0', 'alert_interval' => 'numeric|nullable|gt:0',
'audit_warning_days' => 'numeric|nullable|gt:0', 'audit_warning_days' => 'numeric|nullable|gt:0',

View file

@ -30,6 +30,7 @@ use Illuminate\Support\Facades\Mail;
use Illuminate\Support\Facades\Notification; use Illuminate\Support\Facades\Notification;
use Exception; use Exception;
use Illuminate\Support\Facades\Log; use Illuminate\Support\Facades\Log;
use Osama\LaravelTeamsNotification\TeamsNotification;
class CheckoutableListener class CheckoutableListener
{ {
@ -73,18 +74,27 @@ class CheckoutableListener
* 2. The item has a EULA * 2. The item has a EULA
* 3. The item should send an email at check-in/check-out * 3. The item should send an email at check-in/check-out
*/ */
if ($notifiable instanceof User && $notifiable->email != '') {
if ($event->checkoutable->requireAcceptance() || $event->checkoutable->getEula() || if ($event->checkoutable->requireAcceptance() || $event->checkoutable->getEula() ||
(method_exists($event->checkoutable, 'checkin_email') && $event->checkoutable->checkin_email())) { (method_exists($event->checkoutable, 'checkin_email') && $event->checkoutable->checkin_email())) {
Mail::to($notifiable)->cc($ccEmails)->send($mailable); if (!empty($notifiable->email)) {
Mail::to($notifiable)->cc($ccEmails)->send($mailable);
} else {
Mail::cc($ccEmails)->send($mailable);
}
Log::info('Sending email, Locale: ' . ($event->checkedOutTo->locale ?? 'default')); Log::info('Sending email, Locale: ' . ($event->checkedOutTo->locale ?? 'default'));
} }
}
// Send Webhook notification // Send Webhook notification
if ($this->shouldSendWebhookNotification()) { if ($this->shouldSendWebhookNotification()) {
Notification::route(Setting::getSettings()->webhook_selected, Setting::getSettings()->webhook_endpoint) if (Setting::getSettings()->webhook_selected === 'microsoft') {
->notify($this->getCheckoutNotification($event, $acceptance)); $message = $this->getCheckoutNotification($event)->toMicrosoftTeams();
$notification = new TeamsNotification(Setting::getSettings()->webhook_endpoint);
$notification->success()->sendMessage($message[0], $message[1]); // Send the message to Microsoft Teams
} else {
Notification::route(Setting::getSettings()->webhook_selected, Setting::getSettings()->webhook_endpoint)
->notify($this->getCheckoutNotification($event, $acceptance));
}
} }
} catch (ClientException $e) { } catch (ClientException $e) {
Log::debug("Exception caught during checkout notification: " . $e->getMessage()); Log::debug("Exception caught during checkout notification: " . $e->getMessage());
@ -142,13 +152,16 @@ class CheckoutableListener
* 3. The item should send an email at check-in/check-out * 3. The item should send an email at check-in/check-out
*/ */
if ($notifiable instanceof User && $notifiable->email != '') {
if ($event->checkoutable->requireAcceptance() || $event->checkoutable->getEula() || if ($event->checkoutable->requireAcceptance() || $event->checkoutable->getEula() ||
(method_exists($event->checkoutable, 'checkin_email') && $event->checkoutable->checkin_email())) { (method_exists($event->checkoutable, 'checkin_email') && $event->checkoutable->checkin_email())) {
Mail::to($notifiable)->cc($ccEmails)->send($mailable); if (!empty($notifiable->email)) {
Mail::to($notifiable)->cc($ccEmails)->send($mailable);
} else {
Mail::cc($ccEmails)->send($mailable);
}
Log::info('Sending email, Locale: ' . $event->checkedOutTo->locale); Log::info('Sending email, Locale: ' . $event->checkedOutTo->locale);
} }
}
// Send Webhook notification // Send Webhook notification
if ($this->shouldSendWebhookNotification()) { if ($this->shouldSendWebhookNotification()) {
Notification::route(Setting::getSettings()->webhook_selected, Setting::getSettings()->webhook_endpoint) Notification::route(Setting::getSettings()->webhook_selected, Setting::getSettings()->webhook_endpoint)

View file

@ -4,10 +4,11 @@ namespace App\Livewire;
use GuzzleHttp\Client; use GuzzleHttp\Client;
use Illuminate\Support\Facades\Http; use Illuminate\Support\Facades\Http;
use Illuminate\Support\Str;
use Livewire\Component; use Livewire\Component;
use App\Models\Setting; use App\Models\Setting;
use App\Helpers\Helper; use App\Helpers\Helper;
use Osama\LaravelTeamsNotification\TeamsNotification;
class SlackSettingsForm extends Component class SlackSettingsForm extends Component
{ {
public $webhook_endpoint; public $webhook_endpoint;
@ -19,6 +20,7 @@ class SlackSettingsForm extends Component
public $webhook_placeholder; public $webhook_placeholder;
public $webhook_icon; public $webhook_icon;
public $webhook_selected; public $webhook_selected;
public $teams_webhook_deprecated;
public array $webhook_text; public array $webhook_text;
public Setting $setting; public Setting $setting;
@ -62,7 +64,7 @@ class SlackSettingsForm extends Component
"name" => trans('admin/settings/general.ms_teams'), "name" => trans('admin/settings/general.ms_teams'),
"icon" => "fa-brands fa-microsoft", "icon" => "fa-brands fa-microsoft",
"placeholder" => "https://abcd.webhook.office.com/webhookb2/XXXXXXX", "placeholder" => "https://abcd.webhook.office.com/webhookb2/XXXXXXX",
"link" => "https://learn.microsoft.com/en-us/microsoftteams/platform/webhooks-and-connectors/how-to/add-incoming-webhook?tabs=dotnet#create-incoming-webhooks-1", "link" => "https://support.microsoft.com/en-us/office/create-incoming-webhooks-with-workflows-for-microsoft-teams-8ae491c7-0394-4861-ba59-055e33f75498",
"test" => "msTeamTestWebhook" "test" => "msTeamTestWebhook"
), ),
]; ];
@ -79,15 +81,17 @@ class SlackSettingsForm extends Component
$this->webhook_channel = $this->setting->webhook_channel; $this->webhook_channel = $this->setting->webhook_channel;
$this->webhook_botname = $this->setting->webhook_botname; $this->webhook_botname = $this->setting->webhook_botname;
$this->webhook_options = $this->setting->webhook_selected; $this->webhook_options = $this->setting->webhook_selected;
if($this->webhook_selected == 'microsoft' || $this->webhook_selected == 'google'){ $this->teams_webhook_deprecated = !Str::contains($this->webhook_endpoint, 'workflows');
if($this->webhook_selected === 'microsoft' || $this->webhook_selected === 'google'){
$this->webhook_channel = '#NA'; $this->webhook_channel = '#NA';
} }
if($this->setting->webhook_endpoint != null && $this->setting->webhook_channel != null){ if($this->setting->webhook_endpoint != null && $this->setting->webhook_channel != null){
$this->isDisabled= ''; $this->isDisabled= '';
} }
if($this->webhook_selected === 'microsoft' && $this->teams_webhook_deprecated) {
session()->flash('warning', 'The selected Microsoft Teams webhook URL will be deprecated Jan 31st, 2025. Please use a workflow URL. Microsofts Documentation on creating a workflow can be found <a href="https://support.microsoft.com/en-us/office/create-incoming-webhooks-with-workflows-for-microsoft-teams-8ae491c7-0394-4861-ba59-055e33f75498" target="_blank"> here.</a>');
}
} }
public function updated($field) { public function updated($field) {
@ -109,7 +113,6 @@ class SlackSettingsForm extends Component
if($this->webhook_selected == 'microsoft' || $this->webhook_selected == 'google'){ if($this->webhook_selected == 'microsoft' || $this->webhook_selected == 'google'){
$this->webhook_channel = '#NA'; $this->webhook_channel = '#NA';
} }
} }
private function isButtonDisabled() { private function isButtonDisabled() {
@ -126,7 +129,9 @@ class SlackSettingsForm extends Component
public function render() public function render()
{ {
$this->isButtonDisabled(); $this->isButtonDisabled();
return view('livewire.slack-settings-form'); return view('livewire.slack-settings-form');
} }
public function testWebhook(){ public function testWebhook(){
@ -236,20 +241,32 @@ class SlackSettingsForm extends Component
} }
public function msTeamTestWebhook(){ public function msTeamTestWebhook(){
$payload = try {
[
"@type" => "MessageCard",
"@context" => "http://schema.org/extensions",
"summary" => trans('mail.snipe_webhook_summary'),
"title" => trans('mail.snipe_webhook_test'),
"text" => trans('general.webhook_test_msg', ['app' => $this->webhook_name]),
];
try { if($this->teams_webhook_deprecated){
$response = Http::withHeaders([ //will use the deprecated webhook format
'content-type' => 'applications/json', $payload =
])->post($this->webhook_endpoint, [
$payload)->throw(); "@type" => "MessageCard",
"@context" => "http://schema.org/extensions",
"summary" => trans('mail.snipe_webhook_summary'),
"title" => trans('mail.snipe_webhook_test'),
"text" => trans('general.webhook_test_msg', ['app' => $this->webhook_name]),
];
$response = Http::withHeaders([
'content-type' => 'applications/json',
])->post($this->webhook_endpoint,
$payload)->throw();
}
else {
$notification = new TeamsNotification($this->webhook_endpoint);
$message = trans('general.webhook_test_msg', ['app' => $this->webhook_name]);
$notification->success()->sendMessage($message);
$response = Http::withHeaders([
'content-type' => 'applications/json',
])->post($this->webhook_endpoint);
}
if(($response->getStatusCode() == 302)||($response->getStatusCode() == 301)){ if(($response->getStatusCode() == 302)||($response->getStatusCode() == 301)){
return session()->flash('error' , trans('admin/settings/message.webhook.error_redirect', ['endpoint' => $this->webhook_endpoint])); return session()->flash('error' , trans('admin/settings/message.webhook.error_redirect', ['endpoint' => $this->webhook_endpoint]));

View file

@ -184,7 +184,7 @@ class License extends Depreciable
$logAction->item_type = self::class; $logAction->item_type = self::class;
$logAction->item_id = $license->id; $logAction->item_id = $license->id;
$logAction->created_by = auth()->id() ?: 1; // We don't have an id while running the importer from CLI. $logAction->created_by = auth()->id() ?: 1; // We don't have an id while running the importer from CLI.
$logAction->note = "deleted ${change} seats"; $logAction->note = "deleted {$change} seats";
$logAction->target_id = null; $logAction->target_id = null;
$logAction->logaction('delete seats'); $logAction->logaction('delete seats');
@ -216,7 +216,7 @@ class License extends Depreciable
$logAction->item_type = self::class; $logAction->item_type = self::class;
$logAction->item_id = $license->id; $logAction->item_id = $license->id;
$logAction->created_by = auth()->id() ?: 1; // Importer. $logAction->created_by = auth()->id() ?: 1; // Importer.
$logAction->note = "added ${change} seats"; $logAction->note = "added {$change} seats";
$logAction->target_id = null; $logAction->target_id = null;
$logAction->logaction('add seats'); $logAction->logaction('add seats');
} }
@ -743,4 +743,4 @@ class License extends Depreciable
{ {
return $query->leftJoin('users as admin_sort', 'licenses.created_by', '=', 'admin_sort.id')->select('licenses.*')->orderBy('admin_sort.first_name', $order)->orderBy('admin_sort.last_name', $order); return $query->leftJoin('users as admin_sort', 'licenses.created_by', '=', 'admin_sort.id')->select('licenses.*')->orderBy('admin_sort.first_name', $order)->orderBy('admin_sort.last_name', $order);
} }
} }

View file

@ -10,6 +10,7 @@ use Illuminate\Notifications\Channels\SlackWebhookChannel;
use Illuminate\Notifications\Messages\MailMessage; use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Messages\SlackMessage; use Illuminate\Notifications\Messages\SlackMessage;
use Illuminate\Notifications\Notification; use Illuminate\Notifications\Notification;
use Illuminate\Support\Str;
use NotificationChannels\GoogleChat\Card; use NotificationChannels\GoogleChat\Card;
use NotificationChannels\GoogleChat\GoogleChatChannel; use NotificationChannels\GoogleChat\GoogleChatChannel;
use NotificationChannels\GoogleChat\GoogleChatMessage; use NotificationChannels\GoogleChat\GoogleChatMessage;
@ -91,18 +92,29 @@ class CheckinAccessoryNotification extends Notification
$admin = $this->admin; $admin = $this->admin;
$item = $this->item; $item = $this->item;
$note = $this->note; $note = $this->note;
if(!Str::contains(Setting::getSettings()->webhook_endpoint, 'workflows')) {
return MicrosoftTeamsMessage::create()
->to($this->settings->webhook_endpoint)
->type('success')
->addStartGroupToSection('activityTitle')
->title(trans('Accessory_Checkin_Notification'))
->addStartGroupToSection('activityText')
->fact(htmlspecialchars_decode($item->present()->name), '', 'activityTitle')
->fact(trans('mail.checked_into'), $item->location->name ? $item->location->name : '')
->fact(trans('mail.Accessory_Checkin_Notification')." by ", $admin->present()->fullName())
->fact(trans('admin/consumables/general.remaining'), $item->numRemaining())
->fact(trans('mail.notes'), $note ?: '');
}
return MicrosoftTeamsMessage::create() $message = trans('mail.Accessory_Checkin_Notification');
->to($this->settings->webhook_endpoint) $details = [
->type('success') trans('mail.accessory_name') => htmlspecialchars_decode($item->present()->name),
->addStartGroupToSection('activityTitle') trans('mail.checked_into') => $item->location->name ? $item->location->name : '',
->title(trans('Accessory_Checkin_Notification')) trans('mail.Accessory_Checkin_Notification'). ' by' => $admin->present()->fullName(),
->addStartGroupToSection('activityText') trans('admin/consumables/general.remaining')=> $item->numRemaining(),
->fact(htmlspecialchars_decode($item->present()->name), '', 'activityTitle') trans('mail.notes') => $note ?: '',
->fact(trans('mail.checked_into'), $item->location->name ? $item->location->name : '') ];
->fact(trans('mail.Accessory_Checkin_Notification')." by ", $admin->present()->fullName()) return array($message, $details);
->fact(trans('admin/consumables/general.remaining'), $item->numRemaining())
->fact(trans('mail.notes'), $note ?: '');
} }
public function toGoogleChat() public function toGoogleChat()
{ {

View file

@ -10,6 +10,7 @@ use Illuminate\Bus\Queueable;
use Illuminate\Notifications\Messages\MailMessage; use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Messages\SlackMessage; use Illuminate\Notifications\Messages\SlackMessage;
use Illuminate\Notifications\Notification; use Illuminate\Notifications\Notification;
use Illuminate\Support\Str;
use NotificationChannels\GoogleChat\Card; use NotificationChannels\GoogleChat\Card;
use NotificationChannels\GoogleChat\GoogleChatChannel; use NotificationChannels\GoogleChat\GoogleChatChannel;
use NotificationChannels\GoogleChat\GoogleChatMessage; use NotificationChannels\GoogleChat\GoogleChatMessage;
@ -97,16 +98,30 @@ class CheckinAssetNotification extends Notification
$item = $this->item; $item = $this->item;
$note = $this->note; $note = $this->note;
return MicrosoftTeamsMessage::create() if(!Str::contains(Setting::getSettings()->webhook_endpoint, 'workflows')) {
->to($this->settings->webhook_endpoint) return MicrosoftTeamsMessage::create()
->type('success') ->to($this->settings->webhook_endpoint)
->title(trans('mail.Asset_Checkin_Notification')) ->type('success')
->addStartGroupToSection('activityText') ->title(trans('mail.Asset_Checkin_Notification'))
->fact(htmlspecialchars_decode($item->present()->name), '', 'activityText') ->addStartGroupToSection('activityText')
->fact(trans('mail.checked_into'), $item->location->name ? $item->location->name : '') ->fact(htmlspecialchars_decode($item->present()->name), '', 'activityText')
->fact(trans('mail.Asset_Checkin_Notification')." by ", $admin->present()->fullName()) ->fact(trans('mail.checked_into'), $item->location->name ? $item->location->name : '')
->fact(trans('admin/hardware/form.status'), $item->assetstatus->name) ->fact(trans('mail.Asset_Checkin_Notification') . " by ", $admin->present()->fullName())
->fact(trans('mail.notes'), $note ?: ''); ->fact(trans('admin/hardware/form.status'), $item->assetstatus->name)
->fact(trans('mail.notes'), $note ?: '');
}
$message = trans('mail.Asset_Checkin_Notification');
$details = [
trans('mail.asset') => htmlspecialchars_decode($item->present()->name),
trans('mail.checked_into') => $item->location->name ? $item->location->name : '',
trans('mail.Asset_Checkin_Notification')." by " => $admin->present()->fullName(),
trans('admin/hardware/form.status') => $item->assetstatus->name,
trans('mail.notes') => $note ?: '',
];
return array($message, $details);
} }
public function toGoogleChat() public function toGoogleChat()
{ {

View file

@ -10,6 +10,7 @@ use Illuminate\Notifications\Channels\SlackWebhookChannel;
use Illuminate\Notifications\Messages\MailMessage; use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Messages\SlackMessage; use Illuminate\Notifications\Messages\SlackMessage;
use Illuminate\Notifications\Notification; use Illuminate\Notifications\Notification;
use Illuminate\Support\Str;
use NotificationChannels\GoogleChat\Card; use NotificationChannels\GoogleChat\Card;
use NotificationChannels\GoogleChat\GoogleChatChannel; use NotificationChannels\GoogleChat\GoogleChatChannel;
use NotificationChannels\GoogleChat\GoogleChatMessage; use NotificationChannels\GoogleChat\GoogleChatMessage;
@ -102,18 +103,30 @@ class CheckinLicenseSeatNotification extends Notification
$admin = $this->admin; $admin = $this->admin;
$item = $this->item; $item = $this->item;
$note = $this->note; $note = $this->note;
if(!Str::contains(Setting::getSettings()->webhook_endpoint, 'workflows')) {
return MicrosoftTeamsMessage::create()
->to($this->settings->webhook_endpoint)
->type('success')
->addStartGroupToSection('activityTitle')
->title(trans('mail.License_Checkin_Notification'))
->addStartGroupToSection('activityText')
->fact(htmlspecialchars_decode($item->present()->name), '', 'header')
->fact(trans('mail.License_Checkin_Notification')." by ", $admin->present()->fullName() ?: 'CLI tool')
->fact(trans('mail.checkedin_from'), $target->present()->fullName())
->fact(trans('admin/consumables/general.remaining'), $item->availCount()->count())
->fact(trans('mail.notes'), $note ?: '');
}
return MicrosoftTeamsMessage::create() $message = trans('mail.License_Checkin_Notification');
->to($this->settings->webhook_endpoint) $details = [
->type('success') trans('mail.checkedin_from')=> $target->present()->fullName(),
->addStartGroupToSection('activityTitle') trans('mail.license_for') => htmlspecialchars_decode($item->present()->name),
->title(trans('mail.License_Checkin_Notification')) trans('mail.License_Checkin_Notification')." by " => $admin->present()->fullName() ?: 'CLI tool',
->addStartGroupToSection('activityText') trans('admin/consumables/general.remaining') => $item->availCount()->count(),
->fact(htmlspecialchars_decode($item->present()->name), '', 'header') trans('mail.notes') => $note ?: '',
->fact(trans('mail.License_Checkin_Notification')." by ", $admin->present()->fullName() ?: 'CLI tool') ];
->fact(trans('mail.checkedin_from'), $target->present()->fullName())
->fact(trans('admin/consumables/general.remaining'), $item->availCount()->count()) return array($message, $details);
->fact(trans('mail.notes'), $note ?: '');
} }
public function toGoogleChat() public function toGoogleChat()
{ {

View file

@ -9,6 +9,7 @@ use Illuminate\Bus\Queueable;
use Illuminate\Notifications\Messages\MailMessage; use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Messages\SlackMessage; use Illuminate\Notifications\Messages\SlackMessage;
use Illuminate\Notifications\Notification; use Illuminate\Notifications\Notification;
use Illuminate\Support\Str;
use NotificationChannels\GoogleChat\Card; use NotificationChannels\GoogleChat\Card;
use NotificationChannels\GoogleChat\GoogleChatChannel; use NotificationChannels\GoogleChat\GoogleChatChannel;
use NotificationChannels\GoogleChat\GoogleChatMessage; use NotificationChannels\GoogleChat\GoogleChatMessage;
@ -120,6 +121,7 @@ class CheckoutAccessoryNotification extends Notification
$item = $this->item; $item = $this->item;
$note = $this->note; $note = $this->note;
if(!Str::contains(Setting::getSettings()->webhook_endpoint, 'workflows')) {
return MicrosoftTeamsMessage::create() return MicrosoftTeamsMessage::create()
->to($this->settings->webhook_endpoint) ->to($this->settings->webhook_endpoint)
->type('success') ->type('success')
@ -133,7 +135,19 @@ class CheckoutAccessoryNotification extends Notification
->fact(trans('mail.Accessory_Checkout_Notification') . " by ", $admin->present()->fullName()) ->fact(trans('mail.Accessory_Checkout_Notification') . " by ", $admin->present()->fullName())
->fact(trans('admin/consumables/general.remaining'), $item->numRemaining()) ->fact(trans('admin/consumables/general.remaining'), $item->numRemaining())
->fact(trans('mail.notes'), $note ?: ''); ->fact(trans('mail.notes'), $note ?: '');
}
$message = trans('mail.Accessory_Checkout_Notification');
$details = [
trans('mail.assigned_to') => $target->present()->name,
trans('mail.accessory_name') => htmlspecialchars_decode($item->present()->name),
trans('general.qty') => $this->checkout_qty,
trans('mail.checkedout_from') => $item->location->name ? $item->location->name : '',
trans('mail.Accessory_Checkout_Notification'). ' by' => $admin->present()->fullName(),
trans('admin/consumables/general.remaining')=> $item->numRemaining(),
trans('mail.notes') => $note ?: '',
];
return array($message, $details);
} }
public function toGoogleChat() public function toGoogleChat()
{ {

View file

@ -11,6 +11,7 @@ use Illuminate\Bus\Queueable;
use Illuminate\Notifications\Channels\SlackWebhookChannel; use Illuminate\Notifications\Channels\SlackWebhookChannel;
use Illuminate\Notifications\Messages\SlackMessage; use Illuminate\Notifications\Messages\SlackMessage;
use Illuminate\Notifications\Notification; use Illuminate\Notifications\Notification;
use Illuminate\Support\Str;
use NotificationChannels\GoogleChat\Card; use NotificationChannels\GoogleChat\Card;
use NotificationChannels\GoogleChat\Enums\Icon; use NotificationChannels\GoogleChat\Enums\Icon;
use NotificationChannels\GoogleChat\Enums\ImageStyle; use NotificationChannels\GoogleChat\Enums\ImageStyle;
@ -21,6 +22,9 @@ use NotificationChannels\GoogleChat\Widgets\KeyValue;
use NotificationChannels\MicrosoftTeams\MicrosoftTeamsChannel; use NotificationChannels\MicrosoftTeams\MicrosoftTeamsChannel;
use NotificationChannels\MicrosoftTeams\MicrosoftTeamsMessage; use NotificationChannels\MicrosoftTeams\MicrosoftTeamsMessage;
use Illuminate\Support\Facades\Log; use Illuminate\Support\Facades\Log;
use Osama\LaravelTeamsNotification\Logging\TeamsLoggingChannel;
use Osama\LaravelTeamsNotification\TeamsNotification;
class CheckoutAssetNotification extends Notification class CheckoutAssetNotification extends Notification
{ {
use Queueable; use Queueable;
@ -66,7 +70,7 @@ class CheckoutAssetNotification extends Notification
if (Setting::getSettings()->webhook_selected === 'microsoft' && Setting::getSettings()->webhook_endpoint) { if (Setting::getSettings()->webhook_selected === 'microsoft' && Setting::getSettings()->webhook_endpoint) {
$notifyBy[] = MicrosoftTeamsChannel::class; $notifyBy[] = TeamsNotification::class;
} }
@ -107,24 +111,33 @@ class CheckoutAssetNotification extends Notification
->content($note); ->content($note);
}); });
} }
public function toMicrosoftTeams() public function toMicrosoftTeams() : array
{ {
$target = $this->target; $target = $this->target;
$admin = $this->admin; $admin = $this->admin;
$item = $this->item; $item = $this->item;
$note = $this->note; $note = $this->note;
return MicrosoftTeamsMessage::create() if(!Str::contains(Setting::getSettings()->webhook_endpoint, 'workflows')) {
->to($this->settings->webhook_endpoint) return MicrosoftTeamsMessage::create()
->type('success') ->to($this->settings->webhook_endpoint)
->title(trans('mail.Asset_Checkout_Notification')) ->type('success')
->addStartGroupToSection('activityText') ->title(trans('mail.Asset_Checkout_Notification'))
->fact(trans('mail.assigned_to'), $target->present()->name) ->addStartGroupToSection('activityText')
->fact(htmlspecialchars_decode($item->present()->name), '', 'activityText') ->fact(trans('mail.assigned_to'), $target->present()->name)
->fact(trans('mail.Asset_Checkout_Notification') . " by ", $admin->present()->fullName()) ->fact(htmlspecialchars_decode($item->present()->name), '', 'activityText')
->fact(trans('mail.notes'), $note ?: ''); ->fact(trans('mail.Asset_Checkout_Notification') . " by ", $admin->present()->fullName())
->fact(trans('mail.notes'), $note ?: '');
}
$message = trans('mail.Asset_Checkout_Notification');
$details = [
trans('mail.assigned_to') => $target->present()->name,
trans('mail.asset') => htmlspecialchars_decode($item->present()->name),
trans('mail.Asset_Checkout_Notification'). ' by' => $admin->present()->fullName(),
trans('mail.notes') => $note ?: '',
];
return array($message, $details);
} }
public function toGoogleChat() public function toGoogleChat()
{ {

View file

@ -10,6 +10,7 @@ use Illuminate\Notifications\Channels\SlackWebhookChannel;
use Illuminate\Notifications\Messages\MailMessage; use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Messages\SlackMessage; use Illuminate\Notifications\Messages\SlackMessage;
use Illuminate\Notifications\Notification; use Illuminate\Notifications\Notification;
use Illuminate\Support\Str;
use NotificationChannels\GoogleChat\Card; use NotificationChannels\GoogleChat\Card;
use NotificationChannels\GoogleChat\GoogleChatChannel; use NotificationChannels\GoogleChat\GoogleChatChannel;
use NotificationChannels\GoogleChat\GoogleChatMessage; use NotificationChannels\GoogleChat\GoogleChatMessage;
@ -100,17 +101,30 @@ class CheckoutConsumableNotification extends Notification
$item = $this->item; $item = $this->item;
$note = $this->note; $note = $this->note;
return MicrosoftTeamsMessage::create() if(!Str::contains(Setting::getSettings()->webhook_endpoint, 'workflows')) {
->to($this->settings->webhook_endpoint) return MicrosoftTeamsMessage::create()
->type('success') ->to($this->settings->webhook_endpoint)
->addStartGroupToSection('activityTitle') ->type('success')
->title(trans('mail.Consumable_checkout_notification')) ->addStartGroupToSection('activityTitle')
->addStartGroupToSection('activityText') ->title(trans('mail.Consumable_checkout_notification'))
->fact(htmlspecialchars_decode($item->present()->name), '', 'activityTitle') ->addStartGroupToSection('activityText')
->fact(trans('mail.Consumable_checkout_notification')." by ", $admin->present()->fullName()) ->fact(htmlspecialchars_decode($item->present()->name), '', 'activityTitle')
->fact(trans('mail.assigned_to'), $target->present()->fullName()) ->fact(trans('mail.Consumable_checkout_notification')." by ", $admin->present()->fullName())
->fact(trans('admin/consumables/general.remaining'), $item->numRemaining()) ->fact(trans('mail.assigned_to'), $target->present()->fullName())
->fact(trans('mail.notes'), $note ?: ''); ->fact(trans('admin/consumables/general.remaining'), $item->numRemaining())
->fact(trans('mail.notes'), $note ?: '');
}
$message = trans('mail.Consumable_checkout_notification');
$details = [
trans('mail.assigned_to') => $target->present()->fullName(),
trans('mail.item') => htmlspecialchars_decode($item->present()->name),
trans('mail.Consumable_checkout_notification').' by' => $admin->present()->fullName(),
trans('admin/consumables/general.remaining') => $item->numRemaining(),
trans('mail.notes') => $note ?: '',
];
return array($message, $details);
} }
public function toGoogleChat() public function toGoogleChat()
{ {

View file

@ -10,6 +10,7 @@ use Illuminate\Notifications\Channels\SlackWebhookChannel;
use Illuminate\Notifications\Messages\MailMessage; use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Messages\SlackMessage; use Illuminate\Notifications\Messages\SlackMessage;
use Illuminate\Notifications\Notification; use Illuminate\Notifications\Notification;
use Illuminate\Support\Str;
use NotificationChannels\GoogleChat\Card; use NotificationChannels\GoogleChat\Card;
use NotificationChannels\GoogleChat\GoogleChatChannel; use NotificationChannels\GoogleChat\GoogleChatChannel;
use NotificationChannels\GoogleChat\GoogleChatMessage; use NotificationChannels\GoogleChat\GoogleChatMessage;
@ -98,17 +99,29 @@ class CheckoutLicenseSeatNotification extends Notification
$item = $this->item; $item = $this->item;
$note = $this->note; $note = $this->note;
return MicrosoftTeamsMessage::create() if(!Str::contains(Setting::getSettings()->webhook_endpoint, 'workflows')) {
->to($this->settings->webhook_endpoint) return MicrosoftTeamsMessage::create()
->type('success') ->to($this->settings->webhook_endpoint)
->addStartGroupToSection('activityTitle') ->type('success')
->title(trans('mail.License_Checkout_Notification')) ->addStartGroupToSection('activityTitle')
->addStartGroupToSection('activityText') ->title(trans('mail.License_Checkout_Notification'))
->fact(htmlspecialchars_decode($item->present()->name), '', 'activityTitle') ->addStartGroupToSection('activityText')
->fact(trans('mail.License_Checkout_Notification')." by ", $admin->present()->fullName()) ->fact(htmlspecialchars_decode($item->present()->name), '', 'activityTitle')
->fact(trans('mail.assigned_to'), $target->present()->fullName()) ->fact(trans('mail.License_Checkout_Notification')." by ", $admin->present()->fullName())
->fact(trans('admin/consumables/general.remaining'), $item->availCount()->count()) ->fact(trans('mail.assigned_to'), $target->present()->fullName())
->fact(trans('mail.notes'), $note ?: ''); ->fact(trans('admin/consumables/general.remaining'), $item->availCount()->count())
->fact(trans('mail.notes'), $note ?: '');
}
$message = trans('mail.License_Checkout_Notification');
$details = [
trans('mail.assigned_to') => $target->present()->fullName(),
trans('mail.license_for') => htmlspecialchars_decode($item->present()->name),
trans('mail.License_Checkout_Notification').' by' => $admin->present()->fullName(),
trans('admin/consumables/general.remaining') => $item->availCount()->count(),
trans('mail.notes') => $note ?: '',
];
return array($message, $details);
} }
public function toGoogleChat() public function toGoogleChat()
{ {

View file

@ -38,7 +38,7 @@
"intervention/image": "^2.5", "intervention/image": "^2.5",
"javiereguiluz/easyslugger": "^1.0", "javiereguiluz/easyslugger": "^1.0",
"laravel-notification-channels/google-chat": "^3.0", "laravel-notification-channels/google-chat": "^3.0",
"laravel-notification-channels/microsoft-teams": "^1.1", "laravel-notification-channels/microsoft-teams": "^1.2",
"laravel/framework": "^10.0", "laravel/framework": "^10.0",
"laravel/helpers": "^1.4", "laravel/helpers": "^1.4",
"laravel/passport": "^11.0", "laravel/passport": "^11.0",
@ -55,6 +55,7 @@
"nunomaduro/collision": "^7.0", "nunomaduro/collision": "^7.0",
"okvpn/clock-lts": "^1.0", "okvpn/clock-lts": "^1.0",
"onelogin/php-saml": "^3.4", "onelogin/php-saml": "^3.4",
"osa-eg/laravel-teams-notification": "^2.1",
"paragonie/constant_time_encoding": "^2.3", "paragonie/constant_time_encoding": "^2.3",
"paragonie/sodium_compat": "^1.19", "paragonie/sodium_compat": "^1.19",
"phpdocumentor/reflection-docblock": "^5.1", "phpdocumentor/reflection-docblock": "^5.1",

67
composer.lock generated
View file

@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically" "This file is @generated automatically"
], ],
"content-hash": "5341bc5be02b3c33e28e46e06dd99f29", "content-hash": "0750e3a427347b2a56a05a8b9b533d48",
"packages": [ "packages": [
{ {
"name": "alek13/slack", "name": "alek13/slack",
@ -5572,6 +5572,71 @@
], ],
"time": "2024-05-30T15:14:26+00:00" "time": "2024-05-30T15:14:26+00:00"
}, },
{
"name": "osa-eg/laravel-teams-notification",
"version": "v2.1.2",
"source": {
"type": "git",
"url": "https://github.com/osa-eg/laravel-teams-notification.git",
"reference": "76173689930aca92b5174a3b102e705279192c0f"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/osa-eg/laravel-teams-notification/zipball/76173689930aca92b5174a3b102e705279192c0f",
"reference": "76173689930aca92b5174a3b102e705279192c0f",
"shasum": ""
},
"require": {
"guzzlehttp/guzzle": ">=6.5",
"illuminate/support": "^5.5 || ^6.0 || ^7.0 || ^8.0 || ^9.0 || ^10.0 || ^11.0",
"monolog/monolog": ">=1.0",
"php": ">=7.0"
},
"require-dev": {
"phpunit/phpunit": "^8.5"
},
"type": "library",
"extra": {
"laravel": {
"providers": [
"Osama\\LaravelTeamsNotification\\LaravelTeamsNotificationServiceProvider"
]
}
},
"autoload": {
"psr-4": {
"Osama\\LaravelTeamsNotification\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Osama Saad",
"email": "osaad96eg@gmail.com"
}
],
"description": "A Laravel package to send notifications to Microsoft Teams",
"keywords": [
"Teams",
"adaptive-card",
"laravel",
"logging",
"microsoft-teams-workflow",
"notification",
"teams-connector",
"teams-webhock",
"teams-workflow",
"teams_logging"
],
"support": {
"issues": "https://github.com/osa-eg/laravel-teams-notification/issues",
"source": "https://github.com/osa-eg/laravel-teams-notification/tree/v2.1.2"
},
"time": "2024-09-23T05:24:48+00:00"
},
{ {
"name": "paragonie/constant_time_encoding", "name": "paragonie/constant_time_encoding",
"version": "v2.7.0", "version": "v2.7.0",

View file

@ -23,6 +23,7 @@ return [
'Item_Requested' => 'Item Requested', 'Item_Requested' => 'Item Requested',
'License_Checkin_Notification' => 'License checked in', 'License_Checkin_Notification' => 'License checked in',
'License_Checkout_Notification' => 'License checked out', 'License_Checkout_Notification' => 'License checked out',
'license_for' => 'License for',
'Low_Inventory_Report' => 'Low Inventory Report', 'Low_Inventory_Report' => 'Low Inventory Report',
'a_user_canceled' => 'A user has canceled an item request on the website', 'a_user_canceled' => 'A user has canceled an item request on the website',
'a_user_requested' => 'A user has requested an item on the website', 'a_user_requested' => 'A user has requested an item on the website',

View file

@ -268,17 +268,24 @@ dir="{{ Helper::determineLanguageDirection() }}">
@can('admin') @can('admin')
@if ($snipeSettings->show_alerts_in_menu=='1') @if ($snipeSettings->show_alerts_in_menu=='1')
<!-- Tasks: style can be found in dropdown.less --> <!-- Tasks: style can be found in dropdown.less -->
<?php $alert_items = Helper::checkLowInventory(); ?> <?php $alert_items = Helper::checkLowInventory(); $deprecations = Helper::deprecationCheck()?>
<li class="dropdown tasks-menu"> <li class="dropdown tasks-menu">
<a href="#" class="dropdown-toggle" data-toggle="dropdown"> <a href="#" class="dropdown-toggle" data-toggle="dropdown">
<x-icon type="alerts" /> <x-icon type="alerts" />
<span class="sr-only">{{ trans('general.alerts') }}</span> <span class="sr-only">{{ trans('general.alerts') }}</span>
@if (count($alert_items)) @if (count($alert_items) || count($deprecations))
<span class="label label-danger">{{ count($alert_items) }}</span> <span class="label label-danger">{{ count($alert_items) + count($deprecations) }}</span>
@endif @endif
</a> </a>
<ul class="dropdown-menu"> <ul class="dropdown-menu">
@if($deprecations)
@foreach ($deprecations as $key => $deprecation)
@if ($deprecation['check'])
<li class="header alert-warning">{!! $deprecation['message'] !!}</li>
@endif
@endforeach
@endif
<li class="header">{{ trans_choice('general.quantity_minimum', count($alert_items)) }}</li> <li class="header">{{ trans_choice('general.quantity_minimum', count($alert_items)) }}</li>
<li> <li>
<!-- inner menu: contains the actual data --> <!-- inner menu: contains the actual data -->

View file

@ -15,7 +15,14 @@
<div><!-- livewire div - do not remove --> <div><!-- livewire div - do not remove -->
<form class="form-horizontal" role="form" wire:submit="submit"> <form class="form-horizontal" role="form" wire:submit="submit">
{{csrf_field()}} {{csrf_field()}}
@if (session()->has('warning'))
<div class="alert alert-warning">
{!! session('warning') !!}
@php
session()->forget('warning'); // Clear the session flash immediately
@endphp
</div>
@endif
<div class="row"> <div class="row">
<div class="col-sm-10 col-sm-offset-1 col-md-8 col-md-offset-2"> <div class="col-sm-10 col-sm-offset-1 col-md-8 col-md-offset-2">

View file

@ -24,8 +24,6 @@ use App\Http\Controllers\Auth\LoginController;
use App\Http\Controllers\Auth\ForgotPasswordController; use App\Http\Controllers\Auth\ForgotPasswordController;
use App\Http\Controllers\Auth\ResetPasswordController; use App\Http\Controllers\Auth\ResetPasswordController;
use App\Livewire\Importer; use App\Livewire\Importer;
use App\Models\Asset;
use App\Models\User;
use Illuminate\Support\Facades\Route; use Illuminate\Support\Facades\Route;
use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\Auth;
@ -551,22 +549,3 @@ Route::middleware(['auth'])->get(
'/', '/',
[DashboardController::class, 'index'] [DashboardController::class, 'index']
)->name('home'); )->name('home');
Route::get('/test-email', function() {
$item = Asset::find(1); // Load some test data
$admin = User::find(1);
$target = User::find(2);
$acceptance = null; // Simulate acceptance data
$note = 'Test note';
$fields = [];
if (($item->model) && ($item->model->fieldset)) {
$fields = $item->model->fieldset->fields;
}
return new \App\Mail\CheckoutAssetMail(
$item,
$admin,
$target,
$acceptance,
$note);
});