diff --git a/app/Console/Commands/SendExpirationAlerts.php b/app/Console/Commands/SendExpirationAlerts.php index 025ba2ce23..1220e0cd9d 100644 --- a/app/Console/Commands/SendExpirationAlerts.php +++ b/app/Console/Commands/SendExpirationAlerts.php @@ -2,13 +2,13 @@ namespace App\Console\Commands; +use App\Mail\ExpiringAssetsMail; +use App\Mail\ExpiringLicenseMail; use App\Models\Asset; use App\Models\License; -use App\Models\Recipients\AlertRecipient; use App\Models\Setting; -use App\Notifications\ExpiringAssetsNotification; -use App\Notifications\ExpiringLicenseNotification; use Illuminate\Console\Command; +use Illuminate\Support\Facades\Mail; class SendExpirationAlerts extends Command { @@ -47,22 +47,22 @@ class SendExpirationAlerts extends Command if (($settings->alert_email != '') && ($settings->alerts_enabled == 1)) { // Send a rollup to the admin, if settings dictate - $recipients = collect(explode(',', $settings->alert_email))->map(function ($item, $key) { - return new AlertRecipient($item); - }); - + $recipients = collect(explode(',', $settings->alert_email)) + ->map(fn($item) => trim($item)) // Trim each email + ->all(); // Expiring Assets $assets = Asset::getExpiringWarrantee($threshold); + if ($assets->count() > 0) { $this->info(trans_choice('mail.assets_warrantee_alert', $assets->count(), ['count' => $assets->count(), 'threshold' => $threshold])); - \Notification::send($recipients, new ExpiringAssetsNotification($assets, $threshold)); + Mail::to($recipients)->send(new ExpiringAssetsMail($assets, $threshold)); } // Expiring licenses $licenses = License::getExpiringLicenses($threshold); if ($licenses->count() > 0) { $this->info(trans_choice('mail.license_expiring_alert', $licenses->count(), ['count' => $licenses->count(), 'threshold' => $threshold])); - \Notification::send($recipients, new ExpiringLicenseNotification($licenses, $threshold)); + Mail::to($recipients)->send(new ExpiringLicenseMail($licenses, $threshold)); } } else { if ($settings->alert_email == '') { diff --git a/app/Http/Controllers/Accessories/AccessoriesFilesController.php b/app/Http/Controllers/Accessories/AccessoriesFilesController.php index c251166ce2..9dbb16d83a 100644 --- a/app/Http/Controllers/Accessories/AccessoriesFilesController.php +++ b/app/Http/Controllers/Accessories/AccessoriesFilesController.php @@ -55,11 +55,11 @@ class AccessoriesFilesController extends Controller } - return redirect()->route('accessories.show', $accessory->id)->with('error', trans('general.no_files_uploaded')); + return redirect()->route('accessories.show', $accessory->id)->withFragment('files')->with('error', trans('general.no_files_uploaded')); } // Prepare the error message - return redirect()->route('accessories.index') - ->with('error', trans('general.file_does_not_exist')); + return redirect()->route('accessories.index')->with('error', trans('admin/accessories/message.does_not_exist')); + } /** @@ -72,29 +72,27 @@ class AccessoriesFilesController extends Controller */ public function destroy($accessoryId = null, $fileId = null) : RedirectResponse { - $accessory = Accessory::find($accessoryId); - - // the asset is valid - if (isset($accessory->id)) { + if ($accessory = Accessory::find($accessoryId)) { $this->authorize('update', $accessory); - $log = Actionlog::find($fileId); - // Remove the file if one exists - if (Storage::exists('accessories/'.$log->filename)) { - try { - Storage::delete('accessories/'.$log->filename); - } catch (\Exception $e) { - Log::debug($e); + if ($log = Actionlog::find($fileId)) { + + if (Storage::exists('private_uploads/accessories/'.$log->filename)) { + try { + Storage::delete('private_uploads/accessories/' . $log->filename); + $log->delete(); + return redirect()->back()->withFragment('files')->with('success', trans('admin/hardware/message.deletefile.success')); + } catch (\Exception $e) { + Log::debug($e); + return redirect()->route('accessories.index')->with('error', trans('general.file_does_not_exist')); + } } + } - - $log->delete(); - - return redirect()->back()->withFragment('files')->with('success', trans('admin/hardware/message.deletefile.success')); + return redirect()->route('accessories.show', ['accessory' => $accessory])->withFragment('files')->with('error', trans('general.log_record_not_found')); } - // Redirect to the licence management page - return redirect()->route('accessories.index')->with('error', trans('general.file_does_not_exist')); + return redirect()->route('accessories.index')->with('error', trans('admin/accessories/message.does_not_exist')); } /** @@ -124,10 +122,11 @@ class AccessoriesFilesController extends Controller } } - return redirect()->route('accessories.show', ['accessory' => $accessory])->with('error', trans('general.log_record_not_found')); + return redirect()->route('accessories.show', ['accessory' => $accessory])->withFragment('files')->with('error', trans('general.log_record_not_found')); } - return redirect()->route('accessories.index')->with('error', trans('general.file_not_found')); + return redirect()->route('accessories.index')->with('error', trans('admin/accessories/message.does_not_exist')); + } } diff --git a/app/Http/Controllers/Api/AssetsController.php b/app/Http/Controllers/Api/AssetsController.php index da400d216e..cfa7652501 100644 --- a/app/Http/Controllers/Api/AssetsController.php +++ b/app/Http/Controllers/Api/AssetsController.php @@ -765,9 +765,13 @@ class AssetsController extends Controller } if ($problems_updating_encrypted_custom_fields) { - return response()->json(Helper::formatStandardApiResponse('success', (new AssetsTransformer)->transformAsset($asset), trans('admin/hardware/message.update.encrypted_warning'))); + return response()->json(Helper::formatStandardApiResponse('success', $asset, trans('admin/hardware/message.update.encrypted_warning'))); + // Below is the *correct* return since it uses the transformer, but we have to use the old, flat return for now until we can update Jamf2Snipe and Kanji2Snipe + // return response()->json(Helper::formatStandardApiResponse('success', (new AssetsTransformer)->transformAsset($asset), trans('admin/hardware/message.update.encrypted_warning'))); } else { - return response()->json(Helper::formatStandardApiResponse('success', (new AssetsTransformer)->transformAsset($asset), trans('admin/hardware/message.update.success'))); + return response()->json(Helper::formatStandardApiResponse('success', $asset, trans('admin/hardware/message.update.success'))); + // Below is the *correct* return since it uses the transformer, but we have to use the old, flat return for now until we can update Jamf2Snipe and Kanji2Snipe + /// return response()->json(Helper::formatStandardApiResponse('success', (new AssetsTransformer)->transformAsset($asset), trans('admin/hardware/message.update.success'))); } } return response()->json(Helper::formatStandardApiResponse('error', null, $asset->getErrors()), 200); diff --git a/app/Http/Controllers/Api/CategoriesController.php b/app/Http/Controllers/Api/CategoriesController.php index e772bec4df..319b51dd11 100644 --- a/app/Http/Controllers/Api/CategoriesController.php +++ b/app/Http/Controllers/Api/CategoriesController.php @@ -39,6 +39,7 @@ class CategoriesController extends Controller 'components_count', 'licenses_count', 'image', + 'notes', ]; $categories = Category::select([ @@ -52,6 +53,7 @@ class CategoriesController extends Controller 'require_acceptance', 'checkin_email', 'image', + 'notes', ]) ->with('adminuser') ->withCount('accessories as accessories_count', 'consumables as consumables_count', 'components as components_count', 'licenses as licenses_count'); diff --git a/app/Http/Controllers/Api/CompaniesController.php b/app/Http/Controllers/Api/CompaniesController.php index 5ba342db33..2f1f0740b3 100644 --- a/app/Http/Controllers/Api/CompaniesController.php +++ b/app/Http/Controllers/Api/CompaniesController.php @@ -38,6 +38,7 @@ class CompaniesController extends Controller 'accessories_count', 'consumables_count', 'components_count', + 'notes', ]; $companies = Company::withCount(['assets as assets_count' => function ($query) { diff --git a/app/Http/Controllers/Api/DepartmentsController.php b/app/Http/Controllers/Api/DepartmentsController.php index a7b30a10fc..167d5cbc2a 100644 --- a/app/Http/Controllers/Api/DepartmentsController.php +++ b/app/Http/Controllers/Api/DepartmentsController.php @@ -23,7 +23,7 @@ class DepartmentsController extends Controller public function index(Request $request) : JsonResponse | array { $this->authorize('view', Department::class); - $allowed_columns = ['id', 'name', 'image', 'users_count']; + $allowed_columns = ['id', 'name', 'image', 'users_count', 'notes']; $departments = Department::select( 'departments.id', @@ -35,7 +35,8 @@ class DepartmentsController extends Controller 'departments.manager_id', 'departments.created_at', 'departments.updated_at', - 'departments.image' + 'departments.image', + 'departments.notes', )->with('users')->with('location')->with('manager')->with('company')->withCount('users as users_count'); if ($request->filled('search')) { diff --git a/app/Http/Controllers/Api/GroupsController.php b/app/Http/Controllers/Api/GroupsController.php index 81217ce8db..5f2e222c70 100644 --- a/app/Http/Controllers/Api/GroupsController.php +++ b/app/Http/Controllers/Api/GroupsController.php @@ -24,7 +24,7 @@ class GroupsController extends Controller $this->authorize('view', Group::class); - $groups = Group::select('id', 'name', 'permissions', 'created_at', 'updated_at', 'created_by')->with('adminuser')->withCount('users as users_count'); + $groups = Group::select('id', 'name', 'permissions', 'notes', 'created_at', 'updated_at', 'created_by')->with('adminuser')->withCount('users as users_count'); if ($request->filled('search')) { $groups = $groups->TextSearch($request->input('search')); @@ -81,6 +81,7 @@ class GroupsController extends Controller $group->name = $request->input('name'); $group->created_by = auth()->id(); + $group->notes = $request->input('notes'); $group->permissions = json_encode($request->input('permissions', $groupPermissions)); if ($group->save()) { @@ -118,6 +119,7 @@ class GroupsController extends Controller $group = Group::findOrFail($id); $group->name = $request->input('name'); + $group->notes = $request->input('notes'); $group->permissions = $request->input('permissions'); // Todo - some JSON validation stuff here if ($group->save()) { diff --git a/app/Http/Controllers/Api/LocationsController.php b/app/Http/Controllers/Api/LocationsController.php index f4f788d563..53990e9a97 100644 --- a/app/Http/Controllers/Api/LocationsController.php +++ b/app/Http/Controllers/Api/LocationsController.php @@ -53,6 +53,7 @@ class LocationsController extends Controller 'updated_at', 'users_count', 'zip', + 'notes', ]; $locations = Location::with('parent', 'manager', 'children')->select([ @@ -73,6 +74,7 @@ class LocationsController extends Controller 'locations.image', 'locations.ldap_ou', 'locations.currency', + 'locations.notes', ]) ->withCount('assignedAssets as assigned_assets_count') ->withCount('assets as assets_count') @@ -190,6 +192,7 @@ class LocationsController extends Controller 'locations.updated_at', 'locations.image', 'locations.currency', + 'locations.notes', ]) ->withCount('assignedAssets as assigned_assets_count') ->withCount('assets as assets_count') diff --git a/app/Http/Controllers/Api/ManufacturersController.php b/app/Http/Controllers/Api/ManufacturersController.php index f716fbbf7f..652fad1cfc 100644 --- a/app/Http/Controllers/Api/ManufacturersController.php +++ b/app/Http/Controllers/Api/ManufacturersController.php @@ -39,7 +39,8 @@ class ManufacturersController extends Controller 'assets_count', 'consumables_count', 'components_count', - 'licenses_count' + 'licenses_count', + 'notes', ]; $manufacturers = Manufacturer::select([ @@ -55,6 +56,7 @@ class ManufacturersController extends Controller 'updated_at', 'image', 'deleted_at', + 'notes', ]) ->with('adminuser') ->withCount('assets as assets_count') diff --git a/app/Http/Controllers/Assets/AssetsController.php b/app/Http/Controllers/Assets/AssetsController.php index 8f3b1f054b..9cb88cfb93 100755 --- a/app/Http/Controllers/Assets/AssetsController.php +++ b/app/Http/Controllers/Assets/AssetsController.php @@ -535,7 +535,7 @@ class AssetsController extends Controller { $settings = Setting::getSettings(); - if (($settings->qr_code === '1') && ($settings->label2_2d_type !== 'none')) { + if (($settings->qr_code == '1') && ($settings->label2_2d_type !== 'none')) { $asset = Asset::withTrashed()->find($assetId); if ($asset) { $size = Helper::barcodeDimensions($settings->label2_2d_type); diff --git a/app/Http/Controllers/CategoriesController.php b/app/Http/Controllers/CategoriesController.php index 93b3d4a0d0..1b42037f3b 100755 --- a/app/Http/Controllers/CategoriesController.php +++ b/app/Http/Controllers/CategoriesController.php @@ -69,6 +69,7 @@ class CategoriesController extends Controller $category->use_default_eula = $request->input('use_default_eula', '0'); $category->require_acceptance = $request->input('require_acceptance', '0'); $category->checkin_email = $request->input('checkin_email', '0'); + $category->notes = $request->input('notes'); $category->created_by = auth()->id(); $category = $request->handleImages($category); @@ -134,6 +135,7 @@ class CategoriesController extends Controller $category->use_default_eula = $request->input('use_default_eula', '0'); $category->require_acceptance = $request->input('require_acceptance', '0'); $category->checkin_email = $request->input('checkin_email', '0'); + $category->notes = $request->input('notes'); $category = $request->handleImages($category); diff --git a/app/Http/Controllers/CompaniesController.php b/app/Http/Controllers/CompaniesController.php index 238ffc85f5..12655cb2a5 100644 --- a/app/Http/Controllers/CompaniesController.php +++ b/app/Http/Controllers/CompaniesController.php @@ -60,6 +60,7 @@ final class CompaniesController extends Controller $company->phone = $request->input('phone'); $company->fax = $request->input('fax'); $company->email = $request->input('email'); + $company->notes = $request->input('notes'); $company->created_by = auth()->id(); $company = $request->handleImages($company); @@ -111,6 +112,7 @@ final class CompaniesController extends Controller $company->phone = $request->input('phone'); $company->fax = $request->input('fax'); $company->email = $request->input('email'); + $company->notes = $request->input('notes'); $company = $request->handleImages($company); diff --git a/app/Http/Controllers/DepartmentsController.php b/app/Http/Controllers/DepartmentsController.php index 287315ef2c..fe90162c48 100644 --- a/app/Http/Controllers/DepartmentsController.php +++ b/app/Http/Controllers/DepartmentsController.php @@ -55,6 +55,7 @@ class DepartmentsController extends Controller $department->manager_id = ($request->filled('manager_id') ? $request->input('manager_id') : null); $department->location_id = ($request->filled('location_id') ? $request->input('location_id') : null); $department->company_id = ($request->filled('company_id') ? $request->input('company_id') : null); + $department->notes = $request->input('notes'); $department = $request->handleImages($department); if ($department->save()) { @@ -171,7 +172,7 @@ class DepartmentsController extends Controller $department->company_id = ($request->filled('company_id') ? $request->input('company_id') : null); $department->phone = $request->input('phone'); $department->fax = $request->input('fax'); - + $department->notes = $request->input('notes'); $department = $request->handleImages($department); if ($department->save()) { diff --git a/app/Http/Controllers/GroupsController.php b/app/Http/Controllers/GroupsController.php index a85cabf246..6aaf58ebde 100755 --- a/app/Http/Controllers/GroupsController.php +++ b/app/Http/Controllers/GroupsController.php @@ -62,6 +62,7 @@ class GroupsController extends Controller $group->name = $request->input('name'); $group->permissions = json_encode($request->input('permission')); $group->created_by = auth()->id(); + $group->notes = $request->input('notes'); if ($group->save()) { return redirect()->route('groups.index')->with('success', trans('admin/groups/message.success.create')); @@ -108,6 +109,7 @@ class GroupsController extends Controller } $group->name = $request->input('name'); $group->permissions = json_encode($request->input('permission')); + $group->notes = $request->input('notes'); if (! config('app.lock_passwords')) { if ($group->save()) { diff --git a/app/Http/Controllers/LocationsController.php b/app/Http/Controllers/LocationsController.php index 75abce97ed..e250e5cfa5 100755 --- a/app/Http/Controllers/LocationsController.php +++ b/app/Http/Controllers/LocationsController.php @@ -78,6 +78,7 @@ class LocationsController extends Controller $location->created_by = auth()->id(); $location->phone = request('phone'); $location->fax = request('fax'); + $location->notes = $request->input('notes'); $location = $request->handleImages($location); @@ -138,6 +139,7 @@ class LocationsController extends Controller $location->fax = request('fax'); $location->ldap_ou = $request->input('ldap_ou'); $location->manager_id = $request->input('manager_id'); + $location->notes = $request->input('notes'); $location = $request->handleImages($location); diff --git a/app/Http/Controllers/ManufacturersController.php b/app/Http/Controllers/ManufacturersController.php index 68124f644c..eb8c80d877 100755 --- a/app/Http/Controllers/ManufacturersController.php +++ b/app/Http/Controllers/ManufacturersController.php @@ -67,6 +67,7 @@ class ManufacturersController extends Controller $manufacturer->warranty_lookup_url = $request->input('warranty_lookup_url'); $manufacturer->support_phone = $request->input('support_phone'); $manufacturer->support_email = $request->input('support_email'); + $manufacturer->notes = $request->input('notes'); $manufacturer = $request->handleImages($manufacturer); if ($manufacturer->save()) { @@ -123,6 +124,7 @@ class ManufacturersController extends Controller $manufacturer->warranty_lookup_url = $request->input('warranty_lookup_url'); $manufacturer->support_phone = $request->input('support_phone'); $manufacturer->support_email = $request->input('support_email'); + $manufacturer->notes = $request->input('notes'); // Set the model's image property to null if the image is being deleted if ($request->input('image_delete') == 1) { diff --git a/app/Http/Controllers/SettingsController.php b/app/Http/Controllers/SettingsController.php index 1bc120d1c1..0b15f35626 100755 --- a/app/Http/Controllers/SettingsController.php +++ b/app/Http/Controllers/SettingsController.php @@ -869,7 +869,6 @@ class SettingsController extends Controller } if ($setting->save()) { - $setting->update_client_side_cert_files(); return redirect()->route('settings.ldap.index') ->with('success', trans('admin/settings/message.update.success')); } diff --git a/app/Http/Transformers/CategoriesTransformer.php b/app/Http/Transformers/CategoriesTransformer.php index 2dd82b3b70..0d1834649d 100644 --- a/app/Http/Transformers/CategoriesTransformer.php +++ b/app/Http/Transformers/CategoriesTransformer.php @@ -66,6 +66,7 @@ class CategoriesTransformer 'id' => (int) $category->adminuser->id, 'name'=> e($category->adminuser->present()->fullName()), ] : null, + 'notes' => Helper::parseEscapedMarkedownInline($category->notes), 'created_at' => Helper::getFormattedDateObject($category->created_at, 'datetime'), 'updated_at' => Helper::getFormattedDateObject($category->updated_at, 'datetime'), ]; diff --git a/app/Http/Transformers/CompaniesTransformer.php b/app/Http/Transformers/CompaniesTransformer.php index 530df32044..8ca5344de6 100644 --- a/app/Http/Transformers/CompaniesTransformer.php +++ b/app/Http/Transformers/CompaniesTransformer.php @@ -40,6 +40,7 @@ class CompaniesTransformer 'id' => (int) $company->adminuser->id, 'name'=> e($company->adminuser->present()->fullName()), ] : null, + 'notes' => Helper::parseEscapedMarkedownInline($company->notes), 'created_at' => Helper::getFormattedDateObject($company->created_at, 'datetime'), 'updated_at' => Helper::getFormattedDateObject($company->updated_at, 'datetime'), ]; diff --git a/app/Http/Transformers/DepartmentsTransformer.php b/app/Http/Transformers/DepartmentsTransformer.php index 546cedf04f..3d1e4c6f90 100644 --- a/app/Http/Transformers/DepartmentsTransformer.php +++ b/app/Http/Transformers/DepartmentsTransformer.php @@ -44,6 +44,7 @@ class DepartmentsTransformer 'name' => e($department->location->name), ] : null, 'users_count' => e($department->users_count), + 'notes' => Helper::parseEscapedMarkedownInline($department->notes), 'created_at' => Helper::getFormattedDateObject($department->created_at, 'datetime'), 'updated_at' => Helper::getFormattedDateObject($department->updated_at, 'datetime'), ]; diff --git a/app/Http/Transformers/GroupsTransformer.php b/app/Http/Transformers/GroupsTransformer.php index 03e96d5622..920c856b1a 100644 --- a/app/Http/Transformers/GroupsTransformer.php +++ b/app/Http/Transformers/GroupsTransformer.php @@ -26,6 +26,7 @@ class GroupsTransformer 'name' => e($group->name), 'permissions' => json_decode($group->permissions), 'users_count' => (int) $group->users_count, + 'notes' => Helper::parseEscapedMarkedownInline($group->notes), 'created_by' => ($group->adminuser) ? [ 'id' => (int) $group->adminuser->id, 'name'=> e($group->adminuser->present()->fullName()), diff --git a/app/Http/Transformers/LocationsTransformer.php b/app/Http/Transformers/LocationsTransformer.php index d6ba2f01b2..331f3839b2 100644 --- a/app/Http/Transformers/LocationsTransformer.php +++ b/app/Http/Transformers/LocationsTransformer.php @@ -55,6 +55,7 @@ class LocationsTransformer 'users_count' => (int) $location->users_count, 'currency' => ($location->currency) ? e($location->currency) : null, 'ldap_ou' => ($location->ldap_ou) ? e($location->ldap_ou) : null, + 'notes' => Helper::parseEscapedMarkedownInline($location->notes), 'created_at' => Helper::getFormattedDateObject($location->created_at, 'datetime'), 'updated_at' => Helper::getFormattedDateObject($location->updated_at, 'datetime'), 'parent' => ($location->parent) ? [ diff --git a/app/Http/Transformers/ManufacturersTransformer.php b/app/Http/Transformers/ManufacturersTransformer.php index d6954c1d24..cf17eb7764 100644 --- a/app/Http/Transformers/ManufacturersTransformer.php +++ b/app/Http/Transformers/ManufacturersTransformer.php @@ -37,6 +37,7 @@ class ManufacturersTransformer 'consumables_count' => (int) $manufacturer->consumables_count, 'accessories_count' => (int) $manufacturer->accessories_count, 'components_count' => (int) $manufacturer->components_count, + 'notes' => Helper::parseEscapedMarkedownInline($manufacturer->notes), 'created_by' => ($manufacturer->adminuser) ? [ 'id' => (int) $manufacturer->adminuser->id, 'name'=> e($manufacturer->adminuser->present()->fullName()), diff --git a/app/Importer/LocationImporter.php b/app/Importer/LocationImporter.php index 5a87d069e5..1fcef6625d 100644 --- a/app/Importer/LocationImporter.php +++ b/app/Importer/LocationImporter.php @@ -74,6 +74,8 @@ class LocationImporter extends ItemImporter $this->item['ldap_ou'] = trim($this->findCsvMatch($row, 'ldap_ou')); $this->item['manager'] = trim($this->findCsvMatch($row, 'manager')); $this->item['manager_username'] = trim($this->findCsvMatch($row, 'manager_username')); + $this->item['notes'] = trim($this->findCsvMatch($row, 'notes')); + if ($this->findCsvMatch($row, 'parent_location')) { $this->item['parent_id'] = $this->createOrFetchLocation(trim($this->findCsvMatch($row, 'parent_location'))); diff --git a/app/Livewire/Importer.php b/app/Livewire/Importer.php index aee6b852d4..eea319a400 100644 --- a/app/Livewire/Importer.php +++ b/app/Livewire/Importer.php @@ -342,6 +342,7 @@ class Importer extends Component 'manager_username' => trans('general.importer.manager_username'), 'manager' => trans('general.importer.manager_full_name'), 'parent_location' => trans('admin/locations/table.parent'), + 'notes' => trans('general.notes'), ]; $this->assetmodels_fields = [ diff --git a/app/Mail/ExpiringAssetsMail.php b/app/Mail/ExpiringAssetsMail.php new file mode 100644 index 0000000000..13d322f060 --- /dev/null +++ b/app/Mail/ExpiringAssetsMail.php @@ -0,0 +1,62 @@ +assets = $params; + $this->threshold = $threshold; + } + + /** + * Get the message envelope. + */ + public function envelope(): Envelope + { + $from = new Address(config('mail.from.address'), config('mail.from.name')); + + return new Envelope( + from: $from, + subject: trans('mail.Expiring_Assets_Report'), + ); + } + + /** + * Get the message content definition. + */ + public function content(): Content + { + return new Content( + markdown: 'notifications.markdown.report-expiring-assets', + with: [ + 'assets' => $this->assets, + 'threshold' => $this->threshold, + ] + ); + } + + /** + * Get the attachments for the message. + * + * @return array + */ + public function attachments(): array + { + return []; + } +} diff --git a/app/Mail/ExpiringLicenseMail.php b/app/Mail/ExpiringLicenseMail.php new file mode 100644 index 0000000000..77d94df637 --- /dev/null +++ b/app/Mail/ExpiringLicenseMail.php @@ -0,0 +1,62 @@ +licenses = $params; + $this->threshold = $threshold; + } + + /** + * Get the message envelope. + */ + public function envelope(): Envelope + { + $from = new Address(config('mail.from.address'), config('mail.from.name')); + + return new Envelope( + from: $from, + subject: trans('mail.Expiring_Licenses_Report'), + ); + } + + /** + * Get the message content definition. + */ + public function content(): Content + { + return new Content( + markdown: 'notifications.markdown.report-expiring-licenses', + with: [ + 'licenses' => $this->licenses, + 'threshold' => $this->threshold, + ] + ); + } + + /** + * Get the attachments for the message. + * + * @return array + */ + public function attachments(): array + { + return []; + } +} diff --git a/app/Models/Category.php b/app/Models/Category.php index 5965404f59..cfa83328ab 100755 --- a/app/Models/Category.php +++ b/app/Models/Category.php @@ -71,6 +71,7 @@ class Category extends SnipeModel 'require_acceptance', 'use_default_eula', 'created_by', + 'notes', ]; use Searchable; @@ -80,7 +81,7 @@ class Category extends SnipeModel * * @var array */ - protected $searchableAttributes = ['name', 'category_type']; + protected $searchableAttributes = ['name', 'category_type', 'notes']; /** * The relations and their attributes that should be included when searching the model. diff --git a/app/Models/Group.php b/app/Models/Group.php index 7278152df9..ef60e6737c 100755 --- a/app/Models/Group.php +++ b/app/Models/Group.php @@ -18,7 +18,8 @@ class Group extends SnipeModel protected $fillable = [ 'name', - 'permissions' + 'permissions', + 'notes', ]; /** @@ -37,7 +38,7 @@ class Group extends SnipeModel * * @var array */ - protected $searchableAttributes = ['name', 'created_at']; + protected $searchableAttributes = ['name', 'created_at', 'notes']; /** * The relations and their attributes that should be included when searching the model. diff --git a/app/Models/Location.php b/app/Models/Location.php index f146d37c66..63cb2de39d 100755 --- a/app/Models/Location.php +++ b/app/Models/Location.php @@ -72,6 +72,7 @@ class Location extends SnipeModel 'currency', 'manager_id', 'image', + 'notes', ]; protected $hidden = ['user_id']; @@ -82,7 +83,7 @@ class Location extends SnipeModel * * @var array */ - protected $searchableAttributes = ['name', 'address', 'city', 'state', 'zip', 'created_at', 'ldap_ou', 'phone', 'fax']; + protected $searchableAttributes = ['name', 'address', 'city', 'state', 'zip', 'created_at', 'ldap_ou', 'phone', 'fax', 'notes']; /** * The relations and their attributes that should be included when searching the model. diff --git a/app/Models/Manufacturer.php b/app/Models/Manufacturer.php index 1b31f496d3..6d7b010677 100755 --- a/app/Models/Manufacturer.php +++ b/app/Models/Manufacturer.php @@ -53,6 +53,7 @@ class Manufacturer extends SnipeModel 'support_url', 'url', 'warranty_lookup_url', + 'notes', ]; use Searchable; @@ -62,7 +63,7 @@ class Manufacturer extends SnipeModel * * @var array */ - protected $searchableAttributes = ['name', 'created_at']; + protected $searchableAttributes = ['name', 'created_at', 'notes']; /** * The relations and their attributes that should be included when searching the model. diff --git a/app/Models/Setting.php b/app/Models/Setting.php index 232285fbdb..8f8299a3c5 100755 --- a/app/Models/Setting.php +++ b/app/Models/Setting.php @@ -2,6 +2,7 @@ namespace App\Models; +use Carbon\Carbon; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; use Illuminate\Notifications\Notifiable; @@ -339,6 +340,33 @@ class Setting extends Model return collect($ldapSettings); } + /** + * For a particular cache-file, refresh it if the settings have + * been updated more recently than the file. Then return the + * full filepath + */ + public static function get_fresh_file_path($attribute, $path) + { + $full_path = storage_path().'/'.$path; + $file_exists = file_exists($full_path); + if ($file_exists) { + $statblock = stat($full_path); + } + if (!$file_exists || Carbon::createFromTimestamp($statblock['mtime']) < Setting::getSettings()->updated_at) { + if (Setting::getSettings()->{$attribute}) { + file_put_contents($full_path, Setting::getSettings()->{$attribute}); + } else { + //this doesn't fire when you might expect it to because a lot of the time we do something like: + // if ($settings->ldap_client_tls_cert && ... + // so we never get a chance to 'uncache' the file. + if ($file_exists) { + unlink($full_path); + } + } + } + return $full_path; + } + /** * Return the filename for the client-side SSL cert * @@ -346,7 +374,7 @@ class Setting extends Model */ public static function get_client_side_cert_path() { - return storage_path().'/ldap_client_tls.cert'; + return self::get_fresh_file_path('ldap_client_tls_cert', 'ldap_client_tls.cert'); } /** @@ -356,36 +384,7 @@ class Setting extends Model */ public static function get_client_side_key_path() { - return storage_path().'/ldap_client_tls.key'; + return self::get_fresh_file_path('ldap_client_tls_key', 'ldap_client_tls.key'); } - public function update_client_side_cert_files() - { - /** - * I'm not sure if it makes sense to have a cert but no key - * nor vice versa, but for now I'm just leaving it like this. - * - * Also, we could easily set this up with an event handler and - * self::saved() or something like that but there's literally only - * one place where we will do that, so I'll just explicitly call - * this method at that spot instead. It'll be easier to debug and understand. - */ - if ($this->ldap_client_tls_cert) { - file_put_contents(self::get_client_side_cert_path(), $this->ldap_client_tls_cert); - } else { - if (file_exists(self::get_client_side_cert_path())) { - unlink(self::get_client_side_cert_path()); - } - } - - if ($this->ldap_client_tls_key) { - file_put_contents(self::get_client_side_key_path(), $this->ldap_client_tls_key); - } else { - if (file_exists(self::get_client_side_key_path())) { - unlink(self::get_client_side_key_path()); - } - } - } - - } diff --git a/app/Notifications/CheckinAssetNotification.php b/app/Notifications/CheckinAssetNotification.php index fa4780c1fd..c6828ef8e9 100644 --- a/app/Notifications/CheckinAssetNotification.php +++ b/app/Notifications/CheckinAssetNotification.php @@ -79,7 +79,7 @@ class CheckinAssetNotification extends Notification $fields = [ trans('general.administrator') => '<'.$admin->present()->viewUrl().'|'.$admin->present()->fullName().'>', - trans('general.status') => $item->assetstatus->name, + trans('general.status') => $item->assetstatus?->name, trans('general.location') => ($item->location) ? $item->location->name : '', ]; @@ -106,9 +106,9 @@ class CheckinAssetNotification extends Notification ->title(trans('mail.Asset_Checkin_Notification')) ->addStartGroupToSection('activityText') ->fact(htmlspecialchars_decode($item->present()->name), '', 'activityText') - ->fact(trans('mail.checked_into'), $item->location->name ? $item->location->name : '') + ->fact(trans('mail.checked_into'), ($item->location) ? $item->location->name : '') ->fact(trans('mail.Asset_Checkin_Notification') . " by ", $admin->present()->fullName()) - ->fact(trans('admin/hardware/form.status'), $item->assetstatus->name) + ->fact(trans('admin/hardware/form.status'), $item->assetstatus?->name) ->fact(trans('mail.notes'), $note ?: ''); } @@ -116,9 +116,9 @@ class CheckinAssetNotification extends Notification $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.checked_into') => ($item->location) ? $item->location->name : '', trans('mail.Asset_Checkin_Notification')." by " => $admin->present()->fullName(), - trans('admin/hardware/form.status') => $item->assetstatus->name, + trans('admin/hardware/form.status') => $item->assetstatus?->name, trans('mail.notes') => $note ?: '', ]; @@ -142,8 +142,8 @@ class CheckinAssetNotification extends Notification Section::create( KeyValue::create( trans('mail.checked_into') ?: '', - $item->location->name ? $item->location->name : '', - trans('admin/hardware/form.status').": ".$item->assetstatus->name, + ($item->location) ? $item->location->name : '', + trans('admin/hardware/form.status').": ".$item->assetstatus?->name, ) ->onClick(route('hardware.show', $item->id)) ) diff --git a/app/Presenters/CategoryPresenter.php b/app/Presenters/CategoryPresenter.php index f551c0ba1b..d4a9f01a05 100644 --- a/app/Presenters/CategoryPresenter.php +++ b/app/Presenters/CategoryPresenter.php @@ -77,7 +77,13 @@ class CategoryPresenter extends Presenter "title" => trans('admin/categories/general.use_default_eula_column'), 'visible' => true, "formatter" => 'trueFalseFormatter', - ],[ + ], [ + 'field' => 'notes', + 'searchable' => true, + 'sortable' => true, + 'visible' => false, + 'title' => trans('general.notes'), + ], [ 'field' => 'created_by', 'searchable' => false, 'sortable' => true, diff --git a/app/Presenters/CompanyPresenter.php b/app/Presenters/CompanyPresenter.php index 6f9ece2141..fb86166092 100644 --- a/app/Presenters/CompanyPresenter.php +++ b/app/Presenters/CompanyPresenter.php @@ -105,7 +105,13 @@ class CompanyPresenter extends Presenter 'title' => trans('general.components'), 'visible' => true, 'class' => 'css-component', - ],[ + ], [ + 'field' => 'notes', + 'searchable' => true, + 'sortable' => true, + 'visible' => false, + 'title' => trans('general.notes'), + ], [ 'field' => 'created_by', 'searchable' => false, 'sortable' => true, diff --git a/app/Presenters/LocationPresenter.php b/app/Presenters/LocationPresenter.php index af910bfdc1..9283824a28 100644 --- a/app/Presenters/LocationPresenter.php +++ b/app/Presenters/LocationPresenter.php @@ -184,6 +184,12 @@ class LocationPresenter extends Presenter 'title' => trans('admin/users/table.manager'), 'visible' => false, 'formatter' => 'usersLinkObjFormatter', + ], [ + 'field' => 'notes', + 'searchable' => true, + 'sortable' => true, + 'visible' => false, + 'title' => trans('general.notes'), ], [ 'field' => 'created_at', 'searchable' => true, diff --git a/database/factories/CategoryFactory.php b/database/factories/CategoryFactory.php index 540dcb3085..9897b396c1 100644 --- a/database/factories/CategoryFactory.php +++ b/database/factories/CategoryFactory.php @@ -30,6 +30,7 @@ class CategoryFactory extends Factory 'require_acceptance' => false, 'use_default_eula' => $this->faker->boolean(), 'created_by' => User::factory()->superuser(), + 'notes' => 'Created by DB seeder', ]; } diff --git a/database/factories/CompanyFactory.php b/database/factories/CompanyFactory.php index 5f1ac0c98a..12195d78a5 100644 --- a/database/factories/CompanyFactory.php +++ b/database/factories/CompanyFactory.php @@ -24,6 +24,7 @@ class CompanyFactory extends Factory return [ 'name' => $this->faker->unique()->company(), 'created_by' => 1, + 'notes' => 'Created by DB seeder', ]; } } diff --git a/database/factories/DepartmentFactory.php b/database/factories/DepartmentFactory.php index 011a632669..7e6c2f0025 100644 --- a/database/factories/DepartmentFactory.php +++ b/database/factories/DepartmentFactory.php @@ -27,6 +27,7 @@ class DepartmentFactory extends Factory 'name' => $this->faker->unique()->word() . ' Department', 'created_by' => User::factory()->superuser(), 'location_id' => Location::factory(), + 'notes' => 'Created by DB seeder', ]; } diff --git a/database/factories/GroupFactory.php b/database/factories/GroupFactory.php index 1c6eaa8125..fecf8239bb 100644 --- a/database/factories/GroupFactory.php +++ b/database/factories/GroupFactory.php @@ -24,6 +24,7 @@ class GroupFactory extends Factory return [ 'name' => $this->faker->name(), 'permissions' => json_encode([]), + 'notes' => 'Created by DB seeder', ]; } } diff --git a/database/factories/LocationFactory.php b/database/factories/LocationFactory.php index 3aa0577bd8..3d0b444f70 100644 --- a/database/factories/LocationFactory.php +++ b/database/factories/LocationFactory.php @@ -23,6 +23,7 @@ class LocationFactory extends Factory 'currency' => $this->faker->currencyCode(), 'zip' => $this->faker->postcode(), 'image' => rand(1, 9).'.jpg', + 'notes' => 'Created by DB seeder', ]; } diff --git a/database/factories/ManufacturerFactory.php b/database/factories/ManufacturerFactory.php index 47d4f672f3..a8d6208d7e 100644 --- a/database/factories/ManufacturerFactory.php +++ b/database/factories/ManufacturerFactory.php @@ -28,6 +28,7 @@ class ManufacturerFactory extends Factory 'support_phone' => $this->faker->phoneNumber(), 'url' => $this->faker->url(), 'support_email' => $this->faker->safeEmail(), + 'notes' => 'Created by DB seeder', ]; } diff --git a/database/migrations/2025_02_10_230155_add_notes_to_locations_companies_categories_manufacturers_groups.php b/database/migrations/2025_02_10_230155_add_notes_to_locations_companies_categories_manufacturers_groups.php new file mode 100644 index 0000000000..bbffc50305 --- /dev/null +++ b/database/migrations/2025_02_10_230155_add_notes_to_locations_companies_categories_manufacturers_groups.php @@ -0,0 +1,60 @@ +text('notes')->nullable()->default(null); + }); + + Schema::table('companies', function (Blueprint $table) { + $table->text('notes')->nullable()->default(null); + }); + + Schema::table('categories', function (Blueprint $table) { + $table->text('notes')->nullable()->default(null); + }); + + Schema::table('manufacturers', function (Blueprint $table) { + $table->text('notes')->nullable()->default(null); + }); + + Schema::table('permission_groups', function (Blueprint $table) { + $table->text('notes')->nullable()->default(null); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('locations', function (Blueprint $table) { + $table->dropColumn('notes'); + }); + + Schema::table('companies', function (Blueprint $table) { + $table->dropColumn('notes'); + }); + + Schema::table('categories', function (Blueprint $table) { + $table->dropColumn('notes'); + }); + + Schema::table('manufacturers', function (Blueprint $table) { + $table->dropColumn('notes'); + }); + + Schema::table('permission_groups', function (Blueprint $table) { + $table->dropColumn('notes'); + }); + } +}; diff --git a/public/css/build/AdminLTE.css b/public/css/build/AdminLTE.css index 46885f5f02..ca7aa7a66c 100644 Binary files a/public/css/build/AdminLTE.css and b/public/css/build/AdminLTE.css differ diff --git a/public/css/build/app.css b/public/css/build/app.css index 7ea8f083b9..9365354e77 100644 Binary files a/public/css/build/app.css and b/public/css/build/app.css differ diff --git a/public/css/build/overrides.css b/public/css/build/overrides.css index 1074758f2b..d69492c1c2 100644 Binary files a/public/css/build/overrides.css and b/public/css/build/overrides.css differ diff --git a/public/css/dist/all.css b/public/css/dist/all.css index 848587ae70..d701d75673 100644 Binary files a/public/css/dist/all.css and b/public/css/dist/all.css differ diff --git a/public/css/dist/bootstrap-table.css b/public/css/dist/bootstrap-table.css index bfd8ab0bd3..89c11da6f8 100644 Binary files a/public/css/dist/bootstrap-table.css and b/public/css/dist/bootstrap-table.css differ diff --git a/public/css/dist/signature-pad.min.css b/public/css/dist/signature-pad.min.css index 218b9c2365..7065929572 100644 Binary files a/public/css/dist/signature-pad.min.css and b/public/css/dist/signature-pad.min.css differ diff --git a/public/css/dist/skins/_all-skins.css b/public/css/dist/skins/_all-skins.css index b532ddb1f6..dd53f5635c 100644 Binary files a/public/css/dist/skins/_all-skins.css and b/public/css/dist/skins/_all-skins.css differ diff --git a/public/css/dist/skins/_all-skins.min.css b/public/css/dist/skins/_all-skins.min.css index b532ddb1f6..9427f05bb0 100644 Binary files a/public/css/dist/skins/_all-skins.min.css and b/public/css/dist/skins/_all-skins.min.css differ diff --git a/public/css/dist/skins/skin-black-dark.css b/public/css/dist/skins/skin-black-dark.css index 9b8aa60934..c8f18f6979 100644 Binary files a/public/css/dist/skins/skin-black-dark.css and b/public/css/dist/skins/skin-black-dark.css differ diff --git a/public/css/dist/skins/skin-black-dark.min.css b/public/css/dist/skins/skin-black-dark.min.css index 9b8aa60934..bb68e3148a 100644 Binary files a/public/css/dist/skins/skin-black-dark.min.css and b/public/css/dist/skins/skin-black-dark.min.css differ diff --git a/public/css/dist/skins/skin-black.css b/public/css/dist/skins/skin-black.css index ab4d845e2a..2d3d0edc3b 100644 Binary files a/public/css/dist/skins/skin-black.css and b/public/css/dist/skins/skin-black.css differ diff --git a/public/css/dist/skins/skin-black.min.css b/public/css/dist/skins/skin-black.min.css index ab4d845e2a..5a5decc906 100644 Binary files a/public/css/dist/skins/skin-black.min.css and b/public/css/dist/skins/skin-black.min.css differ diff --git a/public/css/dist/skins/skin-blue-dark.css b/public/css/dist/skins/skin-blue-dark.css index 4290f090ba..aad99fcc92 100644 Binary files a/public/css/dist/skins/skin-blue-dark.css and b/public/css/dist/skins/skin-blue-dark.css differ diff --git a/public/css/dist/skins/skin-blue-dark.min.css b/public/css/dist/skins/skin-blue-dark.min.css index 4290f090ba..7923bbc585 100644 Binary files a/public/css/dist/skins/skin-blue-dark.min.css and b/public/css/dist/skins/skin-blue-dark.min.css differ diff --git a/public/css/dist/skins/skin-blue.css b/public/css/dist/skins/skin-blue.css index cac9000174..cdc62766ec 100644 Binary files a/public/css/dist/skins/skin-blue.css and b/public/css/dist/skins/skin-blue.css differ diff --git a/public/css/dist/skins/skin-blue.min.css b/public/css/dist/skins/skin-blue.min.css index cac9000174..09b0bba755 100644 Binary files a/public/css/dist/skins/skin-blue.min.css and b/public/css/dist/skins/skin-blue.min.css differ diff --git a/public/css/dist/skins/skin-contrast.css b/public/css/dist/skins/skin-contrast.css index 50dfc577e2..8f5c99c013 100644 Binary files a/public/css/dist/skins/skin-contrast.css and b/public/css/dist/skins/skin-contrast.css differ diff --git a/public/css/dist/skins/skin-contrast.min.css b/public/css/dist/skins/skin-contrast.min.css index 50dfc577e2..25ebe1f277 100644 Binary files a/public/css/dist/skins/skin-contrast.min.css and b/public/css/dist/skins/skin-contrast.min.css differ diff --git a/public/css/dist/skins/skin-green-dark.css b/public/css/dist/skins/skin-green-dark.css index af11e57391..6adec7c623 100644 Binary files a/public/css/dist/skins/skin-green-dark.css and b/public/css/dist/skins/skin-green-dark.css differ diff --git a/public/css/dist/skins/skin-green-dark.min.css b/public/css/dist/skins/skin-green-dark.min.css index af11e57391..70e85ed032 100644 Binary files a/public/css/dist/skins/skin-green-dark.min.css and b/public/css/dist/skins/skin-green-dark.min.css differ diff --git a/public/css/dist/skins/skin-green.css b/public/css/dist/skins/skin-green.css index fe0b851609..cd113d5e54 100644 Binary files a/public/css/dist/skins/skin-green.css and b/public/css/dist/skins/skin-green.css differ diff --git a/public/css/dist/skins/skin-green.min.css b/public/css/dist/skins/skin-green.min.css index fe0b851609..620d48e3f4 100644 Binary files a/public/css/dist/skins/skin-green.min.css and b/public/css/dist/skins/skin-green.min.css differ diff --git a/public/css/dist/skins/skin-orange-dark.css b/public/css/dist/skins/skin-orange-dark.css index 58a0afd1f2..4fe3148e7b 100644 Binary files a/public/css/dist/skins/skin-orange-dark.css and b/public/css/dist/skins/skin-orange-dark.css differ diff --git a/public/css/dist/skins/skin-orange-dark.min.css b/public/css/dist/skins/skin-orange-dark.min.css index 58a0afd1f2..ccebd4458e 100644 Binary files a/public/css/dist/skins/skin-orange-dark.min.css and b/public/css/dist/skins/skin-orange-dark.min.css differ diff --git a/public/css/dist/skins/skin-orange.css b/public/css/dist/skins/skin-orange.css index b26415b6a3..411d4994ac 100644 Binary files a/public/css/dist/skins/skin-orange.css and b/public/css/dist/skins/skin-orange.css differ diff --git a/public/css/dist/skins/skin-orange.min.css b/public/css/dist/skins/skin-orange.min.css index b26415b6a3..af01a70cff 100644 Binary files a/public/css/dist/skins/skin-orange.min.css and b/public/css/dist/skins/skin-orange.min.css differ diff --git a/public/css/dist/skins/skin-purple-dark.css b/public/css/dist/skins/skin-purple-dark.css index 0517db814c..201e4709b1 100644 Binary files a/public/css/dist/skins/skin-purple-dark.css and b/public/css/dist/skins/skin-purple-dark.css differ diff --git a/public/css/dist/skins/skin-purple-dark.min.css b/public/css/dist/skins/skin-purple-dark.min.css index 0517db814c..1b90bca8e3 100644 Binary files a/public/css/dist/skins/skin-purple-dark.min.css and b/public/css/dist/skins/skin-purple-dark.min.css differ diff --git a/public/css/dist/skins/skin-purple.css b/public/css/dist/skins/skin-purple.css index d4f67fee9b..344cbfce10 100644 Binary files a/public/css/dist/skins/skin-purple.css and b/public/css/dist/skins/skin-purple.css differ diff --git a/public/css/dist/skins/skin-purple.min.css b/public/css/dist/skins/skin-purple.min.css index d4f67fee9b..8a89eae1a6 100644 Binary files a/public/css/dist/skins/skin-purple.min.css and b/public/css/dist/skins/skin-purple.min.css differ diff --git a/public/css/dist/skins/skin-red-dark.css b/public/css/dist/skins/skin-red-dark.css index 2b87b2b921..092c24bf11 100644 Binary files a/public/css/dist/skins/skin-red-dark.css and b/public/css/dist/skins/skin-red-dark.css differ diff --git a/public/css/dist/skins/skin-red-dark.min.css b/public/css/dist/skins/skin-red-dark.min.css index 2b87b2b921..5601ce5055 100644 Binary files a/public/css/dist/skins/skin-red-dark.min.css and b/public/css/dist/skins/skin-red-dark.min.css differ diff --git a/public/css/dist/skins/skin-red.css b/public/css/dist/skins/skin-red.css index 0dc3658056..c6167ad739 100644 Binary files a/public/css/dist/skins/skin-red.css and b/public/css/dist/skins/skin-red.css differ diff --git a/public/css/dist/skins/skin-red.min.css b/public/css/dist/skins/skin-red.min.css index 0dc3658056..4f73db5918 100644 Binary files a/public/css/dist/skins/skin-red.min.css and b/public/css/dist/skins/skin-red.min.css differ diff --git a/public/css/dist/skins/skin-yellow-dark.css b/public/css/dist/skins/skin-yellow-dark.css index 119afcd4fd..115637bf1d 100644 Binary files a/public/css/dist/skins/skin-yellow-dark.css and b/public/css/dist/skins/skin-yellow-dark.css differ diff --git a/public/css/dist/skins/skin-yellow-dark.min.css b/public/css/dist/skins/skin-yellow-dark.min.css index 119afcd4fd..6000adc7b5 100644 Binary files a/public/css/dist/skins/skin-yellow-dark.min.css and b/public/css/dist/skins/skin-yellow-dark.min.css differ diff --git a/public/css/dist/skins/skin-yellow.css b/public/css/dist/skins/skin-yellow.css index 8aef4cb90e..5424b7f75d 100644 Binary files a/public/css/dist/skins/skin-yellow.css and b/public/css/dist/skins/skin-yellow.css differ diff --git a/public/css/dist/skins/skin-yellow.min.css b/public/css/dist/skins/skin-yellow.min.css index 8aef4cb90e..f64159f334 100644 Binary files a/public/css/dist/skins/skin-yellow.min.css and b/public/css/dist/skins/skin-yellow.min.css differ diff --git a/public/js/build/app.js b/public/js/build/app.js index 5f6dc71c8d..87797a2655 100644 Binary files a/public/js/build/app.js and b/public/js/build/app.js differ diff --git a/public/js/build/vendor.js b/public/js/build/vendor.js index 102490976b..39600c0d68 100644 Binary files a/public/js/build/vendor.js and b/public/js/build/vendor.js differ diff --git a/public/js/dist/all.js b/public/js/dist/all.js index ad883df21c..3a13cb77be 100644 Binary files a/public/js/dist/all.js and b/public/js/dist/all.js differ diff --git a/public/js/dist/bootstrap-table.js b/public/js/dist/bootstrap-table.js index 608f300733..d0be272444 100644 Binary files a/public/js/dist/bootstrap-table.js and b/public/js/dist/bootstrap-table.js differ diff --git a/public/mix-manifest.json b/public/mix-manifest.json index 08bf9cdbfc..c8122e9306 100644 --- a/public/mix-manifest.json +++ b/public/mix-manifest.json @@ -1,25 +1,25 @@ { - "/js/build/app.js": "/js/build/app.js?id=578c0308b8a324cc78c7786da9406022", - "/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/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", - "/css/dist/skins/skin-yellow.css": "/css/dist/skins/skin-yellow.css?id=7b315b9612b8fde8f9c5b0ddb6bba690", - "/css/dist/skins/skin-yellow-dark.css": "/css/dist/skins/skin-yellow-dark.css?id=ea22079836a432d7f46a5d390c445e13", - "/css/dist/skins/skin-red.css": "/css/dist/skins/skin-red.css?id=44bf834f2110504a793dadec132a5898", - "/css/dist/skins/skin-red-dark.css": "/css/dist/skins/skin-red-dark.css?id=05cc02539441b717012c4efc3303192f", - "/css/dist/skins/skin-purple.css": "/css/dist/skins/skin-purple.css?id=6fe68325d5356197672c27bc77cedcb4", - "/css/dist/skins/skin-purple-dark.css": "/css/dist/skins/skin-purple-dark.css?id=fca90dff303e17dc2991ca395c7f7fa8", - "/css/dist/skins/skin-orange.css": "/css/dist/skins/skin-orange.css?id=6f0563e726c2fe4fab4026daaa5bfdf2", - "/css/dist/skins/skin-orange-dark.css": "/css/dist/skins/skin-orange-dark.css?id=71b7731f7ae692eada36b9b08a2e04a9", - "/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-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", + "/js/build/app.js": "/js/build/app.js?id=eeefb5463df4ea2a4cbae72c96006e10", + "/css/dist/skins/skin-black-dark.css": "/css/dist/skins/skin-black-dark.css?id=d34ae2483cbe2c77478c45f4006eba55", + "/css/dist/skins/_all-skins.css": "/css/dist/skins/_all-skins.css?id=b1c78591f51b52beab05b52f407ad6e6", + "/css/build/overrides.css": "/css/build/overrides.css?id=4f85f2e6fd839b8812dd68d001aae4a3", + "/css/build/app.css": "/css/build/app.css?id=50f697122a35791df98a58bcf0665220", + "/css/build/AdminLTE.css": "/css/build/AdminLTE.css?id=a67bd93bed52e6a29967fe472de66d6c", + "/css/dist/skins/skin-yellow.css": "/css/dist/skins/skin-yellow.css?id=fc7adb943668ac69fe4b646625a7571f", + "/css/dist/skins/skin-yellow-dark.css": "/css/dist/skins/skin-yellow-dark.css?id=53edc92eb2d272744bc7404ec259930e", + "/css/dist/skins/skin-red.css": "/css/dist/skins/skin-red.css?id=b9a74ec0cd68f83e7480d5ae39919beb", + "/css/dist/skins/skin-red-dark.css": "/css/dist/skins/skin-red-dark.css?id=cdbb4f543fb448f03617c7ed9d2cbec3", + "/css/dist/skins/skin-purple.css": "/css/dist/skins/skin-purple.css?id=cf6c8c340420724b02d6e787ef9bded5", + "/css/dist/skins/skin-purple-dark.css": "/css/dist/skins/skin-purple-dark.css?id=cfa51820f16533fd62b3c3d720e368ec", + "/css/dist/skins/skin-orange.css": "/css/dist/skins/skin-orange.css?id=268041e902b019730c23ee3875838005", + "/css/dist/skins/skin-orange-dark.css": "/css/dist/skins/skin-orange-dark.css?id=98bd6927e46418c642fdd33fe56f4f26", + "/css/dist/skins/skin-green.css": "/css/dist/skins/skin-green.css?id=b48f4d8af0e1ca5621c161e93951109f", + "/css/dist/skins/skin-green-dark.css": "/css/dist/skins/skin-green-dark.css?id=16dc04eb54142bd3c32c2768d365d988", + "/css/dist/skins/skin-contrast.css": "/css/dist/skins/skin-contrast.css?id=f0fbbb0ac729ea092578fb05ca615460", + "/css/dist/skins/skin-blue.css": "/css/dist/skins/skin-blue.css?id=392cc93cfc0be0349bab9697669dd091", + "/css/dist/skins/skin-blue-dark.css": "/css/dist/skins/skin-blue-dark.css?id=18787b3f00a3be7be38ee4e26cbd2a07", + "/css/dist/skins/skin-black.css": "/css/dist/skins/skin-black.css?id=1f33ca3d860461c1127ec465ab3ebb6b", + "/css/dist/all.css": "/css/dist/all.css?id=baad37c1b095168a326c5bb16b0feb38", "/css/dist/signature-pad.css": "/css/dist/signature-pad.css?id=6a89d3cd901305e66ced1cf5f13147f7", "/css/dist/signature-pad.min.css": "/css/dist/signature-pad.min.css?id=6a89d3cd901305e66ced1cf5f13147f7", "/js/select2/i18n/af.js": "/js/select2/i18n/af.js?id=4f6fcd73488ce79fae1b7a90aceaecde", @@ -92,24 +92,24 @@ "/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/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-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", - "/css/dist/skins/skin-orange-dark.min.css": "/css/dist/skins/skin-orange-dark.min.css?id=71b7731f7ae692eada36b9b08a2e04a9", - "/css/dist/skins/skin-orange.min.css": "/css/dist/skins/skin-orange.min.css?id=6f0563e726c2fe4fab4026daaa5bfdf2", - "/css/dist/skins/skin-purple-dark.min.css": "/css/dist/skins/skin-purple-dark.min.css?id=fca90dff303e17dc2991ca395c7f7fa8", - "/css/dist/skins/skin-purple.min.css": "/css/dist/skins/skin-purple.min.css?id=6fe68325d5356197672c27bc77cedcb4", - "/css/dist/skins/skin-red-dark.min.css": "/css/dist/skins/skin-red-dark.min.css?id=05cc02539441b717012c4efc3303192f", - "/css/dist/skins/skin-red.min.css": "/css/dist/skins/skin-red.min.css?id=44bf834f2110504a793dadec132a5898", - "/css/dist/skins/skin-yellow-dark.min.css": "/css/dist/skins/skin-yellow-dark.min.css?id=ea22079836a432d7f46a5d390c445e13", - "/css/dist/skins/skin-yellow.min.css": "/css/dist/skins/skin-yellow.min.css?id=7b315b9612b8fde8f9c5b0ddb6bba690", + "/css/dist/skins/_all-skins.min.css": "/css/dist/skins/_all-skins.min.css?id=b1c78591f51b52beab05b52f407ad6e6", + "/css/dist/skins/skin-black-dark.min.css": "/css/dist/skins/skin-black-dark.min.css?id=d34ae2483cbe2c77478c45f4006eba55", + "/css/dist/skins/skin-black.min.css": "/css/dist/skins/skin-black.min.css?id=1f33ca3d860461c1127ec465ab3ebb6b", + "/css/dist/skins/skin-blue-dark.min.css": "/css/dist/skins/skin-blue-dark.min.css?id=18787b3f00a3be7be38ee4e26cbd2a07", + "/css/dist/skins/skin-blue.min.css": "/css/dist/skins/skin-blue.min.css?id=392cc93cfc0be0349bab9697669dd091", + "/css/dist/skins/skin-contrast.min.css": "/css/dist/skins/skin-contrast.min.css?id=f0fbbb0ac729ea092578fb05ca615460", + "/css/dist/skins/skin-green-dark.min.css": "/css/dist/skins/skin-green-dark.min.css?id=16dc04eb54142bd3c32c2768d365d988", + "/css/dist/skins/skin-green.min.css": "/css/dist/skins/skin-green.min.css?id=b48f4d8af0e1ca5621c161e93951109f", + "/css/dist/skins/skin-orange-dark.min.css": "/css/dist/skins/skin-orange-dark.min.css?id=98bd6927e46418c642fdd33fe56f4f26", + "/css/dist/skins/skin-orange.min.css": "/css/dist/skins/skin-orange.min.css?id=268041e902b019730c23ee3875838005", + "/css/dist/skins/skin-purple-dark.min.css": "/css/dist/skins/skin-purple-dark.min.css?id=cfa51820f16533fd62b3c3d720e368ec", + "/css/dist/skins/skin-purple.min.css": "/css/dist/skins/skin-purple.min.css?id=cf6c8c340420724b02d6e787ef9bded5", + "/css/dist/skins/skin-red-dark.min.css": "/css/dist/skins/skin-red-dark.min.css?id=cdbb4f543fb448f03617c7ed9d2cbec3", + "/css/dist/skins/skin-red.min.css": "/css/dist/skins/skin-red.min.css?id=b9a74ec0cd68f83e7480d5ae39919beb", + "/css/dist/skins/skin-yellow-dark.min.css": "/css/dist/skins/skin-yellow-dark.min.css?id=53edc92eb2d272744bc7404ec259930e", + "/css/dist/skins/skin-yellow.min.css": "/css/dist/skins/skin-yellow.min.css?id=fc7adb943668ac69fe4b646625a7571f", "/css/dist/bootstrap-table.css": "/css/dist/bootstrap-table.css?id=ceded08e0cc745a83c13647035b03406", "/js/build/vendor.js": "/js/build/vendor.js?id=89dffa552c6e3abe3a2aac6c9c7b466b", "/js/dist/bootstrap-table.js": "/js/dist/bootstrap-table.js?id=61285c8ac5ea7b46002ea8c451c94e60", - "/js/dist/all.js": "/js/dist/all.js?id=eeeac92878ac0b207ad7f39d593f62c3" + "/js/dist/all.js": "/js/dist/all.js?id=ba1c5e26a7d391ad40d699be7bea633e" } diff --git a/resources/lang/en-US/general.php b/resources/lang/en-US/general.php index 77670b5a7e..cf344273be 100644 --- a/resources/lang/en-US/general.php +++ b/resources/lang/en-US/general.php @@ -561,6 +561,7 @@ return [ 'consumables' => ':count Consumable|:count Consumables', 'components' => ':count Component|:count Components', ], + 'more_info' => 'More Info', 'quickscan_bulk_help' => 'Checking this box will edit the asset record to reflect this new location. Leaving it unchecked will simply note the location in the audit log. Note that if this asset is checked out, it will not change the location of the person, asset or location it is checked out to.', 'whoops' => 'Whoops!', @@ -577,4 +578,9 @@ return [ 'user_managed_passwords_disallow' => 'Disallow users from managing their own passwords', 'user_managed_passwords_allow' => 'Allow users to manage their own passwords', +// Add form placeholders here + 'placeholders' => [ + 'notes' => 'Add a note', + ], + ]; diff --git a/resources/views/account/profile.blade.php b/resources/views/account/profile.blade.php index d27367192a..b745c19360 100755 --- a/resources/views/account/profile.blade.php +++ b/resources/views/account/profile.blade.php @@ -128,7 +128,7 @@
{!! $errors->first('image_delete', ':message') !!} @@ -150,13 +150,23 @@ @if ($snipeSettings->two_factor_enabled=='1')
- @can('self.two_factor') -
- {!! Form::textarea('field_values', old('name', $field->field_values), ['style' => 'width: 100%', 'rows' => 4, 'class' => 'form-control', 'aria-label'=>'field_values']) !!} + {!! $errors->first('field_values', '') !!}

{{ trans('admin/custom_fields/general.field_values_help') }}

diff --git a/resources/views/custom_fields/fieldsets/view.blade.php b/resources/views/custom_fields/fieldsets/view.blade.php index b73ae708c6..626b5b73a4 100644 --- a/resources/views/custom_fields/fieldsets/view.blade.php +++ b/resources/views/custom_fields/fieldsets/view.blade.php @@ -109,7 +109,7 @@
diff --git a/resources/views/departments/edit.blade.php b/resources/views/departments/edit.blade.php index c1a2b38d56..05d9b49e4c 100644 --- a/resources/views/departments/edit.blade.php +++ b/resources/views/departments/edit.blade.php @@ -26,6 +26,20 @@ @include ('partials.forms.edit.location-select', ['translated_name' => trans('general.location'), 'fieldname' => 'location_id']) @include ('partials.forms.edit.image-upload', ['image_path' => app('departments_upload_path')]) +
+ +
+ + {!! $errors->first('notes', '') !!} +
+
@stop diff --git a/resources/views/departments/index.blade.php b/resources/views/departments/index.blade.php index aa9d09e660..d05d5c9d75 100644 --- a/resources/views/departments/index.blade.php +++ b/resources/views/departments/index.blade.php @@ -43,6 +43,7 @@ {{ trans('admin/departments/table.manager') }} {{ trans('general.users') }} {{ trans('admin/departments/table.location') }} + {{ trans('general.notes') }} {{ trans('table.actions') }} diff --git a/resources/views/groups/edit.blade.php b/resources/views/groups/edit.blade.php index bd6bd85d1c..4c387f73ef 100755 --- a/resources/views/groups/edit.blade.php +++ b/resources/views/groups/edit.blade.php @@ -54,12 +54,29 @@ @section('inputFields')
- -
+ +
{!! $errors->first('name', '') !!}
+ +
+ +
+ + + {!! $errors->first('notes', '') !!} +
+
+
diff --git a/resources/views/hardware/bulk.blade.php b/resources/views/hardware/bulk.blade.php index b8189d59c3..4ac80e9820 100755 --- a/resources/views/hardware/bulk.blade.php +++ b/resources/views/hardware/bulk.blade.php @@ -47,7 +47,7 @@
@@ -66,7 +66,7 @@
@@ -85,7 +85,7 @@
@@ -103,7 +103,7 @@
@@ -112,7 +112,7 @@
@@ -215,7 +215,7 @@
diff --git a/resources/views/livewire/category-edit-form.blade.php b/resources/views/livewire/category-edit-form.blade.php index cb80eb45d3..82dbf57e85 100644 --- a/resources/views/livewire/category-edit-form.blade.php +++ b/resources/views/livewire/category-edit-form.blade.php @@ -3,7 +3,12 @@
- {{ Form::textarea('eula_text', null, ['wire:model.live' => 'eulaText', 'class' => 'form-control', 'aria-label'=>'eula_text', 'disabled' => $this->eulaTextDisabled]) }} +

{!! trans('admin/categories/general.eula_text_help') !!}

{!! trans('admin/settings/general.eula_markdown') !!}

{!! $errors->first('eula_text', '') !!} diff --git a/resources/views/locations/edit.blade.php b/resources/views/locations/edit.blade.php index 4b4e655a52..004053d8ab 100755 --- a/resources/views/locations/edit.blade.php +++ b/resources/views/locations/edit.blade.php @@ -57,6 +57,23 @@
@endif + @include ('partials.forms.edit.image-upload', ['image_path' => app('locations_upload_path')]) + +
+ +
+ + {!! $errors->first('notes', '') !!} +
+
+ @stop diff --git a/resources/views/manufacturers/edit.blade.php b/resources/views/manufacturers/edit.blade.php index b5429e5f34..000fd3a8f6 100755 --- a/resources/views/manufacturers/edit.blade.php +++ b/resources/views/manufacturers/edit.blade.php @@ -63,6 +63,21 @@ @include ('partials.forms.edit.image-upload', ['image_path' => app('manufacturers_upload_path')]) +
+ +
+ + {!! $errors->first('notes', '') !!} +
+
+ @stop diff --git a/resources/views/modals/upload-file.blade.php b/resources/views/modals/upload-file.blade.php index c5816bf175..491eca2721 100644 --- a/resources/views/modals/upload-file.blade.php +++ b/resources/views/modals/upload-file.blade.php @@ -31,7 +31,13 @@
- {{ Form::textarea('notes', old('notes', old('notes')), ['class' => 'form-control','placeholder' => 'Notes (Optional)', 'rows'=>3, 'aria-label' => 'file']) }} +
diff --git a/resources/views/partials/forms/edit/notes.blade.php b/resources/views/partials/forms/edit/notes.blade.php index f6b08ea1aa..5f82616c2c 100644 --- a/resources/views/partials/forms/edit/notes.blade.php +++ b/resources/views/partials/forms/edit/notes.blade.php @@ -1,6 +1,6 @@
- +
{!! $errors->first('notes', '') !!} diff --git a/resources/views/settings/branding.blade.php b/resources/views/settings/branding.blade.php index ee31677bc0..a4d753913b 100644 --- a/resources/views/settings/branding.blade.php +++ b/resources/views/settings/branding.blade.php @@ -233,11 +233,22 @@
@if (config('app.lock_passwords')===true) - {{ Form::textarea('custom_css', old('custom_css', $setting->custom_css), array('class' => 'form-control','placeholder' => 'Add your custom CSS','disabled'=>'disabled', 'aria-label'=>'custom_css')) }} + {!! $errors->first('custom_css', '') !!}

{{ trans('general.feature_disabled') }}

@else - {{ Form::textarea('custom_css', old('custom_css', $setting->custom_css), array('class' => 'form-control','placeholder' => 'Add your custom CSS', 'aria-label'=>'custom_css')) }} + {!! $errors->first('custom_css', '') !!} @endif

{!! trans('admin/settings/general.custom_css_help') !!}

@@ -289,10 +300,21 @@
@if (config('app.lock_passwords')===true) - {{ Form::textarea('footer_text', old('footer_text', $setting->footer_text), array('class' => 'form-control', 'rows' => '4', 'placeholder' => 'Optional footer text','disabled'=>'disabled')) }} +

{{ trans('general.feature_disabled') }}

@else - {{ Form::textarea('footer_text', old('footer_text', $setting->footer_text), array('class' => 'form-control','rows' => '4','placeholder' => 'Optional footer text')) }} + @endif

{!! trans('admin/settings/general.footer_text_help') !!}

{!! $errors->first('footer_text', '') !!} diff --git a/resources/views/settings/general.blade.php b/resources/views/settings/general.blade.php index be19a9ee30..da3aefe689 100644 --- a/resources/views/settings/general.blade.php +++ b/resources/views/settings/general.blade.php @@ -208,7 +208,11 @@
- {{ Form::textarea('default_eula_text', old('default_eula_text', $setting->default_eula_text), array('class' => 'form-control','placeholder' => 'Add your default EULA text')) }} + {!! $errors->first('default_eula_text', '') !!}

{{ trans('admin/settings/general.default_eula_help_text') }}

{!! trans('admin/settings/general.eula_markdown') !!}

diff --git a/resources/views/settings/ldap.blade.php b/resources/views/settings/ldap.blade.php index 86a091252f..9f635bc3fd 100644 --- a/resources/views/settings/ldap.blade.php +++ b/resources/views/settings/ldap.blade.php @@ -174,7 +174,11 @@ {{ Form::label('ldap_client_tls_key', trans('admin/settings/general.ldap_client_tls_key')) }}
- {{ Form::textarea('ldap_client_tls_key', old('ldap_client_tls_key', $setting->ldap_client_tls_key), ['class' => 'form-control','placeholder' => trans('general.example') .'-----BEGIN RSA PRIVATE KEY-----'."\r\n1234567890\r\n-----END RSA PRIVATE KEY-----"]) }} + @error('ldap_client_tls_key') @@ -197,7 +201,11 @@ {{ Form::label('ldap_client_tls_cert', trans('admin/settings/general.ldap_client_tls_cert')) }}
- {{ Form::textarea('ldap_client_tls_cert', old('ldap_client_tls_cert', $setting->ldap_client_tls_cert), ['class' => 'form-control','placeholder' => trans('general.example') .'-----BEGIN CERTIFICATE-----'."\r\n1234567890\r\n-----END CERTIFICATE-----"]) }} +

{{ trans('admin/settings/general.ldap_client_tls_cert_help') }}

@error('ldap_client_tls_cert') diff --git a/resources/views/settings/saml.blade.php b/resources/views/settings/saml.blade.php index bc3f7b11a5..a3a116da78 100644 --- a/resources/views/settings/saml.blade.php +++ b/resources/views/settings/saml.blade.php @@ -82,8 +82,13 @@
@if (!empty($setting->saml_sp_x509cert)) - - {{ Form::textarea('saml_sp_x509cert', $setting->saml_sp_x509cert, ['class' => 'form-control', 'wrap' => 'off', 'readonly']) }} + +
@endif @@ -106,7 +111,12 @@
- {{ Form::textarea('saml_idp_metadata', old('saml_idp_metadata', $setting->saml_idp_metadata), ['class' => 'form-control','placeholder' => 'https://example.com/idp/metadata', 'wrap' => 'off', $setting->demoMode]) }} + {!! $errors->first('saml_idp_metadata', '') !!}
{{ trans('admin/settings/general.saml_custom_settings') }}
- {{ Form::textarea('saml_custom_settings', old('saml_custom_settings', $setting->saml_custom_settings), ['class' => 'form-control','placeholder' => 'example.option=false sp_x509cert=file:///... sp_private_key=file:///', 'wrap' => 'off', $setting->demoMode]) }} +

{{ trans('admin/settings/general.saml_custom_settings_help') }}

{!! $errors->first('saml_custom_settings', '') !!}
diff --git a/tests/Feature/Categories/Api/CreateCategoriesTest.php b/tests/Feature/Categories/Api/CreateCategoriesTest.php index fc464242af..2a4a0661a6 100644 --- a/tests/Feature/Categories/Api/CreateCategoriesTest.php +++ b/tests/Feature/Categories/Api/CreateCategoriesTest.php @@ -27,6 +27,7 @@ class CreateCategoriesTest extends TestCase 'name' => 'Test Category', 'eula_text' => 'Test EULA', 'category_type' => 'accessory', + 'notes' => 'Test Note', ]) ->assertOk() ->assertStatusMessageIs('success') @@ -38,6 +39,7 @@ class CreateCategoriesTest extends TestCase $category = Category::find($response['payload']['id']); $this->assertEquals('Test Category', $category->name); $this->assertEquals('Test EULA', $category->eula_text); + $this->assertEquals('Test Note', $category->notes); $this->assertEquals('accessory', $category->category_type); } diff --git a/tests/Feature/Categories/Api/UpdateCategoriesTest.php b/tests/Feature/Categories/Api/UpdateCategoriesTest.php index 1a784c1179..6d6bc8da10 100644 --- a/tests/Feature/Categories/Api/UpdateCategoriesTest.php +++ b/tests/Feature/Categories/Api/UpdateCategoriesTest.php @@ -17,6 +17,7 @@ class UpdateCategoriesTest extends TestCase ->patchJson(route('api.categories.update', $category), [ 'name' => 'Test Category', 'eula_text' => 'Test EULA', + 'notes' => 'Test Note', ]) ->assertOk() ->assertStatusMessageIs('success') @@ -27,6 +28,7 @@ class UpdateCategoriesTest extends TestCase $category->refresh(); $this->assertEquals('Test Category', $category->name, 'Name was not updated'); $this->assertEquals('Test EULA', $category->eula_text, 'EULA was not updated'); + $this->assertEquals('Test Note', $category->notes, 'Note was not updated'); } @@ -39,6 +41,7 @@ class UpdateCategoriesTest extends TestCase 'name' => 'Test Category', 'eula_text' => 'Test EULA', 'category_type' => 'accessory', + 'note' => 'Test Note', ]) ->assertOk() ->assertStatusMessageIs('error') @@ -48,6 +51,7 @@ class UpdateCategoriesTest extends TestCase $category->refresh(); $this->assertNotEquals('Test Category', $category->name, 'Name was not updated'); $this->assertNotEquals('Test EULA', $category->eula_text, 'EULA was not updated'); + $this->assertNotEquals('Test Note', $category->notes, 'Note was not updated'); $this->assertNotEquals('accessory', $category->category_type, 'EULA was not updated'); } diff --git a/tests/Feature/Categories/Ui/CreateCategoriesTest.php b/tests/Feature/Categories/Ui/CreateCategoriesTest.php index 45e821d9d9..694b61c613 100644 --- a/tests/Feature/Categories/Ui/CreateCategoriesTest.php +++ b/tests/Feature/Categories/Ui/CreateCategoriesTest.php @@ -33,11 +33,12 @@ class CreateCategoriesTest extends TestCase $this->actingAs(User::factory()->superuser()->create()) ->post(route('categories.store'), [ 'name' => 'Test Category', - 'category_type' => 'asset' + 'category_type' => 'asset', + 'notes' => 'Test Note', ]) ->assertRedirect(route('categories.index')); - $this->assertTrue(Category::where('name', 'Test Category')->exists()); + $this->assertTrue(Category::where('name', 'Test Category')->where('notes', 'Test Note')->exists()); } public function testUserCannotCreateCategoriesWithInvalidType() @@ -48,7 +49,7 @@ class CreateCategoriesTest extends TestCase ->from(route('categories.create')) ->post(route('categories.store'), [ 'name' => 'Test Category', - 'category_type' => 'invalid' + 'category_type' => 'invalid', ]) ->assertRedirect(route('categories.create')); diff --git a/tests/Feature/Categories/Ui/UpdateCategoriesTest.php b/tests/Feature/Categories/Ui/UpdateCategoriesTest.php index 901b779582..7e61097793 100644 --- a/tests/Feature/Categories/Ui/UpdateCategoriesTest.php +++ b/tests/Feature/Categories/Ui/UpdateCategoriesTest.php @@ -32,7 +32,7 @@ class UpdateCategoriesTest extends TestCase $this->actingAs(User::factory()->superuser()->create()) ->post(route('categories.store'), [ 'name' => 'Test Category', - 'category_type' => 'asset' + 'category_type' => 'asset', ]) ->assertStatus(302) ->assertSessionHasNoErrors() @@ -49,13 +49,14 @@ class UpdateCategoriesTest extends TestCase $response = $this->actingAs(User::factory()->superuser()->create()) ->put(route('categories.update', ['category' => $category]), [ 'name' => 'Test Category Edited', + 'notes' => 'Test Note Edited', ]) ->assertStatus(302) ->assertSessionHasNoErrors() ->assertRedirect(route('categories.index')); $this->followRedirects($response)->assertSee('Success'); - $this->assertTrue(Category::where('name', 'Test Category Edited')->exists()); + $this->assertTrue(Category::where('name', 'Test Category Edited')->where('notes', 'Test Note Edited')->exists()); } @@ -69,13 +70,14 @@ class UpdateCategoriesTest extends TestCase ->put(route('categories.update', ['category' => $category]), [ 'name' => 'Test Category Edited', 'category_type' => 'accessory', + 'notes' => 'Test Note Edited', ]) ->assertSessionHasNoErrors() ->assertStatus(302) ->assertRedirect(route('categories.index')); $this->followRedirects($response)->assertSee('Success'); - $this->assertTrue(Category::where('name', 'Test Category Edited')->exists()); + $this->assertTrue(Category::where('name', 'Test Category Edited')->where('notes', 'Test Note Edited')->exists()); } @@ -89,6 +91,7 @@ class UpdateCategoriesTest extends TestCase ->put(route('categories.update', ['category' => $category]), [ 'name' => 'Test Category Edited', 'category_type' => 'accessory', + 'notes' => 'Test Note Edited', ]) ->assertSessionHasErrors(['category_type']) ->assertInvalid(['category_type']) @@ -96,7 +99,7 @@ class UpdateCategoriesTest extends TestCase ->assertRedirect(route('categories.edit', ['category' => $category->id])); $this->followRedirects($response)->assertSee(trans('general.error')); - $this->assertFalse(Category::where('name', 'Test Category Edited')->exists()); + $this->assertFalse(Category::where('name', 'Test Category Edited')->where('notes', 'Test Note Edited')->exists()); } diff --git a/tests/Feature/Departments/Api/CreateDepartmentsTest.php b/tests/Feature/Departments/Api/CreateDepartmentsTest.php index a8725c5ff2..e0f975dd7f 100644 --- a/tests/Feature/Departments/Api/CreateDepartmentsTest.php +++ b/tests/Feature/Departments/Api/CreateDepartmentsTest.php @@ -20,4 +20,23 @@ class CreateDepartmentsTest extends TestCase ->assertForbidden(); } + public function testCanCreateDepartment() + { + $response = $this->actingAsForApi(User::factory()->superuser()->create()) + ->postJson(route('api.departments.store'), [ + 'name' => 'Test Department', + 'notes' => 'Test Note', + ]) + ->assertOk() + ->assertStatusMessageIs('success') + ->assertStatus(200) + ->json(); + + $this->assertTrue(Department::where('name', 'Test Department')->exists()); + + $department = Department::find($response['payload']['id']); + $this->assertEquals('Test Department', $department->name); + $this->assertEquals('Test Note', $department->notes); + } + } diff --git a/tests/Feature/Departments/Api/UpdateDepartmentsTest.php b/tests/Feature/Departments/Api/UpdateDepartmentsTest.php index 2a6401e7f1..b4eb38301a 100644 --- a/tests/Feature/Departments/Api/UpdateDepartmentsTest.php +++ b/tests/Feature/Departments/Api/UpdateDepartmentsTest.php @@ -25,6 +25,7 @@ class UpdateDepartmentsTest extends TestCase $this->actingAsForApi(User::factory()->superuser()->create()) ->patchJson(route('api.departments.update', $department), [ 'name' => 'Test Department', + 'notes' => 'Test Note', ]) ->assertOk() ->assertStatusMessageIs('success') @@ -33,6 +34,7 @@ class UpdateDepartmentsTest extends TestCase $department->refresh(); $this->assertEquals('Test Department', $department->name, 'Name was not updated'); + $this->assertEquals('Test Note', $department->notes, 'Note was not updated'); } diff --git a/tests/Feature/Departments/Ui/CreateDepartmentsTest.php b/tests/Feature/Departments/Ui/CreateDepartmentsTest.php index 08dc12ba09..f20a2c7b6a 100644 --- a/tests/Feature/Departments/Ui/CreateDepartmentsTest.php +++ b/tests/Feature/Departments/Ui/CreateDepartmentsTest.php @@ -34,11 +34,12 @@ class CreateDepartmentsTest extends TestCase $this->actingAs(User::factory()->superuser()->create()) ->post(route('departments.store'), [ 'name' => 'Test Department', - 'company_id' => Company::factory()->create()->id + 'company_id' => Company::factory()->create()->id, + 'notes' => 'Test Note', ]) ->assertRedirect(route('departments.index')); - $this->assertTrue(Department::where('name', 'Test Department')->exists()); + $this->assertTrue(Department::where('name', 'Test Department')->where('notes', 'Test Note')->exists()); } diff --git a/tests/Feature/Departments/Ui/UpdateDepartmentsTest.php b/tests/Feature/Departments/Ui/UpdateDepartmentsTest.php index 71f7cfe477..bb5fc27e14 100644 --- a/tests/Feature/Departments/Ui/UpdateDepartmentsTest.php +++ b/tests/Feature/Departments/Ui/UpdateDepartmentsTest.php @@ -34,13 +34,14 @@ class UpdateDepartmentsTest extends TestCase $response = $this->actingAs(User::factory()->superuser()->create()) ->put(route('departments.update', ['department' => $department]), [ 'name' => 'Test Department Edited', + 'notes' => 'Test Note Edited', ]) ->assertStatus(302) ->assertSessionHasNoErrors() ->assertRedirect(route('departments.index')); $this->followRedirects($response)->assertSee('Success'); - $this->assertTrue(Department::where('name', 'Test Department Edited')->exists()); + $this->assertTrue(Department::where('name', 'Test Department Edited')->where('notes', 'Test Note Edited')->exists()); } diff --git a/tests/Feature/Groups/Api/StoreGroupTest.php b/tests/Feature/Groups/Api/StoreGroupTest.php index ebcbff71c5..484c921a6c 100644 --- a/tests/Feature/Groups/Api/StoreGroupTest.php +++ b/tests/Feature/Groups/Api/StoreGroupTest.php @@ -21,6 +21,7 @@ class StoreGroupTest extends TestCase $this->actingAsForApi(User::factory()->superuser()->create()) ->postJson(route('api.groups.store'), [ 'name' => 'My Awesome Group', + 'notes' => 'My Awesome Note', 'permissions' => [ 'admin' => '1', 'import' => '1', @@ -29,7 +30,7 @@ class StoreGroupTest extends TestCase ]) ->assertOk(); - $group = Group::where('name', 'My Awesome Group')->first(); + $group = Group::where('name', 'My Awesome Group')->where('notes', 'My Awesome Note')->first(); $this->assertNotNull($group); $this->assertEquals('1', $group->decodePermissions()['admin']); diff --git a/tests/Feature/Groups/Ui/CreateGroupTest.php b/tests/Feature/Groups/Ui/CreateGroupTest.php index 56b3a76053..796905c50f 100644 --- a/tests/Feature/Groups/Ui/CreateGroupTest.php +++ b/tests/Feature/Groups/Ui/CreateGroupTest.php @@ -2,6 +2,7 @@ namespace Tests\Feature\Groups\Ui; +use App\Models\Group; use App\Models\User; use Tests\TestCase; @@ -13,4 +14,18 @@ class CreateGroupTest extends TestCase ->get(route('groups.create')) ->assertOk(); } + + public function testUserCanCreateGroup() + { + $this->assertFalse(Group::where('name', 'Test Group')->exists()); + + $this->actingAs(User::factory()->superuser()->create()) + ->post(route('groups.store'), [ + 'name' => 'Test Group', + 'notes' => 'Test Note', + ]) + ->assertRedirect(route('groups.index')); + + $this->assertTrue(Group::where('name', 'Test Group')->where('notes', 'Test Note')->exists()); + } } diff --git a/tests/Feature/Groups/Ui/UpdateGroupTest.php b/tests/Feature/Groups/Ui/UpdateGroupTest.php index c68d7cb84b..edb2368726 100644 --- a/tests/Feature/Groups/Ui/UpdateGroupTest.php +++ b/tests/Feature/Groups/Ui/UpdateGroupTest.php @@ -14,4 +14,22 @@ class UpdateGroupTest extends TestCase ->get(route('groups.edit', Group::factory()->create()->id)) ->assertOk(); } + + public function testUserCanEditGroups() + { + $group = Group::factory()->create(['name' => 'Test Group']); + $this->assertTrue(Group::where('name', 'Test Group')->exists()); + + $response = $this->actingAs(User::factory()->superuser()->create()) + ->put(route('groups.update', ['group' => $group]), [ + 'name' => 'Test Group Edited', + 'notes' => 'Test Note Edited', + ]) + ->assertStatus(302) + ->assertSessionHasNoErrors() + ->assertRedirect(route('groups.index')); + + $this->followRedirects($response)->assertSee('Success'); + $this->assertTrue(Group::where('name', 'Test Group Edited')->where('notes', 'Test Note Edited')->exists()); + } } diff --git a/tests/Feature/Locations/Api/CreateLocationsTest.php b/tests/Feature/Locations/Api/CreateLocationsTest.php index 171508b725..0a75517f31 100644 --- a/tests/Feature/Locations/Api/CreateLocationsTest.php +++ b/tests/Feature/Locations/Api/CreateLocationsTest.php @@ -16,6 +16,26 @@ class CreateLocationsTest extends TestCase ->assertForbidden(); } + + public function testCanCreateLocation() + { + $response = $this->actingAsForApi(User::factory()->superuser()->create()) + ->postJson(route('api.locations.store'), [ + 'name' => 'Test Location', + 'notes' => 'Test Note', + ]) + ->assertOk() + ->assertStatusMessageIs('success') + ->assertStatus(200) + ->json(); + + $this->assertTrue(Location::where('name', 'Test Location')->exists()); + + $department = Location::find($response['payload']['id']); + $this->assertEquals('Test Location', $department->name); + $this->assertEquals('Test Note', $department->notes); + } + public function testCannotCreateNewLocationsWithTheSameName() { $location = Location::factory()->create(); diff --git a/tests/Feature/Locations/Api/UpdateLocationsTest.php b/tests/Feature/Locations/Api/UpdateLocationsTest.php index a3dd8c228c..a169ba87bf 100644 --- a/tests/Feature/Locations/Api/UpdateLocationsTest.php +++ b/tests/Feature/Locations/Api/UpdateLocationsTest.php @@ -22,7 +22,8 @@ class UpdateLocationsTest extends TestCase $this->actingAsForApi(User::factory()->superuser()->create()) ->patchJson(route('api.locations.update', $location), [ - 'name' => 'Test Location', + 'name' => 'Test Updated Location', + 'notes' => 'Test Updated Note', ]) ->assertOk() ->assertStatusMessageIs('success') @@ -30,7 +31,8 @@ class UpdateLocationsTest extends TestCase ->json(); $location->refresh(); - $this->assertEquals('Test Location', $location->name, 'Name was not updated'); + $this->assertEquals('Test Updated Location', $location->name, 'Name was not updated'); + $this->assertEquals('Test Updated Note', $location->notes, 'Note was not updated'); } diff --git a/tests/Feature/Locations/Ui/CreateLocationsTest.php b/tests/Feature/Locations/Ui/CreateLocationsTest.php index 2e2e1e0aa9..794ee06c67 100644 --- a/tests/Feature/Locations/Ui/CreateLocationsTest.php +++ b/tests/Feature/Locations/Ui/CreateLocationsTest.php @@ -33,11 +33,11 @@ class CreateLocationsTest extends TestCase $this->actingAs(User::factory()->superuser()->create()) ->post(route('locations.store'), [ 'name' => 'Test Location', - 'company_id' => Company::factory()->create()->id + 'notes' => 'Test Note', ]) ->assertRedirect(route('locations.index')); - $this->assertTrue(Location::where('name', 'Test Location')->exists()); + $this->assertTrue(Location::where('name', 'Test Location')->where('notes', 'Test Note')->exists()); } public function testUserCannotCreateLocationsWithInvalidParent() diff --git a/tests/Feature/Locations/Ui/UpdateLocationsTest.php b/tests/Feature/Locations/Ui/UpdateLocationsTest.php index 6cead815bc..c38ee25f8e 100644 --- a/tests/Feature/Locations/Ui/UpdateLocationsTest.php +++ b/tests/Feature/Locations/Ui/UpdateLocationsTest.php @@ -33,13 +33,14 @@ class UpdateLocationsTest extends TestCase $response = $this->actingAs(User::factory()->superuser()->create()) ->put(route('locations.update', ['location' => $location]), [ 'name' => 'Test Location Edited', + 'notes' => 'Test Note Edited', ]) ->assertStatus(302) ->assertSessionHasNoErrors() ->assertRedirect(route('locations.index')); $this->followRedirects($response)->assertSee('Success'); - $this->assertTrue(Location::where('name', 'Test Location Edited')->exists()); + $this->assertTrue(Location::where('name', 'Test Location Edited')->where('notes', 'Test Note Edited')->exists()); } public function testUserCannotEditLocationsToMakeThemTheirOwnParent() diff --git a/tests/Feature/Manufacturers/Api/CreateManufacturersTest.php b/tests/Feature/Manufacturers/Api/CreateManufacturersTest.php new file mode 100644 index 0000000000..9dc953148e --- /dev/null +++ b/tests/Feature/Manufacturers/Api/CreateManufacturersTest.php @@ -0,0 +1,39 @@ +actingAsForApi(User::factory()->create()) + ->postJson(route('api.departments.store')) + ->assertForbidden(); + } + + public function testCanCreateManufacturer() + { + $response = $this->actingAsForApi(User::factory()->superuser()->create()) + ->postJson(route('api.manufacturers.store'), [ + 'name' => 'Test Manufacturer', + 'notes' => 'Test Note', + ]) + ->assertOk() + ->assertStatusMessageIs('success') + ->assertStatus(200) + ->json(); + + $this->assertTrue(Manufacturer::where('name', 'Test Manufacturer')->where('notes', 'Test Note')->exists()); + + $manufacturer = Manufacturer::find($response['payload']['id']); + $this->assertEquals('Test Manufacturer', $manufacturer->name); + $this->assertEquals('Test Note', $manufacturer->notes); + } + +} diff --git a/tests/Feature/Manufacturers/Api/UpdateManufacturersTest.php b/tests/Feature/Manufacturers/Api/UpdateManufacturersTest.php new file mode 100644 index 0000000000..d3ab461b4f --- /dev/null +++ b/tests/Feature/Manufacturers/Api/UpdateManufacturersTest.php @@ -0,0 +1,50 @@ +actingAs(User::factory()->create()) + ->post(route('manufacturers.store'), [ + 'name' => 'Test Manufacturer', + ]) + ->assertStatus(403) + ->assertForbidden(); + } + + public function testPageRenders() + { + $this->actingAs(User::factory()->superuser()->create()) + ->get(route('manufacturers.edit', Manufacturer::factory()->create()->id)) + ->assertOk(); + } + + public function testUserCanEditManufacturers() + { + $department = Manufacturer::factory()->create(['name' => 'Test Manufacturer']); + $this->assertTrue(Manufacturer::where('name', 'Test Manufacturer')->exists()); + + $response = $this->actingAs(User::factory()->superuser()->create()) + ->put(route('manufacturers.update', ['manufacturer' => $department]), [ + 'name' => 'Test Manufacturer Edited', + 'notes' => 'Test Note Edited', + ]) + ->assertStatus(302) + ->assertSessionHasNoErrors() + ->assertRedirect(route('manufacturers.index')); + + $this->followRedirects($response)->assertSee('Success'); + $this->assertTrue(Manufacturer::where('name', 'Test Manufacturer Edited')->where('notes', 'Test Note Edited')->exists()); + + } + + + +} diff --git a/tests/Feature/Manufacturers/Ui/CreateManufacturerTest.php b/tests/Feature/Manufacturers/Ui/CreateManufacturerTest.php index 133b271ea3..4eb9d4fb7e 100644 --- a/tests/Feature/Manufacturers/Ui/CreateManufacturerTest.php +++ b/tests/Feature/Manufacturers/Ui/CreateManufacturerTest.php @@ -3,6 +3,7 @@ namespace Tests\Feature\Manufacturers\Ui; use App\Models\User; +use App\Models\Manufacturer; use Tests\TestCase; class CreateManufacturerTest extends TestCase @@ -13,4 +14,19 @@ class CreateManufacturerTest extends TestCase ->get(route('manufacturers.create')) ->assertOk(); } + + public function testUserCanCreateManufacturer() + { + $this->assertFalse(Manufacturer::where('name', 'Test Manufacturer')->exists()); + + $this->actingAs(User::factory()->superuser()->create()) + ->post(route('manufacturers.store'), [ + 'name' => 'Test Manufacturer', + 'notes' => 'Test Note', + ]) + ->assertRedirect(route('manufacturers.index')); + + $this->assertTrue(Manufacturer::where('name', 'Test Manufacturer')->where('notes', 'Test Note')->exists()); + } + } diff --git a/tests/Feature/Manufacturers/Ui/UpdateManufacturerTest.php b/tests/Feature/Manufacturers/Ui/UpdateManufacturerTest.php index e2f7724fa3..398b7fe239 100644 --- a/tests/Feature/Manufacturers/Ui/UpdateManufacturerTest.php +++ b/tests/Feature/Manufacturers/Ui/UpdateManufacturerTest.php @@ -14,4 +14,23 @@ class UpdateManufacturerTest extends TestCase ->get(route('manufacturers.edit', Manufacturer::factory()->create()->id)) ->assertOk(); } + + public function testUserCanEditManufacturers() + { + $manufacturer = Manufacturer::factory()->create(['name' => 'Test Manufacturer']); + $this->assertTrue(Manufacturer::where('name', 'Test Manufacturer')->exists()); + + $response = $this->actingAs(User::factory()->superuser()->create()) + ->put(route('manufacturers.update', ['manufacturer' => $manufacturer]), [ + 'name' => 'Test Manufacturer Edited', + 'notes' => 'Test Note Edited', + ]) + ->assertStatus(302) + ->assertSessionHasNoErrors() + ->assertRedirect(route('manufacturers.index')); + + $this->followRedirects($response)->assertSee('Success'); + $this->assertTrue(Manufacturer::where('name', 'Test Manufacturer Edited')->where('notes', 'Test Note Edited')->exists()); + } + } diff --git a/tests/Feature/Notifications/Email/ExpiringAlertsNotificationTest.php b/tests/Feature/Notifications/Email/ExpiringAlertsNotificationTest.php new file mode 100644 index 0000000000..220f6543c8 --- /dev/null +++ b/tests/Feature/Notifications/Email/ExpiringAlertsNotificationTest.php @@ -0,0 +1,91 @@ +markIncompleteIfSqlite(); + Mail::fake(); + + $this->settings->enableAlertEmail('admin@example.com'); + $this->settings->setAlertInterval(30); + + $alert_email = Setting::first()->alert_email; + + $expiringAsset = Asset::factory()->create([ + 'purchase_date' => now()->subMonths(11)->format('Y-m-d'), + 'warranty_months' => 12, + 'archived' => 0, + 'deleted_at' => null, + ]); + + $expiredAsset = Asset::factory()->create([ + 'purchase_date' => now()->subMonths(13)->format('Y-m-d'), + 'warranty_months' => 12, + 'archived' => 0, + 'deleted_at' => null, + ]); + $notExpiringAsset = Asset::factory()->create([ + 'purchase_date' => now()->subMonths(10)->format('Y-m-d'), + 'warranty_months' => 12, + 'archived' => 0, + 'deleted_at' => null, + ]); + + $this->artisan('snipeit:expiring-alerts')->assertExitCode(0); + + Mail::assertSent(ExpiringAssetsMail::class, function($mail) use ($alert_email, $expiringAsset) { + return $mail->hasTo($alert_email) && $mail->assets->contains($expiringAsset); + }); + + Mail::assertNotSent(ExpiringAssetsMail::class, function($mail) use ($expiredAsset, $notExpiringAsset) { + return $mail->assets->contains($expiredAsset) || $mail->assets->contains($notExpiringAsset); + }); + } + + public function testExpiringLicensesEmailNotification() + { + $this->markIncompleteIfSqlite(); + Mail::fake(); + $this->settings->enableAlertEmail('admin@example.com'); + $this->settings->setAlertInterval(60); + + $alert_email = Setting::first()->alert_email; + + $expiringLicense = License::factory()->create([ + 'expiration_date' => now()->addDays(30)->format('Y-m-d'), + 'deleted_at' => null, + ]); + + $expiredLicense = License::factory()->create([ + 'expiration_date' => now()->subDays(10)->format('Y-m-d'), + 'deleted_at' => null, + ]); + $notExpiringLicense = License::factory()->create([ + 'expiration_date' => now()->addMonths(3)->format('Y-m-d'), + 'deleted_at' => null, + ]); + + $this->artisan('snipeit:expiring-alerts')->assertExitCode(0); + + Mail::assertSent(ExpiringLicenseMail::class, function($mail) use ($alert_email, $expiringLicense) { + return $mail->hasTo($alert_email) && $mail->licenses->contains($expiringLicense); + }); + + Mail::assertNotSent(ExpiringLicenseMail::class, function($mail) use ($expiredLicense, $notExpiringLicense) { + return $mail->licenses->contains($expiredLicense) || $mail->licenses->contains($notExpiringLicense); + }); + } +} \ No newline at end of file diff --git a/tests/Support/Settings.php b/tests/Support/Settings.php index e171c0ab95..09d40974c1 100644 --- a/tests/Support/Settings.php +++ b/tests/Support/Settings.php @@ -21,12 +21,23 @@ class Settings public function enableAlertEmail(string $email = 'notifications@afcrichmond.com'): Settings { - return $this->update(['alert_email' => $email]); + return $this->update([ + 'alert_email' => $email, + 'alerts_enabled' => 1, + ]); + } + public function setAlertInterval(int $days): Settings + { + return $this->update([ + 'alert_threshold' => $days, + ]); } - public function disableAlertEmail(): Settings { - return $this->update(['alert_email' => null]); + return $this->update([ + 'alert_email' => null, + 'alerts_enabled' => 0, + ]); } public function enableMultipleFullCompanySupport(): Settings diff --git a/tests/Unit/LdapTest.php b/tests/Unit/LdapTest.php index f3bc521635..a492b1efbc 100644 --- a/tests/Unit/LdapTest.php +++ b/tests/Unit/LdapTest.php @@ -2,6 +2,7 @@ namespace Tests\Unit; +use App\Models\Setting; use PHPUnit\Framework\Attributes\Group; use App\Models\Ldap; use Tests\TestCase; @@ -206,4 +207,30 @@ class LdapTest extends TestCase $this->assertEqualsCanonicalizing(["count" => 2], $results); } + public function testNonexistentTLSFile() + { + $this->settings->enableLdap()->set(['ldap_client_tls_cert' => 'SAMPLE CERT TEXT']); + $certfile = Setting::get_client_side_cert_path(); + $this->assertStringEqualsFile($certfile, 'SAMPLE CERT TEXT'); + } + + public function testStaleTLSFile() + { + file_put_contents(Setting::get_client_side_cert_path(), 'STALE CERT FILE'); + sleep(1); // FIXME - this is going to slow down tests + $this->settings->enableLdap()->set(['ldap_client_tls_cert' => 'SAMPLE CERT TEXT']); + $certfile = Setting::get_client_side_cert_path(); + $this->assertStringEqualsFile($certfile, 'SAMPLE CERT TEXT'); + } + + public function testFreshTLSFile() + { + $this->settings->enableLdap()->set(['ldap_client_tls_cert' => 'SAMPLE CERT TEXT']); + $client_side_cert_path = Setting::get_client_side_cert_path(); + file_put_contents($client_side_cert_path, 'WEIRDLY UPDATED CERT FILE'); + //the system should respect our cache-file, since the settings haven't been updated + $possibly_recached_cert_file = Setting::get_client_side_cert_path(); //this should *NOT* re-cache from the Settings + $this->assertStringEqualsFile($possibly_recached_cert_file, 'WEIRDLY UPDATED CERT FILE'); + } + }