Compare commits

...

3123 Commits

Author SHA1 Message Date
snipe b540a5afc0 Fixed #19006 - update null location 2026-05-14 15:58:10 +01:00
snipe 663bab1f9d Merge pull request #19030 from grokability/purchase-cost-fix
Fixed #19029 - switch back to text for purchase cost
2026-05-14 15:56:25 +01:00
snipe 8b1e312292 Normalize purchase_cost 2026-05-14 15:33:42 +01:00
snipe 9004211a59 Added text string 2026-05-14 15:04:48 +01:00
snipe 053eb91457 Update bulk asset controller 2026-05-14 15:03:55 +01:00
snipe 3810513224 Updated HTML fields back to text from number 2026-05-14 14:30:09 +01:00
snipe e50e0f0e34 Updated tests 2026-05-14 14:29:51 +01:00
snipe cdf73f9c89 Merge pull request #19028 from grokability/move-and-rename-trait
Move and rename CheckInOutRequest to CheckInOutTrait
2026-05-14 13:13:50 +01:00
snipe bc808cbe46 Pint 2026-05-14 12:50:31 +01:00
snipe fdc65fb1b2 Moved and renamed CheckInOutRequest 2026-05-14 12:50:23 +01:00
snipe 3db9a15dd3 Merge pull request #19027 from grokability/add-fields-to-user-export
Fixed #18659 - added more data to user export
2026-05-14 12:32:24 +01:00
snipe 42bf43d68d Fixed #18659 - added more data to user export 2026-05-14 12:24:08 +01:00
snipe 4548ed8a45 Fixed flappy test 2026-05-14 11:45:20 +01:00
snipe 407e2d0246 Merge pull request #19026 from grokability/scim-typo
Fixed SCIMConfig typo "string_starts_with"
2026-05-14 11:12:52 +01:00
snipe 2af7367480 Pint 2026-05-14 11:00:58 +01:00
snipe 29b9a78f54 Fixed typo “string_starts_with” 2026-05-14 11:00:25 +01:00
snipe 382a164b9d Updated composer.lock 2026-05-14 10:40:41 +01:00
snipe 9216a7550f Merge pull request #19019 from grokability/adding-normal-pagination-to-api-responses
Added page number support in API, added `per_page`, `total_pages`, and `current_page` to API response
2026-05-13 22:16:40 +01:00
snipe 4f9ba7c6cc Updated to use fullUrlWithQuery 2026-05-13 22:08:27 +01:00
snipe afb7c69ac3 Merge pull request #19021 from marcusmoore/fixes/21081-missing-asset-in-maintenance
Fixed asset maintenances page not rendering with missing asset
2026-05-13 22:00:24 +01:00
snipe 5f232c0584 Merge pull request #19024 from grokability/api-disallow-own-priv-changes
Tighten permission changes and UI, fixed #18831
2026-05-13 21:59:15 +01:00
snipe ed931d497a Hide admin/superadmin sections if the user is not an admin/superadmin 2026-05-13 21:45:56 +01:00
snipe 59278c3f70 Missed a spot 2026-05-13 21:39:46 +01:00
snipe 179d031bb2 Fixed #18831 - better spacing for buttons 2026-05-13 21:32:36 +01:00
snipe dc1410aa70 Tweaked logic around messaging 2026-05-13 21:27:25 +01:00
snipe 0f595a8854 Updated preserve permissions action 2026-05-13 21:06:04 +01:00
snipe 70e1dcf1b4 Disallow self-editing of privs on user model 2026-05-13 20:06:51 +01:00
snipe 780e3e1cd9 Merge pull request #19023 from marcusmoore/fixes/users-export
Fixed duplicate headers in users csv export
2026-05-13 19:41:55 +01:00
Marcus Moore 339c93ebbf Add documentation for assertion 2026-05-13 11:27:26 -07:00
Marcus Moore b4bb1556be Add assertions 2026-05-13 11:26:04 -07:00
Marcus Moore ba96aa5a61 Write assertion implementation 2026-05-13 11:25:52 -07:00
snipe 2171556ec4 Merge pull request #19022 from marcusmoore/fixes/disable-debugbar-for-unaccepted-assets-report
Disabled debugbar on acceptance report
2026-05-13 19:18:53 +01:00
Marcus Moore 2d33368063 WIP: better assertions 2026-05-13 11:10:45 -07:00
Marcus Moore 93a2f74f9e Disable debugbar on acceptance report 2026-05-13 10:46:58 -07:00
Marcus Moore ee61084ac8 Ensure maintenance has asset before attempting to render 2026-05-13 10:11:50 -07:00
snipe 8d8a1889cd Drop the limit from the next/prev links unless they were specifically sent in the URL parameters 2026-05-13 17:17:14 +01:00
snipe f275cb6928 Pint 2026-05-13 17:10:41 +01:00
snipe db8de1f794 Codacy fixes 2026-05-13 17:10:34 +01:00
snipe d901e821cc Include next and previous urls in the payload 2026-05-13 16:55:55 +01:00
snipe 34a533b2d6 Added page number support in API, added per_page, total_pages, and current_page 2026-05-13 16:48:39 +01:00
snipe d3d37c70ab Merge pull request #19017 from grokability/FD-52058-importer-updated-at-timestamp
Fixed importer `created_at` timestamp getting weird on large imports
2026-05-13 12:18:01 +01:00
snipe 475e674fc6 Bumped laravel version in README 2026-05-13 12:17:44 +01:00
snipe 01436d0532 Import the model in test 2026-05-13 12:06:39 +01:00
snipe 96bf7d0c2b Fixed FD-52058 - Importer using wrong created_at date 2026-05-13 12:06:13 +01:00
snipe 529973aa77 Updated EULA PDF filename to include username 2026-05-13 10:32:17 +01:00
snipe f4cd090ac6 Merge pull request #19012 from marcusmoore/fixes/activity-report-link
Fixed anchor tag on report index page
2026-05-13 02:41:35 +01:00
Marcus Moore 6d5e68274d Only write headers once 2026-05-12 16:36:26 -07:00
Marcus Moore 3e002cb940 Implement test and remove trailing comma in group column 2026-05-12 16:33:53 -07:00
Marcus Moore b7ea9a959c Scaffold some tests 2026-05-12 16:25:53 -07:00
Marcus Moore dc3a16c437 Update test macros 2026-05-12 16:25:00 -07:00
Marcus Moore 608af84253 Fix anchor tag 2026-05-12 15:13:29 -07:00
snipe 161d7e1c2b Dev assets 2026-05-12 19:42:20 +01:00
snipe 8627032c4f Bumped version to 8.5.0 2026-05-12 19:41:10 +01:00
snipe 5bead4fbcc Pint :( 2026-05-12 19:30:54 +01:00
snipe ef44ba5f97 Updated languages 2026-05-12 19:29:57 +01:00
snipe 2dc0ec9e7e Bumped php_max_major_minor for new 8.5 support 2026-05-12 19:27:50 +01:00
snipe afd435e895 Bumped php max requirement 2026-05-12 15:23:15 +01:00
snipe 80d1bf6a7a Better manufacturer check again :( 2026-05-12 15:12:38 +01:00
snipe 737f3ef3db Skip lookup URL if manufacturer was deleted 2026-05-12 15:07:55 +01:00
snipe d179f47274 Merge pull request #19007 from uberbrady/reintroduce_scim_logging
Change branch of home-forked SCIM server to re-introduce logging
2026-05-12 14:51:11 +01:00
snipe 1832d95371 Merge pull request #19009 from grokability/bulk-delete-licenses
🎥 Added bulk deletion of licenses
2026-05-12 13:55:37 +01:00
snipe a614f986f0 Added test for the fix I made in the prior commit 2026-05-12 13:07:16 +01:00
snipe f398a59d26 Fixed bug on API delete 2026-05-12 13:05:15 +01:00
snipe c8bd104268 Added comment for clarity 2026-05-12 13:00:51 +01:00
snipe 7f01bd4c56 Merge pull request #19008 from uberbrady/more_exception_handling_in_scim
Widen exception scope in emails; similar treatment for phones
2026-05-12 12:57:06 +01:00
Brady Wetherington 6c3c7fdf49 Widen exception scope in emails; similar treatment for phones 2026-05-12 12:43:53 +01:00
snipe bdc8fc8d4a Eager load license seat relations to avoid n+1 2026-05-12 12:41:45 +01:00
snipe 41be127489 Added bulk license action 2026-05-12 12:41:30 +01:00
snipe fdfae9593d Use isDeletable for delete ability status 2026-05-12 12:41:08 +01:00
snipe 6a21eb53c9 Fixed return type 2026-05-12 12:40:29 +01:00
snipe efde2b4672 Added checknbox to presneter 2026-05-12 12:40:08 +01:00
snipe daaa26cbf4 Added new text strings 2026-05-12 12:34:40 +01:00
snipe 3e7441562c Added bulk action menu 2026-05-12 12:34:31 +01:00
snipe 7b53fa5245 Added bulk delete route 2026-05-12 12:34:16 +01:00
snipe d35d46f5b4 Added tests 2026-05-12 12:34:03 +01:00
Brady Wetherington f4772a9cad Change branch of home-forked SCIM server to re-introduce logging 2026-05-12 12:26:37 +01:00
snipe 4c1bb7e0ac Merge remote-tracking branch 'origin/master' into develop 2026-05-11 19:45:01 +01:00
snipe 762ea9b4db One more try I guess 2026-05-11 19:44:41 +01:00
snipe b16970a61e Merge pull request #18629 from Godmartinz/update-print-invtentory-view-with-assigned2assets
Update print inventory view with indirect assignments table
2026-05-11 18:27:25 +01:00
snipe dadb9bd81e Merge remote-tracking branch 'origin/develop' 2026-05-11 16:12:03 +01:00
snipe 13dc7de660 Add enter to submit advanced search modal 2026-05-11 16:11:51 +01:00
snipe 003ea36e18 Merge remote-tracking branch 'origin/develop' 2026-05-11 16:04:10 +01:00
snipe f4bd2a68c9 Fix for compound is:not_null 2026-05-11 16:03:59 +01:00
snipe be4e75d4f7 Merge remote-tracking branch 'origin/develop' 2026-05-11 15:25:56 +01:00
snipe 538c21ce1e Merge pull request #19002 from grokability/fixed-crash-on-checkout-outside-of-company-id
Fixed crash on checkout outside of company via API
2026-05-11 15:25:27 +01:00
snipe 626cd6cb2e Fixed #18989 - better wrapping for auth self.profile checks 2026-05-11 15:25:03 +01:00
snipe 2a56f6573d Wrap the checkout in a transaction and add tests 2026-05-11 15:07:25 +01:00
snipe 6ee2dc1cd6 Merge pull request #18998 from uberbrady/fix_scim_error_email
Don't 500 on malformed emails input
2026-05-11 14:59:56 +01:00
snipe 3fcde8bd16 Prevent crash when trying to check out a component from another company if FMCS is on 2026-05-11 14:43:54 +01:00
snipe e2ff7a7bc7 Merge pull request #19000 from grokability/reports-index
🎥 Added reports index
2026-05-11 14:37:14 +01:00
snipe c7efd16517 Fixed progressbar color 2026-05-11 14:25:25 +01:00
snipe f2907f04d9 Added nicer border 2026-05-11 14:19:10 +01:00
snipe 7d98c267d5 More formatting tweaks 2026-05-11 14:13:16 +01:00
snipe 5bc6330c13 Messed with the boxes 2026-05-11 14:05:11 +01:00
snipe 1706ed597d Updated text 2026-05-11 14:05:03 +01:00
snipe 6e9ba28ef7 Tightened up query string 2026-05-11 13:26:35 +01:00
snipe 554d1a44de More shifting 2026-05-11 13:21:33 +01:00
snipe c0a8f4c1a4 Include withrashed() 2026-05-11 13:19:49 +01:00
snipe 08be9aac6d Added users chart 2026-05-11 13:08:23 +01:00
Brady Wetherington a51b17fb53 Don't 500 on malformed emails input 2026-05-11 13:07:16 +01:00
snipe 66d5618d60 Fixed links in summary box 2026-05-11 12:59:53 +01:00
snipe e16c2384fd Fixed some dark/light mode stuff 2026-05-11 12:55:25 +01:00
snipe b3323f08a0 More b0xen 2026-05-11 12:29:58 +01:00
snipe 7e63c2ef92 CSS is hard :( 2026-05-11 12:25:38 +01:00
snipe 7f65b6d598 Shifting stuff around again 2026-05-11 12:25:32 +01:00
snipe 8fb8f0a4d2 Edited queries in ReportsController 2026-05-11 12:24:05 +01:00
snipe 637dbc8d2a New strings 2026-05-11 12:23:47 +01:00
snipe 978990fdff Added progressbar 2026-05-11 12:23:41 +01:00
snipe 52a058e511 Breaking everything.. whee 2026-05-11 12:16:15 +01:00
snipe 64bea202c5 Switched layout, added chart 2026-05-11 12:01:45 +01:00
snipe 37f60993ca Added charts with date range picker 2026-05-11 11:45:34 +01:00
snipe 32717c67c7 Added reports index to sidenav 2026-05-11 11:45:20 +01:00
snipe 3681e3f025 Removed extranneous div 2026-05-11 11:45:08 +01:00
snipe 1d0f055349 Added new strings 2026-05-11 11:44:58 +01:00
snipe fb3024ca9c Added controller methods for reports 2026-05-11 11:44:52 +01:00
snipe 005c0ea9f6 Pint 2026-05-11 11:44:37 +01:00
snipe 7c3f1f3a84 Added routes 2026-05-11 11:44:29 +01:00
snipe 900e5209d9 Added claude.md :( 2026-05-11 10:21:30 +01:00
snipe 4fbf416d16 Merge remote-tracking branch 'origin/develop' 2026-05-11 09:56:31 +01:00
snipe 7b7d2c87fb Added League\Csv\EscapeFormula for a few more reports 2026-05-11 09:54:55 +01:00
snipe 6debb3a65d Added is_not: as search modifier 2026-05-11 09:46:05 +01:00
snipe 315ba49a1d Larger tag size 2026-05-11 09:43:42 +01:00
snipe ff57855038 Added EthicalCheck
Giving this a test drive
2026-05-08 17:10:40 +01:00
snipe da6e837578 Merge pull request #18991 from uberbrady/better_scim_errors
Fixed #18987 - fix SCIM error on mismapped fields
2026-05-08 14:25:02 +01:00
snipe a2d8f89162 Merge remote-tracking branch 'origin/develop' 2026-05-08 14:21:20 +01:00
snipe e36d65e695 Use carbon instead 2026-05-08 14:21:07 +01:00
snipe 34abf14cbe Merge remote-tracking branch 'origin/develop' 2026-05-08 14:12:29 +01:00
snipe dda7a4f22f Format dates in custom report 2026-05-08 14:12:15 +01:00
Brady Wetherington 283a885196 Get rid of 'setCode' and just use the constructor parameter instead 2026-05-08 13:15:37 +01:00
snipe d44aa3f16e Merge remote-tracking branch 'origin/develop' 2026-05-07 12:42:15 +01:00
snipe 575e825579 Typo 2026-05-07 12:42:04 +01:00
snipe dc8cbf4786 Stricter FMCS enforcement in API 2026-05-07 12:41:46 +01:00
snipe 5f81a48d8b Merge pull request #18986 from grokability/#18905-asset-location-on-checkin
Fixed #18905 - update location of child assets if parent asset is checked in
2026-05-07 12:32:44 +01:00
snipe c22e4c00a5 Fixed #18905 - update location of child assets if parent asset is checked in 2026-05-07 12:20:25 +01:00
snipe afb37981bf Merge remote-tracking branch 'origin/develop' 2026-05-07 12:07:46 +01:00
snipe 9b5ead39d3 Merge pull request #18985 from grokability/#18959-slack-notification-location
Fixed #18959 - refresh data on checkout notification
2026-05-07 12:06:19 +01:00
snipe 158e66f9c6 Fixed #18959 - refresh data on checkout notification 2026-05-07 11:59:01 +01:00
snipe bd8e944e2f Merge pull request #18967 from marcusmoore/fixes/test-namespace
Fixed namespace for test class
2026-05-07 11:13:31 +01:00
snipe 2b6518427a Merge remote-tracking branch 'origin/develop' 2026-05-07 11:11:16 +01:00
snipe 06d95b679b Merge pull request #18983 from grokability/add-option-to-export-only-assigned-or-unassigned
Allow custom report to filter on assigned/unassigned
2026-05-07 11:11:01 +01:00
snipe ff75b9eed8 Merge pull request #18982 from marcusmoore/consolidate-test-macros
Improved test macros for streamed content
2026-05-07 11:02:28 +01:00
snipe 17a88fcb80 Allow custom report to filter on assigned/unassigned 2026-05-07 11:00:43 +01:00
snipe 185e0073b3 Merge remote-tracking branch 'origin/develop' 2026-05-07 10:40:10 +01:00
snipe eca34de593 Added null-safe operator for components and consumables 2026-05-07 10:39:57 +01:00
snipe d0794ba71c Merge remote-tracking branch 'origin/develop' 2026-05-07 10:37:15 +01:00
snipe 40e89756bf Extend new operators to custom fields 2026-05-07 10:36:59 +01:00
Marcus Moore 55e46b2d15 Improve macro 2026-05-06 12:08:18 -07:00
Marcus Moore 02383aad7b Fix assertSeeTextInStreamedResponse and assertDontSeeTextInStreamedResponse macros
These were previously only checking the first column and not all of the data.
2026-05-06 11:46:28 -07:00
Marcus Moore e75f54cc1c Move helper macros to CustomTestMacros 2026-05-06 11:40:37 -07:00
snipe 1b42e2e138 Merge remote-tracking branch 'origin/develop' 2026-05-06 17:50:59 +01:00
snipe 3668c24d02 Pint again 2026-05-06 17:50:45 +01:00
snipe a84533b4f4 Quick tweak to advanced search aliases 2026-05-06 17:50:33 +01:00
snipe b4efabe82e Merge remote-tracking branch 'origin/develop' 2026-05-06 16:38:06 +01:00
snipe cbe750cc9e Merge pull request #18980 from uberbrady/reduce_scim_error_level
Throw 4xx SCIMExceptions when SCIM clients send bad data
2026-05-06 16:09:53 +01:00
snipe a77dedf3d7 Merge pull request #18979 from uberbrady/improve_saml_nonces
Add new unique constraint and improved nonce-checking logic for SAML
2026-05-06 15:26:39 +01:00
Brady Wetherington b6ce823cc2 Make sure to throw 400-series SCIMExceptions when SCIM clients send bad data 2026-05-06 15:24:58 +01:00
snipe f7e8ce2ade Merge pull request #18969 from grokability/advanced-search-improvements
🎥 Advanced search improvements
2026-05-06 13:02:07 +01:00
snipe 62e5b71dc1 Added loads of comments - this is gnarly stuff 2026-05-06 12:40:40 +01:00
snipe 3d04324595 Added searchableRelationAliases to user model 2026-05-06 12:39:31 +01:00
snipe 468cf73b97 Updated help text 2026-05-06 12:38:15 +01:00
snipe 5b90f9fb87 Switched to templates for readability (still gross, but whatever) 2026-05-06 12:37:57 +01:00
snipe 9131dbf09b Added more filter options 2026-05-06 12:03:55 +01:00
snipe 9b37e95b58 Merge remote-tracking branch 'origin/develop' 2026-05-05 22:00:13 +01:00
snipe a425234365 Fixed typo, added context (“worm”? Really?) 2026-05-05 22:00:02 +01:00
snipe a92d8eeaab Merge remote-tracking branch 'origin/develop' 2026-05-05 20:37:03 +01:00
snipe cd4e268c72 Added/updated tests 2026-05-05 20:36:39 +01:00
snipe b94945a461 Fixed RB-4121 2026-05-05 20:36:31 +01:00
Brady Wetherington 5b0a779c07 Add new unique constraint and improved nonce-checking logic 2026-05-05 15:23:07 +01:00
snipe e8dbb12ccc Merge remote-tracking branch 'origin/develop' 2026-05-05 13:22:59 +01:00
snipe d099bf2983 Merge pull request #18970 from uberbrady/fix_case_sensitive_classname
Change capitalization on SCIMUser; Linux filenames are case-sensitive
2026-05-05 13:22:28 +01:00
Brady Wetherington f7add0e4dd Change capitalization on SCIMUser; Linux filenames are case-sensitive 2026-05-05 13:19:59 +01:00
snipe 1e1cc897ad Added search help 2026-05-05 12:53:30 +01:00
snipe 04e2c59aa9 Typo 2026-05-05 12:40:56 +01:00
snipe 03bd3517be Added ablity to use “not:” or “!” to exclude results 2026-05-05 12:40:42 +01:00
snipe eeba5bc8fd Cleanup 2026-05-05 12:30:25 +01:00
snipe 1f54180c9c Removed highlighting in advanced search 2026-05-05 12:20:36 +01:00
snipe 8497a27c81 Added tags 2026-05-05 11:45:43 +01:00
snipe 80afa470ee Fixed issue where the button classes would get overwritten when closed and the modal re-opened 2026-05-05 11:39:45 +01:00
snipe 10c750e1a2 Added localstorage to handle remembering and/or 2026-05-05 11:33:56 +01:00
snipe 3aa175b36d Added and/or operator 2026-05-05 11:32:08 +01:00
snipe 8a2cd19ea6 Merge remote-tracking branch 'origin/develop' 2026-05-05 10:58:55 +01:00
snipe e76036965b Same for assets 2026-05-05 10:58:43 +01:00
snipe 2bb86a2ec1 Fixed RB-20854 - only allow scalars for users/hardware query strings 2026-05-05 10:52:51 +01:00
Marcus Moore a89c8c6e5b Fix namespace 2026-05-04 13:47:58 -07:00
Marcus Moore 1bdf205ca6 Run pint on test 2026-05-04 13:47:47 -07:00
snipe afdf86ad0d Merge remote-tracking branch 'origin/develop' 2026-05-04 21:47:15 +01:00
snipe ccf801137a Fixed typo 2026-05-04 21:46:47 +01:00
snipe ef746a173e Fixed RB-4120 - Column 'location_id' in where clause is ambiguous 2026-05-04 21:46:40 +01:00
snipe a5dae3f222 Merge remote-tracking branch 'origin/develop' 2026-05-04 20:55:35 +01:00
snipe e3552f4e36 Merge pull request #18966 from uberbrady/scim_php_82_fixes
Switch to PHPv8.2-compatible way of invoking a constructor and a method
2026-05-04 20:41:34 +01:00
snipe 75d9357488 Removed files notes field - confusing and kinda redundant 2026-05-04 20:34:12 +01:00
Brady Wetherington 26c028cf37 Switch to PHPv8.2-compatible way of invoking a constructor and a method 2026-05-04 20:34:01 +01:00
snipe 10c483967f Merge pull request #18965 from grokability/#18952-upload-files-directly-from-create/edit-screen-for-maintenances
🎥 Fixed #18952 - allow non-image files to be uploaded on create/edit maintenances
2026-05-04 20:33:16 +01:00
snipe 07b33e8189 Fixed #18952 - allow non-image files to be uploaded on create/edit maintenances 2026-05-04 20:15:56 +01:00
snipe 97765c08b1 Merge remote-tracking branch 'origin/develop' 2026-05-04 19:58:48 +01:00
snipe fc3ea78005 Fixed #18780 - limit height for tall images in info-panel 2026-05-04 19:58:37 +01:00
snipe 6ad92556a1 Merge remote-tracking branch 'origin/develop' 2026-05-04 19:47:36 +01:00
snipe bd4150af5a Merge pull request #18964 from grokability/fixes-for-maintenance-permissions
Fixed #18951 - maintenance permissions
2026-05-04 19:47:15 +01:00
snipe e2465ca2a7 Merge remote-tracking branch 'origin/develop' 2026-05-04 19:47:03 +01:00
snipe 1c6c93da35 Fixed typo 2026-05-04 19:30:21 +01:00
snipe 0daec32ddd Added dedicated maintenance permission (related right now just to assets) 2026-05-04 19:30:11 +01:00
snipe e466ed9e06 Merge pull request #18184 from uberbrady/use_new_laravel_scim_server
Use new laravel SCIM server
2026-05-04 18:49:44 +01:00
Brady Wetherington 4445b0317f Re-generated lockfile hash with minimal changes 2026-05-04 18:43:20 +01:00
Brady Wetherington beaea6c3bf Merge branch 'develop' into use_new_laravel_scim_server 2026-05-04 18:39:48 +01:00
snipe f5644928a8 Prod assets 2026-05-04 13:24:50 +01:00
snipe a279c44aa5 Pint 2026-05-04 13:23:49 +01:00
snipe f1f96e574c Bumped hash 2026-05-04 13:23:14 +01:00
snipe 1879001ef3 Merge remote-tracking branch 'origin/master' into develop 2026-05-04 13:21:34 +01:00
snipe 5014b1c459 Fixed #18955 - added manufacturer to view-assigned view 2026-05-04 13:21:12 +01:00
snipe 903459cf7e Merge remote-tracking branch 'origin/master' into develop 2026-05-04 13:12:54 +01:00
snipe 7c04661cfa Merge pull request #18963 from grokability/_add-custom-fields-to-eula-pdf
Add custom fields to eula pdf
2026-05-04 13:07:56 +01:00
snipe 76d3194c96 Shifted layout 2026-05-04 12:57:26 +01:00
snipe b63aee2851 Added custom fields to EULA PDFs 2026-05-04 12:51:43 +01:00
snipe f57d2608c5 Fixed #18956 - hide well if no matching graphs are present 2026-05-04 12:20:25 +01:00
snipe 34331525b1 Merge remote-tracking branch 'origin/master' into develop 2026-05-04 12:17:28 +01:00
snipe 8d1f4427ae Merge pull request #18910 from grokability/audit-visibility-fix
Fixed #18896 - Audit visibility fix
2026-05-04 12:14:05 +01:00
snipe 7f89f8284f Merge pull request #18961 from grokability/add-visibility-icons
🖼️ Added visibility icons in custom fields forms
2026-05-04 12:12:56 +01:00
snipe 3b2ac2bc3c Fixed classname 2026-05-04 12:06:42 +01:00
snipe 73e88be8f3 Small cleanup 2026-05-04 12:05:48 +01:00
snipe f5d092f497 Added aria label for accessibility 2026-05-04 11:56:53 +01:00
snipe 8edbad92cb Added visual icons to show where the custom fields will be visible 2026-05-04 11:55:55 +01:00
snipe b0e13a1352 Merge pull request #18946 from marcusmoore/8.5-actions
Added PHP 8.5 to Action tests
2026-04-30 10:03:48 +01:00
snipe 5c75648cd7 Merge remote-tracking branch 'origin/master' into develop 2026-04-28 19:38:44 +01:00
snipe 1872c6eed9 Merge pull request #18950 from grokability/show-hide-password
🎥 Added password toggle JS/HTML
2026-04-28 10:42:21 +01:00
snipe 53199b9737 Added password toggle JS/HTML 2026-04-28 10:35:36 +01:00
snipe 73861c6a04 Merge pull request #18948 from marcusmoore/fixes/index-history-test
Fixed test name
2026-04-27 22:58:34 +01:00
Marcus Moore e2969dd3e2 Fix filename 2026-04-27 13:59:40 -07:00
snipe 0b1b99697e Merge pull request #18947 from spencerrlongg/mobile-client-endpoint
Mobile OAuth Client Endpoint
2026-04-27 20:05:47 +01:00
snipe 07202a8061 Merge pull request #18937 from uberbrady/fix_saml_intended_url
Fix redirecting users to their intended URL's when logging in via SAML
2026-04-27 19:54:09 +01:00
spencerrlongg 189454096b route for mobile client authentication 2026-04-27 13:52:55 -05:00
Marcus Moore 55ee5df852 Merge branch 'develop' into 8.5-actions 2026-04-27 11:52:29 -07:00
snipe f6466b9154 Merge pull request #18945 from marcusmoore/deps/phpspec/prophecy
Bumped phpspec/prophecy to allow installing on PHP 8.5
2026-04-27 19:51:24 +01:00
Marcus Moore 8e5a64dca9 Add php 8.5 to testing workflows 2026-04-27 11:48:26 -07:00
Marcus Moore b894147514 Bump phpspec/prophecy to v1.26.1 2026-04-27 11:27:41 -07:00
snipe d55c2c269f Merge remote-tracking branch 'origin/master' into develop 2026-04-27 19:05:50 +01:00
Brady Wetherington c7afcf0bef Fix returning to intended URL on 2-factor success (or enrollment success) 2026-04-27 14:59:32 +01:00
Brady Wetherington c79f5b8b74 Merge branch 'develop' into use_new_laravel_scim_server 2026-04-27 14:15:27 +01:00
snipe c5296fd76d Fixed selected attribute on multiselect (normal, not select2) for groups 2026-04-27 13:49:11 +01:00
snipe 3cb3284b26 Merge pull request #18942 from grokability/#18939-blank-tag-after-submit
Fixed #18939 - blank audit field in scanner audit screen
2026-04-27 13:22:12 +01:00
snipe d5d0d00ecc Fixed #18939 - blank audit field in scanner audit screen 2026-04-27 13:20:08 +01:00
Brady Wetherington dc6b45cbcb Fix redirecting users to their intended URL's when logging in via SAML 2026-04-23 15:29:28 +01:00
snipe 5db9d67e65 Merge pull request #18936 from grokability/info-panel-button-blade
Refactor show/hide info button into blade component
2026-04-23 14:26:19 +01:00
snipe f64dfa7f92 Refactor show/hide info button into blade component 2026-04-23 14:18:19 +01:00
snipe 06584d17a6 Merge pull request #18874 from marcusmoore/fixes/fd-54740-user-avatar-via-api-master
[FD-54740] Fixed managing user avatar via API
2026-04-23 13:02:36 +01:00
snipe 73bbe5062d Merge remote-tracking branch 'origin/master' into develop 2026-04-22 17:37:29 +01:00
snipe 75cb1041ec Merge pull request #18932 from grokability/small-tweak-to-info-element-status
🎥 Small tweak to info element status
2026-04-22 17:37:15 +01:00
snipe b61ed66d9d Updated logic 2026-04-22 17:25:48 +01:00
snipe 48ebd7faf5 Refine checkin checkout button display 2026-04-22 17:25:26 +01:00
snipe d6de3baa6e Hide button if orphaned 2026-04-22 17:21:33 +01:00
snipe 1be44a4c05 Pint 2026-04-22 17:18:07 +01:00
snipe f17f34f730 Added routes and logging 2026-04-22 17:17:58 +01:00
snipe da5bb6126a Add a warning well if the asset’s checkout is bonked 2026-04-22 17:09:58 +01:00
snipe a5d04d2e65 Added tests 2026-04-22 17:09:34 +01:00
snipe 22d07214fe Sort of fixed #18918 - prevent showing more permissions if user is admin or superadmin 2026-04-22 15:50:27 +01:00
snipe 8d4523d250 Merge pull request #18930 from grokability/#18920-sort-by-eula-in-categories
Added #18920 - sort by EULA in categories
2026-04-22 15:30:55 +01:00
snipe 37a3d694d4 Pint 2026-04-22 15:24:52 +01:00
snipe d21ccdfcbf Added #18920 - sorting by EULA in category view 2026-04-22 15:24:45 +01:00
snipe 11eaf7ce7b Merge remote-tracking branch 'origin/master' into develop 2026-04-22 15:01:22 +01:00
snipe 4eba97d388 Added Armenian as a possible language 2026-04-22 15:01:11 +01:00
snipe 590e97a99f Merge remote-tracking branch 'origin/master' into develop 2026-04-22 14:58:25 +01:00
snipe 613137551a Pint 2026-04-22 14:58:03 +01:00
snipe 23f941c810 Updated language strings 2026-04-22 14:57:16 +01:00
snipe 4c09f3a229 Merge remote-tracking branch 'origin/master' into develop 2026-04-22 14:38:39 +01:00
snipe e7312801ac Fixed division by zero in new label engine 2026-04-22 14:24:11 +01:00
snipe cd69a7ea53 Merge pull request #18927 from grokability/enforce-basenames-on-filenames
Enforce basenames on filenames
2026-04-22 13:42:09 +01:00
snipe 13ffdda12e Piiiint 2026-04-22 13:35:24 +01:00
snipe 372e74aad3 Adds basename to places where we pass a filename 2026-04-22 13:35:16 +01:00
snipe 2a32f7d372 Merge pull request #18926 from grokability/#18172-correctly-decrypt-encrypted-custom-fields-in-custom-asset-report
Fixed #18172 - Encrypted custom fields not correctly decrypted in custom asset report
2026-04-22 12:56:11 +01:00
snipe a2d34cca76 Pint 2026-04-22 12:49:55 +01:00
snipe c513ed5fc3 Fixed #18172 - correctly dencrypt custom fields in custom asset report 2026-04-22 12:49:48 +01:00
snipe 34cd5dcf7c Add @Husky-Devel as a contributor 2026-04-22 12:24:19 +01:00
snipe 260ca085bb Merge pull request #18908 from Husky-Devel/patch-1
Update snipeit.sh script to add support for CentOS/Alma/Redhat 10.x
2026-04-22 12:22:59 +01:00
snipe 7b00074b9e Merge pull request #18915 from Godmartinz/fix-api-label-with-old-engine
Adds translation and better error messaging for API labels
2026-04-22 12:22:33 +01:00
snipe 16e981d99d Merge pull request #18916 from marcusmoore/fixes/fd-54943-acceptance-email
Fixed display of email setting on category show page
2026-04-22 12:21:47 +01:00
snipe 16eb899ba7 Merge pull request #18924 from grokability/#18367-add-option-to-audit-by-serial-in-quickscan
Fixed #18367 - Added option to audit by serial in quickscan audit
2026-04-22 12:21:13 +01:00
snipe 3367f8e5c7 Edited audit method to allow searching by serial 2026-04-22 12:04:27 +01:00
snipe ad635ab95c Updated text 2026-04-22 12:04:11 +01:00
snipe b94e7fd8a0 Added select2 2026-04-22 12:04:04 +01:00
snipe 683fbd7953 Moved nav option 2026-04-22 12:00:41 +01:00
snipe 246ec9e20b Added tests 2026-04-22 11:57:58 +01:00
snipe 81d669d62a Pint 2026-04-22 09:05:01 +01:00
snipe 9ff951d379 Added redundent migration for delete_at 2026-04-22 09:04:53 +01:00
Marcus Moore e327303b3c Fix display of alert_on_response 2026-04-20 16:18:23 -07:00
snipe 21d030db26 Merge pull request #18914 from Godmartinz/rb20958
Fix RB-20958 company display name in custom reports
2026-04-20 20:31:57 +01:00
Godfrey M 444b58504c rename translation 2026-04-20 11:27:56 -07:00
Godfrey M c1e2f4ad75 update api label exception messages to translations 2026-04-20 11:10:41 -07:00
Godfrey M ec6778e770 adds ternary to user company display in custom reports 2026-04-20 10:09:44 -07:00
snipe 1c5d81cb04 Parse through carbon to make suyre the dates match properly 2026-04-20 15:54:45 +01:00
snipe 10e6c93a95 Merge remote-tracking branch 'origin/master' into develop 2026-04-20 15:40:55 +01:00
snipe d37f43daba Merge pull request #18912 from grokability/small-info-panel-tweaks
Small info panel tweaks
2026-04-20 15:40:39 +01:00
snipe dbabd1bab3 Removed stupid space from phpstorm 2026-04-20 15:34:25 +01:00
snipe 6b5398139a Pull date out of the progress bar
This was squishing weird on smaller screens
2026-04-20 15:32:24 +01:00
snipe 0ec45a4fd0 Add text to dates, added class if almost depreciated 2026-04-20 15:31:16 +01:00
snipe b99fd237f3 Use refactored methods 2026-04-20 15:30:55 +01:00
snipe 5d7123eb05 Added tests 2026-04-20 15:30:25 +01:00
snipe 7eb6ebb60d Refactor the percent logic out of the blade 2026-04-20 15:30:16 +01:00
snipe 0060207816 Merge remote-tracking branch 'origin/master' into develop 2026-04-20 14:19:38 +01:00
snipe 5bc273686e Use support_url in manufacturer blade component 2026-04-20 14:18:58 +01:00
snipe 2f6420e05f Pint 2026-04-20 13:57:50 +01:00
snipe c01699b6e4 Skip checking for company_id on models table 2026-04-20 13:57:45 +01:00
snipe 6c6199add8 Narrowed test 2026-04-20 13:40:49 +01:00
snipe 42cd5e0017 Pint :( 2026-04-20 13:30:22 +01:00
snipe baee6a37ea Backfill audit company ID (if one is present) 2026-04-20 13:30:15 +01:00
Peter Gallwas 90b3685808 Add support for CentOS/Alma/Redhat 10.x
Based off the 9.x code add 10.x support, tested on Rocky 10.1
2026-04-20 18:47:03 +12:00
snipe 37a37318aa Merge pull request #18901 from grokability/display-effective-permissions
Display effective permissions
2026-04-17 12:50:58 +01:00
snipe 74e831c4f0 Oh, Pint 2026-04-17 12:36:56 +01:00
snipe be36390b0f Display effective permissions on user view 2026-04-17 12:36:43 +01:00
snipe e9a628066f Merge pull request #18889 from fvollmer/ldap-deletion
Added #14662: Allow (soft) deletion via ldap sync
2026-04-17 12:14:29 +01:00
ArturoSirvent 8f46b5254e Fix backup disk driver configuration for S3 support
- Fix the backup disk in config/filesystems.php to use a dedicated BACKUP_FILESYSTEM_DRIVER env var instead of PRIVATE_FILESYSTEM_DISK
- Add AWS credential fields to the backup disk config so S3 backups work
- Use BACKUP_FILESYSTEM_ROOT with safe default (storage_path('app')) for local driver
- Document BACKUP_FILESYSTEM_DRIVER and BACKUP_FILESYSTEM_ROOT in .env.example

Fixes #14057
2026-04-17 12:10:03 +01:00
snipe cf44119bc6 Merge pull request #18710 from ArturoSirvent/fix/backup-disk-s3-driver
Fix backup disk driver configuration for S3 support
2026-04-17 12:09:34 +01:00
snipe a15e9d737c Merge pull request #18882 from Godmartinz/purge-old-eula-option-for-deleted-users
adds #18868 options to Eula Purge Command
2026-04-17 12:08:20 +01:00
snipe 08f6f5cf71 Merge remote-tracking branch 'origin/master' into develop 2026-04-17 12:04:50 +01:00
snipe faa2adbde2 Pint 2026-04-17 12:04:31 +01:00
snipe 7fae60d5c3 Log requestable check on checkin/checkout 2026-04-17 12:04:21 +01:00
snipe 4f9ce07304 Merge remote-tracking branch 'origin/master' into develop 2026-04-17 11:58:04 +01:00
snipe 3cad34821e Merge pull request #18900 from grokability/#7418-toggle-requestable
Fixed #7418 - Ability to toggle requestable on checkin/checkout
2026-04-17 11:57:46 +01:00
snipe 1e4353f0db Added controller logic and form request constraints 2026-04-17 11:40:37 +01:00
snipe 7520a1b2a3 Allow the user to leave the requestability unchanged in bulk checkout 2026-04-17 11:38:45 +01:00
snipe cdd91e498a Updated test 2026-04-17 11:37:58 +01:00
snipe 2daf0458a7 Added checkboxes and JS to checkin/checkout blades 2026-04-17 11:35:10 +01:00
snipe 6299fc09bf Added tests 2026-04-17 11:33:12 +01:00
snipe 2327cc6866 Merge pull request #18895 from grokability/resend-acceptance-on-user-page
Resend acceptance on user page
2026-04-16 20:01:50 +01:00
snipe b235df0bbf Fixed div 2026-04-16 19:57:25 +01:00
snipe 6d56ab9b63 Re-added import 2026-04-16 19:51:50 +01:00
snipe ce5de8fe06 Allow admin to resend unaccepted assets 2026-04-16 15:50:11 +01:00
snipe ce3f80246e Pint 2026-04-16 15:49:32 +01:00
snipe 046ef82c65 Added gates for 2FA reset API endpoint 2026-04-16 15:49:25 +01:00
snipe 0f347e8453 Use translation for unauthorized 2026-04-16 15:28:36 +01:00
snipe 1cb0ca84ab Add wrapping for address 2026-04-16 14:52:03 +01:00
snipe 7625646c11 Remove wrapping from wells 2026-04-16 14:51:42 +01:00
snipe 743c598b83 Merge remote-tracking branch 'origin/master' into develop
# Conflicts:
#	public/js/dist/all.js
#	public/js/dist/all.js.map
#	public/mix-manifest.json
2026-04-16 14:13:02 +01:00
snipe 324530fb8c Updated language 2026-04-16 14:12:07 +01:00
snipe 68acf7b90a Merge pull request #18884 from grokability/#8414-sign-in-place
Added #8414 - acceptance sign in place
2026-04-16 14:11:11 +01:00
snipe 9c610f51af Updated language, nicer form 2026-04-16 13:37:31 +01:00
snipe 40ec0627c4 Check for global acceptance requirement as well 2026-04-16 13:14:21 +01:00
snipe 645e66b30c Updated language 2026-04-16 13:07:32 +01:00
snipe 2311d56836 Only show the sign-in-place box if the category requires it 2026-04-16 13:06:18 +01:00
snipe 1f3481c54b Use breadcrumb action in route 2026-04-16 12:51:57 +01:00
snipe 07fa51aa4c Lots of tests 2026-04-16 12:51:38 +01:00
snipe 0866469cc0 Added checkout date and admin to acceptance form 2026-04-16 12:51:22 +01:00
snipe 3d9bb29b1b Updated string 2026-04-16 12:50:59 +01:00
snipe 5a67bcaf17 Pint doing pint things 2026-04-16 12:50:52 +01:00
snipe 01b18513f1 Safe redirect if request is weird 2026-04-16 12:49:02 +01:00
snipe d92ec582fa Check for “stale” acceptance 2026-04-16 12:47:30 +01:00
snipe 205eb7fd37 Moved breadcrumbs into action to get the logic out of the route 2026-04-16 12:35:31 +01:00
snipe 0798e62417 Normalize the box header - it looked kinda weird before 2026-04-16 11:31:12 +01:00
snipe 83adcc61bc More cleanup 2026-04-16 11:22:39 +01:00
snipe 788e07947f Nicer styling 2026-04-16 11:14:35 +01:00
snipe f7717571ea Merge remote-tracking branch 'origin/master' into develop 2026-04-16 10:01:04 +01:00
snipe 83fec75bc8 Avoid crashing if assignedto isn’t valid 2026-04-16 10:00:45 +01:00
snipe 53c240f13f Pint 2026-04-15 21:29:32 +01:00
snipe f142eb7a44 Moved back in time migration 2026-04-15 21:29:26 +01:00
Felix Vollmer fe84d35ce4 Added #14662: Allow (soft) deletion via ldap sync 2026-04-15 17:14:53 +02:00
Godfrey M 5c5414c960 remove comments, reorder command options 2026-04-14 17:57:06 -07:00
Godfrey M 2eeb1f588a rename tests 2026-04-14 16:13:18 -07:00
Godfrey M 9f69eacf71 tweak to acceptance factory, adds purge eula command tests 2026-04-14 16:11:32 -07:00
snipe 495382c42f Merge pull request #18885 from grokability/fix-soft-deleted-companies-in-migrations
Fix soft deleted companies in migrations
2026-04-14 23:19:33 +01:00
snipe 029634707b Oh, Pint 2026-04-14 22:50:32 +01:00
snipe fd5736fac4 Belt and suspenders 2026-04-14 22:50:21 +01:00
snipe f3ed2d9dd8 Derp. Run if the column DOES exist 2026-04-14 22:38:44 +01:00
snipe 676cd66e4b Make the temp datetime nullable 2026-04-14 22:31:00 +01:00
snipe 17c73c4017 Pint :( 2026-04-14 22:30:26 +01:00
snipe 5983a4530f Fix back in time migrations for very old restores or upgrades 2026-04-14 22:30:05 +01:00
snipe 1cd8395b23 Piiiint 2026-04-14 21:44:08 +01:00
snipe ea4374a855 Oops. Forgot to commit accessories :D 2026-04-14 21:44:00 +01:00
snipe 061b913413 Better naming for session variable 2026-04-14 20:54:42 +01:00
Godfrey M b2fda13ac3 adds option for only deleted users and company id for eula purging 2026-04-14 11:58:54 -07:00
snipe e79af0163a Oh, Pint 2026-04-14 19:49:18 +01:00
snipe 91e41049bd Skip the initial checkout email to the recipient if sign_in_place was checked 2026-04-14 19:49:05 +01:00
snipe 18f67bcce5 Store the sign in place in the session so it’s remembered 2026-04-14 12:20:51 +01:00
snipe 264347e323 Added redirects 2026-04-14 12:16:46 +01:00
snipe 18d9f7dbf1 Updated JS assets 2026-04-14 12:13:59 +01:00
snipe 702af91c84 Added tests 2026-04-14 12:13:02 +01:00
snipe e9db3b3861 Added sign-in-place language keys 2026-04-14 12:12:54 +01:00
snipe 896922fde5 Added acceptance checkbox to checkout blades 2026-04-14 12:09:42 +01:00
snipe 7c2bb69bc9 Nicer width for field 2026-04-14 12:02:43 +01:00
snipe d2921346a2 Fixed datepicker width 2026-04-14 11:07:59 +01:00
snipe cc06b2f0eb Merge pull request #18878 from grokability/fixes-n+1-on-history
Fixes n+1 on history
2026-04-14 11:06:44 +01:00
snipe d98c7bddba Added test to prevent n+1 regression 2026-04-14 10:25:55 +01:00
snipe fe308ef2e4 Use query clone to prevent n+1 2026-04-14 10:25:37 +01:00
snipe 9b43835e2d Added forHistory scope in ActionLog, use it in Loggable 2026-04-14 10:23:36 +01:00
snipe 88d34a5b92 Merge remote-tracking branch 'origin/master' into develop 2026-04-14 09:27:28 +01:00
snipe 019f0af282 Fixed typo 2026-04-14 09:13:45 +01:00
Marcus Moore c6619a621c Move comment 2026-04-13 16:42:47 -07:00
Marcus Moore 565e3de183 Allow updating user avatar via API 2026-04-13 16:41:21 -07:00
snipe b91dd15f96 Merge remote-tracking branch 'origin/master' into develop 2026-04-13 16:19:51 +01:00
snipe 1a852cdacf Merge pull request #18872 from grokability/location-breadcrumbs
Fixes #9037 - Added breadcrumbs to top breadcrumb trail
2026-04-13 16:19:34 +01:00
snipe 4ea527d980 Added breadcrumb to info-panel 2026-04-13 16:16:33 +01:00
snipe 392af4f127 Fixes #9037 - Added breadcrumbs to top breadcrumb trail 2026-04-13 16:09:10 +01:00
snipe 6e8e72f281 Merge remote-tracking branch 'origin/master' into develop 2026-04-13 15:52:11 +01:00
snipe 1c198500c6 Merge pull request #18871 from grokability/#18869-throw-error-if-no-MAIL_REPLYTO_ADDR-is-set
Fixed #18869 - skip mail test if no `MAIL_REPLYTO_ADDR` is given
2026-04-13 15:20:45 +01:00
snipe 8620f25c0e Fixed #18869 - skip mail test if no MAIL_REPLYTO_ADDR is given 2026-04-13 15:17:23 +01:00
snipe 1311ce48d3 Merge remote-tracking branch 'origin/master' into develop 2026-04-13 15:01:01 +01:00
snipe 8a59809937 Merge pull request #18870 from grokability/#18736-add-cumulative-cost-of-an-asset-with-maintenances
#18736 add cumulative cost of an asset with maintenances
2026-04-13 15:00:38 +01:00
snipe bac8299ea6 Added accessor for component qty 2026-04-13 14:51:48 +01:00
snipe 500dcdd582 Re-jigger the order 2026-04-13 14:51:24 +01:00
snipe cbae494c54 Fixed totals 2026-04-13 14:08:23 +01:00
snipe 09bec66406 Meh 2026-04-13 13:55:05 +01:00
snipe 2b2291dc7e Pint 2026-04-13 13:48:21 +01:00
snipe 1357b45e24 Added content to blade, refactoring some relationships 2026-04-13 13:48:14 +01:00
snipe 4a0dbba3ec Dev assets 2026-04-13 11:59:47 +01:00
snipe fcd0360135 Merge remote-tracking branch 'origin/master' into develop 2026-04-13 11:57:54 +01:00
snipe 6935cf1dde Merge pull request #18867 from grokability/fixed-#18856-duplicate-icons
Fixed #18856 - clicking and canceling would result in multiple icons in modal
2026-04-13 11:57:36 +01:00
snipe cf384373df Fixed #18856 - clicking and canceling would result in multiple icons in modal 2026-04-13 11:50:41 +01:00
snipe 48c4f34af3 Fixed #18863 - backfill status vs status_type for older integrations 2026-04-13 11:08:14 +01:00
snipe 7b800152ee Merge pull request #18866 from grokability/adds-validation-check-console-command
Adds validation check console command - helps with #18851
2026-04-13 10:45:49 +01:00
snipe f289691e22 Merge pull request #18865 from Joly0/patch-1
Add artisan command to clear compiled views (for docker startup.sh)
2026-04-13 10:45:25 +01:00
snipe 50421494c5 Pint 2026-04-13 10:33:55 +01:00
snipe 33b8861ae3 Adds conosole command for listing invalid assets 2026-04-13 10:33:49 +01:00
Joly0 31f90d20f8 Add artisan command to clear compiled views
After the recent update to 8.4.1 this command was mandatory, but wasnt applied to docker environment, therefore (atleast for my company) views were broken (empty licenses for example). Had to manually exec into the container and execute this command.

Adding it to the startup script should bring no real downsides, but should fix this for all others and all future version of snipe-it that have the same requirement for clearing compiled views
2026-04-13 09:49:51 +02:00
snipe a94ba474f3 Updated version in confog for develop 2026-04-11 11:05:10 +01:00
snipe a81ab0ea0f Merge remote-tracking branch 'origin/master' into develop 2026-04-11 11:04:29 +01:00
snipe 87e65893d3 Updated tests with new text 2026-04-11 10:48:37 +01:00
snipe 405540aea2 Clarified text 2026-04-11 10:38:42 +01:00
snipe ccfebee5f1 Not sure why the timestamps wouldn’t handle this for us, but… 2026-04-11 10:34:03 +01:00
snipe 1d9469a3df Fix action_date on action_logs on bulk checkin and delete 2026-04-11 10:32:04 +01:00
snipe 5417bf3445 Merge pull request #18860 from uberbrady/fix_migrations
Move migration to fire after deleted_at column added to companies
2026-04-09 21:22:58 +01:00
snipe 51ea1327cf Merge pull request #18861 from grokability/log-authed-user-header
Log authed user ID header
2026-04-09 20:16:12 +01:00
Brady Wetherington 8113ddb2d5 Re-Add the old migration as an 'empty migration' just for safety 2026-04-09 20:10:02 +01:00
snipe a88ad35b68 Added token name and ID 2026-04-09 19:35:09 +01:00
snipe 6e60f59265 Changed the name because reasons 2026-04-09 19:24:11 +01:00
snipe a866bfafcd Oh ffs pint 2026-04-09 19:23:29 +01:00
snipe 97d1677568 Check for bearer token in header 2026-04-09 19:23:21 +01:00
snipe f4562db0c0 Pint 2026-04-09 19:19:56 +01:00
snipe a616da3e5c Moved to an API-only header 2026-04-09 19:19:50 +01:00
snipe a895566b02 Pint fixes 2026-04-09 19:09:32 +01:00
snipe 5d75765aae Optionally log the user’s ID in the header 2026-04-09 19:09:21 +01:00
snipe 3bc34fcd5e Added nice icons for revoked/not revoked status 2026-04-09 18:46:18 +01:00
snipe 99c3ac56e9 Fixed typo 2026-04-09 18:32:50 +01:00
Brady Wetherington 95c7d5eeff Move migration to fire _after_ the deleted_at column is added to companies 2026-04-09 18:19:28 +01:00
snipe 371f0b82f6 This is superadmin, do not scope to just the authed user 2026-04-09 18:06:27 +01:00
snipe 114b5d3db0 Updated text 2026-04-09 18:01:44 +01:00
snipe 9ab0f60b41 Merge pull request #18858 from grokability/_api-token-rework
Api token rework
2026-04-09 17:42:09 +01:00
snipe 33b8226ebe A little more cleanup 2026-04-09 17:36:32 +01:00
snipe e062062cb3 Added livewire component for persoinal access tokens for admin 2026-04-09 17:24:51 +01:00
snipe 5f713862fb Updated tests 2026-04-09 17:24:20 +01:00
snipe fe013b5ea0 A bit more polish 2026-04-09 17:20:16 +01:00
snipe 57df2dc2cf Removed extra column 2026-04-09 16:21:39 +01:00
snipe c86fa4c521 Moved tabs 2026-04-09 16:00:49 +01:00
snipe c90acf53d5 One more quick fix for consumables qty percent 2026-04-09 15:14:10 +01:00
snipe fece4d2fdc Handle 0 qty for consumables 2026-04-09 15:10:58 +01:00
snipe f49837e5fe Fix division by zero? 2026-04-09 15:08:46 +01:00
snipe e6ead7c6fa Added tests 2026-04-09 14:52:30 +01:00
snipe 3e84af83d8 Added translations to OAuthClients livewire 2026-04-09 14:52:22 +01:00
snipe aff375c799 Added OAuth table button - I don’t know if this really works properly? 2026-04-09 14:52:01 +01:00
snipe 6ada1a646f Tabbed UI 2026-04-09 14:51:33 +01:00
snipe 42bfd24a8f Expanded OAuth language 2026-04-09 14:49:33 +01:00
snipe c7c6b41dab Added revoke to user model 2026-04-09 14:49:12 +01:00
snipe 449e6b5f5c Added revoke controllers 2026-04-09 14:48:50 +01:00
snipe bbe0c7409f Added TokenRevoked action 2026-04-09 14:48:22 +01:00
snipe 41bb9c378b Added keywords for translation 2026-04-09 14:48:03 +01:00
snipe 9a82b890d4 Translation 2026-04-09 14:47:52 +01:00
snipe 2d2180c9e8 Added revoke/unrevoke routes 2026-04-09 14:26:11 +01:00
snipe 798a590c2a Pint gonna pint 2026-04-09 14:03:37 +01:00
snipe 8a08878062 Added language strings 2026-04-09 14:03:18 +01:00
snipe fde6ff1571 Pint 2026-04-09 12:16:46 +01:00
snipe 8c9a48b38a Fixed custom field search nesting 2026-04-09 12:16:40 +01:00
snipe fff89ee94c Merge pull request #18852 from marcusmoore/fixes/rb-20840-bulk-asset-checkout
Fixed potential exception in bulk asset checkout
2026-04-09 11:28:42 +01:00
Marcus Moore 2745552915 Update asset factory 2026-04-08 14:05:26 -07:00
Marcus Moore 2f400a2b17 Handle target being assigned to a non-user model 2026-04-08 13:40:37 -07:00
Marcus Moore de5256b8f5 Use correct relationship 2026-04-08 13:36:22 -07:00
Marcus Moore 344ae053cf Add failing test 2026-04-08 13:35:11 -07:00
snipe 45fffd74b7 Merge pull request #18846 from grokability/strikethroug-if-component-is-deleted
Strikethrough if component is deleted
2026-04-08 12:47:49 +01:00
snipe a0cf0751de Pint 2026-04-08 12:39:38 +01:00
snipe 7485cb81aa Show strikethrough and unlink if item is deleted 2026-04-08 12:39:29 +01:00
snipe 7faa9a6fdf Fixed #18816 - updated language in acceptance email 2026-04-08 11:24:54 +01:00
snipe f6f7063419 Fixed #18844 - use correct component for bulk editing models on category detail view 2026-04-08 11:17:48 +01:00
snipe 1300fff94c Null safe operator for assets transformer 2026-04-08 11:11:55 +01:00
snipe 5ef9798c68 Pint 2026-04-08 10:09:56 +01:00
snipe db48c18766 Fixed #18840 - added print inventory button back to locations 2026-04-08 10:09:49 +01:00
snipe 880261500b Piiiiiint 2026-04-07 19:14:08 +01:00
snipe e02c257df6 Bumper version 2026-04-07 19:13:58 +01:00
snipe d6b48a2818 Merge pull request #18835 from uberbrady/improve_restore_port_numbers
Fixed #18786 - add port number option to the restore command
2026-04-07 15:48:20 +01:00
Brady Wetherington f8c7eee17b Add port number option to the restore command 2026-04-07 15:40:44 +01:00
snipe 5898205480 Merge pull request #18834 from grokability/asset-components-display-fix
Asset components display fix
2026-04-07 15:32:16 +01:00
snipe c8d2118c74 Merge pull request #18833 from uberbrady/new_indices_for_locations_query
Add new indexes to improve some Location queries
2026-04-07 15:31:32 +01:00
snipe 50676288a1 Pint 2026-04-07 15:29:15 +01:00
snipe db2269092a Moved limit 2026-04-07 15:29:06 +01:00
Brady Wetherington ddaa75a6dd Add new indexes to improve some Location queries 2026-04-07 15:23:31 +01:00
snipe b3f56900e5 Added created_by to sortable fields 2026-04-07 14:46:23 +01:00
snipe f1820b739f Use sum 2026-04-07 14:45:52 +01:00
snipe 56957e28f9 Standardized transformer 2026-04-07 14:45:42 +01:00
snipe 3c32721791 Use ComponentsAssignment model 2026-04-07 14:44:56 +01:00
snipe 2632433cc6 Load location and company on asset load 2026-04-07 14:44:09 +01:00
snipe 16ea577099 Include created_by in pivot 2026-04-07 12:20:25 +01:00
snipe 182e06173d Merge pull request #18730 from marcusmoore/laravel-12-take-2
Upgraded to Laravel 12
2026-04-06 13:03:39 +01:00
snipe f6b4600f8a Added checkout_class alias 2026-04-06 11:24:01 +01:00
snipe 7456c9dce5 Check that $image is not empty 2026-04-06 10:58:12 +01:00
snipe f9e16e16d1 Avoid searching by human readable custom field name to avoid collisions with normal attributes 2026-04-06 10:45:10 +01:00
snipe b42094a1be Merge remote-tracking branch 'origin/develop' 2026-04-06 10:17:38 +01:00
snipe 4c343afec7 Pint 2026-04-06 10:17:29 +01:00
snipe 40b3007676 Removed duplicated custom field search 2026-04-06 10:17:23 +01:00
snipe 48395d162a Merge remote-tracking branch 'origin/develop' 2026-04-06 09:54:45 +01:00
snipe 50aaa54c27 Check status_type for list_all 2026-04-06 09:52:43 +01:00
snipe 47737b082b Missed one in the nav 2026-04-06 09:51:50 +01:00
snipe c4a3c71448 Merge remote-tracking branch 'origin/develop' 2026-04-06 09:49:41 +01:00
snipe 9939849e40 pint 2026-04-06 09:49:33 +01:00
snipe d690989b58 Use status_type instead of status for filtering 2026-04-06 09:49:24 +01:00
snipe d9deb0f30c Merge remote-tracking branch 'origin/develop' 2026-04-06 08:49:05 +01:00
snipe 53ce14dddf Switched to AND operator 2026-04-06 08:48:56 +01:00
snipe 1d0be6261b Merge pull request #18823 from grokability/small-permission-tweaks
Added actions for normalizing permissions input
2026-04-06 08:46:03 +01:00
snipe 108c6eda1d Oh, pint 2026-04-06 08:06:28 +01:00
snipe 6e33bfaf8f Don’t check for filled on groups in user save 2026-04-06 08:06:20 +01:00
snipe a7bc9f0ae9 Use fill() for more compact code 2026-04-05 13:03:37 +01:00
snipe 927e0a4e7b Just set the field directly, since it’s a UI edit 2026-04-05 13:03:02 +01:00
snipe 75b2ac9d33 Aaaaand pint 2026-04-05 13:02:22 +01:00
snipe b0d7ae6f04 Removed redundent display_name setting, since it’s already fillable 2026-04-05 13:02:13 +01:00
snipe c764605d07 Implement the new actions in the controllers 2026-04-05 12:40:34 +01:00
snipe 205cf3cf28 MOAR tests 2026-04-05 12:38:02 +01:00
snipe ea274f0df0 Added tests 2026-04-05 12:37:53 +01:00
snipe 31541c4a56 Sigh. Pint 2026-04-05 12:35:19 +01:00
snipe 2a601ae483 Switched to use actions for normalizing payload 2026-04-05 12:35:09 +01:00
snipe 3fe8600a70 Normalize permissions array 2026-04-05 11:55:08 +01:00
snipe dbd7df2b85 Merge remote-tracking branch 'origin/develop' 2026-04-04 17:09:05 +01:00
snipe 717deb544e Merge pull request #18822 from grokability/fixed-history-api-pagination
Fixed #18821- history api pagination
2026-04-04 17:08:26 +01:00
snipe 51446a5fe0 Pint 2026-04-04 16:59:30 +01:00
snipe 4c4ec3eacc Fixed #18821 - pagination on history 2026-04-04 16:59:23 +01:00
snipe 71b72eae10 Merge remote-tracking branch 'origin/develop' 2026-04-03 15:40:30 +01:00
snipe 01eb585e59 Fixed light-dark button in nav dropdown 2026-04-03 15:40:16 +01:00
snipe 2343841aa1 Merge remote-tracking branch 'origin/develop' 2026-04-03 13:57:31 +01:00
snipe b2790d98d0 Removed codacy badge (for now) 2026-04-03 13:57:20 +01:00
snipe b14e925158 Merge remote-tracking branch 'origin/develop' 2026-04-03 13:46:03 +01:00
snipe 18ef770a85 Fixed RB, added withTrashed() 2026-04-03 13:45:53 +01:00
snipe ee831c9361 Merge remote-tracking branch 'origin/develop' 2026-04-03 13:07:47 +01:00
snipe e446dc1cba Fixed [RB-4105] - check for item’s existance before applying withTrashed() 2026-04-03 13:07:37 +01:00
snipe af283c7e01 Merge remote-tracking branch 'origin/develop'
# Conflicts:
#	config/version.php
2026-04-03 12:28:30 +01:00
snipe 4703a8b021 Pint 2026-04-03 12:28:00 +01:00
snipe eb3a608e80 Bumped to pre version 2026-04-03 12:27:50 +01:00
snipe 6fbd189553 Pint 2026-04-03 12:26:49 +01:00
snipe 753e2790ac Merge remote-tracking branch 'origin/develop'
# Conflicts:
#	public/js/dist/all.js
#	public/js/dist/all.js.map
#	public/mix-manifest.json
2026-04-03 12:26:28 +01:00
snipe 2c2de8719b Exclude encrypted custom fields in search 2026-04-03 12:25:09 +01:00
snipe 1e884bf627 Update the alias 2026-04-03 12:19:49 +01:00
snipe 7a001c81ea Merge pull request #18809 from grokability/rename-assetstatus
Rename assetstatus to status (variation of #18808)
2026-04-03 11:38:45 +01:00
snipe 9e82f3ffd9 Merge pull request #18814 from Godmartinz/add-example-logo-to-label-preview
Adds #18663 generic example logo for label preview
2026-04-03 11:37:06 +01:00
snipe e1dc605657 Merge pull request #18820 from grokability/search-one-more-stab
Adds to #18778, fixes for advanced search
2026-04-03 11:36:26 +01:00
snipe bca93b57ec Pint fixes 2026-04-03 11:08:35 +01:00
snipe d929c87bbd Final fixes, tests 2026-04-03 11:08:16 +01:00
snipe 72eb4d6d4d Merge remote-tracking branch 'origin/develop' 2026-04-03 09:52:19 +01:00
snipe 0ccdeed318 Merge pull request #18817 from Godmartinz/notification-language-fix
Fixes #18811  locale for Requestable notifications
2026-04-03 09:41:06 +01:00
snipe 5d6fc9f516 Merge pull request #18818 from marcusmoore/fixes/18798-create-asset-with-scoped-locations
Fixed #18798: creating assets with location for non-super-admins with FMCS
2026-04-03 09:40:31 +01:00
snipe 7f0435e3d6 Merge pull request #18815 from marcusmoore/fixes/18810-acceptance-url-in-mail
Fixed #18810: Display acceptance url in checkout asset email
2026-04-03 09:36:40 +01:00
Marcus Moore 85d7ba73aa Set company_id in request for non-super-admins when fmcs enabled 2026-04-02 15:50:13 -07:00
Godfrey M c6a3afa555 revert change, but still add locale 2026-04-02 15:31:25 -07:00
Godfrey M 6cc8ec63be Correct way to append locale 2026-04-02 15:29:57 -07:00
Godfrey M cf7cb8069b get locale from settings before sending requestable message 2026-04-02 15:22:59 -07:00
Marcus Moore e70519c9c2 Fix test assertion 2026-04-02 13:40:16 -07:00
Marcus Moore 6617cc3e7e Add missing endif 2026-04-02 11:47:27 -07:00
Marcus Moore 3426a427d8 Add more details to failure 2026-04-02 11:30:02 -07:00
Marcus Moore 2e67787d75 Add failing test 2026-04-02 11:28:42 -07:00
snipe 70a30a96fa Try to resolve polymorism for checkout 2026-04-02 19:23:45 +01:00
Godfrey M 8832596aa0 Merge branch 'develop' into add-example-logo-to-label-preview 2026-04-02 11:08:11 -07:00
snipe 0cd013191a Merge pull request #18805 from Godmartinz/fix-company-disabled-css-bug
Fixes #18715 Fixes disabled CSS rules for select2
2026-04-02 19:07:00 +01:00
Marcus Moore 8f70b299cf Merge branch 'develop' into fixes/18798-create-asset-with-scoped-locations 2026-04-02 11:06:42 -07:00
Godfrey M 2c87a469e3 adds generic example logo if no logo present" 2026-04-02 10:55:56 -07:00
snipe 5ca2ec5534 Merge remote-tracking branch 'origin/develop' 2026-04-02 18:12:10 +01:00
snipe 46caf9d9ec Removed phpmd.xml 2026-04-02 18:11:58 +01:00
snipe 7ac0842bc2 Merge remote-tracking branch 'origin/develop' 2026-04-02 17:45:59 +01:00
snipe de1674d001 Removed the display none from bulk asset checkout 2026-04-02 17:45:48 +01:00
Godfrey M 37c30a3079 remove unnecessary css 2026-04-02 09:41:45 -07:00
snipe ce825d1df2 Merge remote-tracking branch 'origin/develop' 2026-04-02 17:39:24 +01:00
snipe b5c01ab820 Fixed #18812 - light/dark on signature page 2026-04-02 17:39:15 +01:00
snipe 8de674c837 Merge remote-tracking branch 'origin/develop' 2026-04-02 17:21:06 +01:00
snipe d289ac7f05 Pint 2026-04-02 11:26:33 +01:00
snipe 7ec60bc6f2 Same as #18808 but renamed assetstatus to status 2026-04-02 11:26:23 +01:00
snipe eb78474d1e Make order number clickable if asset 2026-04-02 10:32:21 +01:00
snipe 6dc5a4a27e Merge remote-tracking branch 'origin/develop' 2026-04-02 09:59:56 +01:00
snipe 10c8045351 Check for file view permissions 2026-04-02 09:59:46 +01:00
snipe 03b6a54fe8 Merge remote-tracking branch 'origin/develop' 2026-04-02 09:36:35 +01:00
snipe 1140795ab8 Fixed #18734 - open markdown link in new window 2026-04-02 09:36:24 +01:00
snipe 0441c07266 Merge remote-tracking branch 'origin/develop' 2026-04-02 09:17:11 +01:00
snipe 64f346a5f0 Aaaand pint 2026-04-02 09:12:03 +01:00
snipe 0ac63a8ac6 Codacy tweaks 2026-04-02 09:11:50 +01:00
snipe f5a3d751da Merge remote-tracking branch 'origin/develop' 2026-04-01 23:32:56 +01:00
snipe 985e7d0c7c Merge pull request #18806 from marcusmoore/fixes/rb-4103manufacturer-url
Fixed RB-4103: Allow more models to access dynamic url presenter method
2026-04-01 23:32:09 +01:00
snipe 97a024b3ec Merge remote-tracking branch 'origin/develop' 2026-04-01 23:29:09 +01:00
snipe c501999676 Merge pull request #18807 from grokability/adds-model-number-to-info-panel-if-asset
Added model number on info-panel if the object is an asset
2026-04-01 23:28:22 +01:00
snipe 80e7cf0b46 Added model number on info-panel if the object is an asset 2026-04-01 23:21:30 +01:00
Marcus Moore b7d2bea3ea Fix dynamic url 2026-04-01 15:15:31 -07:00
Marcus Moore 2acb38a6a5 Move dynamic method to base presenter and adjust for other model types 2026-04-01 15:05:42 -07:00
Godfrey M 8ea7242c38 remove input[type=*]:disabled 2026-04-01 14:45:23 -07:00
Godfrey M 616a93cb52 removed override changes 2026-04-01 14:33:28 -07:00
Godfrey M 7170ea0303 adjust disabled look for select 2 2026-04-01 14:28:32 -07:00
snipe 10eb14776b Merge remote-tracking branch 'origin/develop' 2026-04-01 22:09:03 +01:00
snipe a7b43d1879 Merge pull request #18800 from Godmartinz/acceptance-double-send-bug
Fix #18595 checkout acceptance url bug
2026-04-01 22:08:03 +01:00
snipe 439f3c9c91 Merge remote-tracking branch 'origin/develop' 2026-04-01 21:49:49 +01:00
snipe e2b8368f40 Removed dupe category in info panel 2026-04-01 21:49:38 +01:00
Godfrey M 1243f690c4 changed disabled=true to disabled, adjust css" 2026-04-01 13:48:56 -07:00
snipe e2c8d41a58 Merge pull request #18803 from marcusmoore/fixes/18802-support-url
Fixed #18802: Display dynamic support url for manufacturers properly
2026-04-01 21:46:34 +01:00
snipe 591bba71d5 Pint 2026-04-01 21:46:23 +01:00
snipe 7aef0f78b0 Fixed weird component linking 2026-04-01 21:46:13 +01:00
Marcus Moore b6dc0e2a08 Display dynamic support url properly 2026-04-01 13:37:06 -07:00
Godfrey M 1ed7dd0e1e fix markdown to send messages with Eulas 2026-04-01 13:17:02 -07:00
snipe 5ecfa0b8d8 Merge remote-tracking branch 'origin/develop' 2026-04-01 20:41:09 +01:00
snipe 3578580956 Fix variable 2026-04-01 20:41:00 +01:00
snipe 67457d324c Merge remote-tracking branch 'origin/develop' 2026-04-01 16:25:54 +01:00
snipe 8b4e4aff27 Merge pull request #18801 from grokability/small-improvements-to-activity-report
Small improvements to activity report
2026-04-01 16:25:40 +01:00
snipe eb11c4640b Pint :-/ 2026-04-01 16:16:36 +01:00
snipe 5806fced78 Add optional hide for history 2026-04-01 16:16:25 +01:00
snipe ee0e036354 Removed unused routes 2026-04-01 15:00:16 +01:00
snipe af0ec10e78 Addd notes tab 2026-04-01 15:00:01 +01:00
snipe ccbd73259b Fixed license tabs 2026-04-01 14:58:33 +01:00
snipe 1a44a11b62 Added journal permission 2026-04-01 14:51:57 +01:00
snipe 8502a2291b Allow non-report users to view assets, etc if they have permission 2026-04-01 14:51:42 +01:00
snipe 67ccb5e6d9 Make a generic formatter for class names 2026-04-01 14:51:10 +01:00
snipe 520a70d2ea Added tests 2026-04-01 14:50:56 +01:00
snipe 3dee30c48e Changed button color 2026-04-01 14:50:47 +01:00
snipe f314e12685 Merge remote-tracking branch 'origin/develop' 2026-04-01 10:13:50 +01:00
snipe e3b53c8fa2 Use newer files permission 2026-04-01 10:13:39 +01:00
snipe 4bb5020e0a Added assets obj to asset tab check 2026-04-01 10:13:32 +01:00
snipe 4f1fa95cf9 Check for valid category beofre chekcing for tag color 2026-04-01 10:01:17 +01:00
snipe baeeb8e609 Use shorter auth check 2026-04-01 09:56:41 +01:00
snipe f109ca6f1f Merge remote-tracking branch 'origin/develop' 2026-04-01 09:14:20 +01:00
Marcus Moore 1714d62762 Add failing test 2026-03-31 17:20:40 -07:00
Godfrey M f19ac4d5bb send checkout mail without link or acceptance reference 2026-03-31 16:38:35 -07:00
snipe c6dbccb463 Merge pull request #18799 from marcusmoore/fixes/54576-component-link
Fixed #18797: Fix link to components in asset view
2026-03-31 23:42:24 +01:00
Marcus Moore 80ca2a6d21 Fix link to component 2026-03-31 15:36:24 -07:00
snipe 90c1c8cddd Merge remote-tracking branch 'origin/develop' 2026-03-31 15:28:14 +01:00
snipe 0b6593bdc8 Merge pull request #18783 from ubc-cpsc/fix/aws-sdk-php-PKSA-4t1p-xpk2-nsss
Fixes PKSA-4t1p-xpk2-nsss for aws/aws-sdk-php
2026-03-31 15:26:24 +01:00
snipe 6e8c0e5a14 Merge pull request #18758 from Godmartinz/extends-field-value-if-no-label
Fixes FD-54467 TZe_24mm_E Field value to extend full width
2026-03-31 15:25:53 +01:00
snipe 78c300ea1b Merge pull request #18788 from Godmartinz/fix-bulk-edit-breadcrumb
Fixes bulk edit breadcrumb translation
2026-03-31 15:25:28 +01:00
snipe a3fb492e37 Merge pull request #18790 from spencerrlongg/bug/rm-dead-license-route-rb
Removes Unused License Route
2026-03-31 15:24:21 +01:00
snipe 667f50497c Merge pull request #18791 from spencerrlongg/bug/better-error-reporting-in-custom-rules
Better Error Reporting in Custom Rules
2026-03-31 15:23:53 +01:00
snipe cb93eda4e2 Merge pull request #18792 from spencerrlongg/bug/nest-error-callback-errors-properly
Wrap importer errors in array properly
2026-03-31 15:23:15 +01:00
snipe 613b536f97 Merge remote-tracking branch 'origin/develop' 2026-03-31 13:58:59 +01:00
snipe 1ffaa077e6 Use maintenance buttons on asset view 2026-03-31 13:58:49 +01:00
snipe dbc850550f Merge remote-tracking branch 'origin/develop' 2026-03-31 13:14:30 +01:00
snipe 1efe65e6ba Pint :( 2026-03-31 13:13:43 +01:00
snipe 6a39db7e47 Fixed history return 2026-03-31 13:13:35 +01:00
snipe 43841b8b3c Fixed return type 2026-03-31 10:12:24 +01:00
spencerrlongg c33ab9c924 wrap in array properly 2026-03-30 20:13:52 -05:00
spencerrlongg 135118de65 rm ->getMessage(), report full exception 2026-03-30 19:53:26 -05:00
spencerrlongg b42b9e354f rm dead route for freecheckout endpoint 2026-03-30 19:28:47 -05:00
snipe b59b51b2aa Merge remote-tracking branch 'origin/develop' 2026-03-30 20:17:53 +01:00
snipe 7677b3916d Removed parens 2026-03-30 20:17:43 +01:00
snipe b4debacd1a Merge remote-tracking branch 'origin/develop' 2026-03-30 20:06:48 +01:00
Godfrey M d91c26e718 fix bulk edit breadcrumb translation 2026-03-30 10:38:30 -07:00
snipe 8e64083f06 Removed “in active” class 2026-03-30 14:52:57 +01:00
snipe 56580f117a Fixed audit view tab on assets 2026-03-30 14:52:43 +01:00
snipe 29e994dfd0 Added manufacturer and category relationships 2026-03-30 13:05:57 +01:00
snipe b833daf943 Merge remote-tracking branch 'origin/develop' 2026-03-30 12:15:35 +01:00
snipe 537e09a0a6 Fixed #18779 - added audits tab back in 2026-03-30 12:13:56 +01:00
Joël Pittet f53f55b283 Fixes PKSA-4t1p-xpk2-nsss for aws/aws-sdk-php 2026-03-29 10:03:02 -07:00
snipe 943903d8d6 Merge remote-tracking branch 'origin/develop' 2026-03-28 10:36:48 +00:00
snipe 523920d6d6 Pint 2026-03-28 10:36:37 +00:00
snipe e39a242a76 Ignnore counts 2026-03-28 10:36:29 +00:00
snipe e3b57b0c2f Merge remote-tracking branch 'origin/develop' 2026-03-27 21:10:15 +00:00
snipe 125a9e4031 Merge pull request #18778 from grokability/advanced-search-for-licenses
Advanced search for licenses
2026-03-27 21:09:59 +00:00
snipe 9576871ff9 Pint. Sigh. 2026-03-27 21:02:37 +00:00
snipe 968724f369 Mark test as incomplete in SQLite 2026-03-27 21:02:26 +00:00
snipe 4444a63b92 Added created_at and searchableCounts 2026-03-27 20:39:27 +00:00
snipe 9924112d08 Use Filter request on categories API 2026-03-27 20:38:16 +00:00
snipe 368796c40e Added created_at to category search 2026-03-27 20:37:48 +00:00
snipe b9f6b2bbb8 Made user counts searchable 2026-03-27 20:36:45 +00:00
snipe 86afa9d201 Added advanced search to categories 2026-03-27 20:36:27 +00:00
snipe 294d320aa0 Added test 2026-03-27 20:18:13 +00:00
snipe bdd44061f3 Added ability to support aliased count/sum fields in search 2026-03-27 20:18:05 +00:00
snipe 8545d2d703 Made % remaining sortable 2026-03-27 19:21:55 +00:00
snipe 61f3180d74 Small fixes to Searchable trait 2026-03-27 19:21:41 +00:00
snipe 9efcb09836 Moved adminuser into SnipeModel 2026-03-27 19:21:27 +00:00
snipe 80b7ebd508 Moved adminuser method to the SnipeModel 2026-03-27 19:20:54 +00:00
snipe 4545cf8989 Removed broken(?) use statement 2026-03-27 19:20:11 +00:00
snipe 4dc5e8bbdb Use filter check 2026-03-27 19:19:48 +00:00
snipe 0261776778 Added FilterRequest and added refactorerd search check 2026-03-27 19:19:25 +00:00
snipe 1dfce30a32 Broke out the use statements for readaibility 2026-03-27 19:17:55 +00:00
snipe d7f44fdda4 Added license filter tests 2026-03-27 18:34:54 +00:00
snipe 8facdcd55c Added advanced search back to licenses 2026-03-27 18:34:36 +00:00
snipe 582b8858bc Pint 2026-03-27 18:34:15 +00:00
snipe 6d4264bc58 Refactor Searchable Trait to allow for filters 2026-03-27 18:34:05 +00:00
snipe 340433f418 Merge remote-tracking branch 'origin/develop' 2026-03-27 16:14:39 +00:00
snipe 107576eb01 Merge pull request #18777 from grokability/small-s3-fixes
Fixed #18573 - download URLs for S3, actually force the download
2026-03-27 15:53:48 +00:00
snipe ede406c904 Fixed #18573 - Removed extra slash in files controllers 2026-03-27 15:44:27 +00:00
snipe 3b875ce6ec Actually force the download in S3 2026-03-27 15:43:28 +00:00
snipe c89e14ae52 Removed unused showOrDownloadFile() method 2026-03-27 15:21:49 +00:00
snipe cff2fc0f16 Fixed typo 2026-03-27 13:39:39 +00:00
snipe e8b637b900 Allow qty parameter in partial 2026-03-27 12:59:24 +00:00
snipe 84bb484761 Merge remote-tracking branch 'origin/develop' 2026-03-26 17:50:06 +00:00
snipe 25c8fdd5d6 Fixed typo 2026-03-26 17:49:27 +00:00
snipe 6beaea8be9 Merge remote-tracking branch 'origin/develop' 2026-03-26 17:41:14 +00:00
snipe 7952bdefa8 Pint formatting 2026-03-26 17:40:56 +00:00
snipe 280d16637a Added file-specific policies 2026-03-26 17:40:49 +00:00
snipe cc397f6846 Merge remote-tracking branch 'origin/develop' 2026-03-26 16:27:40 +00:00
snipe bec443ce97 Tweaked checkin/checkout button statuses 2026-03-26 16:27:04 +00:00
snipe 8417007eb8 Fixed #18725 - scope by assetsForShow() 2026-03-26 16:26:33 +00:00
snipe 3db77f05e9 Merge remote-tracking branch 'origin/develop' 2026-03-26 16:05:51 +00:00
snipe 3c1eb27ce1 Merge pull request #18770 from grokability/#18767-added-uploads-for-companies
#18767 added uploads for companies
2026-03-26 16:05:20 +00:00
snipe 614a2cd5de Pint cleanup 2026-03-26 16:02:24 +00:00
snipe 616d0f00f9 Added #18767 - uploads for companies and departments 2026-03-26 16:02:07 +00:00
snipe ef22fb256b Fixed #18768 - people tab on locations 2026-03-26 14:52:43 +00:00
snipe 6e0dbc94d7 Merge remote-tracking branch 'origin/develop' 2026-03-26 13:01:33 +00:00
snipe 328a724920 Fixed #18764 - check for model category in info-panel 2026-03-26 13:01:23 +00:00
snipe f9e620a77f Merge remote-tracking branch 'origin/develop' 2026-03-26 12:57:18 +00:00
snipe 334f27424e Fixed #18765 - viewKeys hiding serial for non-licenses 2026-03-26 12:57:06 +00:00
snipe 45b7df15c3 Merge remote-tracking branch 'origin/develop' 2026-03-26 12:14:34 +00:00
snipe 316f1be3d0 Fixed typo and spacing 2026-03-26 12:14:20 +00:00
snipe a500dd4e9e Add generic history method and component blade for loggables 2026-03-26 12:13:59 +00:00
snipe 4fc35e30c4 Change permissions for maintenances tab 2026-03-26 11:21:31 +00:00
snipe 920676fbd7 Merge remote-tracking branch 'origin/develop' 2026-03-25 14:46:12 +00:00
snipe c2c90dd614 Fixed history count 2026-03-25 14:45:53 +00:00
snipe c69b83da3f Make user tab more flexible 2026-03-25 14:45:53 +00:00
snipe 3d43de0763 Added icons 2026-03-25 14:45:53 +00:00
snipe 413b571ce8 Merge pull request #18737 from guyguy333/public-s3-proxy
Add S3 proxy option
2026-03-25 14:35:56 +00:00
snipe e777d3a54c Merge pull request #18762 from vmikhnevych/debian13installer
Added #18761: Debian 13 support in snipeit.sh installer script
2026-03-25 14:32:17 +00:00
snipe 1981c7daef Merge remote-tracking branch 'origin/develop' 2026-03-25 14:10:22 +00:00
snipe 6a802f9c3c Added padding to pane 2026-03-25 14:09:19 +00:00
snipe f64912e461 Nicer padding in infopanel 2026-03-25 13:57:35 +00:00
snipe 6e3567f0bf Fixed weird BS tables search text local storage issue 2026-03-25 13:56:57 +00:00
snipe 9406b600f9 Formatting 2026-03-25 12:10:07 +00:00
snipe 1398b4cbd6 Small cleanup on the views, added comments to detail view blades 2026-03-25 12:09:56 +00:00
snipe bde097a827 Merge remote-tracking branch 'origin/develop' 2026-03-25 10:39:28 +00:00
snipe a4ad7a0baf Small tweaks to locations API 2026-03-25 10:39:12 +00:00
snipe a3927f25ce Use shorter buttons for opening in maps 2026-03-25 09:52:32 +00:00
snipe d5d8084f95 Remove unused translations 2026-03-25 09:52:19 +00:00
snipe b48fe19617 Added apple and google icon types 2026-03-25 09:51:56 +00:00
snipe f802ea4d38 Fixed tests 2026-03-25 09:20:51 +00:00
vmikhnevych 8107588576 Added #18761: Debian 13 support in snipeit.sh installer script 2026-03-25 10:01:08 +02:00
snipe 531dce4305 Merge remote-tracking branch 'origin/develop' 2026-03-24 23:12:13 +00:00
snipe 44e81dfb8a Fixed typo 2026-03-24 23:11:58 +00:00
snipe b4753e369c Fixed #18732 - use newer datepicker and wire up the today button for today’s date 2026-03-24 23:10:11 +00:00
snipe 7a5842712b Merge remote-tracking branch 'origin/develop'
# Conflicts:
#	public/css/build/app.css
#	public/css/build/app.css.map
#	public/css/build/overrides.css
#	public/css/build/overrides.css.map
#	public/css/dist/all.css
#	public/mix-manifest.json
2026-03-24 21:41:59 +00:00
snipe b479cdf358 Allow zero or null for accessory qty 2026-03-24 21:40:27 +00:00
snipe 222277de9a Used correct phone string for mobile 2026-03-24 21:38:10 +00:00
snipe e285ee2931 Small fixes in formatting 2026-03-24 21:33:46 +00:00
Godfrey M c4b20a16ce use full width if no field label present on TZe_24mm_E 2026-03-24 10:30:58 -07:00
snipe ae7d967227 Merge pull request #18754 from grokability/modernize-user-view
Modernize user view
2026-03-24 13:30:39 +00:00
snipe 2135efe8a9 Small fixes 2026-03-24 13:25:47 +00:00
snipe 00c617b2b8 Fixed typo 2026-03-24 13:06:09 +00:00
snipe 8dd105a31a Added missing path info 2026-03-24 12:51:18 +00:00
snipe 66aeaaefdb More tab tweaks 2026-03-24 12:48:23 +00:00
snipe eb68789327 Added cost well 2026-03-24 12:41:56 +00:00
snipe d73ab0daa0 Tweaked styles 2026-03-24 12:41:43 +00:00
snipe bce9a91408 Responsive tabs 2026-03-24 12:41:32 +00:00
snipe 43808b00ad Tweaked styles 2026-03-24 12:41:16 +00:00
snipe 17e8ef8e30 Added role to tab nav 2026-03-24 12:40:19 +00:00
snipe d02278930d Pass an alignment to the dl 2026-03-24 12:39:16 +00:00
snipe c2597a788b Hide the info panel toggle on smaller devices 2026-03-24 12:38:59 +00:00
snipe 227afd3965 Changed icon 2026-03-24 12:36:19 +00:00
snipe fc97b68503 Added API key count 2026-03-24 10:41:11 +00:00
snipe d83ec4ea05 Merge pull request #18755 from marcusmoore/fixes/18495-bulk-audit-date
Fixed #18495: properly handle null audit date during bulk audit
2026-03-23 23:13:27 +00:00
Marcus Moore 420bf9162d Populate test cases 2026-03-23 15:54:45 -07:00
Marcus Moore 8b1ec3d54b Improve test names 2026-03-23 15:39:56 -07:00
Marcus Moore ea3d970743 Add a couple sanity tests 2026-03-23 15:39:43 -07:00
Marcus Moore a0c905de33 Handle null next_audit_date 2026-03-23 15:38:57 -07:00
Marcus Moore 3517e040c4 Organization 2026-03-23 14:22:17 -07:00
Marcus Moore cf1fb87b63 Improve assertions 2026-03-23 14:16:59 -07:00
Marcus Moore b2389fb67c Scaffold test cases 2026-03-23 14:16:55 -07:00
Marcus Moore f9f57fb161 Merge branch 'develop' into fixes/18495-bulk-audit-date
# Conflicts:
#	tests/Feature/Assets/Api/AuditAssetTest.php
#	tests/Feature/Assets/Ui/AuditAssetTest.php
#	tests/Feature/Assets/Ui/CloneAssetTest.php
#	tests/Support/Settings.php
2026-03-23 11:49:34 -07:00
Marcus Moore a9f7d42d77 Formatting 2026-03-23 10:51:54 -07:00
Marcus Moore 537861c232 Add auditing group tag to tests 2026-03-23 10:50:12 -07:00
Marcus Moore 6eaea0b73f Merge branch 'develop' into laravel-12-take-2 2026-03-23 10:29:49 -07:00
Marcus Moore ee7dddf836 Update league/commonmark 2026-03-23 10:29:44 -07:00
snipe 4c493efb24 Bulk edit not working on locations now? 2026-03-23 15:00:03 +00:00
snipe 323d308c73 Overhaul user view 2026-03-23 14:59:52 +00:00
snipe 07ddc0e574 Fixed typo 2026-03-23 14:59:41 +00:00
snipe d159f6a3db More copy to clipboard 2026-03-23 14:59:15 +00:00
snipe 1bcfe94818 More icon stuff 2026-03-23 14:58:57 +00:00
snipe f7db8ef03d Fixed typo 2026-03-23 14:58:51 +00:00
snipe 1b2a46d7a0 Made name optional 2026-03-23 14:58:42 +00:00
snipe 0ff2a971a4 Moved new styles into default layout 2026-03-23 14:05:08 +00:00
snipe dce076157b Added new tabs 2026-03-23 14:04:44 +00:00
snipe 7cc0aa336b Added more copy links 2026-03-23 14:04:37 +00:00
snipe 5b193f7a7a Added helper function 2026-03-23 14:04:06 +00:00
snipe e290c70732 Added helper function 2026-03-23 14:03:54 +00:00
snipe a73e68fa1a Added icons 2026-03-23 14:03:45 +00:00
snipe b0578757d2 Merge pull request #18749 from grokability/added-percent-bars
Added percent bars to accessories, etc list views
2026-03-23 10:57:17 +00:00
snipe bf8082f0b9 Formatted tests via pint 2026-03-23 10:48:53 +00:00
snipe 04bebca323 Added unit tests 2026-03-23 10:47:16 +00:00
snipe 0fe753b7da Added % bars to accessories, licenses, etc 2026-03-23 10:41:48 +00:00
snipe 24c3c01851 Merge remote-tracking branch 'origin/develop' 2026-03-23 09:46:13 +00:00
snipe a6a211f386 Check for manufacturer model 2026-03-23 09:46:04 +00:00
snipe 603aa39e3f Merge remote-tracking branch 'origin/develop' 2026-03-23 09:41:07 +00:00
snipe 66607069fe Merge pull request #18740 from grokability/modern-ui-for-assets-view
Modern UI for assets view
2026-03-23 09:40:46 +00:00
snipe 54badc5545 Merge pull request #18748 from grokability/copilot/sub-pr-18740-another-one
[WIP] [WIP] Address feedback on Modern UI for assets view PR
2026-03-23 09:37:05 +00:00
snipe 64c07aa7b6 Merge pull request #18747 from grokability/copilot/sub-pr-18740-again
[WIP] [WIP] Address feedback on Modern UI for assets view PR
2026-03-23 09:36:34 +00:00
copilot-swe-agent[bot] 9d40df179d Guard last_checkout against null before calling diffForHumans
Co-authored-by: snipe <197404+snipe@users.noreply.github.com>
Agent-Logs-Url: https://github.com/grokability/snipe-it/sessions/dfb459ae-6819-47c9-8db5-67d70a8e9e2d
2026-03-23 09:35:35 +00:00
copilot-swe-agent[bot] af5e87970e fix: remove duplicate @elseif condition in currency prefix display
Co-authored-by: snipe <197404+snipe@users.noreply.github.com>
Agent-Logs-Url: https://github.com/grokability/snipe-it/sessions/191de9a3-2211-4805-b0f8-27dc485af039
2026-03-23 09:35:35 +00:00
copilot-swe-agent[bot] e9d7189e16 Initial plan 2026-03-23 09:34:43 +00:00
copilot-swe-agent[bot] 1cc15c3931 Initial plan 2026-03-23 09:34:35 +00:00
snipe dfb4cae5ed Merge pull request #18746 from grokability/copilot/sub-pr-18740-again
[WIP] [WIP] Address feedback on Modern UI for assets view PR
2026-03-23 09:32:21 +00:00
copilot-swe-agent[bot] c4c8750b26 Fix showCheckoutButton/showCheckinButton to call availability methods
Co-authored-by: snipe <197404+snipe@users.noreply.github.com>
Agent-Logs-Url: https://github.com/grokability/snipe-it/sessions/2cd4613d-eb6f-499d-8df3-4463e731a501
2026-03-23 09:31:07 +00:00
copilot-swe-agent[bot] aa25a68af8 Initial plan 2026-03-23 09:29:20 +00:00
snipe ad5c5e27bd Merge pull request #18745 from grokability/copilot/sub-pr-18740
Fix progress bar percentages: real 0–100 values with null guards
2026-03-23 09:27:27 +00:00
snipe 141e28d627 Deleted example blade component 2026-03-23 09:25:31 +00:00
snipe d0b28b6e65 Fixed ternary 2026-03-23 09:24:48 +00:00
copilot-swe-agent[bot] 068e6c0e92 Fix progress bar percentages: compute real 0-100 values with null guards and clamping
Co-authored-by: snipe <197404+snipe@users.noreply.github.com>
Agent-Logs-Url: https://github.com/grokability/snipe-it/sessions/bb7b5cc7-2a85-425c-be61-555bbaddc99c
2026-03-23 09:23:20 +00:00
copilot-swe-agent[bot] 95a342fc25 Initial plan 2026-03-23 09:19:49 +00:00
snipe b21efb91b5 Update app/Models/SnipeModel.php
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-03-23 09:15:30 +00:00
snipe d363793c56 Update resources/lang/en-US/general.php
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-03-23 09:15:11 +00:00
snipe 7e687e91c2 Update resources/views/blade/button/label.blade.php
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-03-23 09:13:41 +00:00
snipe 255c7e323f Update resources/views/blade/button/note.blade.php
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-03-23 09:13:25 +00:00
snipe d3fd535605 Merge remote-tracking branch 'origin/develop' 2026-03-23 08:59:36 +00:00
snipe 5992525d8e Merge pull request #18744 from grokability/added-percent-remaining-and-add-asset-button
Added % remaining and create asset button to models view and list
2026-03-23 08:59:23 +00:00
snipe 03b0e24289 Added % remaining and create asset button to models view and list 2026-03-23 08:54:13 +00:00
snipe f7f58ba12d Merge remote-tracking branch 'origin/develop' 2026-03-21 10:59:37 +00:00
snipe 595b5c865f Merge pull request #18742 from grokability/added-armenian-updated-languages
Added Armenian updated languages
2026-03-21 10:59:20 +00:00
snipe 2b2a015f51 Updated language strings 2026-03-21 10:57:56 +00:00
snipe 8160ebf854 Added Amenian 2026-03-21 10:57:28 +00:00
snipe dc27169129 Added Armenian as a language option 2026-03-21 10:47:03 +00:00
snipe 8d7cf50089 Merge remote-tracking branch 'origin/develop' 2026-03-21 10:20:26 +00:00
snipe 8498b9b6bd Use route model binding for department 2026-03-21 10:20:18 +00:00
snipe aead8f6c56 Merge remote-tracking branch 'origin/develop' 2026-03-21 10:03:19 +00:00
snipe d58fda626e Import company model 2026-03-21 10:02:18 +00:00
snipe 0f753ae5b5 Merge pull request #18739 from ubc-cpsc/fix/commonmark-PKSA-21fb-n1x5-5nf7
Fix CVE-2026-33347 and CVE-2026-30838 in league/commonmark
2026-03-21 09:51:01 +00:00
snipe 3371ac9552 Use calendar icon 2026-03-20 19:18:08 +00:00
snipe 1351df90f9 Link to manager in user profile if they have one and can see the user’s profile 2026-03-20 19:17:52 +00:00
snipe 02b6a928b4 Moved calendar stuff together in icon helper 2026-03-20 19:16:58 +00:00
snipe a1c72d8972 Added presenter 2026-03-20 18:23:17 +00:00
snipe 62596c875e New strings 2026-03-20 18:23:10 +00:00
snipe 282388fb33 New transformers 2026-03-20 18:23:04 +00:00
snipe afbd31ca01 Only allow audit if not deleted 2026-03-20 18:22:53 +00:00
snipe f1d32b8cae Show the field but with no data if no value 2026-03-20 18:22:39 +00:00
snipe fa7033f4e3 Hide buttons on print 2026-03-20 18:22:21 +00:00
snipe 46bcc7ede8 Added manufacturer to side panel 2026-03-20 18:22:13 +00:00
snipe 2adc10ed6e Make sure the object exists (only needed when models are invalid/broken 2026-03-20 18:22:01 +00:00
snipe ab8a88350f Added additional parameters for licenses table 2026-03-20 18:21:36 +00:00
snipe e1809f1c19 Only allow notes, labels if not deleted 2026-03-20 18:21:05 +00:00
snipe b8cc9ac788 Added checkin button 2026-03-20 18:20:46 +00:00
snipe 40c2a49e98 Progressbar and other work 2026-03-20 18:20:36 +00:00
snipe 1894f55474 Commented out a weird test 2026-03-20 18:19:52 +00:00
snipe 18a4c88ead RMB on licenses for assets API call 2026-03-20 18:19:42 +00:00
snipe 210fd6399a Helper methods to determine if the asset or thing can be checked in 2026-03-20 18:19:17 +00:00
Joël Pittet b91882f5dd Fix commonmark security update 2026-03-20 10:26:26 -07:00
snipe 6af827f595 Fixed weird copy icon on layout 2026-03-20 15:48:30 +00:00
snipe 200d92186c More updates to hardware view 2026-03-20 13:27:12 +00:00
snipe cc971dba4c Added info-panel components 2026-03-20 13:27:04 +00:00
snipe 35c0b3b8b1 Changed location for info-panel 2026-03-20 13:26:39 +00:00
snipe cf637f8f65 Added last note to language 2026-03-20 10:28:23 +00:00
snipe c86226c13b Made status component a bit more generic 2026-03-20 10:28:13 +00:00
snipe eaed40966a Added model to info-panel 2026-03-20 10:27:59 +00:00
snipe 5083207477 Updated model files tab component with correct hash 2026-03-20 10:27:50 +00:00
snipe 5f57402903 Added progressbar component 2026-03-20 10:27:29 +00:00
snipe 4c9ffe4eb9 Fixed suppliers tab component 2026-03-20 10:27:06 +00:00
snipe f705a2e24d Made (very messy) custom fields component 2026-03-20 10:25:47 +00:00
snipe 61a8567cc3 Updated copy to clipboard component 2026-03-20 10:25:30 +00:00
snipe 8e33a644cf Removed unused code 2026-03-20 10:25:01 +00:00
Marcus Moore e2e4743994 Attempt to handle docker build fail 2026-03-19 13:56:44 -07:00
Marcus Moore 7b1a5aea19 Revert "Allow installation when MAIL_FROM_ADDR is not set"
This reverts commit 602e13dab7.
2026-03-19 13:37:44 -07:00
Marcus Moore 602e13dab7 Allow installation when MAIL_FROM_ADDR is not set 2026-03-19 13:31:38 -07:00
Marcus Moore 64117b92b0 Revert "Add default address for docker"
This reverts commit 17c89a3f2b.
2026-03-19 13:19:23 -07:00
Marcus Moore 17c89a3f2b Add default address for docker 2026-03-19 12:07:24 -07:00
Guillaume Delbergue 1482abc8b9 feat: add PUBLIC_S3_PROXY option to serve public uploads through the app
When PUBLIC_S3_PROXY=true, public uploads (images, logos, avatars) are
served through a proxy controller instead of directly from S3. This
allows using a single fully private S3 bucket for all storage, with no
public ACLs or direct S3 URLs exposed to the browser.

The proxy streams files from the configured public disk with proper
cache headers (ETag, Last-Modified, Cache-Control). Disabled by default
for full backward compatibility.
2026-03-19 19:41:05 +01:00
Brady Wetherington 9d33a2c524 Merge branch 'develop' into use_new_laravel_scim_server 2026-03-19 17:41:18 +00:00
snipe af31dfd19c Formatting 2026-03-19 17:13:47 +00:00
snipe 53c090fd6c First stab 2026-03-19 17:13:24 +00:00
snipe 1aef412b13 Merge pull request #18735 from marcusmoore/fixes/54250-assigned-to-in-expiring-assets
Fixed FD-54250: Display assigned entity in expiring assets mail
2026-03-19 16:55:09 +00:00
Marcus Moore f9956cf617 Display assigned to in expiring assets mail 2026-03-19 09:30:47 -07:00
Guillaume Delbergue bc7473d863 feat: use Storage::disk('public')->url() instead of hardcoded upload URLs
Several presenters, models, transformers, and Blade views were building
upload URLs by concatenating config('app.url') with hardcoded '/uploads/'
paths. This only works with local storage and breaks when using S3 or
any non-local public disk. Replaced with Storage::disk('public')->url()
which respects the configured filesystem driver.

Made-with: Cursor
2026-03-19 13:52:36 +01:00
Marcus Moore a470ba76df Remove assertion
Log::setEventDispatcher(Event::fake()) no longer works...
2026-03-18 14:04:17 -07:00
snipe 84c42999e4 Merge remote-tracking branch 'origin/develop' 2026-03-18 20:04:59 +00:00
snipe 5f1566d6ab Fixed path for translations 2026-03-18 19:59:25 +00:00
snipe 87c5e3e01e Fixed path for non-deletable path info 2026-03-18 19:59:10 +00:00
snipe 27a554bebd Merge pull request #18728 from grokability/modernize-views
Modernize views
2026-03-18 19:57:36 +00:00
Marcus Moore 3ce017fa68 Upgrade to Laravel 12
Co-authored-by: Brady Wetherington <bwetherington@grokability.com>
2026-03-18 12:36:16 -07:00
Marcus Moore d446da2243 Update telescope 2026-03-18 12:23:46 -07:00
Marcus Moore cdb4416421 Update collision 2026-03-18 12:21:38 -07:00
Marcus Moore a1de8aa20c Bump phpunit to v11 2026-03-18 12:20:57 -07:00
Marcus Moore adfad90f7c Bump laravel-backup to v9
Co-authored-by: Brady Wetherington <bwetherington@grokability.com>
2026-03-18 12:17:46 -07:00
Marcus Moore 22703806cd Bump larastan to v3 2026-03-18 12:11:20 -07:00
Marcus Moore 22a63fc2ee Bump scim server 2026-03-18 12:10:33 -07:00
snipe eec2773c88 Changed history icon 2026-03-18 17:01:10 +00:00
snipe c1c3c6724f Use history tab icon 2026-03-18 17:00:59 +00:00
snipe 0223304ec7 Moved files table header into component 2026-03-18 16:35:47 +00:00
snipe 08f9879ada Added details and models tab nav 2026-03-18 16:31:59 +00:00
snipe 29559485e2 Removed erroneous content slot 2026-03-18 16:17:52 +00:00
snipe 6e100177da Nicer UI for groups 2026-03-18 15:57:18 +00:00
snipe d36e17eaae Check for deletability in groups 2026-03-18 15:57:11 +00:00
snipe 51e60d2d6b Fixed name in companies 2026-03-18 15:28:32 +00:00
snipe 995276643c Updated suppliers view to use more specific components 2026-03-18 15:20:02 +00:00
snipe a3c792619d Updated company to use specific blade components 2026-03-18 15:19:29 +00:00
snipe 946161a514 Updated icon 2026-03-18 15:18:51 +00:00
snipe 075be02f96 Added maintenance tab element 2026-03-18 15:18:46 +00:00
snipe 3664bbf423 Changed to use table_header slot 2026-03-18 15:17:19 +00:00
snipe 820b41927d Updated icon 2026-03-18 15:16:31 +00:00
snipe 7ff5927409 Removed active class - this is handled via JS now 2026-03-18 15:15:47 +00:00
snipe f93b40f402 Smaller header for tables 2026-03-18 14:40:16 +00:00
snipe 7d226a6dca Set default API routes in table components 2026-03-18 14:16:29 +00:00
snipe 7b2edd0762 Use table components 2026-03-18 13:20:36 +00:00
snipe 5dc0401f23 Use correct bulk edit component 2026-03-18 13:18:19 +00:00
snipe b5164e4c92 Remove sticky header from maintenance report 2026-03-18 13:17:15 +00:00
snipe e1a06fa188 Switch to users table component 2026-03-18 13:16:57 +00:00
snipe b2ec69ce7f Make table blades more flexible 2026-03-18 13:16:15 +00:00
snipe a9706f6d5e Added users table component 2026-03-18 12:48:54 +00:00
snipe cee2b77fbc Moved filestable into table component directory 2026-03-18 12:48:34 +00:00
snipe 3425599461 Moved filestable into table blade directory 2026-03-18 12:47:46 +00:00
snipe 104123495d Use generic name translation 2026-03-18 12:44:32 +00:00
snipe c2735fce90 Added sumformatter 2026-03-18 12:44:22 +00:00
snipe d4ff9dce24 Added sumformatter 2026-03-18 12:44:11 +00:00
snipe 5c8a62d9b7 Added wrap-prevention on tag colors 2026-03-18 12:21:20 +00:00
snipe 87fa71c599 Use table component for maintenance index 2026-03-18 08:11:02 +00:00
snipe 0b08b8007b Use table component for maintenances 2026-03-18 08:10:40 +00:00
snipe 3e93684451 Added sumformatter to maintenances 2026-03-18 08:09:59 +00:00
Godfrey M 8747ff32dd Merge branch 'develop' into update-print-invtentory-view-with-assigned2assets
# Conflicts:
#	app/Http/Controllers/ProfileController.php
#	app/Http/Controllers/Users/UsersController.php
2026-03-17 16:11:16 -07:00
snipe 218190d989 Merge remote-tracking branch 'origin/develop' 2026-03-17 14:01:35 +00:00
snipe 0a4ec84875 Use has instead of filled for email, username, etc 2026-03-17 13:58:59 +00:00
snipe 33402f5e0c Merge remote-tracking branch 'origin/develop' 2026-03-17 13:29:13 +00:00
snipe d0e57cfab6 Added null operator in the case of a bad status label on asset audit 2026-03-17 13:27:46 +00:00
snipe 0ebd103e21 Merge remote-tracking branch 'origin/develop' 2026-03-17 13:11:20 +00:00
snipe 95ba562021 Remove int from asset_maintenance_time 2026-03-17 13:11:10 +00:00
snipe 67f5fb72c3 Merge remote-tracking branch 'origin/develop' 2026-03-17 12:22:34 +00:00
snipe 62cadfdc8c Removed permissions on report view 2026-03-17 12:22:26 +00:00
snipe 27e8995cce Merge pull request #18722 from grokability/improve-maintenance-report
Improved asset maintenance report
2026-03-17 12:21:24 +00:00
snipe e2406e33d8 Improved asset maintenance report 2026-03-17 12:16:31 +00:00
snipe da2dd79765 Merge pull request #18720 from marcusmoore/pint-tests
Apply pint to tests directory
2026-03-17 10:32:40 +00:00
snipe 4568180e85 Merge remote-tracking branch 'origin/develop' 2026-03-17 09:07:00 +00:00
Marcus Moore cc8f59d9e0 Add pint commits 2026-03-16 17:41:25 -07:00
Marcus Moore 446f5f3cef Run pint on tests 2026-03-16 17:40:57 -07:00
Marcus Moore d84eb43278 Snake case FMCS and permission methods in tests 2026-03-16 17:36:35 -07:00
snipe bb72dab877 Merge pull request #18719 from marcusmoore/ignore-revs
Add .git-blame-ignore-revs file
2026-03-16 23:41:08 +00:00
Marcus Moore b06762ea4f Fix commits 2026-03-16 15:31:41 -07:00
Marcus Moore 33d75cdd2d Fix commit 2026-03-16 15:25:52 -07:00
Marcus Moore 3372b7a647 Fix comments 2026-03-16 15:25:03 -07:00
Marcus Moore 4e0d34b826 Create and add styling commits to .git-blame-ignore-revs 2026-03-16 15:24:16 -07:00
snipe 324c937cc4 Merge remote-tracking branch 'origin/develop' 2026-03-16 21:06:38 +00:00
snipe 908d04e98a Merge pull request #18718 from grokability/added-blade-component-for-status
Added status component box
2026-03-16 21:06:24 +00:00
snipe 79fd541498 Removed if/else 2026-03-16 20:57:18 +00:00
snipe 8c360a26e5 Added status component box 2026-03-16 20:49:15 +00:00
snipe 93ae07cc89 Merge remote-tracking branch 'origin/develop' 2026-03-16 20:08:56 +00:00
snipe 713a726bde Merge pull request #18717 from grokability/#18574-add-checked-out-to-to-maintenances
Fixed #18574 - adds checked out field to maintenances
2026-03-16 20:05:26 +00:00
snipe 100f1683be Added checkout info to view 2026-03-16 19:59:09 +00:00
snipe ed201b24d6 Fixed #18574 - adds checked out field to maintenances 2026-03-16 19:54:04 +00:00
snipe 0b7ebcaeb0 Merge pull request #18543 from Godmartinz/changing-recipient-header-to-cc
Fix CC Mail header for checkouts and check-ins
2026-03-16 10:41:28 +00:00
snipe 52a9993b0d Merge remote-tracking branch 'origin/develop' 2026-03-16 10:36:13 +00:00
snipe 4e733fab02 Merge pull request #18714 from grokability/#17348-show-deleted-assets-for-deleted-models
Fixed #17348 - show deleted assets for deleted models
2026-03-16 10:35:59 +00:00
snipe 3257c6e709 Updated restore button to be inline 2026-03-16 10:30:48 +00:00
snipe ece4ed4caf Added optional deleted_at constraint 2026-03-16 10:30:36 +00:00
snipe fa04891ddb Added tooltip for clone and edit 2026-03-16 10:24:25 +00:00
ArturoSirvent 6145c6cc5a Fix backup disk driver configuration for S3 support
- Fix the backup disk in config/filesystems.php to use a dedicated BACKUP_FILESYSTEM_DRIVER env var instead of PRIVATE_FILESYSTEM_DISK
- Add AWS credential fields to the backup disk config so S3 backups work
- Use BACKUP_FILESYSTEM_ROOT with safe default (storage_path('app')) for local driver
- Document BACKUP_FILESYSTEM_DRIVER and BACKUP_FILESYSTEM_ROOT in .env.example

Fixes #14057
2026-03-14 23:24:58 +01:00
snipe dffff07436 Removed codacy config 2026-03-13 18:29:21 +00:00
snipe 97854ad02d Bumped hash 2026-03-13 18:27:23 +00:00
snipe 500d6e1f2d Merge remote-tracking branch 'origin/develop'
# Conflicts:
#	config/version.php
2026-03-13 18:25:48 +00:00
snipe f69e2c671b Merge pull request #18709 from grokability/pint-resources
Applied pint to languages and resources
2026-03-13 18:22:55 +00:00
snipe 84fdb5d6c1 Applied pint to languages and resources 2026-03-13 18:17:51 +00:00
snipe dc58ddce59 Merge pull request #18708 from grokability/pint-database
Apply pint to database directory
2026-03-13 18:14:02 +00:00
snipe b5a46a370f Apply pint to database directory 2026-03-13 18:12:37 +00:00
snipe 199bdb219f Merge pull request #18707 from grokability/pint-config
Apply pint to config directory
2026-03-13 18:11:02 +00:00
snipe c1a93e3ac8 Apply pint to config directory 2026-03-13 18:08:12 +00:00
snipe f334b8caa3 Merge pull request #18706 from grokability/pint-providers
Apply pint to Providers directory
2026-03-13 18:03:57 +00:00
snipe 8b658a19b9 Apply pint to Providers directory 2026-03-13 17:56:51 +00:00
snipe 59dd9970d0 Merge pull request #18705 from grokability/pint-presenters
Apply pint to Presenters directory
2026-03-13 17:53:04 +00:00
snipe 55d46cbefe Apply pint to Presenters directory 2026-03-13 17:43:54 +00:00
snipe e37ce27773 Merge pull request #18704 from grokability/pint-policies-and-observers
Apply pint to Observers and Policy directories
2026-03-13 17:42:57 +00:00
snipe b2c0a21230 Apply pint to Observers and Policy directories 2026-03-13 17:41:08 +00:00
snipe 00704aea73 Merge pull request #18703 from grokability/pint-notifications
Apply pint to Notifications directory
2026-03-13 17:39:24 +00:00
snipe 31043d1f5c Apply pint to Notifications directory 2026-03-13 17:37:47 +00:00
snipe 33b68c11db Merge pull request #18702 from grokability/pint-mail
Apply pint to Mail directory
2026-03-13 17:32:33 +00:00
snipe de607e7d83 Apply pint to Mail directory 2026-03-13 17:26:56 +00:00
snipe ab7ff30a73 Merge pull request #18701 from grokability/pint-livewire
Applied pint to Livewire directory
2026-03-13 17:25:21 +00:00
snipe 53f2ef2ca1 Applied pint to Livewire directory 2026-03-13 17:19:19 +00:00
snipe 25f2e560f1 Merge pull request #18700 from grokability/pint-jobs-listeners
Apply pint to Jobs and Listeners directory
2026-03-13 17:18:21 +00:00
snipe 317b1a462e Apply pint to Jobs and Listeners directory 2026-03-13 17:13:08 +00:00
snipe bf97734533 Merge pull request #18699 from grokability/pint-importer
Apply pint to Importer directory
2026-03-13 17:11:35 +00:00
snipe 3e831bf9b3 Apply pint to Importer directory 2026-03-13 17:10:06 +00:00
snipe b4400b38a9 Merge pull request #18698 from grokability/pint-traits-and-transformers
Applied pint to Traits and Transformers
2026-03-13 17:07:54 +00:00
snipe a613380811 Applied pint to Traits and Transformers 2026-03-13 17:02:28 +00:00
snipe 7f30fe1a95 Merge pull request #18697 from grokability/pint-requests
Apply pint to Requests directory
2026-03-13 17:00:47 +00:00
snipe 93168326da Apply pint to Requests directory 2026-03-13 16:56:26 +00:00
snipe 70c672eb52 Merge pull request #18696 from grokability/pint-middleware
Apply pint to Middleware directory
2026-03-13 16:54:17 +00:00
snipe ec6caf9b59 Apply pint to Middleware directory 2026-03-13 16:53:11 +00:00
snipe 1f1d41ecfd Merge pull request #18695 from grokability/pint-controllers
Apply pint to non-API controllers
2026-03-13 16:50:28 +00:00
snipe 9bc92f57c8 Apply pint to non-API controllers 2026-03-13 16:45:30 +00:00
snipe bbe6475eb2 Merge pull request #18694 from grokability/pint-api-controllers
Apply pint to API controllers
2026-03-13 16:43:33 +00:00
snipe 1e5d426e70 Apply pint to API controllers 2026-03-13 16:38:23 +00:00
snipe ccf6856143 Apply pint to Helpers 2026-03-13 16:37:19 +00:00
snipe 175d8306b8 Merge pull request #18693 from grokability/pint-exceptions
Apply pint to Exceptions directory
2026-03-13 16:35:43 +00:00
snipe 2e7046a810 Apply pint to Exceptions directory 2026-03-13 16:32:11 +00:00
snipe c03c913ce7 Merge pull request #18692 from grokability/pint-enums
Apply pint to enums and events
2026-03-13 16:30:52 +00:00
snipe f7b82ad1ff Apply pint to enums and events 2026-03-13 16:25:59 +00:00
snipe 118ddfce94 Merge pull request #18691 from grokability/pint-console
Apply pint to Console directory
2026-03-13 16:24:39 +00:00
snipe 8bce38b918 Apply pint to Console directory 2026-03-13 16:20:24 +00:00
snipe d31ba20dd5 Merge pull request #18690 from grokability/pint-actions
Use pint on actions directory
2026-03-13 16:19:11 +00:00
snipe a3c7410c35 Apply pint to actions directory 2026-03-13 16:04:34 +00:00
snipe 624e6839c3 Merge pull request #18689 from grokability/pint-models
Use pint on models directory
2026-03-13 16:02:51 +00:00
snipe 9623fa4d87 Use pint on models directory 2026-03-13 15:55:28 +00:00
snipe c196637922 Install pint dev dependency 2026-03-13 14:52:13 +00:00
snipe 67284e2e6d Updated badge in readme 2026-03-13 11:17:36 +00:00
snipe f6ee500e6c Merge pull request #18684 from marcusmoore/copilot-updates
Updated copilot instructions
2026-03-13 11:16:41 +00:00
snipe b76d909619 Merge pull request #18685 from marcusmoore/test-improvements
Improved asset tests
2026-03-13 11:16:29 +00:00
snipe faf9cecc10 Merge pull request #18688 from grokability/normalize-requests-with-class-reference
Use Blah::class instead of new Blah in form requests
2026-03-13 11:09:42 +00:00
snipe 1246de2644 Use Blah::class instead of new Blah in form requests 2026-03-13 11:02:05 +00:00
snipe 0c72109ad8 Revert RMB for more consistent UX 2026-03-13 09:34:26 +00:00
Marcus Moore 5aad15256c Improve tests around assets 2026-03-12 16:15:27 -07:00
Marcus Moore 69f7778067 Revise copilot instructions 2026-03-12 15:56:37 -07:00
snipe 5d6b9890ca Import eloquent model 2026-03-12 18:44:45 +00:00
snipe 20382ea5bf Merge remote-tracking branch 'origin/develop' 2026-03-12 14:54:28 +00:00
snipe 0d257d956f Undo json encode 2026-03-12 14:54:18 +00:00
snipe f853d25d4f Merge remote-tracking branch 'origin/develop' 2026-03-12 14:46:48 +00:00
snipe 4c05f26940 Merge pull request #18681 from grokability/redirect-fixes
Use intended() for redirect options
2026-03-12 14:44:38 +00:00
snipe ce18ff669c Added admin check 2026-03-12 14:42:36 +00:00
snipe a3b5346773 Ignore the sqlite database in git 2026-03-12 14:24:59 +00:00
snipe 3c96491295 Remove unused route 2026-03-12 14:24:46 +00:00
snipe 53abf8cdcc Load count with RMB controller 2026-03-12 14:10:43 +00:00
snipe e376492128 Use intended() for redirect options 2026-03-12 13:57:50 +00:00
snipe 2658b9b064 Fixed variable in trans_choice for deployable check 2026-03-12 13:47:23 +00:00
snipe 46e7e12cb2 Merge remote-tracking branch 'origin/develop' 2026-03-12 13:41:06 +00:00
snipe f412b56caa Fixed #18678 - small UI tweaks 2026-03-12 13:40:47 +00:00
snipe 9c63b40a5a Merge pull request #18680 from grokability/copilot
Added copilot instructions file
2026-03-12 13:21:38 +00:00
snipe 40843f93dc Added copilot instructions file 2026-03-12 13:20:37 +00:00
snipe 9165f59dcc Normalized requiered colors 2026-03-12 12:23:20 +00:00
snipe 92ff333778 Force foreground color for label form-control 2026-03-12 12:13:59 +00:00
snipe 63e62cde1b Moved gates higher, switch to RMB for accessories 2026-03-12 12:13:38 +00:00
snipe c5081ce3e5 Added colors to setting seeder 2026-03-12 11:47:04 +00:00
snipe 67d2a5d094 Use better maintenance name 2026-03-12 11:44:40 +00:00
snipe a170da5c01 Merge pull request #18679 from grokability/normalize-breadcrumb-text
Normalize breadcrumb text
2026-03-12 11:42:27 +00:00
snipe 9652cb312a Normalize breadcrumb text 2026-03-12 11:34:38 +00:00
snipe e4d7e08902 Merge pull request #18672 from marcusmoore/remove-laravel-collective-dep
Fixed #17199: Remove Laravel Collective HTML dependency
2026-03-11 19:53:25 +00:00
snipe ce3a7bb687 Merge remote-tracking branch 'origin/develop' 2026-03-11 17:57:10 +00:00
snipe 428095b71b Fixed #18670 - set nav link color override in ResetDemo console command 2026-03-11 17:56:58 +00:00
Marcus Moore 411ffb12ca Merge branch 'develop' into remove-laravel-collective-dep 2026-03-11 10:41:06 -07:00
snipe 3b93193da1 Merge pull request #18667 from marcusmoore/migrate-link-methods
Fixed #18666: Migrate Laravel Collective helper methods
2026-03-11 10:14:31 +00:00
snipe 17584e4799 Merge remote-tracking branch 'origin/develop' 2026-03-11 09:33:14 +00:00
snipe 224a813f25 Fixed #18668 - changed button type 2026-03-11 09:33:03 +00:00
Marcus Moore 7d079f74a1 Uninstall laravelcollective/html 2026-03-10 16:52:42 -07:00
Marcus Moore 4ca53e6f70 Remove Collective provider and aliases 2026-03-10 16:45:48 -07:00
Marcus Moore 70d1ffe294 Remove MacroServiceProvider and macros.php 2026-03-10 16:39:30 -07:00
Marcus Moore 335e1a7e18 Merge branch 'develop' into migrate-link-methods 2026-03-10 16:35:23 -07:00
Marcus Moore 287481a44e Fix model reference 2026-03-10 13:38:14 -07:00
Marcus Moore 2dd09f9702 Remove unused method 2026-03-10 13:35:25 -07:00
snipe 1503f90394 Merge remote-tracking branch 'origin/develop' 2026-03-10 20:26:06 +00:00
snipe 9317d6551d Fixed #18653 - “select company” to “company” in user edit 🙄 2026-03-10 20:25:53 +00:00
snipe d2834fcdb9 Merge remote-tracking branch 'origin/develop' 2026-03-10 20:13:10 +00:00
snipe ed3d30e343 Merge pull request #18657 from marcusmoore/form-macros
Fixed #17200 and #17201: Remove alt_barcode_types and barcode_types macros
2026-03-10 20:11:01 +00:00
Marcus Moore ca5a25f703 Replace remaining calls to link_to_route in Presenters 2026-03-10 13:06:46 -07:00
Godfrey M 4ddd2f1cf8 change indirect Asset name 2026-03-10 12:49:37 -07:00
Godfrey M 11c8fd4d4c update scope for directLicense.category" 2026-03-10 12:41:19 -07:00
Godfrey M ab04f3de93 use inventory scope, add quantity to print blade 2026-03-10 12:35:34 -07:00
Marcus Moore 692a9ebebf Replace call to link_to_route 2026-03-10 11:58:27 -07:00
Marcus Moore bf314a0f84 Replace call to link_to_route 2026-03-10 11:54:29 -07:00
Marcus Moore c8c2bb6709 Remove unused serialUrl method from LicensePresenter 2026-03-10 11:31:07 -07:00
Godfrey M 4c16796256 reduce query count to 52 2026-03-10 10:59:59 -07:00
Marcus Moore 3fc8b976fc Merge branch 'develop' into form-macros
# Conflicts:
#	resources/macros/macros.php
2026-03-10 10:12:31 -07:00
Godfrey M 516771d948 update profile Controller print inventory 2026-03-10 09:50:00 -07:00
snipe 6b9dc97fa1 Merge pull request #18665 from grokability/#18662-fix-seat-search
Fixed #18662 wire up search box in assigned license seats
2026-03-10 16:10:37 +00:00
snipe 69d7d6aae2 Fixed #18661 - return true/false in JSON 2026-03-10 15:43:13 +00:00
snipe 4f3a30261e Fixed #18661 - return true/false in JSON 2026-03-10 15:42:35 +00:00
snipe e7c478318c Fixed donked route 2026-03-10 15:39:29 +00:00
snipe e75860c6ee Fixed #18662 wire up search box in assigned license seats 2026-03-10 15:31:54 +00:00
snipe 982766dd77 Merge remote-tracking branch 'origin/develop' 2026-03-10 11:40:14 +00:00
snipe d0dbd1e561 Link parent company 2026-03-10 11:40:03 +00:00
snipe 81cbad52f7 Merge remote-tracking branch 'origin/develop' 2026-03-10 10:25:21 +00:00
snipe e7eb4f0e80 More display_name 2026-03-10 10:25:01 +00:00
snipe f1ef1bc38a Merge remote-tracking branch 'origin/develop' 2026-03-10 10:22:57 +00:00
snipe 676a995889 Use update check for files controller api 2026-03-10 10:22:39 +00:00
snipe b696642993 Merge remote-tracking branch 'origin/develop' 2026-03-10 10:14:47 +00:00
snipe a44fe14de1 Use display_name in more places 2026-03-10 10:14:27 +00:00
snipe e7bb7d3656 Merge remote-tracking branch 'origin/develop' 2026-03-10 09:54:08 +00:00
snipe 0015dbcd1d Merge pull request #18656 from marcusmoore/form-macro-username-select
Fixed #17208: Replace username_format macro
2026-03-10 09:42:15 +00:00
snipe fc5e7cccbc Merge pull request #18652 from grokability/dependabot/github_actions/develop/docker/login-action-4
Bump docker/login-action from 3 to 4
2026-03-10 09:41:54 +00:00
dependabot[bot] 8987f3f951 Bump docker/login-action from 3 to 4
Bumps [docker/login-action](https://github.com/docker/login-action) from 3 to 4.
- [Release notes](https://github.com/docker/login-action/releases)
- [Commits](https://github.com/docker/login-action/compare/v3...v4)

---
updated-dependencies:
- dependency-name: docker/login-action
  dependency-version: '4'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-10 09:30:14 +00:00
snipe ba671a8f1f Merge pull request #18651 from grokability/dependabot/github_actions/develop/docker/build-push-action-7
Bump docker/build-push-action from 6 to 7
2026-03-10 09:29:32 +00:00
snipe fbe871f8d1 Merge pull request #18650 from grokability/dependabot/github_actions/develop/docker/metadata-action-6
Bump docker/metadata-action from 5 to 6
2026-03-10 09:29:10 +00:00
snipe 116b2d1229 Merge pull request #18649 from grokability/dependabot/github_actions/develop/docker/setup-buildx-action-4
Bump docker/setup-buildx-action from 3 to 4
2026-03-10 09:28:03 +00:00
snipe 20fd870b59 Merge pull request #18658 from marcusmoore/form-macro-countries
Fixed #17202: Replaced countries form macro
2026-03-10 09:27:05 +00:00
snipe 5c46990195 Check for user on enable_sounds 2026-03-10 09:20:35 +00:00
snipe fab57020f2 Prevent browser errors since input field is display none 2026-03-10 09:16:24 +00:00
snipe b37074f473 Null check on status (RB-4087) 2026-03-10 09:03:57 +00:00
snipe 24e2e81a28 Use component table in suppliers 2026-03-10 09:00:29 +00:00
Marcus Moore ccabc1fbcc Remove countries macro 2026-03-09 17:37:58 -07:00
Marcus Moore f847f83cb8 Replace macro in location modal 2026-03-09 17:36:26 -07:00
Marcus Moore e0771827aa Replace country in address partial 2026-03-09 17:34:57 -07:00
Marcus Moore fa6adaa155 Migrate countries macro on user page 2026-03-09 17:22:43 -07:00
Marcus Moore f3504ce6fc Remove barcode_types macro 2026-03-09 16:36:54 -07:00
Marcus Moore a075ca904b Remove alt_barcode_types macro 2026-03-09 16:36:26 -07:00
Marcus Moore e3fb6fabf8 Remove username_format maco 2026-03-09 16:30:12 -07:00
Marcus Moore 6f89af790e Migrate username format to blade component 2026-03-09 16:29:55 -07:00
snipe 28f493d84d Escape pivot notes 2026-03-09 09:06:58 +00:00
dependabot[bot] a87e862148 Bump docker/build-push-action from 6 to 7
Bumps [docker/build-push-action](https://github.com/docker/build-push-action) from 6 to 7.
- [Release notes](https://github.com/docker/build-push-action/releases)
- [Commits](https://github.com/docker/build-push-action/compare/v6...v7)

---
updated-dependencies:
- dependency-name: docker/build-push-action
  dependency-version: '7'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-09 08:42:34 +00:00
dependabot[bot] 6e264bfee0 Bump docker/metadata-action from 5 to 6
Bumps [docker/metadata-action](https://github.com/docker/metadata-action) from 5 to 6.
- [Release notes](https://github.com/docker/metadata-action/releases)
- [Commits](https://github.com/docker/metadata-action/compare/v5...v6)

---
updated-dependencies:
- dependency-name: docker/metadata-action
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-09 08:42:27 +00:00
dependabot[bot] 1ecf862f2d Bump docker/setup-buildx-action from 3 to 4
Bumps [docker/setup-buildx-action](https://github.com/docker/setup-buildx-action) from 3 to 4.
- [Release notes](https://github.com/docker/setup-buildx-action/releases)
- [Commits](https://github.com/docker/setup-buildx-action/compare/v3...v4)

---
updated-dependencies:
- dependency-name: docker/setup-buildx-action
  dependency-version: '4'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-09 08:42:22 +00:00
snipe 338fc88095 Merge pull request #18647 from grokability/revert-18601-chore/security-upgrade-passport13-socialite-jwt7
Revert "Upgrade Passport to v13 and move php-jwt to v7 to remediate JWT advisory"
2026-03-08 12:32:31 +00:00
snipe 0a724cc49a Revert "Upgrade Passport to v13 and move php-jwt to v7 to remediate JWT advisory" 2026-03-08 12:29:56 +00:00
snipe a2efcf1ca9 Merge pull request #18601 from ubc-cpsc/chore/security-upgrade-passport13-socialite-jwt7
Upgrade Passport to v13 and move php-jwt to v7 to remediate JWT advisory
2026-03-08 11:51:15 +00:00
snipe ffc9e882d7 Merge remote-tracking branch 'origin/develop' 2026-03-08 11:37:38 +00:00
snipe c9d73e85e1 Fixed RB-4083 2026-03-08 11:37:19 +00:00
Joël Pittet a956676745 Move Passport 13 key permission normalization to upgrade.php to cover existing installs with incorrect permissions 2026-03-07 22:22:46 -08:00
Joël Pittet 5800d08202 normalize key permissions 2026-03-07 21:59:07 -08:00
Joël Pittet b8958bad72 Test failure fixes from 'Key Files Permissions Validation' from https://github.com/laravel/passport/blob/13.x/UPGRADE.md#key-files-permissions-validation 2026-03-07 21:59:00 -08:00
Joël Pittet 0508d7558e OAuth Client Table Changes (Optional) from https://github.com/laravel/passport/blob/13.x/UPGRADE.md#oauth-client-table-changes-optional 2026-03-07 21:59:00 -08:00
Joël Pittet 98c3192a13 Bump laravel/socialite to latest patch release, upgrade laravel/passport to 13 which is compatible with Laravel 11, and security release for firebase/php-jwt 2026-03-07 21:59:00 -08:00
snipe 6e7ff15e78 Merge remote-tracking branch 'origin/develop' 2026-03-07 20:50:31 +00:00
snipe b886e11670 Fixed user API tests 2026-03-07 20:50:18 +00:00
snipe b0c45c7179 Merge remote-tracking branch 'origin/develop' 2026-03-07 11:05:48 +00:00
snipe 92bb1df82e Removed error log in test 2026-03-07 11:05:33 +00:00
snipe 1c4549dd8e Added word break on history 2026-03-07 11:04:25 +00:00
snipe 83e61ec8cd Unset admin if auth user is not admin 2026-03-07 10:45:57 +00:00
snipe 7ea549df4a Added .journal to gitignore 2026-03-06 21:57:23 +00:00
snipe 0fabc5d88d Merge remote-tracking branch 'origin/develop' 2026-03-06 21:55:59 +00:00
snipe af1c55cd7e Small code re-org for clarity 2026-03-06 21:55:46 +00:00
snipe 7822c0bc3e Merge pull request #18644 from uberbrady/fix_location_observer
Re-add Location Observer with null-safe companyable check
2026-03-06 21:47:58 +00:00
Brady Wetherington 2b7ed1f7fa Re-add Location Observer with null-safe companyable check 2026-03-06 21:43:19 +00:00
snipe 33ae9f1d5b Merge remote-tracking branch 'origin/develop' 2026-03-06 20:15:11 +00:00
snipe 45ddaf1b72 Temp comment out location observer 2026-03-06 20:14:56 +00:00
snipe f27aae5e31 Merge remote-tracking branch 'origin/develop' 2026-03-06 14:03:50 +00:00
snipe 7595c922fa Fixed #18043 - added location logging 2026-03-06 14:03:37 +00:00
snipe ff6a6407f5 Merge remote-tracking branch 'origin/develop' 2026-03-06 13:40:16 +00:00
snipe 4d4513d936 Fixed #18642 - view-assets mobile 2026-03-06 13:40:01 +00:00
snipe e378c99923 Layout tweakas 2026-03-06 13:29:38 +00:00
snipe 32a6c8edbe Merge remote-tracking branch 'origin/develop'
# Conflicts:
#	public/js/dist/all.js
#	public/js/dist/all.js.map
#	public/mix-manifest.json
2026-03-06 10:48:34 +00:00
snipe 078c870970 Merge pull request #18162 from Godmartinz/status_bulk_select_fix
Adds #17685 better warning for bulk status change to undeployable type
2026-03-06 09:58:41 +01:00
snipe 4a91d37423 Merge pull request #17666 from akemidx/xxdays-since-last-update
Feature: Added xx days since last update to Custom Report
2026-03-06 09:54:32 +01:00
snipe 96befb2aef Merge branch 'develop' into xxdays-since-last-update 2026-03-06 09:54:01 +01:00
snipe 925452e106 Merge pull request #18248 from iryadifarhan/fix/depreciation-report-displays-incorrect-monthly-depreciation-value
Fixes inaccurate monthly depreciation value displayed at depreciation report when using a floor value
2026-03-06 09:40:39 +01:00
snipe 1678330f0c Merge pull request #18426 from akemidx/global-report-templates
Fixed: Added global report templates
2026-03-06 09:30:15 +01:00
snipe 58cf3fc2ea Dev assets 2026-03-06 08:17:48 +00:00
snipe 13ce17ffc6 Merge pull request #18494 from marcusmoore/livewire4
Upgraded Livewire to v4
2026-03-06 09:16:25 +01:00
snipe 70e020ee0c Merge pull request #18637 from marcusmoore/test-updates
Fixed some minor issues in tests
2026-03-06 09:16:00 +01:00
snipe c6a167ef40 Removed min-height (this might go badly) 2026-03-06 07:42:28 +00:00
snipe f0d1697108 Merge remote-tracking branch 'origin/develop' 2026-03-06 06:46:08 +00:00
snipe 420ba5f261 Fixed #18341 - remove action button from user profile view 2026-03-06 06:45:46 +00:00
snipe 90cb53566c Merge remote-tracking branch 'origin/develop' 2026-03-06 06:24:38 +00:00
snipe 7aa1f3ae1d Merge pull request #18639 from grokability/#18282-add-user-notes-to-custom-export
Fixed #18282 - added original notes to checkout target in custom report
2026-03-06 07:23:58 +01:00
snipe 556d638136 Fixed #18282 - added original notes to checkout target in custom report 2026-03-06 06:19:16 +00:00
snipe 64982d01cf Merge remote-tracking branch 'origin/develop' 2026-03-06 05:59:23 +00:00
snipe c4aa10baf8 Added user company to custom asset report 2026-03-06 05:59:11 +00:00
snipe b6cad58917 Merge remote-tracking branch 'origin/develop' 2026-03-06 05:39:20 +00:00
snipe 86f647e714 Improved bulk audit bg 2026-03-06 05:39:09 +00:00
snipe 4f9c952dbe Merge remote-tracking branch 'origin/develop' 2026-03-06 05:22:09 +00:00
snipe 64f5d40fd9 Removed duplicate code 2026-03-06 05:21:59 +00:00
snipe b9c3c8954f Merge remote-tracking branch 'origin/develop' 2026-03-06 05:17:51 +00:00
snipe 1a0869c2ca Merge pull request #18628 from marcusmoore/fixes/fd-54108-checkin-all-button
Fixed Checkin All Seats button
2026-03-06 06:17:12 +01:00
snipe 82b6159475 Merge remote-tracking branch 'origin/develop' 2026-03-06 04:46:33 +00:00
snipe 1fb32ee461 Merge pull request #18638 from grokability/experiments/compact-nav
Compacted nav UI, components for buttons
2026-03-06 05:45:02 +01:00
snipe 68a863e63e Updated test, fixed route 2026-03-06 04:38:48 +00:00
snipe a1e62ccd46 Fixed (shimmed) #18636 - added shim roite for fieldsets 2026-03-06 03:54:33 +00:00
snipe dae66c0fa4 Fixed audit background 2026-03-06 03:48:45 +00:00
snipe 1d6b21e1c7 Switched to newer button model 2026-03-06 03:33:04 +00:00
snipe 455be12058 Gate fix for admin 2026-03-06 03:05:40 +00:00
snipe 2ebb3ecb96 Update views with new button blades 2026-03-06 01:17:00 +00:00
Marcus Moore b29056dddf Delete duplicate test 2026-03-05 16:35:15 -08:00
Marcus Moore 3ed09f304c Fix method name 2026-03-05 16:30:05 -08:00
Marcus Moore 4875283ed1 Fix test route 2026-03-05 16:20:27 -08:00
Marcus Moore 261231c09e Fix method and variable names 2026-03-05 15:55:59 -08:00
snipe 180dad6ee6 Use updated infobox 2026-03-05 14:36:12 +00:00
snipe d7121ad82f Removed class active (this is handled in jquery) 2026-03-05 11:46:55 +00:00
snipe f121c61524 Added hidden-print class to action buttons column 2026-03-05 11:45:21 +00:00
Godfrey M e25ea465c5 add ternary on variables in asset count" 2026-03-04 10:25:59 -08:00
Godfrey M 30ac3d1a26 fix display name of item" 2026-03-03 16:11:46 -08:00
Godfrey M e47c772230 cleaned up other tables in print view 2026-03-03 16:04:13 -08:00
Godfrey M 706b623d95 adds assets to indirect assignment table 2026-03-03 15:51:47 -08:00
Godfrey M a908a76f53 adds components to indirect assignment table 2026-03-03 15:15:45 -08:00
Marcus Moore 93bf91869b Fix checkin all seats button 2026-03-03 14:57:43 -08:00
Marcus Moore a026ca92ff Populate tests 2026-03-03 14:46:10 -08:00
Godfrey M a2ec707f79 add licenses to indirect assignedment table 2026-03-03 12:53:37 -08:00
Marcus Moore 1b7fe4f728 Scaffold test cases 2026-03-03 11:07:28 -08:00
Marcus Moore 2bf2d55c6e Fix test case 2026-03-03 11:07:18 -08:00
snipe dbe998d9cf Merge remote-tracking branch 'origin/develop' 2026-03-02 18:36:13 +01:00
snipe 2ed32612b9 Fixed typo in comments 2026-03-02 18:35:57 +01:00
snipe 314bcbe208 Added assets upload url singleton 2026-03-02 18:35:57 +01:00
snipe 6290e34623 Exclude show route for settings API [RB-17718] 2026-03-02 18:35:57 +01:00
snipe 5e5521a128 Merge pull request #18623 from grokability/dependabot/github_actions/develop/actions/upload-artifact-7
Bump actions/upload-artifact from 6 to 7
2026-03-02 12:51:02 +00:00
dependabot[bot] 1e8bed86d3 Bump actions/upload-artifact from 6 to 7
Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 6 to 7.
- [Release notes](https://github.com/actions/upload-artifact/releases)
- [Commits](https://github.com/actions/upload-artifact/compare/v6...v7)

---
updated-dependencies:
- dependency-name: actions/upload-artifact
  dependency-version: '7'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-02 08:43:13 +00:00
Brady Wetherington 7cbc0fa671 Merge branch 'develop' into use_new_laravel_scim_server 2026-02-26 19:53:05 +00:00
snipe 79907a2770 Merge remote-tracking branch 'origin/develop' 2026-02-26 16:04:07 +00:00
snipe 8bc7d50e35 Updated to check gate on object 2026-02-26 16:03:57 +00:00
Marcus Moore aa420e5006 Bump Livewire to v4.1.4 2026-02-25 13:30:30 -08:00
Marcus Moore 4babaa85fc Merge branch 'develop' into livewire4
# Conflicts:
#	composer.lock
2026-02-25 13:29:07 -08:00
snipe 6f60ef9ec2 Merge remote-tracking branch 'origin/develop' 2026-02-25 19:46:20 +00:00
snipe 378d9e008e Removed truncate that ran after maintenance seeder 2026-02-25 19:46:09 +00:00
snipe 581867eefc Merge remote-tracking branch 'origin/develop' 2026-02-25 19:05:48 +00:00
snipe 340fabe4f6 Merge pull request #18614 from spencerrlongg/eof-rollbar
Fixes (hopefully) RB #19772 Unexpected EOF
2026-02-25 19:05:30 +00:00
spencerrlongg 29331b8b06 missing semicolon - kind of a shot in the dark 2026-02-25 12:54:43 -06:00
snipe 234855f225 Merge remote-tracking branch 'origin/develop' 2026-02-25 18:42:04 +00:00
snipe 6fbcaa0959 Make sure manager_id is an integer 2026-02-25 18:41:53 +00:00
snipe 52e10205c5 Add license ID to tabke cookie 2026-02-25 18:40:29 +00:00
snipe 0b8176a730 Merge remote-tracking branch 'origin/develop' 2026-02-25 17:41:38 +00:00
snipe f419ae3f4a Fixed license history target 2026-02-25 17:41:26 +00:00
snipe 84a6b8e012 Add display_name to asset advanced search filter 2026-02-25 16:54:54 +00:00
snipe d1be571d4d Merge remote-tracking branch 'origin/develop' 2026-02-25 16:41:47 +00:00
snipe f234aee691 Use display_name in transformUserCompact() 2026-02-25 16:41:30 +00:00
snipe 623d516595 Merge pull request #18095 from marcusmoore/5947-bulk-checkout-rollup
#5947 - roll up bulk asset checkout email
2026-02-25 15:36:58 +00:00
snipe 156eaf53d5 Fix for #18408 2026-02-25 15:30:37 +00:00
snipe 678a7c1437 Removed BS class 2026-02-25 15:04:24 +00:00
snipe ce2a760093 Merge pull request #17964 from Godmartinz/add-License-checkedout-to-user
Adds #11741 currently assigned license table to license checkout
2026-02-25 14:50:39 +00:00
snipe 34b02d8534 Merge pull request #18485 from marcusmoore/debugbar
Bumped Debugbar to v4
2026-02-25 14:43:03 +00:00
snipe 42e0e691dd Merge pull request #18609 from ubc-cpsc/bugfix/php-deprecated-string-interpolation
Fix deprecated string interpolation in controllers
2026-02-25 14:41:24 +00:00
snipe d392439f82 Merge remote-tracking branch 'origin/develop' 2026-02-25 14:23:13 +00:00
snipe ccfda99060 Merge pull request #18613 from grokability/add-sorting-on-model-name-and-number-for-maintenances
Added model number as a separate field, added sorting
2026-02-25 14:22:48 +00:00
snipe 57f02bdc57 Fixed typo 2026-02-25 14:22:27 +00:00
snipe 7056656eab Added model number as a separate field, added sorting 2026-02-25 14:19:01 +00:00
snipe 2d899fc772 Merge pull request #18612 from grokability/added-maintenances-seeder
Added maintenances seeder
2026-02-25 14:16:44 +00:00
snipe 80ee0835aa Added maintenances seeder 2026-02-25 14:12:13 +00:00
snipe f423b88b16 Merge remote-tracking branch 'origin/develop' 2026-02-25 12:39:39 +00:00
snipe 7b7e6c7971 Fixed maintence image display 2026-02-25 12:39:29 +00:00
snipe 853aed5954 Merge remote-tracking branch 'origin/develop' 2026-02-25 12:03:32 +00:00
snipe 025fb30335 Added user email to exportable field in custom report 2026-02-25 12:03:23 +00:00
snipe 947a149d08 Merge remote-tracking branch 'origin/develop' 2026-02-25 11:51:03 +00:00
snipe fcace4a192 Override the table search with the asset tag search if one is passed 2026-02-25 11:50:52 +00:00
snipe 619e1c70ea Fixed #18603 - set unique cookie ID on asset history table 2026-02-25 11:48:42 +00:00
Joël Pittet 7a95bdfba6 Fix deprecated string interpolation in controllers 2026-02-24 14:57:29 -08:00
Marcus Moore 89962de161 Move to Traits directory 2026-02-24 11:37:07 -08:00
Marcus Moore d9328bd0ce Merge branch 'develop' into debugbar 2026-02-24 11:27:04 -08:00
snipe 81306df06a Merge pull request #18606 from grokability/#18600-check-filesystem-on-healthcheck
Fixed #18600 - add filesystem check on health checker
2026-02-24 14:00:14 +00:00
snipe 75abe9eb3e Re-add try/catch for DB for cleaner output 2026-02-24 13:23:12 +00:00
snipe 1f26bf1125 Fixed #18600 - add filesystem check on health checker 2026-02-24 13:17:15 +00:00
snipe 3aec52eab0 Merge remote-tracking branch 'origin/develop' 2026-02-24 12:00:15 +00:00
snipe 14b9c06d77 Remove optional qualifier 2026-02-24 12:00:06 +00:00
snipe 4f3d23d1ef Merge pull request #18576 from marcusmoore/fixes/rb-20713-license-seat-assigned-to
Fixed RB-20713: Improved validation of license seat update api endpoint
2026-02-24 07:29:41 +00:00
Marcus Moore cada43f34d Allow checking in from unfound targets 2026-02-23 17:23:42 -08:00
snipe 8d0fda88b7 Tagged 8.4.0 release
# Conflicts:
#	config/version.php
2026-02-23 20:41:11 +00:00
snipe 9188f89a2a Tagged v8.4.0 2026-02-23 20:40:40 +00:00
Marcus Moore 1cc7ef0543 Organization 2026-02-23 10:51:34 -08:00
snipe 91a95dbc66 Merge remote-tracking branch 'origin/develop' 2026-02-23 14:44:08 +00:00
snipe a86ffc29d1 Added display name to search term in advanced search 2026-02-23 14:43:55 +00:00
snipe a15adc806b Merge remote-tracking branch 'origin/develop' 2026-02-23 14:30:54 +00:00
snipe 9ed5540c49 Merge pull request #18597 from uberbrady/improve_ldap_binding
Improve LDAP escaping to better reflect modern PHP standards
2026-02-23 13:38:28 +00:00
Brady Wetherington 3a7e00ccc3 Improve LDAP escaping to better reflect modern PHP standards 2026-02-23 13:01:00 +00:00
snipe f328da37bc Merge remote-tracking branch 'origin/develop' 2026-02-23 11:41:54 +00:00
snipe f82cdabccd More info anel refinements 2026-02-23 11:41:45 +00:00
Brady Wetherington 15346eec22 WIP: cleaning up new SCIM config 2026-02-23 11:34:41 +00:00
snipe b9c9cc0046 Merge pull request #18596 from grokability/add-with-trashed-to-formattednamelink
Adds withTrashed() to `adminuser` and updates presenter to show strikethrough
2026-02-23 11:00:43 +00:00
snipe 27ece84d52 Adds withTrashed() to adminuser and updates presenter to show strikethrough 2026-02-23 10:49:44 +00:00
snipe 3adc8f279b Merge remote-tracking branch 'origin/develop' 2026-02-21 13:17:52 +00:00
snipe 1299186fb8 Merge pull request #18591 from grokability/#18017-show-more-info-in-bulk-audit
Fixed #18017 - show status on bulk audit
2026-02-21 13:17:31 +00:00
snipe d837e4845b Show note 2026-02-21 13:16:58 +00:00
snipe 39be0c5590 Fixed #18017 - show status on bulk audit 2026-02-21 13:08:23 +00:00
snipe 41c75022a9 Merge remote-tracking branch 'origin/develop' 2026-02-21 12:53:42 +00:00
snipe d2bb10e96d Merge pull request #18590 from grokability/optionally-update-audit-dates
Added checkbox to determine if existing audit dates should be changed
2026-02-21 12:53:12 +00:00
snipe f139a616c7 Added checkbox to determine if existing audit dates should be changed 2026-02-21 12:49:36 +00:00
snipe 84924a68b7 Merge remote-tracking branch 'origin/develop' 2026-02-20 15:01:15 +00:00
snipe d5099d973b Move copy icon to right side 2026-02-20 15:00:04 +00:00
snipe 82b18a3207 Updated requestable icon 2026-02-20 14:15:50 +00:00
snipe 5a3a63e0a4 Merge remote-tracking branch 'origin/develop' 2026-02-20 13:10:55 +00:00
snipe 10aee6bb5f Fixed tab pane name 2026-02-20 13:10:14 +00:00
snipe 980cc5704f Switched branch name to master 2026-02-20 13:08:23 +00:00
snipe 28054a9112 Merge remote-tracking branch 'origin/develop' 2026-02-20 13:07:33 +00:00
snipe c1b11ab9bf Small fixes for accessories/checkedout tab 2026-02-20 13:05:31 +00:00
snipe c226a061f5 Tagged pre-release 2026-02-20 12:42:09 +00:00
snipe c0be738aef Removed unneeded return check 2026-02-20 12:13:01 +00:00
snipe 7a312f5868 Merge remote-tracking branch 'origin/develop' 2026-02-20 12:12:04 +00:00
snipe e6987ec148 Early return on non-existent acceptance 2026-02-20 12:11:49 +00:00
snipe 973fa7a58b Merge pull request #18575 from spencerrlongg/encrypted-custom-fields-api
Adds field_encrypted To Fields API Response
2026-02-20 12:11:00 +00:00
snipe 5ce493180d Merge remote-tracking branch 'origin/develop' 2026-02-20 11:56:33 +00:00
snipe b6195ba3ae Default active tab fix 2026-02-20 11:56:23 +00:00
snipe d3bd213f29 Fixed typo in tooltip text 2026-02-20 09:49:06 +00:00
snipe bbdc78a13c Merge remote-tracking branch 'origin/develop' 2026-02-20 09:36:48 +00:00
snipe 9502dd8bd7 Back out :class 2026-02-20 09:36:38 +00:00
Marcus Moore e81ccf4280 Add more failing assertions 2026-02-19 16:53:22 -08:00
Marcus Moore 9730f2c0f3 Add some failing assertions 2026-02-19 16:40:45 -08:00
Marcus Moore 1de34c0656 Some controller clean up 2026-02-19 16:40:34 -08:00
Marcus Moore bdce6b1387 Add test case 2026-02-19 13:51:20 -08:00
Marcus Moore ce0c2ecd8f Populate new tests 2026-02-19 13:47:52 -08:00
Marcus Moore 40f07e3d72 Scaffold addition test cases 2026-02-19 11:50:04 -08:00
snipe 43971b9625 Merge remote-tracking branch 'origin/develop' 2026-02-19 19:15:59 +00:00
snipe 3c3ccae7c9 Allow context overwrites in FCO specific tables 2026-02-19 19:14:26 +00:00
Godfrey M be211f6f86 fix apostophes 2026-02-19 09:57:29 -08:00
snipe f27a3a2c61 Build prod JS assets 2026-02-19 15:13:19 +00:00
snipe b96d0d55c9 Merge remote-tracking branch 'origin/develop' 2026-02-19 15:12:52 +00:00
snipe 9789ca42f8 Highlight inventory in red if below min 2026-02-19 15:11:27 +00:00
snipe da26bc5165 Updated JS assets 2026-02-19 14:55:45 +00:00
snipe 0b67626961 Merge pull request #18580 from grokability/fixes-for-alert-menu
Quick fix for alert menu 1001 queries
2026-02-19 14:54:50 +00:00
snipe 546c8ce7d5 Quick fix for alert menu 1001 queries 2026-02-19 14:52:01 +00:00
Brady Wetherington c48e0c7377 Clean out fixme's, standardize on UpdatableComplex 2026-02-19 14:50:02 +00:00
snipe c76a888d11 Merge pull request #18579 from uberbrady/fix_npm_install_jspdf
Careful upgrade to minimize too many version changes
2026-02-19 14:25:34 +00:00
Brady Wetherington 38c495a4ac Careful upgrade to minimize too many version changes 2026-02-19 14:11:15 +00:00
Brady Wetherington 95fdfa6396 Merge branch 'develop' into use_new_laravel_scim_server 2026-02-19 12:41:43 +00:00
snipe f699935f5f Merge remote-tracking branch 'origin/develop' 2026-02-19 12:05:17 +00:00
snipe d0ce5e0c57 Merge pull request #18578 from grokability/#18435-fixed-currency-selection-selectbox
Fixed #18435 - correct option value for currency format selector
2026-02-19 12:05:01 +00:00
snipe 7a0e5b57db Fixed currency selector 2026-02-19 12:01:56 +00:00
snipe 8336cf5baa Merge remote-tracking branch 'origin/develop' 2026-02-19 11:42:54 +00:00
snipe c31f1d2cce Nicer row selected color 2026-02-19 11:42:45 +00:00
snipe d3d90abba7 Merge remote-tracking branch 'origin/develop' 2026-02-19 11:31:05 +00:00
snipe ea98ee07e5 Fixed #18577 - set url back parameter as default in form component 2026-02-19 11:30:53 +00:00
snipe a38bfada57 Merge pull request #18572 from uberbrady/fix_cross_company_created_by_in_asset_acceptance
Fixed #18571 - fix cross-company created_by in asset acceptance
2026-02-19 11:24:28 +00:00
snipe bdaf13da4c Merge remote-tracking branch 'origin/develop'
# Conflicts:
#	resources/views/maintenances/view.blade.php
2026-02-19 11:11:18 +00:00
snipe e5ff19aec4 Fixd required field color 2026-02-19 11:02:12 +00:00
Marcus Moore 504f63066f Add note 2026-02-18 16:34:22 -08:00
Marcus Moore 41b327529b Reference rollbar 2026-02-18 16:31:55 -08:00
Marcus Moore e84279c402 Implement remaining tests 2026-02-18 16:17:34 -08:00
spencerrlongg 65e6519f97 adds field_encrypted to fields api response 2026-02-18 17:53:04 -06:00
Marcus Moore dbbb3beacc Clean up 2026-02-18 15:35:57 -08:00
Marcus Moore e8a73a8de6 Organization 2026-02-18 15:29:44 -08:00
Marcus Moore 411cbc0962 Avoid overwriting created_by and timestamps 2026-02-18 15:20:28 -08:00
Marcus Moore b487c0e3e9 Scaffold additional tests 2026-02-18 15:20:18 -08:00
Marcus Moore fa0e8f6e01 Improve validation 2026-02-18 15:11:52 -08:00
Marcus Moore e25e405f74 Scaffold additional test cases and organize 2026-02-18 14:52:43 -08:00
Marcus Moore 302c4a6414 Organize test 2026-02-18 14:35:06 -08:00
Marcus Moore d1e7f6e55e Inline 2026-02-18 14:03:28 -08:00
Marcus Moore d12f0974df Add test for permission 2026-02-18 14:01:53 -08:00
snipe e92e550e9c Null operator for maintenances 2026-02-18 16:32:40 +00:00
snipe b751fe7903 Fixed incorrect translation string 2026-02-18 16:30:37 +00:00
snipe a6e34522eb Partially convert maintenances into new blade components 2026-02-18 16:26:13 +00:00
snipe 735e6f3471 Merge pull request #18570 from grokability/convert-consumables-to-new-blade-components
Converted consumables to new blade component
2026-02-18 16:02:32 +00:00
snipe c9f41c950a Added copy+paste, added additional fields 2026-02-18 15:57:40 +00:00
Brady Wetherington 091c710940 Make User parameter nullable 2026-02-18 15:25:05 +00:00
snipe 276f412a3c Small tweaks to info panel 2026-02-18 15:22:46 +00:00
snipe 6f6e5c847a Converted consumables to new blade component 2026-02-18 14:44:08 +00:00
snipe 6ef0274bb3 Merge pull request #18569 from grokability/updated-csvs
Small importer improvements, added larger CSV samples
2026-02-18 14:22:23 +00:00
snipe 7ef6a72ec4 Updated CSVs 2026-02-18 14:06:33 +00:00
snipe e2b8c69cf6 Use iconhelper for dynamic icon 2026-02-18 14:06:24 +00:00
snipe 1254d12d83 Tweaks to info panel 2026-02-18 14:06:14 +00:00
snipe b68642a827 Added alias strings 2026-02-18 14:04:51 +00:00
snipe c5214b976b Added string 2026-02-18 14:04:44 +00:00
snipe e611121244 Added tag color to main importer, added aliases 2026-02-18 14:04:38 +00:00
snipe 3aa7f0b7fe Added tag_color to importer 2026-02-18 14:04:19 +00:00
snipe 3d38eee71d Added/updated icons 2026-02-18 14:04:00 +00:00
snipe 90e6e309f9 Removed redundant icon helper 2026-02-18 14:03:53 +00:00
snipe 885314b87a Added large components sample CSV 2026-02-18 12:01:59 +00:00
snipe ef013a7026 Updated components sample 2026-02-18 12:01:48 +00:00
snipe 0353ade90e Trim off whitespace for headers 2026-02-18 12:01:34 +00:00
snipe d90c9282ac Updated strings 2026-02-18 11:13:52 +00:00
Marcus Moore 5055aafe1d Scaffold tests 2026-02-17 17:37:24 -08:00
Marcus Moore e68b9ea267 Validate assigned_to is integer 2026-02-17 16:51:31 -08:00
Marcus Moore 1d8ba2ec61 Add failing test 2026-02-17 16:49:32 -08:00
snipe d56970eaa3 Merge pull request #18566 from grokability/fixed-new-vs-update-on-custom-fieldset-creation
Fixed new vs update button label on custom fieldset creation, fixed breadcrumbs on new custom fieldset creation screen
2026-02-17 22:23:06 +00:00
snipe 8b3f18ec59 Better breadcrumbs for fieldset creation 2026-02-17 22:17:38 +00:00
snipe 170d20ddb5 Fixed new vs update button on custom fieldset create vs edit 2026-02-17 22:17:27 +00:00
snipe 70407dac85 Merge pull request #18565 from grokability/#18555-component-clone
Added #18555 - ability to clone components
2026-02-17 16:22:02 +00:00
snipe c2334d87de Merge pull request #18564 from uberbrady/fix_component_counts
Fixed #18557 - Tweak numRemaining to not re-query for un-checked-out components
2026-02-17 15:44:00 +00:00
snipe 0662e3351e Added #18555 - ability to clone components 2026-02-17 15:43:43 +00:00
Brady Wetherington 6b90b3743e Tweak numRemaining to not re-query for un-checked-out components 2026-02-17 15:27:04 +00:00
snipe dd1d456106 Alphabetize dictionary 2026-02-17 15:21:24 +00:00
snipe dceead8302 Show footer by default if the transformer asks for it 2026-02-17 15:09:29 +00:00
snipe 832f449868 Merge pull request #18561 from grokability/#18512-comment-out-first-checkout
Fixes #18512 (first checkout) temporarily
2026-02-17 14:18:05 +00:00
snipe 33a104f142 Fixes #18512 temporarily 2026-02-17 14:11:14 +00:00
snipe 28f19689ec Fixed focus color for input fields 2026-02-17 13:38:43 +00:00
snipe ce6ee32e89 Made seats a numeric field 2026-02-17 13:38:29 +00:00
snipe fdf42ba321 Add class to checkedout blade 2026-02-17 13:18:27 +00:00
snipe aadd158108 Added active class to accessory tab 2026-02-17 13:18:14 +00:00
snipe d6592819e8 Show only active licenses 2026-02-17 13:17:49 +00:00
snipe 8f34c06196 Added order_number to API for accessories, consumables, components 2026-02-17 13:08:09 +00:00
snipe 9cdc73917b Merge pull request #18537 from grokability/more-refactoring-tables-and-tabs
WIP - More refactoring of tabs, tab panes, and tables
2026-02-17 12:39:31 +00:00
snipe 2976159499 Check for parent (only really matters in locations) 2026-02-17 12:32:07 +00:00
snipe e302ccf985 Added plain clone translation 2026-02-17 12:31:35 +00:00
snipe 08915e8607 Use isDeletable in transformers 2026-02-17 12:31:26 +00:00
snipe 32b2131bff Fixed asset model deletable check 2026-02-17 12:31:12 +00:00
snipe 50cf15fb71 Added isDeletable() method 2026-02-17 12:31:01 +00:00
snipe f07ef6d7c5 Added restore and clone blade 2026-02-17 12:28:48 +00:00
snipe 666025d7f6 Use more generic text 2026-02-17 12:28:27 +00:00
snipe 671601365c Use new button blade components 2026-02-17 12:28:16 +00:00
snipe 263b04cd69 Merge pull request #13506 from matmair/develop-1
Fixed: wrong index reference in MoveUploadsToNewDisk.php
2026-02-17 11:08:24 +00:00
snipe 57b98ca782 Fixed copypasta 2026-02-13 19:03:44 +00:00
snipe 46df19d7cd Don’t use fixed columns on unaccepted asset report 2026-02-13 18:27:18 +00:00
snipe fa18524223 Fixed unaccepted report to account for much older items that might not exist 2026-02-13 18:23:59 +00:00
snipe 3ebc0532ca Added isDeleteable to Accessories 2026-02-13 18:07:22 +00:00
snipe 4f59752b8b Added rtd tab icon 2026-02-13 17:30:11 +00:00
snipe 668ab221cc Removed uploads for manufacturers since we don’t have them? 2026-02-13 17:29:56 +00:00
snipe ad90e005c4 Added history tabs 2026-02-13 17:28:07 +00:00
snipe 952b3d6884 Converted components view to blade component
This effing sucked
2026-02-13 17:27:45 +00:00
snipe 19ca1f7578 Converted to object-specific elements in indexes 2026-02-13 17:27:14 +00:00
snipe ef02fab94b Added checkout blade 2026-02-13 17:22:35 +00:00
snipe 144b5e7558 Switch to accessory table on accessory view 2026-02-13 17:22:22 +00:00
snipe aff0a60138 Added presenter for component history 2026-02-13 17:22:07 +00:00
snipe 92a641f01a Added snipe_component because wtf laravel 2026-02-13 17:21:59 +00:00
snipe 929132ba07 Merge pull request #18544 from uberbrady/fix_1001_query_on_available_models_for_notification
Added some withCount() params to tweak the 'minimum number of assets' notification
2026-02-12 21:37:10 +00:00
Brady Wetherington 2a1a4a1c72 Added some withCount() params to tweak the 'minimum number of assets' notification 2026-02-12 21:32:30 +00:00
snipe 4d73894cd2 Merge pull request #18542 from marcusmoore/fixes/fd-53577-reminder-subject-2
Updated subject line of acceptance reminder emails
2026-02-12 21:22:55 +00:00
Godfrey M 4d9bc04d58 fix test: change hasTo to hasCc pt2 2026-02-12 13:09:38 -08:00
Godfrey M 3527b86b6d fix test: change hasTo to hasCc 2026-02-12 13:05:51 -08:00
snipe e49e805b2b Merge pull request #18539 from Godmartinz/L7163_title_adjustment
Fixes title alignment to fit label L7163_A
2026-02-12 20:43:52 +00:00
Godfrey M 30f4e1eb08 remove class usage 2026-02-12 12:22:26 -08:00
snipe 05f3bf633e Fixed typeError for isManagerOf in manager view of EULAs 2026-02-12 20:21:15 +00:00
Godfrey M 8142ab64f6 change to() to cc() 2026-02-12 12:21:11 -08:00
Brady Wetherington f8ecbf8f0b removing Log::error lines 2026-02-12 16:03:40 +00:00
Marcus Moore 4d5b3548d6 Update introduction line 2026-02-11 16:28:17 -08:00
Marcus Moore 00408f0103 Revert "Put checkout_qty on checkoutable so accessory and consumable emails are formatted correctly"
This reverts commit 548cceee18.
2026-02-11 16:06:27 -08:00
Marcus Moore 548cceee18 Put checkout_qty on checkoutable so accessory and consumable emails are formatted correctly 2026-02-11 13:39:37 -08:00
Marcus Moore 7eb536f80e Bump debugbar to v4.0.7 2026-02-11 11:37:57 -08:00
Marcus Moore d91ce88e9a Merge branch 'develop' into debugbar 2026-02-11 11:37:02 -08:00
Godfrey M 76d1a20e21 adjust label L7163_A to fit title properly 2026-02-11 11:02:49 -08:00
snipe 5b6951b88d Tightened up licenses index list 2026-02-11 15:22:58 +00:00
snipe 56313e4436 Covert assets table 2026-02-11 14:54:30 +00:00
snipe 7810ae74d1 Fixed translation string 2026-02-11 14:30:42 +00:00
snipe 3ac1012757 Set fixed number for assets 2026-02-11 14:30:32 +00:00
snipe 91aec08ce0 More refactoring of tabs, tab panes, and tables 2026-02-11 13:18:32 +00:00
Brady Wetherington c5ffbf6ed9 Merge branch 'develop' into use_new_laravel_scim_server 2026-02-11 12:53:42 +00:00
snipe 30970cc7f2 A few more disabled/readonly state color fixes 2026-02-11 11:21:53 +00:00
snipe 985c027b04 Fixed disabled select2 color 2026-02-11 11:12:33 +00:00
snipe d1c4b055a9 Merge pull request #18535 from grokability/rename-field-in-infobox
Update the name of the object within the side panel
2026-02-11 10:20:23 +00:00
snipe 3f2f508e49 Fixed failing test 2026-02-11 10:16:44 +00:00
snipe 07513cb559 Update the name of the object within the side panel
It’s not always a contact/person, so…
2026-02-11 10:02:20 +00:00
snipe 66022902b7 Small style tweaks to info-box 2026-02-11 09:57:43 +00:00
snipe 613efe963a Use consistent box icon 2026-02-11 09:48:44 +00:00
snipe 5a0affcd8e Updated categories view 2026-02-11 09:47:38 +00:00
snipe 79150edb92 Fixed variable name 2026-02-11 07:41:13 +00:00
snipe 6cca24be8e Fixed typo 2026-02-11 07:27:16 +00:00
snipe c2ca51e8ef Added edit buttons to supplier view 2026-02-11 07:27:08 +00:00
snipe b9908d5665 Cast the DB_PORT to integer 2026-02-11 07:01:03 +00:00
snipe cbca420217 Added tooltips 2026-02-11 06:42:15 +00:00
snipe 017183e3fe Merge pull request #18529 from grokability/consolidate-customfieldset-edit
Consolidated custom fieldset edit/show
2026-02-11 05:25:27 +00:00
snipe 0236527f05 Use correct seeding color for links 2026-02-10 15:27:05 +00:00
snipe e946c4bf8c Consolidated custom fieldset edit/show 2026-02-10 15:20:57 +00:00
snipe 8a0414cef6 Merge remote-tracking branch 'origin/master' into develop 2026-02-10 14:16:42 +00:00
snipe ee1ad692a4 Tweaked disabled button color 2026-02-10 13:40:14 +00:00
snipe fdd5f6b0e1 Fixed #18497 - Added model name to aliases 2026-02-10 13:07:41 +00:00
snipe dca6df3244 Fixed #18527 - disable sticky column on dashboard tables 2026-02-10 11:31:25 +00:00
snipe 0874b853a0 Fixed #18520 - use plain_text_company 2026-02-10 11:10:48 +00:00
snipe 3393916b5e Merge pull request #18524 from ubc-cpsc/fix/subpath-livewire-prefix
Fix Livewire and Passport routes for subpath hosting
2026-02-10 08:34:18 +00:00
Joël Pittet b2728b4eb1 Fix Livewire routes for subpath hosting 2026-02-10 00:22:13 -08:00
snipe f3cc3ed682 Merge pull request #18470 from bilias/pr-clean
Do not delete asset name if update request does not have a name
2026-02-09 20:57:07 +00:00
snipe f8cfb8833f Merge pull request #18514 from grokability/update-models-with-new-components
Update models with new components
2026-02-09 19:53:40 +00:00
snipe c2c2332e83 Removed erroneous icon 2026-02-09 13:05:22 +00:00
snipe 9f69c36426 Added depreciations and departments 2026-02-09 13:03:07 +00:00
snipe ea9de35a3b Show/hide on companies and depts 2026-02-07 18:44:37 +00:00
snipe a50a16fb01 Nicer toggle, nicer show/hide info button 2026-02-07 18:39:42 +00:00
snipe f27c0206de Expand/contract info tab (still looks a little junky) 2026-02-07 17:52:22 +00:00
snipe 6791ddd911 Merge remote-tracking branch 'origin/develop' 2026-02-07 15:55:20 +00:00
snipe ce95060d60 Fixed #18516 - added kits for sticky columns 2026-02-07 15:55:11 +00:00
snipe 6d9bbe1ddf Small tweaks to EULA API 2026-02-07 15:41:51 +00:00
snipe 5b1507f4b7 Updated license presenter 2026-02-07 15:16:32 +00:00
snipe 53e985aaab Tweaked color for alt striping again 2026-02-07 15:08:51 +00:00
snipe f5c2119122 Merge remote-tracking branch 'origin/develop' 2026-02-07 15:03:58 +00:00
snipe 5fd6918948 Fixed text color in light mode on alt striping 2026-02-07 15:03:50 +00:00
Marcus Moore 7423d13bdd Accept $firstTimeSending in mails 2026-02-05 17:06:36 -08:00
Marcus Moore fb8586f186 Properly pass parameter for asset emails 2026-02-05 16:59:49 -08:00
Marcus Moore 8b9ebf736b Add assertions for subject line 2026-02-05 16:59:36 -08:00
Marcus Moore 5abcdb8c5a Fix relationships in AccessoryCheckout model 2026-02-05 16:46:51 -08:00
Marcus Moore e549f67fcc Create AccessoryCheckout factory 2026-02-05 16:45:25 -08:00
Marcus Moore d68576c2fa Make test name more accurate 2026-02-05 13:57:51 -08:00
Marcus Moore a6042b6a03 Clean up 2026-02-05 13:52:15 -08:00
Marcus Moore d1a3afd992 More test clean up 2026-02-05 13:39:47 -08:00
Marcus Moore 34b00f7dba More test clean up 2026-02-05 13:38:05 -08:00
Marcus Moore 14b6c6861f Test clean up 2026-02-05 13:34:09 -08:00
Marcus Moore fe4bb4209c Split out tests 2026-02-05 13:07:41 -08:00
Marcus Moore e997eb2012 Inline method 2026-02-05 12:57:42 -08:00
snipe 8337473f5a Added box arrows 2026-02-05 19:27:36 +00:00
Marcus Moore 7ada7fb327 Merge branch 'develop' into livewire4 2026-02-05 10:39:56 -08:00
Marcus Moore 9d632e39bf Merge branch 'develop' into debugbar 2026-02-05 10:33:13 -08:00
snipe 1f50eada6d Added bulk edit to department user listing 2026-02-05 14:38:46 +00:00
snipe 38e1114dad Convert manufacturers and departments 2026-02-05 14:35:01 +00:00
snipe 11be73a578 Removed stray closing div 2026-02-05 14:14:25 +00:00
snipe 13a00df73c Use new components for company view 2026-02-05 14:13:51 +00:00
snipe 7739690bf5 Extend SnipeModel for custom fieldsets 2026-02-05 13:41:26 +00:00
snipe 389eb9e05d Bumped hash 2026-02-05 13:25:53 +00:00
snipe 98fe94aa24 Bumped hash 2026-02-05 13:25:21 +00:00
snipe 4ee378bf8e Merge remote-tracking branch 'origin/master' into develop
# Conflicts:
#	public/css/dist/bootstrap-table.css
#	public/js/dist/bootstrap-table.js
#	resources/views/blade/table/index.blade.php
#	resources/views/models/custom_fields_form.blade.php
2026-02-05 13:24:27 +00:00
snipe a8c268760b Fixed #18500 - skip encoding on API url for table component 2026-02-05 13:19:16 +00:00
snipe c684b8ab1e Fixed #18502 - custom fields disappearing on smaller resolution breakpoints 2026-02-05 12:25:49 +00:00
snipe 333d0e2391 Fixed #18510 - use correct GH link in social footer 2026-02-05 11:28:29 +00:00
snipe c22c5993fc Fixed #18503 - alt row colors on striped tables 2026-02-05 11:27:10 +00:00
snipe 1c239cc7cf Fixed typo in icon name 2026-02-05 10:16:24 +00:00
snipe 6ee5aa3e12 Fixed checkout to all modal 2026-02-04 20:55:38 +00:00
snipe 0d5ceb1e90 Merge pull request #18492 from marcusmoore/bump-phpunit
Bumped PHPUnit version
2026-02-04 20:48:06 +00:00
snipe 166a241761 Merge pull request #18484 from spencerrlongg/undefined_var_files
Fixes `Undefined variable $files` Exception
2026-02-04 20:47:02 +00:00
snipe f6f5e806e4 More flexibility in blade components for labels vs icons vs icon types 2026-02-04 20:31:11 +00:00
snipe f0f42240f3 Still more icons 2026-02-04 20:30:20 +00:00
snipe 686afc0974 Gate check linking in presenters 2026-02-04 20:30:12 +00:00
Marcus Moore 5d085469ec Bump debugbar to v4.0.6 2026-02-04 10:46:34 -08:00
Marcus Moore 7c54429c13 Bump Livewire to v4.1.2 2026-02-03 09:14:41 -08:00
Marcus Moore 8dfd04573e Bump debugbar to v4.0.5 2026-02-02 09:53:17 -08:00
snipe 7e5fb3c9ae Added more icons 2026-02-02 15:20:21 +00:00
Brady Wetherington 2115de9926 WIP: move towards UpdatableComplex class for SCIM 2026-02-02 14:55:03 +00:00
snipe 65e4c0b8d1 Renamed contact box to info-panel 2026-02-02 12:22:20 +00:00
snipe b1301237f1 Removed double lines in table 2026-02-02 11:35:09 +00:00
snipe cf82c12708 Fixed custom fieldset table colors 2026-02-02 11:27:18 +00:00
snipe 52f8697d91 Added icons, more additions to sidebar 2026-02-02 11:16:53 +00:00
Marcus Moore 1aee8679d2 Fix updating bug in oauth clients 2026-01-28 12:46:57 -08:00
Marcus Moore 3169c5b503 Bump phpunit 2026-01-28 10:15:11 -08:00
snipe 741f0d69ab Merge pull request #18490 from Godmartinz/add-label-preview-translation
Add translation and template name for Label Preview
2026-01-28 13:14:54 +00:00
Marcus Moore 8829ea9b29 Update category edit form 2026-01-27 17:08:21 -08:00
Godfrey M 53b283eac5 add seperate brackets for template name 2026-01-27 16:21:06 -08:00
Godfrey M 1234b6297e add Label preview translation, also which label is previewed 2026-01-27 14:59:44 -08:00
Marcus Moore 6ba99e8199 Bump livewire to v4.1.0 2026-01-27 14:03:52 -08:00
Marcus Moore b4eb603f22 Switch blur to change 2026-01-27 13:58:42 -08:00
Marcus Moore 62f9ce979d Fix js 2026-01-27 13:41:57 -08:00
Marcus Moore f5928fc707 Fix tags in importer 2026-01-27 12:33:46 -08:00
Marcus Moore f7040e3616 Remove console.log 2026-01-26 17:43:47 -08:00
Marcus Moore a70f1cc1ef Migrate request hook 2026-01-26 17:38:01 -08:00
Marcus Moore a86b738231 Update route 2026-01-26 17:13:56 -08:00
Marcus Moore 8a9ddba208 Use traditional component naming 2026-01-26 17:02:32 -08:00
Marcus Moore 4c727966e7 Migrate config 2026-01-26 16:59:08 -08:00
Marcus Moore c2ac53029a Update to v4 2026-01-26 16:58:58 -08:00
Marcus Moore 5d300d85bd Update content-type assertion 2026-01-26 14:52:53 -08:00
Marcus Moore 1dc181797b Move trait to base controller 2026-01-26 14:39:48 -08:00
Marcus Moore 30d932e2e0 Re-enable exception collector 2026-01-26 14:30:03 -08:00
Marcus Moore 9fb32d33af Migrate to v4 config 2026-01-26 14:28:18 -08:00
Marcus Moore 70baa60521 Install v4 of laravel debugbar 2026-01-26 14:02:01 -08:00
Marcus Moore 8ea2784d44 Uninstall debugbar 2026-01-26 14:01:29 -08:00
Marcus Moore 2b56d82577 Move disabling debugbar to trait 2026-01-26 14:01:21 -08:00
spencerrlongg 8ff34baafa wrap $files in isset to avoid null errors 2026-01-26 15:44:23 -06:00
snipe eeae534a37 Added a few more helpers 2026-01-25 14:33:54 +00:00
snipe 8b71049a3d Merge pull request #18482 from grokability/move-form-components
Move form components into their own directory
2026-01-24 21:13:07 +00:00
snipe 373361dab0 Move form components into their own directory 2026-01-24 21:06:02 +00:00
snipe 60a1141b9d Merge pull request #18480 from grokability/#more-table-components
Moves more indexes to blade components
2026-01-24 20:55:51 +00:00
snipe a38c8a0235 Merge more into contact card 2026-01-24 20:37:08 +00:00
snipe c39d165a3d Added space 2026-01-24 20:36:50 +00:00
snipe 2238f8e8ad More icons 2026-01-24 20:36:43 +00:00
snipe e0c53c3ead Merge classes 2026-01-24 18:32:13 +00:00
snipe 1074bc2d3b More conversions 2026-01-24 18:27:06 +00:00
snipe 4b22b1c115 Better defaults in nav-item component 2026-01-24 17:41:02 +00:00
snipe 141794caf7 Use new contact panel in suppliers view 2026-01-24 17:40:41 +00:00
snipe d5997e2394 Added new classes 2026-01-24 17:40:29 +00:00
snipe 429ca8dd34 Added info components 2026-01-24 17:40:18 +00:00
snipe c2ad0defe0 Added contact component 2026-01-24 17:39:53 +00:00
snipe b4658f2696 Added address presenter 2026-01-24 17:39:44 +00:00
snipe 11b7dfc9b0 Added icons 2026-01-24 17:39:33 +00:00
snipe f7b7ef850d Updated suppliers view 2026-01-24 12:10:58 +00:00
snipe bb9b145519 Updated helper icon 2026-01-24 12:10:50 +00:00
snipe d75f5b8fd3 Fixed label 2026-01-23 19:14:29 +00:00
snipe 34fe64b27c Fixed spacing 2026-01-23 19:09:48 +00:00
snipe 2151595b45 Fixed a few typos 2026-01-23 18:28:49 +00:00
snipe b2c94386b3 Switched from stupid layouts/edit-form to new form component 2026-01-23 18:26:09 +00:00
snipe b99ae9be88 Form component (will move the other things later) 2026-01-23 18:25:49 +00:00
snipe ffbc831071 Include the box footer if there is a route passed 2026-01-23 18:25:34 +00:00
snipe 302a60fbe7 Better breadcrumb 2026-01-23 18:25:06 +00:00
snipe 3ec8ba01d0 Updated manufacturer with new tabs 2026-01-23 18:24:50 +00:00
snipe 2048eb7d5a Removed unneeded presenter methods 2026-01-23 17:08:25 +00:00
snipe 4d605927f3 Fixed typos 2026-01-23 17:07:38 +00:00
snipe b7ee3a2f1d Updated groups index to use new components 2026-01-23 17:05:28 +00:00
snipe 44fa9e2d1e Handle status label index 2026-01-23 16:58:42 +00:00
snipe a5e818f970 More moved to new box+table method 2026-01-23 16:47:27 +00:00
snipe 066cf81233 Added model bulk component 2026-01-23 16:46:52 +00:00
snipe 1b4552cf30 Refactorered bulk action component 2026-01-23 16:46:42 +00:00
snipe 0ba8ee1c5f Added bulkactions named slot in box index 2026-01-23 16:45:48 +00:00
snipe 5c4f3a5aec Removed unneeded body blade 2026-01-23 16:45:30 +00:00
snipe c963c0b25b Updated path for new table component location 2026-01-23 15:45:36 +00:00
snipe b3a4fb2676 Use new user bulk edit blade 2026-01-23 15:45:19 +00:00
snipe 0b82902248 Fixed background loading color 2026-01-23 15:45:06 +00:00
snipe e7f70ccd1f Moved to new component structure 2026-01-23 15:44:52 +00:00
snipe 683395599f Moved files into table directory 2026-01-23 15:44:12 +00:00
snipe 755d7c2351 Added printIgnore, reordered fields 2026-01-23 15:43:35 +00:00
snipe 17d91bcd8e Merge pull request #18479 from grokability/improved-tab-components
Removed font-size override on tabs
2026-01-23 13:53:33 +00:00
snipe 2633ec10dc Removed font-size override on tabs 2026-01-23 13:52:00 +00:00
snipe c4f772c8d9 Merge pull request #18478 from grokability/refined-sticky-columns
Added sticky column
2026-01-23 13:50:49 +00:00
snipe 18addf2a87 Added sticky column 2026-01-23 13:49:09 +00:00
snipe eee826248d Merge pull request #18476 from marcusmoore/fixes/18475-action-log-checkin-during-import
Fixed #18475 - reference the correct model when checking in an asset via import
2026-01-23 09:37:50 +00:00
Marcus Moore 96a817753c Pass the assigned model to the event instead of always passing a User 2026-01-22 14:24:37 -08:00
snipe 600b06e66b Merge pull request #18474 from grokability/move-box-index
Renamed box blade component wrapper to index
2026-01-22 21:10:53 +00:00
snipe cd680daa4c Merge remote-tracking branch 'origin/develop' 2026-01-22 20:58:42 +00:00
snipe 315b716e87 Removed advanced search from files table
It’s not wired up on the backend, so…
2026-01-22 20:50:24 +00:00
snipe b2f1966a78 Renamed box blade component wrapper to index 2026-01-22 20:41:25 +00:00
snipe 6305f87037 Merge pull request #18473 from grokability/added-tab-component
Added tab components
2026-01-22 20:37:11 +00:00
snipe ab02b67d3c Merge remote-tracking branch 'origin/develop' 2026-01-22 20:34:51 +00:00
snipe 0f4086eaf0 Added gates to the tab panes as well 2026-01-22 20:32:33 +00:00
snipe e7c5329e57 Merge pull request #18472 from Godmartinz/fix-n+1-issue
Moved helper query, to eager load through Asset API index
2026-01-22 20:27:44 +00:00
snipe ad82ea86c8 Added tab components 2026-01-22 20:25:33 +00:00
Godfrey M c310e1e3b7 update blade 2026-01-22 11:37:24 -08:00
Brady Wetherington 53149666ad Merge branch 'develop' into use_new_laravel_scim_server 2026-01-22 19:26:41 +00:00
Brady Wetherington 5d55c5021b Fix last of groups, phone numbers, etc. 2026-01-22 19:16:22 +00:00
Godfrey M aaf9372474 move helper query to eager load in the asset api 2026-01-22 11:12:49 -08:00
snipe 2cf169359e Missed updating the closing tags 2026-01-22 15:45:53 +00:00
snipe 7f67f8c20d Merge pull request #18471 from grokability/move-box-blades-into-own-directory
Moved anonymous box blade components into their own directory
2026-01-22 15:44:10 +00:00
snipe 5607dfcecb Moved anonymous box blade components into their own dir 2026-01-22 15:38:20 +00:00
Giannis Kapetanakis ca99f525c9 Do not delete asset name if update request does not have a name 2026-01-22 12:40:59 +02:00
snipe 7e92517d13 Merge remote-tracking branch 'origin/develop' 2026-01-22 08:46:46 +00:00
snipe 1ebb67b2e7 Nicer route formatting for maintenances 2026-01-22 08:45:38 +00:00
snipe d9ef7b43b0 Merge remote-tracking branch 'origin/develop' 2026-01-21 19:59:59 +00:00
snipe c074fae885 Merge pull request #18459 from Godmartinz/moar_label_fixes
Fixes #18353 Label title scales with label fields. adjusted label row allotment.
2026-01-21 19:58:32 +00:00
snipe c5ada0fc2f Merge pull request #18466 from marcusmoore/eager-load-expiring-alerts-command
Added eager load to Expiring Alerts command
2026-01-21 19:57:44 +00:00
snipe 5268b0f67f Merge pull request #18456 from grokability/container-component-phase-2
Next step in container+box component
2026-01-21 19:57:32 +00:00
Marcus Moore 7e10089c13 Eager load assignedTo and supplier 2026-01-21 11:49:02 -08:00
Godfrey M 1dab36da2d replaced extracted variables with array 2026-01-21 10:32:26 -08:00
snipe fab50e53b8 Merge pull request #18458 from marcusmoore/fixes/17309-asset-eol-in-custom-report
Fixed #17309 - include EOL date in custom asset report
2026-01-21 11:45:08 +00:00
Godfrey M 10cfe6d37a remove duplicate parameter 2026-01-20 16:23:36 -08:00
Godfrey M 3718ce9749 if label is null make room for value 2026-01-20 16:18:13 -08:00
Godfrey M fd39c8bf11 update title help text 2026-01-20 16:09:04 -08:00
Godfrey M 2e122fa8d8 update LW 11354 2026-01-20 16:00:56 -08:00
Godfrey M 66d85d17d9 update LW 1933081 2026-01-20 16:00:24 -08:00
Godfrey M 61bc570d59 add title to layout helper, update lw2112283 2026-01-20 15:59:40 -08:00
Marcus Moore 62dbd400a4 Use asset_eol_date in custom asset report 2026-01-20 15:07:19 -08:00
snipe 74af52d29d Merge pull request #18457 from marcusmoore/fixes/api-image-upload
Fixed storing image for accessory and consumable creation via api
2026-01-20 22:28:04 +00:00
Marcus Moore 59f377b058 Prepare images prior to validation in accessory and asset creation requests 2026-01-20 13:38:01 -08:00
snipe 949f65b210 Merge pull request #18356 from Godmartinz/add-first-checkout-to-asset
Adds #17210 1st checkout to asset view and index
2026-01-20 20:36:21 +00:00
snipe 4046fbae89 Merge pull request #18256 from iryadifarhan/fix/audit-log-displays-negative-number-incorrectly-when-next-audit-date-filled-with-current-date
Fixes inconsistent negative symbol at Audit Log Report when Next Audit Date is set to the current date
2026-01-20 20:35:16 +00:00
snipe da8776c2f1 Larger group select box 2026-01-20 20:20:39 +00:00
snipe 4043df1d02 Sort groups by name, asc 2026-01-20 20:13:22 +00:00
snipe 3bc5ab593a Next step in container+box component 2026-01-20 14:49:09 +00:00
snipe 6dad0d669f Merge pull request #18454 from grokability/container-components
Use basic container+box for primary index pages with one column
2026-01-19 16:54:45 +00:00
snipe 39f581a826 Use basic container+box for primary index pages with one column 2026-01-19 16:47:55 +00:00
snipe 2034b25b25 Set footer to default false 2026-01-19 16:20:48 +00:00
snipe 468a7aa911 Added button component 2026-01-19 16:19:07 +00:00
snipe ec50643d96 Basic container+box components 2026-01-19 16:17:47 +00:00
snipe 3b98fb666f Added tel as form type to make look right 2026-01-19 16:15:14 +00:00
snipe f17eeed579 Added fax icon 2026-01-19 15:09:28 +00:00
snipe 452d0b6f6e Merge remote-tracking branch 'origin/develop' 2026-01-19 11:44:04 +00:00
snipe 41450b6e1b Merge pull request #18368 from marcusmoore/feature/group-create-edit-load-improvement
Improved loading speeds on group create and edit page
2026-01-19 11:38:00 +00:00
snipe 30029462b1 Merge remote-tracking branch 'origin/develop' 2026-01-17 11:40:22 +00:00
snipe e109879cac Small autolabeler improvements 2026-01-17 11:40:08 +00:00
snipe 90ad4e9abf Merge remote-tracking branch 'origin/develop' 2026-01-17 11:27:43 +00:00
snipe fd0e2b1a96 Fixed indenting and page footer 2026-01-17 11:27:34 +00:00
snipe 19d637efea Merge remote-tracking branch 'origin/develop' 2026-01-16 13:03:26 +00:00
snipe 6c18b35276 Added barcode class 2026-01-16 13:03:17 +00:00
snipe 184eddb5cf Merge remote-tracking branch 'origin/develop' 2026-01-16 12:52:43 +00:00
snipe 1d577b0171 Merge pull request #18450 from grokability/#18449-small-sidenav-fixes
Fixed #18449 - small sidenav improvements for selected contexts
2026-01-16 12:51:52 +00:00
snipe 05c998227a Fixed #18449 - small sidenav improvements for selected contexts 2026-01-16 12:48:28 +00:00
snipe 53ed810d86 Merge remote-tracking branch 'origin/develop' 2026-01-16 11:38:09 +00:00
snipe 7c136b6f57 Use fa-fw in footer icons 2026-01-16 11:37:57 +00:00
snipe 4e510d9d8c Merge remote-tracking branch 'origin/develop'
# Conflicts:
#	resources/views/models/index.blade.php
2026-01-16 11:36:35 +00:00
snipe e1f30f96c9 Remove stray closing divs 2026-01-16 11:36:10 +00:00
snipe 146d0cefc0 Removed extra closing divs 2026-01-16 11:35:18 +00:00
snipe 0103bd58e1 Merge pull request #18434 from Godmartinz/label_lay_fix
Fixes Label text scaling
2026-01-15 21:13:01 +00:00
Godfrey M dbc1e7d6ab remove scaling from label title 2026-01-15 12:03:45 -08:00
snipe ea706863b5 Merge remote-tracking branch 'origin/develop' 2026-01-15 11:42:18 +00:00
snipe 04f4f5b57c Merge pull request #18439 from grokability/#18135-better-handle-cli-importer-permissions
Fixed #18135 - only unset sensitive variables in the web UI importer
2026-01-15 11:39:03 +00:00
snipe 98b9246c10 Merge pull request #18442 from uberbrady/fewer_scim_exceptions
Fixed - throw fewer exceptions on SCIM misconfigurations
2026-01-15 11:38:49 +00:00
snipe 1e158721ee Merge remote-tracking branch 'origin/develop' 2026-01-15 11:10:09 +00:00
snipe ab4eefcac2 Added links to snipeit-mcp (by @jameshgordy) and SnipeScheduler (by @JSY-Ben) 2026-01-15 11:09:50 +00:00
snipe cf3b36f124 Merge remote-tracking branch 'origin/develop' 2026-01-15 09:45:40 +00:00
snipe 8da01b8569 Check for ID in ldap sync UI screen 2026-01-15 09:45:29 +00:00
snipe c90afaa312 Fixed quotes in cli purge eula command 2026-01-15 09:10:31 +00:00
snipe 9f20bb89c1 Merge remote-tracking branch 'origin/develop' 2026-01-14 21:37:54 +00:00
snipe dfe664b779 Merge pull request #18437 from grokability/#18409-purge-signature-pdfs
Fixed #18409 - command line option to purge signatures
2026-01-14 21:37:35 +00:00
snipe 88bd1fd6ef Merge pull request #18387 from vasiliyplotnikov/mysql_rds_ssl_support_18312
Fixed #18312: support aws rds mysql with force tls
2026-01-14 21:23:18 +00:00
snipe 33f8823edb Merge remote-tracking branch 'origin/develop' 2026-01-14 21:17:28 +00:00
snipe 06d5c0a86c Merge pull request #18440 from ManiacTwister/fix-importer-logfile
Fixed #8740: Use log instance with configured log path
2026-01-14 21:17:09 +00:00
snipe e12a5eda01 Merge remote-tracking branch 'origin/develop' 2026-01-14 20:56:44 +00:00
snipe b3c59b2cc3 Use readonly style with light/dark on LDAP settings 2026-01-14 20:56:35 +00:00
Brady Wetherington 778da511a5 Merge branch 'develop' into use_new_laravel_scim_server 2026-01-14 15:38:34 +00:00
Brady Wetherington 24d5969ce8 Bump versions of our branch of laravel-scim-server to reduce reollbar usage 2026-01-14 14:37:47 +00:00
Brady Wetherington 84940f12c5 add fix to handling blank emails, add notes on things that look weird 2026-01-14 14:31:16 +00:00
snipe 6ad42a02ad Merge remote-tracking branch 'origin/develop' 2026-01-14 14:21:50 +00:00
snipe 90b1ee4805 Check that signature exists on the server before trying to display 2026-01-14 14:21:41 +00:00
snipe 0c9d5ca9da Merge remote-tracking branch 'origin/develop' 2026-01-14 14:13:53 +00:00
snipe e05ecd0c3e Add created_by on acceptance logging to action_log 2026-01-14 14:13:43 +00:00
snipe 441657cbfb Merge remote-tracking branch 'origin/develop' 2026-01-14 13:48:54 +00:00
snipe 0fb6b02fc4 Merge pull request #18418 from Godmartinz/rb20479
Fix [RB-20479] Checkin/Checkout notifications from logging as errors
2026-01-14 13:37:48 +00:00
snipe f83df0d651 Merge remote-tracking branch 'origin/develop' 2026-01-14 13:34:29 +00:00
snipe e667cd20a8 Set require_signature to default to 0 2026-01-14 13:30:54 +00:00
ManiacTwister d06c56367f Fixed #8740: Use log instance with configured log path 2026-01-14 14:23:42 +01:00
snipe 039b4cf19f Fixed #18135 - only unset variables if the user is authenticated (Web UI) 2026-01-14 13:10:46 +00:00
snipe ca0961bd49 Clarified text 2026-01-14 12:50:57 +00:00
snipe 79528fa87b Fixed #18409 - command line option to purge signatures 2026-01-14 12:45:18 +00:00
Godfrey M d96d0b1bcb applied to LabelWriter_11354 2026-01-13 12:11:30 -08:00
Godfrey M 02c237404e applied to TZe_24mm_E 2026-01-13 12:07:39 -08:00
Godfrey M c56f5282ff applied to TZe_241 2026-01-13 12:02:05 -08:00
Godfrey M d62f10cb46 apply helper to L4736_A 2026-01-13 11:57:53 -08:00
Godfrey M 4c6f123cda apply helper to L6009_A 2026-01-13 11:55:10 -08:00
Godfrey M b0b1829426 add Helper function for label layout, applied to 1933081 2112283" 2026-01-13 11:50:14 -08:00
snipe 68b590c263 Merge pull request #18419 from Godmartinz/rb20638
Refactor the exceptions for Audit log (again)
2026-01-13 18:20:20 +00:00
Godfrey M b45efddd9a readd connection and throwable 2026-01-13 08:56:12 -08:00
snipe d8f5d8c6ec Merge remote-tracking branch 'origin/develop' 2026-01-13 13:34:18 +00:00
snipe 56baa8ac9f Fixed manager view label alignment 2026-01-13 13:34:09 +00:00
Brady Wetherington 0f45ecc00f Merge branch 'develop' into use_new_laravel_scim_server 2026-01-13 13:31:15 +00:00
snipe 15aa64ed28 Merge remote-tracking branch 'origin/develop' 2026-01-13 13:30:52 +00:00
snipe 6d0bfeb420 Fixed #18422 - Hide edit buttons if the manager is looking at a different profile 2026-01-13 13:30:42 +00:00
snipe ceff334420 Merge remote-tracking branch 'origin/develop' 2026-01-13 12:43:25 +00:00
snipe 4ee2db68fc Fixed #18429 - corrected string for requestable vs requested items 2026-01-13 12:43:07 +00:00
snipe 1f04d0023b Merge remote-tracking branch 'origin/develop' 2026-01-13 12:38:43 +00:00
snipe 4427fdcaec Use theme button for LDAP sync 2026-01-13 12:38:33 +00:00
snipe 4de642c6a4 Merge pull request #18430 from grokability/#18415-null-ldap-display-name
Fixed #18415 - LDAP sync improvements to allow null display_name and bulk editing display_name
2026-01-13 12:37:48 +00:00
snipe d3eb89a97c Fixed display name in user table 2026-01-13 12:01:34 +00:00
snipe d7362a3785 Nicer light/dark for ldap sync page 2026-01-13 12:01:12 +00:00
snipe 26347ac41e Add display name to bulk user edit 2026-01-13 12:00:46 +00:00
snipe b396da3f33 Use null instead of blank if value is empty 2026-01-13 12:00:27 +00:00
snipe 306a0bf6de Merge remote-tracking branch 'origin/develop' 2026-01-13 10:22:38 +00:00
snipe 8000e274c6 Fixed #18424 - adds BYOD to view-assets page 2026-01-13 10:22:19 +00:00
akemidx 5d91e0fa0a name box alignment/icons for shared or not 2026-01-12 07:48:53 -05:00
akemidx eb41247f2d changing 'shared_report_template' to 'is_shared' in DB part 2, also last commit deleted an unused request file 2026-01-08 18:54:44 -07:00
akemidx d53eafe87a changing 'shared_report_template' to 'is_shared' in DB 2026-01-08 18:52:36 -07:00
Godfrey M e48c40e5af remove use statements 2026-01-08 15:58:15 -08:00
Godfrey M df51318fb9 remove throwable exception..too vague 2026-01-08 15:55:30 -08:00
Marcus Moore 065c17002e Remove unused test cases 2026-01-08 15:18:16 -08:00
Marcus Moore 0e46a54013 Improve input alignment 2026-01-08 15:08:56 -08:00
Marcus Moore 0e35fb941b Improve assertions 2026-01-08 14:17:10 -08:00
Marcus Moore 71c9b927c6 Allow using same template name 2026-01-08 14:17:00 -08:00
Godfrey M 0327d01287 typo fixes" 2026-01-08 10:52:27 -08:00
Godfrey M 0ab206ca13 log warnings instead of errors for 4xx status codes 2026-01-08 09:47:35 -08:00
akemidx e42960ea15 sharing a report template test 2026-01-07 18:49:34 -07:00
Marcus Moore 636d42a52e Make test more explicit 2026-01-07 16:42:47 -08:00
Marcus Moore 1451843f84 Implement test for viewing shared template 2026-01-07 16:39:10 -08:00
Marcus Moore f8af21306a Handle attempting to delete another user's template 2026-01-07 16:37:34 -08:00
Marcus Moore 4e874cdb1b Fix update logic 2026-01-07 16:13:22 -08:00
akemidx dbd9a844dc scaffold test cases around sharing templates 2026-01-07 16:29:32 -07:00
snipe 542cdef0bd Merge remote-tracking branch 'origin/develop' 2026-01-07 15:55:44 +00:00
snipe f5955e14ff Merge pull request #18410 from grokability/#18402-saml-fields-readonly-display
Fixed #18402 - Clean up SAML readonly display
2026-01-07 15:55:25 +00:00
snipe a0df7adbd1 Override readonly styles on user edit page 2026-01-07 15:50:01 +00:00
snipe 82a4398ef6 Removed @disabled on textarea 2026-01-07 15:37:05 +00:00
snipe 9271930ba8 Clean up SAML readonly display 2026-01-07 15:27:33 +00:00
snipe f149f0d994 Merge remote-tracking branch 'origin/develop' 2026-01-07 13:36:31 +00:00
snipe 14ff325608 Merge pull request #18404 from kenchan0130/patch-displayname
fixed: Prefer display name of user on UI
2026-01-07 13:29:56 +00:00
Tadayuki Onishi 8e37fcc71e Since displayname should be referenced in the UI, we've changed it to use displayname 2026-01-07 21:59:27 +09:00
snipe bf910bc708 Merge pull request #18406 from dbakan/patch-1
Fixed #18405: Clean up closing divs to fix footer position
2026-01-07 12:55:54 +00:00
Daniel Albertsen 1136ea0779 Clean up stray closing div tags
Removed redundant closing div tags in the edit view.
2026-01-07 12:43:03 +01:00
Daniel Albertsen 9ad94b6562 Fix white space indention 2026-01-07 12:43:03 +01:00
akemidx c5284ed195 works fully, just needs to restrict editing for non template creator 2026-01-06 17:21:22 -07:00
Marcus Moore 5cd92dd794 Remove redundant display of "Category" 2026-01-05 15:13:27 -08:00
snipe 5ddb0b4a55 Merge remote-tracking branch 'origin/develop' 2026-01-05 22:29:17 +00:00
snipe 990858ba41 Merge pull request #18398 from grokability/fixes-rb-#20282-set-files-variable
Set `$files` in UploadedFilesController API POST endpoint only if there are results
2026-01-05 22:28:48 +00:00
snipe 406951fc84 Set $files only if there are results 2026-01-05 22:17:06 +00:00
snipe 41c7bf4aaa Merge pull request #18397 from Godmartinz/rb-20474-fix
Adds [RB-20474] a try/catch to ms teams audit notification
2026-01-05 20:39:42 +00:00
Godfrey M 1543634cb0 remove line break 2026-01-05 12:39:28 -08:00
Godfrey M b935752ec0 reference endpoint appropriately" 2026-01-05 12:35:20 -08:00
Godfrey M 2a60b7b7b2 move endpoint 2026-01-05 12:31:00 -08:00
snipe cef78687b3 Merge remote-tracking branch 'origin/develop' 2026-01-05 20:27:37 +00:00
snipe 2f29edc01f Changed “reset to default” button to theme button style 2026-01-05 20:27:25 +00:00
snipe 134491b59e Merge remote-tracking branch 'origin/develop'
# Conflicts:
#	public/js/dist/all.js
#	public/js/dist/all.js.map
#	public/mix-manifest.json
2026-01-05 20:20:51 +00:00
snipe 812ff0bfd2 Bumped jspdf to >=4.0.0 2026-01-05 20:20:09 +00:00
Godfrey M 201c4fa0d9 remove use path 2026-01-05 12:15:37 -08:00
Godfrey M ced83b9bfc add a try catch to ms teams audit notification 2026-01-05 12:14:42 -08:00
akemidx bd98ee62e1 something something prebreak 2026-01-05 12:16:16 -07:00
snipe e67c5273d7 Merge remote-tracking branch 'origin/develop' 2026-01-05 17:22:50 +00:00
snipe b4b9339065 Merge pull request #18396 from uberbrady/fix_select2_break_on_modal
Fixed #17652 - don't break company drop-down with modals
2026-01-05 17:22:29 +00:00
snipe f3cd68eb3f Merge remote-tracking branch 'origin/develop' 2026-01-05 17:21:44 +00:00
snipe ad57dea0e5 Suppress refresh button on client-side tables
Refresh only works on server-side tables
2026-01-05 17:21:32 +00:00
snipe 1e0a348b8e Merge remote-tracking branch 'origin/develop' 2026-01-05 17:19:56 +00:00
snipe 9c06a2126d Update sha.js to 2.4.12 2026-01-05 17:19:43 +00:00
snipe dab030e95d Merge remote-tracking branch 'origin/develop' 2026-01-05 16:56:02 +00:00
snipe 4995bc0d0d Small tweaks to select2 values 2026-01-05 16:55:53 +00:00
Brady Wetherington d2369893c8 Remove ID from company select in partial 2026-01-05 16:30:47 +00:00
snipe e48adf6443 Merge remote-tracking branch 'origin/develop' 2026-01-05 16:06:08 +00:00
snipe 505bca8386 Fixed :focus on theme buttons 2026-01-05 16:05:59 +00:00
snipe 31ca93a259 Merge remote-tracking branch 'origin/develop' 2026-01-05 15:40:59 +00:00
snipe 71523b7038 Merge pull request #18393 from grokability/#18291-bump-alpine
Attempted fix of #18291 - update PHP versions and alpine versions
2026-01-05 15:36:40 +00:00
snipe 9885dc9c8a Merge remote-tracking branch 'origin/develop' 2026-01-05 15:34:19 +00:00
snipe 00d9d9f132 Merge pull request #18395 from grokability/#18394-ldap-text-dark-mode
Fixed #18394 - LDAP sync test table background in dark mode
2026-01-05 15:34:00 +00:00
snipe 320dc3fac6 Fixed LDAP sync test table background in dark mode 2026-01-05 15:29:50 +00:00
Brady Wetherington 6e68e43a25 In this version of Alpine, php84 is default, so it's easier. 2026-01-05 15:11:08 +00:00
snipe a19c391aa1 Check can edit on demo in bulk user edit 2026-01-05 14:58:14 +00:00
snipe 32f0101c1b Attempted fix of #18291 - update PHP versions and alpine versions 2026-01-05 14:05:47 +00:00
snipe 12b9fdced5 Merge remote-tracking branch 'origin/develop' 2026-01-05 13:39:48 +00:00
snipe 0af45a53a9 Merge pull request #18359 from marcusmoore/17816-qty-in-activity-report
Fixed #17816 - added quantity to activity reports
2026-01-05 13:03:56 +00:00
snipe 37773d35f2 Merge pull request #18391 from ubc-cpsc/fix/PKSA-8x19-j2j3-bn67-sodium_compat
fix: paragonie/sodium_compat - Missing check that a point is on the prime subgroup for Edwards25519
2026-01-05 12:58:24 +00:00
snipe fca3eb4b7b Merge pull request #18392 from grokability/#18377-min-value-for-name
Fixes #18377 - make min value for names consistent
2026-01-05 12:56:29 +00:00
snipe 5e9e0b70db Fixes #18377 - make min value for names consistent 2026-01-05 12:51:49 +00:00
Joël Pittet 5242ffc04b fix: Missing check that a point is on the prime subgroup for Edwards25519 2026-01-02 13:55:18 -08:00
snipe f0c9a5b2dc Merge remote-tracking branch 'origin/develop' 2025-12-31 05:31:06 +00:00
snipe b3902e82fc Merge pull request #18388 from dylang3/fix/unintended-shell-exec-call
Fixed #18384: Remove backticks in bulk-actions.blade.php to avoid unintentional shell_exec() call
2025-12-31 05:30:06 +00:00
Dylan Guthrie d70eff6fc4 Fix: Remove backticks in bulk-actions.blade.php to avoid unintentional shell_exec() call 2025-12-30 22:37:49 -06:00
Vasily Plotnikov 5b5695ffe1 Fixed #18312: support aws rds mysql with force tls 2025-12-30 11:59:31 +00:00
snipe deb44cad30 Merge remote-tracking branch 'origin/develop' 2025-12-23 13:34:36 +00:00
snipe 35fdca3607 Added logo hover color 2025-12-23 13:33:53 +00:00
snipe 93080523d0 Merge remote-tracking branch 'origin/develop' 2025-12-21 08:34:42 +00:00
snipe b7b8f5a7e7 Merge pull request #18348 from grokability/dependabot/github_actions/develop/actions/cache-5
Bump actions/cache from 4 to 5
2025-12-21 08:16:48 +00:00
snipe 59ee55a6b2 Merge pull request #18349 from grokability/dependabot/github_actions/develop/actions/upload-artifact-6
Bump actions/upload-artifact from 5 to 6
2025-12-21 08:16:29 +00:00
snipe d85b25d683 Merge pull request #18363 from ubc-cpsc/task/request-get
fix: replace deprecated Symfony Request::get() usage
2025-12-21 08:09:50 +00:00
snipe 0108006fab Merge remote-tracking branch 'origin/develop' 2025-12-19 06:32:09 +00:00
snipe 755bb8f189 Merge pull request #18326 from dylang3/fix/users-groups-sync
Fixes #18325: Ensure existing permission group users are maintained when editing a group
2025-12-19 06:26:44 +00:00
Marcus Moore f53dcbc64f Only pull needed fields from database 2025-12-18 13:37:56 -08:00
Joël Pittet 0f215bbcf8 fix: replace deprecated Symfony Request::get() usage 2025-12-17 18:44:04 -08:00
snipe 9770775770 Merge remote-tracking branch 'origin/develop' 2025-12-17 16:27:42 +00:00
snipe 0b63bcc056 Derp. Copypasta 2025-12-17 16:25:03 +00:00
snipe 03116f5ece Fixed tests 2025-12-17 16:16:58 +00:00
snipe 5c091d8690 DIsable delete button if user cannot delete the user 2025-12-17 15:31:57 +00:00
snipe da1ca24190 Remove avatar delete - should be done in purge 2025-12-17 15:29:07 +00:00
akemidx 33f7a8d356 save copy 2025-12-16 21:38:13 -05:00
akemidx 64c3fe9099 notes and new direction? 2025-12-16 21:27:51 -05:00
Marcus Moore fa7382851f Use enum 2025-12-16 15:00:07 -08:00
Marcus Moore ab363596fd Replace qty with quantity 2025-12-16 14:55:00 -08:00
Marcus Moore b05970acf4 Add command to migrate license seat quantities in action log table 2025-12-16 13:48:23 -08:00
snipe aa6b70c296 Merge remote-tracking branch 'origin/develop' 2025-12-16 20:31:58 +00:00
snipe 00171e6d16 Fixed api docs url 2025-12-16 20:31:50 +00:00
snipe 061e0ded72 Merge remote-tracking branch 'origin/develop' 2025-12-16 20:26:18 +00:00
snipe 81bdd86fb7 Merge pull request #18358 from grokability/add-scim-url
Add SCIM url to admin settings
2025-12-16 20:06:50 +00:00
snipe 60ff06bcf0 Fixed nav footer label color 2025-12-16 20:02:20 +00:00
snipe a3e3f48d47 Added scim and API links to admin page 2025-12-16 19:59:52 +00:00
Godfrey M a3a79a696f adds first checkout to asset view and index 2025-12-16 08:48:08 -08:00
Marcus Moore 6947672046 Add seats to transformer 2025-12-15 17:31:56 -08:00
Marcus Moore 6f77e96998 Log quantity when adding or removing seats from license 2025-12-15 17:26:05 -08:00
Marcus Moore 8a595aa269 Display qty in history 2025-12-15 15:12:34 -08:00
Marcus Moore 1ccf38221f Set qty when accepting or declining checkout 2025-12-15 14:45:05 -08:00
Marcus Moore 18c639e6c0 WIP - adding qty to more event calls 2025-12-15 14:38:13 -08:00
Marcus Moore 06224371b3 Begin passing qty in CheckoutableCheckedOut event 2025-12-15 12:47:36 -08:00
dependabot[bot] d06105f410 Bump actions/upload-artifact from 5 to 6
Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 5 to 6.
- [Release notes](https://github.com/actions/upload-artifact/releases)
- [Commits](https://github.com/actions/upload-artifact/compare/v5...v6)

---
updated-dependencies:
- dependency-name: actions/upload-artifact
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-12-15 08:02:41 +00:00
dependabot[bot] 3226340b08 Bump actions/cache from 4 to 5
Bumps [actions/cache](https://github.com/actions/cache) from 4 to 5.
- [Release notes](https://github.com/actions/cache/releases)
- [Changelog](https://github.com/actions/cache/blob/main/RELEASES.md)
- [Commits](https://github.com/actions/cache/compare/v4...v5)

---
updated-dependencies:
- dependency-name: actions/cache
  dependency-version: '5'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-12-15 08:02:30 +00:00
snipe 25ef5d64b4 Merge remote-tracking branch 'origin/develop' 2025-12-13 13:44:34 +00:00
snipe f286558065 Fixed #18344 2025-12-13 13:44:23 +00:00
snipe 9586c50cb5 Merge pull request #18347 from grokability/added-reset-for-theme
Added reset for theme, preview for effects in profile
2025-12-13 13:43:23 +00:00
snipe 4658bf38c5 Removed user migration for colors 2025-12-13 13:34:10 +00:00
snipe 951a4e37f3 New strings 2025-12-13 13:33:59 +00:00
snipe 6ad3154035 Added confetti, sounds test on checkboxes 2025-12-13 13:33:49 +00:00
snipe d7fa4a0df2 Tweaked colors 2025-12-13 13:33:13 +00:00
snipe 1112a40f0f Added reset button 2025-12-13 13:33:06 +00:00
snipe 78d1256b74 Merge remote-tracking branch 'origin/develop'
# Conflicts:
#	config/version.php
2025-12-12 08:47:16 +00:00
snipe a3f9aad418 Bumped version 2025-12-12 08:46:25 +00:00
snipe dba8cb83bf Merge remote-tracking branch 'origin/develop' 2025-12-12 07:49:53 +00:00
snipe 1954c607cd #18339 - removed heroku support 2025-12-12 07:49:01 +00:00
snipe 744124f407 Merge remote-tracking branch 'origin/develop' 2025-12-12 07:14:51 +00:00
snipe 3c14921a8c #18340 - jfc swift 2025-12-12 07:14:36 +00:00
snipe b595fe7488 Merge remote-tracking branch 'origin/develop' 2025-12-12 06:41:18 +00:00
snipe b0b194cef7 Fixed missing comma 2025-12-12 06:41:06 +00:00
snipe eb0a3a27d3 Merge remote-tracking branch 'origin/develop' 2025-12-12 05:03:09 +00:00
snipe 72fbcd72e0 Fix for fullscreen with dark/light 2025-12-12 05:02:56 +00:00
snipe 09e660a38c Merge remote-tracking branch 'origin/develop'
# Conflicts:
#	public/js/dist/all.js
#	public/js/dist/all.js.map
#	public/mix-manifest.json
2025-12-12 04:26:35 +00:00
snipe add1810fcc Added more options and validation to suppliers “new” modal 2025-12-12 04:18:42 +00:00
snipe eead2ce93e Adds cursor pointer to checkboxes and radios and their labels 2025-12-12 03:51:20 +00:00
akemidx 193fba71f3 fixing validation 2025-12-11 17:21:48 -05:00
snipe 5e60d96614 Simpler footer link color 2025-12-11 20:15:57 +00:00
snipe 85c721da99 Better alert color on dark 2025-12-11 20:14:33 +00:00
snipe f3f09dd9a5 Upgraded jquery to 3.7.1 2025-12-11 20:12:23 +00:00
snipe 29ad804ca8 Merge pull request #18332 from Godmartinz/add-category-to-account-accept-table
Fixed #18316 - Adds #18316 category to pending acceptance index table
2025-12-11 19:12:15 +00:00
Godfrey M a8c77d6e26 update accessor to laravel 11.x standards 2025-12-11 11:07:36 -08:00
snipe b949380db8 Fixed highlighted button in license toolbar 2025-12-11 18:38:40 +00:00
Godfrey M b7f6137a63 add accessor for category name on checkout acceptance model 2025-12-11 10:08:00 -08:00
snipe 181cd7f0dc Merge remote-tracking branch 'origin/develop' 2025-12-11 18:03:12 +00:00
snipe 10692dc587 Removed back button on history importer, themed upload button 2025-12-11 17:49:56 +00:00
snipe 8d0793e004 Merge remote-tracking branch 'origin/develop' 2025-12-11 17:45:23 +00:00
snipe 02da163ee0 Fixed modal header color in light mode 2025-12-11 17:45:14 +00:00
snipe 3199e94b3c Made icons fixed width via fa-fw 2025-12-11 16:49:02 +00:00
snipe ac2a1503e2 Merge remote-tracking branch 'origin/develop' 2025-12-11 16:45:48 +00:00
snipe ea10167607 Merge pull request #18333 from Godmartinz/fix-checkin-notification
Fixes [FD-52267] Expected Checkin Notification Shows Overdue instead of Reminder
2025-12-11 16:44:45 +00:00
snipe e617b913cd Merge remote-tracking branch 'origin/develop' 2025-12-11 16:44:01 +00:00
snipe 8f6208a3c9 Removed text-blue in bootstrap-tables 2025-12-11 16:42:56 +00:00
snipe 39c71481c9 Added breaks 2025-12-11 16:34:55 +00:00
snipe a38e49290e Added external link indicator to help text 2025-12-11 16:31:12 +00:00
snipe f974427964 Merge remote-tracking branch 'origin/develop' 2025-12-11 16:05:41 +00:00
snipe 1f311c8657 One more nullsafe 2025-12-11 16:05:31 +00:00
snipe c0406734bc Merge remote-tracking branch 'origin/develop' 2025-12-11 16:01:15 +00:00
snipe 66e80628f6 Account for no created_by value 2025-12-11 16:01:06 +00:00
akemidx 8a14800ef2 fixes/beginning validation 2025-12-11 03:42:10 -05:00
akemidx a46d73f562 spacing/hiding when no template loaded 2025-12-11 03:21:34 -05:00
Marcus Moore e908838376 Add failing tests 2025-12-10 15:44:51 -08:00
Marcus Moore 4b1339a11c Add qty to action_logs table 2025-12-10 13:30:34 -08:00
Godfrey M 620c43fd6d fixes expected checkin Notification 2025-12-10 11:33:08 -08:00
Godfrey M dfb9d5622a adds category to account accept index table 2025-12-10 10:43:59 -08:00
snipe af0aa7da4e Merge remote-tracking branch 'origin/develop' 2025-12-10 10:27:49 +00:00
snipe 75ddb50738 Use theme color for logo uploads 2025-12-10 10:27:40 +00:00
snipe 600238dd9b Merge remote-tracking branch 'origin/develop' 2025-12-10 09:38:51 +00:00
snipe 5a88e98ad9 Merge pull request #18330 from grokability/bigger-double-scrollbar-issue
Fixed #18317 - Longer double scrollbar issue
2025-12-10 09:38:37 +00:00
snipe 84a0544621 Removed <div class="table-responsive"> 2025-12-10 09:33:08 +00:00
snipe 8a1c7ee448 Remove <div class="table table-responsive"> 2025-12-10 09:09:12 +00:00
Dylan Guthrie c978be5cab send associated_users to view as collection 2025-12-09 19:47:42 -06:00
snipe 2fb29dad0a Merge remote-tracking branch 'origin/develop' 2025-12-10 00:09:17 +00:00
snipe 7d160abdaf Merge pull request #18323 from grokability/#18317-removed-responsive-table-divs
Fixed #18317 - Double scrollbars on some screens
2025-12-10 00:08:55 +00:00
snipe 6c5d2c6716 Merge pull request #18328 from grokability/#17197-download-importer-files
Added #17197: Ability to download uploaded import CSVs
2025-12-10 00:07:01 +00:00
snipe f3feff7988 Disable delete button if not owner of super admin 2025-12-09 23:59:22 +00:00
snipe 7d24f50cdc Removed extra whitespace 2025-12-09 23:49:21 +00:00
snipe 7c7375ed43 Undo temp delete commented out 2025-12-09 23:48:34 +00:00
snipe e2e4adca4e Generic message if the user tries to delete a file they don’t have access to 2025-12-09 23:46:53 +00:00
snipe a350b9bc3d Handle redirect if the user does not have permission to view results 2025-12-09 23:46:33 +00:00
snipe 7854543122 Added import-download controller 2025-12-09 23:46:13 +00:00
snipe 8b5636c0ab Override progress bar text color 2025-12-09 23:45:58 +00:00
snipe 9f948fd2ba Link to download and user 2025-12-09 23:45:49 +00:00
snipe 60fb67461a Added downnload route 2025-12-09 23:45:38 +00:00
snipe 5c896fc965 Merge pull request #18314 from Godmartinz/adjust-fonts-on-labelwriter-211xxx
Fixes [FD-52064] LabelWriter label font choice for fields, adds scaling to all labels.
2025-12-09 22:08:35 +00:00
Dylan Guthrie 242201ca91 Fix: Ensure existing permission group users are maintained when editing group 2025-12-09 16:06:49 -06:00
akemidx 865392d1f7 margin 2025-12-09 14:10:32 -05:00
akemidx b880ed2371 front end clarity 2025-12-09 13:14:09 -05:00
snipe c779988771 Fixed gallery cards in dark mode 2025-12-09 16:53:02 +00:00
snipe e6eb15d053 Removed the duplicate table-responsive in BS tables 2025-12-09 16:52:51 +00:00
snipe 05b957df19 Merge pull request #18322 from grokability/bulk-checkin-delete-UI-fixes-dark-mode
Bulk checkin delete UI fixes dark mode
2025-12-09 15:38:25 +00:00
snipe 96da8a5fab Updated route 2025-12-09 15:28:22 +00:00
snipe 62bf61402e Updated strings 2025-12-09 15:24:16 +00:00
snipe 227be798f6 Visual tweaks to bulk 2025-12-09 15:24:10 +00:00
snipe 53f304d137 Updated view with tooltip on disabled 2025-12-09 15:23:59 +00:00
snipe 137d362369 Added breadcrumbs 2025-12-09 15:21:50 +00:00
snipe 5b2cf54f50 Fixed accessory buttons on mobile 2025-12-09 14:06:53 +00:00
snipe b4bc785f7c Merge remote-tracking branch 'origin/develop' 2025-12-09 13:13:59 +00:00
snipe 98a8e4c2ec Merge pull request #18319 from uberbrady/fix_component_edit
Fixed [RB-4066], #18308 - Fix error on saving component after create
2025-12-09 13:13:45 +00:00
Brady Wetherington bed6b04c3d Unset the 'sum_unconstrained_assets' attribute before saving 2025-12-09 13:00:41 +00:00
Marcus Moore def04017e0 Improve readability in tests 2025-12-08 14:10:44 -08:00
Marcus Moore 9eeb916796 Improve clarity in test 2025-12-08 14:04:18 -08:00
Marcus Moore b06a0c5d83 Use value already computed 2025-12-08 13:59:07 -08:00
Marcus Moore 90541ba349 Use foreach instead of reduce 2025-12-08 13:57:38 -08:00
Marcus Moore 0cc346259b Use foreach instead of reduce 2025-12-08 13:51:30 -08:00
Marcus Moore 98c343b438 Improve method ordering 2025-12-08 13:48:22 -08:00
akemidx 7ee0cdc6c7 hide edit and delete for non report creators 2025-12-08 16:42:38 -05:00
akemidx 6a770832ba only creator can see share checkbox 2025-12-08 16:32:11 -05:00
akemidx ef0ff65162 scoping shared templates 2025-12-08 16:29:14 -05:00
akemidx 8c0e7e1bb3 share option saved in db column 2025-12-08 15:55:26 -05:00
snipe babb3ffb9c Merge remote-tracking branch 'origin/develop' 2025-12-08 20:24:31 +00:00
snipe 15c96f753c Revert hasMany “fix” 2025-12-08 20:22:55 +00:00
snipe 354bdeffbf Merge remote-tracking branch 'origin/develop' 2025-12-08 20:19:54 +00:00
snipe 512af90d31 Re-removed non-asset models from kits
These still do not work as expected.
2025-12-08 20:18:39 +00:00
Marcus Moore 8cb2ef7cac Add typehint 2025-12-08 12:17:04 -08:00
Marcus Moore 046b38e5c2 Improve method name 2025-12-08 12:10:25 -08:00
Marcus Moore d50d7fd631 Account for null value 2025-12-08 12:09:58 -08:00
snipe ed837b7527 Merge remote-tracking branch 'origin/develop' 2025-12-08 19:33:07 +00:00
snipe fa5dd99f00 Only try to print status name if it exists 2025-12-08 19:32:57 +00:00
Godfrey M a19282710b fix up 11354 label, and readd 1d barcode to 2112283 2025-12-08 10:44:21 -08:00
Godfrey M 2f3cfb0a4e fix labelwriter fonts and add scaling 2025-12-08 10:20:53 -08:00
snipe af4db94d17 Merge pull request #18306 from fdiaz3000/change-import-assetmodel
Change title_class to ucfirst in Object Import Command to allow AssetModel
2025-12-08 17:05:23 +00:00
snipe bcbf27acca Merge remote-tracking branch 'origin/develop' 2025-12-08 16:51:44 +00:00
snipe 80b037c5a5 Fixed label url 2025-12-08 16:51:36 +00:00
snipe 20bacfeecf Merge remote-tracking branch 'origin/develop' 2025-12-07 21:40:19 +00:00
snipe 8a128ae8c2 Fixed RB-4062 - double-braces 2025-12-07 21:40:02 +00:00
snipe beacfbb082 Merge remote-tracking branch 'origin/develop' 2025-12-07 15:02:17 +00:00
snipe df0d565ae5 Set audit button back to btn-primary 2025-12-07 15:02:07 +00:00
snipe 9ee755c112 More consistent bulk action labels 2025-12-07 14:58:08 +00:00
snipe 130aca2943 Merge remote-tracking branch 'origin/develop' 2025-12-07 14:53:10 +00:00
snipe 5ea76ecb66 Fixed checkmark class on model buk edit 2025-12-07 14:52:49 +00:00
snipe b8ff3ef41a Merge remote-tracking branch 'origin/develop' 2025-12-07 14:49:44 +00:00
snipe 3e8156be54 Merge pull request #18307 from grokability/bulk-model-edit-dark-light-fix
Fixed unreadable table on dark mode for asset model bulk edit, added breadcrumbs
2025-12-07 14:49:31 +00:00
snipe 47e192b530 Fixed breadcrumb title 2025-12-07 14:43:47 +00:00
snipe b33f222fc0 Smaller bulk delete form 2025-12-07 14:39:00 +00:00
snipe 20eab1f403 Fixed updated route names 2025-12-07 14:37:22 +00:00
snipe a283fdb75a Removed back button 2025-12-07 14:37:10 +00:00
snipe a29a115846 Nicer layout on asset bulk delete form 2025-12-07 14:36:59 +00:00
snipe 05ff9183fb Fixed weird top border 2025-12-07 14:31:47 +00:00
snipe 793d299c1d Fixed breadcrumbs 2025-12-07 14:31:01 +00:00
snipe 7d5f862f34 Use striped mode 2025-12-07 14:13:17 +00:00
snipe b0ab900a0f Fixed new dark mode for bulk model edit 2025-12-07 14:10:09 +00:00
Felix 0ea5012ba2 fix(import-command): 18305 change title_class to ucfirst 2025-12-06 15:00:43 -05:00
snipe 7ecb96d45a Merge remote-tracking branch 'origin/develop' 2025-12-06 01:08:46 +00:00
snipe 5f0d7fde39 Better selected color 2025-12-06 01:08:31 +00:00
snipe fe3c301ca2 Prod assets 2025-12-06 00:59:55 +00:00
snipe 3adf8847b0 Merge remote-tracking branch 'origin/develop'
# Conflicts:
#	public/css/build/app.css
#	public/css/build/app.css.map
#	public/css/build/overrides.css
#	public/css/build/overrides.css.map
#	public/css/dist/all.css
#	public/js/dist/all.js
#	public/js/dist/all.js.map
#	public/mix-manifest.json
2025-12-06 00:59:47 +00:00
snipe 9ae68f0000 More color tweaks 2025-12-06 00:58:32 +00:00
snipe 36415a1f7a Updated buttons 2025-12-05 23:43:56 +00:00
snipe 39d1aa932c Moved clear button 2025-12-05 21:35:47 +00:00
snipe 82b37c3b58 Removed back button 2025-12-05 21:25:17 +00:00
snipe c73c2b003a Merge remote-tracking branch 'origin/develop' 2025-12-05 20:52:48 +00:00
snipe 65b39d3a30 Use the themed buttons 2025-12-05 20:51:47 +00:00
snipe 6a59119c58 Merge pull request #18303 from grokability/update-users-api-with-disallowed-fields-list
Update users api with disallowed fields list
2025-12-05 20:32:55 +00:00
snipe 8b4387ec32 Fixed weird indenting 2025-12-05 19:52:31 +00:00
snipe dc82f8f077 Updated tests 2025-12-05 19:27:05 +00:00
snipe 07e1f67e13 Disallow fill for sensitive fields 2025-12-05 19:27:01 +00:00
snipe 412f4c65c8 Fixed dark mode footer links 2025-12-05 18:35:18 +00:00
snipe a6d9c1f882 Merge remote-tracking branch 'origin/develop' 2025-12-05 18:07:13 +00:00
snipe bb5c142f52 Nicer footer color for light/dark 2025-12-05 18:06:48 +00:00
snipe a5e1528c0d Merge remote-tracking branch 'origin/develop' 2025-12-05 17:46:30 +00:00
snipe 904c20e879 Removed blue text override 2025-12-05 17:46:20 +00:00
snipe 612daa6824 Merge pull request #18302 from grokability/preflight-quickstart-cleanup
Preflight quickstart cleanup
2025-12-05 17:20:29 +00:00
snipe 02b6de2385 Added tests 2025-12-05 17:03:10 +00:00
snipe da5db1920e Use generic email address domains 2025-12-05 17:03:02 +00:00
snipe d20545741e Nicer views 2025-12-05 17:02:51 +00:00
snipe 03b42d2c6c Nicer styles 2025-12-05 17:02:19 +00:00
snipe e9dbeebbc4 Updated some strings 2025-12-05 17:02:09 +00:00
snipe bb53fa245b Removed email domain from required setup fields 2025-12-05 17:01:36 +00:00
snipe bc796498a3 Moved setup controller methods out of settings controller 2025-12-05 17:01:24 +00:00
snipe c25266054b Merge remote-tracking branch 'origin/develop' 2025-12-05 10:55:59 +00:00
snipe 0204414196 Handle /setup link colors via middleware 2025-12-05 10:55:49 +00:00
snipe c6b2017494 Merge pull request #18297 from Godmartinz/tze_24mm_E_2d-adjustment-and-scaling
Fixes [FD-50838] adjust `Tze_24mm_E` 2D barcode 20% bigger, scales fields, center label more
2025-12-05 08:57:20 +00:00
snipe 84fd48602e Merge pull request #18298 from Godmartinz/add-TZe_241
Adds [FD-52267] TZe_241 based on TZe_18mm sizes
2025-12-05 08:56:55 +00:00
Marcus Moore a34ea0804d Separate out info and prompt 2025-12-04 17:22:23 -08:00
Marcus Moore 0fbf4ce443 Move singular eula to bottom of email 2025-12-04 17:08:48 -08:00
Marcus Moore d062cc45df Add translation 2025-12-04 15:18:24 -08:00
Marcus Moore da790136ff WIP 2025-12-04 14:40:51 -08:00
Marcus Moore 134f374ada WIP 2025-12-04 14:39:37 -08:00
Marcus Moore df304a894f WIP 2025-12-04 14:38:13 -08:00
Marcus Moore 2d1d90e38c Add comment 2025-12-04 14:34:50 -08:00
Marcus Moore dcbdc6fcb8 WIP 2025-12-04 14:27:53 -08:00
Marcus Moore 5a4ef15de5 Avoid rendering rule if last item in loop 2025-12-04 14:22:13 -08:00
Marcus Moore affc4c8bd9 Styling 2025-12-04 14:07:10 -08:00
Marcus Moore bc5d6e89ba Readability 2025-12-04 14:05:22 -08:00
Marcus Moore c17e6811d2 Group categories visually 2025-12-04 14:03:11 -08:00
Marcus Moore 7f097c029a Fix indent 2025-12-04 13:52:26 -08:00
Godfrey M c8e8eb58aa adds TZe_241 based on TZe_18mm sizes 2025-12-04 12:41:57 -08:00
akemidx 60f5affe43 more sharing framewor. tests outlines 2025-12-04 13:48:36 -05:00
Godfrey M 0b087ca77d adjust 2d barcode 20% bigger, scale fields, center label more 2025-12-04 09:55:47 -08:00
snipe 444083ec5d Merge remote-tracking branch 'origin/develop' 2025-12-04 17:54:31 +00:00
snipe bf01a11fec Fixed label colors in dark/light 2025-12-04 17:54:19 +00:00
snipe 8f232421d2 Merge remote-tracking branch 'origin/develop' 2025-12-04 17:37:58 +00:00
snipe dbc688ad6e Set '#ffffff' as default 2025-12-04 17:37:44 +00:00
snipe 6217a721ac Merge remote-tracking branch 'origin/develop' 2025-12-04 15:11:38 +00:00
snipe c2ba937ac6 Merge pull request #18295 from grokability/#18288-allow-reference-editing-if-edit-profile-is-disabled
Fixed #18288: Allow users to edit display preferences even if profile editing is not enabled
2025-12-04 15:11:11 +00:00
snipe d860786221 Re-add button 2025-12-04 13:21:54 +00:00
snipe 621ce1777f Fixed #18288: Allow users to change preferences even if profile editing is not permitted 2025-12-04 13:21:04 +00:00
snipe 4f610ac1af Added tag color to importer 2025-12-04 11:07:59 +00:00
snipe 7341cd1712 Merge pull request #18294 from grokability/#18278-import-company-in-locations
Fixed #18278: Import companies into locations on initial import
2025-12-04 11:07:18 +00:00
snipe bf112b7b4b Fixed #18278: Import companies into locations on initial import 2025-12-04 10:59:45 +00:00
snipe ad9e0cc39a Merge remote-tracking branch 'origin/develop' 2025-12-04 10:50:09 +00:00
snipe 1439681113 Alert message link text 2025-12-04 10:34:58 +00:00
snipe 3b750541c9 Prod assets 2025-12-04 10:19:12 +00:00
snipe 79765201ac Merge remote-tracking branch 'origin/develop' 2025-12-04 10:18:37 +00:00
snipe 0086b9d848 mix 2025-12-04 10:17:17 +00:00
snipe c8ddb44783 Fixed button color 2025-12-04 10:16:44 +00:00
snipe d4829a4bac Fixed #18286 - :user in declined email 2025-12-04 10:16:35 +00:00
snipe 486f0c0035 Re-running assets for prod 2025-12-04 08:46:53 +00:00
snipe dc3a695ab0 Merge remote-tracking branch 'origin/develop'
# Conflicts:
#	config/version.php
#	public/css/build/app.css
#	public/css/build/app.css.map
#	public/css/build/overrides.css
#	public/css/build/overrides.css.map
#	public/css/dist/all.css
#	public/css/dist/skins/_all-skins.css
#	public/css/dist/skins/_all-skins.css.map
#	public/css/dist/skins/_all-skins.min.css
#	public/css/dist/skins/skin-black-dark.css
#	public/css/dist/skins/skin-black-dark.css.map
#	public/css/dist/skins/skin-black-dark.min.css
#	public/css/dist/skins/skin-black.css
#	public/css/dist/skins/skin-black.css.map
#	public/css/dist/skins/skin-black.min.css
#	public/css/dist/skins/skin-blue-dark.css
#	public/css/dist/skins/skin-blue-dark.css.map
#	public/css/dist/skins/skin-blue-dark.min.css
#	public/css/dist/skins/skin-blue.css
#	public/css/dist/skins/skin-blue.css.map
#	public/css/dist/skins/skin-blue.min.css
#	public/css/dist/skins/skin-contrast.css
#	public/css/dist/skins/skin-contrast.css.map
#	public/css/dist/skins/skin-contrast.min.css
#	public/css/dist/skins/skin-green-dark.css
#	public/css/dist/skins/skin-green-dark.css.map
#	public/css/dist/skins/skin-green-dark.min.css
#	public/css/dist/skins/skin-green.css
#	public/css/dist/skins/skin-green.css.map
#	public/css/dist/skins/skin-green.min.css
#	public/css/dist/skins/skin-orange-dark.css
#	public/css/dist/skins/skin-orange-dark.css.map
#	public/css/dist/skins/skin-orange-dark.min.css
#	public/css/dist/skins/skin-orange.css
#	public/css/dist/skins/skin-orange.css.map
#	public/css/dist/skins/skin-orange.min.css
#	public/css/dist/skins/skin-purple-dark.css
#	public/css/dist/skins/skin-purple-dark.css.map
#	public/css/dist/skins/skin-purple-dark.min.css
#	public/css/dist/skins/skin-purple.css
#	public/css/dist/skins/skin-purple.css.map
#	public/css/dist/skins/skin-purple.min.css
#	public/css/dist/skins/skin-red-dark.css
#	public/css/dist/skins/skin-red-dark.css.map
#	public/css/dist/skins/skin-red-dark.min.css
#	public/css/dist/skins/skin-red.css
#	public/css/dist/skins/skin-red.css.map
#	public/css/dist/skins/skin-red.min.css
#	public/css/dist/skins/skin-yellow-dark.css
#	public/css/dist/skins/skin-yellow-dark.css.map
#	public/css/dist/skins/skin-yellow-dark.min.css
#	public/css/dist/skins/skin-yellow.css
#	public/css/dist/skins/skin-yellow.css.map
#	public/css/dist/skins/skin-yellow.min.css
#	public/js/dist/all.js
#	public/js/dist/all.js.map
#	public/mix-manifest.json
2025-12-04 08:45:19 +00:00
akemidx e769239213 only user can change report sharing 2025-12-04 00:39:47 -05:00
akemidx 45923a74f6 only user can change report sharing 2025-12-04 00:34:30 -05:00
Marcus Moore 7bf7a87f8a Begin to display EULAs for all categories 2025-12-03 16:59:57 -08:00
Marcus Moore 8396e27a2c Revert "Avoid showing EULA"
This reverts commit 8c89eb6650.
2025-12-03 16:16:30 -08:00
Marcus Moore 5153c68b8b Remove old todos 2025-12-03 16:15:43 -08:00
snipe 3feee682b6 Fixed import view with light/dark 2025-12-03 21:38:57 +00:00
snipe 4ea5cb9538 Merge pull request #18284 from Godmartinz/fix-alert-threshold-bug
Fixes Low Inventory Alerts not sending when threshold is `null`
2025-12-03 21:32:29 +00:00
Godfrey M f6461a755a revert again 2025-12-03 13:22:46 -08:00
Godfrey M 39cf5ce66e revert some changes 2025-12-03 13:22:03 -08:00
Godfrey M c68d9892b5 fix threshold bug, include minimum to available 2025-12-03 13:20:01 -08:00
snipe 33b20b6268 Fixed sidemenu hover 2025-12-03 19:27:44 +00:00
snipe 280df20a0b Better default link colors for skin migration 2025-12-03 18:18:24 +00:00
snipe 7027cd80d4 Updated modal for light/dark 2025-12-03 18:18:14 +00:00
snipe bfbcfe7bae Updated text string 2025-12-03 17:36:48 +00:00
snipe e1f64b6d2b Modal title color fix 2025-12-03 17:36:39 +00:00
snipe 6944c438dd Inline tooltip improvements 2025-12-03 16:04:23 +00:00
snipe 49b7ff1192 Fixed email field color 2025-12-03 15:58:50 +00:00
snipe 662cdbaa0e Datepicker color fixes 2025-12-03 15:55:04 +00:00
snipe e912eb5ef8 Merge pull request #18279 from uberbrady/new_allowlist_restore_cleaner
Loosen regex allowlist for setting character sets
2025-12-03 13:31:01 +00:00
Brady Wetherington 5ab68d83a5 Loosen regex allowlist for setting character sets 2025-12-03 13:06:02 +00:00
snipe f7c432f7fd Bumped hash 2025-12-03 10:09:23 +00:00
snipe 592ccb6ebe Merge pull request #18244 from Godmartinz/receive-all-expired-licenses-on-report
adds #17422 [FD-49345] `--expired-licenses` command parameter to `snipeit:expiring-alerts`
2025-12-03 09:49:49 +00:00
snipe d22d70dd92 Merge pull request #18257 from iryadifarhan/fix/manager-view-not-displaying-subordinates-eulas-properly
Fixes Manager View not displaying subordinates EULAs properly in View Assets page
2025-12-03 09:49:35 +00:00
snipe 7ec5606ce4 Merge pull request #18247 from uberbrady/multi_create_fixes
Fixed #18160 - Multi-create fixes
2025-12-03 09:49:14 +00:00
snipe 476bf95edf Merge pull request #18272 from spencerrlongg/add-null-checks
Adds Null Checks
2025-12-03 09:48:43 +00:00
Marcus Moore 391495dd86 Remove some assertions 2025-12-02 17:41:22 -08:00
Marcus Moore 8c89eb6650 Avoid showing EULA 2025-12-02 17:37:21 -08:00
Marcus Moore 4167c6ea70 Add some translations 2025-12-02 17:36:05 -08:00
Marcus Moore ca3151ce29 Improve naming 2025-12-02 16:10:53 -08:00
akemidx cc20844eff share template bits 2025-12-02 18:34:13 -05:00
Marcus Moore d876e710e4 Be more specific in tests 2025-12-02 13:48:59 -08:00
Marcus Moore 5c1290425b Improve variable name 2025-12-02 13:28:59 -08:00
Marcus Moore 2043488c67 Cleanups 2025-12-02 12:31:04 -08:00
Marcus Moore e7e48c8f03 Cleanups 2025-12-02 12:30:16 -08:00
Marcus Moore dad650b804 Readability 2025-12-02 12:28:51 -08:00
Marcus Moore d0e73714c6 Implement test 2025-12-02 11:57:02 -08:00
Marcus Moore d8b95d3a20 Organization 2025-12-02 11:53:37 -08:00
Marcus Moore 559d8cc0db Implement test 2025-12-02 11:53:01 -08:00
Marcus Moore 7a804aa576 Implement test 2025-12-02 11:51:28 -08:00
snipe cdf036ed7b Merge pull request #18274 from spencerrlongg/check-that-email-exists-on-recipient
Check That Email Exists on Recipient in Checkout Acceptance
2025-12-02 19:35:28 +00:00
snipe 639a3b9295 Merge pull request #18273 from Godmartinz/fix-null-assignee-bug-in-checkoutable
Refactor `assignee` in Checkoutable to accept null
2025-12-02 19:31:22 +00:00
spencerrlongg e4f8c3bef7 add null check and check for email 2025-12-02 13:17:13 -06:00
Godfrey M 462945022c allow null for assignee in checkoutable 2025-12-02 11:05:07 -08:00
spencerrlongg aa57687df0 add null checks to license 2025-12-02 12:13:38 -06:00
snipe 3237a3b9de One more button fix 2025-12-02 16:44:31 +00:00
snipe ff30e109cc Small button fixes 2025-12-02 16:42:32 +00:00
snipe 2d291f843a Fixed create new on table buttons 2025-12-02 16:36:54 +00:00
snipe 7219fc1c3c Added style to border on colorpicker 2025-12-02 16:22:53 +00:00
snipe ed6bfa7810 Disable branding colopickers on demos 2025-12-02 16:16:33 +00:00
snipe ad15090c34 Nicer search highlight box 2025-12-02 15:58:34 +00:00
snipe 9d34bf4a19 Fixed table header colors 2025-12-02 15:54:18 +00:00
snipe 7c9b1a52af Swapped link colors 2025-12-02 15:39:32 +00:00
snipe dd297dca31 Merge pull request #18249 from grokability/proper-dark-toggle
Experiment: simpler light/dark toggle
2025-12-02 14:37:52 +00:00
snipe 1409d01078 Tweaked color 2025-12-02 14:19:53 +00:00
snipe c9a03cf9b7 Final color tweaks 2025-12-02 14:03:08 +00:00
snipe 6a99132e76 More tweaks 2025-12-02 13:29:12 +00:00
Marcus Moore 0bca66b671 Send email if asset has checkin_email set to true 2025-12-01 16:58:02 -08:00
Marcus Moore 24e5cf8121 Improve readability 2025-12-01 16:51:09 -08:00
Marcus Moore ee7c4ce0f3 Improve assertion 2025-12-01 16:47:23 -08:00
Marcus Moore 428b511687 Send if eula is set 2025-12-01 16:41:50 -08:00
Marcus Moore 49497996d5 Fix template 2025-12-01 16:41:39 -08:00
Marcus Moore bccd65e2fc Add failing test 2025-12-01 16:33:46 -08:00
Marcus Moore f2158843ce Avoid attempting to loop over null 2025-12-01 16:25:37 -08:00
Marcus Moore 87fc4a4f22 Scaffold scenarios 2025-12-01 16:01:34 -08:00
Marcus Moore 27291f9ee9 Add todo 2025-12-01 14:23:33 -08:00
Marcus Moore cba963110e Remove unused import 2025-12-01 14:22:06 -08:00
Marcus Moore aa014e3706 Improve wording 2025-12-01 14:19:54 -08:00
akemidx 58d577f67a shared/notshared marker 2025-12-01 16:48:39 -05:00
Marcus Moore cd3678841b Fix intro line to locations 2025-12-01 13:41:23 -08:00
Marcus Moore 425e0c33df Add tests for introduction line 2025-12-01 12:55:39 -08:00
Marcus Moore 2018407782 Avoid error by pre-checking if user has email address 2025-12-01 12:04:53 -08:00
snipe 2e269d2e63 Removed old skin less files 2025-11-29 10:42:10 +00:00
snipe 7820636c9f Nicer defaults 2025-11-29 10:41:58 +00:00
snipe db1b35ccf6 Fixed style 2025-11-28 19:20:41 +00:00
snipe fadfe0a782 Removed old skin references 2025-11-28 19:17:52 +00:00
snipe 255a2ecdd9 Sigh 2025-11-28 19:09:38 +00:00
snipe 97ffe33fc8 Check that a setting record exists 2025-11-28 19:07:46 +00:00
snipe 56d97a1f59 Updated map 2025-11-28 19:05:25 +00:00
snipe 28d5d24617 Migration to handle skins 2025-11-28 19:05:19 +00:00
snipe d97f6903d6 Save settings controller 2025-11-28 19:05:03 +00:00
snipe 3bf84d96d9 Update language 2025-11-28 19:04:49 +00:00
snipe 8df643a2ab Removed user skin option 2025-11-28 19:04:40 +00:00
snipe 2d001c4fa1 Added colorpickers for link colors 2025-11-28 19:04:20 +00:00
snipe cbd6b57445 Removed skin from user profile update 2025-11-28 19:04:00 +00:00
snipe dac684c08a Update demo settings 2025-11-28 19:03:48 +00:00
snipe 772c29791a Use css variable 2025-11-28 17:48:08 +00:00
snipe 89a232ae14 Merge pull request #18266 from Valinwolf/develop
Added endpoint & use_path_style_endpoint configs for public/private S3
2025-11-28 17:39:23 +00:00
snipe 4e4b8ddb77 And more updates 2025-11-28 17:33:30 +00:00
Patrick Thomas 6eaefa0bdd Added endpoint & use_path_style_endpoint configs for public/private S3 2025-11-28 17:29:02 +00:00
snipe 20a75bbbb7 More styles 2025-11-28 15:54:24 +00:00
snipe 5cc261dd3c Smaller LDAP screen 2025-11-28 15:50:37 +00:00
snipe 6d958b6f65 Added fa-fw to arrow class 2025-11-28 15:50:25 +00:00
snipe 8ddac4d7c7 More select2 styling :( 2025-11-28 15:16:22 +00:00
snipe a321ad9dbe Handle select2 stuff 2025-11-28 14:13:19 +00:00
snipe 4dff66253c Added contrast-color to dynamically pick white/black for topnav 2025-11-27 16:15:35 +00:00
snipe 9a1e9f90bc Better preview for header color, updated text 2025-11-27 15:56:06 +00:00
snipe c54724919c Show header color preview 2025-11-27 15:29:24 +00:00
snipe 139d1cdcf8 Added a few more classes 2025-11-27 14:48:28 +00:00
snipe 490c50a182 Added fa-fw to action buttons 2025-11-27 14:48:16 +00:00
snipe af1e496eab Added correct box class 2025-11-27 13:30:11 +00:00
snipe efea043549 Added dark/light text 2025-11-27 13:29:59 +00:00
snipe d4ee91f013 Removed a few classes 2025-11-27 13:29:50 +00:00
iryadifarhan d4561581ad Apply fix around view-assets to pass request parameter and profile controller to address request parameter 2025-11-27 13:42:47 +07:00
snipe a17f167952 Fix button overrides 2025-11-26 15:41:38 +00:00
snipe 5beb068cde More updates for dark and light switches 2025-11-26 15:35:43 +00:00
snipe a272bdc796 Merge pull request #18251 from uberbrady/improve_component_asset_counts
Optimize queries for Components listing
2025-11-26 14:40:14 +00:00
snipe 30a43089a0 More variablization 2025-11-26 13:50:39 +00:00
Brady Wetherington 416b32cbc8 Optimize queries for Components listing 2025-11-26 12:36:44 +00:00
iryadifarhan a3a49e47b7 Apply toDateString so that the it equally compare date only, evades including time/hour comparing 2025-11-26 13:21:15 +07:00
snipe d203cece0e Removed indicidual skins 2025-11-26 04:08:31 +00:00
snipe 9f6f0f04c7 Few more tweaks 2025-11-26 04:06:20 +00:00
iryadifarhan a4729a7de8 Fix implemented by using existing function from Depreciable trait, hence addressing the floor value 2025-11-26 10:17:21 +07:00
snipe a974c6d4cd Moved icon-med 2025-11-26 02:56:05 +00:00
snipe 34612acdcf Experiment: light/dark simplifcation 2025-11-26 02:49:40 +00:00
snipe 9e23117f9c Merge remote-tracking branch 'origin/develop' 2025-11-26 00:35:26 +00:00
snipe b3996f1970 In the sea, @uberbrady! (fixed missing semicolon) 2025-11-26 00:35:16 +00:00
snipe e143017432 Tinkering with CSS/JS dark more 2025-11-26 00:34:46 +00:00
Brady Wetherington c6c0a14ee0 Whoops, used PHP's equal signs instead of MySQL's :/ 2025-11-25 20:23:15 +00:00
Brady Wetherington 9b8768dbdd Tighten everything up, remove logging, fix last bits of functionality 2025-11-25 19:34:10 +00:00
snipe a3bfcc962d Merge remote-tracking branch 'origin/develop' 2025-11-25 18:50:23 +00:00
snipe ca4ed605a8 Merge pull request #18246 from Godmartinz/resize-label-fields-conditionally-L6009_A
Fixes [FD-52064] Avery `L6009_A` & `L4736_A` label field overflow with scaling
2025-11-25 18:37:06 +00:00
Godfrey M d3e6d7442f typo bonanza 2025-11-25 10:30:56 -08:00
Godfrey M b558bc5334 change variable" 2025-11-25 10:30:06 -08:00
Godfrey M 204d7b5be6 added scaling to L4736_A 2025-11-25 10:23:08 -08:00
Godfrey M 7dccfec332 adds notes 2025-11-25 10:12:27 -08:00
snipe 0b694bfd0b Merge remote-tracking branch 'origin/develop' 2025-11-25 18:02:23 +00:00
snipe dfb59d8a55 Added link to rudder2snipe repo 2025-11-25 18:01:29 +00:00
Brady Wetherington 3cd191210c Merge branch 'develop' into multi_create_fixes 2025-11-25 13:58:56 +00:00
snipe 56a44ad421 Merge remote-tracking branch 'origin/develop' 2025-11-25 13:38:54 +00:00
snipe a12ee3c0da Merge pull request #18245 from uberbrady/redirect_upgrader
Add new 'git remote' management to change Snipe-IT URLs
2025-11-25 13:38:31 +00:00
Brady Wetherington a657c479be Add new 'git remote' management to change Snipe-IT URL's 2025-11-25 13:17:56 +00:00
Godfrey M bb7dabc73b adds expired-licenses command parameter 2025-11-24 11:41:50 -08:00
Godfrey M ab82c5fd88 resizes label field box to size if needed 2025-11-24 11:04:23 -08:00
snipe 78cfb19f69 Merge remote-tracking branch 'origin/develop' 2025-11-24 17:40:26 +00:00
snipe f2334082ee Added tag color to location query 2025-11-24 17:40:13 +00:00
snipe 58a47cb52b Merge remote-tracking branch 'origin/develop'
# Conflicts:
#	config/version.php
2025-11-24 12:32:17 +00:00
snipe c7cb4674f5 Bumped version 2025-11-24 12:31:50 +00:00
snipe 523df21d83 Merge remote-tracking branch 'origin/develop' 2025-11-24 12:30:22 +00:00
snipe 82314076a9 Updated translations 2025-11-24 12:30:07 +00:00
snipe d04bf2e8f2 Merge remote-tracking branch 'origin/develop' 2025-11-24 11:37:44 +00:00
snipe a1c67b5154 Fixed user details toggle 2025-11-24 11:37:14 +00:00
snipe 3e343fe8b7 Merge pull request #18236 from grokability/dependabot/github_actions/develop/actions/checkout-6
Bump actions/checkout from 5 to 6
2025-11-24 08:33:46 +00:00
dependabot[bot] e288c942ee Bump actions/checkout from 5 to 6
Bumps [actions/checkout](https://github.com/actions/checkout) from 5 to 6.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v5...v6)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-11-24 08:04:19 +00:00
snipe 7a1ccb0d53 Nicer query 2025-11-23 14:09:55 +00:00
snipe 89656c7e65 Merge remote-tracking branch 'origin/develop' 2025-11-23 14:05:39 +00:00
snipe 7f76198139 Fixed RB-20501 - correctly return error response when license+seat don’t match
TypeError: App\Http\Transformers\LicenseSeatsTransformer::transformLicenseSeat(): Argument #1 ($seat) must be of type App\Models\LicenseSeat, bool given, called in /snipe-it/app/Http/Controllers/Api/LicenseSeatsController.php on line 92
2025-11-23 14:05:24 +00:00
snipe 5ff813f9b7 Merge pull request #18233 from grokability/develop
Merging from dev
2025-11-22 14:24:36 +00:00
snipe 69994e0c11 Merge pull request #18232 from grokability/check-for-valid-json-on-filter
Added filter form request to validate JSON
2025-11-22 14:22:33 +00:00
snipe aa959fbe92 Added filter form request to validate JSON 2025-11-22 14:03:58 +00:00
snipe 948b7cda15 Merge remote-tracking branch 'origin/develop' 2025-11-22 12:04:28 +00:00
snipe 644ef040d0 Merge pull request #18226 from Godmartinz/audit-notification-rb-19608
Fixes RB-19608 adds safe guards, adds Audit notification for google workspace, adds tests
2025-11-22 11:41:57 +00:00
snipe 33839d7244 Re-added the horizontal class 2025-11-22 11:14:59 +00:00
Godfrey M 48270cb9b4 url trim 2025-11-21 10:11:28 -08:00
Godfrey M cd42760b68 notes 2025-11-20 14:25:13 -08:00
Godfrey M 1116da389e add google chat to audit notification test 2025-11-20 14:24:03 -08:00
Godfrey M 24d7ae4a2f added google chat to audit notifications" 2025-11-20 14:22:08 -08:00
Godfrey M e598ef6e05 adds tests, webhook enable settings 2025-11-20 13:51:14 -08:00
snipe 6601e73069 Merge remote-tracking branch 'origin/develop' 2025-11-20 20:15:44 +00:00
snipe 7f2a80552b Fixed form layout for SAML 2025-11-20 20:15:34 +00:00
Godfrey M eceeb4aa3b return if there is no item for the audit notification 2025-11-20 10:56:43 -08:00
snipe b5c7f374f3 Merge remote-tracking branch 'origin/develop' 2025-11-20 13:44:19 +00:00
snipe 9d08e2d297 Clearer language 2025-11-20 13:44:09 +00:00
snipe f2303ae2dc Merge remote-tracking branch 'origin/develop' 2025-11-20 13:28:00 +00:00
snipe 4d44fd47c3 Merge pull request #18217 from Godmartinz/unaccepted-row-null-fix
Fixes FD-52005 Adds null safe operators to unacceptable items report
2025-11-20 13:27:24 +00:00
snipe 88635cb6c3 Merge pull request #18223 from grokability/#18114-fixed-declined-notification-added-x-header
Fixed #18114 - include declined item name, added app headers
2025-11-20 13:27:01 +00:00
snipe 1687fcc035 Small subject tweaks 2025-11-20 13:23:17 +00:00
snipe 39e7937458 Fixed #18114 - include declined item name, added app headers 2025-11-20 12:58:53 +00:00
Marcus Moore 54f065f42c Improve test 2025-11-19 17:11:39 -08:00
Marcus Moore 333ebb88b9 Enable sending to manager 2025-11-19 17:08:00 -08:00
Marcus Moore 53ff367473 Add failing tests 2025-11-19 16:31:48 -08:00
Marcus Moore 33a7de9448 Add custom fields to email 2025-11-19 13:31:30 -08:00
Godfrey M 60ff2970f0 safeguard null rows by filtering rows in query 2025-11-19 11:35:24 -08:00
Godfrey M 212cd026a3 add null safe operators to company and csv plain values 2025-11-18 12:36:07 -08:00
snipe cf47f8fea9 Merge pull request #18216 from Godmartinz/fix-license-patch-to-allow-update-of-other-fields
Fixed #18024 License Seat update/patch method
2025-11-18 20:29:18 +00:00
akemidx c797472bcc migration, and front end 2025-11-18 15:03:28 -05:00
Godfrey M 4b45ffd841 updating fields of checkout now works 2025-11-18 11:35:26 -08:00
snipe 69a57b77c9 Merge remote-tracking branch 'origin/develop' 2025-11-18 13:13:48 +00:00
snipe 5daba6034d Merge pull request #18213 from grokability/#18202-copy-to-clipboard-spaces
Fixed #18202 - copy to clipboard adding spaces in FF
2025-11-18 13:13:29 +00:00
snipe 4e5c19e932 Fixed #18202 - copy to clipboard adding spaces in FF 2025-11-18 13:11:40 +00:00
snipe 5eb73baf5e Removed duplicate formatter 2025-11-18 12:54:21 +00:00
snipe d819f31bdd Merge remote-tracking branch 'origin/develop' 2025-11-18 12:01:01 +00:00
snipe a97c453706 Small fixes for user profiles 2025-11-18 11:59:54 +00:00
snipe 5ee955a713 Merge remote-tracking branch 'origin/develop' 2025-11-18 11:40:23 +00:00
snipe 57224f7304 Fixed #18209 - translate asset filters 2025-11-18 11:40:15 +00:00
snipe 270d145466 Merge remote-tracking branch 'origin/develop' 2025-11-18 11:15:31 +00:00
snipe c564ee6093 Fixed #18211 - limit regex field to 191 characters 2025-11-18 11:15:15 +00:00
snipe caaa9ab23e Merge pull request #18122 from chruoss/master
Renamed L6009 -> L4736 and added correct L6009
2025-11-17 21:40:08 +00:00
snipe b6d2c6d28c Merge pull request #18208 from marcusmoore/fixes/null-array-filter
Fixed potential exception while filtering in users index endpoint
2025-11-17 21:39:08 +00:00
Marcus Moore c36c8968d3 Avoid passing null to array_filter in user controller 2025-11-17 10:26:29 -08:00
snipe b019af1851 Merge remote-tracking branch 'origin/develop' 2025-11-17 17:50:30 +00:00
snipe bcd32da2bc Remove loading user count since we don’t use it for depts 2025-11-17 17:34:43 +00:00
snipe 6f97a40372 Merge remote-tracking branch 'origin/develop'
# Conflicts:
#	public/css/build/app.css
#	public/css/build/app.css.map
#	public/css/build/overrides.css
#	public/css/build/overrides.css.map
#	public/css/dist/all.css
#	public/js/dist/all.js
#	public/js/dist/all.js.map
#	public/mix-manifest.json
2025-11-17 13:37:16 +00:00
snipe c56c7ddd03 Merge pull request #18201 from grokability/#18185-added-tag-color-to-companies
Added #18185 added tag color to companies
2025-11-17 13:33:17 +00:00
snipe 9a0dd604c9 Small layout tweaks 2025-11-17 13:21:01 +00:00
snipe a1dec176a1 Added mobile 2025-11-17 13:09:13 +00:00
snipe 67032d068d Removed space 2025-11-17 13:09:08 +00:00
snipe 401c83945d Updated gate check on presenters 2025-11-17 13:07:28 +00:00
snipe ed6d020edb Fixed permission name for locations 2025-11-17 12:31:18 +00:00
snipe 8eb5600b1e Fixed manufacturer link 2025-11-17 12:19:27 +00:00
snipe 9c4cd69106 Updated checkout blades 2025-11-17 12:15:38 +00:00
snipe 64cbe0c960 Use dept presenter 2025-11-17 12:15:25 +00:00
snipe be70b217d9 Updated presenters 2025-11-17 12:11:38 +00:00
snipe b4f5260dda Updated controllers to use tag_color 2025-11-17 11:36:11 +00:00
snipe 83e446f99c Updated formatters to use tag_color if given 2025-11-17 11:18:38 +00:00
snipe 767139cf0b Updated select2 to use tag_color if available 2025-11-17 11:18:21 +00:00
snipe e3ac60111f Added tag_color to factories 2025-11-17 11:18:02 +00:00
snipe c694c11724 Added presenter reference 2025-11-15 14:58:02 +00:00
snipe b50765a151 Added more to the views 2025-11-15 14:50:51 +00:00
snipe 590f77bdb4 Updated controllers and presenters 2025-11-14 17:58:27 +00:00
snipe 09575e5312 Added tag color to transformer 2025-11-14 15:58:07 +00:00
snipe 1693825dd0 Added translations 2025-11-14 15:57:57 +00:00
snipe 5a89056112 Added migration 2025-11-14 15:57:47 +00:00
snipe 2ee51bb282 Added tag color to transformer 2025-11-14 15:57:39 +00:00
snipe ea7cffc1a3 Made tag_color fillable 2025-11-14 15:57:27 +00:00
snipe c20d1b82ae Added tag color to controllers 2025-11-14 15:57:18 +00:00
snipe 607781382f Merge remote-tracking branch 'origin/develop' 2025-11-14 14:10:05 +00:00
snipe 4e8c1e853b Fixed markdown in upcoming audits email 2025-11-14 14:09:53 +00:00
snipe 2c6869501e Merge remote-tracking branch 'origin/develop' 2025-11-13 16:46:32 +00:00
snipe 4509e1d1dc Merge pull request #18195 from grokability/#18189-day-of-week
Fixed #18189 - added option to pick the day the week starts on
2025-11-13 16:46:15 +00:00
snipe 6b9d4941be Language tweaks 2025-11-13 16:35:40 +00:00
snipe 308cd6b91d Fixed #18189 - added option to pick the day the week starts on 2025-11-13 16:33:08 +00:00
snipe 23b54de8bd Merge remote-tracking branch 'origin/develop' 2025-11-13 15:37:42 +00:00
snipe bd742aec9c Merge pull request #18192 from Godmartinz/fix-requestable-asset-model-query
Fixes FD51910 requestable asset model available quantity count
2025-11-13 15:37:24 +00:00
snipe d2ab3071a6 Merge pull request #18193 from ubc-cpsc/bugfix/CVE-2025-64500
Fixes CVE-2025-64500: Incorrect parsing of PATH_INFO can lead to limited authorization
2025-11-13 09:52:50 +00:00
Joël Pittet 1dd4c161f0 Fixes CVE-2025-64500 2025-11-12 18:09:37 -08:00
Godfrey M 5e48dd45b2 remove unnecessary code 2025-11-12 16:27:04 -08:00
Godfrey M 601d6e7377 fixes requestable models query 2025-11-12 16:25:08 -08:00
snipe 3934b40282 Merge remote-tracking branch 'origin/develop' 2025-11-12 20:59:15 +00:00
snipe d43be271e6 Small tweaks to user group listings 2025-11-12 20:59:06 +00:00
snipe d3c9963051 Merge remote-tracking branch 'origin/develop' 2025-11-12 20:25:00 +00:00
snipe 92a3bdf4e9 Merge pull request #18191 from grokability/limit-adding-users-to-group-if-over-limit
Set a limit on number of users for group user loading
2025-11-12 20:24:24 +00:00
snipe fa2aafe41f Set a limit on number of users for group user loading 2025-11-12 20:19:52 +00:00
snipe bc5da2532c Merge remote-tracking branch 'origin/develop' 2025-11-12 16:02:01 +00:00
snipe a7be1acbd8 Merge pull request #18190 from grokability/improved-checkin-reminders
Improved overdue checkin alert
2025-11-12 16:01:32 +00:00
snipe fbe2ae03ff Use due_checkin_days setting instead of audit warning days 2025-11-12 15:52:16 +00:00
snipe d1a492f953 Improved overdue checkin alert 2025-11-12 15:38:47 +00:00
snipe ac6ea8bdcc Merge remote-tracking branch 'origin/develop' 2025-11-11 18:43:54 +00:00
snipe 352807c2d7 Fixed RB-20498 - Check that logo file exists on acceptance 2025-11-11 18:43:39 +00:00
Brady Wetherington 70d79c1890 Merge branch 'develop' into multi_create_fixes 2025-11-11 18:20:49 +00:00
Brady Wetherington fb1fde26ce Use a FormRequest to better handle multiple-asset-creation by GUI 2025-11-11 18:00:22 +00:00
snipe dc4cf8496a Merge remote-tracking branch 'origin/develop' 2025-11-11 14:01:54 +00:00
snipe 3aa046bfa7 Include trashed in other acceptance tasks 2025-11-11 14:00:48 +00:00
snipe ed79d21e1b Merge remote-tracking branch 'origin/develop' 2025-11-11 13:53:55 +00:00
snipe 9454ff677b Get deleted objects in unaccepted asset report 2025-11-11 13:53:43 +00:00
snipe 743d340bca Merge remote-tracking branch 'origin/develop' 2025-11-11 13:18:18 +00:00
snipe a5c7b8f609 Small unaccepted items report fixes 2025-11-11 13:17:56 +00:00
snipe 3d1398ab97 Merge remote-tracking branch 'origin/develop' 2025-11-11 12:29:44 +00:00
snipe 9365d1adc6 Merge pull request #18164 from Godmartinz/fix-accessories-redirect-previous-page
Fixes #18138 redirect to Previous Page from accessories edit screen
2025-11-11 12:29:23 +00:00
snipe ddd2a96ac5 Clearer message on no inventory to report 2025-11-11 11:52:05 +00:00
Godfrey M 6faf171007 update asset_deployable translation 2025-11-10 16:58:42 -08:00
snipe 7a680ce4ff Merge remote-tracking branch 'origin/develop' 2025-11-10 21:31:28 +00:00
snipe bf8ff51234 Make suppliers notes nullable by default 2025-11-10 21:31:14 +00:00
snipe 2ac4456f4e Merge remote-tracking branch 'origin/develop'
# Conflicts:
#	config/version.php
2025-11-10 20:58:15 +00:00
snipe 7891f52bd4 Merge pull request #18177 from grokability/add-files-to-suppliers
Fixed #12451: Add file upload support to suppliers, changed notes field to text (from varchar)
2025-11-10 20:57:21 +00:00
snipe baa4a8a461 Migration to change notes on suppliers to text from varchar 2025-11-10 20:53:21 +00:00
snipe 34daffcdf4 Added supplier file uploads 2025-11-10 20:47:45 +00:00
snipe 21baea27a8 Merge pull request #18141 from uberbrady/actiontype_enum_redux
Actiontype enum redux
2025-11-10 18:55:01 +00:00
snipe e1d3714445 Add @MarvelousAnything as a contributor 2025-11-10 14:15:10 +00:00
snipe 8b7e0a0d78 Add @mohammad-ahmadi1 as a contributor 2025-11-10 14:15:01 +00:00
snipe a1cc427c9c Add @smarsching as a contributor 2025-11-10 14:14:51 +00:00
snipe 391aa30da2 Bumped version 2025-11-10 13:49:26 +00:00
snipe 5dc675040d Bumped version 2025-11-10 13:48:59 +00:00
snipe 1258eb6533 Merge pull request #17913 from Godmartinz/add_types_to_unaccepted_asset_report
Fixed #15664 - Adds Accessories, Components, Consumables, and Licenses to Unaccepted Assets report
2025-11-10 12:24:13 +00:00
snipe f92f76b48a Merge remote-tracking branch 'origin/develop' 2025-11-07 13:42:04 +00:00
snipe 83abfc9ca6 Updated language files 2025-11-07 13:41:46 +00:00
snipe 61b6d4dc47 Merge remote-tracking branch 'origin/develop'
# Conflicts:
#	public/css/dist/skins/_all-skins.css
#	public/css/dist/skins/_all-skins.css.map
#	public/css/dist/skins/_all-skins.min.css
#	public/css/dist/skins/skin-black-dark.css
#	public/css/dist/skins/skin-black-dark.css.map
#	public/css/dist/skins/skin-black-dark.min.css
#	public/css/dist/skins/skin-blue-dark.css
#	public/css/dist/skins/skin-blue-dark.css.map
#	public/css/dist/skins/skin-blue-dark.min.css
#	public/css/dist/skins/skin-green-dark.css
#	public/css/dist/skins/skin-green-dark.css.map
#	public/css/dist/skins/skin-green-dark.min.css
#	public/css/dist/skins/skin-orange-dark.css
#	public/css/dist/skins/skin-orange-dark.css.map
#	public/css/dist/skins/skin-orange-dark.min.css
#	public/css/dist/skins/skin-purple-dark.css
#	public/css/dist/skins/skin-purple-dark.css.map
#	public/css/dist/skins/skin-purple-dark.min.css
#	public/css/dist/skins/skin-red-dark.css
#	public/css/dist/skins/skin-red-dark.css.map
#	public/css/dist/skins/skin-red-dark.min.css
#	public/css/dist/skins/skin-yellow-dark.css
#	public/css/dist/skins/skin-yellow-dark.css.map
#	public/css/dist/skins/skin-yellow-dark.min.css
#	public/js/dist/all.js.map
#	public/mix-manifest.json
2025-11-07 13:26:23 +00:00
snipe b42d6677cc Updated assets 2025-11-07 13:25:45 +00:00
snipe e8c644a600 Merge pull request #18165 from Godmartinz/border-color-create-new-button-fix
Fixes #18140 Changes border color of create New in Dark modes
2025-11-07 13:21:52 +00:00
snipe aa041e39eb Merge remote-tracking branch 'origin/develop'
# Conflicts:
#	public/js/dist/all.js
#	public/js/dist/all.js.map
#	public/mix-manifest.json
2025-11-06 21:12:42 +00:00
snipe 9f6a73b290 Merge pull request #18170 from grokability/fix-for-groups
Fixed #18157 - only partial information stored on group save if lower `max_input_vars` and/or `max_multipart_body_parts`
2025-11-06 21:09:42 +00:00
snipe 4d38bd1c62 Renamed variable 2025-11-06 21:07:52 +00:00
snipe 138262114d Added enctype back in 2025-11-06 21:04:55 +00:00
snipe 4073c9e638 Updated ordering 2025-11-06 21:01:20 +00:00
snipe f1b4877a98 A few small tweaks for new groups 2025-11-06 20:36:51 +00:00
snipe c39c92d0d7 Mash the ids into a string, fixed disclosure arrows 2025-11-06 20:12:25 +00:00
snipe 90fc48d959 Shim workaround to avoid max_input_vars and max_multipart_body_parts limits
max_input_vars = 2000
max_multipart_body_parts = 2048
2025-11-06 18:17:40 +00:00
Godfrey M 7f10a53105 dark blue 2025-11-05 12:47:10 -08:00
Godfrey M 7ae1b7a765 change border-color of create new 2025-11-05 12:40:29 -08:00
Godfrey M 22a43a0463 adds redirect option fix to accessories update method 2025-11-05 12:19:18 -08:00
Godfrey M 9348204987 remove spacing adjustment 2025-11-05 11:22:11 -08:00
Godfrey M 776c7caaa5 get warning/success status check to display 2025-11-05 11:19:05 -08:00
Godfrey M 2216b83ca7 get warning/success status check to display 2025-11-05 11:16:35 -08:00
snipe dea399398a Merge pull request #18161 from Godmartinz/TZE_24mm_E_adjustment
FD-50838: Fixes 24mm_E label sizing
2025-11-05 18:50:42 +00:00
Godfrey M 7434dd9458 final adjustments to 24mm_E label 2025-11-05 09:32:21 -08:00
snipe 723abca34a Merge remote-tracking branch 'origin/develop' 2025-11-05 15:28:40 +00:00
snipe 88e532dbc4 Fixed #18157 - reports permission glitch 2025-11-05 15:24:15 +00:00
snipe 32b28327e9 Merge remote-tracking branch 'origin/develop' 2025-11-04 21:42:05 +00:00
snipe c5ad451c39 Merge pull request #18156 from grokability/#18119-fix-double-helpering-on-dates-for-asset-acceptance
Fixed #18119 - double formatting for acceptance/decline date
2025-11-04 21:40:58 +00:00
snipe 44bfceeb0f Fixed #18119 - double formatting for acceptance/decline date 2025-11-04 21:36:27 +00:00
snipe c30131275f Merge remote-tracking branch 'origin/develop' 2025-11-04 21:23:14 +00:00
snipe 37eb63837b Merge pull request #18155 from grokability/#18021-fix-patch-api-with-unique-serial
Override unique_undeleted in the form request
2025-11-04 21:23:00 +00:00
snipe 4ada47e3b0 Use new setting variable since we already have it 2025-11-04 21:12:49 +00:00
snipe e5c55c9ab3 Fixed typo in the comment 2025-11-04 21:11:54 +00:00
snipe 547b3df7b4 Added more commentary on why we’re intefering with the request 2025-11-04 21:08:48 +00:00
snipe 4100f2600c Override unique_undeleted in the form request 2025-11-04 20:43:31 +00:00
snipe 56218dfcb2 Merge remote-tracking branch 'origin/develop' 2025-11-04 19:39:52 +00:00
snipe a9574e8fd6 Fixed #18133 - make the disabled toggle JS so it’s clearer 2025-11-04 19:39:35 +00:00
snipe 0d2a75db0a Merge remote-tracking branch 'origin/develop' 2025-11-04 19:04:25 +00:00
snipe c6269d6bbc Merge pull request #18151 from MarvelousAnything/fixes/test_webhook_content_type
Fix Content-Type Header not being set correctly for testWebhook
2025-11-04 19:03:53 +00:00
snipe eb9d066844 Merge remote-tracking branch 'origin/develop' 2025-11-04 18:56:15 +00:00
snipe c1204a5301 Merge pull request #18152 from grokability/#18020-rework-pr
Re-apply #18020, fixed #15107 (mostly) - added prefix and more options to 2D barcodes
2025-11-04 18:55:54 +00:00
snipe cc5ac65909 Re-apply #18020, fixed #15107 (mostly) - added prefix and more options to label 2D tags 2025-11-04 18:43:35 +00:00
Owen Voskuhl Hayes 9ddc48e3d7 fix the headers field for Guzzle request 2025-11-04 12:03:21 -05:00
snipe 029f3030a7 Merge remote-tracking branch 'origin/develop' 2025-11-04 16:06:35 +00:00
snipe 4a39d7c67a Use transformer for dept update responses 2025-11-04 16:06:19 +00:00
snipe b7a6706591 Merge pull request #18150 from grokability/#18148-dept-api-request-user-count
Fixed #18148 and #17451 - return int for user_count, fixed validation
2025-11-04 16:05:42 +00:00
snipe ddb031f091 Fixed #18148 and #17451 - return int for user_count, fixed validation 2025-11-04 15:56:23 +00:00
snipe e906d25776 Merge pull request #16973 from spencerrlongg/bug/sc-29245
Adds Form Request for Creating Departments
2025-11-04 15:09:38 +00:00
Brady Wetherington 27d7449459 Fix comment to properly reflext the current state of the database 2025-11-04 14:04:37 +00:00
snipe 8c59a8d405 Merged clipboard PR and generated prod assets 2025-11-03 17:39:41 +00:00
snipe 5d8905c997 Merge pull request #18143 from grokability/#18101-make-copy-to-clipboard-more-consistent
Fixed #18101: Make copy to clipboard alignment more consistent
2025-11-03 17:36:54 +00:00
snipe 517f4ce121 Fixed #18101: Make copy to clipboard alignment more consistent 2025-11-03 17:29:39 +00:00
snipe 6809bbd3d5 Merge pull request #18142 from grokability/#18136-copy-asset-name
Fixed #18136 - adds copy to clipbpard to asset name
2025-11-03 15:48:59 +00:00
snipe ab555d05e1 Fixed #18136 - adds copy to clipbpard to asset name 2025-11-03 15:47:32 +00:00
Brady Wetherington f7bc538fdf Intorduce ActionType enum and ensure all logactions are using it 2025-11-03 15:39:31 +00:00
Brady Wetherington 2de66ad5db Merge branch 'fix_incorrect_action_types' into actiontype_enum_redux 2025-11-03 15:31:14 +00:00
snipe 30e16b6213 Added int 2025-11-03 14:10:36 +00:00
snipe 92b50ca7ae Addresses #17994, #16925 2025-11-03 14:10:27 +00:00
snipe 9ee36df979 Merge pull request #18139 from grokability/#18082-add-company-to-seat-view
Fixed #18082: Added user company to checked out licenses
2025-11-03 12:51:29 +00:00
snipe 46d1c14e1a Added user company to checked out licenses 2025-11-03 12:45:33 +00:00
snipe 61895011fb Merge pull request #18131 from Godmartinz/fix-inventory-alert-notification-misfire
Adds a null check for items and threshold in inventory alert notification
2025-10-30 20:11:24 +00:00
Godfrey M 32d43034bd add a null check for items and threshold in inventory alert notification 2025-10-30 10:47:17 -07:00
snipe dfc6cdc127 Merge pull request #18128 from marcusmoore/fixes/17738-category-edit-form-fix
Fixed #17738 - accurately represent checkbox on category edit screen
2025-10-30 16:43:17 +00:00
snipe 16e93f9e18 Merge remote-tracking branch 'origin/master' into develop 2025-10-30 14:03:23 +00:00
snipe 7395b1a4eb Track permission changes 2025-10-30 13:40:24 +00:00
snipe fa98557225 Check that the permissions are really an array
This accounts for weird data in the permissions column
2025-10-30 13:34:50 +00:00
Marcus Moore 894606b62e Remove old tests 2025-10-29 13:16:03 -07:00
Marcus Moore f0a6a0026a Improve phrasing 2025-10-29 13:03:37 -07:00
Marcus Moore 070e0c93be Improve phrasing 2025-10-29 12:46:26 -07:00
Marcus Moore 2b27b733e5 Improve wording 2025-10-29 12:45:45 -07:00
Marcus Moore 0355c2b642 Dynamically adjust checkbox wording 2025-10-29 12:44:34 -07:00
Marcus Moore 3bad19fb56 Improve translation key name 2025-10-29 12:40:39 -07:00
Marcus Moore 0f84d51a48 Improve property name 2025-10-29 12:37:17 -07:00
Marcus Moore 2e8572d9c5 Use v3 syntax for computed properties 2025-10-29 12:35:30 -07:00
Marcus Moore df53d5d966 Skip computing sendCheckInEmail 2025-10-29 12:32:01 -07:00
Marcus Moore 23838959ca Never disable email checkbox 2025-10-29 12:27:12 -07:00
snipe 6dbb836a01 Merge pull request #18125 from grokability/form-row-again
Added form row component
2025-10-29 16:33:15 +00:00
snipe 3426afe5a8 Account for input styles 2025-10-29 16:15:22 +00:00
snipe 4bbf923eb6 Smaller default row for textarea 2025-10-29 16:11:56 +00:00
snipe e2c3480194 Apply form rows to manufacturers 2025-10-29 16:11:47 +00:00
snipe 73159076f6 Better handle input groups in js validator 2025-10-29 16:11:37 +00:00
snipe 90d040573d Added regular link icon 2025-10-29 16:07:16 +00:00
chruoss 6904ad02a2 Renamed L6009.php -> L4736.php
Renamed L6009_A.php -> L4736_A.php
Added correct L6009.php
Added correct L6009_A.php
2025-10-29 15:13:12 +01:00
snipe 155481a442 Merge pull request #18120 from grokability/small-form-fixes-settings
Fixed form label alignments in settings section
2025-10-29 11:16:59 +00:00
snipe 2f31bfc5fe Fixed some HTML labels in settings 2025-10-29 11:13:07 +00:00
snipe 8d0c88dc74 Merge pull request #18116 from akemidx/auditwarningthreshold
Fixed #17329 Audit Warning Threshold could be negative
2025-10-28 20:44:58 +00:00
snipe 07256fd833 Merge pull request #18044 from mohammad-ahmadi1/ISSUE-17004-fix-db-dump-ssl-issue
fix: update mysqldump options to use --ssl-mode=DISABLED for modern versions
2025-10-28 20:37:08 +00:00
snipe 776cd43a58 Change text string for item (versus asset) 2025-10-28 20:36:05 +00:00
akemidx acb5309aab min = 0 2025-10-28 16:32:21 -04:00
snipe c68f81db3c Merge pull request #18113 from Godmartinz/customfieldvalue-in-importer-fix
Adds #17433  `is_null` check to import handler for custom fields
2025-10-28 20:27:22 +00:00
snipe ac8e341b37 Merge pull request #18115 from marcusmoore/fixes/rb-20449-remove-admin-from-acceptance-email
Fixed #18112 - fix consumable and license acceptances
2025-10-28 20:26:59 +00:00
snipe 36122b3966 Added BACKUP_TIME_LIMIT to env example 2025-10-28 20:26:23 +00:00
akemidx 79bcf472f0 greater than or equal to zero 2025-10-28 16:13:33 -04:00
Marcus Moore 55d86da846 Remove references to administrator in acceptance notification 2025-10-28 13:07:00 -07:00
Godfrey M e4f8c1ba3f fix custom field value conditional check 2025-10-28 12:24:35 -07:00
Godfrey M c36236b7dc add is_null acheck to import hanlder for custom fields 2025-10-28 11:37:38 -07:00
snipe 63994333d0 Merge pull request #18111 from grokability/#16914-better-ldap-sync-phrasing
Fixed #16914: better ldap sync phrasing
2025-10-28 15:51:10 +00:00
snipe da4c7d8934 One more tweak 2025-10-28 15:47:56 +00:00
snipe 186721eca0 Added breadcrumbs 2025-10-28 15:42:59 +00:00
snipe f53d939c86 Better explanation for location sync, nicer look 2025-10-28 15:42:53 +00:00
snipe 23e6909708 Merge pull request #18110 from grokability/#18107-normalize-to-strings
Fixed #18107: normalize "to" strings
2025-10-28 15:03:16 +00:00
snipe cf421fe1c1 Added user-specific “to” 2025-10-28 15:02:15 +00:00
snipe 4d80e806e4 Use “-“ instead of “to” string, added placeholders 2025-10-28 15:02:03 +00:00
snipe 60a7b7f7ff Merge pull request #18109 from grokability/audit-improvements
Limit the upcoming audit email to 30 records, added optional --with-output
2025-10-28 14:31:55 +00:00
snipe 90263eab06 Added note for —with-option flag 2025-10-28 14:20:40 +00:00
snipe 9d8f251fc4 Limit the email to 30 records, added optional --with-output 2025-10-28 14:15:15 +00:00
snipe 2b4986571c Merge pull request #18108 from uberbrady/fix_ldap_tests
Fixed - LDAP test needs to be fixed to match new behavior
2025-10-28 12:49:11 +00:00
Brady Wetherington 890d13bd52 LDAP test needs to be fixed to match new behavior 2025-10-28 12:30:30 +00:00
snipe e698e71137 Merge pull request #18100 from marcusmoore/fixes/20318-license-seat-display-name
Added null safe operator in case of missing license
2025-10-28 09:29:25 +00:00
snipe d064a5530a Merge remote-tracking branch 'origin/master' into develop 2025-10-28 02:10:07 +00:00
snipe ab4fbf6c19 Merge pull request #18105 from grokability/ldap-fast-find-and-bind
Possible fix for 504 gateway timeout on unreachable LDAP server
2025-10-28 02:09:41 +00:00
snipe 728afa8361 Possible fix for 504 gateway timeout on unreachable LDAP server 2025-10-27 23:45:12 +00:00
snipe b77019c16e Merge remote-tracking branch 'origin/develop' 2025-10-27 19:32:28 +00:00
snipe 6703448b80 Merge pull request #18102 from marcusmoore/fixes/rb-20434-undefined-permissions-variable
Fixed issue when viewing user that does not have permissions set
2025-10-27 19:31:54 +00:00
Marcus Moore 776ba19a1f Define default permissions array 2025-10-27 12:28:55 -07:00
Marcus Moore 1f499e0d44 Add null safe operator in case of missing license 2025-10-27 10:47:55 -07:00
snipe 0a6eb61103 Merge remote-tracking branch 'origin/develop' 2025-10-27 13:20:18 +00:00
snipe 32a2eed5ec Fixed #18075 - make require_serial boolean in API transformer 2025-10-27 13:19:37 +00:00
snipe 40a70d39d0 Merge remote-tracking branch 'origin/develop' 2025-10-27 12:42:40 +00:00
snipe 5697054e98 Merge pull request #18099 from grokability/fix-cjk-for-acceptance-translated-strings
Fixed #18097 - check for CJK in field labels as well as content
2025-10-27 12:41:59 +00:00
snipe def5969e1c Fixed #18097 - check for CJK in field labels as well as content 2025-10-27 12:34:30 +00:00
snipe 78a418630d Merge remote-tracking branch 'origin/develop' 2025-10-27 12:21:25 +00:00
snipe 6d76e7b2d4 Added dumb pverride for reports :( 2025-10-27 12:21:16 +00:00
snipe f052c8b44c Merge pull request #18076 from uberbrady/move_traits_into_directories
Moved Traits into its directory and modify the FCO's to point to them
2025-10-27 11:43:31 +00:00
snipe 0e6991d56d Merge remote-tracking branch 'origin/develop' 2025-10-27 11:42:05 +00:00
snipe 06eab5f8a4 Merge pull request #18093 from Godmartinz/fix-warranty-part-of-expiring-asset-query
Fixed expiring warranties not being included in the expiring alerts notification
2025-10-27 11:41:51 +00:00
snipe 4a481e79c4 Merge remote-tracking branch 'origin/develop'
# Conflicts:
#	public/css/build/app.css
#	public/css/build/app.css.map
#	public/css/build/overrides.css
#	public/css/build/overrides.css.map
#	public/css/dist/all.css
#	public/js/dist/all.js
#	public/js/dist/all.js.map
#	public/mix-manifest.json
2025-10-27 11:14:05 +00:00
snipe ee4abbcbaa Updated dev assets 2025-10-27 11:12:13 +00:00
snipe dcc82d742f Fixed RB-20430 - 500 on LDAP if baseDN is not set 2025-10-27 11:09:24 +00:00
snipe 19cb2089d7 Merge pull request #18098 from grokability/dependabot/github_actions/develop/actions/upload-artifact-5
Bump actions/upload-artifact from 4 to 5
2025-10-27 10:47:59 +00:00
snipe 04923b06b0 Merge pull request #18078 from grokability/groups-ui-improvements
Groups UI improvements, ability to add users from the group edit screen
2025-10-27 10:47:11 +00:00
dependabot[bot] e16755d491 Bump actions/upload-artifact from 4 to 5
Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 4 to 5.
- [Release notes](https://github.com/actions/upload-artifact/releases)
- [Commits](https://github.com/actions/upload-artifact/compare/v4...v5)

---
updated-dependencies:
- dependency-name: actions/upload-artifact
  dependency-version: '5'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-27 08:19:26 +00:00
snipe 742b0769a4 Use translation string 2025-10-26 12:10:08 +00:00
snipe df68dca9dc Warn if user has individual permission overrides 2025-10-25 18:57:17 +01:00
snipe 4a5bf78d58 Merge branch 'develop' into groups-ui-improvements 2025-10-25 18:31:22 +01:00
snipe 7947237489 Double check the admin status when toggling the superadmin 2025-10-25 18:29:52 +01:00
snipe 1115205164 Normalize the JS 2025-10-25 18:20:22 +01:00
snipe d5d01136c4 Fixed js errors 2025-10-25 17:57:59 +01:00
snipe 3d47277614 Added cursor style 2025-10-25 17:57:44 +01:00
snipe b937bea04f Working, but there’s a bit of a jitter I need to fix 2025-10-25 15:59:47 +01:00
snipe fff14632bc Merge remote-tracking branch 'origin/develop'
# Conflicts:
#	public/css/build/app.css
#	public/css/build/app.css.map
#	public/css/build/overrides.css
#	public/css/build/overrides.css.map
#	public/css/dist/all.css
#	public/mix-manifest.json
2025-10-25 14:59:31 +01:00
snipe 9bdf1a620f Built assets 2025-10-25 14:58:27 +01:00
snipe 60099aa989 FAFOing on disclosure arrows being remembered 2025-10-25 14:56:01 +01:00
Marcus Moore 777872d41f Add notification group 2025-10-23 13:53:38 -07:00
Marcus Moore b85d1f184a Remove redundant test 2025-10-23 13:52:52 -07:00
Marcus Moore 02129eeddb Add try/catch 2025-10-23 13:51:53 -07:00
Marcus Moore 2612e0bbc8 Remove unused import 2025-10-23 12:43:12 -07:00
Marcus Moore 3670efacb4 Implement test 2025-10-23 12:39:36 -07:00
snipe f3976e5dd8 Merge pull request #18094 from Godmartinz/custom_field_color_fixx
Fixed fieldset colors on dark themes
2025-10-23 20:32:05 +01:00
Marcus Moore 476611b70f Remove redundant test 2025-10-23 12:27:20 -07:00
Godfrey M d7d6893304 fix Custom Fields section header font color 2025-10-23 12:05:13 -07:00
Godfrey M 99549ce805 rewrite query for expired warranties on assets, concat queries" 2025-10-23 11:01:51 -07:00
snipe 7eb15fe04d Merge pull request #18091 from uberbrady/fix_backup_durations
Moved import time limit inside class, added new backup time limit
2025-10-23 18:51:35 +01:00
Godfrey M e2019a13ab rewrite expired assets collection query 2025-10-23 10:49:58 -07:00
Brady Wetherington 4b7a06761a Moved import time limit inside class, added new backup time limit 2025-10-23 16:05:09 +01:00
Brady Wetherington b96e2fb52c Added migration to fix incorrect action_type in action_log 2025-10-23 15:40:54 +01:00
snipe 8f4a1f5801 Moved JS and styles into js and css files 2025-10-23 13:24:26 +01:00
snipe 891bec9cdb Styling fixes 2025-10-23 13:06:45 +01:00
Marcus Moore 60df2a17f8 Check context when sending to alert address 2025-10-22 16:41:36 -07:00
Marcus Moore f64f4795c1 Send request instead of firing event 2025-10-22 16:39:34 -07:00
Marcus Moore e036f756d5 Improve setup 2025-10-22 16:24:47 -07:00
Marcus Moore 92fd121cae Clean up 2025-10-22 16:12:35 -07:00
Marcus Moore 6307337892 Add scenario 2025-10-22 16:09:26 -07:00
Marcus Moore fc2e35cd32 Improve assertions 2025-10-22 14:23:07 -07:00
Marcus Moore 1811e061aa Populate scenario 2025-10-22 14:21:24 -07:00
Marcus Moore 59037f0d83 Move scenario 2025-10-22 14:18:45 -07:00
Marcus Moore 67edb7d396 Send to alert email 2025-10-22 14:17:32 -07:00
Marcus Moore 0da393f950 Populate scenario 2025-10-22 14:02:16 -07:00
Marcus Moore abd30e551e Clean up 2025-10-22 13:46:19 -07:00
Marcus Moore 6fb2889a92 Clean up 2025-10-22 13:45:00 -07:00
Marcus Moore 54125d27e0 Add scenario 2025-10-22 13:44:14 -07:00
Godfrey M c5252ea583 skip in one more spot 2025-10-22 12:23:14 -07:00
Godfrey M 82d553c180 skip test if sqllite 2025-10-22 12:19:13 -07:00
Godfrey M 71e34355b9 remove unwanted changes 2025-10-22 11:51:00 -07:00
Godfrey M 2bad8c72e4 fixes warranty part of expiring alerts query 2025-10-22 11:43:54 -07:00
Godfrey M 6134ca01ac Merge remote-tracking branch 'origin/develop' into develop 2025-10-22 10:48:05 -07:00
snipe be8193ebff Fixed inherit permissions 2025-10-22 15:00:04 +01:00
snipe 430ee46645 Small tweaks to inherit js 2025-10-22 13:41:59 +01:00
snipe 76fbbf29e8 Replace generate text with icon button 2025-10-22 13:37:45 +01:00
snipe 3108159d95 Jitter CSS tweaks 2025-10-22 12:37:39 +01:00
snipe f282a1ead7 Removed duplicated permissions js code 2025-10-22 12:03:55 +01:00
snipe 324bc4957d Merge pull request #18080 from Godmartinz/add-null-safe-operator-to-manager
Fixes admin alerts when a location doesnt have a manager
2025-10-22 11:56:59 +01:00
snipe c3b5c4dfae Moved the logic into the permissions partial, added translations 2025-10-21 22:10:09 +01:00
Godfrey M 4ab5d97e86 add nullsafe operator to location manager 2025-10-21 14:06:08 -07:00
Marcus Moore 41efda5f82 Add todos 2025-10-21 13:22:41 -07:00
Marcus Moore 2aee14a800 Only send mail to target if they have an email address 2025-10-21 13:14:50 -07:00
Marcus Moore be69da0a0d Add test case 2025-10-21 13:13:45 -07:00
Godfrey M b4696ef11e added alert_email to send conditional in listener 2025-10-21 13:11:21 -07:00
Marcus Moore 31a247b55b Add test case 2025-10-21 12:44:50 -07:00
Marcus Moore 33c156be16 Add failing test 2025-10-21 12:43:23 -07:00
Marcus Moore fd66a083d6 Fix assertion 2025-10-21 12:41:51 -07:00
snipe 294ffb72a4 Translations!!! 2025-10-21 20:36:09 +01:00
Marcus Moore d276f50fdf Fix assertion 2025-10-21 12:30:27 -07:00
Marcus Moore 4cb748e124 Improve test assertions 2025-10-21 12:29:25 -07:00
snipe 8c534d29d3 WTF tower?? 2025-10-21 19:36:28 +01:00
snipe d6cb262f9d Bumped version 2025-10-21 19:22:36 +01:00
snipe 5211e2ae20 Some UI refinement 2025-10-21 19:22:36 +01:00
snipe 90832fd1ad Checked check 2025-10-21 19:22:36 +01:00
snipe 889cbc69e1 Starter improvements - needs testing 2025-10-21 19:22:36 +01:00
snipe 15948370d4 Updated assets 2025-10-21 19:22:24 +01:00
snipe 63c5177b37 Merge pull request #18077 from Godmartinz/acceptance-notif-fixes-pt2
Adds admin to decline notification, fix asset and model name translations on asset notification
2025-10-21 18:31:28 +01:00
Godfrey M 4fbfaf6b9f add admin to decline, fix asset and model name translations 2025-10-21 10:22:34 -07:00
Brady Wetherington 9e68497b63 Moved Traits into directory and modify the users to point to them 2025-10-21 16:45:58 +01:00
snipe 0b9e13bf1e Merge remote-tracking branch 'origin/develop' 2025-10-21 12:58:06 +01:00
snipe 485d343e0f Merge pull request #18058 from uberbrady/ldap_fetch_dn_before_login_FIXED
FIXED - perform Ldap fetch for dn (Distinguished Name) before logging-in (fixed)
2025-10-21 12:56:31 +01:00
snipe 07f0e8a3be Merge pull request #18070 from Godmartinz/fix-admin-in-user-acceptance-notif
Fixes `admin` parameter acceptance notifications
2025-10-21 12:54:03 +01:00
snipe cc5afb1cd8 Merge pull request #18074 from grokability/smaller-audit-image-fix
Fixed audit images not displaying inline
2025-10-21 12:51:20 +01:00
snipe c69f1c0890 Smaller fix for missing audit images 2025-10-21 12:43:59 +01:00
Marcus Moore 503e6898c3 WIP 2025-10-20 16:53:36 -07:00
Marcus Moore f34056fe2e Scaffold some testing changes 2025-10-20 16:35:27 -07:00
Marcus Moore 8ff3575442 Add test for listener registration 2025-10-20 16:31:52 -07:00
Marcus Moore b5e3358bbd Add todos 2025-10-20 14:29:05 -07:00
Marcus Moore 047a1197be Add failing conditions 2025-10-20 14:18:11 -07:00
Godfrey M a8733bdedf remove nullsafe operator 2025-10-20 11:01:38 -07:00
Godfrey M 4222e4eb51 add nullsafe operator after admin 2025-10-20 11:00:59 -07:00
Godfrey M 5db4441f5c fix admin param in user accepted notification 2025-10-20 10:51:24 -07:00
snipe 2bcfe97211 Merge remote-tracking branch 'origin/develop' 2025-10-20 16:03:55 +01:00
snipe 4e74c97c84 Merge pull request #18066 from smarsching/issue-18065
Fixed #18065: Ensure that private_key_bits is always an int
2025-10-20 13:51:42 +01:00
Sebastian Marsching 71a46c9bd6 Fixed #18065: ensure that private_key_bits is always an int. 2025-10-18 18:39:43 +02:00
snipe 1a7c7fdebf Merge remote-tracking branch 'origin/develop'
# Conflicts:
#	config/version.php
#	public/css/build/app.css
#	public/css/build/app.css.map
#	public/css/build/overrides.css
#	public/css/build/overrides.css.map
#	public/css/dist/all.css
#	public/mix-manifest.json
2025-10-17 18:37:18 +01:00
snipe 65ff3d414a Bumped version 2025-10-17 18:34:54 +01:00
snipe 9fa38b70c8 Bumped version 2025-10-17 18:26:44 +01:00
snipe 470172f53f Re-run assets 2025-10-17 18:26:05 +01:00
snipe 81261d9e36 Put the session check back in - possible fix for #18004 2025-10-17 18:25:50 +01:00
snipe 3ab2e20119 Merge remote-tracking branch 'origin/develop' 2025-10-17 17:12:47 +01:00
snipe b773d576ea Updated cipher-base library 2025-10-17 17:12:31 +01:00
snipe 23feb64b5a Fixed potential XSS on locations 2025-10-17 17:07:57 +01:00
snipe 87fe9d9d3d Merge remote-tracking branch 'origin/develop'
# Conflicts:
#	public/css/build/app.css
#	public/css/build/app.css.map
#	public/css/build/overrides.css
#	public/css/build/overrides.css.map
#	public/css/dist/all.css
#	public/css/dist/skins/_all-skins.css
#	public/css/dist/skins/_all-skins.css.map
#	public/css/dist/skins/_all-skins.min.css
#	public/css/dist/skins/skin-contrast.css
#	public/css/dist/skins/skin-contrast.css.map
#	public/css/dist/skins/skin-contrast.min.css
#	public/mix-manifest.json
2025-10-17 17:00:10 +01:00
snipe b1ef3f51cb Merge pull request #18064 from grokability/new-fieldsets
Use new fieldset component
2025-10-17 16:58:17 +01:00
snipe e1b6488f8e Use new fieldset component 2025-10-17 16:55:36 +01:00
snipe a472dede2b Merge pull request #18063 from grokability/improved-fieldset-UI-and-better-help-test-for-ldap-mapping
New legend styles and additional help hints for LDAP
2025-10-17 15:45:05 +01:00
snipe 263cc3f7a1 New styles and additional help hints for LDAP 2025-10-17 15:29:24 +01:00
Marcus Moore 0e87843446 WIP: start testing 2025-10-16 14:30:48 -07:00
Brady Wetherington 598612d4bf Got tests to pass? Not very happy about it, tbh. 2025-10-16 19:11:49 +01:00
Brady Wetherington a07d83e583 Improved find-and-bind for complex LDAP directory structures 2025-10-16 19:11:49 +01:00
snipe d355812433 Updated assets 2025-10-16 19:06:22 +01:00
snipe 1afc14f5ab Merge remote-tracking branch 'origin/develop' 2025-10-16 19:04:30 +01:00
snipe 8947b667ae Fixed status labels skin for visited link buttons 2025-10-16 19:04:15 +01:00
snipe 6b41796d44 Fixed restore button on asset view page 2025-10-16 19:04:01 +01:00
snipe 6efe8eb55b Small fix for high contrast skin 2025-10-16 18:33:33 +01:00
snipe 4c8f8918e8 Merge remote-tracking branch 'origin/develop' 2025-10-16 15:49:59 +01:00
snipe 4cb5bb1855 Merge pull request #18057 from grokability/user-selector-fix
Fixed #18053 - user selector missing on page load without cookies
2025-10-16 15:49:39 +01:00
snipe eb007e025a Fixed #18053 - user selector missing on page load without cookies 2025-10-16 15:47:25 +01:00
snipe 18aefa9dee Merge remote-tracking branch 'origin/develop' 2025-10-16 15:10:29 +01:00
snipe 2ec540bd36 Updated language translations 2025-10-16 15:10:17 +01:00
snipe 1374ec408a Merge pull request #18019 from akemidx/emdashcharfix
Fixed #17363 - Emdash Character Encoding error
2025-10-16 15:07:31 +01:00
snipe 8f8fed2b79 Merge remote-tracking branch 'origin/develop' 2025-10-16 14:33:30 +01:00
snipe a1e6f01fe9 Fixed updating notes in bulk edit 2025-10-16 14:33:21 +01:00
snipe d7496f22e5 Merge remote-tracking branch 'origin/develop' 2025-10-16 14:04:44 +01:00
snipe 7de25a1c37 Merge pull request #18056 from grokability/add-expected-checkin-to-view-assets
Added expected_checkin to user’s View Assigned page
2025-10-16 14:04:31 +01:00
snipe 78da89340c Added expected_checkin to user’s View Assigned page 2025-10-16 13:59:59 +01:00
snipe 60606115fe Merge remote-tracking branch 'origin/develop' 2025-10-16 12:46:47 +01:00
snipe 57b49fc31c Check for array key for license report/formatters 2025-10-16 12:46:17 +01:00
snipe 6e90c8f6e6 Bumped hash for master 2025-10-16 11:28:37 +01:00
snipe a7ff2595a5 Bumped hash 2025-10-16 11:28:01 +01:00
snipe 1edea6abef Fixed RB-20347 - ambigious field in custom fields 2025-10-16 11:27:25 +01:00
snipe a3bd58bda6 Foundation 2025-10-16 11:17:48 +01:00
snipe 3339d1999f Merge remote-tracking branch 'origin/develop' 2025-10-16 11:12:56 +01:00
akemidx df3e8ec0f3 cleaning up notes 2025-10-15 17:35:25 -04:00
snipe 2dbec867d9 Merge pull request #18038 from boteroTradebe/develop
Fixed LDAP sync not syncing all user fields
2025-10-15 17:25:33 +01:00
Marcus Moore 4f1ff328ad Display eula if it is the same for all items 2025-10-14 17:10:57 -07:00
Marcus Moore ad5bbb9b37 Add divider 2025-10-14 16:34:18 -07:00
Marcus Moore c6e2fd2cab Add note 2025-10-14 16:33:37 -07:00
Marcus Moore d3a7e25b86 Move expected checking and only show once 2025-10-14 16:29:59 -07:00
Marcus Moore 062445a48e Add expected checkin 2025-10-14 16:25:32 -07:00
Marcus Moore 3c32be6181 Make introduction line dynamic 2025-10-14 16:22:19 -07:00
Marcus Moore e2f4a9bf9f Make subject dynamic 2025-10-14 16:20:01 -07:00
Marcus Moore 2db4c1b2e4 Add todo 2025-10-14 16:19:42 -07:00
Mohammad Ahmadi 3fc651d659 fix: update mysqldump options to use --ssl-mode=DISABLED for modern versions 2025-10-15 00:30:53 +02:00
Marcus Moore 6ed93f4a4f Add asset details 2025-10-14 14:02:21 -07:00
snipe b91d23023d Fix blade template syntax for accessory fields 2025-10-14 13:45:58 +01:00
boteroTradebe cc234c60b8 Update LdapSync.php to populate/update user fields
Added missing IF statements for address, city, state, and ZIP code. Previously, this information would be pulled via LDAP sync but would not update the user data due to the missing IF statements for these attributes.
2025-10-13 13:42:11 -05:00
snipe f1883c8004 Merge remote-tracking branch 'origin/develop' 2025-10-13 14:48:46 +01:00
snipe 79f6ddc8ee Merge pull request #18036 from grokability/better-messaging-for-bulk-deletes
Fixed #18034 - Shows success message on partial bulk delete success
2025-10-13 14:30:26 +01:00
snipe 89f439a18d Shows success message on partial bulk delete success 2025-10-13 14:25:05 +01:00
snipe 79eb5bfad9 Merge pull request #18035 from grokability/fixes-bulk-error-notification
Fixed bulk error display to be more consistent and correct HTML
2025-10-13 14:02:11 +01:00
snipe 3a36b7dafd Fixed display to be more consistent and correct HTML 2025-10-13 13:57:04 +01:00
snipe 1fe2fd9891 Merge pull request #17573 from spencerrlongg/feature/8709-bulk-deletion-of-asset-categories-suppliers-manufacturers
Fixed #8709 - Bulk Deletion of Categories, Suppliers, Manufa...
2025-10-13 13:20:13 +01:00
snipe 5fdb999ece Merge branch 'develop' into feature/8709-bulk-deletion-of-asset-categories-suppliers-manufacturers 2025-10-13 13:07:53 +01:00
snipe 5a38d9c2b6 Merge pull request #18029 from grokability/dependabot/github_actions/develop/github/codeql-action-4
Bump github/codeql-action from 3 to 4
2025-10-13 12:00:49 +01:00
snipe b1c7dc6cbb Merge remote-tracking branch 'origin/develop' 2025-10-13 11:32:19 +01:00
snipe b21b2ac41c Merge pull request #18032 from grokability/move-asset-private-files
Added migration to move asset model private uploads
2025-10-13 11:31:55 +01:00
snipe 1396c597ef Move files 2025-10-13 11:19:25 +01:00
dependabot[bot] 46af72ee4e Bump github/codeql-action from 3 to 4
Bumps [github/codeql-action](https://github.com/github/codeql-action) from 3 to 4.
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/v3...v4)

---
updated-dependencies:
- dependency-name: github/codeql-action
  dependency-version: '4'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-13 08:19:22 +00:00
snipe e3e8f553c8 Merge remote-tracking branch 'origin/develop' 2025-10-09 18:39:13 +01:00
snipe 549928d3d1 Updated assets 2025-10-09 18:38:59 +01:00
snipe abefec9628 Upgraded jdpdf to ^3.0.3 2025-10-09 18:37:59 +01:00
snipe b483eeded4 Merge remote-tracking branch 'origin/develop' 2025-10-09 11:24:47 +01:00
snipe fab85dafa8 Added employee number and email to acceptance PDF 2025-10-09 11:24:16 +01:00
snipe 955faed919 Merge pull request #18018 from grokability/advanced-user-search
Normalize advanced search
2025-10-09 11:04:28 +01:00
snipe 3ff516180d Merge remote-tracking branch 'origin/develop' 2025-10-09 10:56:08 +01:00
snipe 0c8ca6d6b0 Search on status label name 2025-10-09 10:54:11 +01:00
snipe a5de077e04 Merge pull request #17975 from marcusmoore/replace-date-and-time-display-macros
Removed date and time display format form macros
2025-10-09 04:54:05 +01:00
akemidx c0a99d6b52 notes 2025-10-08 19:20:32 -04:00
Marcus Moore 9dcee71baf wip 2025-10-08 16:18:54 -07:00
Marcus Moore 9bdd0d1d1e Add admin name 2025-10-08 16:05:55 -07:00
Marcus Moore 13b51d8608 Make acceptance section dynamic 2025-10-08 15:46:36 -07:00
Marcus Moore 19969fee39 Update closing 2025-10-08 15:32:38 -07:00
Marcus Moore 28dc4bf52e Move template to correct directory 2025-10-08 14:13:04 -07:00
Marcus Moore 9a380ac3d4 Extract intro text 2025-10-08 14:12:35 -07:00
Marcus Moore 17a26b43f0 Naively send email 2025-10-08 14:01:07 -07:00
Marcus Moore a1e65cd897 Merge branch 'develop' into replace-date-and-time-display-macros
# Conflicts:
#	resources/macros/macros.php
2025-10-08 13:10:56 -07:00
snipe 5d65f1ffc5 Merge pull request #17976 from marcusmoore/17204-replace-form-digit-separator
Fixed #17204 - replace Form::digit_separator macro
2025-10-08 21:01:11 +01:00
snipe b7193a06fd Normalize advanced search 2025-10-08 20:51:35 +01:00
akemidx cba090f8eb notes 2025-10-08 15:50:00 -04:00
snipe 0d6baa1081 Merge remote-tracking branch 'origin/develop' 2025-10-08 15:29:02 +01:00
snipe bc60d796a3 Fixed RB-20329 - ambiguous clause on deleted_at 2025-10-08 15:28:48 +01:00
snipe 85a208526b Merge remote-tracking branch 'origin/develop' 2025-10-08 10:38:08 +01:00
snipe c3ac0a750d Added licenses checkin permission 2025-10-08 10:37:58 +01:00
snipe 0f111127a5 Merge pull request #18005 from marcusmoore/fixes/drop-index-migration
Fixed exception when rolling back migrations
2025-10-08 05:26:22 +01:00
snipe cd266a6bef Merge remote-tracking branch 'origin/develop' 2025-10-08 05:13:14 +01:00
snipe 0f4945621c Merge pull request #18009 from grokability/#18002-audit-image-location
Fixed #18002 - use correct path for audit images to determine validity
2025-10-08 05:12:54 +01:00
snipe 9a477f227b Fixed #18002 - use correct path for audit images to determine validity 2025-10-08 05:09:04 +01:00
akemidx 3c81257325 fix? 2025-10-07 20:23:46 -04:00
Marcus Moore 218fe9ebdc Allow Laravel to calculate index name 2025-10-07 16:04:12 -07:00
spencerrlongg 24bb45ab97 change translation 2025-10-07 13:26:08 -05:00
snipe 85f39de540 Merge pull request #18001 from grokability/#17670-fixes-advanced-search-on-assets
Fixed #17670 - advanced search on relationships not working
2025-10-07 17:35:05 +01:00
snipe 5cc3277e2d Merge pull request #18003 from uberbrady/fix_file_upload_base64
Fixed [FD-50921] - base64-encoded image files for asset creation was broken
2025-10-07 17:34:53 +01:00
snipe d5ef7f3204 Merge remote-tracking branch 'origin/develop' 2025-10-07 17:29:24 +01:00
snipe cb47d01f51 Fixed variable name in location print 2025-10-07 17:29:12 +01:00
Brady Wetherington ee499c1385 Fix base64-encoded image files for asset creation; add test 2025-10-07 16:00:16 +01:00
snipe 4ae4af5c10 Fixed #17670 - advanced search on relationships not working 2025-10-07 15:39:09 +01:00
snipe b0f5fe7e25 Merge remote-tracking branch 'origin/develop' 2025-10-07 14:32:33 +01:00
snipe fd32585efc Added notes back to audit email 2025-10-07 14:32:24 +01:00
snipe c675bb7252 Merge remote-tracking branch 'origin/develop' 2025-10-07 14:29:21 +01:00
snipe e65d11d71e Pulled incorrect button label 2025-10-07 14:29:10 +01:00
snipe c2680334f1 Clearer title on maintenances within asset context 2025-10-07 14:28:38 +01:00
snipe 1217a02ec1 Merge pull request #17992 from marcusmoore/17963-undelete-files-command
Added command to remove invalid "upload deleted" entries from the action log
2025-10-07 14:17:56 +01:00
snipe 143a091f45 Merge remote-tracking branch 'origin/develop' 2025-10-07 14:15:59 +01:00
snipe 49ecc93dbe Merge pull request #17999 from grokability/updated-audit-report
Improved upcoming audit email layout and cli feedback
2025-10-07 14:15:44 +01:00
snipe 1735fb6bed Improved audit email 2025-10-07 14:08:33 +01:00
snipe 8fefc11b4d Merge remote-tracking branch 'origin/develop' 2025-10-07 12:09:32 +01:00
snipe 1a3b22171c Merge pull request #17997 from grokability/#17924-add-url-to-maintenances
Fixed #17924 - added url to maintenances
2025-10-07 12:09:06 +01:00
snipe 5e773be260 Enhanced tests 2025-10-07 12:05:37 +01:00
snipe c317a1dc8b Added url to factory 2025-10-07 12:03:35 +01:00
snipe 9401ffc83c Added link to view 2025-10-07 11:55:32 +01:00
snipe 479a852446 Fixed #17924 - added url to maintenances 2025-10-07 11:49:10 +01:00
snipe 9188fb03f0 Merge remote-tracking branch 'origin/develop' 2025-10-07 10:49:59 +01:00
snipe 36bb91cbc3 Merge pull request #17995 from grokability/#17910-show-counts-on-mobile
Fixed #17910 - added counts to mobile view for assets
2025-10-07 10:47:41 +01:00
snipe 56e5ab8bc6 Fixed #17910 - added counts to mobile view for assets 2025-10-07 10:41:03 +01:00
snipe 607eb6ca03 Merge remote-tracking branch 'origin/develop' 2025-10-07 09:42:59 +01:00
snipe ad745cc84b Fixed #17911 - updated language string 2025-10-07 09:42:30 +01:00
Marcus Moore 5a13d5ea6f Update command description 2025-10-06 15:23:55 -07:00
Marcus Moore 0b065eb7fe Improve command 2025-10-06 15:20:43 -07:00
Marcus Moore e2c0e4bc66 WIP build out command 2025-10-06 15:14:15 -07:00
Marcus Moore 655b0e6778 Scaffold command 2025-10-06 14:59:25 -07:00
Marcus Moore cd785c9fc3 Remove name_display_format macro that was accidentally re-added 2025-10-06 13:06:52 -07:00
Marcus Moore 23885f5166 Merge branch 'develop' into 17204-replace-form-digit-separator
# Conflicts:
#	resources/macros/macros.php
2025-10-06 13:04:34 -07:00
snipe 44ef39e419 Merge remote-tracking branch 'origin/develop' 2025-10-06 20:53:14 +01:00
snipe e05a0ef565 Merge pull request #17967 from marcusmoore/fixes/17963-delete-file-via-api-fix
Fixed #17963 - over eager deletion of asset files via api
2025-10-06 20:52:57 +01:00
snipe 0ea9c0647f Merge remote-tracking branch 'origin/develop'
# Conflicts:
#	config/version.php
2025-10-06 15:14:56 +01:00
snipe 00b9ba2b75 Merge pull request #17989 from grokability/fixes-tcpdf-png-handling
Fixed #17940 - pngs not showing in acceptance PDFs
2025-10-06 15:13:58 +01:00
snipe f1e3bc9531 Fixed #17940 - use base64encoding on images in acceptance PDF 2025-10-06 15:02:53 +01:00
snipe 7360e093b2 Bumped version 2025-10-06 10:41:15 +01:00
snipe 5f639bc24f Updated translations 2025-10-06 10:39:04 +01:00
snipe 884d2a9552 Merge remote-tracking branch 'origin/develop' 2025-10-04 14:09:54 +01:00
snipe fd8a8b29b1 Added inactive and expired to licenses table listing 2025-10-04 13:18:51 +01:00
snipe 4e1ef40c05 Updated active button colors 2025-10-04 13:16:46 +01:00
snipe 00af0ddff5 Merge pull request #17982 from grokability/expiring-alerts-improvements
Small expiring alerts improvements
2025-10-04 01:11:03 +01:00
snipe 2467e823a5 Reordered buttons 2025-10-04 01:06:56 +01:00
snipe 224642fcb5 Removed funky search cookie 2025-10-04 01:04:25 +01:00
snipe 59518ca2c5 Small style updates 2025-10-04 00:31:17 +01:00
snipe dfb7c73069 Added column search to users 2025-10-04 00:31:06 +01:00
snipe 70eccceab3 Updated button class for add new 2025-10-04 00:18:09 +01:00
snipe 3f69b70367 Moved btn methods closer to the BS table 2025-10-03 23:54:38 +01:00
snipe 94a0a2f8be Fixed dropdown toggle 2025-10-03 23:50:40 +01:00
snipe 7e23596ab8 Translate export to CSV 2025-10-03 23:09:33 +01:00
snipe 3c58a5dd3d Fixed column selector 2025-10-03 20:36:52 +01:00
snipe 51789ccbf3 Got tooltips to work on built-in buttons! 2025-10-03 18:54:05 +01:00
snipe 6ae4a9aa1a Added tooltips to custom btn methods 2025-10-03 17:14:47 +01:00
snipe 0aebd669b2 Fixed accessor for console view 2025-10-03 16:25:31 +01:00
snipe 2a92c4899d Don’t use parenthases unless a manufacturer is given 2025-10-03 16:19:00 +01:00
snipe 530089895a Added category and manufacturer to expiring license report 2025-10-03 16:13:00 +01:00
snipe ae8289fc8c Eager load cagory and manufacturer 2025-10-03 16:12:40 +01:00
snipe 90f4dfb48b Use regular blade syntax 2025-10-03 16:03:03 +01:00
snipe ec2eddf538 Add order scope to query 2025-10-03 16:02:07 +01:00
snipe 44d31d4b39 Moved date fields closer together 2025-10-03 16:01:49 +01:00
snipe 4934e7666c Added text string 2025-10-03 16:01:38 +01:00
snipe 35bf0d020e Added breadcrumb to expiring 2025-10-03 16:01:27 +01:00
snipe 4934dc85ac Reverse expires diff direction 2025-10-03 16:00:58 +01:00
snipe 5ceb50d7e5 Added expiring licenses to API and UI 2025-10-03 16:00:23 +01:00
snipe ae7ccbb7bd Fixed icons 2025-10-03 15:59:55 +01:00
snipe 1cd9fc47aa Use diff_in_days instead 2025-10-03 15:03:14 +01:00
snipe 013c50607a Put old setter back because reasons? 2025-10-03 14:46:32 +01:00
snipe d7bf9b7f2e Added more accessors and mutators 2025-10-03 14:38:37 +01:00
snipe 4702fdddc6 Nicer output in console command 2025-10-03 14:38:08 +01:00
snipe dd06a530c0 Added Terminates string 2025-10-03 14:37:43 +01:00
snipe c36125dc95 Added CSS to the message blade 2025-10-03 14:37:25 +01:00
snipe ae43f93d0a Improved expiring assets and licenses email 2025-10-03 14:37:12 +01:00
snipe 8918b17f77 Updated test 2025-10-03 14:36:16 +01:00
snipe dfd05e8b5b Refactored scope 2025-10-03 14:13:58 +01:00
snipe 3daa6dd051 Added accessors for termination date 2025-10-03 14:13:28 +01:00
snipe 14e43192e6 Merge remote-tracking branch 'origin/develop' 2025-10-03 09:17:35 +01:00
snipe 6cf88b1792 Merge pull request #17978 from marcusmoore/17205-replace-form-email-format
Fixed #17205 - replace Form:: email_format
2025-10-03 09:15:49 +01:00
snipe 6b9839367f Merge pull request #17973 from marcusmoore/fixes/17972-update-last-checkin-upon-edit
Fixed #17972 - set last_checkin if asset is checked in during an update
2025-10-03 09:15:35 +01:00
snipe 34fcf5d616 Merge pull request #17974 from marcusmoore/replace-form-checkbox
Replaced Form::checkbox with raw html
2025-10-03 09:15:12 +01:00
snipe 1cf3c74e67 Merge pull request #17979 from akemidx/term-date-on-license-report
Fixed #17977: Term date on license report
2025-10-03 09:14:07 +01:00
snipe 16b57b931e Merge pull request #17980 from marcusmoore/17206-replace-name-display-format-macro
Fixed #17206 - replace Form::name_display_format macro
2025-10-03 09:13:23 +01:00
Marcus Moore 3457e7d617 Remove Form::name_display_format macro 2025-10-02 16:08:37 -07:00
Marcus Moore edbe8001e6 Replace Form::name_display_format 2025-10-02 16:08:16 -07:00
akemidx 71644c1cbe added term date 2025-10-02 19:00:18 -04:00
Marcus Moore 03fd8df8bd Remove Form::email_format 2025-10-02 15:52:09 -07:00
Marcus Moore 71d622b6dd Replace Form:: email_format 2025-10-02 15:51:41 -07:00
Marcus Moore 689d5a2d58 Remove digit_separator form macro 2025-10-02 15:39:28 -07:00
Marcus Moore b2e9eb866c Replace digit_separator form macro
Fixes #17204
2025-10-02 15:38:59 -07:00
Marcus Moore c8b7782d1d Remove date_display_format and time_display_format macros 2025-10-02 15:27:20 -07:00
Marcus Moore 673f936689 Replace Form:: time_display_format on localization screen 2025-10-02 15:26:31 -07:00
Marcus Moore 2ca0d39e51 Replace Form:: date_display_format on localization screen 2025-10-02 15:21:51 -07:00
Marcus Moore 908c8bc397 Remove Form::checkbox on user create screen 2025-10-02 14:33:48 -07:00
Marcus Moore 93082e1e87 Set last_checkin if asset checked in during update 2025-10-02 13:56:42 -07:00
Marcus Moore ef0a6aa25e Add failing condition 2025-10-02 13:53:19 -07:00
spencerrlongg b9f4dc1e9d translation 2025-10-02 12:00:52 -05:00
snipe 90afec864e Fixed info text help block class 2025-10-02 08:07:54 +01:00
akemidx b082fb6692 investigation and notes 2025-10-01 18:21:25 -04:00
Marcus Moore 4bbbd786cd Constrain to "uploaded" action_type 2025-10-01 14:37:36 -07:00
snipe 0c1b2a54e7 Merge remote-tracking branch 'origin/develop' 2025-10-01 22:27:06 +01:00
snipe a6ded20ede Merge pull request #17966 from uberbrady/fix_filetype_validation
Cleanups and improvements to output on snipeit:restore command
2025-10-01 22:26:49 +01:00
Brady Wetherington 9b96314371 Cleanups and improvements to output on snipeit:restore command 2025-10-01 22:07:45 +01:00
snipe 85e16ecd51 Merge remote-tracking branch 'origin/develop' 2025-10-01 21:34:50 +01:00
snipe 2ac36cdfd6 Fixed alignment on create-new dropdown in header 2025-10-01 21:32:28 +01:00
snipe e40c532354 Merge remote-tracking branch 'origin/develop' 2025-10-01 12:13:08 +01:00
snipe 9404dff79c Added note about markdown 2025-10-01 12:12:56 +01:00
snipe 55b324d8d6 Merge remote-tracking branch 'origin/develop' 2025-10-01 11:49:15 +01:00
snipe 3ed2e2d79e Added link to docs for common issues in upgrading script 2025-10-01 11:49:05 +01:00
snipe 3152d9eadd Merge remote-tracking branch 'origin/develop' 2025-10-01 11:24:33 +01:00
snipe f1266ab5d6 Check if telescope tables already exist 2025-10-01 11:24:20 +01:00
snipe e70f1408aa Merge remote-tracking branch 'origin/develop' 2025-10-01 11:19:35 +01:00
snipe 664e3984e3 Merge pull request #17877 from grokability/label-cjk-fix
Fixed CJK on labels
2025-10-01 11:16:55 +01:00
snipe 665c13e238 Merge pull request #17957 from marcusmoore/fixes/17956-handle-force-deleted-model-in-asset-edit
Fixed #17956 - handle accessing deleted model during asset update
2025-10-01 11:10:11 +01:00
snipe 8a667b20c2 Merge branch 'develop' into fixes/17956-handle-force-deleted-model-in-asset-edit 2025-10-01 11:09:40 +01:00
snipe 3693241292 Merge pull request #17959 from marcusmoore/fixes/17958-handle-force-deleted-model-in-bulk-edit
Fixes #17958 - handle accessing deleted model during bulk asset update
2025-10-01 11:06:32 +01:00
Marcus Moore 3c42acebf0 Scaffold new listener 2025-09-30 15:11:12 -07:00
akemidx a384245368 investigation and notes 2025-09-30 16:33:33 -04:00
Marcus Moore 3327b2ce3c Add assertions 2025-09-30 13:03:24 -07:00
Godfrey M 8c56aa9575 changed the wrong language file 2025-09-30 12:42:46 -07:00
Godfrey M d528126f15 right hand table loading, need styling and translations 2025-09-30 12:31:44 -07:00
Marcus Moore 3c3acff79b Fix more attempted access of deleted model 2025-09-30 12:22:26 -07:00
Marcus Moore e15de83a95 Fix attempted access of deleted model 2025-09-30 12:19:12 -07:00
Marcus Moore 636fccbf97 Add failing test 2025-09-30 12:18:51 -07:00
Marcus Moore 7d8ed399a8 Fix accessing force deleted model 2025-09-30 11:27:56 -07:00
Marcus Moore 272385db6c Add failing test 2025-09-30 11:27:38 -07:00
akemidx 64d0e3928c clean erroneous added space 2025-09-30 13:11:38 -04:00
snipe 9334b8df47 Improve Bug Report template details
Updated version placeholders and descriptions for clarity.
2025-09-30 11:57:06 +01:00
snipe e0bc2ae86f Add PHP and Composer version fields to bug report 2025-09-30 11:45:55 +01:00
snipe 2f019bb033 Merge remote-tracking branch 'origin/develop' 2025-09-30 11:40:34 +01:00
snipe 291be64aa0 Refined remnaining asset count for archived 2025-09-30 11:40:21 +01:00
snipe 75c83236ff Merge remote-tracking branch 'origin/develop' 2025-09-30 11:20:44 +01:00
snipe 72be171917 Added archived to model view 2025-09-30 11:20:33 +01:00
snipe 4ddee4ac40 Merge remote-tracking branch 'origin/develop' 2025-09-30 10:55:00 +01:00
snipe 43cd0d7eb3 Use min_amt formatter 2025-09-30 10:54:43 +01:00
snipe 6b693e2644 Merge remote-tracking branch 'origin/develop' 2025-09-30 10:51:35 +01:00
snipe eeea69d8f2 Make available_assets_count sortable 2025-09-30 10:51:25 +01:00
snipe 72cf921a4b Merge remote-tracking branch 'origin/develop' 2025-09-30 10:46:12 +01:00
spencerrlongg 32882f81e7 replace box-default 2025-09-29 15:52:43 -05:00
spencerrlongg 36f5099932 added new counts and throw new exceptions and catch them 2025-09-29 15:16:41 -05:00
snipe bec88a0441 Merge pull request #17950 from grokability/#17932-fix-remaining-counts-in-model-listing
Fixed #17932 - incorrect number for remaining assets in asset models
2025-09-29 20:55:52 +01:00
snipe 6e67e3a8a0 Fixed #17932 - incorrect number for remaining assets in asset models 2025-09-29 20:55:06 +01:00
snipe 4dc3c30354 Merge remote-tracking branch 'origin/develop' 2025-09-29 19:04:42 +01:00
snipe 947ccf911d Merge pull request #17868 from Godmartinz/adds-Tze_24mm-variant
Adds Brother Label TZe_24mm_E variant
2025-09-29 15:48:10 +01:00
snipe 06f313febe Merge pull request #17869 from marcusmoore/api-components-assigned-to-asset
Added api endpoint for retrieving components checked out to asset
2025-09-29 15:47:53 +01:00
snipe b387136b8f Merge pull request #17883 from akemidx/purchasepricereportfilter
FEATURE: Purchase Cost Report Filter
2025-09-29 15:37:39 +01:00
snipe 31614c5da1 Merge pull request #17888 from marcusmoore/fixes/bulk-checkout-extra-requests
Fixed excessive api requests on bulk checkout page
2025-09-29 14:46:19 +01:00
snipe 146b5a3085 Merge pull request #17933 from marcusmoore/17914-bulk-checkout-error-ux
Fixed #17914 - Improve UX around attempted bulk checkout of assigned assets
2025-09-29 14:44:20 +01:00
Brady Wetherington fc4ac029b1 Added the actual files to make that previous statement true 2025-09-29 12:56:59 +01:00
Brady Wetherington 73f4afa05e Got groups support working in Entra ID 2025-09-29 12:56:23 +01:00
snipe 397cc1754a Merge remote-tracking branch 'origin/develop' 2025-09-29 11:05:45 +01:00
snipe ff1297cac5 Merge pull request #17945 from kingspride/develop
with --no-interactive, make composer non-interactive aswell
2025-09-29 11:04:30 +01:00
William Kirstaedter 8af3cf4056 with --no-interactive, make composer non-interactive aswell 2025-09-29 11:39:23 +02:00
Marcus Moore 7017a0cae1 WIP: introduce event 2025-09-25 16:23:43 -07:00
Marcus Moore a40e4d7d04 Begin experimenting with context 2025-09-25 15:43:04 -07:00
Marcus Moore 9e3b56f4bc Add failing test 2025-09-25 15:41:37 -07:00
Marcus Moore 9edec9e212 Extract translation 2025-09-25 11:09:27 -07:00
Godfrey Martinez ca44ee94a4 Merge pull request #28 from Godmartinz/add_types_to_command
update the snipeit reminder command
2025-09-25 10:44:53 -07:00
Godfrey M 3ae7a77032 update the snipeit reminder command 2025-09-25 10:43:41 -07:00
snipe be4362c59a Merge pull request #17925 from Godmartinz/fix-factory-auto-gen-action-logs
Adds option to disable auto generating action log from acceptance factory
2025-09-25 11:10:34 +01:00
Marcus Moore 8461b147de Link to removed assets 2025-09-24 16:38:48 -07:00
Godfrey M 881c789a75 add usuage of withoutactionlog 2025-09-24 15:45:01 -07:00
Godfrey M fea0189479 Merge branch 'fix-factory-auto-gen-action-logs' into add_types_to_unaccepted_asset_report 2025-09-24 15:43:27 -07:00
Godfrey M 82bdd43168 renamed variable 2025-09-24 15:38:30 -07:00
Godfrey M 533d82d4d8 remove unnecessary changes 2025-09-24 15:34:02 -07:00
Godfrey M 6f990dd1de adds an option to disable Auto assigned an actionlogs in factories 2025-09-24 15:27:16 -07:00
Marcus Moore be848598e3 Keep removed asset out of scope of partial 2025-09-24 14:32:25 -07:00
Godfrey M 6ca0e19819 uncomment code 2025-09-24 13:50:41 -07:00
Godfrey M bf6964ee62 tests passing, CheckoutAcceptance Factory needs eyes though 2025-09-24 13:41:04 -07:00
Godfrey M 9ac2ea2a52 fix test to check all mailable types for reminders 2025-09-24 13:22:33 -07:00
Brady Wetherington ef1a42fff2 Progress! Got addresses updating correctly 2025-09-24 15:57:39 +01:00
snipe 62a58fa23b Merge remote-tracking branch 'origin/develop' 2025-09-24 14:52:55 +01:00
snipe 7d0742054f Merge pull request #17923 from uberbrady/fix_checkout_type_selector2
Fixed #17919 - correct the behavior of the checkout type selector
2025-09-24 14:52:05 +01:00
Brady Wetherington dcf7e83507 Remove extra pointless class="active" 2025-09-24 14:47:13 +01:00
Brady Wetherington 407c2bf0c8 Switch to ?: from ?? to better handle empty strings 2025-09-24 14:45:43 +01:00
Brady Wetherington c46227ee94 Fix to the checkout-selector issue 2025-09-24 14:28:49 +01:00
Godfrey M 0ce20c1edd fix send reminder method to handle other types 2025-09-23 18:40:03 -07:00
Godfrey M d31d99b40f remove else and blank lines 2025-09-23 17:00:08 -07:00
Godfrey M 3527c357cc whoops 2025-09-23 16:57:06 -07:00
Godfrey M 2b5254e68f fixed, eager loading, variable names, clean up 2025-09-23 16:55:10 -07:00
Godfrey M 6f3323c195 fix data in view model 2025-09-23 12:50:26 -07:00
Brady Wetherington 760d089073 Azure-specific Manager is handled now 2025-09-23 20:40:21 +01:00
Godfrey M 5af85bfe7d further clean up 2025-09-23 12:10:50 -07:00
Godfrey M 20adad3c6b fix company name link, clean up query 2025-09-23 12:09:21 -07:00
Godfrey M ca8eae4064 updated the csv values to be plain 2025-09-23 11:40:29 -07:00
Godfrey M 7077faaf4a updated the postassetAcceptanceReport query and rows 2025-09-23 11:08:37 -07:00
snipe d8171eb056 Remove duplicate PUT route for hardware assets
Removed duplicate route definition for updating hardware assets.
2025-09-23 13:24:56 +01:00
snipe c67ca500db Clarify descriptions for multiple company support 2025-09-23 13:06:33 +01:00
snipe 0081e7b731 Revise demo reproduction question in Bug Report template 2025-09-23 13:05:26 +01:00
snipe 4e6483d3ed Enhance Bug Report template with required validations
Make fields required
2025-09-23 13:04:19 +01:00
snipe 0ddf0002c4 Change dropdown options to single quotes in Bug Report
Fixed quotes
2025-09-23 13:02:36 +01:00
snipe ad0daf33b9 Add dropdown options to Bug Report template
Added additional fields to bug report template related to FMCS
2025-09-23 13:01:37 +01:00
Marcus Moore c614c44d4c Remove assigned assets from bulk checkout 2025-09-22 16:04:29 -07:00
Godfrey M ab30df10ff remove sorter from blade 2025-09-22 12:20:32 -07:00
Godfrey M a6cb75c481 remove sorter, didnt work 2025-09-22 12:19:34 -07:00
snipe 8a46579588 Merge pull request #17887 from marcusmoore/fixes/17404-prevent-bulk-checkout-across-companies
Fixed #17404 - Disallow bulk checkout of assets across companies
2025-09-22 18:57:43 +01:00
Marcus Moore fb9fb9c097 Merge branch 'develop' into fixes/17404-prevent-bulk-checkout-across-companies
# Conflicts:
#	app/Http/Controllers/Assets/BulkAssetsController.php
#	tests/Feature/Checkouts/Ui/BulkAssetCheckoutTest.php
2025-09-22 10:52:04 -07:00
snipe d9399534ce Merge pull request #17909 from spacjalex/17908-fix-typo
Fix #17908: typo in storage location of backups
2025-09-22 14:28:05 +01:00
spacjalex 17a749bbed fix typo 2025-09-22 15:23:14 +02:00
snipe 0b60c6a939 Merge remote-tracking branch 'origin/develop'
# Conflicts:
#	public/css/build/app.css
#	public/css/build/app.css.map
#	public/css/build/overrides.css
#	public/css/build/overrides.css.map
#	public/css/dist/all.css
#	public/mix-manifest.json
2025-09-19 12:44:49 +01:00
snipe 25ce63f00b Merge pull request #17904 from grokability/#17804-searchable-columns
Fixed #17804 - make columns searchable in column picker
2025-09-19 12:43:46 +01:00
snipe 2462bc05b3 Added column search to additional views 2025-09-19 12:41:30 +01:00
snipe c3748da0b1 Fixed #17804 - make columns searchable in column picker 2025-09-19 12:16:56 +01:00
snipe 90c242a441 Merge pull request #17897 from marcusmoore/fixes/17896-prevent-bulk-checkout-of-checked-out-assets
Fixed #17896 - Prevent assigned assets from being bulk checked out
2025-09-19 07:03:43 +01:00
Marcus Moore 52239a88b5 Improve test name 2025-09-18 17:27:17 -07:00
Marcus Moore 7a3596c86d Test against other types 2025-09-18 17:21:27 -07:00
Marcus Moore ac8a9e38f0 Implement fix 2025-09-18 17:18:27 -07:00
Marcus Moore 5c08f3a27e Add failing test 2025-09-18 17:14:33 -07:00
Marcus Moore 2dc11a84bf Fix test name 2025-09-18 17:05:08 -07:00
Marcus Moore 2960ea15f5 Consolidate to data provider 2025-09-18 14:29:12 -07:00
Marcus Moore 17aab4c490 Implement test 2025-09-18 14:20:05 -07:00
Marcus Moore 59d0f0d292 Re-order assertions 2025-09-18 14:05:13 -07:00
Marcus Moore 27d13a113a Implement test 2025-09-18 14:01:44 -07:00
Marcus Moore c58e999fbb Scaffold tests 2025-09-18 13:11:06 -07:00
Marcus Moore a02a96d5c4 Extract translation string 2025-09-18 12:57:56 -07:00
Marcus Moore 47e9e4704d Improve error message 2025-09-18 12:56:36 -07:00
Marcus Moore b2ad9d404e Fix re-population of assets 2025-09-18 12:38:11 -07:00
Godfrey M 51ce570eb3 attempt to sort chronologically, can not resort still 2025-09-18 11:01:40 -07:00
snipe 925d48640d Merge remote-tracking branch 'origin/develop'
# Conflicts:
#	config/version.php
2025-09-18 14:49:56 +01:00
snipe 5216dd75bf Bumped version 2025-09-18 14:49:15 +01:00
snipe 028b4e7b79 Merge remote-tracking branch 'origin/develop' 2025-09-18 13:59:25 +01:00
snipe b8b45d2d81 Merge pull request #17892 from grokability/#17891-fixes-maintenance-file-route
Fixed #17891 - missing maintenance file deletion route
2025-09-18 13:59:10 +01:00
snipe 4b2b2cb68e Fixed #17891 - missing maintenance file deletion route 2025-09-18 13:58:30 +01:00
snipe 625a46a2c2 Merge remote-tracking branch 'origin/develop' 2025-09-18 13:52:08 +01:00
snipe be4ace293e Use trans_choice for user acceptance 2025-09-18 13:51:57 +01:00
snipe ebc1e27c22 Merge remote-tracking branch 'origin/develop' 2025-09-18 13:40:07 +01:00
snipe 764b363bbc A few small tweaks to acceptance screen design 2025-09-18 13:38:37 +01:00
Marcus Moore 705474dc14 Avoid pre-loading all assets on page load 2025-09-17 16:56:37 -07:00
Marcus Moore e639d7726b Disallow bulk checkout across companies 2025-09-17 14:32:27 -07:00
snipe 357e85d358 Merge remote-tracking branch 'origin/develop' 2025-09-17 22:02:11 +01:00
snipe 9da9166442 Merge pull request #17886 from grokability/small-tweaks-to-acceptance-pdf
Small adjustments for acceptance PDF layout
2025-09-17 22:01:41 +01:00
snipe 8ea339f0ef More small tweaks 2025-09-17 22:00:49 +01:00
Marcus Moore e29b0aa6a4 Add todo 2025-09-17 13:55:54 -07:00
Marcus Moore d2157868f2 Populate failing test 2025-09-17 13:49:32 -07:00
snipe 89b36ba63f Derp. Uncomment the acceptance. 2025-09-17 21:43:40 +01:00
snipe 1d3dfa1fa4 Pull the acceptance stuff into the model 2025-09-17 21:43:17 +01:00
Marcus Moore 89cfafd933 Scaffold test 2025-09-17 13:40:34 -07:00
snipe ca567eec8a Small adjustments for layout 2025-09-17 21:08:13 +01:00
snipe 75cfcb83aa Merge remote-tracking branch 'origin/develop' 2025-09-17 14:05:06 +01:00
snipe 41da31c379 Merge pull request #17885 from grokability/#8859-show-cost-footer-on-models
Fixed #8859 - adds purchase sums on model view
2025-09-17 14:04:38 +01:00
snipe e81f63f46b Fixed #8859 - adds purchase sums on model view 2025-09-17 14:03:48 +01:00
snipe ade03e4827 Merge pull request #17882 from Godmartinz/add-total-cost-columns
Adds total cost to Accessories, Consumables, Components
2025-09-17 13:56:08 +01:00
snipe 63a4d1ad33 Merge remote-tracking branch 'origin/develop' 2025-09-17 11:44:41 +01:00
snipe 33a4c88c3a Added table to deleted_at clauses to resolve ambiguity 2025-09-17 11:44:28 +01:00
akemidx 69c5dbfc23 formatting 2025-09-17 05:39:45 -04:00
Godfrey M dcbb09bbd7 added checkoutable class 2025-09-16 15:59:53 -07:00
Godfrey M 58eac619ea add checkoutable class, rework blade for unaccepted items 2025-09-16 15:52:41 -07:00
akemidx cf1bccfd65 prep for val 2025-09-16 15:24:44 -04:00
akemidx 99acf018f1 validation rule & query 2025-09-16 15:17:59 -04:00
snipe f04d6f37e5 Merge remote-tracking branch 'origin/develop' 2025-09-16 19:22:06 +01:00
snipe 1f79776b8f Pull HTML tags out before converting markdown 2025-09-16 19:21:39 +01:00
Godfrey M 11e5f851f0 typo 2025-09-16 10:49:33 -07:00
Godfrey M 4ca1db8a1b remove footer formatter from consumable purchase cost 2025-09-16 10:43:02 -07:00
Godfrey M 14b829aa30 add total cost to components and consumables 2025-09-16 10:37:32 -07:00
Godfrey M 384652b3df add total cost to accessories 2025-09-16 10:10:49 -07:00
Brady Wetherington 92fbf83bdb Adjusting some Schema settings to match our requirements 2025-09-16 15:41:14 +01:00
Brady Wetherington 9525bbf502 Re-worked the SCIMConfig for the new version of laravel-scim-server 2025-09-16 15:22:33 +01:00
snipe 469069b471 Merge remote-tracking branch 'origin/develop' 2025-09-16 14:33:57 +01:00
snipe 9db65c6ae9 Merge pull request #17881 from grokability/#17873-eula-tab-on-users
Fixed #17873 - Added EULA tab to user view
2025-09-16 14:28:50 +01:00
snipe 1346e33e99 Check that the person trying to download can see both the user and the target 2025-09-16 14:21:03 +01:00
snipe ab9cc447aa Use more specific filename 2025-09-16 14:20:20 +01:00
akemidx cb63c12d2f i think this is gonna need livewire to validate lol 2025-09-16 08:24:22 -04:00
snipe fe9e0444b4 Added EULA tab to user view 2025-09-16 13:20:50 +01:00
akemidx 6ce0fd20ce works, needs error handling 2025-09-16 08:11:42 -04:00
snipe a18957dbe9 Include output even if there is nothing to send 2025-09-16 12:33:06 +01:00
snipe 13d5b724ee Fixed tests 2025-09-16 12:16:18 +01:00
snipe b383cd9493 Fixed CJK on labels 2025-09-16 12:10:01 +01:00
snipe c7d8203da9 Merge pull request #17866 from grokability/_reworked_tcpdf
Fixed #14744 and #17808 - Added CJK and Arabic font support for asset acceptance
2025-09-16 12:04:15 +01:00
snipe 96b5c1d8e1 Merge pull request #17876 from uberbrady/add_users_location_index
Add new index to users over deleted_at and location_id
2025-09-16 12:03:45 +01:00
Brady Wetherington 882ee80424 Add new index to users over deleted_at and location_id 2025-09-16 11:54:24 +01:00
snipe e977771fe4 One more query tweak 2025-09-16 11:50:50 +01:00
snipe 4339e4552e Fixed nesting in orWhere 2025-09-16 11:50:50 +01:00
Brady Wetherington 61df3bc462 WIP: switching to new version of laravel-scim-server 2025-09-16 11:44:10 +01:00
snipe 9bca5912d9 Merge remote-tracking branch 'origin/develop' 2025-09-16 11:39:12 +01:00
snipe b54d222943 One more query tweak 2025-09-16 11:39:02 +01:00
snipe 23756ba1c7 Merge remote-tracking branch 'origin/develop' 2025-09-16 11:27:27 +01:00
snipe e4e613550a Merge pull request #17875 from grokability/fixed-eol-query
Fixed nesting in orWhere
2025-09-16 11:27:07 +01:00
snipe d1207444db Fixed nesting in orWhere 2025-09-16 11:20:49 +01:00
Marcus Moore 06f060161d Apply offset and limit 2025-09-15 15:43:54 -07:00
Marcus Moore 73e0628124 Populate test 2025-09-15 15:26:30 -07:00
Marcus Moore 7393c4170b Apply first pass and scaffold additional test 2025-09-15 15:22:35 -07:00
Marcus Moore 73e185bf9d Scaffold route and tests 2025-09-15 15:12:05 -07:00
snipe 0bad75b263 Fixed declined asset name 2025-09-15 20:56:57 +01:00
snipe 74b98083e2 Override the getEula() method at the SnipeModel level 2025-09-15 20:05:35 +01:00
snipe 9034b5ec11 Slightly nicer display 2025-09-15 20:04:17 +01:00
Godfrey M 77153c3e78 adds Tze_24mm variant 2025-09-15 11:20:35 -07:00
snipe 927f557672 Fixed sorting on updated/created at 2025-09-15 18:13:46 +01:00
snipe 86fb089901 Remove unused blades 2025-09-15 18:13:32 +01:00
snipe 630ea05e17 A little more cleanup 2025-09-15 17:16:05 +01:00
snipe 7df5196083 A little cleanup 2025-09-15 16:09:49 +01:00
snipe 01f7b5d709 Added CJK and Arabic font support 2025-09-15 14:46:11 +01:00
snipe 07227887f6 Merge remote-tracking branch 'origin/develop' 2025-09-15 14:42:08 +01:00
snipe ec47ee3573 Merge pull request #17850 from Godmartinz/change-purchase-cost-to-unit
Rewords Purchase cost to Unit Cost for Accessories, Components, Consumables
2025-09-15 14:20:04 +01:00
snipe 13d3b103f1 Merge remote-tracking branch 'origin/develop' 2025-09-15 13:43:23 +01:00
snipe 7062962cc8 Show warnings on the dates if expired or terminated 2025-09-15 13:43:08 +01:00
snipe fde447846a Merge pull request #17865 from grokability/show-inactive-licenses
Show inactive licenses
2025-09-15 13:42:22 +01:00
snipe 319cb1bd1e Removed logging 2025-09-15 13:23:44 +01:00
snipe 58cda5ae6d Added scopes 2025-09-15 13:22:25 +01:00
snipe 251a3db880 Fixed factory 2025-09-15 13:20:34 +01:00
snipe 30b6dcd767 Added status to breadcrumbs 2025-09-15 13:13:50 +01:00
snipe 05f6622912 Added status to URL 2025-09-15 13:13:32 +01:00
snipe 36183ac19d Fixed url and tooltip text 2025-09-15 13:13:18 +01:00
snipe f6a823e0a8 Escape text 2025-09-15 13:13:04 +01:00
snipe 312353551d Changed button color 2025-09-15 13:11:58 +01:00
snipe 4bdfd0e115 Merge remote-tracking branch 'origin/develop' 2025-09-15 10:32:08 +01:00
snipe fd5c9cee38 Merge pull request #17863 from grokability/added-status-label-to-asset-view
Added status label to asset view
2025-09-15 10:31:54 +01:00
snipe 84bf71802c Added status label to asset view 2025-09-15 10:31:06 +01:00
snipe 786b20708e Merge remote-tracking branch 'origin/develop' 2025-09-15 08:38:56 +01:00
snipe 35739c2eef Merge pull request #17835 from marcusmoore/feature/10052-assigned-assets-via-api
Fixed #10052 - Added api endpoint for retrieving assets checked out to asset
2025-09-15 08:38:35 +01:00
snipe 1914a71623 Merge pull request #17851 from marcusmoore/fixes/qty-in-component-email
Fixed potentially incorrect qty in component checkout email
2025-09-15 08:37:48 +01:00
snipe dcc53886d9 Merge pull request #17857 from uberbrady/fix_client_tls_ldap
Fixed #17414 - client-side TLS certificate didn't work in Google LDAP
2025-09-15 08:37:14 +01:00
Brady Wetherington 21ef87ef09 Merge branch 'develop' into fix_client_tls_ldap 2025-09-12 18:52:43 +01:00
snipe 0e957cad84 Merge remote-tracking branch 'origin/develop' 2025-09-12 18:08:15 +01:00
snipe b67f808da9 Fixed fieldname 2025-09-12 18:07:40 +01:00
snipe ad69447b53 Merge pull request #17858 from grokability/ignore-expiring-licenses-with-past-termination-date
Ignore expiring licenses with past termination date
2025-09-12 17:55:14 +01:00
snipe b4614df88c Removed awkward period 2025-09-12 17:39:52 +01:00
snipe 7171247cdc Updated tests 2025-09-12 17:37:36 +01:00
snipe 6d0084f108 Nicer alert layout for expiring asset report 2025-09-12 17:37:27 +01:00
snipe 29359f42ae Added table printout 2025-09-12 17:37:12 +01:00
snipe cf875bf872 Changed verbiage 2025-09-12 17:37:03 +01:00
snipe 13c0d335d3 Refactor alert query 2025-09-12 17:36:51 +01:00
snipe ceb33409b5 Removed duplicate array key 2025-09-12 17:36:33 +01:00
Brady Wetherington 83597d4a8b Possible fix to client-side TLS certificate issue for google LDAP 2025-09-12 17:12:35 +01:00
Marcus Moore 81eefc5448 Merge branch 'develop' into fixes/qty-in-component-email 2025-09-11 14:14:42 -07:00
Marcus Moore 082bc3ece4 Use correct qty in component checkout email 2025-09-11 14:10:31 -07:00
snipe b2406b61fb Merge pull request #17826 from marcusmoore/fixes/17585-accessory-checkout-amount-in-subject
Fixed #17585 - Display accessory checkout qty in subject line and intro text
2025-09-11 21:55:20 +01:00
Marcus Moore 15698d7694 Update introduction lines with qty 2025-09-11 13:50:48 -07:00
Godfrey M 990cd82f97 change purchase cost to unit cost in several places 2025-09-11 10:46:20 -07:00
snipe c87829b3e8 Merge pull request #17849 from Godmartinz/rollbar-unreassignablecount-fix
Fixed typo in UnreassignableCount
2025-09-11 18:43:07 +01:00
Godfrey M 6799c41d65 fixed typo 2025-09-11 10:23:53 -07:00
snipe 80c059be58 Skip terminated licenses in alert 2025-09-11 13:14:53 +01:00
snipe aa3f896538 Merge pull request #17842 from Godmartinz/expiration-and-termination-license-enhancement
Adds #8799 Prevention of checkout of expired or terminated licenses
2025-09-11 11:46:15 +01:00
snipe 85c728f313 Merge remote-tracking branch 'origin/develop' 2025-09-11 11:40:26 +01:00
snipe d8c17a8a5e One more small tweak to language 2025-09-11 11:40:15 +01:00
akemidx 3492ed54de i'm dumb, fixed query 2025-09-10 19:05:28 -04:00
akemidx 1455281957 updated to outside window 2025-09-10 18:49:04 -04:00
akemidx 50e210b2db fixing naming convention to match 2025-09-10 17:35:09 -04:00
Godfrey M 850939367c adds translation warning message 2025-09-10 12:59:35 -07:00
Marcus Moore bf4fef9bf7 Merge branch 'develop' into fixes/17585-accessory-checkout-amount-in-subject 2025-09-10 12:49:41 -07:00
Godfrey M d5175961a4 adds a seperate formatter for checking out on license index, fix interactions 2025-09-10 12:42:10 -07:00
snipe ba3fb8cd66 Merge remote-tracking branch 'origin/develop' 2025-09-10 20:19:55 +01:00
snipe e7e1d6a232 Small tweaks to language 2025-09-10 20:17:33 +01:00
snipe 712345f3a0 Added link to discussions and discord 2025-09-10 20:14:19 +01:00
snipe 54c9bc3dcb Merge pull request #17840 from marcusmoore/issue-template
Made install method required in issue template
2025-09-10 20:14:10 +01:00
Godfrey M e796c0da4a disallows checkout of expired or terminated licenses 2025-09-10 12:08:14 -07:00
Marcus Moore cf8ff0f43e Add note on English 2025-09-10 10:41:20 -07:00
Marcus Moore e67ce23a7c Require installation method 2025-09-10 10:23:22 -07:00
snipe d9fb7dc754 Merge remote-tracking branch 'origin/develop' 2025-09-10 15:48:31 +01:00
snipe a66bb95a81 A few more tweaks 2025-09-10 15:48:21 +01:00
snipe 2249dad9d7 Merge remote-tracking branch 'origin/develop' 2025-09-10 15:43:21 +01:00
snipe c66fa33b2e Have I mentioned how much I hate YAML? 2025-09-10 15:43:09 +01:00
snipe 5c4fa630ae Merge remote-tracking branch 'origin/develop' 2025-09-10 15:40:24 +01:00
snipe 56eebb9db4 Small tweaks to templates 2025-09-10 15:40:12 +01:00
snipe ede74ad24e Merge remote-tracking branch 'origin/develop' 2025-09-10 15:38:30 +01:00
snipe d9773f107e Added feature request form
Signed-off-by: snipe <snipe@snipe.net>
2025-09-10 15:38:19 +01:00
snipe 27542a8f91 Okay, I guess we can’t require that field :(
Signed-off-by: snipe <snipe@snipe.net>
2025-09-10 15:34:30 +01:00
snipe 5dc07b94aa Merge remote-tracking branch 'origin/develop' 2025-09-10 15:33:20 +01:00
snipe e09112f46a Require installation type
Signed-off-by: snipe <snipe@snipe.net>
2025-09-10 15:33:06 +01:00
snipe d7acf721ae Merge remote-tracking branch 'origin/develop' 2025-09-10 15:30:54 +01:00
snipe 50a17a82b6 Sigh
Signed-off-by: snipe <snipe@snipe.net>
2025-09-10 15:30:42 +01:00
snipe eff5232828 Merge remote-tracking branch 'origin/develop' 2025-09-10 15:26:14 +01:00
snipe 7eb032d646 Rename issue template (I guess?)
Signed-off-by: snipe <snipe@snipe.net>
2025-09-10 15:25:51 +01:00
snipe 3eb29b1cdb Merge remote-tracking branch 'origin/develop' 2025-09-10 15:21:05 +01:00
snipe e065f22f8e Merge pull request #17838 from grokability/issue-form
New GH issue form
2025-09-10 15:20:51 +01:00
snipe c1b4ba1f85 Last one for now
Signed-off-by: snipe <snipe@snipe.net>
2025-09-10 15:20:27 +01:00
snipe eeaec471f0 Dunno if this will work
Signed-off-by: snipe <snipe@snipe.net>
2025-09-10 15:19:29 +01:00
snipe 0d3c8678d8 Moved text
Signed-off-by: snipe <snipe@snipe.net>
2025-09-10 15:17:16 +01:00
snipe bbddf5f95b Still a few more tweaks
Signed-off-by: snipe <snipe@snipe.net>
2025-09-10 15:15:09 +01:00
snipe 3b8c8b3af9 Nicer markdown
Signed-off-by: snipe <snipe@snipe.net>
2025-09-10 15:12:38 +01:00
snipe 84753aa13f Added browser console
Signed-off-by: snipe <snipe@snipe.net>
2025-09-10 15:08:37 +01:00
snipe 90b84451d8 Fixed indenting
Signed-off-by: snipe <snipe@snipe.net>
2025-09-10 15:07:04 +01:00
snipe 54c8ae41cc Still hate YAML
Signed-off-by: snipe <snipe@snipe.net>
2025-09-10 15:06:03 +01:00
snipe 7d32b1a724 God I hate YAML
Signed-off-by: snipe <snipe@snipe.net>
2025-09-10 15:05:27 +01:00
snipe 69ffd63ca6 Removed backticks
Signed-off-by: snipe <snipe@snipe.net>
2025-09-10 15:02:50 +01:00
snipe 4857c19eb6 More tweaks
Signed-off-by: snipe <snipe@snipe.net>
2025-09-10 15:02:07 +01:00
snipe d535e23da0 More template tweaks
Signed-off-by: snipe <snipe@snipe.net>
2025-09-10 14:51:33 +01:00
snipe 30e02544ab Try renaming so I can preview
via https://github.com/orgs/community/discussions/7039#discussioncomment-5327083

Signed-off-by: snipe <snipe@snipe.net>
2025-09-10 14:43:16 +01:00
snipe ee53925bd2 Starter for preview
Signed-off-by: snipe <snipe@snipe.net>
2025-09-10 14:40:38 +01:00
snipe c9961f63b4 Merge remote-tracking branch 'origin/develop' 2025-09-10 13:53:21 +01:00
snipe 40495b8a17 Small demo tweaks
Signed-off-by: snipe <snipe@snipe.net>
2025-09-10 12:33:33 +01:00
akemidx b1de98f05d first front end 2025-09-09 19:18:29 -04:00
Marcus Moore 6bc9a82a7a Formatting 2025-09-09 14:51:22 -07:00
snipe 09e843a800 Merge remote-tracking branch 'origin/develop'
Signed-off-by: snipe <snipe@snipe.net>

# Conflicts:
#	public/css/build/app.css
#	public/css/build/app.css.map
#	public/css/build/overrides.css
#	public/css/build/overrides.css.map
#	public/css/dist/all.css
#	public/mix-manifest.json
2025-09-09 22:34:33 +01:00
Marcus Moore 6504ee37bd Remove dump 2025-09-09 13:09:52 -07:00
Marcus Moore 082bff2fa8 Add and use query scope helper 2025-09-09 13:04:14 -07:00
Marcus Moore ab7bd86336 Improve assertions 2025-09-09 13:01:59 -07:00
Marcus Moore eada0b0bb5 Implement test 2025-09-09 11:58:43 -07:00
Marcus Moore f221f9f22a Implement test 2025-09-09 11:50:41 -07:00
snipe 6731e44a0d Merge pull request #17828 from marcusmoore/fixes/17586-acceptance-banner-qty
Fixed #17586 - Display accurate quantity in banner
2025-09-09 19:38:34 +01:00
Marcus Moore acc37045e4 Implement test 2025-09-09 11:34:50 -07:00
Marcus Moore a7c5899c16 Implement test 2025-09-09 11:33:54 -07:00
Marcus Moore 80b02635a9 Add test stub 2025-09-09 10:10:53 -07:00
snipe f90de5ec67 Merge pull request #17833 from grokability/tighter-controls-on-licenses
Tighter controls on license deletion, also fixes #16227 adding more tables to location print
2025-09-09 15:35:12 +01:00
snipe 9a3e046530 Fixed HTML
Signed-off-by: snipe <snipe@snipe.net>
2025-09-09 15:30:34 +01:00
snipe 7f56e461fe Added child location icon
Signed-off-by: snipe <snipe@snipe.net>
2025-09-09 15:19:00 +01:00
snipe 1da37e0d38 Added child location count
Signed-off-by: snipe <snipe@snipe.net>
2025-09-09 15:18:47 +01:00
snipe 0004d4936c Cleaned up print view
Signed-off-by: snipe <snipe@snipe.net>
2025-09-09 15:18:28 +01:00
snipe 7a6fdc4e0a Added parent ID to location API
Signed-off-by: snipe <snipe@snipe.net>
2025-09-09 15:18:09 +01:00
snipe 2eb727bd0c Added tests
Signed-off-by: snipe <snipe@snipe.net>
2025-09-09 13:51:56 +01:00
snipe 57af507170 Added deleted button to locations, check for additional relations
Signed-off-by: snipe <snipe@snipe.net>
2025-09-09 12:20:34 +01:00
snipe e37f87465c Merge pull request #17827 from Godmartinz/duplicate-emails-fix
Fixed #17756 - Duplicate checkout emails
2025-09-09 09:33:03 +01:00
Marcus Moore 324070f345 Begin to build out test 2025-09-08 17:20:22 -07:00
Marcus Moore e1aa843b6d Scaffold test 2025-09-08 17:05:14 -07:00
Godfrey M e652a7fd61 fix tests 2025-09-08 14:56:15 -07:00
Marcus Moore 2397bfbad0 Improve variable name 2025-09-08 14:51:19 -07:00
Marcus Moore 7e2bc8e452 Display accurate quantity in banner 2025-09-08 14:48:11 -07:00
Godfrey M 00e8fd0483 cloned mailable 2025-09-08 14:44:58 -07:00
Marcus Moore 6d8bf2c665 Display accessory checkout qty in subject line 2025-09-08 14:25:56 -07:00
snipe 77b79dbd95 Merge remote-tracking branch 'origin/develop' 2025-09-08 15:04:42 +01:00
snipe 72466f1aab Revert "Merge pull request #17823 from grokability/#17822-fix-n+1-in-topmenu"
This reverts commit 6901deccbf, reversing
changes made to 6b87c90e02.

Signed-off-by: snipe <snipe@snipe.net>
2025-09-08 15:04:28 +01:00
snipe dafc6c5136 Merge remote-tracking branch 'origin/develop' 2025-09-08 14:34:16 +01:00
snipe 6901deccbf Merge pull request #17823 from grokability/#17822-fix-n+1-in-topmenu
Fixed #17822 - n+1 in top menu check
2025-09-08 14:33:47 +01:00
snipe 5a9c906eb9 Added filter to assets loading
Signed-off-by: snipe <snipe@snipe.net>
2025-09-08 14:32:58 +01:00
snipe b95b60b49e Use eager-loaded model assets
Signed-off-by: snipe <snipe@snipe.net>
2025-09-08 14:07:49 +01:00
snipe 14408ef18f Fixed n+1 in top menu check
Signed-off-by: snipe <snipe@snipe.net>
2025-09-08 13:55:22 +01:00
snipe c790147a5c Merge remote-tracking branch 'origin/develop' 2025-09-08 13:33:29 +01:00
snipe 6b87c90e02 Use scope for assets for show in sidebar
Signed-off-by: snipe <snipe@snipe.net>
2025-09-08 13:33:19 +01:00
snipe 80c39c5ef3 Merge remote-tracking branch 'origin/develop' 2025-09-08 12:17:41 +01:00
snipe 2b4d5222eb Made “add new” buttons clearer on table headers
Signed-off-by: snipe <snipe@snipe.net>
2025-09-08 12:17:29 +01:00
snipe 9604ecebad Fixed jobtitle in advanced search
Signed-off-by: snipe <snipe@snipe.net>
2025-09-08 12:01:59 +01:00
snipe 9a3e84d84c Merge remote-tracking branch 'origin/develop' 2025-09-08 09:27:51 +01:00
snipe 0d67970a45 Update @swift2512 as a contributor 2025-09-08 09:27:34 +01:00
snipe 913b9f0c40 Reworks PR #15490 - adds location to inventory email
Signed-off-by: snipe <snipe@snipe.net>
2025-09-08 09:26:36 +01:00
snipe 610a5745f0 Merge pull request #17818 from grokability/dependabot/github_actions/develop/actions/stale-10
Bump actions/stale from 9 to 10
2025-09-08 09:17:19 +01:00
dependabot[bot] dff12324c6 Bump actions/stale from 9 to 10
Bumps [actions/stale](https://github.com/actions/stale) from 9 to 10.
- [Release notes](https://github.com/actions/stale/releases)
- [Changelog](https://github.com/actions/stale/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/stale/compare/v9...v10)

---
updated-dependencies:
- dependency-name: actions/stale
  dependency-version: '10'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-08 08:16:24 +00:00
snipe f340390fc8 Merge pull request #17703 from marcusmoore/17369-accessory-checkout-qty-scaffold
Fixed issues around accessory acceptance
2025-09-08 09:09:26 +01:00
snipe 643960c829 Merge remote-tracking branch 'origin/develop' 2025-09-08 08:25:08 +01:00
snipe be81e74921 Shifted log meta position
Signed-off-by: snipe <snipe@snipe.net>
2025-09-08 08:24:50 +01:00
snipe 1737018325 Merge remote-tracking branch 'origin/develop' 2025-09-08 08:14:45 +01:00
snipe 2bee8729e4 Better escaping for display_name in API controller
Signed-off-by: snipe <snipe@snipe.net>
2025-09-08 08:14:33 +01:00
snipe 5d03038734 Use auto-direction for <p> in preview
Signed-off-by: snipe <snipe@snipe.net>
2025-09-05 15:12:38 +01:00
snipe 75b11de0f4 Bumped composer packages
Signed-off-by: snipe <snipe@snipe.net>
2025-09-04 19:55:30 +01:00
snipe 484d5ba76e Merge remote-tracking branch 'origin/develop' 2025-09-04 17:15:53 +01:00
snipe c5bede8594 More small display_name fixes
Signed-off-by: snipe <snipe@snipe.net>
2025-09-04 17:15:06 +01:00
snipe 798685d0b8 Merge remote-tracking branch 'origin/develop' 2025-09-04 16:56:55 +01:00
snipe cd9ea6ae3b Fixed typo
Signed-off-by: snipe <snipe@snipe.net>
2025-09-04 16:56:43 +01:00
snipe cb7654ae90 Merge remote-tracking branch 'origin/develop' 2025-09-04 16:55:57 +01:00
snipe 113b762ec7 Fix for null location in locations print
Signed-off-by: snipe <snipe@snipe.net>
2025-09-04 16:55:44 +01:00
snipe 78704d8b85 Fixed #17803 - checked out to name in custom report
Signed-off-by: snipe <snipe@snipe.net>
2025-09-04 16:51:10 +01:00
snipe 1109db76fe Merge pull request #17797 from grokability/#17796-search-on-model-name-and-number
Fixed #17796 - search on model name and number on importer
2025-09-04 16:35:43 +01:00
snipe b1b390febf Removed flaky test
Signed-off-by: snipe <snipe@snipe.net>
2025-09-04 16:30:02 +01:00
snipe be451fa0c0 Removed asset model from original factory
Signed-off-by: snipe <snipe@snipe.net>
2025-09-04 16:14:27 +01:00
snipe 1fa553c785 Use nths
Signed-off-by: snipe <snipe@snipe.net>
2025-09-04 16:04:16 +01:00
snipe 905f61371d Fixed tests
Signed-off-by: snipe <snipe@snipe.net>
2025-09-04 16:02:40 +01:00
snipe 7da5210a01 Switched to nth from fetchOne in CSV reader
Signed-off-by: snipe <snipe@snipe.net>
2025-09-04 12:50:12 +01:00
snipe 18172d3896 Merge pull request #17752 from marcusmoore/fixes/existing-assets-report
Improve expiring alerts notification layout
2025-09-04 12:33:32 +01:00
snipe c28e78b9e2 Merge pull request #16063 from Godmartinz/checkin_non_reassignable_license
Allows check-ins of unreassignable licenses
2025-09-04 11:22:17 +01:00
snipe e7827a3847 Merge pull request #17800 from marcusmoore/chore/test-action-logs
Upload log file in GitHub Action tests
2025-09-04 10:20:12 +01:00
Marcus Moore 039564e74c Wrap migration in check 2025-09-03 12:52:46 -07:00
Marcus Moore e164595a0f Fall back to displaying 1 2025-09-03 12:35:18 -07:00
Marcus Moore d29e09a3ff Merge branch 'develop' into 17369-accessory-checkout-qty-scaffold
# Conflicts:
#	resources/views/account/accept/create.blade.php
#	resources/views/account/accept/index.blade.php
2025-09-03 12:26:43 -07:00
Godfrey M db9f85e9da Merge branch 'develop' into checkin_non_reassignable_license
# Conflicts:
#	app/Models/License.php
#	resources/views/licenses/view.blade.php
#	tests/Feature/Checkins/Api/LicenseCheckInTest.php
2025-09-03 11:09:51 -07:00
Marcus Moore 27022954b1 Inline icon 2025-09-03 10:44:19 -07:00
Marcus Moore 30362c924f Upload log as artifact 2025-09-03 10:13:01 -07:00
snipe bf63b15b46 Merge pull request #17799 from grokability/#17798-adds-require-serial-to-importer
Fixed #17798 - added `require_serial` to model importer
2025-09-03 15:32:42 +01:00
snipe 19aea4bd6c Fixed #17798 - added require_serial to model importer
Signed-off-by: snipe <snipe@snipe.net>
2025-09-03 15:25:56 +01:00
snipe 090890e9c6 Fixed #17796 - search on model name and number on importer
Signed-off-by: snipe <snipe@snipe.net>
2025-09-03 15:15:29 +01:00
snipe 00c394345a Merge remote-tracking branch 'origin/develop' 2025-09-03 15:09:42 +01:00
snipe 605022a9e3 Merge pull request #17795 from grokability/#17791-larger-currency-field
Fixed #17791 - increase size of purchase cost field
2025-09-03 15:09:28 +01:00
snipe b06c58fe7b Switch to older style rules for consistency
Signed-off-by: snipe <snipe@snipe.net>
2025-09-03 15:06:27 +01:00
snipe f5c8b3eb04 Fixed #17791 - increase size of purchase cost field
Signed-off-by: snipe <snipe@snipe.net>
2025-09-03 15:03:49 +01:00
snipe 739980aa09 Merge pull request #16947 from Godmartinz/add-require-serial-to-models
Adds require serial as Asset Model option
2025-09-03 14:53:15 +01:00
snipe afde5943e3 Fixed typo - #17784
Signed-off-by: snipe <snipe@snipe.net>
2025-09-03 14:39:59 +01:00
snipe 32300cb42c Merge pull request #17788 from grokability/add-delete-log-instead-of-soft-deleting-the-log-itself
Fixed #17777 - Log upload deletion
2025-09-03 14:37:32 +01:00
snipe dffcb62fa1 Merge remote-tracking branch 'origin/develop' 2025-09-03 14:35:31 +01:00
snipe de3b1697c8 Merge pull request #17760 from Godmartinz/fix-translation-string-in-notifications
Fixes #17759 translation used in asset check in/out notifications
2025-09-03 14:33:57 +01:00
snipe 8c668b72b7 Merge remote-tracking branch 'origin/develop' 2025-09-03 08:45:20 +01:00
snipe a18fb10b5a Merge pull request #17783 from marcusmoore/fixes/company-in-location-print
Fixed company name reference in location print
2025-09-03 08:44:40 +01:00
snipe 52140dbe06 Log upload deletion
Signed-off-by: snipe <snipe@snipe.net>
2025-09-03 08:37:42 +01:00
Marcus Moore db5bb1928e Merge branch 'develop' into fixes/existing-assets-report
# Conflicts:
#	resources/views/notifications/markdown/report-expiring-assets.blade.php
2025-09-02 15:07:23 -07:00
Marcus Moore 65b66beb07 Make icon more prominent 2025-09-02 14:55:46 -07:00
Marcus Moore c83504b4e7 Use display_name in place of presenter 2025-09-02 12:57:40 -07:00
Godfrey M cd2e7ee31d fix google and slack notifications 2025-09-02 10:53:42 -07:00
Godfrey M c3a0a0415a fix MS Teams Notifications 2025-09-02 10:48:02 -07:00
snipe 709f4672b7 Merge pull request #17771 from grokability/#10107-remember-checkout-to-type
Fixed #10107 - remember checkout to type
2025-09-02 13:46:13 +01:00
snipe b54ecd4da0 Merge remote-tracking branch 'origin/develop' 2025-09-02 13:45:41 +01:00
snipe e6c030b050 Merge pull request #17781 from grokability/#17780-add-withtrashed-to-files
Fixed #17780 - Added `withTrashed()` to allow viewing files on deleted objects
2025-09-02 13:45:18 +01:00
snipe 7bd3a791a1 Added withTrashed() to allow viewing files on deleted objects
Signed-off-by: snipe <snipe@snipe.net>
2025-09-02 13:39:35 +01:00
snipe 87a7e3501b Merge remote-tracking branch 'origin/develop' 2025-09-02 11:30:44 +01:00
snipe b9cfc03b4f display name fix
Signed-off-by: snipe <snipe@snipe.net>
2025-09-02 11:30:34 +01:00
snipe daefec3013 Merge remote-tracking branch 'origin/develop' 2025-09-01 20:32:57 +01:00
snipe 131327a64d Fixed “undefined” error on status labels in BS tables
Signed-off-by: snipe <snipe@snipe.net>
2025-09-01 20:32:42 +01:00
snipe 183a9742c4 Merge remote-tracking branch 'origin/develop' 2025-09-01 17:08:43 +01:00
snipe 77d002a158 Use null for role as well
Signed-off-by: snipe <snipe@snipe.net>
2025-09-01 16:43:05 +01:00
snipe 94699893ac Updated fieldname in user API request
Signed-off-by: snipe <snipe@snipe.net>
2025-09-01 16:17:39 +01:00
snipe 9f81989bdd Return null instead of blank for display_name in API
Signed-off-by: snipe <snipe@snipe.net>
2025-09-01 16:06:28 +01:00
snipe 15abe36c53 More tweaks to display
Signed-off-by: snipe <snipe@snipe.net>
2025-09-01 13:58:02 +01:00
snipe 3094e007ee Set session to remember checkout type
Signed-off-by: snipe <snipe@snipe.net>
2025-09-01 13:28:07 +01:00
snipe eb259aee22 Set asset selector to true for components since it will always be required
Signed-off-by: snipe <snipe@snipe.net>
2025-09-01 13:18:58 +01:00
snipe 04b83f8176 Merge remote-tracking branch 'origin/develop' 2025-09-01 12:28:40 +01:00
snipe c05c8defb9 Merge pull request #17769 from grokability/#9978-add-pivot-to-accessories-api
Fixes #9978 - Added payload to accessories API
2025-09-01 12:28:08 +01:00
snipe bf5668a42e Added payload to accessories API
Signed-off-by: snipe <snipe@snipe.net>
2025-09-01 12:23:39 +01:00
Godfrey M eadce51f10 fixes check in check out translations for assets in notiications 2025-08-29 11:12:05 -07:00
Marcus Moore 35b79e4d14 Remove old comments 2025-08-28 16:56:40 -07:00
Marcus Moore 751dad7f2e Inline days 2025-08-28 16:56:12 -07:00
Marcus Moore b08d86220a First pass at moving to table structure 2025-08-28 16:53:13 -07:00
spencerrlongg 1d24b7985b another translation change 2025-08-27 17:25:17 -05:00
spencerrlongg 526bb2c650 more translation changes 2025-08-27 17:23:46 -05:00
spencerrlongg c450c0ddb8 lots of translation changes 2025-08-27 17:17:18 -05:00
spencerrlongg 51f6927076 add details block for more than 3 errors to notification 2025-08-26 21:50:08 -05:00
akemidx e1de57384e field for number choice 2025-08-26 18:03:47 -04:00
Marcus Moore 4298aad008 Merge branch 'develop' into 17369-accessory-checkout-qty-scaffold
# Conflicts:
#	app/Http/Controllers/Account/AcceptanceController.php
#	resources/views/notifications/markdown/asset-acceptance.blade.php
2025-08-26 11:39:52 -07:00
Marcus Moore 823c67400d Fix indent 2025-08-26 11:34:10 -07:00
Marcus Moore 3160d1064d Remove unused import 2025-08-26 11:32:38 -07:00
spencerrlongg 1d88cf443f revert SuppliersController as well 2025-08-25 18:45:31 -05:00
spencerrlongg 7b6c0c3a40 Revert "tests passing, needs some manual testing"
This reverts commit fdb0651bf4.
2025-08-25 18:42:11 -05:00
spencerrlongg fdb0651bf4 tests passing, needs some manual testing 2025-08-25 18:25:36 -05:00
spencerrlongg c39d484611 rm unused import, new prop 2025-08-25 16:30:53 -05:00
spencerrlongg c42996429f rm unused import 2025-08-25 14:10:12 -05:00
spencerrlongg a091baf5a6 component finally working 2025-08-25 14:06:56 -05:00
Marcus Moore 918426a2fa Add qty to accept assets table 2025-08-21 15:49:36 -07:00
Marcus Moore c076b37c9b Add qty to accessory eula pdf 2025-08-21 15:05:24 -07:00
Marcus Moore 7c58bfa282 Add qty to AcceptanceAssetDeclinedNotification 2025-08-21 14:56:24 -07:00
Marcus Moore 0caaba156d Add qty to AcceptanceAssetAcceptedNotification 2025-08-21 14:54:43 -07:00
Marcus Moore c22575812d Add qty to AcceptanceAssetAcceptedToUserNotification 2025-08-21 14:53:00 -07:00
Marcus Moore 0ede4da816 Remove CleanDeclinedAccessoryCheckouts command 2025-08-21 14:34:31 -07:00
Marcus Moore 98e23ff92e Remove legacy testing from test 2025-08-21 14:34:16 -07:00
spencerrlongg 643d44af22 change \Throwable to \Exceptionm, add missing report()s 2025-08-20 23:09:59 -05:00
spencerrlongg b934f43db0 rename all exceptions 2025-08-20 22:58:39 -05:00
Marcus Moore c7bdad649a Build out command 2025-08-20 16:06:11 -07:00
Marcus Moore 18c2508d2f Scaffold command for cleaning accessory_checkout 2025-08-20 13:49:19 -07:00
Marcus Moore 4dcfd8b353 Improve method name 2025-08-20 13:19:00 -07:00
Marcus Moore 726116574d Improve readability? 2025-08-20 12:40:03 -07:00
Marcus Moore 27f02014ca Add failing test 2025-08-20 12:26:55 -07:00
Marcus Moore f80f1acaa7 Improve variable name 2025-08-20 12:15:58 -07:00
Marcus Moore 39d5ffeceb Implement fix 2025-08-20 12:05:58 -07:00
Marcus Moore 48ba7eed3e Remove legacy checks from test 2025-08-20 11:45:36 -07:00
Marcus Moore 9caa240fdb Revert "Remove total qty of accessory checkouts"
This reverts commit 3ffb73a516.
2025-08-19 17:17:46 -07:00
Marcus Moore 3ffb73a516 Remove total qty of accessory checkouts 2025-08-19 17:04:13 -07:00
Marcus Moore cc1132be87 Remove flakiness 2025-08-19 16:50:36 -07:00
Marcus Moore 1c31f126ef Clear some flakiness 2025-08-19 16:46:41 -07:00
Marcus Moore d8eaf2676f Add a couple of notes 2025-08-19 15:54:46 -07:00
akemidx c95462328a selected value(s) 2025-08-19 18:35:07 -04:00
akemidx 84fc89250a backend works, no save yet 2025-08-19 14:30:26 -04:00
akemidx a80f52cbf4 putting dropdown back 2025-08-18 19:47:26 -04:00
Marcus Moore 3101212c49 Continue to scaffold test 2025-08-14 17:24:36 -07:00
akemidx 7ce324a3a5 controller 2025-08-14 17:42:19 -04:00
Marcus Moore 3f0ac103a1 Scaffold test 2025-08-14 13:29:18 -07:00
Marcus Moore 59bd6ca360 Update button text 2025-08-14 13:21:11 -07:00
Marcus Moore 22fe9a786e Display number of items being accepted 2025-08-14 12:36:46 -07:00
akemidx 7624082b29 dropdown 2025-08-13 18:07:39 -04:00
Marcus Moore d2ee8de9ac Attach qty to CheckoutAcceptance 2025-08-13 12:14:10 -07:00
Marcus Moore 03d3fb6a5f Add qty to checkout_acceptances table 2025-08-13 12:09:56 -07:00
akemidx 6d3bba696a first front end bit 2025-08-12 19:14:11 -04:00
spencerrlongg e33b1b6c90 fixed maintenances 2025-08-12 13:34:40 -05:00
Spencer Long 30520297e8 Merge branch 'develop' into feature/8709-bulk-deletion-of-asset-categories-suppliers-manufacturers 2025-08-12 11:58:11 -06:00
spencerrlongg 78ca1d1335 some cleanup 2025-08-11 21:07:08 -05:00
spencerrlongg 6159ee8c2c category done! 2025-08-11 20:16:43 -05:00
spencerrlongg 5cd5392958 manufacturer completed, just categories left 2025-08-11 19:42:09 -05:00
spencerrlongg 0dcdfc5d14 fix tests after routing change 2025-08-11 19:11:40 -05:00
spencerrlongg d0e068f1c0 suppliers completely done, rinse and repeat for the other two 2025-08-11 19:04:36 -05:00
spencerrlongg 3eefeec4ce partials made, need to figure out all this jquery, button disabled 2025-08-09 22:40:00 -05:00
spencerrlongg b61419c1ce oop, revert delete 2025-08-09 22:19:28 -05:00
spencerrlongg f590fcffbc some tests, a component i probably won't use, beginning of front end 2025-08-09 22:16:23 -05:00
spencerrlongg 7cdfaa93ec a couple more tests and cleanup 2025-07-10 16:45:15 -05:00
spencerrlongg 59ccc70303 bulk changes that should make this work 2025-07-10 16:02:39 -05:00
spencerrlongg f1584b722d work on bulk tests, switching branches to check something 2025-07-10 15:29:42 -05:00
spencerrlongg 4d8c5a86a4 routes added, tests scratched but need writing 2025-07-09 23:01:58 -05:00
spencerrlongg 5f835aa009 delete unused imports 2025-07-07 18:07:26 -05:00
spencerrlongg d5ca543719 start introducing parent exception 2025-07-07 18:05:23 -05:00
Godfrey M 2b8ea9a233 add required to input validation 2025-07-07 10:46:54 -07:00
spencerrlongg db63ad1cf4 add image check to supplier action 2025-06-17 18:13:37 -05:00
spencerrlongg 5da79cd5ca destroy manufacturer action, bulk manufacturer controller 2025-06-12 17:11:45 -05:00
spencerrlongg 13c971b171 some refinements, bulk categories controller 2025-06-12 15:19:49 -05:00
spencerrlongg 1cee7e43ed more (reusable) exceptions, a couple notes 2025-06-12 00:47:57 -05:00
spencerrlongg 5e81c63d6e some notes and things moved 2025-06-11 11:39:14 -05:00
spencerrlongg 17456482d6 category destroy action 2025-06-04 21:42:58 -05:00
spencerrlongg a0431e1912 supplier actions working 2025-06-04 20:44:18 -05:00
spencerrlongg ee5aac8008 supplier destroy action creaated and a lot scratched out 2025-06-03 20:25:07 -05:00
spencerrlongg 1b397cd780 assertDbHas 2025-05-21 18:17:45 -05:00
spencerrlongg 120316bae0 wrong location import 2025-05-21 13:36:31 -05:00
spencerrlongg 7571ff007f add fillable properties to rules, some tests, move authorization to request 2025-05-21 12:51:21 -05:00
spencerrlongg 7afd7da2b4 initial work, more testing/tests needed 2025-05-21 11:44:54 -05:00
Godfrey M b0067fee51 remove some N+1s, collect an array of missing serial errors 2025-05-20 12:31:34 -07:00
Godfrey M 732c3dae89 added require_serial to model factory 2025-05-20 09:53:51 -07:00
Godfrey M d45bd67cae added corrections 2025-05-20 09:51:02 -07:00
Godfrey M 9200de5032 made require_serial column nullable 2025-05-19 09:58:37 -07:00
Godfrey M 3fbbff5a47 revert unnecessary change to laels 2025-05-14 12:57:01 -07:00
Godfrey M c22efc2c3d add to present and transformer and api 2025-05-14 12:55:41 -07:00
Godfrey M 8c0281bf70 adds tests for requiring serial to asset model 2025-05-14 12:31:27 -07:00
Godfrey M 720a4bc4a2 add warning to update method for missing a serial 2025-05-13 12:54:28 -07:00
Godfrey M 7fd93645b3 valdiation fires for asset creation 2025-05-13 12:17:58 -07:00
Godfrey M fcbfbca6d0 add checkbox to model edit and create 2025-05-13 11:10:46 -07:00
Godfrey M f2bca9491c changed name of field in model fillable 2025-05-13 10:59:02 -07:00
Godfrey M b48f309ab6 add require_serial to bulk asset model blades and lang 2025-05-13 10:58:05 -07:00
Godfrey M 0b1be3e63b add migration, model and controller update 2025-05-12 11:44:34 -07:00
Godfrey M 8c129c10af removed payload from api error message 2025-04-30 11:11:53 -07:00
Godfrey M 63ce2a14fe fix the ghosts pt2 2025-04-23 10:17:11 -07:00
Godfrey M f435ebb110 fix the ghosts 2025-04-23 10:15:26 -07:00
Godfrey M 843f001bf6 rename test class 2025-04-23 09:33:56 -07:00
Godfrey M 0d28165c04 merged develop, fix conflicts 2025-04-21 10:54:01 -07:00
Godfrey M ee31bfbcd4 Merge branch 'develop' into checkin_non_reassignable_license
# Conflicts:
#	app/Helpers/Helper.php
#	app/Http/Controllers/Api/LicenseSeatsController.php
#	app/Http/Transformers/LicensesTransformer.php
2025-04-21 10:49:35 -07:00
Godfrey M 1c67d6802d added testing to Api check in, renamed other test method 2025-01-27 12:18:24 -08:00
Godfrey M 5da8c86ec7 fix license query for bulk licenses checkin for assets 2025-01-22 10:55:41 -08:00
Godfrey Martinez 10a2d59ec1 Merge pull request #27 from Godmartinz/checkin_non_reassignable_license_cleanup
adds bulk check in of unreassinable licenses, cleans up methods used for counting.
2025-01-22 10:49:47 -08:00
Godfrey M 34e8360b10 moves counts to licenses, allows bulk check in of unreassignable licenses 2025-01-22 10:46:28 -08:00
Godfrey Martinez ca259ee4c3 Merge pull request #26 from Godmartinz/checkin_non_reassignable_license_cleanup
moved methods to licenseSeat model, clean up code, removed unused namespaces etc
2025-01-21 11:47:42 -08:00
Godfrey M 2143952a1e removed unused models, castged unreassignable_seat, clean up in general 2025-01-21 11:43:47 -08:00
Godfrey M 6bab6e7151 remove unintended change 2025-01-16 12:27:01 -08:00
Godfrey M d217c2e295 last rename 2025-01-16 12:24:32 -08:00
Godfrey M 52bf0faaa5 renamed unassignable to reassignable_seat 2025-01-16 12:19:59 -08:00
Godfrey M 3f3f2bfc61 fixed factory and test 2025-01-16 12:14:03 -08:00
Godfrey M f050864fb4 renamed dead to unassigned, replaced 0 and 1 with true and flase 2025-01-16 12:12:14 -08:00
Godfrey M db11fc35f4 fixed typo, fixed variable name 2025-01-16 12:00:49 -08:00
Godfrey M f47a2b10c0 updated column name, updated Api license checkin and out 2025-01-16 11:53:15 -08:00
Godfrey M 344b4e7d60 fixes test to check if checked in licenses is unavailable 2025-01-16 09:46:03 -08:00
Godfrey M 7a23372489 adds migration for column unavailable, changes logic to utlize value 2025-01-15 15:36:12 -08:00
Godfrey M 9da15a8e58 get button color correct 2025-01-13 14:44:26 -08:00
Godfrey M 50e0e4a07b remove unrelated change 2025-01-13 14:37:03 -08:00
Godfrey M 5e1562ae4c adds count on tabs and reports and index 2025-01-13 14:31:54 -08:00
Godfrey M 8a0ed49623 allows checkin of unreassignable license seats 2025-01-13 13:35:48 -08:00
Matthias Mair 68dad1d3ae fixed wrong index reference in MoveUploadsToNewDisk.php
usage of undefined reference fixed
2023-08-22 20:39:21 +02:00
7558 changed files with 480308 additions and 236629 deletions
+38 -1
View File
@@ -3206,7 +3206,8 @@
"avatar_url": "https://avatars.githubusercontent.com/u/3755203?v=4",
"profile": "https://github.com/swift2512",
"contributions": [
"bug"
"bug",
"code"
]
},
{
@@ -4234,6 +4235,42 @@
"contributions": [
"code"
]
},
{
"login": "smarsching",
"name": "Sebastian Marsching",
"avatar_url": "https://avatars.githubusercontent.com/u/2880129?v=4",
"profile": "http://sebastian.marsching.com/",
"contributions": [
"code"
]
},
{
"login": "mohammad-ahmadi1",
"name": "Mo",
"avatar_url": "https://avatars.githubusercontent.com/u/40658372?v=4",
"profile": "https://github.com/mohammad-ahmadi1",
"contributions": [
"code"
]
},
{
"login": "MarvelousAnything",
"name": "Owen V. Hayes",
"avatar_url": "https://avatars.githubusercontent.com/u/20994684?v=4",
"profile": "https://github.com/MarvelousAnything",
"contributions": [
"code"
]
},
{
"login": "Husky-Devel",
"name": "Peter Gallwas",
"avatar_url": "https://avatars.githubusercontent.com/u/75509373?v=4",
"profile": "https://www.husky.nz",
"contributions": [
"code"
]
}
]
}
+4
View File
@@ -137,6 +137,8 @@ PUBLIC_AWS_ACCESS_KEY_ID=null
PUBLIC_AWS_DEFAULT_REGION=null
PUBLIC_AWS_BUCKET=null
PUBLIC_AWS_URL=null
PUBLIC_AWS_ENDPOINT=null
PUBLIC_AWS_PATH_STYLE=null
PUBLIC_AWS_BUCKET_ROOT=null
# --------------------------------------------
@@ -147,6 +149,8 @@ PRIVATE_AWS_SECRET_ACCESS_KEY=null
PRIVATE_AWS_DEFAULT_REGION=null
PRIVATE_AWS_BUCKET=null
PRIVATE_AWS_URL=null
PRIVATE_AWS_ENDPOINT=null
PRIVATE_AWS_PATH_STYLE=null
PRIVATE_AWS_BUCKET_ROOT=null
# --------------------------------------------
+4
View File
@@ -144,6 +144,8 @@ PUBLIC_AWS_ACCESS_KEY_ID=null
PUBLIC_AWS_DEFAULT_REGION=null
PUBLIC_AWS_BUCKET=null
PUBLIC_AWS_URL=null
PUBLIC_AWS_ENDPOINT=null
PUBLIC_AWS_PATH_STYLE=null
PUBLIC_AWS_BUCKET_ROOT=null
# --------------------------------------------
@@ -154,6 +156,8 @@ PRIVATE_AWS_SECRET_ACCESS_KEY=null
PRIVATE_AWS_DEFAULT_REGION=null
PRIVATE_AWS_BUCKET=null
PRIVATE_AWS_URL=null
PRIVATE_AWS_ENDPOINT=null
PRIVATE_AWS_PATH_STYLE=null
PRIVATE_AWS_BUCKET_ROOT=null
# --------------------------------------------
+38 -2
View File
@@ -40,12 +40,26 @@ DB_SANITIZE_BY_DEFAULT=false
# --------------------------------------------
# OPTIONAL: SSL DATABASE SETTINGS
# --------------------------------------------
# Enable SSL connection to database (true/false)
DB_SSL=false
# Set to true for cloud databases like AWS RDS, Azure Database, Google Cloud SQL
# Set to false for self-hosted databases with client certificates
DB_SSL_IS_PAAS=false
# Required when DB_SSL_IS_PAAS=false (client certificate authentication)
DB_SSL_KEY_PATH=null
DB_SSL_CERT_PATH=null
# Path to CA certificate bundle (required for SSL connections)
# For AWS RDS, download from: https://truststore.pki.rds.amazonaws.com/global/global-bundle.pem
DB_SSL_CA_PATH=null
# SSL cipher (optional, leave null for default)
DB_SSL_CIPHER=null
# Verify server certificate (true/false, defaults to false if not set)
# Set to false for development or when using self-signed certificates
DB_SSL_VERIFY_SERVER=null
# --------------------------------------------
@@ -76,7 +90,16 @@ IMAGE_LIB=gd
# --------------------------------------------
# OPTIONAL: BACKUP SETTINGS
# --------------------------------------------
# Backup filesystem configuration
# - BACKUP_FILESYSTEM_DRIVER: Driver to use (local, s3, etc.)
# Default: local (backward compatible)
# Set to s3 to use S3 for backups (requires PRIVATE_AWS_* credentials)
# - BACKUP_FILESYSTEM_ROOT: Root path/prefix
# For local driver: leave commented for default to storage_path("app")
# For S3 driver: empty string = bucket root, or specify prefix like "backups/"
#--------------------------------------------
BACKUP_FILESYSTEM_DRIVER=local
#BACKUP_FILESYSTEM_ROOT=
MAIL_BACKUP_NOTIFICATION_DRIVER=null
MAIL_BACKUP_NOTIFICATION_ADDRESS=null
BACKUP_ENV=true
@@ -135,6 +158,14 @@ REDIS_PORT=null
MEMCACHED_HOST=null
MEMCACHED_PORT=null
# --------------------------------------------
# OPTIONAL: S3 PROXY
# When enabled, public uploads (images, logos, avatars) are served through
# the application instead of directly from S3. This allows using a single
# fully private S3 bucket for all storage.
# --------------------------------------------
PUBLIC_S3_PROXY=false
# --------------------------------------------
# OPTIONAL: PUBLIC S3 Settings
# --------------------------------------------
@@ -143,6 +174,8 @@ PUBLIC_AWS_ACCESS_KEY_ID=null
PUBLIC_AWS_DEFAULT_REGION=null
PUBLIC_AWS_BUCKET=null
PUBLIC_AWS_URL=null
PUBLIC_AWS_ENDPOINT=null
PUBLIC_AWS_PATH_STYLE=null
PUBLIC_AWS_BUCKET_ROOT=null
# --------------------------------------------
@@ -153,6 +186,8 @@ PRIVATE_AWS_SECRET_ACCESS_KEY=null
PRIVATE_AWS_DEFAULT_REGION=null
PRIVATE_AWS_BUCKET=null
PRIVATE_AWS_URL=null
PRIVATE_AWS_ENDPOINT=null
PRIVATE_AWS_PATH_STYLE=null
PRIVATE_AWS_BUCKET_ROOT=null
# --------------------------------------------
@@ -190,13 +225,14 @@ APP_ALLOW_INSECURE_HOSTS=false
GOOGLE_MAPS_API=
LDAP_MEM_LIM=500M
LDAP_TIME_LIM=600
BACKUP_TIME_LIMIT=600
IMPORT_TIME_LIMIT=600
IMPORT_MEMORY_LIMIT=500M
REPORT_TIME_LIMIT=12000
API_THROTTLE_PER_MINUTE=120
CSV_ESCAPE_FORMULAS=true
LIVEWIRE_URL_PREFIX=null
MAX_UNPAGINATED=5000
# --------------------------------------------
# OPTIONAL: SAML SETTINGS
+66
View File
@@ -0,0 +1,66 @@
# Pint: Models
9623fa4d87e7fb38307028338c6991afb7d4e099
# Pint: Actions
a3c7410c35388af08997b1c52adebda1056488a6
# Pint: Console
8bce38b9187d23089a28a4f3a4ab960ac7471e90
# Pint: Enums and Events
f7b82ad1ff513a25d775c20b58e9a8ce23461ec2
# Pint: Exceptions
2e7046a810ce1f7562dec9d3ee4fee0cbc7262db
# Pint: Non-api controllers
9bc92f57c8a29ac0e89c2d3f72f23c6c64567dd8
# Pint: Api controllers
1e5d426e70dcd72fd7e87c2b11ff42fe3cc7a1a4
# Pint: Middleware
ec6caf9b5959c6c57bd7be047e91bbb70fc303a7
# Pint: Requests
93168326da54fa87880570c82df3ccbf3ff152e1
# Pint: Traits and Transformers
a613380811f63f51e2951d2f4b8454d5274d5cdf
# Pint: Importer
3e831bf9b3cc060f11c88ec69a9313131de8ee1f
# Pint: Jobs and Listeners
317b1a462e079bf96d492dd3782de38b7144be9f
# Pint: Livewire
53f2ef2ca11b0571de758b101f08f259de7830cf
# Pint: Mail
de607e7d83704b30f809238c44d3d759196a77db
# Pint: Notifications
31043d1f5cb5d287c0ab2ca2ba1ae08665bc6ad5
# Pint: Observers and policies
b2c0a21230977443536655e43e524773e2ad9e27
# Pint: Presenters
55d46cbefec5fe0bb7e28b859d540977d2cfee46
# Pint: Providers
8b658a19b9182bf9a19e34bc9101ee11a13ed85b
# Pint: Config
c1a93e3ac890ed1fc1c27ba6c431f6b58ff661d6
# Pint: Lang and resources
84fdb5d6c19bf7882cb91d42fe8768fc0db0ce67
# Pint: Database
b5a46a370f85c6e87c8a9fa4a4593424bb027712
# Pint: Tests
d84eb43278177a9bcdfffe04c94d933eb49f2c48
446f5f3cefdc1837a65fd4bc983741b29f821a78
+163
View File
@@ -0,0 +1,163 @@
name: Bug Report
description: File a bug report.
title: "[Bug]: "
projects: ["grokability/snipe-it"]
type: bug
body:
- type: markdown
attributes:
value: |
Thanks for taking the time to fill out this bug report! Most issues are documented in the [Snipe-IT repository's issues](https://github.com/grokability/snipe-it/issues) or in the official [Common Issues section of the Documentation](https://snipe-it.readme.io/docs/common-issues#/) and are due to the following:
- `.env` misconfiguration
- [Server Permissions](https://snipe-it.readme.io/docs/debugging-permissions#/)
- [Database Migrations](https://snipe-it.readme.io/docs/database-issues#run-migrations)
Please make sure you've checked these resources before submitting a new issue. If you find an existing issue, please add your context to it instead of opening a new issue. If your issue is more of a question, consider [opening a new discussion](https://github.com/grokability/snipe-it/discussions) or [pop by our Discord](https://discord.gg/yZFtShAcKk) instead of creating an issue.
**Please write your bug report in English.** You can use tools like [DeepL](https://www.deepl.com) or [Google Translate](https://translate.google.com/) to translate if necessary.
**If you choose to upload screenshots or videos (which we always encourage), please make sure they do not contain any sensitive information.**
- type: input
id: version
attributes:
label: Snipe-IT Version
description: What version of Snipe-IT are you seeing this issue on? You can find the version number in the footer of any page in Snipe-IT.
placeholder: ex. v8.3.2 - build 19577 (master)
validations:
required: true
- type: input
id: php-version
attributes:
label: PHP Version
description: What version of PHP are you running? You can find the version of PHP your webserver is running in the `Admin Settings` section in the footer, and the cli version by running `php -v` via command line .
placeholder: ex. v8.3.1 (web), PHP 8.4.12 (cli)
validations:
required: true
- type: input
id: composer-version
attributes:
label: Composer Version
description: What version of composer are you running? You can find the version number by running `composer --version`.
placeholder: ex. 2.8.10
validations:
required: true
- type: input
id: db-version
attributes:
label: MySQL/MariaDB version
description: What database are you using, and what version?
placeholder: ex. MySQL 5.7
validations:
required: true
- type: dropdown
id: install-method
attributes:
label: How did you install Snipe-IT?
options:
- Git install
- Manual install (downloading zip/tar.gz)
- Docker
- install.sh
- Hosted by Grokability
- Other
- Not sure
validations:
required: true
- type: dropdown
id: upgrade-or-fresh
attributes:
label: Is this a fresh install or an upgrade?
options:
- Fresh install
- Upgrade
- NA
validations:
required: true
- type: textarea
id: what-happened
attributes:
label: What happened?
description: Also tell us, what did you expect to happen?
placeholder: Tell us what you see! (Be nice!)
validations:
required: true
- type: dropdown
id: browsers
attributes:
label: What browsers are you seeing the problem on?
multiple: true
options:
- Firefox
- Chrome
- Safari
- Microsoft Edge
- Other
- type: dropdown
id: on-demo
attributes:
label: Can you reproduce this on the public demo?
description: You can check this at https://demo.snipeitapp.com.
options:
- 'Yes'
- 'No'
- N/A
validations:
required: true
- type: dropdown
id: fmcs
attributes:
label: Do you have full multiple company support enabled?
description: You can check this in your Snipe-IT installation at `Admin Settings > General Settings > Scoping`.
options:
- 'Yes'
- 'No'
validations:
required: true
- type: dropdown
id: fmcs-location
attributes:
label: If you have full multiple company support enabled, do you have location scoping to company enabled?
description: You can check this in your Snipe-IT installation at `Admin Settings > General Settings > Scoping`.
options:
- 'Yes'
- 'No'
- I do not have full multiple company support enabled
validations:
required: true
- type: textarea
id: server-logs
attributes:
label: Application log output
description: Please copy and paste any relevant log output from `storage/logs/laravel.log`. This will be automatically formatted into code, so no need for backticks.
render: shell
- type: textarea
id: browser-logs
attributes:
label: Browser console output
description: Please copy and paste any relevant log output from your browser console. This will be automatically formatted into code, so no need for backticks.
render: shell
- type: checkboxes
id: common-issues
attributes:
label: Common Issues
description: Please make sure you have done the following before submitting your issue.
options:
- label: I have searched this repo for existing issues related to my issue (including closed issues)
required: true
- label: My APP_URL is set correctly in my .env file (including http or https and no trailing slash)
required: true
- label: I have searched the official Snipe-IT documentation and have checked the Common Issues documentation (where applicable)
required: true
- label: I have run database migrations (where applicable).
required: true
- label: I have attached screenshots and/or videos of the issue (where applicable)
required: true
- type: checkboxes
id: terms
attributes:
label: Code of Conduct
description: By submitting this issue, you agree to follow our [Code of Conduct](https://github.com/grokability/snipe-it/blob/master/CODE_OF_CONDUCT.md).
options:
- label: I agree to follow this project's Code of Conduct
required: true
@@ -0,0 +1,38 @@
name: Feature Request
description: Request a new feature.
title: "[Feature]: "
projects: ["grokability/snipe-it"]
type: feature
body:
- type: markdown
attributes:
value: |
Thanks for taking the time to fill out this feature request! Please make sure to search the existing issues in this repository to see if your feature has already been requested, and feel free to add your context to any existing requests.
**Please write your issue in English.** You can use tools like [DeepL](https://www.deepl.com) or [Google Translate](https://translate.google.com/) to translate if necessary.
**If you choose to upload screenshots or videos (which we always encourage), please make sure they do not contain any sensitive information.**
- type: input
id: version
attributes:
label: Snipe-IT Version
description: What version of Snipe-IT are you currently running? You can find the version number in the footer of any page in Snipe-IT.
placeholder: ex. v8.3.1 - build 19577 (master)
validations:
required: true
- type: textarea
id: feature-description
attributes:
label: How can we help?
description: Let us know in detail what feature you'd like to see added. While we can't promise to implement every feature request, we do read every one and take them into consideration when planning future releases.
placeholder: Tell us what you'd like to see in Snipe-IT! (Be nice!)
validations:
required: true
- type: checkboxes
id: terms
attributes:
label: Code of Conduct
description: By submitting this issue, you agree to follow our [Code of Conduct](https://github.com/grokability/snipe-it/blob/master/CODE_OF_CONDUCT.md).
options:
- label: I agree to follow this project's Code of Conduct
required: true
+4 -3
View File
@@ -1,10 +1,11 @@
frontend: ["*.js", "*.css", "*.vue", "*.scss", "*.less", "*.blade.*", "resources/views/livewire/*"]
frontend: ["*.js", "*.css", "*.scss", "*.less", "*.blade.*", "resources/views/livewire/*","resources/views/layouts/default.blade.php"]
skins: ["*.js", "*.css", "*.scss", "*.less"]
css: ["*.css","*.scss", "*.less"]
javascript: ["*.js", "package.json", "package.lock"]
backend: ["/app/*", "composer.json", "composer.lock"]
translations: ["/resources/lang"]
translations: ["/resources/lang/*"]
livewire: ["/app/Http/Livewire/*", "resources/views/livewire/*"]
blade-components: ["resources/views/blade/*"]
backups: ["*backup*"]
restore: ["*restore*"]
saml: ["*saml*"]
@@ -16,7 +17,7 @@ api: ["/app/Http/Controllers/Api/*"]
notifications: ["/app/Notifications/*"]
importer: ["/app/Importer/*","/app/Http/Livewire/Importer.php", "resources/views/livewire/importer.php"]
cli / artisan: ["/app/Console/*"]
LDAP: ["*Ldap*", "/app/Console/Commands/Ldap*","/app/Models/Ldap.php"]
LDAP: ["*Ldap*", "/app/Console/Commands/Ldap*","/app/Models/Ldap.php", "/resources/views/users/ldap.blade.php","/resources/views/settings/ldap.blade.php"]
docker: ["*docker/*", "Dockerfile", "Dockerfile.alpine", "Dockerfile.fpm-alpine", ".dockerignore", ".env.docker"]
tests: ["/tests/*", "/database/factories/*", "/stubs"]
config: .github
+117
View File
@@ -0,0 +1,117 @@
# GitHub Copilot Custom Instructions for Snipe-IT
These instructions guide Copilot to generate code that aligns with modern Laravel 11 standards, PHP 8.2/8.4 features, software engineering principles, and industry best practices to improve software quality, maintainability, and security.
## ✅ General Coding Standards
- Prefer short, expressive, and readable code.
- Use **meaningful, descriptive variable, function, class, and file names**.
- Apply proper PHPDoc blocks for classes, methods, and complex logic.
- Organize code into small, reusable functions or classes with single responsibility.
- Avoid magic numbers or hard-coded strings; use constants or config files.
## ✅ PHP 8.2/8.4 Best Practices
- Use **readonly properties** to enforce immutability where applicable.
- Use **Enums** instead of string or integer constants.
- Utilize **First-class callable syntax** for callbacks.
- Leverage **Constructor Property Promotion**.
- Use **Union Types**, **Intersection Types**, and **true/false return types** for strict typing.
- Apply **Static Return Type** where needed.
- Use the **Nullsafe Operator (?->)** for optional chaining.
- Adopt **final classes** where extension is not intended.
- Use **Named Arguments** for improved clarity when calling functions with multiple parameters.
## ✅ Laravel 11 Project Structure & Conventions
- Follow the official Laravel project structure:
- `app/Http/Controllers` - Controllers
- `app/Models` - Eloquent models
- `app/Http/Requests` - Form request validation
- `app/Http/Resources` - API resource responses
- `app/Enums` - Enums
- `app/Actions` - Single-responsibility action classes
- `app/Policies` - Authorization logic
- Controllers must:
- Use dependency injection.
- Use Form Requests for validation. The request class should utilize the rules set on the model.
- Return typed responses (e.g., `JsonResponse`).
- Use Transformers for API responses.
## ✅ Eloquent ORM & Database
- Use **Eloquent Models** with proper `$fillable` or `$guarded` attributes for mass assignment protection.
- Utilize **casts** for date, boolean, JSON, and custom data types.
- Apply **accessors & mutators** for attribute transformation.
- Avoid direct raw SQL unless absolutely necessary; prefer Eloquent or Query Builder.
- Migrations:
- Always use migrations for schema changes.
- Include proper constraints (foreign keys, unique indexes, etc.).
- Prefer UUIDs or ULIDs as primary keys where applicable.
## ✅ API Development
- Use **Transformer classes** for consistent and structured JSON responses.
- Apply **route model binding** where possible.
- Use Form Requests for input validation.
## ✅ Blade & Frontend (if applicable)
- Keep Blade templates clean and logic-free; use View Composers or dedicated View Models for complex data.
- Use `@props`, `@aware`, `@once` Blade features appropriately.
- Utilize Alpine.js or Livewire for interactive frontend logic (optional).
## ✅ Security Best Practices
- Never trust user input; always validate and sanitize inputs.
- Use prepared statements via Eloquent or Query Builder to prevent SQL injection.
- Use Laravel's built-in CSRF, XSS, and validation mechanisms.
- Store sensitive information in `.env`, never hard-code secrets.
- Apply proper authorization checks using Policies or Gates.
- Follow principle of least privilege for users, roles, and permissions.
## ✅ Testing Standards
- Use **factories** for test data setup.
- Include feature tests for user-facing functionality.
- Include unit tests for business logic, services, and helper classes.
- Mock external services using Laravel's `Http::fake()` or equivalent.
- Maintain high code coverage but focus on meaningful tests over 100% coverage obsession.
## ✅ Software Quality & Maintainability
- Follow **SOLID Principles**:
- Single Responsibility Principle (SRP)
- Open/Closed Principle (OCP)
- Liskov Substitution Principle (LSP)
- Interface Segregation Principle (ISP)
- Dependency Inversion Principle (DIP)
- Follow **DRY** (Don't Repeat Yourself) and **KISS** (Keep It Simple, Stupid) principles.
- Apply **YAGNI** (You Aren't Gonna Need It) to avoid overengineering.
- Document complex logic with PHPDoc and inline comments.
## ✅ Performance & Optimization
- Eager load relationships to avoid N+1 queries.
- Use caching with Laravel's Cache system for frequently accessed data.
- Paginate large datasets using `paginate()` instead of `get()`.
- Queue long-running tasks using Laravel Queues.
- Optimize database indexes for common queries.
## ✅ Modern Laravel Features to Use
- Use **Event Broadcasting** if real-time updates are needed.
- Use **Full-text search** if search functionality is required.
- Use **Rate Limiting** for API routes.
## ✅ Additional Copilot Behavior Preferences
- Generate **strictly typed**, modern PHP code using latest language features.
- Prioritize **readable, clean, maintainable** code over cleverness.
- Avoid legacy or deprecated Laravel patterns (facade overuse, logic-heavy views, etc.).
- Suggest proper class placement based on Laravel directory structure.
- Suggest tests alongside new features where applicable.
- Default to **immutability**, **dependency injection**, and **encapsulation** best practices.
No newline at end of file
+4 -4
View File
@@ -26,14 +26,14 @@ jobs:
language: [ 'javascript' ]
steps:
- name: Checkout repository
uses: actions/checkout@v5
uses: actions/checkout@v6
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v3
uses: github/codeql-action/init@v4
with:
languages: ${{ matrix.language }}
- name: Autobuild
uses: github/codeql-action/autobuild@v3
uses: github/codeql-action/autobuild@v4
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v3
uses: github/codeql-action/analyze@v4
-57
View File
@@ -1,57 +0,0 @@
# This workflow checks out code, performs a Codacy security scan
# and integrates the results with the
# GitHub Advanced Security code scanning feature. For more information on
# the Codacy security scan action usage and parameters, see
# https://github.com/codacy/codacy-analysis-cli-action.
# For more information on Codacy Analysis CLI in general, see
# https://github.com/codacy/codacy-analysis-cli.
name: Codacy Security Scan
on:
push:
branches: [ develop ]
pull_request:
# The branches below must be a subset of the branches above
branches: [ develop ]
schedule:
- cron: '36 23 * * 3'
permissions:
contents: read
jobs:
codacy-security-scan:
# Ensure schedule job never runs on forked repos. It's only executed for 'grokability/snipe-it'
permissions:
contents: read # for actions/checkout to fetch code
security-events: write # for github/codeql-action/upload-sarif to upload SARIF results
if: (github.repository == 'grokability/snipe-it') || ((github.repository != 'grokability/snipe-it') && (github.event_name != 'schedule'))
name: Codacy Security Scan
runs-on: ubuntu-latest
steps:
# Checkout the repository to the GitHub Actions runner
- name: Checkout code
uses: actions/checkout@v5
# Execute Codacy Analysis CLI and generate a SARIF output with the security issues identified during the analysis
- name: Run Codacy Analysis CLI
uses: codacy/codacy-analysis-cli-action@v4.4.7
with:
# Check https://github.com/codacy/codacy-analysis-cli#project-token to get your project token from your Codacy repository
# You can also omit the token and run the tools that support default configurations
project-token: ${{ secrets.CODACY_PROJECT_TOKEN }}
verbose: true
output: results.sarif
format: sarif
# Adjust severity of non-security issues
gh-code-scanning-compat: true
# Force 0 exit code to allow SARIF file generation
# This will handover control about PR rejection to the GitHub side
max-allowed-issues: 2147483647
# Upload the SARIF file generated in the previous step
- name: Upload SARIF results file
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: results.sarif
+1 -1
View File
@@ -9,7 +9,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v5
uses: actions/checkout@v6
- name: Crowdin push
uses: crowdin/github-action@v2
+5 -5
View File
@@ -42,17 +42,17 @@ jobs:
steps:
# https://github.com/actions/checkout
- name: Checkout codebase
uses: actions/checkout@v5
uses: actions/checkout@v6
# https://github.com/docker/setup-buildx-action
- name: Setup Docker Buildx
uses: docker/setup-buildx-action@v3
uses: docker/setup-buildx-action@v4
# https://github.com/docker/login-action
- name: Login to DockerHub
# Only login if not a PR, as PRs only trigger a Docker build and not a push
if: github.event_name != 'pull_request'
uses: docker/login-action@v3
uses: docker/login-action@v4
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_ACCESS_TOKEN }}
@@ -64,7 +64,7 @@ jobs:
# Get Metadata for docker_build step below
- name: Sync metadata (tags, labels) from GitHub to Docker for 'snipe-it' image
id: meta_build
uses: docker/metadata-action@v5
uses: docker/metadata-action@v6
with:
images: snipe/snipe-it
tags: ${{ env.IMAGE_TAGS }}
@@ -73,7 +73,7 @@ jobs:
# https://github.com/docker/build-push-action
- name: Build and push 'snipe-it' image
id: docker_build
uses: docker/build-push-action@v6
uses: docker/build-push-action@v7
with:
context: .
file: ./Dockerfile.alpine
+5 -5
View File
@@ -42,17 +42,17 @@ jobs:
steps:
# https://github.com/actions/checkout
- name: Checkout codebase
uses: actions/checkout@v5
uses: actions/checkout@v6
# https://github.com/docker/setup-buildx-action
- name: Setup Docker Buildx
uses: docker/setup-buildx-action@v3
uses: docker/setup-buildx-action@v4
# https://github.com/docker/login-action
- name: Login to DockerHub
# Only login if not a PR, as PRs only trigger a Docker build and not a push
if: github.event_name != 'pull_request'
uses: docker/login-action@v3
uses: docker/login-action@v4
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_ACCESS_TOKEN }}
@@ -64,7 +64,7 @@ jobs:
# Get Metadata for docker_build step below
- name: Sync metadata (tags, labels) from GitHub to Docker for 'snipe-it' image
id: meta_build
uses: docker/metadata-action@v5
uses: docker/metadata-action@v6
with:
images: snipe/snipe-it
tags: ${{ env.IMAGE_TAGS }}
@@ -73,7 +73,7 @@ jobs:
# https://github.com/docker/build-push-action
- name: Build and push 'snipe-it' image
id: docker_build
uses: docker/build-push-action@v6
uses: docker/build-push-action@v7
with:
context: .
file: ./Dockerfile
+1 -1
View File
@@ -11,7 +11,7 @@ jobs:
dockerHubDescription:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v6
- name: Docker Hub Description
uses: grokability/dockerhub-description@7ea9d275c7cdbe2b676a093a0308c50665e3b8b4
+69
View File
@@ -0,0 +1,69 @@
# This workflow uses actions that are not certified by GitHub.
# They are provided by a third-party and are governed by
# separate terms of service, privacy policy, and support
# documentation.
# EthicalCheck addresses the critical need to continuously security test APIs in development and in production.
# EthicalCheck provides the industrys only free & automated API security testing service that uncovers security vulnerabilities using OWASP API list.
# Developers relies on EthicalCheck to evaluate every update and release, ensuring that no APIs go to production with exploitable vulnerabilities.
# You develop the application and API, we bring complete and continuous security testing to you, accelerating development.
# Know your API and Applications are secure with EthicalCheck our free & automated API security testing service.
# How EthicalCheck works?
# EthicalCheck functions in the following simple steps.
# 1. Security Testing.
# Provide your OpenAPI specification or start with a public Postman collection URL.
# EthicalCheck instantly instrospects your API and creates a map of API endpoints for security testing.
# It then automatically creates hundreds of security tests that are non-intrusive to comprehensively and completely test for authentication, authorizations, and OWASP bugs your API. The tests addresses the OWASP API Security categories including OAuth 2.0, JWT, Rate Limit etc.
# 2. Reporting.
# EthicalCheck generates security test report that includes all the tested endpoints, coverage graph, exceptions, and vulnerabilities.
# Vulnerabilities are fully triaged, it contains CVSS score, severity, endpoint information, and OWASP tagging.
# This is a starter workflow to help you get started with EthicalCheck Actions
name: EthicalCheck-Workflow
# Controls when the workflow will run
on:
# Triggers the workflow on push or pull request events but only for the "master" branch
# Customize trigger events based on your DevSecOps processes.
push:
branches: [ "master" ]
pull_request:
branches: [ "master" ]
schedule:
- cron: '35 17 * * 6'
# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:
permissions:
contents: read
jobs:
Trigger_EthicalCheck:
permissions:
security-events: write # for github/codeql-action/upload-sarif to upload SARIF results
actions: read # only required for a private repository by github/codeql-action/upload-sarif to get the Action run status
runs-on: ubuntu-latest
steps:
- name: EthicalCheck Free & Automated API Security Testing Service
uses: apisec-inc/ethicalcheck-action@005fac321dd843682b1af6b72f30caaf9952c641
with:
# The OpenAPI Specification URL or Swagger Path or Public Postman collection URL.
oas-url: "http://netbanking.apisec.ai:8080/v2/api-docs"
# The email address to which the penetration test report will be sent.
email: "snipe@snipe.net"
sarif-result-file: "ethicalcheck-results.sarif"
- name: Upload sarif file to repository
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: ./ethicalcheck-results.sarif
+1 -1
View File
@@ -11,7 +11,7 @@ jobs:
issues: write
# pull-requests: write
steps:
- uses: actions/stale@v9
- uses: actions/stale@v10
with:
debug-only: true
ascending: true
+15 -2
View File
@@ -28,6 +28,7 @@ jobs:
- "8.2"
- "8.3"
- "8.4"
- "8.5"
name: PHP ${{ matrix.php-version }}
@@ -37,13 +38,13 @@ jobs:
php-version: "${{ matrix.php-version }}"
coverage: none
- uses: actions/checkout@v5
- uses: actions/checkout@v6
- name: Get Composer Cache Directory
id: composer-cache
run: |
echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT
- uses: actions/cache@v4
- uses: actions/cache@v5
with:
path: ${{ steps.composer-cache.outputs.dir }}
key: ${{ runner.os }}-${{ matrix.php-version }}-composer-${{ hashFiles('**/composer.lock') }}
@@ -76,4 +77,16 @@ jobs:
DB_DATABASE: snipeit
DB_PORT: ${{ job.services.mysql.ports[3306] }}
DB_USERNAME: root
LOG_CHANNEL: single
LOG_LEVEL: debug
run: php artisan test
- name: Upload Laravel logs as artifacts
if: always()
uses: actions/upload-artifact@v7
with:
name: laravel-logs-php-${{ matrix.php-version }}-run-${{ github.run_attempt }}
path: |
storage/logs/*.log
if-no-files-found: ignore
retention-days: 7
+15 -2
View File
@@ -24,6 +24,7 @@ jobs:
- "8.2"
- "8.3"
- "8.4"
- "8.5"
name: PHP ${{ matrix.php-version }}
@@ -34,13 +35,13 @@ jobs:
php-version: "${{ matrix.php-version }}"
coverage: none
- uses: actions/checkout@v5
- uses: actions/checkout@v6
- name: Get Composer Cache Directory
id: composer-cache
run: |
echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT
- uses: actions/cache@v4
- uses: actions/cache@v5
with:
path: ${{ steps.composer-cache.outputs.dir }}
key: ${{ runner.os }}-${{ matrix.php-version }}-composer-${{ hashFiles('**/composer.lock') }}
@@ -75,4 +76,16 @@ jobs:
DB_PORT: ${{ job.services.postgresql.ports[5432] }}
DB_USERNAME: snipeit
DB_PASSWORD: password
LOG_CHANNEL: single
LOG_LEVEL: debug
run: php artisan test
- name: Upload Laravel logs as artifacts
if: always()
uses: actions/upload-artifact@v7
with:
name: laravel-logs-php-${{ matrix.php-version }}-run-${{ github.run_attempt }}
path: |
storage/logs/*.log
if-no-files-found: ignore
retention-days: 7
+15 -3
View File
@@ -15,7 +15,7 @@ jobs:
fail-fast: false
matrix:
php-version:
- "8.3"
- "8.5"
name: PHP ${{ matrix.php-version }}
@@ -25,13 +25,13 @@ jobs:
php-version: "${{ matrix.php-version }}"
coverage: none
- uses: actions/checkout@v5
- uses: actions/checkout@v6
- name: Get Composer Cache Directory
id: composer-cache
run: |
echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT
- uses: actions/cache@v4
- uses: actions/cache@v5
with:
path: ${{ steps.composer-cache.outputs.dir }}
key: ${{ runner.os }}-${{ matrix.php-version }}-composer-${{ hashFiles('**/composer.lock') }}
@@ -61,4 +61,16 @@ jobs:
- name: Execute tests (Unit and Feature tests) via PHPUnit
env:
DB_CONNECTION: sqlite
LOG_CHANNEL: single
LOG_LEVEL: debug
run: php artisan test
- name: Upload Laravel logs as artifacts
if: always()
uses: actions/upload-artifact@v7
with:
name: laravel-logs-php-${{ matrix.php-version }}-run-${{ github.run_attempt }}
path: |
storage/logs/*.log
if-no-files-found: ignore
retention-days: 7
+8 -8
View File
@@ -1,10 +1,10 @@
{
"DOC1": "This file is meant to be pulled from the current HEAD of the desired branch, NOT referenced locally",
"DOC2": "In other words, what you see locally are the requirements for your _current_ install",
"DOC3": "Please don't rely on these versions for planning upgrades unless you've fetched the most recent version",
"DOC4": "You should really just ignore it and run upgrade.php. Really",
"php_min_version": "8.2.0",
"php_max_major_minor": "8.4",
"php_max_wontwork": "8.5.0",
"current_snipeit_version": "8.0"
"DOC1": "This file is meant to be pulled from the current HEAD of the desired branch, NOT referenced locally",
"DOC2": "In other words, what you see locally are the requirements for your _current_ install",
"DOC3": "Please don't rely on these versions for planning upgrades unless you've fetched the most recent version",
"DOC4": "You should really just ignore it and run upgrade.php. Really",
"php_min_version": "8.2.0",
"php_max_major_minor": "8.5",
"php_max_wontwork": "8.6.0",
"current_snipeit_version": "8.0"
}
+110
View File
@@ -0,0 +1,110 @@
# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## Stack
- **PHP 8.2+** / **Laravel 12** (framework), **Laravel Mix** (webpack) for frontend assets
- **AdminLTE 2** / **Bootstrap 3** UI — Blade views, no Livewire/Inertia
- **Chart.js v2.9.4** — bundled at `public/js/dist/Chart.min.js`; use `horizontalBar` type (v2 API, not v3)
## Common Commands
```bash
# Run all tests
php artisan test
# or
vendor/bin/phpunit
# Run a single test file
php artisan test tests/Feature/Assets/AssetsTest.php
# Run a specific test method
php artisan test --filter testSomeMethod
# Build frontend assets (dev)
npm run dev
# Build for production
npm run prod
# Laravel Mix watch
npm run watch
# Tinker / REPL
php artisan tinker
# Clear caches after config/route changes
php artisan optimize:clear
```
Dev server is served via **Laravel Herd** (`herd coverage` for coverage reports).
## Architecture
### Controllers
Two parallel controller trees:
- `app/Http/Controllers/` — web/UI controllers (Blade views)
- `app/Http/Controllers/Api/` — REST API controllers (JSON, used by datatables + select2)
Subdirectory groupings: `Assets/`, `Licenses/`, `Users/`, `Accessories/`, `Consumables/`, `Components/`, `Kits/`, `Account/`, `Auth/`
### API Pattern
Every API controller returns data via a **Transformer** (`app/Http/Transformers/`). Never return raw model attributes from API controllers — always pass through the transformer. `DatatablesTransformer` wraps paginated results.
```php
return (new AssetsTransformer)->transformAssets($assets, $assets->count());
```
### Authorization
All authorization goes through **Policies** (`app/Policies/`). `CheckoutablePermissionsPolicy` is the base for assets/licenses/accessories/consumables — its `checkout()` / `checkin()` methods accept `$item = null` so you can use `@can('checkout', \App\Models\Asset::class)` without an instance.
### FMCS (Full Multiple Company Support)
`Setting::getSettings()->full_multiple_companies_support == '1'` gates company-scoped filtering. The select2 API endpoints (`selectlist()` methods) accept a `companyId` query param — apply it like this:
```php
if ((Setting::getSettings()->full_multiple_companies_support == '1') && ($request->filled('companyId'))) {
$query->where('table.company_id', $request->input('companyId'));
}
```
Pass `data-company-id="{{ $user->company_id }}"` in Blade to wire it to select2.
### Select2 AJAX Dropdowns
Use `class="js-data-ajax"` with `data-endpoint="hardware|licenses|consumables|..."`. `snipeit.js` auto-initializes these, forwarding `data-company-id` as `companyId` and `data-asset-status-type` as `statusType` to the API.
### Routes
All routes are in `routes/web.php` (UI) and `routes/api.php` (API). Breadcrumbs are defined inline using `->breadcrumbs(fn (Trail $trail) => ...)` from `tabuna/breadcrumbs`. Every UI route should have a breadcrumb.
Note: the `reports/unaccepted_assets` route is named with slashes, not dots — use `route('reports/unaccepted_assets')`.
### Translations
String keys live in `resources/lang/en-US/general.php` (and other files in that directory). Always add new UI strings as translation keys rather than hard-coding English.
### Checkout Redirect Flow
After checkout, `Helper::getRedirectOption()` reads `$request->redirect_option`. For redirecting back to the assigned user after checkout:
- Set `redirect_option=target` in the form
- Set `checkout_to_type=user` in the form
- Set `assigned_user={{ $user->id }}` in the form
### Key Helper Methods (`app/Helpers/Helper.php`)
- `Helper::deployableStatusLabelList()` — status labels for checkout forms
- `Helper::defaultChartColors()` — 10-color palette used in charts
- `Helper::getRedirectOption($request, $id, $table)` — post-checkout redirect logic
### Global View Variables
`$snipeSettings` is injected into all views via a service provider — no need to pass `Setting::getSettings()` from every controller. Use it directly in Blade.
## Testing
Tests live in `tests/Feature/` (organized by entity) and `tests/Unit/`. Feature tests hit the database; the test environment uses `array` cache/session/mail drivers. Tests use factories for data setup.
+3 -2
View File
@@ -52,7 +52,7 @@ Thanks goes to all of these wonderful people ([emoji key](https://github.com/ken
| [<img src="https://avatars.githubusercontent.com/u/2565989?v=4" width="110px;"/><br /><sub>coach1988</sub>](https://github.com/coach1988)<br />[💻](https://github.com/snipe/snipe-it/commits?author=coach1988 "Code") | [<img src="https://avatars.githubusercontent.com/u/11910225?v=4" width="110px;"/><br /><sub>MrM</sub>](https://github.com/mauro-miatello)<br />[💻](https://github.com/snipe/snipe-it/commits?author=mauro-miatello "Code") | [<img src="https://avatars.githubusercontent.com/u/60405354?v=4" width="110px;"/><br /><sub>koiakoia</sub>](https://github.com/koiakoia)<br />[💻](https://github.com/snipe/snipe-it/commits?author=koiakoia "Code") | [<img src="https://avatars.githubusercontent.com/u/5323832?v=4" width="110px;"/><br /><sub>Mustafa Online</sub>](https://github.com/mustafa-online)<br />[💻](https://github.com/snipe/snipe-it/commits?author=mustafa-online "Code") | [<img src="https://avatars.githubusercontent.com/u/104601439?v=4" width="110px;"/><br /><sub>franceslui</sub>](https://github.com/franceslui)<br />[💻](https://github.com/snipe/snipe-it/commits?author=franceslui "Code") | [<img src="https://avatars.githubusercontent.com/u/125313163?v=4" width="110px;"/><br /><sub>Q4kK</sub>](https://github.com/Q4kK)<br />[💻](https://github.com/snipe/snipe-it/commits?author=Q4kK "Code") | [<img src="https://avatars.githubusercontent.com/u/55590532?v=4" width="110px;"/><br /><sub>squintfox</sub>](https://github.com/squintfox)<br />[💻](https://github.com/snipe/snipe-it/commits?author=squintfox "Code") |
| [<img src="https://avatars.githubusercontent.com/u/1380084?v=4" width="110px;"/><br /><sub>Jeff Clay</sub>](https://github.com/jeffclay)<br />[💻](https://github.com/snipe/snipe-it/commits?author=jeffclay "Code") | [<img src="https://avatars.githubusercontent.com/u/52716446?v=4" width="110px;"/><br /><sub>Phil J R</sub>](https://github.com/PP-JN-RL)<br />[💻](https://github.com/snipe/snipe-it/commits?author=PP-JN-RL "Code") | [<img src="https://avatars.githubusercontent.com/u/1496725?v=4" width="110px;"/><br /><sub>i_virus</sub>](https://www.corelight.com/)<br />[💻](https://github.com/snipe/snipe-it/commits?author=chandanchowdhury "Code") | [<img src="https://avatars.githubusercontent.com/u/1020541?v=4" width="110px;"/><br /><sub>Paul Grime</sub>](https://github.com/gitgrimbo)<br />[💻](https://github.com/snipe/snipe-it/commits?author=gitgrimbo "Code") | [<img src="https://avatars.githubusercontent.com/u/922815?v=4" width="110px;"/><br /><sub>Lee Porte</sub>](https://leeporte.co.uk)<br />[💻](https://github.com/snipe/snipe-it/commits?author=LeePorte "Code") | [<img src="https://avatars.githubusercontent.com/u/23613427?v=4" width="110px;"/><br /><sub>BRYAN </sub>](https://github.com/bryanlopezinc)<br />[💻](https://github.com/snipe/snipe-it/commits?author=bryanlopezinc "Code") [⚠️](https://github.com/snipe/snipe-it/commits?author=bryanlopezinc "Tests") | [<img src="https://avatars.githubusercontent.com/u/64061710?v=4" width="110px;"/><br /><sub>U-H-T</sub>](https://github.com/U-H-T)<br />[💻](https://github.com/snipe/snipe-it/commits?author=U-H-T "Code") |
| [<img src="https://avatars.githubusercontent.com/u/5395363?v=4" width="110px;"/><br /><sub>Matt Tyree</sub>](https://github.com/Tyree)<br />[📖](https://github.com/snipe/snipe-it/commits?author=Tyree "Documentation") | [<img src="https://avatars.githubusercontent.com/u/292081?v=4" width="110px;"/><br /><sub>Florent Bervas</sub>](http://spoontux.net)<br />[💻](https://github.com/snipe/snipe-it/commits?author=FlorentDotMe "Code") | [<img src="https://avatars.githubusercontent.com/u/4498077?v=4" width="110px;"/><br /><sub>Daniel Albertsen</sub>](https://ditscheri.com)<br />[💻](https://github.com/snipe/snipe-it/commits?author=dbakan "Code") | [<img src="https://avatars.githubusercontent.com/u/100710244?v=4" width="110px;"/><br /><sub>r-xyz</sub>](https://github.com/r-xyz)<br />[💻](https://github.com/snipe/snipe-it/commits?author=r-xyz "Code") | [<img src="https://avatars.githubusercontent.com/u/47491036?v=4" width="110px;"/><br /><sub>Steven Mainor</sub>](https://github.com/DrekiDegga)<br />[💻](https://github.com/snipe/snipe-it/commits?author=DrekiDegga "Code") | [<img src="https://avatars.githubusercontent.com/u/65785975?v=4" width="110px;"/><br /><sub>arne-kroeger</sub>](https://github.com/arne-kroeger)<br />[💻](https://github.com/snipe/snipe-it/commits?author=arne-kroeger "Code") | [<img src="https://avatars.githubusercontent.com/u/167117705?v=4" width="110px;"/><br /><sub>Glukose1</sub>](https://github.com/Glukose1)<br />[💻](https://github.com/snipe/snipe-it/commits?author=Glukose1 "Code") |
| [<img src="https://avatars.githubusercontent.com/u/1197791?v=4" width="110px;"/><br /><sub>Scarzy</sub>](https://github.com/Scarzy)<br />[💻](https://github.com/snipe/snipe-it/commits?author=Scarzy "Code") | [<img src="https://avatars.githubusercontent.com/u/37372069?v=4" width="110px;"/><br /><sub>setpill</sub>](https://github.com/setpill)<br />[💻](https://github.com/snipe/snipe-it/commits?author=setpill "Code") | [<img src="https://avatars.githubusercontent.com/u/3755203?v=4" width="110px;"/><br /><sub>swift2512</sub>](https://github.com/swift2512)<br />[🐛](https://github.com/snipe/snipe-it/issues?q=author%3Aswift2512 "Bug reports") | [<img src="https://avatars.githubusercontent.com/u/6136439?v=4" width="110px;"/><br /><sub>Darren Rainey</sub>](https://darrenraineys.co.uk)<br />[💻](https://github.com/snipe/snipe-it/commits?author=DarrenRainey "Code") | [<img src="https://avatars.githubusercontent.com/u/133033121?v=4" width="110px;"/><br /><sub>maciej-poleszczyk</sub>](https://github.com/maciej-poleszczyk)<br />[💻](https://github.com/snipe/snipe-it/commits?author=maciej-poleszczyk "Code") | [<img src="https://avatars.githubusercontent.com/u/143394709?v=4" width="110px;"/><br /><sub>Sebastian Groß</sub>](https://github.com/sgross-emlix)<br />[💻](https://github.com/snipe/snipe-it/commits?author=sgross-emlix "Code") | [<img src="https://avatars.githubusercontent.com/u/41107778?v=4" width="110px;"/><br /><sub>Anouar Touati</sub>](https://github.com/AnouarTouati)<br />[💻](https://github.com/snipe/snipe-it/commits?author=AnouarTouati "Code") |
| [<img src="https://avatars.githubusercontent.com/u/1197791?v=4" width="110px;"/><br /><sub>Scarzy</sub>](https://github.com/Scarzy)<br />[💻](https://github.com/snipe/snipe-it/commits?author=Scarzy "Code") | [<img src="https://avatars.githubusercontent.com/u/37372069?v=4" width="110px;"/><br /><sub>setpill</sub>](https://github.com/setpill)<br />[💻](https://github.com/snipe/snipe-it/commits?author=setpill "Code") | [<img src="https://avatars.githubusercontent.com/u/3755203?v=4" width="110px;"/><br /><sub>swift2512</sub>](https://github.com/swift2512)<br />[🐛](https://github.com/snipe/snipe-it/issues?q=author%3Aswift2512 "Bug reports") [💻](https://github.com/snipe/snipe-it/commits?author=swift2512 "Code") | [<img src="https://avatars.githubusercontent.com/u/6136439?v=4" width="110px;"/><br /><sub>Darren Rainey</sub>](https://darrenraineys.co.uk)<br />[💻](https://github.com/snipe/snipe-it/commits?author=DarrenRainey "Code") | [<img src="https://avatars.githubusercontent.com/u/133033121?v=4" width="110px;"/><br /><sub>maciej-poleszczyk</sub>](https://github.com/maciej-poleszczyk)<br />[💻](https://github.com/snipe/snipe-it/commits?author=maciej-poleszczyk "Code") | [<img src="https://avatars.githubusercontent.com/u/143394709?v=4" width="110px;"/><br /><sub>Sebastian Groß</sub>](https://github.com/sgross-emlix)<br />[💻](https://github.com/snipe/snipe-it/commits?author=sgross-emlix "Code") | [<img src="https://avatars.githubusercontent.com/u/41107778?v=4" width="110px;"/><br /><sub>Anouar Touati</sub>](https://github.com/AnouarTouati)<br />[💻](https://github.com/snipe/snipe-it/commits?author=AnouarTouati "Code") |
| [<img src="https://avatars.githubusercontent.com/u/25596663?v=4" width="110px;"/><br /><sub>aHVzY2g</sub>](https://github.com/aHVzY2g)<br />[💻](https://github.com/snipe/snipe-it/commits?author=aHVzY2g "Code") | [<img src="https://avatars.githubusercontent.com/u/13408130?v=4" width="110px;"/><br /><sub>林博仁 Buo-ren Lin</sub>](https://brlin.me)<br />[💻](https://github.com/snipe/snipe-it/commits?author=brlin-tw "Code") | [<img src="https://avatars.githubusercontent.com/u/18550946?v=4" width="110px;"/><br /><sub>Adugna Gizaw</sub>](https://orbalia.pythonanywhere.com/)<br />[🌍](#translation-addex12 "Translation") | [<img src="https://avatars.githubusercontent.com/u/760989?v=4" width="110px;"/><br /><sub>Jesse Ostrander</sub>](https://github.com/jostrander)<br />[💻](https://github.com/snipe/snipe-it/commits?author=jostrander "Code") | [<img src="https://avatars.githubusercontent.com/u/31522486?v=4" width="110px;"/><br /><sub>James M</sub>](https://github.com/azmcnutt)<br />[💻](https://github.com/snipe/snipe-it/commits?author=azmcnutt "Code") | [<img src="https://avatars.githubusercontent.com/u/5183146?v=4" width="110px;"/><br /><sub>Fiala06</sub>](https://github.com/Fiala06)<br />[💻](https://github.com/snipe/snipe-it/commits?author=Fiala06 "Code") | [<img src="https://avatars.githubusercontent.com/u/28693782?v=4" width="110px;"/><br /><sub>Nathan Taylor</sub>](https://github.com/ntaylor-86)<br />[💻](https://github.com/snipe/snipe-it/commits?author=ntaylor-86 "Code") |
| [<img src="https://avatars.githubusercontent.com/u/16699443?v=4" width="110px;"/><br /><sub>fvollmer</sub>](https://github.com/fvollmer)<br />[💻](https://github.com/snipe/snipe-it/commits?author=fvollmer "Code") | [<img src="https://avatars.githubusercontent.com/u/109086466?v=4" width="110px;"/><br /><sub>36864</sub>](https://github.com/36864)<br />[💻](https://github.com/snipe/snipe-it/commits?author=36864 "Code") | [<img src="https://avatars.githubusercontent.com/u/365751?v=4" width="110px;"/><br /><sub>Daniel O'Connor</sub>](http://clockwerx.blogspot.com/)<br />[💻](https://github.com/snipe/snipe-it/commits?author=CloCkWeRX "Code") | [<img src="https://avatars.githubusercontent.com/u/102852568?v=4" width="110px;"/><br /><sub>BeatSpark</sub>](https://github.com/BeatSpark)<br />[💻](https://github.com/snipe/snipe-it/commits?author=BeatSpark "Code") | [<img src="https://avatars.githubusercontent.com/u/59203607?v=4" width="110px;"/><br /><sub>mrdahbi</sub>](https://github.com/mrdahbi)<br />[💻](https://github.com/snipe/snipe-it/commits?author=mrdahbi "Code") | [<img src="https://avatars.githubusercontent.com/u/6661332?v=4" width="110px;"/><br /><sub>Fabian Schmid</sub>](http://sr.solutions)<br />[💻](https://github.com/snipe/snipe-it/commits?author=chfsx "Code") | [<img src="https://avatars.githubusercontent.com/u/1288116?v=4" width="110px;"/><br /><sub>Chris Olin</sub>](https://www.chrisolin.com)<br />[💻](https://github.com/snipe/snipe-it/commits?author=realchrisolin "Code") |
| [<img src="https://avatars.githubusercontent.com/u/3803132?v=4" width="110px;"/><br /><sub>Dan</sub>](https://github.com/mnemonicly)<br />[💻](https://github.com/snipe/snipe-it/commits?author=mnemonicly "Code") | [<img src="https://avatars.githubusercontent.com/u/43917728?v=4" width="110px;"/><br /><sub>Nebel</sub>](https://github.com/NebelKreis)<br />[💻](https://github.com/snipe/snipe-it/commits?author=NebelKreis "Code") | [<img src="https://avatars.githubusercontent.com/u/132433803?v=4" width="110px;"/><br /><sub>test1337ahp</sub>](https://github.com/test1337ahp)<br />[💻](https://github.com/snipe/snipe-it/commits?author=test1337ahp "Code") | [<img src="https://avatars.githubusercontent.com/u/1916566?v=4" width="110px;"/><br /><sub>Jonathon Reinhart</sub>](https://github.com/JonathonReinhart)<br />[💻](https://github.com/snipe/snipe-it/commits?author=JonathonReinhart "Code") | [<img src="https://avatars.githubusercontent.com/u/484742?v=4" width="110px;"/><br /><sub>aranar-pro</sub>](https://github.com/aranar-pro)<br />[💻](https://github.com/snipe/snipe-it/commits?author=aranar-pro "Code") | [<img src="https://avatars.githubusercontent.com/u/27019397?v=4" width="110px;"/><br /><sub>Phil</sub>](https://github.com/phil-flip)<br />[💻](https://github.com/snipe/snipe-it/commits?author=phil-flip "Code") | [<img src="https://avatars.githubusercontent.com/u/6473460?v=4" width="110px;"/><br /><sub>Steffy Fort</sub>](https://fe80.fr/)<br />[💻](https://github.com/snipe/snipe-it/commits?author=fe80 "Code") |
@@ -68,7 +68,8 @@ Thanks goes to all of these wonderful people ([emoji key](https://github.com/ken
| [<img src="https://avatars.githubusercontent.com/u/181059?v=4" width="110px;"/><br /><sub>Juan Font</sub>](https://github.com/juanfont)<br />[💻](https://github.com/snipe/snipe-it/commits?author=juanfont "Code") | [<img src="https://avatars.githubusercontent.com/u/13137708?v=4" width="110px;"/><br /><sub>Juho Taipale</sub>](https://github.com/juhotaipale)<br />[💻](https://github.com/snipe/snipe-it/commits?author=juhotaipale "Code") | [<img src="https://avatars.githubusercontent.com/u/1007419?v=4" width="110px;"/><br /><sub>Korvin Szanto</sub>](https://github.com/KorvinSzanto)<br />[💻](https://github.com/snipe/snipe-it/commits?author=KorvinSzanto "Code") | [<img src="https://avatars.githubusercontent.com/u/8513053?v=4" width="110px;"/><br /><sub>Lewis Foster</sub>](https://lewisfoster.foo/)<br />[💻](https://github.com/snipe/snipe-it/commits?author=sniff122 "Code") | [<img src="https://avatars.githubusercontent.com/u/33877541?v=4" width="110px;"/><br /><sub>Logan Swartzendruber</sub>](https://github.com/loganswartz)<br />[💻](https://github.com/snipe/snipe-it/commits?author=loganswartz "Code") | [<img src="https://avatars.githubusercontent.com/u/1156208?v=4" width="110px;"/><br /><sub>Lorenzo P.</sub>](https://github.com/lopezio)<br />[💻](https://github.com/snipe/snipe-it/commits?author=lopezio "Code") | [<img src="https://avatars.githubusercontent.com/u/33946590?v=4" width="110px;"/><br /><sub>Lukas Jung</sub>](https://github.com/m4us1ne)<br />[💻](https://github.com/snipe/snipe-it/commits?author=m4us1ne "Code") |
| [<img src="https://avatars.githubusercontent.com/u/10965027?v=4" width="110px;"/><br /><sub>Ellie</sub>](https://leafedfox.xyz/)<br />[💻](https://github.com/snipe/snipe-it/commits?author=LeafedFox "Code") | [<img src="https://avatars.githubusercontent.com/u/20960555?v=4" width="110px;"/><br /><sub>GA Stamper</sub>](https://github.com/gastamper)<br />[💻](https://github.com/snipe/snipe-it/commits?author=gastamper "Code") | [<img src="https://avatars.githubusercontent.com/u/206553556?v=4" width="110px;"/><br /><sub>Guillaume Lefranc</sub>](https://github.com/gl-pup)<br />[💻](https://github.com/snipe/snipe-it/commits?author=gl-pup "Code") | [<img src="https://avatars.githubusercontent.com/u/733892?v=4" width="110px;"/><br /><sub>Hajo Möller</sub>](https://github.com/dasjoe)<br />[💻](https://github.com/snipe/snipe-it/commits?author=dasjoe "Code") | [<img src="https://avatars.githubusercontent.com/u/3420063?v=4" width="110px;"/><br /><sub>Istvan Basa</sub>](https://github.com/pottom)<br />[💻](https://github.com/snipe/snipe-it/commits?author=pottom "Code") | [<img src="https://avatars.githubusercontent.com/u/810824?v=4" width="110px;"/><br /><sub>JJ Asghar</sub>](https://jjasghar.github.io/)<br />[💻](https://github.com/snipe/snipe-it/commits?author=jjasghar "Code") | [<img src="https://avatars.githubusercontent.com/u/40404495?v=4" width="110px;"/><br /><sub>James E. Msenga</sub>](https://github.com/JemCdo)<br />[💻](https://github.com/snipe/snipe-it/commits?author=JemCdo "Code") |
| [<img src="https://avatars.githubusercontent.com/u/6865786?v=4" width="110px;"/><br /><sub>Jan Felix Wiebe</sub>](https://github.com/jfwiebe)<br />[💻](https://github.com/snipe/snipe-it/commits?author=jfwiebe "Code") | [<img src="https://avatars.githubusercontent.com/u/43412008?v=4" width="110px;"/><br /><sub>Jo Drexl</sub>](https://www.nfon.com/)<br />[💻](https://github.com/snipe/snipe-it/commits?author=drexljo "Code") | [<img src="https://avatars.githubusercontent.com/u/4807843?v=4" width="110px;"/><br /><sub>Austin Sasko</sub>](https://github.com/austinsasko)<br />[💻](https://github.com/snipe/snipe-it/commits?author=austinsasko "Code") | [<img src="https://avatars.githubusercontent.com/u/4875039?v=4" width="110px;"/><br /><sub>Jasson</sub>](http://jassoncordones.github.io)<br />[💻](https://github.com/snipe/snipe-it/commits?author=JassonCordones "Code") | [<img src="https://avatars.githubusercontent.com/u/76069640?v=4" width="110px;"/><br /><sub>Okean</sub>](https://github.com/Tinyblargon)<br />[💻](https://github.com/snipe/snipe-it/commits?author=Tinyblargon "Code") | [<img src="https://avatars.githubusercontent.com/u/6515064?v=4" width="110px;"/><br /><sub>Alejandro Medrano</sub>](https://www.lst.tfo.upm.es/alejandro-medrano/)<br />[💻](https://github.com/snipe/snipe-it/commits?author=amedranogil "Code") | [<img src="https://avatars.githubusercontent.com/u/58696401?v=4" width="110px;"/><br /><sub>Lukas Kraic</sub>](https://github.com/lukaskraic)<br />[💻](https://github.com/snipe/snipe-it/commits?author=lukaskraic "Code") |
| [<img src="https://avatars.githubusercontent.com/u/1571724?v=4" width="110px;"/><br /><sub>Герхард PICCORO Lenz McKAY </sub>](https://github-readme-stats.vercel.app/api?username=mckaygerhard)<br />[💻](https://github.com/snipe/snipe-it/commits?author=mckaygerhard "Code") | [<img src="https://avatars.githubusercontent.com/u/15015119?v=4" width="110px;"/><br /><sub>Johannes Pollitt</sub>](https://github.com/FlorestanII)<br />[💻](https://github.com/snipe/snipe-it/commits?author=FlorestanII "Code") | [<img src="https://avatars.githubusercontent.com/u/14185442?v=4" width="110px;"/><br /><sub>Michael Strobel</sub>](https://strobelm.de)<br />[💻](https://github.com/snipe/snipe-it/commits?author=strobelm "Code") | [<img src="https://avatars.githubusercontent.com/u/634790?v=4" width="110px;"/><br /><sub>Nicky West</sub>](http://nickwest.me)<br />[💻](https://github.com/snipe/snipe-it/commits?author=nickwest "Code") | [<img src="https://avatars.githubusercontent.com/u/1347327?v=4" width="110px;"/><br /><sub>akaspeh1</sub>](https://github.com/akaspeh1)<br />[💻](https://github.com/snipe/snipe-it/commits?author=akaspeh1 "Code") |
| [<img src="https://avatars.githubusercontent.com/u/1571724?v=4" width="110px;"/><br /><sub>Герхард PICCORO Lenz McKAY </sub>](https://github-readme-stats.vercel.app/api?username=mckaygerhard)<br />[💻](https://github.com/snipe/snipe-it/commits?author=mckaygerhard "Code") | [<img src="https://avatars.githubusercontent.com/u/15015119?v=4" width="110px;"/><br /><sub>Johannes Pollitt</sub>](https://github.com/FlorestanII)<br />[💻](https://github.com/snipe/snipe-it/commits?author=FlorestanII "Code") | [<img src="https://avatars.githubusercontent.com/u/14185442?v=4" width="110px;"/><br /><sub>Michael Strobel</sub>](https://strobelm.de)<br />[💻](https://github.com/snipe/snipe-it/commits?author=strobelm "Code") | [<img src="https://avatars.githubusercontent.com/u/634790?v=4" width="110px;"/><br /><sub>Nicky West</sub>](http://nickwest.me)<br />[💻](https://github.com/snipe/snipe-it/commits?author=nickwest "Code") | [<img src="https://avatars.githubusercontent.com/u/1347327?v=4" width="110px;"/><br /><sub>akaspeh1</sub>](https://github.com/akaspeh1)<br />[💻](https://github.com/snipe/snipe-it/commits?author=akaspeh1 "Code") | [<img src="https://avatars.githubusercontent.com/u/2880129?v=4" width="110px;"/><br /><sub>Sebastian Marsching</sub>](http://sebastian.marsching.com/)<br />[💻](https://github.com/snipe/snipe-it/commits?author=smarsching "Code") | [<img src="https://avatars.githubusercontent.com/u/40658372?v=4" width="110px;"/><br /><sub>Mo</sub>](https://github.com/mohammad-ahmadi1)<br />[💻](https://github.com/snipe/snipe-it/commits?author=mohammad-ahmadi1 "Code") |
| [<img src="https://avatars.githubusercontent.com/u/20994684?v=4" width="110px;"/><br /><sub>Owen V. Hayes</sub>](https://github.com/MarvelousAnything)<br />[💻](https://github.com/snipe/snipe-it/commits?author=MarvelousAnything "Code") | [<img src="https://avatars.githubusercontent.com/u/75509373?v=4" width="110px;"/><br /><sub>Peter Gallwas</sub>](https://www.husky.nz)<br />[💻](https://github.com/snipe/snipe-it/commits?author=Husky-Devel "Code") |
<!-- ALL-CONTRIBUTORS-LIST:END -->
This project follows the [all-contributors](https://github.com/kentcdodds/all-contributors) specification. Contributions of any kind welcome!
+30 -30
View File
@@ -1,35 +1,35 @@
FROM alpine:3.19
FROM alpine:3.23
# Apache + PHP
RUN apk add --no-cache \
apache2 \
php82 \
php82-common \
php82-apache2 \
php82-curl \
php82-ldap \
php82-mysqli \
php82-gd \
php82-xml \
php82-mbstring \
php82-zip \
php82-ctype \
php82-tokenizer \
php82-pdo_mysql \
php82-openssl \
php82-bcmath \
php82-phar \
php82-json \
php82-iconv \
php82-fileinfo \
php82-simplexml \
php82-session \
php82-dom \
php82-xmlwriter \
php82-xmlreader \
php82-sodium \
php82-redis \
php82-pecl-memcached \
php82-exif \
php84 \
php84-common \
php84-apache2 \
php84-curl \
php84-ldap \
php84-mysqli \
php84-gd \
php84-xml \
php84-mbstring \
php84-zip \
php84-ctype \
php84-tokenizer \
php84-pdo_mysql \
php84-openssl \
php84-bcmath \
php84-phar \
php84-json \
php84-iconv \
php84-fileinfo \
php84-simplexml \
php84-session \
php84-dom \
php84-xmlwriter \
php84-xmlreader \
php84-sodium \
php84-redis \
php84-pecl-memcached \
php84-exif \
curl \
wget \
vim \
@@ -42,7 +42,7 @@ COPY docker/column-statistics.cnf /etc/mysql/conf.d/column-statistics.cnf
# Where apache's PID lives
RUN mkdir -p /run/apache2 && chown apache:apache /run/apache2
RUN sed -i 's/variables_order = .*/variables_order = "EGPCS"/' /etc/php82/php.ini
RUN sed -i 's/variables_order = .*/variables_order = "EGPCS"/' /etc/php84/php.ini
COPY docker/000-default-2.4.conf /etc/apache2/conf.d/default.conf
# Enable mod_rewrite
+6 -3
View File
@@ -1,13 +1,13 @@
![snipe-it-by-grok](https://github.com/grokability/snipe-it/assets/197404/b515673b-c7c8-4d9a-80f5-9fa58829a602)
[![Crowdin](https://d322cqt584bo4o.cloudfront.net/snipe-it/localized.svg)](https://crowdin.com/project/snipe-it) [![Docker Pulls](https://img.shields.io/docker/pulls/snipe/snipe-it.svg)](https://hub.docker.com/r/snipe/snipe-it/) [![Codacy Badge](https://app.codacy.com/project/badge/Grade/804dd1beb14a41f38810ab77d64fc4fc)](https://app.codacy.com/gh/grokability/snipe-it/dashboard?utm_source=gh&utm_medium=referral&utm_content=&utm_campaign=Badge_grade) [![Tests](https://github.com/grokability/snipe-it/actions/workflows/tests.yml/badge.svg)](https://github.com/grokability/snipe-it/actions/workflows/tests.yml)
[![Crowdin](https://d322cqt584bo4o.cloudfront.net/snipe-it/localized.svg)](https://crowdin.com/project/snipe-it) [![Docker Pulls](https://img.shields.io/docker/pulls/snipe/snipe-it.svg)](https://hub.docker.com/r/snipe/snipe-it/) [![Tests in MySQL](https://github.com/grokability/snipe-it/actions/workflows/tests-mysql.yml/badge.svg)](https://github.com/grokability/snipe-it/actions/workflows/tests-mysql.yml)
[![All Contributors](https://img.shields.io/badge/all_contributors-331-orange.svg?style=flat-square)](#contributing) [![Discord](https://badgen.net/badge/icon/discord?icon=discord&label)](https://discord.gg/yZFtShAcKk)
## Snipe-IT - Open Source Asset Management System
This is a FOSS project for asset management in IT Operations. Knowing who has which laptop, when it was purchased in order to depreciate it correctly, handling software licenses, etc.
It is built on [Laravel 11](http://laravel.com).
It is built on [Laravel 12](http://laravel.com).
Snipe-IT is actively developed and we [release quite frequently](https://github.com/grokability/snipe-it/releases). ([Check out the live demo here](https://snipeitapp.com/demo/).)
@@ -78,11 +78,14 @@ Since the release of the JSON REST API, several third-party developers have been
#### Libraries & Modules
- [SnipeScheduler](https://github.com/JSY-Ben/SnipeScheduler) by [@JSY-Ben](https://github.com/JSY-Ben) - An Asset Reservation/Checkout System for Snipe-IT
- [Snipe-IT MCP Server](https://github.com/jameshgordy/snipeit-mcp) by [@jameshgordy](https://github.com/jameshgordy) - A Model Context Protocol (MCP) server for managing Snipe-IT inventory systems
- [SnipeSharp - .NET module in C#](https://github.com/barrycarey/SnipeSharp) by [@barrycarey](https://github.com/barrycarey)
- [SnipeitPS](https://github.com/snazy2000/SnipeitPS) by [@snazy2000](https://github.com/snazy2000) - Powershell API Wrapper for Snipe-it
- [jamf2snipe](https://github.com/grokability/jamf2snipe) - Python script to sync assets between a JAMFPro instance and a Snipe-IT instance
- [jamf-snipe-rename](https://macblog.org/jamf-snipe-rename/) - Python script to rename computers in Jamf from Snipe-IT
- [Snipe-IT plugin for Jira Service Desk](https://marketplace.atlassian.com/apps/1220964/snipe-it-for-jira)
- [Rudder2Snipe](https://github.com/norbertoaquino/rudder2snipe) by [@norbertoaquino](https://github.com/norbertoaquino) - Rudder.io integration for Snipe-IT
- [Python 3 CSV importer](https://github.com/gastamper/snipeit-csvimporter) - allows importing assets into Snipe-IT based on Item Name rather than Asset Tag.
- [Snipe-IT Kubernetes Helm Chart](https://github.com/t3n/helm-charts/tree/master/snipeit) - For more information, [click here](https://hub.helm.sh/charts/t3n/snipeit).
- [Snipe-IT Bulk Edit](https://github.com/bricelabelle/snipe-it-bulkedit) - Google Script files to use Google Sheets as a bulk checkout/checkin/edit tool for Snipe-IT.
@@ -121,7 +124,7 @@ We're currently working on our own mobile app, but in the meantime, check out th
### Contributing
**Please refrain from submitting issues or pull requests generated by fully-automated tools. Maintainers reserve the right, at their sole discretion, to close such submissions and to block any account responsible for them.**
**Please refrain from submitting issues or pull requests generated by fully-automated tools. Maintainers reserve the right, at their sole discretion, to close such submissions and to block any account responsible for them.** Please see our [AI Contribution Policy](https://snipe-it.readme.io/docs/contributing-overview#ai-usage-policy) for more information.
Contributions should follow from a human-to-human discussion in the form of an issue for the best chances of being merged into the core project. (Sometimes we might already be working on that feature, sometimes we've decided against )
+15 -4
View File
@@ -10,9 +10,9 @@ however there are times when library dependencies and/or PHP/MySQL dependencies
make it impossible to backport security fixes on older versions.
| Version | Supported |
|---------| ------------------ |
|---------|--------------------|
| 8.x | :white_check_mark: |
| 7.x | :white_check_mark: |
| 7.x | :x: |
| 6.x | :x: |
| 5.1.x | :x: |
| 5.0.x | :x: |
@@ -24,7 +24,18 @@ make it impossible to backport security fixes on older versions.
Security vulnerabilities should be sent to security@snipeitapp.com. You can typically expect a
response within two business days, and we typically have fixes out in under a week from the initial disclosure.
This obviously varies based on the severity of the security issue and the difficulty in remediation,
but those have historically been the timelines we worm around.
This obviously varies based on the severity of the security issue and the difficulty in remediation, but those have
historically been the timelines we work around.
We do ask that you do not disclose the vulnerability publicly until we have had a chance to address it and tag a release
so that we can protect our users, and we will work
with you to coordinate a public disclosure once we have a fix out. We will also work with you to ensure that you receive
appropriate credit for the discovery of the vulnerability, if you would like to be credited. (Please provide a GitHub
username or other information if you would like to be credited, and please let us know if you would like to remain
anonymous.)
For responsible disclosure, we ask that you give us at least __90 days__ to address the issue before disclosing it
publicly,
but we will work with you if you need to disclose it sooner than that.
For a full breakdown of our security policies, please see https://snipeitapp.com/security.
@@ -0,0 +1,109 @@
<?php
namespace App\Actions\Breadcrumbs;
use App\Models\Accessory;
use App\Models\Asset;
use App\Models\CheckoutAcceptance;
use App\Models\Consumable;
use App\Models\License;
use App\Models\LicenseSeat;
use App\Models\User;
use Tabuna\Breadcrumbs\Trail;
final class BuildAcceptanceBreadcrumbs
{
public static function forAcceptance(Trail $trail, CheckoutAcceptance|int|string $acceptance): void
{
$acceptance = self::resolveAcceptance($acceptance);
$trail->parent('home');
if (! $acceptance instanceof CheckoutAcceptance) {
self::appendProfileContext($trail);
return;
}
if (! self::isSignInPlaceFlow($acceptance)) {
self::appendProfileContext($trail);
$trail->push(trans('general.accept_item'), route('account.accept.item', $acceptance));
return;
}
self::appendCheckoutFlowContext($trail, $acceptance);
$trail->push(self::buildSignInPlaceLabel($acceptance));
}
private static function resolveAcceptance(CheckoutAcceptance|int|string $acceptance): ?CheckoutAcceptance
{
if ($acceptance instanceof CheckoutAcceptance) {
return $acceptance;
}
if (is_numeric($acceptance)) {
return CheckoutAcceptance::find((int) $acceptance);
}
return null;
}
private static function isSignInPlaceFlow(CheckoutAcceptance $acceptance): bool
{
return (int) session('sign_in_place_acceptance_id') === (int) $acceptance->id;
}
private static function appendProfileContext(Trail $trail): void
{
$trail->push(trans('general.profile'), route('account'));
$trail->push(trans('general.accept_items'), route('account.accept'));
}
private static function appendCheckoutFlowContext(Trail $trail, CheckoutAcceptance $acceptance): void
{
$checkoutable = $acceptance->checkoutable;
if ($checkoutable instanceof Asset) {
$trail->push(trans('general.assets'), route('hardware.index'));
$trail->push($checkoutable->display_name ?? trans('general.asset'), route('hardware.show', $checkoutable));
$trail->push(trans('general.checkout'));
return;
}
if ($checkoutable instanceof LicenseSeat) {
$license = $checkoutable->license;
if ($license instanceof License) {
$trail->push(trans('general.licenses'), route('licenses.index'));
$trail->push($license->display_name ?? trans('general.license'), route('licenses.show', $license));
$trail->push(trans('general.checkout'));
}
return;
}
if ($checkoutable instanceof Consumable) {
$trail->push(trans('general.consumables'), route('consumables.index'));
$trail->push($checkoutable->display_name ?? trans('general.consumable'), route('consumables.show', $checkoutable));
$trail->push(trans('general.checkout'));
return;
}
if ($checkoutable instanceof Accessory) {
$trail->push(trans('general.accessories'), route('accessories.index'));
$trail->push($checkoutable->display_name ?? trans('general.accessory'), route('accessories.show', $checkoutable));
$trail->push(trans('general.checkout'));
}
}
private static function buildSignInPlaceLabel(CheckoutAcceptance $acceptance): string
{
if ($acceptance->assignedTo instanceof User) {
return sprintf('%s for %s', trans('general.sign_in_place'), $acceptance->assignedTo->display_name);
}
return trans('general.sign_in_place');
}
}
@@ -0,0 +1,59 @@
<?php
namespace App\Actions\Categories;
use App\Exceptions\ItemStillHasAccessories;
use App\Exceptions\ItemStillHasAssetModels;
use App\Exceptions\ItemStillHasAssets;
use App\Exceptions\ItemStillHasComponents;
use App\Exceptions\ItemStillHasConsumables;
use App\Exceptions\ItemStillHasLicenses;
use App\Models\Category;
use Illuminate\Support\Facades\Storage;
class DestroyCategoryAction
{
/**
* @throws ItemStillHasAssets
* @throws ItemStillHasAssetModels
* @throws ItemStillHasComponents
* @throws ItemStillHasAccessories
* @throws ItemStillHasLicenses
* @throws ItemStillHasConsumables
*/
public static function run(Category $category): bool
{
$category->loadCount([
'assets as assets_count',
'accessories as accessories_count',
'consumables as consumables_count',
'components as components_count',
'licenses as licenses_count',
'models as models_count',
]);
if ($category->assets_count > 0) {
throw new ItemStillHasAssets($category);
}
if ($category->accessories_count > 0) {
throw new ItemStillHasAccessories($category);
}
if ($category->consumables_count > 0) {
throw new ItemStillHasConsumables($category);
}
if ($category->components_count > 0) {
throw new ItemStillHasComponents($category);
}
if ($category->licenses_count > 0) {
throw new ItemStillHasLicenses($category);
}
if ($category->models_count > 0) {
throw new ItemStillHasAssetModels($category);
}
Storage::disk('public')->delete('categories'.'/'.$category->image);
$category->delete();
return true;
}
}
@@ -14,8 +14,8 @@ class CancelCheckoutRequestAction
{
public static function run(Asset $asset, User $user)
{
if (!Company::isCurrentUserHasAccess($asset)) {
throw new AuthorizationException();
if (! Company::isCurrentUserHasAccess($asset)) {
throw new AuthorizationException;
}
$asset->cancelRequest();
@@ -27,7 +27,7 @@ class CancelCheckoutRequestAction
$data['item_quantity'] = 1;
$settings = Setting::getSettings();
$logaction = new Actionlog();
$logaction = new Actionlog;
$logaction->item_id = $data['asset_id'] = $asset->id;
$logaction->item_type = $data['item_type'] = Asset::class;
$logaction->created_at = $data['requested_date'] = date('Y-m-d H:i:s');
@@ -44,5 +44,4 @@ class CancelCheckoutRequestAction
return true;
}
}
}
@@ -23,8 +23,8 @@ class CreateCheckoutRequestAction
if (is_null(Asset::RequestableAssets()->find($asset->id))) {
throw new AssetNotRequestable($asset);
}
if (!Company::isCurrentUserHasAccess($asset)) {
throw new AuthorizationException();
if (! Company::isCurrentUserHasAccess($asset)) {
throw new AuthorizationException;
}
$data['item'] = $asset;
@@ -32,7 +32,7 @@ class CreateCheckoutRequestAction
$data['item_quantity'] = 1;
$settings = Setting::getSettings();
$logaction = new Actionlog();
$logaction = new Actionlog;
$logaction->item_id = $data['asset_id'] = $asset->id;
$logaction->item_type = $data['item_type'] = Asset::class;
$logaction->created_at = $data['requested_date'] = date('Y-m-d H:i:s');
@@ -44,11 +44,11 @@ class CreateCheckoutRequestAction
$asset->request();
$asset->increment('requests_counter', 1);
try {
$settings->notify(new RequestAssetNotification($data));
$settings->notify((new RequestAssetNotification($data))->locale($settings->locale));
} catch (\Exception $e) {
Log::warning($e);
}
return true;
}
}
}
@@ -0,0 +1,62 @@
<?php
namespace App\Actions\Manufacturers;
use App\Exceptions\ItemStillHasAccessories;
use App\Exceptions\ItemStillHasAssets;
use App\Exceptions\ItemStillHasComponents;
use App\Exceptions\ItemStillHasConsumables;
use App\Exceptions\ItemStillHasLicenses;
use App\Models\Manufacturer;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Storage;
class DeleteManufacturerAction
{
/**
* @throws ItemStillHasAssets
* @throws ItemStillHasComponents
* @throws ItemStillHasAccessories
* @throws ItemStillHasLicenses
* @throws ItemStillHasConsumables
*/
public static function run(Manufacturer $manufacturer): bool
{
$manufacturer->loadCount([
'assets as assets_count',
'accessories as accessories_count',
'consumables as consumables_count',
'components as components_count',
'licenses as licenses_count',
]);
if ($manufacturer->assets_count > 0) {
throw new ItemStillHasAssets($manufacturer);
}
if ($manufacturer->accessories_count > 0) {
throw new ItemStillHasAccessories($manufacturer);
}
if ($manufacturer->consumables_count > 0) {
throw new ItemStillHasConsumables($manufacturer);
}
if ($manufacturer->components_count > 0) {
throw new ItemStillHasComponents($manufacturer);
}
if ($manufacturer->licenses_count > 0) {
throw new ItemStillHasLicenses($manufacturer);
}
if ($manufacturer->image) {
try {
Storage::disk('public')->delete('manufacturers/'.$manufacturer->image);
} catch (\Exception $e) {
Log::info($e);
}
}
$manufacturer->delete();
// dd($manufacturer);
return true;
}
}
@@ -0,0 +1,30 @@
<?php
namespace App\Actions\Permissions;
final class NormalizePermissionsPayloadAction
{
/**
* Normalize permissions payloads from request/model to a consistent associative array.
*
* @return array<string, mixed>
*/
public static function run(mixed $permissions): array
{
if (is_string($permissions)) {
$decoded = json_decode($permissions, true);
return is_array($decoded) ? $decoded : [];
}
if (is_array($permissions)) {
return $permissions;
}
if ($permissions instanceof \stdClass) {
return (array) $permissions;
}
return [];
}
}
@@ -0,0 +1,41 @@
<?php
namespace App\Actions\Permissions;
use App\Models\User;
final class PreserveUnauthorizedPrivilegedPermissionsAction
{
/**
* Preserve privileged permission keys unless the authenticated user may manage them.
*
* @param array<string, mixed> $requestedPermissions
* @param array<string, mixed> $originalPermissions
* @return array<string, mixed>
*/
public static function run(array $requestedPermissions, User $authenticatedUser, array $originalPermissions = [], ?User $targetUser = null): array
{
// Disallow non-admin/superuser users from modifying their own permissions, but allow them to modify other users' permissions (except for admin/superuser keys).
if ($targetUser && ! $authenticatedUser->isSuperUser() && $authenticatedUser->id === $targetUser->id) {
return $originalPermissions;
}
if (! $authenticatedUser->isSuperUser()) {
if (array_key_exists('superuser', $originalPermissions)) {
$requestedPermissions['superuser'] = $originalPermissions['superuser'];
} else {
unset($requestedPermissions['superuser']);
}
}
if ((! $authenticatedUser->isAdmin()) && (! $authenticatedUser->isSuperUser())) {
if (array_key_exists('admin', $originalPermissions)) {
$requestedPermissions['admin'] = $originalPermissions['admin'];
} else {
unset($requestedPermissions['admin']);
}
}
return $requestedPermissions;
}
}
@@ -0,0 +1,71 @@
<?php
namespace App\Actions\Suppliers;
use App\Exceptions\ItemStillHasAccessories;
use App\Exceptions\ItemStillHasAssets;
use App\Exceptions\ItemStillHasComponents;
use App\Exceptions\ItemStillHasConsumables;
use App\Exceptions\ItemStillHasLicenses;
use App\Exceptions\ItemStillHasMaintenances;
use App\Models\Supplier;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Storage;
class DestroySupplierAction
{
/**
* @throws ItemStillHasLicenses
* @throws ItemStillHasAssets
* @throws ItemStillHasMaintenances
* @throws ItemStillHasAccessories
* @throws ItemStillHasConsumables
* @throws ItemStillHasComponents
*/
public static function run(Supplier $supplier): bool
{
$supplier->loadCount([
'maintenances as maintenances_count',
'assets as assets_count',
'licenses as licenses_count',
'accessories as accessories_count',
'consumables as consumables_count',
'components as components_count',
]);
if ($supplier->assets_count > 0) {
throw new ItemStillHasAssets($supplier);
}
if ($supplier->maintenances_count > 0) {
throw new ItemStillHasMaintenances($supplier);
}
if ($supplier->licenses_count > 0) {
throw new ItemStillHasLicenses($supplier);
}
if ($supplier->accessories_count > 0) {
throw new ItemStillHasAccessories($supplier);
}
if ($supplier->consumables_count > 0) {
throw new ItemStillHasConsumables($supplier);
}
if ($supplier->components_count > 0) {
throw new ItemStillHasComponents($supplier);
}
if ($supplier->image) {
try {
Storage::disk('public')->delete('suppliers/'.$supplier->image);
} catch (\Exception $e) {
Log::info($e->getMessage());
}
}
$supplier->delete();
return true;
}
}
@@ -4,9 +4,7 @@ namespace App\Console\Commands;
use App\Models\License;
use App\Models\LicenseSeat;
use App\Models\User;
use Illuminate\Console\Command;
use Illuminate\Database\Eloquent\Model;
class CheckinLicensesFromAllUsers extends Command
{
@@ -3,10 +3,8 @@
namespace App\Console\Commands;
use App\Models\License;
use App\Models\LicenseSeat;
use App\Models\User;
use Illuminate\Console\Command;
use Illuminate\Database\Eloquent\Model;
class CheckoutLicenseToAllUsers extends Command
{
@@ -75,6 +73,7 @@ class CheckoutLicenseToAllUsers extends Command
if ($user->licenses->where('id', '=', $license_id)->count()) {
$this->info($user->username.' already has this license checked out to them. Skipping... ');
continue;
}
@@ -21,7 +21,7 @@ class CleanIncorrectCheckoutAcceptances extends Command
*
* @var string
*/
protected $description = "Delete checkout acceptances for checkouts to non-users";
protected $description = 'Delete checkout acceptances for checkouts to non-users';
/**
* Execute the console command.
@@ -35,30 +35,32 @@ class CleanIncorrectCheckoutAcceptances extends Command
$this->withProgressBar(CheckoutAcceptance::all(), function ($checkoutAcceptance) use (&$deletions, &$skips) {
$item = $checkoutAcceptance->checkoutable;
$checkout_to_id = $checkoutAcceptance->assigned_to_id;
if(is_null($item)) {
if (is_null($item)) {
$this->info("'Checkoutable' Item is null, going to next record");
return; //'false' allegedly breaks execution entirely, so 'true' maybe doesn't? hrm. just straight return maybe?
return; // 'false' allegedly breaks execution entirely, so 'true' maybe doesn't? hrm. just straight return maybe?
}
if(get_class($item) == LicenseSeat::class) {
if (get_class($item) == LicenseSeat::class) {
$item = $item->license;
}
foreach($item->assetlog()->where('action_type','checkout')->get() as $assetlog) {
foreach ($item->assetlog()->where('action_type', 'checkout')->get() as $assetlog) {
if ($assetlog->target_id == $checkout_to_id && $assetlog->target_type != User::class) {
//We have a checkout-to an ID for a non-User, which matches to an ID in the checkout_acceptances table
// We have a checkout-to an ID for a non-User, which matches to an ID in the checkout_acceptances table
//now, let's compare the _times_ - are they close?
//I'm picking `created_at` over `action_date` because I'm more interested in when the actionlogs
//were _created_, not when they were alleged to have happened - those created_at times need to be within 'X' seconds of
//each other (currently 5)
if ($assetlog->created_at->diffInSeconds($checkoutAcceptance->created_at, true) <= 5) { //we're allowing for five _ish_ seconds of slop
// now, let's compare the _times_ - are they close?
// I'm picking `created_at` over `action_date` because I'm more interested in when the actionlogs
// were _created_, not when they were alleged to have happened - those created_at times need to be within 'X' seconds of
// each other (currently 5)
if ($assetlog->created_at->diffInSeconds($checkoutAcceptance->created_at, true) <= 5) { // we're allowing for five _ish_ seconds of slop
$deletions++;
$checkoutAcceptance->forceDelete(); // HARD delete this record; it should have never been
return;
} else {
//$this->info("The two records are too far apart");
// $this->info("The two records are too far apart");
}
} else {
//$this->info("No match! checkout to id: " . $checkout_to_id." target_id: ".$assetlog->target_id." target_type: ".$assetlog->target_type);
// $this->info("No match! checkout to id: " . $checkout_to_id." target_id: ".$assetlog->target_id." target_type: ".$assetlog->target_type);
}
}
$skips++;
@@ -8,6 +8,7 @@ use Illuminate\Console\Command;
class CleanOldCheckoutRequests extends Command
{
private int $deletions = 0;
private int $skips = 0;
/**
@@ -44,12 +45,14 @@ class CleanOldCheckoutRequests extends Command
if ($this->shouldForceDelete($request)) {
$request->forceDelete();
$this->deletions++;
return;
}
if ($this->shouldSoftDelete($request)) {
$request->delete();
$this->deletions++;
return;
}
@@ -64,7 +67,7 @@ class CleanOldCheckoutRequests extends Command
private function shouldForceDelete(CheckoutRequest $request)
{
// check if the requestable or user relationship is null
return !$request->requestable || !$request->user;
return ! $request->requestable || ! $request->user;
}
private function shouldSoftDelete(CheckoutRequest $request)
+7 -13
View File
@@ -2,31 +2,28 @@
namespace App\Console\Commands;
use App\Models\User;
use Illuminate\Console\Command;
use \App\Models\User;
use Illuminate\Support\Carbon;
class CreateAdmin extends Command
{
/** @mixin User **/
/**
* App\Console\CreateAdmin
*
* @property mixed $first_name
* @property string $last_name
* @property string $username
* @property string $email
* @property string $permissions
* @property string $password
* @property boolean $activated
* @property boolean $show_in_list
* @property boolean $autoassign_licenses
* @property \Illuminate\Support\Carbon|null $created_at
* @property bool $activated
* @property bool $show_in_list
* @property bool $autoassign_licenses
* @property Carbon|null $created_at
* @property mixed $created_by
*/
protected $signature = 'snipeit:create-admin {--first_name=} {--last_name=} {--email=} {--username=} {--password=} {show_in_list?} {autoassign_licenses?}';
/**
@@ -46,7 +43,6 @@ class CreateAdmin extends Command
parent::__construct();
}
public function handle()
{
$first_name = $this->option('first_name');
@@ -57,8 +53,6 @@ class CreateAdmin extends Command
$show_in_list = $this->argument('show_in_list');
$autoassign_licenses = $this->argument('autoassign_licenses');
if (($first_name == '') || ($last_name == '') || ($username == '') || ($email == '') || ($password == '')) {
$this->info('ERROR: All fields are required.');
} else {
@@ -24,6 +24,7 @@ class FixBulkAccessoryCheckinActionLogEntries extends Command
protected $description = 'This script attempts to fix timestamps and missing created_by values for bulk checkin entries in the log table';
private bool $dryrun = false;
private bool $skipBackup = false;
/**
@@ -50,10 +51,11 @@ class FixBulkAccessoryCheckinActionLogEntries extends Command
if ($logs->isEmpty()) {
$this->info('No logs found with incorrect timestamps.');
return 0;
}
$this->info('Found ' . $logs->count() . ' logs with incorrect timestamps:');
$this->info('Found '.$logs->count().' logs with incorrect timestamps:');
$this->table(
['ID', 'Created By', 'Created At', 'Updated At'],
@@ -67,11 +69,11 @@ class FixBulkAccessoryCheckinActionLogEntries extends Command
})
);
if (!$this->dryrun && !$this->confirm('Update these logs?')) {
if (! $this->dryrun && ! $this->confirm('Update these logs?')) {
return 0;
}
if (!$this->dryrun && !$this->skipBackup) {
if (! $this->dryrun && ! $this->skipBackup) {
$this->info('Backing up the database before making changes...');
$this->call('snipeit:backup');
}
@@ -83,7 +85,7 @@ class FixBulkAccessoryCheckinActionLogEntries extends Command
foreach ($logs as $log) {
$this->newLine();
$this->info('Processing log id:' . $log->id);
$this->info('Processing log id:'.$log->id);
// created_by was not being set for accessory bulk checkins
// so let's see if there was another bulk checkin log
@@ -106,7 +108,7 @@ class FixBulkAccessoryCheckinActionLogEntries extends Command
$this->line(vsprintf('Updating log id:%s from %s to %s', [$log->id, $log->created_at, $log->updated_at]));
$log->created_at = $log->updated_at;
if (!$this->dryrun) {
if (! $this->dryrun) {
Model::withoutTimestamps(function () use ($log) {
$log->saveQuietly();
});
@@ -129,7 +131,7 @@ class FixBulkAccessoryCheckinActionLogEntries extends Command
* This method attempts to find a bulk check in log that was
* created at the same time as the log passed in.
*/
private function getCreatedByAttributeFromSimilarLog(Actionlog $log): null|int
private function getCreatedByAttributeFromSimilarLog(Actionlog $log): ?int
{
$similarLog = Actionlog::query()
->whereNotNull('created_by')
+30 -15
View File
@@ -2,6 +2,21 @@
namespace App\Console\Commands;
use App\Models\Accessory;
use App\Models\Asset;
use App\Models\AssetModel;
use App\Models\Company;
use App\Models\Component;
use App\Models\Consumable;
use App\Models\Department;
use App\Models\Depreciation;
use App\Models\Group;
use App\Models\License;
use App\Models\Location;
use App\Models\Manufacturer;
use App\Models\Statuslabel;
use App\Models\Supplier;
use App\Models\User;
use Illuminate\Console\Command;
class FixDoubleEscape extends Command
@@ -38,21 +53,21 @@ class FixDoubleEscape extends Command
public function handle()
{
$tables = [
\App\Models\Asset::class => ['name'],
\App\Models\License::class => ['name'],
\App\Models\Consumable::class => ['name'],
\App\Models\Accessory::class => ['name'],
\App\Models\Component::class => ['name'],
\App\Models\Company::class => ['name'],
\App\Models\Manufacturer::class => ['name'],
\App\Models\Supplier::class => ['name'],
\App\Models\Statuslabel::class => ['name'],
\App\Models\Depreciation::class => ['name'],
\App\Models\AssetModel::class => ['name'],
\App\Models\Group::class => ['name'],
\App\Models\Department::class => ['name'],
\App\Models\Location::class => ['name'],
\App\Models\User::class => ['first_name', 'last_name'],
Asset::class => ['name'],
License::class => ['name'],
Consumable::class => ['name'],
Accessory::class => ['name'],
Component::class => ['name'],
Company::class => ['name'],
Manufacturer::class => ['name'],
Supplier::class => ['name'],
Statuslabel::class => ['name'],
Depreciation::class => ['name'],
AssetModel::class => ['name'],
Group::class => ['name'],
Department::class => ['name'],
Location::class => ['name'],
User::class => ['first_name', 'last_name'],
];
$count = [];
@@ -4,6 +4,7 @@ namespace App\Console\Commands;
use App\Models\Actionlog;
use App\Models\Asset;
use App\Models\User;
use Illuminate\Console\Command;
class FixMismatchedAssetsAndLogs extends Command
@@ -56,26 +57,26 @@ class FixMismatchedAssetsAndLogs extends Command
$mismatch_count = 0;
$assets = Asset::whereNotNull('assigned_to')
->where('assigned_type', '=', \App\Models\User::class)
->where('assigned_type', '=', User::class)
->orderBy('id', 'ASC')->get();
foreach ($assets as $asset) {
// get the last checkout of the asset
if ($checkout_log = Actionlog::where('target_type', '=', \App\Models\User::class)
if ($checkout_log = Actionlog::where('target_type', '=', User::class)
->where('action_type', '=', 'checkout')
->where('item_id', '=', $asset->id)
->orderBy('created_at', 'DESC')
->first()) {
// Now check for a subsequent checkin log - we want to ignore those
if (! $checkin_log = Actionlog::where('target_type', '=', \App\Models\User::class)
->where('action_type', '=', 'checkin from')
->where('item_id', '=', $asset->id)
->whereDate('created_at', '>', $checkout_log->created_at)
->orderBy('created_at', 'DESC')
->first()) {
// Now check for a subsequent checkin log - we want to ignore those
if (! $checkin_log = Actionlog::where('target_type', '=', User::class)
->where('action_type', '=', 'checkin from')
->where('item_id', '=', $asset->id)
->whereDate('created_at', '>', $checkout_log->created_at)
->orderBy('created_at', 'DESC')
->first()) {
//print_r($asset);
// print_r($asset);
if ($checkout_log->target_id != $asset->assigned_to) {
$this->error('Log ID: '.$checkout_log->id.' -- Asset ID '.$checkout_log->item_id.' SHOULD BE checked out to User '.$checkout_log->target_id.' but its assigned_to is '.$asset->assigned_to);
@@ -90,7 +91,7 @@ class FixMismatchedAssetsAndLogs extends Command
$mismatch_count++;
}
} else {
//$this->info('Asset ID '.$asset->id.': There is a checkin '.$checkin_log->created_at.' after this checkout '.$checkout_log->created_at);
// $this->info('Asset ID '.$asset->id.': There is a checkin '.$checkin_log->created_at.' after this checkout '.$checkout_log->created_at);
}
}
}
@@ -27,6 +27,6 @@ class FixUpAssignedTypeWithoutAssignedTo extends Command
public function handle()
{
DB::table('assets')->whereNotNull('assigned_type')->whereNull('assigned_to')->update(['assigned_type' => null]);
$this->info("Assets with an assigned_type but no assigned_to are fixed");
$this->info('Assets with an assigned_type but no assigned_to are fixed');
}
}
@@ -27,40 +27,42 @@ class FixupAssignedToWithoutAssignedType extends Command
*/
public function handle()
{
$assets = Asset::whereNull("assigned_type")->whereNotNull("assigned_to")->withTrashed();
$assets = Asset::whereNull('assigned_type')->whereNotNull('assigned_to')->withTrashed();
$this->withProgressBar($assets->get(), function (Asset $asset) {
//now check each action log, from the most recent backwards, to find the last checkin or checkout
foreach($asset->log()->orderBy("id","desc")->get() as $action_log) {
if($this->option("debug")) {
$this->info("Asset id: " . $asset->id . " action log, action type is: " . $action_log->action_type);
// now check each action log, from the most recent backwards, to find the last checkin or checkout
foreach ($asset->log()->orderBy('id', 'desc')->get() as $action_log) {
if ($this->option('debug')) {
$this->info('Asset id: '.$asset->id.' action log, action type is: '.$action_log->action_type);
}
switch($action_log->action_type) {
switch ($action_log->action_type) {
case 'checkin from':
if($this->option("debug")) {
$this->info("Doing a checkin for ".$asset->id);
if ($this->option('debug')) {
$this->info('Doing a checkin for '.$asset->id);
}
$asset->assigned_to = null;
// if you have a required custom field, we still want to save, and we *don't* want an action_log
$asset->saveQuietly();
return;
case 'checkout':
if($this->option("debug")) {
$this->info("Doing a checkout for " . $asset->id . " picking target type: " . $action_log->target_type);
if ($this->option('debug')) {
$this->info('Doing a checkout for '.$asset->id.' picking target type: '.$action_log->target_type);
}
if($asset->assigned_to != $action_log->target_id) {
$this->error("Asset's assigned_to does *NOT* match Action Log's target_id. \$asset->assigned_to=".$asset->assigned_to." vs. \$action_log->target_id=".$action_log->target_id);
//FIXME - do we abort here? Do we try to keep looking? I don't know, this means your data is *really* messed up...
if ($asset->assigned_to != $action_log->target_id) {
$this->error("Asset's assigned_to does *NOT* match Action Log's target_id. \$asset->assigned_to=".$asset->assigned_to.' vs. $action_log->target_id='.$action_log->target_id);
// FIXME - do we abort here? Do we try to keep looking? I don't know, this means your data is *really* messed up...
}
$asset->assigned_type = $action_log->target_type;
$asset->saveQuietly(); // see above
return;
}
}
$asset->assigned_to = null; //asset was never checked in or out in its lifetime - it stays 'checked in'
$asset->saveQuietly(); //see above
$asset->assigned_to = null; // asset was never checked in or out in its lifetime - it stays 'checked in'
$asset->saveQuietly(); // see above
});
$this->newLine();
$this->info("Assets assigned_type are fixed");
$this->info('Assets assigned_type are fixed');
}
}
@@ -2,14 +2,13 @@
namespace App\Console\Commands;
use Illuminate\Console\Command;
use App\Models\User;
use Laravel\Passport\TokenRepository;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\DB;
use Laravel\Passport\TokenRepository;
class GeneratePersonalAccessToken extends Command
{
/**
* The name and signature of the console command.
*
@@ -27,15 +26,13 @@ class GeneratePersonalAccessToken extends Command
*/
protected $description = 'This console command allows you to generate Personal API tokens to be used with the Snipe-IT JSON REST API on behalf of a user.';
/**
* The token repository implementation.
*
* @var \Laravel\Passport\TokenRepository
* @var TokenRepository
*/
protected $tokenRepository;
/**
* Create a new command instance.
*
@@ -56,11 +53,11 @@ class GeneratePersonalAccessToken extends Command
{
$accessTokenName = $this->option('name');
if ($accessTokenName=='') {
if ($accessTokenName == '') {
$accessTokenName = 'CLI Auth Token';
}
if ($this->option('user_id')=='') {
if ($this->option('user_id') == '') {
return $this->error('ERROR: user_id cannot be blank.');
}
@@ -75,7 +72,7 @@ class GeneratePersonalAccessToken extends Command
$this->warn('Your API Token has been created. Be sure to copy this token now, as it WILL NOT be accessible again.');
if ($token = DB::table('oauth_access_tokens')->where('user_id', '=', $user->id)->where('name','=',$accessTokenName)->orderBy('created_at', 'desc')->first()) {
if ($token = DB::table('oauth_access_tokens')->where('user_id', '=', $user->id)->where('name', '=', $accessTokenName)->orderBy('created_at', 'desc')->first()) {
$this->info('API Token ID: '.$token->id);
}
@@ -84,11 +81,8 @@ class GeneratePersonalAccessToken extends Command
$this->info('API Token: '.$createAccessToken);
}
} else {
return $this->error('ERROR: Invalid user. API key was not created.');
return $this->error('ERROR: Invalid user. API key was not created.');
}
}
}
+1 -1
View File
@@ -46,7 +46,7 @@ class ImportLocations extends Command
$filename = $this->argument('filename');
$csv = Reader::createFromPath(storage_path('private_uploads/imports/').$filename, 'r');
$this->info('Attempting to process: '.storage_path('private_uploads/imports/').$filename);
$csv->setHeaderOffset(0); //because we don't want to insert the header
$csv->setHeaderOffset(0); // because we don't want to insert the header
$results = $csv->getRecords();
// Import parent location names first if they don't exist
+7 -6
View File
@@ -38,22 +38,23 @@ class KillAllSessions extends Command
public function handle()
{
if (!$this->option('force') && !$this->confirm("****************************************************\nTHIS WILL FORCE A LOGIN FOR ALL LOGGED IN USERS.\n\nAre you SURE you wish to continue? ")) {
return $this->error("Session loss not confirmed");
if (! $this->option('force') && ! $this->confirm("****************************************************\nTHIS WILL FORCE A LOGIN FOR ALL LOGGED IN USERS.\n\nAre you SURE you wish to continue? ")) {
return $this->error('Session loss not confirmed');
}
$session_files = glob(storage_path("framework/sessions/*"));
$session_files = glob(storage_path('framework/sessions/*'));
$count = 0;
foreach ($session_files as $file) {
if (is_file($file))
if (is_file($file)) {
unlink($file);
$count++;
}
$count++;
}
\DB::table('users')->update(['remember_token' => null]);
$this->info($count. ' sessions cleared!');
$this->info($count.' sessions cleared!');
}
}
+172 -102
View File
@@ -5,11 +5,11 @@ namespace App\Console\Commands;
use App\Models\Asset;
use App\Models\Department;
use App\Models\Group;
use Illuminate\Console\Command;
use App\Models\Setting;
use App\Models\Ldap;
use App\Models\User;
use App\Models\Location;
use App\Models\Setting;
use App\Models\User;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Log;
class LdapSync extends Command
@@ -19,7 +19,7 @@ class LdapSync extends Command
*
* @var string
*/
protected $signature = 'snipeit:ldap-sync {--location=} {--location_id=*} {--base_dn=} {--filter=} {--summary} {--json_summary}';
protected $signature = 'snipeit:ldap-sync {--location=} {--location_id=*} {--base_dn=} {--filter=} {--delete} {--summary} {--json_summary}';
/**
* The console command description.
@@ -47,35 +47,34 @@ class LdapSync extends Command
{
// If LDAP enabled isn't set to 1 (ldap_enabled!=1) then we should cut this short immediately without going any further
if (Setting::getSettings()->ldap_enabled!='1') {
if (Setting::getSettings()->ldap_enabled != '1') {
$this->error('LDAP is not enabled. Aborting. See Settings > LDAP to enable it.');
exit();
}
ini_set('max_execution_time', env('LDAP_TIME_LIM', 600)); //600 seconds = 10 minutes
ini_set('max_execution_time', env('LDAP_TIME_LIM', 600)); // 600 seconds = 10 minutes
ini_set('memory_limit', env('LDAP_MEM_LIM', '500M'));
// Map the LDAP attributes to the Snipe-IT user fields.
$ldap_map = [
"username" => Setting::getSettings()->ldap_username_field,
"last_name" => Setting::getSettings()->ldap_lname_field,
"first_name" => Setting::getSettings()->ldap_fname_field,
"active_flag" => Setting::getSettings()->ldap_active_flag,
"emp_num" => Setting::getSettings()->ldap_emp_num,
"email" => Setting::getSettings()->ldap_email,
"phone" => Setting::getSettings()->ldap_phone_field,
"mobile" => Setting::getSettings()->ldap_mobile,
"jobtitle" => Setting::getSettings()->ldap_jobtitle,
"address" => Setting::getSettings()->ldap_address,
"city" => Setting::getSettings()->ldap_city,
"state" => Setting::getSettings()->ldap_state,
"zip" => Setting::getSettings()->ldap_zip,
"country" => Setting::getSettings()->ldap_country,
"location" => Setting::getSettings()->ldap_location,
"dept" => Setting::getSettings()->ldap_dept,
"manager" => Setting::getSettings()->ldap_manager,
"display_name" => Setting::getSettings()->ldap_display_name,
'username' => Setting::getSettings()->ldap_username_field,
'last_name' => Setting::getSettings()->ldap_lname_field,
'first_name' => Setting::getSettings()->ldap_fname_field,
'active_flag' => Setting::getSettings()->ldap_active_flag,
'emp_num' => Setting::getSettings()->ldap_emp_num,
'email' => Setting::getSettings()->ldap_email,
'phone' => Setting::getSettings()->ldap_phone_field,
'mobile' => Setting::getSettings()->ldap_mobile,
'jobtitle' => Setting::getSettings()->ldap_jobtitle,
'address' => Setting::getSettings()->ldap_address,
'city' => Setting::getSettings()->ldap_city,
'state' => Setting::getSettings()->ldap_state,
'zip' => Setting::getSettings()->ldap_zip,
'country' => Setting::getSettings()->ldap_country,
'location' => Setting::getSettings()->ldap_location,
'dept' => Setting::getSettings()->ldap_dept,
'manager' => Setting::getSettings()->ldap_manager,
'display_name' => Setting::getSettings()->ldap_display_name,
];
$ldap_default_group = Setting::getSettings()->ldap_default_group;
@@ -95,19 +94,20 @@ class LdapSync extends Command
}
$summary = [];
$seen_ldap_usernames = [];
try {
/**
* if a location ID has been specified, use that OU
*/
if ( $this->option('location_id') ) {
if ($this->option('location_id')) {
foreach($this->option('location_id') as $location_id){
foreach ($this->option('location_id') as $location_id) {
$location_ou = Location::where('id', '=', $location_id)->value('ldap_ou');
$search_base = $location_ou;
Log::debug('Importing users from specified location OU: \"'.$search_base.'\".');
}
}
}
/**
@@ -153,21 +153,21 @@ class LdapSync extends Command
$default_location = null;
if ($this->option('location') != '') {
if ($default_location = Location::where('name', '=', $this->option('location'))->first()) {
Log::debug('Location name ' . $this->option('location') . ' passed');
Log::debug('Location name '.$this->option('location').' passed');
Log::debug('Importing to '.$default_location->name.' ('.$default_location->id.')');
}
} elseif ($this->option('location_id')) {
//TODO - figure out how or why this is an array?
foreach($this->option('location_id') as $location_id) {
// TODO - figure out how or why this is an array?
foreach ($this->option('location_id') as $location_id) {
if ($default_location = Location::where('id', '=', $location_id)->first()) {
Log::debug('Location ID ' . $location_id . ' passed');
Log::debug('Location ID '.$location_id.' passed');
Log::debug('Importing to '.$default_location->name.' ('.$default_location->id.')');
}
}
}
if (!isset($default_location)) {
if (! isset($default_location)) {
Log::debug('That location is invalid or a location was not provided, so no location will be assigned by default.');
}
@@ -208,17 +208,17 @@ class LdapSync extends Command
}
$usernames = [];
for ($i = 0; $i < $location_users['count']; $i++) {
if (array_key_exists($ldap_map["username"], $location_users[$i])) {
if (array_key_exists($ldap_map['username'], $location_users[$i])) {
$location_users[$i]['ldap_location_override'] = true;
$location_users[$i]['location_id'] = $ldap_loc['id'];
$usernames[] = $location_users[$i][$ldap_map["username"]][0];
$usernames[] = $location_users[$i][$ldap_map['username']][0];
}
}
// Delete located users from the general group.
foreach ($results as $key => $generic_entry) {
if ((is_array($generic_entry)) && (array_key_exists($ldap_map["username"], $generic_entry))) {
if (in_array($generic_entry[$ldap_map["username"]][0], $usernames)) {
if ((is_array($generic_entry)) && (array_key_exists($ldap_map['username'], $generic_entry))) {
if (in_array($generic_entry[$ldap_map['username']][0], $usernames)) {
unset($results[$key]);
}
}
@@ -232,42 +232,41 @@ class LdapSync extends Command
$manager_cache = [];
if($ldap_default_group != null) {
if ($ldap_default_group != null) {
$default = Group::find($ldap_default_group);
if (!$default) {
if (! $default) {
$ldap_default_group = null; // un-set the default group if that group doesn't exist
}
}
// Assign the mapped LDAP attributes for each user to the Snipe-IT user fields
for ($i = 0; $i < $results['count']; $i++) {
$item = [];
$item['username'] = $results[$i][$ldap_map["username"]][0] ?? '';
$item['display_name'] = $results[$i][$ldap_map["display_name"]][0] ?? '';
$item['employee_number'] = $results[$i][$ldap_map["emp_num"]][0] ?? '';
$item['lastname'] = $results[$i][$ldap_map["last_name"]][0] ?? '';
$item['firstname'] = $results[$i][$ldap_map["first_name"]][0] ?? '';
$item['email'] = $results[$i][$ldap_map["email"]][0] ?? '';
$item['ldap_location_override'] = $results[$i]['ldap_location_override'] ?? '';
$item['location_id'] = $results[$i]['location_id'] ?? '';
$item['telephone'] = $results[$i][$ldap_map["phone"]][0] ?? '';
$item['mobile'] = $results[$i][$ldap_map["mobile"]][0] ?? '';
$item['jobtitle'] = $results[$i][$ldap_map["jobtitle"]][0] ?? '';
$item['address'] = $results[$i][$ldap_map["address"]][0] ?? '';
$item['city'] = $results[$i][$ldap_map["city"]][0] ?? '';
$item['state'] = $results[$i][$ldap_map["state"]][0] ?? '';
$item['country'] = $results[$i][$ldap_map["country"]][0] ?? '';
$item['zip'] = $results[$i][$ldap_map["zip"]][0] ?? '';
$item['department'] = $results[$i][$ldap_map["dept"]][0] ?? '';
$item['manager'] = $results[$i][$ldap_map["manager"]][0] ?? '';
$item['location'] = $results[$i][$ldap_map["location"]][0] ?? '';
$location = $default_location; //initially, set '$location' to the default_location (which may just be `null`)
$item['username'] = $results[$i][$ldap_map['username']][0] ?? null;
$item['display_name'] = $results[$i][$ldap_map['display_name']][0] ?? null;
$item['employee_number'] = $results[$i][$ldap_map['emp_num']][0] ?? null;
$item['lastname'] = $results[$i][$ldap_map['last_name']][0] ?? null;
$item['firstname'] = $results[$i][$ldap_map['first_name']][0] ?? null;
$item['email'] = $results[$i][$ldap_map['email']][0] ?? null;
$item['ldap_location_override'] = $results[$i]['ldap_location_override'] ?? null;
$item['location_id'] = $results[$i]['location_id'] ?? null;
$item['telephone'] = $results[$i][$ldap_map['phone']][0] ?? null;
$item['mobile'] = $results[$i][$ldap_map['mobile']][0] ?? null;
$item['jobtitle'] = $results[$i][$ldap_map['jobtitle']][0] ?? null;
$item['address'] = $results[$i][$ldap_map['address']][0] ?? null;
$item['city'] = $results[$i][$ldap_map['city']][0] ?? null;
$item['state'] = $results[$i][$ldap_map['state']][0] ?? null;
$item['country'] = $results[$i][$ldap_map['country']][0] ?? null;
$item['zip'] = $results[$i][$ldap_map['zip']][0] ?? null;
$item['department'] = $results[$i][$ldap_map['dept']][0] ?? null;
$item['manager'] = $results[$i][$ldap_map['manager']][0] ?? null;
$item['location'] = $results[$i][$ldap_map['location']][0] ?? null;
$location = $default_location; // initially, set '$location' to the default_location (which may just be null)
// ONLY if you are using the "ldap_location" option *AND* you have an actual result
if ($ldap_map["location"] && $item['location']) {
if ($ldap_map['location'] && $item['location']) {
$location = Location::firstOrCreate([
'name' => $item['location'],
]);
@@ -276,8 +275,14 @@ class LdapSync extends Command
'name' => $item['department'],
]);
$user = User::where('username', $item['username'])->first();
$user = User::withTrashed()->where('username', $item['username'])->first();
if (! empty($item['username'])) {
$seen_ldap_usernames[] = $item['username'];
}
if ($user) {
if ($user->trashed()) {
$user->restore();
}
// Updating an existing user.
$item['createorupdate'] = 'updated';
} else {
@@ -289,46 +294,58 @@ class LdapSync extends Command
$item['createorupdate'] = 'created';
}
//If a sync option is not filled in on the LDAP settings don't populate the user field
if($ldap_map["username"] != null){
// If a sync option is not filled in on the LDAP settings don't populate the user field
if ($ldap_map['username'] != null) {
$user->username = $item['username'];
}
if($ldap_map["display_name"] != null){
if ($ldap_map['display_name'] != null) {
$user->display_name = $item['display_name'];
}
if($ldap_map["last_name"] != null){
if ($ldap_map['last_name'] != null) {
$user->last_name = $item['lastname'];
}
if($ldap_map["first_name"] != null){
if ($ldap_map['first_name'] != null) {
$user->first_name = $item['firstname'];
}
if($ldap_map["emp_num"] != null){
if ($ldap_map['emp_num'] != null) {
$user->employee_num = e($item['employee_number']);
}
if($ldap_map["email"] != null){
if ($ldap_map['email'] != null) {
$user->email = $item['email'];
}
if($ldap_map["phone"] != null){
if ($ldap_map['phone'] != null) {
$user->phone = $item['telephone'];
}
if($ldap_map["mobile"] != null){
if ($ldap_map['mobile'] != null) {
$user->mobile = $item['mobile'];
}
if($ldap_map["jobtitle"] != null){
if ($ldap_map['jobtitle'] != null) {
$user->jobtitle = $item['jobtitle'];
}
if($ldap_map["country"] != null){
if ($ldap_map['address'] != null) {
$user->address = $item['address'];
}
if ($ldap_map['city'] != null) {
$user->city = $item['city'];
}
if ($ldap_map['state'] != null) {
$user->state = $item['state'];
}
if ($ldap_map['country'] != null) {
$user->country = $item['country'];
}
if($ldap_map["dept"] != null){
if ($ldap_map['zip'] != null) {
$user->zip = $item['zip'];
}
if ($ldap_map['dept'] != null) {
$user->department_id = $department->id;
}
if($ldap_map["location"] != null){
if ($ldap_map['location'] != null) {
$user->location_id = $location?->id;
}
if($ldap_map["manager"] != null){
if($item['manager'] != null) {
if ($ldap_map['manager'] != null) {
if ($item['manager'] != null) {
// Check Cache first
if (isset($manager_cache[$item['manager']])) {
// found in cache; use that and avoid extra lookups
@@ -338,23 +355,23 @@ class LdapSync extends Command
try {
$ldap_manager = Ldap::findLdapUsers($item['manager'], -1, $this->option('filter'));
} catch (\Exception $e) {
Log::warning("Manager lookup caused an exception: " . $e->getMessage() . ". Falling back to direct username lookup");
Log::warning('Manager lookup caused an exception: '.$e->getMessage().'. Falling back to direct username lookup');
// Hail-mary for Okta manager 'shortnames' - will only work if
// Okta configuration is using full email-address-style usernames
$ldap_manager = [
"count" => 1,
'count' => 1,
0 => [
$ldap_map["username"] => [$item['manager']]
]
$ldap_map['username'] => [$item['manager']],
],
];
}
$add_manager_to_cache = true;
if ($ldap_manager["count"] > 0) {
if ($ldap_manager['count'] > 0) {
try {
// Get the Manager's username
// PHP LDAP returns every LDAP attribute as an array, and 90% of the time it's an array of just one item. But, hey, it's an array.
$ldapManagerUsername = $ldap_manager[0][$ldap_map["username"]][0];
$ldapManagerUsername = $ldap_manager[0][$ldap_map['username']][0];
// Get User from Manager username.
$ldap_manager = User::where('username', $ldapManagerUsername)->first();
@@ -365,11 +382,11 @@ class LdapSync extends Command
}
} catch (\Exception $e) {
$add_manager_to_cache = false;
\Log::warning('Handling ldap manager ' . $item['manager'] . ' caused an exception: ' . $e->getMessage() . '. Continuing synchronization.');
\Log::warning('Handling ldap manager '.$item['manager'].' caused an exception: '.$e->getMessage().'. Continuing synchronization.');
}
}
if ($add_manager_to_cache) {
$manager_cache[$item['manager']] = $ldap_manager && isset($ldap_manager->id) ? $ldap_manager->id : null; // Store results in cache, even if 'failed'
$manager_cache[$item['manager']] = $ldap_manager && isset($ldap_manager->id) ? $ldap_manager->id : null; // Store results in cache, even if 'failed'
}
}
@@ -377,18 +394,18 @@ class LdapSync extends Command
}
// Sync activated state for Active Directory.
if (!empty($ldap_map["active_flag"])) { // IF we have an 'active' flag set....
if (! empty($ldap_map['active_flag'])) { // IF we have an 'active' flag set....
// ....then *most* things that are truthy will activate the user. Anything falsey will deactivate them.
// (Specifically, we don't handle a value of '0.0' correctly)
$raw_value = @$results[$i][$ldap_map["active_flag"]][0];
$raw_value = @$results[$i][$ldap_map['active_flag']][0];
$filter_var = filter_var($raw_value, FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE);
$boolean_cast = (bool) $raw_value;
if (Setting::getSettings()->ldap_invert_active_flag === 1) {
// Because ldap_active_flag is set, if filter_var is true or boolean_cast is true, then user is suspended
$user->activated = !($filter_var ?? $boolean_cast);
}else{
$user->activated = ! ($filter_var ?? $boolean_cast);
} else {
$user->activated = $filter_var ?? $boolean_cast; // if filter_var() was true or false, use that. If it's null, use the $boolean_cast
}
@@ -396,7 +413,6 @@ class LdapSync extends Command
// ....otherwise, (ie if no 'active' LDAP flag is defined), IF the UAC setting exists,
// ....then use the UAC setting on the account to determine can-log-in vs. cannot-log-in
/* The following is _probably_ the correct logic, but we can't use it because
some users may have been dependent upon the previous behavior, and this
could cause additional access to be available to users they don't want
@@ -422,7 +438,7 @@ class LdapSync extends Command
'262688', // 0x40220 NORMAL_ACCOUNT, PASSWD_NOTREQD, SMARTCARD_REQUIRED
'328192', // 0x50200 NORMAL_ACCOUNT, SMARTCARD_REQUIRED, DONT_EXPIRE_PASSWORD
'328224', // 0x50220 NORMAL_ACCOUNT, PASSWD_NOT_REQD, SMARTCARD_REQUIRED, DONT_EXPIRE_PASSWORD
'4194816',// 0x400200 NORMAL_ACCOUNT, DONT_REQ_PREAUTH
'4194816', // 0x400200 NORMAL_ACCOUNT, DONT_REQ_PREAUTH
'4260352', // 0x410200 NORMAL_ACCOUNT, DONT_EXPIRE_PASSWORD, DONT_REQ_PREAUTH
'1049088', // 0x100200 NORMAL_ACCOUNT, NOT_DELEGATED
'1114624', // 0x110200 NORMAL_ACCOUNT, DONT_EXPIRE_PASSWORD, NOT_DELEGATED,
@@ -433,14 +449,13 @@ class LdapSync extends Command
} /* implied 'else' here - leave the $user->activated flag alone. Newly-created accounts will be active.
already-existing accounts will be however the administrator has set them */
if ($item['ldap_location_override'] == true) {
$user->location_id = $item['location_id'];
} elseif ((isset($location)) && (!empty($location))) {
} elseif ((isset($location)) && (! empty($location))) {
if ((is_array($location)) && (array_key_exists('id', $location))) {
$user->location_id = $location['id'];
} elseif (is_object($location)) {
$user->location_id = $location->id; //THIS is the magic line, this should do it.
$user->location_id = $location->id; // THIS is the magic line, this should do it.
}
}
// TODO - should we be NULLING locations if $location is really `null`, and that's what we came up with?
@@ -452,16 +467,17 @@ class LdapSync extends Command
$errors = '';
if ($user->save()) {
$item['id'] = $user->id;
$item['note'] = $item['createorupdate'];
$item['status'] = 'success';
if ($item['createorupdate'] === 'created' && $ldap_default_group) {
// Check if the relationship already exists
if (!$user->groups()->where('group_id', $ldap_default_group)->exists()) {
$user->groups()->attach($ldap_default_group);
// Check if the relationship already exists
if (! $user->groups()->where('group_id', $ldap_default_group)->exists()) {
$user->groups()->attach($ldap_default_group);
}
}
//updates assets location based on user's location
// updates assets location based on user's location
if ($user->wasChanged('location_id')) {
foreach ($user->assets as $asset) {
$asset->location_id = $user->location_id;
@@ -481,6 +497,41 @@ class LdapSync extends Command
array_push($summary, $item);
}
// Optionally soft-delete LDAP-imported users that are no longer present in LDAP.
// users with assests etc. are not deletable and skipped
if ($this->option('delete')) {
$missing_ldap_users = User::where('ldap_import', 1);
$missing_ldap_users = $missing_ldap_users->whereNotIn('username', $seen_ldap_usernames);
$missing_ldap_users = $missing_ldap_users->get();
foreach ($missing_ldap_users as $missing_user) {
$is_deletable = $this->isUserDeletable($missing_user);
$missing_item = [
'id' => $missing_user->id,
'username' => $missing_user->username,
'firstname' => $missing_user->first_name,
'lastname' => $missing_user->last_name,
'email' => $missing_user->email,
'createorupdate' => 'skipped',
'status' => 'info',
'deletable' => $is_deletable,
'note' => $is_deletable ? 'missing from LDAP' : 'missing from LDAP, but not deletable',
];
if ($is_deletable) {
$missing_user->delete();
$missing_item['createorupdate'] = 'deleted';
$missing_item['status'] = 'success';
$missing_item['note'] = 'deleted_missing_from_ldap';
}
$summary[] = $missing_item;
}
}
if ($this->option('summary')) {
for ($x = 0; $x < count($summary); $x++) {
if ($summary[$x]['status'] == 'error') {
@@ -496,4 +547,23 @@ class LdapSync extends Command
return $summary;
}
}
/**
* Checks if the user is deletable without gate check
*
* A user is considered deletable if they have no associated assets, accessories, licenses, consumables, managed users, or managed locations.
*
* @param User $user The user to check
*
* @return bool True if the user is deletable, false otherwise
*/
private function isUserDeletable(User $user): bool
{
return (($user->assets_count ?? $user->assets()->count()) === 0)
&& (($user->accessories_count ?? $user->accessories()->count()) === 0)
&& (($user->licenses_count ?? $user->licenses()->count()) === 0)
&& (($user->consumables_count ?? $user->consumables()->count()) === 0)
&& (($user->manages_users_count ?? $user->managesUsers()->count()) === 0)
&& (($user->manages_locations_count ?? $user->managedLocations()->count()) === 0);
}
}
+224 -201
View File
@@ -2,29 +2,32 @@
namespace App\Console\Commands;
use Illuminate\Console\Command;
use App\Models\Ldap;
use App\Models\Setting;
use Exception;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Crypt;
use App\Models\Ldap;
/**
* Check if a given ip is in a network
* @param string $ip IP to check in IPV4 format eg. 127.0.0.1
* @param string $range IP/CIDR netmask eg. 127.0.0.0/24, also 127.0.0.1 is accepted and /32 assumed
* @return boolean true if the ip is in this range / false if not.
*
* @param string $ip IP to check in IPV4 format eg. 127.0.0.1
* @param string $range IP/CIDR netmask eg. 127.0.0.0/24, also 127.0.0.1 is accepted and /32 assumed
* @return bool true if the ip is in this range / false if not.
*/
function ip_in_range( $ip, $range ) {
if ( strpos( $range, '/' ) == false ) {
$range .= '/32';
}
// $range is in IP/CIDR format eg 127.0.0.1/24
list( $range, $netmask ) = explode( '/', $range, 2 );
$range_decimal = ip2long( $range );
$ip_decimal = ip2long( $ip );
$wildcard_decimal = pow( 2, ( 32 - $netmask ) ) - 1;
$netmask_decimal = ~ $wildcard_decimal;
return ( ( $ip_decimal & $netmask_decimal ) == ( $range_decimal & $netmask_decimal ) );
function ip_in_range($ip, $range)
{
if (strpos($range, '/') == false) {
$range .= '/32';
}
// $range is in IP/CIDR format eg 127.0.0.1/24
[$range, $netmask] = explode('/', $range, 2);
$range_decimal = ip2long($range);
$ip_decimal = ip2long($ip);
$wildcard_decimal = pow(2, (32 - $netmask)) - 1;
$netmask_decimal = ~$wildcard_decimal;
return ($ip_decimal & $netmask_decimal) == ($range_decimal & $netmask_decimal);
}
// NOTE - this function was shamelessly stolen from this gist: https://gist.github.com/tott/7684443
@@ -33,10 +36,10 @@ function ip_in_range( $ip, $range ) {
*/
function parenthesized_filter($filter)
{
if(substr($filter,0,1) == "(" ) {
if (substr($filter, 0, 1) == '(') {
return $filter;
} else {
return "(".$filter.")";
return '('.$filter.')';
}
}
@@ -74,41 +77,44 @@ class LdapTroubleshooter extends Command
/**
* Output something *only* if debug is enabled
*
*
* @return void
*/
public function debugout($string)
{
if($this->option('debug')) {
if ($this->option('debug')) {
$this->line($string);
}
}
/**
* Clean the results from ldap_get_entries into something useful
* @param array $array
*
* @param array $array
* @return array
*/
public function ldap_results_cleaner ($array) {
public function ldap_results_cleaner($array)
{
$cleaned = [];
for($i = 0; $i < $array['count']; $i++) {
for ($i = 0; $i < $array['count']; $i++) {
$row = $array[$i];
$clean_row = [];
foreach($row AS $key => $val ) {
$this->debugout("Key is: ".$key);
if($key == "count" || is_int($key) || $key == "dn") {
foreach ($row as $key => $val) {
$this->debugout('Key is: '.$key);
if ($key == 'count' || is_int($key) || $key == 'dn') {
$this->debugout(" and we're gonna skip it\n");
continue;
}
$this->debugout(" And that seems fine.\n");
if(array_key_exists('count',$val)) {
if($val['count'] == 1) {
if (array_key_exists('count', $val)) {
if ($val['count'] == 1) {
$clean_row[$key] = $val[0];
} else {
unset($val['count']); //these counts are annoying
unset($val['count']); // these counts are annoying
$elements = [];
foreach($val as $entry) {
if(isset($ldap_constants[$entry])) {
foreach ($val as $entry) {
if (isset($ldap_constants[$entry])) {
$elements[] = $ldap_constants[$entry];
} else {
$elements[] = $entry;
@@ -122,6 +128,7 @@ class LdapTroubleshooter extends Command
}
$cleaned[$i] = $clean_row;
}
return $cleaned;
}
@@ -132,58 +139,58 @@ class LdapTroubleshooter extends Command
*/
public function handle()
{
if($this->option('trace')) {
ldap_set_option(NULL, LDAP_OPT_DEBUG_LEVEL, 7);
if ($this->option('trace')) {
ldap_set_option(null, LDAP_OPT_DEBUG_LEVEL, 7);
}
$settings = Setting::getSettings();
$this->settings = $settings;
if($this->option('ldap-search')) {
if(!$this->option('force')) {
if ($this->option('ldap-search')) {
if (! $this->option('force')) {
$confirmation = $this->confirm('WARNING: This command will display your LDAP password on your terminal. Are you sure this is ok?');
if(!$confirmation) {
if (! $confirmation) {
$this->error('ABORTING');
exit(-1);
}
}
$output = [];
if($settings->ldap_server_cert_ignore) {
$this->line("# Ignoring server certificate validity");
$output[] = "LDAPTLS_REQCERT=never";
if ($settings->ldap_server_cert_ignore) {
$this->line('# Ignoring server certificate validity');
$output[] = 'LDAPTLS_REQCERT=never';
}
if($settings->ldap_client_tls_cert && $settings->ldap_client_tls_key) {
$this->line("# Adding LDAP Client Certificate and Key");
$output[] = "LDAPTLS_CERT=storage/ldap_client_tls.cert";
$output[] = "LDAPTLS_KEY=storage/ldap_client_tls.key";
if ($settings->ldap_client_tls_cert && $settings->ldap_client_tls_key) {
$this->line('# Adding LDAP Client Certificate and Key');
$output[] = 'LDAPTLS_CERT=storage/ldap_client_tls.cert';
$output[] = 'LDAPTLS_KEY=storage/ldap_client_tls.key';
}
$output[] = "ldapsearch";
$output[] = "-H ".$settings->ldap_server;
$output[] = "-x";
$output[] = "-b ".escapeshellarg($settings->ldap_basedn);
$output[] = "-D ".escapeshellarg($settings->ldap_uname);
$output[] = 'ldapsearch';
$output[] = '-H '.$settings->ldap_server;
$output[] = '-x';
$output[] = '-b '.escapeshellarg($settings->ldap_basedn);
$output[] = '-D '.escapeshellarg($settings->ldap_uname);
try {
$w = Crypt::Decrypt($settings->ldap_pword);
} catch (\Exception $e) {
$this->warn("Could not decrypt password. This usually means an LDAP password was not set or the APP_KEY was changed since the LDAP pasword was last saved. Aborting.");
} catch (Exception $e) {
$this->warn('Could not decrypt password. This usually means an LDAP password was not set or the APP_KEY was changed since the LDAP pasword was last saved. Aborting.');
exit(0);
}
$output[] = "-w ". escapeshellarg($w);
$output[] = '-w '.escapeshellarg($w);
$output[] = escapeshellarg(parenthesized_filter($settings->ldap_filter));
if($settings->ldap_tls) {
$this->line("# adding STARTTLS option");
$output[] = "-Z";
if ($settings->ldap_tls) {
$this->line('# adding STARTTLS option');
$output[] = '-Z';
}
$output[] = "-v";
$output[] = '-v';
$this->line("\n");
$this->line(implode(" \\\n",$output));
$this->line(implode(" \\\n", $output));
exit(0);
}
//PHP Version check for warning
// PHP Version check for warning
$php_version = phpversion();
list($major, $minor, $patch) = explode('.', $php_version);
[$major, $minor, $patch] = explode('.', $php_version);
if (
$major < 8 ||
($major == 8 && $minor < 3) ||
@@ -191,22 +198,22 @@ class LdapTroubleshooter extends Command
($major == 8 && $minor == 4 && $patch < 7)
) {
$this->warn("PHP Version: $php_version WARNING - Versions before 8.3.21 or 8.4.7 will return INCONSISTENT results!");
if (!$this->confirm("Are you sure you wish to continue?")) {
$this->warn("ABORTING");
if (! $this->confirm('Are you sure you wish to continue?')) {
$this->warn('ABORTING');
exit(-1);
}
}
if(!$this->option('force')) {
if (! $this->option('force')) {
$confirmation = $this->confirm('WARNING: This command will make several attempts to connect to your LDAP server. Are you sure this is ok?');
if(!$confirmation) {
if (! $confirmation) {
$this->error('ABORTING');
exit(-1);
}
}
//$this->line(print_r($settings,true));
$this->line("STAGE 1: Checking settings");
if(!$settings->ldap_enabled) {
// $this->line(print_r($settings,true));
$this->line('STAGE 1: Checking settings');
if (! $settings->ldap_enabled) {
$this->error("WARNING: Snipe-IT's LDAP setting is not turned on. (That may be OK if you're still trying to figure out settings)");
}
@@ -214,123 +221,126 @@ class LdapTroubleshooter extends Command
try {
$ldap_conn = ldap_connect($settings->ldap_server);
} catch (Exception $e) {
$this->error("WARNING: Exception caught when executing 'ldap_connect()' - ".$e->getMessage().". We will try to guess.");
$this->error("WARNING: Exception caught when executing 'ldap_connect()' - ".$e->getMessage().'. We will try to guess.');
}
if(!$ldap_conn) {
$this->error("WARNING: LDAP Server setting of: ".$settings->ldap_server." cannot be parsed. We will try to guess.");
//exit(-1);
if (! $ldap_conn) {
$this->error('WARNING: LDAP Server setting of: '.$settings->ldap_server.' cannot be parsed. We will try to guess.');
// exit(-1);
}
//since we never use $ldap_conn again, we don't have to ldap_unbind() it (it's not even connected, tbh - that only happens at bind-time)
// since we never use $ldap_conn again, we don't have to ldap_unbind() it (it's not even connected, tbh - that only happens at bind-time)
$parsed = parse_url($settings->ldap_server);
if(@$parsed['scheme'] != 'ldap' && @$parsed['scheme'] != 'ldaps') {
if (@$parsed['scheme'] != 'ldap' && @$parsed['scheme'] != 'ldaps') {
$this->error("WARNING: LDAP URL Scheme of '".@$parsed['scheme']."' is probably incorrect; should usually be ldap or ldaps");
}
if(!@$parsed['host']) {
$this->error("ERROR: Cannot determine hostname or IP from ldap URL: ".$settings->ldap_server.". ABORTING.");
if (! @$parsed['host']) {
$this->error('ERROR: Cannot determine hostname or IP from ldap URL: '.$settings->ldap_server.'. ABORTING.');
exit(-1);
} else {
$this->info("Determined LDAP hostname to be: ".$parsed['host']);
$this->info('Determined LDAP hostname to be: '.$parsed['host']);
}
$raw_ips = [];
if (inet_pton($parsed['host']) !== false) {
$this->line($parsed['host'] . " already looks like an address; skipping DNS lookup");
$this->line($parsed['host'].' already looks like an address; skipping DNS lookup');
$raw_ips[] = $parsed['host'];
} else {
$this->line("Performing DNS lookup of: " . $parsed['host']);
$this->line('Performing DNS lookup of: '.$parsed['host']);
$ips = dns_get_record($parsed['host']);
//$this->info("Host IP is: ".print_r($ips,true));
// $this->info("Host IP is: ".print_r($ips,true));
if (!$ips || count($ips) == 0) {
$this->error("ERROR: DNS lookup of host: " . $parsed['host'] . " has failed. ABORTING.");
if (! $ips || count($ips) == 0) {
$this->error('ERROR: DNS lookup of host: '.$parsed['host'].' has failed. ABORTING.');
exit(-1);
}
$this->debugout("IP's? " . print_r($ips, true));
$this->debugout("IP's? ".print_r($ips, true));
foreach ($ips as $ip) {
if (!isset($ip['ip'])) {
if (! isset($ip['ip'])) {
continue;
}
$raw_ips[] = $ip['ip'];
}
}
foreach ($raw_ips as $ip) {
if ($ip == "127.0.0.1") {
$this->error("WARNING: Using the localhost IP as the LDAP server. This is usually wrong");
if ($ip == '127.0.0.1') {
$this->error('WARNING: Using the localhost IP as the LDAP server. This is usually wrong');
}
if (ip_in_range($ip, '10.0.0.0/8') || ip_in_range($ip, '192.168.0.0/16') || ip_in_range($ip, '172.16.0.0/12')) {
$this->error("WARNING: Using an RFC1918 Private address for LDAP server. This may be correct, but it can be a problem if your Snipe-IT instance is not hosted on your private network");
$this->error('WARNING: Using an RFC1918 Private address for LDAP server. This may be correct, but it can be a problem if your Snipe-IT instance is not hosted on your private network');
}
}
$this->line("STAGE 2: Checking basic network connectivity");
$this->line('STAGE 2: Checking basic network connectivity');
$ports = [636, 389];
if(@$parsed['port'] && !in_array($parsed['port'],$ports)) {
if (@$parsed['port'] && ! in_array($parsed['port'], $ports)) {
$ports[] = $parsed['port'];
}
$open_ports=[];
foreach($ports as $port ) {
$open_ports = [];
foreach ($ports as $port) {
$errno = 0;
$errstr = '';
$timeout = 30.0;
$result = '';
$this->line("Attempting to connect to port: " . $port . " - may take up to $timeout seconds");
$this->line('Attempting to connect to port: '.$port." - may take up to $timeout seconds");
try {
$result = fsockopen($parsed['host'], $port, $errno, $errstr, 30.0);
} catch(Exception $e) {
$this->error("Exception: ".$e->getMessage());
} catch (Exception $e) {
$this->error('Exception: '.$e->getMessage());
}
if($result) {
$this->info("Success!");
if ($result) {
$this->info('Success!');
$open_ports[] = $port;
} else {
$this->error("WARNING: Cannot connect to port: $port - $errstr ($errno)");
}
}
if(count($open_ports) == 0) {
$this->error("ERROR - no open ports. ABORTING.");
if (count($open_ports) == 0) {
$this->error('ERROR - no open ports. ABORTING.');
exit(-1);
}
$this->line("STAGE 3: Determine encryption algorithm, if any");
$this->line('STAGE 3: Determine encryption algorithm, if any');
$ldap_urls = []; // [url, cert-check?, start_tls?]
$pretty_ldap_urls = [];
foreach($open_ports as $port) {
foreach ($open_ports as $port) {
$this->line("Trying TLS first for port $port");
$ldap_url = "ldaps://".$parsed['host'].":$port";
if($this->test_anonymous_bind($ldap_url)) {
$ldap_url = 'ldaps://'.$parsed['host'].":$port";
if ($this->test_anonymous_bind($ldap_url)) {
$this->info("Anonymous bind succesful to $ldap_url!");
$ldap_urls[] = [ $ldap_url, true, false ];
$pretty_ldap_urls[] = [$ldap_url, "enabled", "n/a (no)"];
$ldap_urls[] = [$ldap_url, true, false];
$pretty_ldap_urls[] = [$ldap_url, 'enabled', 'n/a (no)'];
continue; // TODO - lots of copypasta in these if(test_anonymous_bind()) routines...
} else {
$this->error("WARNING: Failed to bind to $ldap_url - trying without certificate checks.");
}
if($this->test_anonymous_bind($ldap_url, false)) {
if ($this->test_anonymous_bind($ldap_url, false)) {
$this->info("Anonymous bind successful to $ldap_url with certificate-checks disabled");
$ldap_urls[] = [$ldap_url, false, false];
$pretty_ldap_urls[] = [$ldap_url, "DISABLED", "n/a (no)"];
$pretty_ldap_urls[] = [$ldap_url, 'DISABLED', 'n/a (no)'];
continue;
} else {
$this->error("WARNING: Failed to bind to $ldap_url with certificate checks disabled. Trying unencrypted with STARTTLS");
}
// now switching to ldap:// URL's from ldaps://
$ldap_url = "ldap://".$parsed['host'].":$port";
$ldap_url = 'ldap://'.$parsed['host'].":$port";
if($this->test_anonymous_bind($ldap_url, true, true)) {
if ($this->test_anonymous_bind($ldap_url, true, true)) {
$this->info("Plain connection to $ldap_url with STARTTLS succesful!");
$ldap_urls[] = [ $ldap_url, true, true ];
$pretty_ldap_urls[] = [$ldap_url, "enabled", "STARTTLS ENABLED"];
$ldap_urls[] = [$ldap_url, true, true];
$pretty_ldap_urls[] = [$ldap_url, 'enabled', 'STARTTLS ENABLED'];
continue;
} else {
$this->error("WARNING: Failed to bind to $ldap_url with STARTTLS enabled. Trying without certificate checks.");
@@ -339,224 +349,235 @@ class LdapTroubleshooter extends Command
if ($this->test_anonymous_bind($ldap_url, false, true)) {
$this->info("Plain connection to $ldap_url with STARTTLS and cert checks *disabled* successful!");
$ldap_urls[] = [$ldap_url, false, true];
$pretty_ldap_urls[] = [$ldap_url, "DISABLED", "STARTTLS ENABLED"];
$pretty_ldap_urls[] = [$ldap_url, 'DISABLED', 'STARTTLS ENABLED'];
continue;
} else {
$this->error("WARNING: Failed to bind to $ldap_url with STARTTLS enabled, and cert checks disabled. Trying without STARTTLS");
}
if($this->test_anonymous_bind($ldap_url)) {
if ($this->test_anonymous_bind($ldap_url)) {
$this->info("Plain connection to $ldap_url succesful!");
$ldap_urls[] = [ $ldap_url, true, false ];
$pretty_ldap_urls[] = [$ldap_url, "n/a", "starttls disabled"];
$ldap_urls[] = [$ldap_url, true, false];
$pretty_ldap_urls[] = [$ldap_url, 'n/a', 'starttls disabled'];
continue;
} else {
$this->error("WARNING: Failed to bind to $ldap_url. Giving up on port $port");
}
}
$this->debugout(print_r($ldap_urls,true));
$this->debugout(print_r($ldap_urls, true));
if(count($ldap_urls) > 0 ) {
if (count($ldap_urls) > 0) {
$this->debugout("Found working LDAP URL's: ");
foreach($ldap_urls as $ldap_url) { // TODO maybe do this as a $this->table() instead?
$this->debugout("LDAP URL: " . $ldap_url[0]);
$this->debugout($ldap_url[0] . ($ldap_url[1] ? " certificate checks enabled" : " certificate checks disabled") . ($ldap_url[2] ? " STARTTLS Enabled " : " STARTTLS Disabled"));
foreach ($ldap_urls as $ldap_url) { // TODO maybe do this as a $this->table() instead?
$this->debugout('LDAP URL: '.$ldap_url[0]);
$this->debugout($ldap_url[0].($ldap_url[1] ? ' certificate checks enabled' : ' certificate checks disabled').($ldap_url[2] ? ' STARTTLS Enabled ' : ' STARTTLS Disabled'));
}
$this->table(["URL", "Cert Checks?", "STARTTLS?"], $pretty_ldap_urls);
$this->table(['URL', 'Cert Checks?', 'STARTTLS?'], $pretty_ldap_urls);
} else {
$this->error("ERROR - no valid LDAP URL's available - ABORTING");
exit(1);
}
$this->line("STAGE 4: Test Administrative Bind for LDAP Sync");
foreach($ldap_urls AS $ldap_url) {
$this->line('STAGE 4: Test Administrative Bind for LDAP Sync');
foreach ($ldap_urls as $ldap_url) {
try {
$w = Crypt::Decrypt($settings->ldap_pword);
} catch (\Exception $e) {
$this->warn("Could not decrypt password. This usually means an LDAP password was not set or the APP_KEY was changed since the LDAP pasword was last saved. Aborting.");
} catch (Exception $e) {
$this->warn('Could not decrypt password. This usually means an LDAP password was not set or the APP_KEY was changed since the LDAP pasword was last saved. Aborting.');
exit(0);
}
$this->test_authed_bind($ldap_url[0], $ldap_url[1], $ldap_url[2], $settings->ldap_uname, $w);
}
$this->line("STAGE 5: Test BaseDN");
//grab all LDAP_ constants and fill up a reversed array mapping from weird LDAP dotted-strings to (Constant Name)
$this->line('STAGE 5: Test BaseDN');
// grab all LDAP_ constants and fill up a reversed array mapping from weird LDAP dotted-strings to (Constant Name)
$all_defined_constants = get_defined_constants();
$ldap_constants = [];
foreach($all_defined_constants AS $key => $val) {
if(starts_with($key,"LDAP_") && is_string($val)) {
foreach ($all_defined_constants as $key => $val) {
if (starts_with($key, 'LDAP_') && is_string($val)) {
$ldap_constants[$val] = $key; // INVERT the meaning here!
}
}
$this->debugout("LDAP constants are: ".print_r($ldap_constants,true));
$this->debugout('LDAP constants are: '.print_r($ldap_constants, true));
foreach($ldap_urls AS $ldap_url) {
foreach ($ldap_urls as $ldap_url) {
try {
$w = Crypt::Decrypt($settings->ldap_pword);
} catch (\Exception $e) {
$this->warn("Could not decrypt password. This usually means an LDAP password was not set or the APP_KEY was changed since the LDAP pasword was last saved. Aborting.");
} catch (Exception $e) {
$this->warn('Could not decrypt password. This usually means an LDAP password was not set or the APP_KEY was changed since the LDAP pasword was last saved. Aborting.');
exit(0);
}
if($this->test_informational_bind($ldap_url[0],$ldap_url[1],$ldap_url[2],$settings->ldap_uname,$w,$settings)) {
$this->info("Success getting informational bind!");
if ($this->test_informational_bind($ldap_url[0], $ldap_url[1], $ldap_url[2], $settings->ldap_uname, $w, $settings)) {
$this->info('Success getting informational bind!');
} else {
$this->error("Unable to get information from bind.");
$this->error('Unable to get information from bind.');
}
}
$this->line("STAGE 6: Test LDAP Login to Snipe-IT");
foreach($ldap_urls AS $ldap_url) {
$this->line("Starting auth to " . $ldap_url[0]);
while(true) {
$with_tls = $ldap_url[1] ? "with": "without";
$with_startssl = $ldap_url[2] ? "using": "not using";
if(!$this->confirm('Do you wish to try to authenticate to this directory: '.$ldap_url[0]." $with_tls TLS and $with_startssl STARTSSL?")) {
$this->line('STAGE 6: Test LDAP Login to Snipe-IT');
foreach ($ldap_urls as $ldap_url) {
$this->line('Starting auth to '.$ldap_url[0]);
while (true) {
$with_tls = $ldap_url[1] ? 'with' : 'without';
$with_startssl = $ldap_url[2] ? 'using' : 'not using';
if (! $this->confirm('Do you wish to try to authenticate to this directory: '.$ldap_url[0]." $with_tls TLS and $with_startssl STARTSSL?")) {
break;
}
$username = $this->ask("Username");
$password = $this->secret("Password");
$username = $this->ask('Username');
$password = $this->secret('Password');
$results = $this->test_authed_bind($ldap_url[0], $ldap_url[1], $ldap_url[2], $username, $password); // FIXME - should do some other stuff here, maybe with the concatenating or something? maybe? and/or should put up some results?
if ($results) {
$this->info("Success authenticating with " . $username);
$this->info('Success authenticating with '.$username);
} else {
$this->error("Unable to authenticate with " . $username);
$this->error('Unable to authenticate with '.$username);
}
}
}
$this->info("LDAP TROUBLESHOOTING COMPLETE!");
$this->info('LDAP TROUBLESHOOTING COMPLETE!');
}
public function connect_to_ldap($ldap_url, $check_cert, $start_tls)
public function connect_to_ldap($ldap_url, $check_cert, $start_tls)
{
if ($check_cert) {
$this->line("we *ARE* checking certs");
$this->line('we *ARE* checking certs');
Ldap::ignoreCertificates(false);
} else {
$this->line("we are IGNORING certs");
$this->line('we are IGNORING certs');
Ldap::ignoreCertificates(true);
}
$lconn = ldap_connect($ldap_url);
ldap_set_option($lconn, LDAP_OPT_PROTOCOL_VERSION, 3); // should we 'test' different protocol versions here? Does anyone even use anything other than LDAPv3?
// no - it's formally deprecated: https://tools.ietf.org/html/rfc3494
if($this->settings->ldap_client_tls_cert && $this->settings->ldap_client_tls_key) {
// no - it's formally deprecated: https://tools.ietf.org/html/rfc3494
if ($this->settings->ldap_client_tls_cert && $this->settings->ldap_client_tls_key) {
// client-side TLS certificate support for LDAP (Google Secure LDAP)
putenv('LDAPTLS_CERT=storage/ldap_client_tls.cert');
putenv('LDAPTLS_KEY=storage/ldap_client_tls.key');
}
if($start_tls) {
if(!ldap_start_tls($lconn)) {
$this->error("WARNING: Unable to start TLS");
if ($start_tls) {
if (! ldap_start_tls($lconn)) {
$this->error('WARNING: Unable to start TLS');
return false;
}
}
if(!$lconn) {
$this->error("WARNING: Failed to generate connection string - using: ".$ldap_url);
if (! $lconn) {
$this->error('WARNING: Failed to generate connection string - using: '.$ldap_url);
return false;
}
$net = ldap_set_option($lconn, LDAP_OPT_NETWORK_TIMEOUT, $this->option('timeout'));
$time = ldap_set_option($lconn, LDAP_OPT_TIMELIMIT, $this->option('timeout'));
if(!$net || !$time) {
$this->error("Unable to set timeouts!");
if (! $net || ! $time) {
$this->error('Unable to set timeouts!');
}
return $lconn;
}
public function test_anonymous_bind($ldap_url, $check_cert = true, $start_tls = false)
{
return $this->timed_boolean_execute(function () use ($ldap_url, $check_cert , $start_tls) {
return $this->timed_boolean_execute(function () use ($ldap_url, $check_cert, $start_tls) {
try {
$lconn = $this->connect_to_ldap($ldap_url, $check_cert, $start_tls);
$this->line("Attempting to bind now, this can take a while if we mess it up");
$this->line('Attempting to bind now, this can take a while if we mess it up');
$bind_results = ldap_bind($lconn);
$this->line("Bind results are: " . $bind_results . " which translate into boolean: " . (bool)$bind_results);
$this->line('Bind results are: '.$bind_results.' which translate into boolean: '.(bool) $bind_results);
ldap_close($lconn);
return (bool)$bind_results;
return (bool) $bind_results;
} catch (Exception $e) {
$this->error("WARNING: Exception caught during bind - ".$e->getMessage());
$this->error('WARNING: Exception caught during bind - '.$e->getMessage());
return false;
}
});
}
public function test_authed_bind($ldap_url, $check_cert, $start_tls, $username, $password)
public function test_authed_bind($ldap_url, $check_cert, $start_tls, $username, $password)
{
return $this->timed_boolean_execute(function () use ($ldap_url, $check_cert, $start_tls, $username, $password) {
try {
$lconn = $this->connect_to_ldap($ldap_url, $check_cert, $start_tls);
$bind_results = ldap_bind($lconn, $username, $password);
ldap_close($lconn);
if(!$bind_results) {
if (! $bind_results) {
$this->error("WARNING: Failed to bind to $ldap_url as $username");
return false;
} else {
$this->info("SUCCESS - Able to bind to $ldap_url as $username");
return (bool)$lconn;
return (bool) $lconn;
}
} catch (Exception $e) {
$this->error("WARNING: Exception caught during Authed bind to $username - ".$e->getMessage());
return false;
}
});
}
public function test_informational_bind($ldap_url, $check_cert, $start_tls, $username, $password,$settings)
public function test_informational_bind($ldap_url, $check_cert, $start_tls, $username, $password, $settings)
{
return $this->timed_boolean_execute(function () use ($ldap_url, $check_cert, $start_tls, $username, $password, $settings) {
try { // TODO - copypasta'ed from test_authed_bind
$conn = $this->connect_to_ldap($ldap_url, $check_cert, $start_tls);
$bind_results = ldap_bind($conn, $username, $password);
if(!$bind_results) {
if (! $bind_results) {
$this->error("WARNING: Failed to bind to $ldap_url as $username");
return false;
}
$this->info("SUCCESS - Able to bind to $ldap_url as $username");
$cleaned_results = [];
try {
// This _may_ only work for Active Directory?
$result = ldap_read($conn, '', '(objectClass=*)'/* , ['supportedControl']*/);
$result = ldap_read($conn, '', '(objectClass=*)'/* , ['supportedControl'] */);
$results = ldap_get_entries($conn, $result);
$cleaned_results = $this->ldap_results_cleaner($results);
//$this->line(print_r($cleaned_results,true));
// $this->line(print_r($cleaned_results,true));
$default_naming_contexts = $cleaned_results[0]['namingcontexts'];
$this->info("Default Naming Contexts:");
$this->info(implode(", ", $default_naming_contexts));
//okay, great - now how do we display those results? I have no idea.
} catch (\Exception $e) {
$this->info('Default Naming Contexts:');
$this->info(implode(', ', $default_naming_contexts));
// okay, great - now how do we display those results? I have no idea.
} catch (Exception $e) {
$this->error("Unable to get base naming contexts - here's what we *did* get:");
$this->line(print_r($cleaned_results, true));
}
// I don't see why this throws an Exception for Google LDAP, but I guess we ought to try and catch it?
$this->debugout("I guess we're trying to do the ldap search here, but sometimes it takes too long?");
$this->debugout("Base DN is: ".$settings->ldap_basedn." and filter is: ".parenthesized_filter($settings->ldap_filter));
$this->debugout('Base DN is: '.$settings->ldap_basedn.' and filter is: '.parenthesized_filter($settings->ldap_filter));
$search_results = ldap_search($conn, $settings->ldap_basedn, parenthesized_filter($settings->ldap_filter));
$entries = ldap_get_entries($conn, $search_results);
$this->info("Printing first 10 results: ");
$this->info('Printing first 10 results: ');
$pretty_data = array_slice($this->ldap_results_cleaner($entries), 0, 10);
//print_r($data);
// print_r($data);
$headers = [];
foreach ($pretty_data as $row) {
//populate headers
// populate headers
foreach ($row as $key => $value) {
//skip objectsid and objectguid because it junks up output
if ($key == "objectsid" || $key == "objectguid") {
// skip objectsid and objectguid because it junks up output
if ($key == 'objectsid' || $key == 'objectguid') {
continue;
}
if (!in_array($key, $headers)) {
if (! in_array($key, $headers)) {
$headers[] = $key;
}
}
}
$table = [];
//repeat again to populate table
// repeat again to populate table
foreach ($pretty_data as $row) {
$newrow = [];
foreach ($headers as $header) {
if (is_array(@$row[$header])) {
$newrow[] = "[" . implode(", ", $row[$header]) . "]";
$newrow[] = '['.implode(', ', $row[$header]).']';
} else {
$newrow[] = @$row[$header];
}
@@ -565,8 +586,9 @@ class LdapTroubleshooter extends Command
}
$this->table($headers, $table);
} catch (\Exception $e) {
} catch (Exception $e) {
$this->error("WARNING: Exception caught during Authed bind to $username - ".$e->getMessage());
return false;
} finally {
ldap_close($conn);
@@ -575,53 +597,54 @@ class LdapTroubleshooter extends Command
}
/***********************************************
*
* This function executes $function - which is expected to be some kind of executable function -
*
* This function executes $function - which is expected to be some kind of executable function -
* with a timeout set. It respects the timeout by forking execution and setting a strict timer
* for which to get back a SIGUSR1 or SIGUSR2 signal from the forked process.
*
*
***********************************************/
private function timed_boolean_execute($function)
{
if(!(function_exists('pcntl_sigtimedwait') && function_exists('posix_getpid') && function_exists('pcntl_fork') && function_exists('posix_kill') && function_exists('pcntl_wifsignaled'))) {
if (! (function_exists('pcntl_sigtimedwait') && function_exists('posix_getpid') && function_exists('pcntl_fork') && function_exists('posix_kill') && function_exists('pcntl_wifsignaled'))) {
// POSIX functions needed for forking aren't present, just run the function inline (ignoring timeout)
$this->line('WARNING: Unable to execute POSIX fork() commands, timeout may not be respected');
return $function();
} else {
$parent_pid = posix_getpid();
$pid = pcntl_fork();
switch($pid) {
switch ($pid) {
case 0:
//we're the 'child'
if($function()) {
//SUCCESS = SIGUSR1
// we're the 'child'
if ($function()) {
// SUCCESS = SIGUSR1
posix_kill($parent_pid, SIGUSR1);
} else {
//FAILURE = SIGUSR2
// FAILURE = SIGUSR2
posix_kill($parent_pid, SIGUSR2);
}
exit();
break; //yes I know we don't need it.
break; // yes I know we don't need it.
case -1:
//couldn't fork
$this->error("COULD NOT FORK - assuming failure");
// couldn't fork
$this->error('COULD NOT FORK - assuming failure');
return false;
break; //I still know that we don't need it
break; // I still know that we don't need it
default:
//we remain the 'parent', $pid is the PID of the forked process.
// we remain the 'parent', $pid is the PID of the forked process.
$siginfo = [];
$exit_status = pcntl_sigtimedwait ([SIGUSR1, SIGUSR2], $siginfo, $this->option('timeout'));
$exit_status = pcntl_sigtimedwait([SIGUSR1, SIGUSR2], $siginfo, $this->option('timeout'));
if ($exit_status == SIGUSR1) {
return true;
} else {
posix_kill($pid, SIGKILL); //make sure we don't have processes hanging around that might try and send signals during later executions, confusing us
posix_kill($pid, SIGKILL); // make sure we don't have processes hanging around that might try and send signals during later executions, confusing us
return false;
}
break; //Yeah I get it already, shush.
break; // Yeah I get it already, shush.
}
}
}
}
@@ -44,19 +44,15 @@ class MergeUsersByUsername extends Command
$users = User::where('username', 'LIKE', '%@%')->whereNull('deleted_at')->get();
$this->info($users->count().' total non-deleted users whose usernames contain a @ symbol.');
foreach ($users as $user) {
$parts = explode('@', trim($user->username));
$this->info('Checking against username '.trim($parts[0]).'.');
$bad_users = User::where('username', '=', trim($parts[0]))
->whereNull('deleted_at')
->with('assets', 'manager', 'userlog', 'licenses', 'consumables', 'accessories', 'managedLocations','uploads', 'acceptances')
->with('assets', 'manager', 'userlog', 'licenses', 'consumables', 'accessories', 'managedLocations', 'uploads', 'acceptances')
->get();
foreach ($bad_users as $bad_user) {
$this->info($bad_user->username.' ('.$bad_user->id.') will be merged into '.$user->username.' ('.$user->id.') ');
@@ -125,7 +121,6 @@ class MergeUsersByUsername extends Command
event(new UserMerged($bad_user, $user, null));
}
}
}
@@ -0,0 +1,73 @@
<?php
namespace App\Console\Commands;
use App\Enums\ActionType;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Str;
class MigrateLicenseSeatQuantitiesInActionLogs extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'snipeit:migrate-license-seat-quantities-in-action-logs
{--no-interaction: Do not ask any interactive question}';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Updates quantity field in action_logs table for license seats that were added or deleted.';
/**
* Execute the console command.
*/
public function handle()
{
$query = DB::table('action_logs')
->whereIn('action_type', [
ActionType::AddSeats->value,
ActionType::DeleteSeats->value,
])
->where('quantity', '=', 1)
->orderBy('id');
$count = $query->count();
if ($count === 0) {
$this->info('Nothing to update');
return 0;
}
$this->info("{$count} logs to update");
if ($this->option('no-interaction') || $this->confirm('Update quantities in the action log?')) {
$query->chunk(50, function ($logs) {
$logs->each(function ($log) {
$quantityFromNote = Str::between($log->note, 'ed ', ' seats');
if (! is_numeric($quantityFromNote)) {
$this->error('Could not parse quantity from ID: {id}', ['id' => $log->id]);
}
if ($log->quantity !== (int) $quantityFromNote) {
$this->info(vsprintf('Updating id: %s to quantity %s', [
'id' => $log->id,
'new_quantity' => $quantityFromNote,
]));
DB::table('action_logs')->where('id', $log->id)->update(['quantity' => (int) $quantityFromNote]);
}
});
});
}
return 0;
}
}
+41 -45
View File
@@ -3,8 +3,8 @@
namespace App\Console\Commands;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Storage;
class MoveUploadsToNewDisk extends Command
{
@@ -47,30 +47,29 @@ class MoveUploadsToNewDisk extends Command
}
$delete_local = $this->argument('delete_local');
$public_uploads['accessories'] = glob('public/uploads/accessories'."/*.*");
$public_uploads['assets'] = glob('public/uploads/assets'."/*.*");
$public_uploads['avatars'] = glob('public/uploads/avatars'."/*.*");
$public_uploads['categories'] = glob('public/uploads/categories'."/*.*");
$public_uploads['companies'] = glob('public/uploads/companies'."/*.*");
$public_uploads['components'] = glob('public/uploads/components'."/*.*");
$public_uploads['consumables'] = glob('public/uploads/consumables'."/*.*");
$public_uploads['departments'] = glob('public/uploads/departments'."/*.*");
$public_uploads['locations'] = glob('public/uploads/locations'."/*.*");
$public_uploads['manufacturers'] = glob('public/uploads/manufacturers'."/*.*");
$public_uploads['suppliers'] = glob('public/uploads/suppliers'."/*.*");
$public_uploads['assetmodels'] = glob('public/uploads/models'."/*.*");
$public_uploads['accessories'] = glob('public/uploads/accessories'.'/*.*');
$public_uploads['assets'] = glob('public/uploads/assets'.'/*.*');
$public_uploads['avatars'] = glob('public/uploads/avatars'.'/*.*');
$public_uploads['categories'] = glob('public/uploads/categories'.'/*.*');
$public_uploads['companies'] = glob('public/uploads/companies'.'/*.*');
$public_uploads['components'] = glob('public/uploads/components'.'/*.*');
$public_uploads['consumables'] = glob('public/uploads/consumables'.'/*.*');
$public_uploads['departments'] = glob('public/uploads/departments'.'/*.*');
$public_uploads['locations'] = glob('public/uploads/locations'.'/*.*');
$public_uploads['manufacturers'] = glob('public/uploads/manufacturers'.'/*.*');
$public_uploads['suppliers'] = glob('public/uploads/suppliers'.'/*.*');
$public_uploads['assetmodels'] = glob('public/uploads/models'.'/*.*');
// iterate files
foreach ($public_uploads as $public_type => $public_upload) {
$type_count = 0;
$this->info('- There are ' . count($public_upload) . ' PUBLIC ' . $public_type . ' files.');
$this->info('- There are '.count($public_upload).' PUBLIC '.$public_type.' files.');
for ($i = 0; $i < count($public_upload); $i++) {
$type_count++;
$filename = basename($public_upload[$i]);
try {
try {
Storage::disk('public')->put('uploads/'.$public_type.'/'.$filename, file_get_contents($public_upload[$i]));
$new_url = Storage::disk('public')->url('uploads/'.$public_type.'/'.$filename, $filename);
$this->info($type_count.'. PUBLIC: '.$filename.' was copied to '.$new_url);
@@ -81,49 +80,46 @@ class MoveUploadsToNewDisk extends Command
}
}
$logos = glob("public/uploads/setting*.*");
$this->info("- There are ".count($logos).' files that might be logos.');
$logos = glob('public/uploads/setting*.*');
$this->info('- There are '.count($logos).' files that might be logos.');
$type_count = 0;
foreach ($logos as $logo) {
$this->info($logo);
$type_count++;
$filename = basename($logo);
Storage::disk('public')->put('uploads/' . $filename, file_get_contents($logo));
$this->info($type_count . '. LOGO: ' . $filename . ' was copied to ' . env('PUBLIC_AWS_URL') . '/uploads/' . $filename);
Storage::disk('public')->put('uploads/'.$filename, file_get_contents($logo));
$this->info($type_count.'. LOGO: '.$filename.' was copied to '.env('PUBLIC_AWS_URL').'/uploads/'.$filename);
}
$private_uploads['assets'] = glob('storage/private_uploads/assets'."/*.*");
$private_uploads['signatures'] = glob('storage/private_uploads/signatures'."/*.*");
$private_uploads['audits'] = glob('storage/private_uploads/audits'."/*.*");
$private_uploads['assetmodels'] = glob('storage/private_uploads/models'."/*.*");
$private_uploads['imports'] = glob('storage/private_uploads/imports'."/*.*");
$private_uploads['licenses'] = glob('storage/private_uploads/licenses'."/*.*");
$private_uploads['users'] = glob('storage/private_uploads/users'."/*.*");
$private_uploads['backups'] = glob('storage/private_uploads/backups'."/*.*");
$private_uploads['assets'] = glob('storage/private_uploads/assets'.'/*.*');
$private_uploads['signatures'] = glob('storage/private_uploads/signatures'.'/*.*');
$private_uploads['audits'] = glob('storage/private_uploads/audits'.'/*.*');
$private_uploads['assetmodels'] = glob('storage/private_uploads/models'.'/*.*');
$private_uploads['imports'] = glob('storage/private_uploads/imports'.'/*.*');
$private_uploads['licenses'] = glob('storage/private_uploads/licenses'.'/*.*');
$private_uploads['users'] = glob('storage/private_uploads/users'.'/*.*');
$private_uploads['backups'] = glob('storage/private_uploads/backups'.'/*.*');
foreach ($private_uploads as $private_type => $private_upload) {
{
$this->info('- There are ' . count($private_upload) . ' PRIVATE ' . $private_type . ' files.');
$type_count = 0;
for ($x = 0; $x < count($private_upload); $x++) {
$type_count++;
$filename = basename($private_upload[$x]);
$this->info('- There are '.count($private_upload).' PRIVATE '.$private_type.' files.');
try {
Storage::put($private_type . '/' . $filename, file_get_contents($private_upload[$i]));
$new_url = Storage::url($private_type . '/' . $filename, $filename);
$this->info($type_count . '. PRIVATE: ' . $filename . ' was copied to ' . $new_url);
} catch (\Exception $e) {
Log::debug($e);
$this->error($e);
}
$type_count = 0;
for ($x = 0; $x < count($private_upload); $x++) {
$type_count++;
$filename = basename($private_upload[$x]);
try {
Storage::put($private_type.'/'.$filename, file_get_contents($private_upload[$x]));
$new_url = Storage::url($private_type.'/'.$filename, $filename);
$this->info($type_count.'. PRIVATE: '.$filename.' was copied to '.$new_url);
} catch (\Exception $e) {
Log::debug($e);
$this->error($e);
}
}
if ($delete_local == 'true') {
$public_delete_count = 0;
$private_delete_count = 0;
@@ -160,7 +156,7 @@ class MoveUploadsToNewDisk extends Command
}
}
$this->info($public_delete_count . ' PUBLIC local files and ' . $private_delete_count . ' PRIVATE local files were deleted from your filesystem.');
$this->info($public_delete_count.' PUBLIC local files and '.$private_delete_count.' PRIVATE local files were deleted from your filesystem.');
}
}
}
+7 -7
View File
@@ -2,8 +2,8 @@
namespace App\Console\Commands;
use Illuminate\Console\Command;
use App\Models\User;
use Illuminate\Console\Command;
class NormalizeUserNames extends Command
{
@@ -40,13 +40,13 @@ class NormalizeUserNames extends Command
{
$users = User::get();
$this->info($users->count() . ' users');
$this->info($users->count().' users');
foreach ($users as $user) {
$user->first_name = ucwords(strtolower($user->first_name));
$user->last_name = ucwords(strtolower($user->last_name));
$user->email = strtolower($user->email);
$user->save();
foreach ($users as $user) {
$user->first_name = ucwords(strtolower($user->first_name));
$user->last_name = ucwords(strtolower($user->last_name));
$user->email = strtolower($user->email);
$user->save();
}
}
}
+38 -25
View File
@@ -3,13 +3,10 @@
namespace App\Console\Commands;
use Illuminate\Console\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputOption;
use Illuminate\Support\Facades\Log;
use Symfony\Component\Console\Helper\ProgressIndicator;
ini_set('max_execution_time', env('IMPORT_TIME_LIMIT', 600)); //600 seconds = 10 minutes
ini_set('memory_limit', env('IMPORT_MEMORY_LIMIT', '500M'));
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputOption;
/**
* Class ObjectImportCommand
@@ -35,6 +32,11 @@ class ObjectImportCommand extends Command
*/
protected ProgressIndicator $progressIndicator;
/**
* Logger instance with configurable log path
*/
protected $logger;
/**
* Create a new command instance.
*
@@ -52,21 +54,26 @@ class ObjectImportCommand extends Command
*/
public function handle()
{
ini_set('max_execution_time', env('IMPORT_TIME_LIMIT', 600)); // 600 seconds = 10 minutes
ini_set('memory_limit', env('IMPORT_MEMORY_LIMIT', '500M'));
$this->progressIndicator = new ProgressIndicator($this->output);
$filename = $this->argument('filename');
$class = title_case($this->option('item-type'));
$class = ucfirst($this->option('item-type'));
$classString = "App\\Importer\\{$class}Importer";
$importer = new $classString($filename);
$importer->setCallbacks([$this, 'log'], [$this, 'progress'], [$this, 'errorCallback'])
->setCreatedBy($this->option('user_id'))
->setUpdating($this->option('update'))
->setShouldNotify($this->option('send-welcome'))
->setUsernameFormat($this->option('username_format'));
->setCreatedBy($this->option('user_id'))
->setUpdating($this->option('update'))
->setShouldNotify($this->option('send-welcome'))
->setUsernameFormat($this->option('username_format'));
$this->logger = Log::build([
'driver' => 'single',
'path' => $this->option('logfile'),
]);
// This $logFile/useFiles() bit is currently broken, so commenting it out for now
// $logFile = $this->option('logfile');
// Log::useFiles($logFile);
$this->progressIndicator->start('======= Importing Items from '.$filename.' =========');
$importer->import();
@@ -91,17 +98,19 @@ class ObjectImportCommand extends Command
* If a warning message is passed, we'll spit it to the console as well.
*
* @author Daniel Melzter
*
* @since 3.0
* @param string $string
* @param string $level
*
* @param string $string
* @param string $level
*/
public function log($string, $level = 'info')
{
if ($level === 'warning') {
Log::warning($string);
$this->logger->warning($string);
$this->comment($string);
} else {
Log::Info($string);
$this->logger->Info($string);
if ($this->option('verbose')) {
$this->comment($string);
}
@@ -112,7 +121,9 @@ class ObjectImportCommand extends Command
* Get the console command arguments.
*
* @author Daniel Melzter
*
* @since 3.0
*
* @return array
*/
protected function getArguments()
@@ -126,20 +137,22 @@ class ObjectImportCommand extends Command
* Get the console command options.
*
* @author Daniel Melzter
*
* @since 3.0
*
* @return array
*/
protected function getOptions()
{
return [
['email_format', null, InputOption::VALUE_REQUIRED, 'The format of the email addresses that should be generated. Options are firstname.lastname, firstname, filastname', null],
['username_format', null, InputOption::VALUE_REQUIRED, 'The format of the username that should be generated. Options are firstname.lastname, firstname, filastname, email', null],
['logfile', null, InputOption::VALUE_REQUIRED, 'The path to log output to. storage/logs/importer.log by default', storage_path('logs/importer.log')],
['item-type', null, InputOption::VALUE_REQUIRED, 'Item Type To import. Valid Options are Asset, Consumable, Accessory, License, or User', 'Asset'],
['web-importer', null, InputOption::VALUE_NONE, 'Internal: packages output for use with the web importer'],
['user_id', null, InputOption::VALUE_REQUIRED, 'ID of user creating items', 1],
['update', null, InputOption::VALUE_NONE, 'If a matching item is found, update item information'],
['send-welcome', null, InputOption::VALUE_NONE, 'Whether to send a welcome email to any new users that are created.'],
['email_format', null, InputOption::VALUE_REQUIRED, 'The format of the email addresses that should be generated. Options are firstname.lastname, firstname, filastname', null],
['username_format', null, InputOption::VALUE_REQUIRED, 'The format of the username that should be generated. Options are firstname.lastname, firstname, filastname, email', null],
['logfile', null, InputOption::VALUE_REQUIRED, 'The path to log output to. storage/logs/importer.log by default', storage_path('logs/importer.log')],
['item-type', null, InputOption::VALUE_REQUIRED, 'Item Type To import. Valid Options are Asset, Consumable, Accessory, License, or User', 'Asset'],
['web-importer', null, InputOption::VALUE_NONE, 'Internal: packages output for use with the web importer'],
['user_id', null, InputOption::VALUE_REQUIRED, 'ID of user creating items', 1],
['update', null, InputOption::VALUE_NONE, 'If a matching item is found, update item information'],
['send-welcome', null, InputOption::VALUE_NONE, 'Whether to send a welcome email to any new users that are created.'],
];
}
}
+8 -9
View File
@@ -2,11 +2,10 @@
namespace App\Console\Commands;
use App\Models\Asset;
use App\Models\CustomField;
use Illuminate\Support\Facades\Schema;
use Illuminate\Support\Facades\DB;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Schema;
class PaveIt extends Command
{
@@ -42,9 +41,9 @@ class PaveIt extends Command
public function handle()
{
if (!$this->option('force')) {
if (! $this->option('force')) {
$confirmation = $this->confirm("\n****************************************************\nTHIS WILL DELETE ALL OF THE DATA IN YOUR DATABASE. \nThere is NO undo. This WILL destroy ALL of your data, \nINCLUDING ANY non-Snipe-IT tables you have in this database. \n****************************************************\n\nDo you wish to continue? No backsies! ");
if (!$confirmation) {
if (! $confirmation) {
$this->error('ABORTING');
exit(-1);
}
@@ -79,16 +78,16 @@ class PaveIt extends Command
foreach ($tables as $table_obj) {
$table = $table_obj['name'];
if (in_array($table, $except_tables)) {
$this->info($table. ' is SKIPPED.');
$this->info($table.' is SKIPPED.');
} else {
\DB::statement('truncate '.$table);
$this->info($table. ' is TRUNCATED.');
$this->info($table.' is TRUNCATED.');
}
}
// Leave in the demo oauth keys so we don't have to reset them every day in the demos
DB::statement('delete from oauth_clients WHERE id > 2');
DB::statement('delete from oauth_access_tokens WHERE user_id > 2');
}
}
}
+4 -4
View File
@@ -149,13 +149,13 @@ class Purge extends Command
$filenames = Actionlog::where('action_type', 'uploaded')
->where('item_id', $user->id)
->pluck('filename');
foreach($filenames as $filename) {
foreach ($filenames as $filename) {
try {
if (Storage::exists($rel_path . '/' . $filename)) {
Storage::delete($rel_path . '/' . $filename);
if (Storage::exists($rel_path.'/'.$filename)) {
Storage::delete($rel_path.'/'.$filename);
}
} catch (\Exception $e) {
Log::info('An error occurred while deleting files: ' . $e->getMessage());
Log::info('An error occurred while deleting files: '.$e->getMessage());
}
}
$this->info('- User "'.$user->username.'" deleted.');
+155
View File
@@ -0,0 +1,155 @@
<?php
namespace App\Console\Commands;
use App\Models\CheckoutAcceptance;
use Carbon\Carbon;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Storage;
class PurgeEulaPDFs extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'snipeit:purge-eula-pdfs
{--older-than-days= : The number of days we should delete before }
{--company-id= : Only purge acceptances for users in this company}
{--only-deleted-users : Only purge acceptances for deleted users, including soft-deleted or missing users}
{--force : Skip the interactive yes/no prompt for confirmation}
{--dryrun : Show the records that would be deleted but don\'t update the database or delete files from disk}
{--with-output : Display the results in a table in your console}';
/**
* The console command description.
*
* @var string
*/
protected $description = 'This purges signature files and EULAs from the system if they are older than the date passed with --older-than-days=.';
/**
* Execute the console command.
*/
public function handle()
{
$before = $this->option('older-than-days');
if (($before == '') || (! is_numeric($before))) {
return $this->error('ERROR: You must pass a valid number for --older-than-days (example: snipeit:purge-eula-pdfs --older-than-days=365.)');
}
$interval_date = Carbon::now()->subDays($before);
$signature_path = 'private_uploads/signatures/';
$eula_path = 'private_uploads/eula-pdfs/';
if (! Storage::exists($eula_path)) {
$this->fail('The storage directory "'.$eula_path.'" does not exist. No EULA files will be deleted.');
}
if (! Storage::exists($signature_path)) {
$this->fail('The storage directory "'.$signature_path.'" does not exist. No signature files will be deleted.');
}
if ($this->option('dryrun')) {
$this->info('This script is being run with the --dryrun option. No files or records will be deleted.');
}
$companyId = $this->option('company-id');
$query = CheckoutAcceptance::HasFiles()->where('updated_at', '<', $interval_date)
->with([
'assignedTo' => function ($query) {
$query->withTrashed();
},
]);
if ($this->option('only-deleted-users')) {
$query->where(function ($query) use ($companyId) {
$query->whereHas('assignedTo', function ($q) use ($companyId) {
$q->withTrashed()->whereNotNull('deleted_at');
if ($companyId) {
$q->where('company_id', $companyId);
}
});
$query->orWhereDoesntHave('assignedTo');
});
} else {
if ($companyId) {
$query->whereHas('assignedTo', function ($query) use ($companyId) {
$query->withTrashed()->where('company_id', $companyId);
});
}
}
$acceptances = $query->get();
if (! $this->option('force')) {
if ($this->confirm("\n****************************************************\nTHIS WILL DELETE ALL OF THE SIGNATURES AND EULA PDF FILES SINCE $interval_date. \nThere is NO undo! \n****************************************************\n\nDo you wish to continue? No backsies! [y|N]")) {
}
}
if ($acceptances->count() == 0) {
return $this->warn('There are no item acceptances with signatures or EULA PDFs from before '.$interval_date);
}
$this->info(number_format($acceptances->count()).' EULA PDFs from before '.$interval_date.' will be purged');
if (! $this->option('with-output')) {
$this->info('Run this command with the --with-output option to see the full list in the console.');
} else {
$this->table(
[
trans('general.user'),
trans('general.type'),
trans('general.item'),
trans('general.category'),
trans('general.accepted_date'),
trans('general.declined_date'),
trans('general.signature'),
trans('general.filename'),
],
$acceptances->map(fn ($acceptance) => [
trans('general.user') => $acceptance->assignedTo->display_name,
trans('general.type') => $acceptance->display_checkoutable_type,
trans('general.item') => $acceptance->checkoutable_type::find($acceptance->checkoutable_id)->display_name,
trans('general.category') => $acceptance->checkoutable_category_name,
trans('general.accepted_date') => $acceptance->accepted_at,
trans('general.declined_date') => $acceptance->declined_at,
trans('general.signature') => $acceptance->signature_filename,
trans('general.filename') => $acceptance->stored_eula_file,
])
);
}
foreach ($acceptances as $acceptance) {
$signature_file = $signature_path.$acceptance->signature_filename;
$eula_file = $eula_path.$acceptance->stored_eula_file;
if (Storage::exists($signature_file)) {
if (! $this->option('dryrun')) {
Storage::delete($signature_file);
}
} else {
$this->error('The file "'.$signature_file.'" does not exist.');
}
if (Storage::exists($eula_file)) {
if (! $this->option('dryrun')) {
Storage::delete($eula_file);
}
} else {
$this->error('The file "'.$eula_file.'" does not exist.');
}
if (! $this->option('dryrun')) {
$acceptance->delete();
}
}
}
}
@@ -82,10 +82,10 @@ class ReEncodeCustomFieldNames extends Command
if ($field->db_column == $field->convertUnicodeDbSlug() && \Schema::hasColumn('assets', $field->convertUnicodeDbSlug())) {
$this->info('-- ✓ This field exists on the assets table and the value for db_column matches in the custom_fields table.');
/**
* There is a mismatch between the fieldname on the assets table and
* what $field->convertUnicodeDbSlug() is *now* expecting.
*/
/**
* There is a mismatch between the fieldname on the assets table and
* what $field->convertUnicodeDbSlug() is *now* expecting.
*/
} else {
if ($field->db_column != $field->convertUnicodeDbSlug()) {
@@ -96,7 +96,6 @@ class ReEncodeCustomFieldNames extends Command
}
/** Make sure the custom_field_columns array has the ID */
if (array_key_exists($field->id, $custom_field_columns)) {
@@ -114,7 +113,6 @@ class ReEncodeCustomFieldNames extends Command
$field->db_column = $field->convertUnicodeDbSlug();
$field->save();
} else {
$this->warn('-- ✘ WARNING: There is no field on the assets table ending in '.$field->id.'. This may require more in-depth investigation and may mean the schema was altered manually.');
}
+1 -1
View File
@@ -4,8 +4,8 @@ namespace App\Console\Commands;
use App\Models\Asset;
use App\Models\Setting;
use Illuminate\Support\Facades\Artisan;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Artisan;
class RegenerateAssetTags extends Command
{
+2 -2
View File
@@ -44,7 +44,7 @@ class RemoveExplicitEols extends Command
}
$endTime = microtime(true);
$executionTime = ($endTime - $startTime);
$this->info('Command executed in ' . round($executionTime, 2) . ' seconds.');
$this->info('Command executed in '.round($executionTime, 2).' seconds.');
}
private function updateAssets($assets)
@@ -55,6 +55,6 @@ class RemoveExplicitEols extends Command
$asset->save();
}
$this->info($assets->count() . ' Assets updated successfully');
$this->info($assets->count().' Assets updated successfully');
}
}
@@ -0,0 +1,56 @@
<?php
namespace App\Console\Commands;
use App\Models\Actionlog;
use Illuminate\Console\Command;
class RemoveInvalidUploadDeleteActionLogItems extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'snipeit:remove-invalid-upload-delete-action-log-items';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Permanently remove invalid "upload deleted" action log items that have a null filename. This command can potentially result in deleted files being "resurrected" in the UI.';
/**
* Execute the console command.
*/
public function handle()
{
$invalidLogs = Actionlog::query()
->where('action_type', 'upload deleted')
->whereNull('filename')
->withTrashed()
->get();
$this->info("{$invalidLogs->count()} invalid log items found.");
if ($invalidLogs->count() === 0) {
return 0;
}
$this->table(['ID', 'Action Type', 'Item Type', 'Item ID', 'Created At', 'Deleted At'], $invalidLogs->map(fn ($log) => [
$log->id,
$log->action_type,
$log->item_type,
$log->item_id,
$log->created_at,
$log->deleted_at,
])->toArray());
if ($this->confirm("Do you wish to remove {$invalidLogs->count()} log items?")) {
$invalidLogs->each(fn ($log) => $log->forceDelete());
}
return 0;
}
}
+6 -5
View File
@@ -2,7 +2,6 @@
namespace App\Console\Commands;
use App\Models\Setting;
use App\Models\User;
use Illuminate\Console\Command;
@@ -49,14 +48,16 @@ class ResetDemoSettings extends Command
$settings->logo = 'snipe-logo.png';
$settings->alert_email = 'service@snipe-it.io';
$settings->login_note = 'Use `admin` / `password` to login to the demo.';
$settings->header_color = null;
$settings->header_color = '#3c8dbc';
$settings->link_dark_color = '#5fa4cc';
$settings->link_light_color = '#296282;';
$settings->nav_link_color = '#FFFFFF';
$settings->label2_2d_type = 'QRCODE';
$settings->default_currency = 'USD';
$settings->brand = 2;
$settings->ldap_enabled = 0;
$settings->full_multiple_companies_support = 0;
$settings->label2_1d_type = 'C128';
$settings->skin = '';
$settings->email_domain = 'snipeitapp.com';
$settings->email_format = 'filastname';
$settings->username_format = 'filastname';
@@ -75,11 +76,12 @@ class ResetDemoSettings extends Command
$settings->saml_custom_settings = null;
$settings->default_avatar = 'default.png';
$settings->save();
if ($user = User::where('username', '=', 'admin')->first()) {
$user->locale = 'en-US';
$user->enable_confetti = 1;
$user->enable_sounds = 1;
$user->save();
}
@@ -87,5 +89,4 @@ class ResetDemoSettings extends Command
\Storage::disk('public')->put('snipe-logo-lg.png', file_get_contents(public_path('img/demo/snipe-logo-lg.png')));
}
}
+2 -2
View File
@@ -6,9 +6,9 @@ use App\Models\Actionlog;
use App\Models\Asset;
use App\Models\License;
use App\Models\User;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Artisan;
use Illuminate\Support\Facades\DB;
use Illuminate\Console\Command;
class RestoreDeletedUsers extends Command
{
@@ -75,7 +75,7 @@ class RestoreDeletedUsers extends Command
DB::table('assets')
->where('id', $user_log->item_id)
->update(['assigned_to' => $user->id, 'assigned_type'=> User::class]);
->update(['assigned_to' => $user->id, 'assigned_type' => User::class]);
$this->info(' ** Asset '.$user_log->item->id.' ('.$user_log->item->asset_tag.') restored to user '.$user->id.'');
} elseif ($user_log->item_type == License::class) {
+190 -127
View File
@@ -2,13 +2,17 @@
namespace App\Console\Commands;
use enshrined\svgSanitize\Sanitizer;
use Illuminate\Console\Command;
use ZipArchive;
use Illuminate\Support\Facades\Log;
use ZipArchive;
class SQLStreamer {
class SQLStreamer
{
private $input;
private $output;
// embed the prefix here?
public ?string $prefix;
@@ -17,106 +21,112 @@ class SQLStreamer {
public static $buffer_size = 1024 * 1024; // use a 1MB buffer, ought to work fine for most cases?
public array $tablenames = [];
private bool $should_guess = false;
private bool $statement_is_permitted = false;
public function __construct($input, $output, string $prefix = null)
public function __construct($input, $output, ?string $prefix = null)
{
$this->input = $input;
$this->output = $output;
$this->prefix = $prefix;
}
public function parse_sql(string $line): string {
public function parse_sql(string $line): string
{
// take into account the 'start of line or not' setting as an instance variable?
// 'continuation' lines for a permitted statement are PERMITTED.
// remove *only* line-feeds & carriage-returns; helpful for regexes against lines from
// Windows dumps
$line = trim($line, "\r\n");
if($this->statement_is_permitted && $line[0] === ' ') {
return $line . "\n"; //re-add the newline
if ($this->statement_is_permitted && $line[0] === ' ') {
return $line."\n"; // re-add the newline
}
$table_regex = '`?([a-zA-Z0-9_]+)`?';
$allowed_statements = [
"/^(DROP TABLE (?:IF EXISTS )?)`$table_regex(.*)$/" => false,
"/^(CREATE TABLE )$table_regex(.*)$/" => true, //sets up 'continuation'
"/^(CREATE TABLE )$table_regex(.*)$/" => true, // sets up 'continuation'
"/^(LOCK TABLES )$table_regex(.*)$/" => false,
"/^(INSERT INTO )$table_regex(.*)$/" => false,
"/^UNLOCK TABLES/" => false,
'/^UNLOCK TABLES/' => false,
// "/^\\) ENGINE=InnoDB AUTO_INCREMENT=16 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;/" => false, // FIXME not sure what to do here?
"/^\\)[a-zA-Z0-9_= ]*;$/" => false,
'/^\\)[a-zA-Z0-9_= ]*;$/' => false,
// ^^^^^^ that bit should *exit* the 'permitted' block
"/^\\(.*\\)[,;]$/" => false, //older MySQL dump style with one set of values per line
'/^\\(.*\\)[,;]$/' => false, // older MySQL dump style with one set of values per line
/* we *could* have made the ^INSERT INTO blah VALUES$ turn on the capturing state, and closed it with
a ^(blahblah);$ but it's cleaner to not have to manage the state machine. We're just going to
assume that (blahblah), or (blahblah); are values for INSERT and are always acceptable. */
"<^/\*!40101 SET NAMES '?[a-zA-Z0-9_-]+'? \*/;$>" => false, //using weird delimiters (<,>) for readability. allow quoted or unquoted charsets
"<^/\*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' \*/;$>" => false, //same, now handle zero-values
"<^/\*![0-9]{5} SET NAMES '?[a-zA-Z0-9_-]+'? \*/;$>" => false, // using weird delimiters (<,>) for readability. allow quoted or unquoted charsets
"<^/\*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' \*/;$>" => false, // same, now handle zero-values
];
foreach($allowed_statements as $statement => $statechange) {
// $this->info("Checking regex: $statement...\n");
foreach ($allowed_statements as $statement => $statechange) {
// $this->info("Checking regex: $statement...\n");
$matches = [];
if (preg_match($statement,$line,$matches)) {
if (preg_match($statement, $line, $matches)) {
$this->statement_is_permitted = $statechange;
// matches are: 1 => first part of the statement, 2 => tablename, 3 => rest of statement
// (with of course 0 being "the whole match")
if (@$matches[2]) {
// print "Found a tablename! It's: ".$matches[2]."\n";
// print "Found a tablename! It's: ".$matches[2]."\n";
if ($this->should_guess) {
@$this->tablenames[$matches[2]] += 1;
continue; //oh? FIXME
continue; // oh? FIXME
} else {
$cleaned_tablename = \DB::getTablePrefix().preg_replace('/^'.$this->prefix.'/','',$matches[2]);
$line = preg_replace($statement,'$1`'.$cleaned_tablename.'`$3' , $line);
$cleaned_tablename = \DB::getTablePrefix().preg_replace('/^'.$this->prefix.'/', '', $matches[2]);
$line = preg_replace($statement, '$1`'.$cleaned_tablename.'`$3', $line);
}
} else {
// no explicit tablename in this one, leave the line alone
}
//how do we *replace* the tablename?
// print "RETURNING LINE: $line";
return $line . "\n"; //re-add newline
// how do we *replace* the tablename?
// print "RETURNING LINE: $line";
return $line."\n"; // re-add newline
}
}
// all that is not allowed is denied.
return "";
return '';
}
//this is used in exactly *TWO* places, and in both cases should return a prefix I think?
// this is used in exactly *TWO* places, and in both cases should return a prefix I think?
// first - if you do the --sanitize-only one (which is mostly for testing/development)
// next - when you run *without* a guessed prefix, this is run first to figure out the prefix
// I think we have to *duplicate* the call to be able to run it again?
public static function guess_prefix($input):string
public static function guess_prefix($input): string
{
$parser = new self($input, null);
$parser->should_guess = true;
$parser->line_aware_piping(); // <----- THIS is doing the heavy lifting!
$check_tables = ['settings' => null, 'migrations' => null /* 'assets' => null */]; //TODO - move to statics?
//can't use 'users' because the 'accessories_checkout' table?
$check_tables = ['settings' => null, 'migrations' => null /* 'assets' => null */]; // TODO - move to statics?
// can't use 'users' because the 'accessories_checkout' table?
// can't use 'assets' because 'ver1_components_assets'
foreach($check_tables as $check_table => $_ignore) {
foreach ($check_tables as $check_table => $_ignore) {
foreach ($parser->tablenames as $tablename => $_count) {
// print "Comparing $tablename to $check_table\n";
if (str_ends_with($tablename,$check_table)) {
// print "Found one!\n";
$check_tables[$check_table] = substr($tablename,0,-strlen($check_table));
// print "Comparing $tablename to $check_table\n";
if (str_ends_with($tablename, $check_table)) {
// print "Found one!\n";
$check_tables[$check_table] = substr($tablename, 0, -strlen($check_table));
}
}
}
$guessed_prefix = null;
foreach ($check_tables as $clean_table => $prefix_guess) {
if(is_null($prefix_guess)) {
print("Couldn't find table $clean_table\n");
die();
if (is_null($prefix_guess)) {
echo "Couldn't find table $clean_table\n";
exit();
}
if(is_null($guessed_prefix)) {
if (is_null($guessed_prefix)) {
$guessed_prefix = $prefix_guess;
} else {
if ($guessed_prefix != $prefix_guess) {
print("Prefix mismatch! Had guessed $guessed_prefix but got $prefix_guess\n");
die();
echo "Prefix mismatch! Had guessed $guessed_prefix but got $prefix_guess\n";
exit();
}
}
}
@@ -129,7 +139,7 @@ class SQLStreamer {
{
$bytes_read = 0;
if (! $this->input) {
throw new \Exception("No Input available for line_aware_piping");
throw new \Exception('No Input available for line_aware_piping');
}
while (($buffer = fgets($this->input, SQLStreamer::$buffer_size)) !== false) {
@@ -141,25 +151,24 @@ class SQLStreamer {
$bytes_written = fwrite($this->output, $cleaned_buffer);
if ($bytes_written === false) {
throw new \Exception("Unable to write to pipe");
throw new \Exception('Unable to write to pipe');
}
}
}
// if we got a newline at the end of this, then the _next_ read is the beginning of a line
if($buffer[strlen($buffer)-1] === "\n") {
if ($buffer[strlen($buffer) - 1] === "\n") {
$this->reading_beginning_of_line = true;
} else {
$this->reading_beginning_of_line = false;
}
}
return $bytes_read;
}
}
class RestoreFromBackup extends Command
{
/**
@@ -201,7 +210,7 @@ class RestoreFromBackup extends Command
public function handle()
{
$dir = getcwd();
if( $dir != base_path() ) { // usually only the case when running via webserver, not via command-line
if ($dir != base_path()) { // usually only the case when running via webserver, not via command-line
Log::debug("Current working directory is: $dir, changing directory to: ".base_path());
chdir(base_path()); // TODO - is this *safe* to change on a running script?!
}
@@ -220,7 +229,7 @@ class RestoreFromBackup extends Command
return $this->error('DB_CONNECTION must be MySQL in order to perform a restore. Detected: '.config('database.default'));
}
$za = new ZipArchive();
$za = new ZipArchive;
$errcode = $za->open($filename/* , ZipArchive::RDONLY */); // that constant only exists in PHP 7.4 and higher
if ($errcode !== true) {
@@ -239,12 +248,12 @@ class RestoreFromBackup extends Command
return $this->error('Could not access file: '.$filename.' - '.array_key_exists($errcode, $errors) ? $errors[$errcode] : " Unknown reason: $errcode");
}
$private_dirs = [
'storage/private_uploads/accessories',
'storage/private_uploads/assetmodels',
'storage/private_uploads/maintenances',
'storage/private_uploads/models',
'storage/private_uploads/assetmodels' => 'storage/private_uploads/models', // this was changed from assetmodels => models Aug 10 2025
'storage/private_uploads/asset_maintenances' => 'storage/private_uploads/maintenances', // this was changed from asset_maintenances => maintenances Aug 10 2025
'storage/private_uploads/maintenances', // but let 'maintenances' take precedence
'storage/private_uploads/models', // and let 'models' take precedence
'storage/private_uploads/assets', // these are asset _files_, not the pictures.
'storage/private_uploads/audits',
'storage/private_uploads/components',
@@ -262,7 +271,7 @@ class RestoreFromBackup extends Command
];
$public_dirs = [
'public/uploads/accessories',
'public/uploads/assetmodels',
// 'public/uploads/assetmodels' => 'public/uploads/models', //according to git, this was _never_ a thing... (see below)
'public/uploads/maintenances',
'public/uploads/assets', // these are asset _pictures_, not asset files
'public/uploads/avatars',
@@ -273,7 +282,7 @@ class RestoreFromBackup extends Command
'public/uploads/departments',
'public/uploads/locations',
'public/uploads/manufacturers',
'public/uploads/models',
'public/uploads/models', // ...it's been this way for 9 years (as of late 2025)
'public/uploads/suppliers',
];
@@ -286,8 +295,6 @@ class RestoreFromBackup extends Command
'public/uploads/favicon-uploaded.*',
];
$all_files = $private_dirs + $public_dirs;
$sqlfiles = [];
$sqlfile_indices = [];
@@ -295,71 +302,115 @@ class RestoreFromBackup extends Command
$boring_files = [];
$unsafe_files = [];
$good_extensions = config('filesystems.allowed_upload_extensions_array');
$private_extensions = array_merge($good_extensions, ['csv', 'key']); // add csv, and 'key'
$public_extensions = array_diff($good_extensions, ['xml']); // remove xml
$sanitizer = new Sanitizer;
/**
* TODO: I _hate_ the "continue 3" thing we keep doing here
* I think a better approach might be to have the "each file" stuff be in a method on this class, and the
* boring_files and interesting_files be properties on it that we fill out. Then, in that method, we could
* just do a 'return' once the file is actually handled (yay or nay). We could also start to break out some of
* the _other_ things that we do into their own methods too? But I don't care about that as much.
*/
for ($i = 0; $i < $za->numFiles; $i++) {
$stat_results = $za->statIndex($i);
// echo "index: $i\n";
// print_r($stat_results);
$raw_path = $stat_results['name'];
if (strpos($raw_path, '\\') !== false) { //found a backslash, swap it to forward-slash
if (strpos($raw_path, '\\') !== false) { // found a backslash, swap it to forward-slash
$raw_path = strtr($raw_path, '\\', '/');
//print "Translating file: ".$stat_results['name']." to: ".$raw_path."\n";
// print "Translating file: ".$stat_results['name']." to: ".$raw_path."\n";
}
// skip macOS resource fork files (?!?!?!)
if (strpos($raw_path, '__MACOSX') !== false && strpos($raw_path, '._') !== false) {
//print "SKIPPING macOS Resource fork file: $raw_path\n";
$boring_files[] = $raw_path;
// print "SKIPPING macOS Resource fork file: $raw_path\n";
// $boring_files[] = $raw_path; //stop adding this to the boring files list; it's just confusing
continue;
}
if (@pathinfo($raw_path, PATHINFO_EXTENSION) == 'sql') {
Log::debug("Found a sql file!");
Log::debug('Found a sql file!');
$sqlfiles[] = $raw_path;
$sqlfile_indices[] = $i;
continue;
}
if ($raw_path[-1] == '/') {
// last character is '/' - this is a directory, and we don't need it, and we don't need to warn about it
continue;
}
if (in_array(basename($raw_path), ['.gitkeep', '.gitignore', '.DS_Store'])) {
// skip these boring files silently without reporting on them; they're stupid
continue;
}
$extension = strtolower(pathinfo($raw_path, PATHINFO_EXTENSION));
foreach (array_merge($private_dirs, $public_dirs) as $dir) {
$last_pos = strrpos($raw_path, $dir . '/');
if ($last_pos !== false) {
//print("INTERESTING - last_pos is $last_pos when searching $raw_path for $dir - last_pos+strlen(\$dir) is: ".($last_pos+strlen($dir))." and strlen(\$rawpath) is: ".strlen($raw_path)."\n");
//print("We would copy $raw_path to $dir.\n"); //FIXME append to a path?
$interesting_files[$raw_path] = ['dest' => $dir, 'index' => $i];
continue 2;
if ($last_pos + strlen($dir) + 1 == strlen($raw_path)) {
// we don't care about that; we just want files with the appropriate prefix
//print("FOUND THE EXACT DIRECTORY: $dir AT: $raw_path!!!\n");
foreach (['public' => $public_dirs, 'private' => $private_dirs] as $purpose => $dirs) {
$allowed_extensions = match ($purpose) {
'public' => $public_extensions,
'private' => $private_extensions,
};
foreach ($dirs as $dir => $destdir) {
if (is_int($dir)) {
$dir = $destdir;
}
$last_pos = strrpos($raw_path, $dir.'/');
if ($last_pos !== false) {
// print("INTERESTING - last_pos is $last_pos when searching $raw_path for $dir - last_pos+strlen(\$dir) is: ".($last_pos+strlen($dir))." and strlen(\$rawpath) is: ".strlen($raw_path)."\n");
// print("We would copy $raw_path to $dir.\n"); //FIXME append to a path?
// the CSV bit, below, is because we store CSV files as "blahcsv" - without an extension
if (! in_array($extension, $allowed_extensions) && ! ($dir == 'storage/private_uploads/imports' && substr($raw_path, -3) == 'csv' && $extension == '')) {
$unsafe_files[] = $raw_path;
Log::debug($raw_path.' from directory '.$dir.' is being skipped');
} else {
if ($dir != $destdir) {
Log::debug("Getting ready to save file $raw_path to new directory $destdir");
}
$interesting_files[$raw_path] = ['dest' => $destdir, 'index' => $i];
}
continue 3;
}
}
}
$good_extensions = config('filesystems.allowed_upload_extensions_array');
foreach (array_merge($private_files, $public_files) as $file) {
$has_wildcard = (strpos($file, '*') !== false);
if ($has_wildcard) {
$file = substr($file, 0, -1); //trim last character (which should be the wildcard)
}
$last_pos = strrpos($raw_path, $file); // no trailing slash!
if ($last_pos !== false) {
$extension = strtolower(pathinfo($raw_path, PATHINFO_EXTENSION));
if (!in_array($extension, $good_extensions)) {
// gathering potentially unsafe files here to return at exit
$unsafe_files[] = $raw_path;
Log::debug('Potentially unsafe file '.$raw_path.' is being skipped');
$boring_files[] = $raw_path;
continue 2;
foreach (['public' => $public_files, 'private' => $private_files] as $purpose => $files) {
$allowed_extensions = match ($purpose) {
'public' => $public_extensions,
'private' => $private_extensions,
};
foreach ($files as $file) {
$has_wildcard = (strpos($file, '*') !== false);
if ($has_wildcard) {
$file = substr($file, 0, -1); // trim last character (which should be the wildcard)
}
//print("INTERESTING - last_pos is $last_pos when searching $raw_path for $file - last_pos+strlen(\$file) is: ".($last_pos+strlen($file))." and strlen(\$rawpath) is: ".strlen($raw_path)."\n");
//no wildcards found in $file, process 'normally'
if ($last_pos + strlen($file) == strlen($raw_path) || $has_wildcard) { //again, no trailing slash. or this is a wildcard and we just take it.
// print("FOUND THE EXACT FILE: $file AT: $raw_path!!!\n"); //we *do* care about this, though.
$interesting_files[$raw_path] = ['dest' => dirname($file), 'index' => $i];
continue 2;
$last_pos = strrpos($raw_path, $file); // no trailing slash!
if ($last_pos !== false) {
if (! in_array($extension, $allowed_extensions)) {
// gathering potentially unsafe files here to return at exit
$unsafe_files[] = $raw_path;
Log::debug('Potentially unsafe file '.$raw_path.' is being skipped');
$boring_files[] = $raw_path;
continue 3;
}
// print("INTERESTING - last_pos is $last_pos when searching $raw_path for $file - last_pos+strlen(\$file) is: ".($last_pos+strlen($file))." and strlen(\$rawpath) is: ".strlen($raw_path)."\n");
// no wildcards found in $file, process 'normally'
if ($last_pos + strlen($file) == strlen($raw_path) || $has_wildcard) { // again, no trailing slash. or this is a wildcard and we just take it.
// print("FOUND THE EXACT FILE: $file AT: $raw_path!!!\n"); //we *do* care about this, though.
$interesting_files[$raw_path] = ['dest' => dirname($file), 'index' => $i];
continue 3;
}
}
}
}
$boring_files[] = $raw_path; //if we've gotten to here and haven't continue'ed our way into the next iteration, we don't want this file
$boring_files[] = $raw_path; // if we've gotten to here and haven't continue'ed our way into the next iteration, we don't want this file
} // end of pre-processing the ZIP file for-loop
// print_r($interesting_files);exit(-1);
@@ -368,12 +419,12 @@ class RestoreFromBackup extends Command
}
if (strpos($sqlfiles[0], 'db-dumps') === false) {
//return $this->error("SQL backup file is missing 'db-dumps' component of full pathname: ".$sqlfiles[0]);
//older Snipe-IT installs don't have the db-dumps subdirectory component
// return $this->error("SQL backup file is missing 'db-dumps' component of full pathname: ".$sqlfiles[0]);
// older Snipe-IT installs don't have the db-dumps subdirectory component
}
$sql_stat = $za->statIndex($sqlfile_indices[0]);
//$this->info("SQL Stat is: ".print_r($sql_stat,true));
// $this->info("SQL Stat is: ".print_r($sql_stat,true));
$sql_contents = $za->getStream($sql_stat['name']); // maybe copy *THIS* thing?
// OKAY, now that we *found* the sql file if we're doing just the guess-prefix thing, we can do that *HERE* I think?
@@ -388,27 +439,32 @@ class RestoreFromBackup extends Command
if ($this->option('sql-stdout-only')) {
$sql_importer = new SQLStreamer($sql_contents, STDOUT, $this->option('sanitize-with-prefix'));
$bytes_read = $sql_importer->line_aware_piping();
return $this->warn("$bytes_read total bytes read");
//TODO - it'd be nice to dump this message to STDERR so that STDOUT is just pure SQL,
// TODO - it'd be nice to dump this message to STDERR so that STDOUT is just pure SQL,
// which would be good for redirecting to a file, and not having to trim the last line off of it
}
//how to invoke the restore?
// how to invoke the restore?
$pipes = [];
$env_vars = getenv();
$env_vars['MYSQL_PWD'] = config('database.connections.mysql.password');
// TODO notes: we are stealing the dump_binary_path (which *probably* also has your copy of the mysql binary in it. But it might not, so we might need to extend this)
// we unilaterally prepend a slash to the `mysql` command. This might mean your path could look like /blah/blah/blah//mysql - which should be fine. But maybe in some environments it isn't?
$mysql_binary = config('database.connections.mysql.dump.dump_binary_path').\DIRECTORY_SEPARATOR.'mysql'.(\DIRECTORY_SEPARATOR == '\\' ? ".exe" : "");
if( ! file_exists($mysql_binary) ) {
$mysql_binary = config('database.connections.mysql.dump.dump_binary_path').\DIRECTORY_SEPARATOR.'mysql'.(\DIRECTORY_SEPARATOR == '\\' ? '.exe' : '');
if (! file_exists($mysql_binary)) {
return $this->error("mysql tool at: '$mysql_binary' does not exist, cannot restore. Please edit DB_DUMP_PATH in your .env to point to a directory that contains the mysqldump and mysql binary");
}
$proc_results = proc_open("$mysql_binary -h ".escapeshellarg(config('database.connections.mysql.host')).' -u '.escapeshellarg(config('database.connections.mysql.username')).' '.escapeshellarg(config('database.connections.mysql.database')), // yanked -p since we pass via ENV
[0 => ['pipe', 'r'], 1 => ['pipe', 'w'], 2 => ['pipe', 'w']],
$pipes,
null,
$env_vars); // this is not super-duper awesome-secure, but definitely more secure than showing it on the CLI, or dropping temporary files with passwords in them.
$proc_results = proc_open("$mysql_binary -h " .
escapeshellarg(config('database.connections.mysql.host')) .
' -u ' . escapeshellarg(config('database.connections.mysql.username')) . ' ' .
' -P ' . escapeshellarg(config('database.connections.mysql.port')) . ' ' .
escapeshellarg(config('database.connections.mysql.database')), // yanked -p since we pass via ENV
[0 => ['pipe', 'r'], 1 => ['pipe', 'w'], 2 => ['pipe', 'w']],
$pipes,
null,
$env_vars); // this is not super-duper awesome-secure, but definitely more secure than showing it on the CLI, or dropping temporary files with passwords in them.
if ($proc_results === false) {
return $this->error('Unable to invoke mysql via CLI');
}
@@ -422,7 +478,7 @@ class RestoreFromBackup extends Command
// should we read stdout?
// fwrite($pipes[0],config("database.connections.mysql.password")."\n"); //this doesn't work :(
//$sql_contents = fopen($sqlfiles[0], "r"); //NOPE! This isn't a real file yet, silly-billy!
// $sql_contents = fopen($sqlfiles[0], "r"); //NOPE! This isn't a real file yet, silly-billy!
// FIXME - this feels like it wants to go somewhere else?
// and it doesn't seem 'right' - if you can't get a stream to the .sql file,
@@ -437,7 +493,7 @@ class RestoreFromBackup extends Command
}
try {
if ( $this->option('sanitize-with-prefix') === null) {
if ($this->option('sanitize-with-prefix') === null) {
// "Legacy" direct-piping
$bytes_read = 0;
while (($buffer = fgets($sql_contents, SQLStreamer::$buffer_size)) !== false) {
@@ -446,7 +502,7 @@ class RestoreFromBackup extends Command
$bytes_written = fwrite($pipes[0], $buffer);
if ($bytes_written === false) {
throw new Exception("Unable to write to pipe");
throw new Exception('Unable to write to pipe');
}
}
} else {
@@ -454,37 +510,37 @@ class RestoreFromBackup extends Command
$bytes_read = $sql_importer->line_aware_piping();
}
} catch (\Exception $e) {
Log::error("Error during restore!!!! ".$e->getMessage());
Log::error('Error during restore!!!! '.$e->getMessage());
// FIXME - put these back and/or put them in the right places?!
$err_out = fgets($pipes[1]);
$err_err = fgets($pipes[2]);
Log::error("Error OUTPUT: ".$err_out);
Log::error('Error OUTPUT: '.$err_out);
$this->info($err_out);
Log::error("Error ERROR : ".$err_err);
Log::error('Error ERROR : '.$err_err);
$this->error($err_err);
throw $e;
}
if (!feof($sql_contents) || $bytes_read == 0) {
return $this->error("Not at end of file for sql file, or zero bytes read. aborting!");
if (! feof($sql_contents) || $bytes_read == 0) {
return $this->error('Not at end of file for sql file, or zero bytes read. aborting!');
}
fclose($pipes[0]);
fclose($sql_contents);
$this->line(stream_get_contents($pipes[1]));
fclose($pipes[1]);
$this->error(stream_get_contents($pipes[2]));
fclose($pipes[2]);
//wait, have to do fclose() on all pipes first?
// wait, have to do fclose() on all pipes first?
$close_results = proc_close($proc_results);
if ($close_results != 0) {
return $this->error('There may have been a problem with the database import: Error number '.$close_results);
}
//and now copy the files over too (right?)
//FIXME - we don't prune the filesystem space yet!!!!
// and now copy the files over too (right?)
// FIXME - we don't prune the filesystem space yet!!!!
if ($this->option('no-progress')) {
$bar = null;
} else {
@@ -492,18 +548,25 @@ class RestoreFromBackup extends Command
}
foreach ($interesting_files as $pretty_file_name => $file_details) {
$ugly_file_name = $za->statIndex($file_details['index'])['name'];
$fp = $za->getStream($ugly_file_name);
//$this->info("Weird problem, here are file details? ".print_r($file_details,true));
if (!is_dir($file_details['dest'])) {
mkdir($file_details['dest'], 0755, true); //0755 is what Laravel uses, so we do that
$migrated_file_name = $file_details['dest'].'/'.basename($pretty_file_name);
if (strcasecmp(substr($pretty_file_name, -4), '.svg') === 0) {
$svg_contents = $za->getFromIndex($file_details['index']);
$cleaned_svg = $sanitizer->sanitize($svg_contents);
file_put_contents($migrated_file_name, $cleaned_svg);
} else {
$fp = $za->getStream($ugly_file_name);
// $this->info("Weird problem, here are file details? ".print_r($file_details,true));
if (! is_dir($file_details['dest'])) {
mkdir($file_details['dest'], 0755, true); // 0755 is what Laravel uses, so we do that
}
$migrated_file = fopen($migrated_file_name, 'w');
while (($buffer = fgets($fp, SQLStreamer::$buffer_size)) !== false) {
fwrite($migrated_file, $buffer);
}
fclose($migrated_file);
fclose($fp);
// $this->info("Wrote $ugly_file_name to $pretty_file_name");
}
$migrated_file = fopen($file_details['dest'].'/'.basename($pretty_file_name), 'w');
while (($buffer = fgets($fp, SQLStreamer::$buffer_size)) !== false) {
fwrite($migrated_file, $buffer);
}
fclose($migrated_file);
fclose($fp);
//$this->info("Wrote $ugly_file_name to $pretty_file_name");
if ($bar) {
$bar->advance();
}
+15 -13
View File
@@ -5,10 +5,10 @@ namespace App\Console\Commands;
use App\Models\Asset;
use App\Models\CustomField;
use App\Models\Setting;
use Illuminate\Support\Facades\Artisan;
use Illuminate\Console\Command;
use Illuminate\Contracts\Encryption\DecryptException;
use Illuminate\Encryption\Encrypter;
use Illuminate\Support\Facades\Artisan;
class RotateAppKey extends Command
{
@@ -46,12 +46,13 @@ class RotateAppKey extends Command
*/
public function handle()
{
//make sure they specify only exactly one of --emergency, or a filename. Not neither, and not both.
if ( (!$this->option('emergency') && !$this->argument('previous_key')) || ( $this->option('emergency') && $this->argument('previous_key'))) {
$this->error("Specify only one of --emergency, or an app key value, in order to rotate keys");
// make sure they specify only exactly one of --emergency, or a filename. Not neither, and not both.
if ((! $this->option('emergency') && ! $this->argument('previous_key')) || ($this->option('emergency') && $this->argument('previous_key'))) {
$this->error('Specify only one of --emergency, or an app key value, in order to rotate keys');
return 1;
}
if ( $this->option('emergency') ) {
if ($this->option('emergency')) {
$msg = "\n****************************************************\nTHIS WILL MODIFY YOUR APP_KEY AND DE-CRYPT YOUR ENCRYPTED CUSTOM FIELDS AND \nRE-ENCRYPT THEM WITH A NEWLY GENERATED KEY. \n\nThere is NO undo. \n\nMake SURE you have a database backup and a backup of your .env generated BEFORE running this command. \n\nIf you do not save the newly generated APP_KEY to your .env in this process, \nyour encrypted data will no longer be decryptable. \n\nAre you SURE you wish to continue, and have confirmed you have a database backup and an .env backup? ";
} else {
$msg = "\n****************************************************\nTHIS WILL DE-CRYPT YOUR ENCRYPTED CUSTOM FIELDS AND RE-ENCRYPT THEM WITH YOUR\nAPP_KEY.\n\nThere is NO undo. \n\nMake SURE you have a database backup BEFORE running this command. \n\nAre you SURE you wish to continue, and have confirmed you have a database backup? ";
@@ -79,9 +80,9 @@ class RotateAppKey extends Command
$new_app_key = config('app.key');
}
$this->warn('Your app cipher is: ' . $cipher);
$this->warn('Your old APP_KEY is: ' . $old_app_key);
$this->warn('Your new APP_KEY is: ' . $new_app_key);
$this->warn('Your app cipher is: '.$cipher);
$this->warn('Your old APP_KEY is: '.$old_app_key);
$this->warn('Your new APP_KEY is: '.$new_app_key);
// Manually create an old encrypter instance using the old app key
// and also create a new encrypter instance so we can re-crypt the field
@@ -97,12 +98,13 @@ class RotateAppKey extends Command
foreach ($assets as $asset) {
try {
$asset->{$field->db_column} = $oldEncrypter->decrypt($asset->{$field->db_column});
$this->line('DECRYPTED: ' . $field->db_column);
$this->line('DECRYPTED: '.$field->db_column);
} catch (DecryptException $e) {
$this->line('Could not decrypt '. $field->db_column.' using "old key" - skipping...');
$this->line('Could not decrypt '.$field->db_column.' using "old key" - skipping...');
continue;
} catch (\Exception $e) {
$this->error("Error decrypting ".$field->db_column.", reason: ".$e->getMessage().". Aborting key rotation");
$this->error('Error decrypting '.$field->db_column.', reason: '.$e->getMessage().'. Aborting key rotation');
throw $e;
}
$asset->{$field->db_column} = $newEncrypter->encrypt($asset->{$field->db_column});
@@ -119,8 +121,8 @@ class RotateAppKey extends Command
$setting->ldap_pword = $newEncrypter->encrypt($setting->ldap_pword);
$setting->save();
$this->warn('LDAP password has been re-encrypted.');
} catch(DecryptException $e) {
$this->warn("Unable to decrypt old LDAP password; skipping");
} catch (DecryptException $e) {
$this->warn('Unable to decrypt old LDAP password; skipping');
}
}
} else {
@@ -2,8 +2,8 @@
namespace App\Console\Commands;
use Illuminate\Console\Command;
use App\Models\SamlNonce;
use Illuminate\Console\Command;
class SamlClearExpiredNonces extends Command
{
@@ -38,7 +38,8 @@ class SamlClearExpiredNonces extends Command
*/
public function handle()
{
SamlNonce::where('not_valid_after','<=',now())->delete();
SamlNonce::where('not_valid_after', '<=', now())->delete();
return 0;
}
}
+34 -22
View File
@@ -3,13 +3,15 @@
namespace App\Console\Commands;
use App\Mail\UnacceptedAssetReminderMail;
use App\Models\Accessory;
use App\Models\Asset;
use App\Models\CheckoutAcceptance;
use App\Models\Setting;
use App\Models\Component;
use App\Models\Consumable;
use App\Models\LicenseSeat;
use App\Models\User;
use App\Notifications\CheckoutAssetNotification;
use App\Notifications\CurrentInventory;
use Illuminate\Console\Command;
use Illuminate\Database\Eloquent\Relations\MorphTo;
use Illuminate\Support\Facades\Mail;
class SendAcceptanceReminder extends Command
@@ -26,7 +28,7 @@ class SendAcceptanceReminder extends Command
*
* @var string
*/
protected $description = 'This will resend users with unaccepted assets a reminder to accept or decline them.';
protected $description = 'This will resend users with unaccepted items a reminder to accept or decline them.';
/**
* Create a new command instance.
@@ -45,28 +47,39 @@ class SendAcceptanceReminder extends Command
*/
public function handle()
{
$pending = CheckoutAcceptance::pending()->where('checkoutable_type', 'App\Models\Asset')
->whereHas('checkoutable', function($query) {
$query->where('accepted_at', null)
->where('declined_at', null);
})
->with(['assignedTo', 'checkoutable.assignedTo', 'checkoutable.model', 'checkoutable.adminuser'])
->get();
$pending = CheckoutAcceptance::query()
->with([
'checkoutable' => function (MorphTo $morph) {
$morph->morphWith([
Asset::class => ['model.category', 'assignedTo', 'adminuser', 'company', 'checkouts'],
Accessory::class => ['category', 'company', 'checkouts'],
LicenseSeat::class => ['user', 'license', 'checkouts'],
Component::class => ['assignedTo', 'company', 'checkouts'],
Consumable::class => ['company', 'checkouts'],
]);
},
'assignedTo',
])
->whereHasMorph(
'checkoutable',
[Asset::class, Accessory::class, LicenseSeat::class, Component::class, Consumable::class],
fn ($q) => $q->whereNull('accepted_at')
->whereNull('declined_at')
)
->pending()
->get();
$count = 0;
$unacceptedAssetGroups = $pending
->filter(function($acceptance) {
return $acceptance->checkoutable_type == 'App\Models\Asset';
})
->map(function($acceptance) {
->map(function ($acceptance) {
return ['assetItem' => $acceptance->checkoutable, 'acceptance' => $acceptance];
})
->groupBy(function($item) {
->groupBy(function ($item) {
return $item['acceptance']->assignedTo ? $item['acceptance']->assignedTo->id : '';
});
$no_email_list= [];
$no_email_list = [];
foreach($unacceptedAssetGroups as $unacceptedAssetGroup) {
foreach ($unacceptedAssetGroups as $unacceptedAssetGroup) {
// The [0] is weird, but it allows for the item_count to work and grabs the appropriate info for each user.
// Collapsing and flattening the collection doesn't work above.
$acceptance = $unacceptedAssetGroup[0]['acceptance'];
@@ -74,7 +87,7 @@ class SendAcceptanceReminder extends Command
$locale = $acceptance->assignedTo?->locale;
$email = $acceptance->assignedTo?->email;
if(!$email){
if (! $email) {
$no_email_list[] = [
'id' => $acceptance->assignedTo?->id,
'name' => $acceptance->assignedTo?->display_name,
@@ -100,12 +113,11 @@ class SendAcceptanceReminder extends Command
$rows[] = [$user['id'], $user['name']];
}
if (!empty($rows)) {
$this->info("The following users do not have an email address:");
if (! empty($rows)) {
$this->info('The following users do not have an email address:');
$this->table($headers, $rows);
}
return 0;
}
}
@@ -2,6 +2,7 @@
namespace App\Console\Commands;
use App\Helpers\Helper;
use App\Models\Asset;
use App\Models\Recipients\AlertRecipient;
use App\Models\Setting;
@@ -9,6 +10,7 @@ use App\Notifications\ExpectedCheckinAdminNotification;
use App\Notifications\ExpectedCheckinNotification;
use Carbon\Carbon;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Notification;
class SendExpectedCheckinAlerts extends Command
{
@@ -17,7 +19,7 @@ class SendExpectedCheckinAlerts extends Command
*
* @var string
*/
protected $name = 'snipeit:expected-checkin';
protected $signature = 'snipeit:expected-checkin {--with-output : Display the results in a table in your console in addition to sending the email}';
/**
* The console command description.
@@ -42,19 +44,46 @@ class SendExpectedCheckinAlerts extends Command
public function handle()
{
$settings = Setting::getSettings();
$interval = $settings->audit_warning_days ?? 0;
$interval = $settings->due_checkin_days ?? 0;
$today = Carbon::now();
$interval_date = $today->copy()->addDays($interval);
$count = 0;
if (! $this->option('with-output')) {
$this->info('Run this command with the --with-output option to see the full list in the console.');
}
$assets = Asset::whereNull('deleted_at')->DueOrOverdueForCheckin($settings)->orderBy('assets.expected_checkin', 'desc')->get();
$this->info($assets->count().' assets must be checked in on or before '.$interval_date.' is deadline');
$this->info($assets->count().' assets must be checked on or before '.Helper::getFormattedDateObject($interval_date, 'date', false));
foreach ($assets as $asset) {
if ($asset->assignedTo && (isset($asset->assignedTo->email)) && ($asset->assignedTo->email!='') && $asset->checkedOutToUser()) {
$this->info('Sending User ExpectedCheckinNotification to: '.$asset->assignedTo->email);
if ($asset->assignedTo && (isset($asset->assignedTo->email)) && ($asset->assignedTo->email != '') && $asset->checkedOutToUser()) {
$asset->assignedTo->notify((new ExpectedCheckinNotification($asset)));
$count++;
}
}
if ($this->option('with-output')) {
if (($assets) && ($assets->count() > 0) && ($settings->alert_email != '')) {
$this->table(
[
trans('general.id'),
trans('admin/hardware/form.tag'),
trans('admin/hardware/form.model'),
trans('general.model_no'),
trans('general.purchase_date'),
trans('admin/hardware/form.expected_checkin'),
],
$assets->map(fn ($assets) => [
trans('general.id') => $assets->id,
trans('admin/hardware/form.tag') => $assets->asset_tag,
trans('admin/hardware/form.model') => $assets->model->name,
trans('general.model_no') => $assets->model->model_number,
trans('general.purchase_date') => $assets->purchase_date_formatted,
trans('admin/hardware/form.eol_date') => $assets->expected_checkin_formattedDate ? $assets->expected_checkin_formattedDate.' ('.$assets->expected_checkin_diff_for_humans.')' : '',
])
);
}
}
@@ -63,10 +92,11 @@ class SendExpectedCheckinAlerts extends Command
$recipients = collect(explode(',', $settings->alert_email))->map(function ($item) {
return new AlertRecipient($item);
});
$this->info('Sending Admin ExpectedCheckinNotification to: '.$settings->alert_email);
\Notification::send($recipients, new ExpectedCheckinAdminNotification($assets));
Notification::send($recipients, new ExpectedCheckinAdminNotification($assets));
}
$this->info('Sent checkin reminders to to '.$count.' users.');
}
}
+62 -9
View File
@@ -13,11 +13,11 @@ use Illuminate\Support\Facades\Mail;
class SendExpirationAlerts extends Command
{
/**
* The console command name.
* The name and signature of the console command.
*
* @var string
*/
protected $name = 'snipeit:expiring-alerts';
protected $signature = 'snipeit:expiring-alerts {--expired-licenses}';
/**
* The console command description.
@@ -48,27 +48,80 @@ class SendExpirationAlerts extends Command
// Send a rollup to the admin, if settings dictate
$recipients = collect(explode(',', $settings->alert_email))
->map(fn($item) => trim($item)) // Trim each email
->filter(fn($item) => !empty($item))
->map(fn ($item) => trim($item)) // Trim each email
->filter(fn ($item) => ! empty($item))
->all();
// Expiring Assets
$assets = Asset::getExpiringWarrantee($alert_interval);
$assets = Asset::getExpiringWarrantyOrEol($alert_interval);
$assets->load(['assignedTo', 'supplier']);
if ($assets->count() > 0) {
$this->info(trans_choice('mail.assets_warrantee_alert', $assets->count(), ['count' => $assets->count(), 'threshold' => $alert_interval]));
Mail::to($recipients)->send(new ExpiringAssetsMail($assets, $alert_interval));
$this->table(
[
trans('general.id'),
trans('admin/hardware/form.tag'),
trans('admin/hardware/form.model'),
trans('general.model_no'),
trans('general.purchase_date'),
trans('admin/hardware/form.eol_rate'),
trans('admin/hardware/form.eol_date'),
trans('admin/hardware/form.warranty_expires'),
],
$assets->map(fn ($item) => [
trans('general.id') => $item->id,
trans('admin/hardware/form.tag') => $item->asset_tag,
trans('admin/hardware/form.model') => $item->model->name,
trans('general.model_no') => $item->model->model_number,
trans('general.purchase_date') => $item->purchase_date_formatted,
trans('admin/hardware/form.eol_rate') => $item->model->eol,
trans('admin/hardware/form.eol_date') => $item->eol_date ? $item->eol_formatted_date.' ('.$item->eol_diff_for_humans.')' : '',
trans('admin/hardware/form.warranty_expires') => $item->warranty_expires ? $item->warranty_expires_formatted_date.' ('.$item->warranty_expires_diff_for_humans.')' : '',
])
);
}
// Expiring licenses
$licenses = License::getExpiringLicenses($alert_interval);
$licenses = License::query()->ExpiringLicenses($alert_interval, $this->option('expired-licenses'))
->with('manufacturer', 'category')
->orderBy('expiration_date', 'ASC')
->orderBy('termination_date', 'ASC')
->get();
if ($licenses->count() > 0) {
$this->info(trans_choice('mail.license_expiring_alert', $licenses->count(), ['count' => $licenses->count(), 'threshold' => $alert_interval]));
Mail::to($recipients)->send(new ExpiringLicenseMail($licenses, $alert_interval));
$this->table(
[
trans('general.id'),
trans('general.name'),
trans('general.purchase_date'),
trans('admin/licenses/form.expiration'),
trans('mail.expires'),
trans('admin/licenses/form.termination_date'),
trans('mail.terminates')],
$licenses->map(fn ($item) => [
trans('general.id') => $item->id,
trans('general.name') => $item->name,
trans('general.purchase_date') => $item->purchase_date_formatted,
trans('admin/licenses/form.expiration') => $item->expires_formatted_date,
trans('mail.expires') => $item->expires_formatted_date ? $item->expires_diff_for_humans : '',
trans('admin/licenses/form.termination_date') => $item->terminates_formatted_date,
trans('mail.terminates') => $item->terminates_diff_for_humans,
])
);
}
// Send a message even if the count is 0
$this->info(trans_choice('mail.assets_warrantee_alert', $assets->count(), ['count' => $assets->count(), 'threshold' => $alert_interval]));
$this->info(trans_choice('mail.license_expiring_alert', $licenses->count(), ['count' => $licenses->count(), 'threshold' => $alert_interval]));
} else {
if ($settings->alert_email == '') {
$this->error('Could not send email. No alert email configured in settings');
} elseif (1 != $settings->alerts_enabled) {
} elseif ($settings->alerts_enabled != 1) {
$this->info('Alerts are disabled in the settings. No mail will be sent');
}
}
+4 -2
View File
@@ -52,12 +52,14 @@ class SendInventoryAlerts extends Command
return new AlertRecipient($item);
});
\Notification::send($recipients, new InventoryAlert($items, $settings->alert_threshold));
Notification::send($recipients, new InventoryAlert($items, $settings->alert_threshold));
} else {
$this->info('No low inventory items found. No mail sent.');
}
} else {
if ($settings->alert_email == '') {
$this->error('Could not send email. No alert email configured in settings');
} elseif (1 != $settings->alerts_enabled) {
} elseif ($settings->alerts_enabled != 1) {
$this->info('Alerts are disabled in the settings. No mail will be sent');
}
}
@@ -16,7 +16,7 @@ class SendUpcomingAuditReport extends Command
*
* @var string
*/
protected $signature = 'snipeit:upcoming-audits';
protected $signature = 'snipeit:upcoming-audits {--with-output : Display the results in a table in your console in addition to sending the email}';
/**
* The console command description.
@@ -47,20 +47,62 @@ class SendUpcomingAuditReport extends Command
$today = Carbon::now();
$interval_date = $today->copy()->addDays($interval);
$assets = Asset::whereNull('deleted_at')->dueOrOverdueForAudit($settings)->orderBy('assets.next_audit_date', 'desc')->get();
$this->info($assets->count() . ' assets must be audited in on or before ' . $interval_date . ' is deadline');
$assets_query = Asset::whereNull('deleted_at')->dueOrOverdueForAudit($settings)->orderBy('assets.next_audit_date', 'asc')->with('supplier');
$asset_count = $assets_query->count();
$this->info(number_format($asset_count).' assets must be audited on or before '.$interval_date);
if (! $this->option('with-output')) {
$this->info('Run this command with the --with-output option to see the full list in the console.');
}
if ($asset_count > 0) {
$assets_for_email = $assets_query->limit(30)->get();
if ((count($assets) !== 0) && ($assets->count() > 0) && ($settings->alert_email != '')) {
// Send a rollup to the admin, if settings dictate
$recipients = collect(explode(',', $settings->alert_email))
->map(fn($item) => trim($item))
->filter(fn($item) => !empty($item))
->all();
if ($settings->alert_email != '') {
$recipients = collect(explode(',', $settings->alert_email))
->map(fn ($item) => trim($item))
->filter(fn ($item) => ! empty($item))
->all();
$this->info('Sending Admin SendUpcomingAuditNotification to: ' . $settings->alert_email);
Mail::to($recipients)->send(new SendUpcomingAuditMail($assets, $settings->audit_warning_days));
Mail::to($recipients)->send(new SendUpcomingAuditMail($assets_for_email, $settings->audit_warning_days, $asset_count));
$this->info('Audit notification sent to: '.$settings->alert_email);
} else {
$this->info('There is no admin alert email set so no email will be sent.');
}
if ($this->option('with-output')) {
// Get the full list if the user wants output in the console
$assets_for_output = $assets_query->limit(null)->get();
$this->table(
[
trans('general.id'),
trans('general.name'),
trans('general.last_audit'),
trans('general.next_audit_date'),
trans('mail.Days'),
trans('mail.supplier'),
trans('mail.assigned_to'),
],
$assets_for_output->map(fn ($item) => [
trans('general.id') => $item->id,
trans('general.name') => $item->display_name,
trans('general.last_audit') => $item->last_audit_formatted_date,
trans('general.next_audit_date') => $item->next_audit_formatted_date,
trans('mail.Days') => round($item->next_audit_diff_in_days),
trans('mail.supplier') => $item->supplier ? $item->supplier->name : '',
trans('mail.assigned_to') => $item->assignedTo ? $item->assignedTo->display_name : '',
])
);
}
} else {
$this->info('There are no assets due for audit in the next '.$interval.' days.');
}
}
+4 -6
View File
@@ -63,16 +63,14 @@ class SyncAssetCounters extends Command
}
} else {
$this->info('No assets to sync');
}
});
} else {
$this->info('No assets to sync');
}
});
$bar->finish();
$time_elapsed_secs = microtime(true) - $start;
$this->info("\nSync of ".$assets_count.' assets executed in '.$time_elapsed_secs.' seconds');
}
}
+6 -4
View File
@@ -3,6 +3,8 @@
namespace App\Console\Commands;
use App\Models\Asset;
use App\Models\Location;
use App\Models\User;
use Illuminate\Console\Command;
class SyncAssetLocations extends Command
@@ -57,7 +59,7 @@ class SyncAssetLocations extends Command
$bar->advance();
}
$assigned_user_assets = Asset::where('assigned_type', \App\Models\User::class)->whereNotNull('assigned_to')->whereNull('deleted_at')->get();
$assigned_user_assets = Asset::where('assigned_type', User::class)->whereNotNull('assigned_to')->whereNull('deleted_at')->get();
$output['info'][] = 'There are '.$assigned_user_assets->count().' assets checked out to users.';
foreach ($assigned_user_assets as $assigned_user_asset) {
if (($assigned_user_asset->assignedTo) && ($assigned_user_asset->assignedTo->userLoc)) {
@@ -73,7 +75,7 @@ class SyncAssetLocations extends Command
$bar->advance();
}
$assigned_location_assets = Asset::where('assigned_type', \App\Models\Location::class)
$assigned_location_assets = Asset::where('assigned_type', Location::class)
->whereNotNull('assigned_to')->whereNull('deleted_at')->get();
$output['info'][] = 'There are '.$assigned_location_assets->count().' assets checked out to locations.';
@@ -90,13 +92,13 @@ class SyncAssetLocations extends Command
}
// Assigned to assets
$assigned_asset_assets = Asset::where('assigned_type', \App\Models\Asset::class)
$assigned_asset_assets = Asset::where('assigned_type', Asset::class)
->whereNotNull('assigned_to')->whereNull('deleted_at')->get();
$output['info'][] = 'Asset-assigned assets: '.$assigned_asset_assets->count();
foreach ($assigned_asset_assets as $assigned_asset_asset) {
// Check to make sure there aren't any invalid relationships
// Check to make sure there aren't any invalid relationships
if ($assigned_asset_asset->assetLoc()) {
$assigned_asset_asset->location_id = $assigned_asset_asset->assetLoc()->id;
$output['info'][] = 'Setting Asset Assigned asset '.$assigned_asset_asset->assetLoc()->id.' ('.$assigned_asset_asset->asset_tag.') location to: '.$assigned_asset_asset->assetLoc()->id;
+3 -1
View File
@@ -37,11 +37,13 @@ class SystemBackup extends Command
*/
public function handle()
{
ini_set('max_execution_time', env('BACKUP_TIME_LIMIT', 600)); // 600 seconds = 10 minutes
if ($this->option('filename')) {
$filename = $this->option('filename');
// Make sure the filename ends in .zip
if (!ends_with($filename, '.zip')) {
if (! ends_with($filename, '.zip')) {
$filename = $filename.'.zip';
}
@@ -47,5 +47,4 @@ class TestLocationsFMCS extends Command
$this->table($header, $mismatched);
}
}
@@ -17,7 +17,6 @@ class ToggleCustomfieldEncryption extends Command
protected $signature = 'snipeit:customfield-encryption
{fieldname : the db_column_name of the field}';
/**
* The console command description.
*
@@ -61,15 +60,15 @@ class ToggleCustomfieldEncryption extends Command
$field->field_encrypted = 1;
$field->save();
// This field is already encrypted. Do nothing.
// This field is already encrypted. Do nothing.
} else {
$this->error('The custom field ' . $field->db_column.' is already encrypted. No action was taken.');
$this->error('The custom field '.$field->db_column.' is already encrypted. No action was taken.');
}
});
// No matching column name found
// No matching column name found
} else {
$this->error('No matching results for unencrypted custom fields with db_column name: ' . $fieldname.'. Please check the fieldname.');
$this->error('No matching results for unencrypted custom fields with db_column name: '.$fieldname.'. Please check the fieldname.');
}
}
+92
View File
@@ -0,0 +1,92 @@
<?php
namespace App\Console\Commands;
use App\Models\Asset;
use Illuminate\Console\Command;
use Illuminate\Support\MessageBag;
class ValidateAssets extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'snipeit:validate-assets {--all : Display the valid assets in your table output as well} ';
/**
* The console command description.
*
* @var string
*/
protected $description = 'This runs through the list of assets and checks for any validation errors that would prevent it from being updated or checked in or out. ';
/**
* Execute the console command.
*/
public function handle()
{
$showAll = (bool) $this->option('all');
$assets = Asset::query()
->whereNull('deleted_at')
->with('model')
->orderBy('assets.created_at', 'desc')
->get();
if (! $showAll) {
$this->info('Run this command with the --all option to see the full list in the console.');
}
$rows = $assets
->filter(fn (Asset $asset) => $showAll || ! $asset->isValid())
->map(fn (Asset $asset) => [
trans('general.id') => $asset->id,
trans('admin/hardware/form.tag') => $asset->asset_tag,
trans('admin/hardware/form.serial') => $asset->serial ?? '',
trans('admin/hardware/form.model') => $asset->model?->name ?? '',
trans('general.model_no') => $asset->model?->model_number ?? '',
trans('general.error') => $asset->isValid() ? '√ valid' : $this->formatValidationErrors($asset),
])
->values()
->all();
$this->table(
[
trans('general.id'),
trans('admin/hardware/form.tag'),
trans('admin/hardware/form.serial'),
trans('admin/hardware/form.model'),
trans('general.model_no'),
trans('general.error'),
],
$rows
);
return self::SUCCESS;
}
private function formatValidationErrors(Asset $asset): string
{
$errors = $asset->getErrors();
$messages = [];
if ($errors instanceof MessageBag) {
$messages = $errors->all();
} elseif (is_array($errors)) {
$messages = $errors;
} else {
$messages = [(string) $errors];
}
$prefixedMessages = collect($messages)
->map(fn ($message) => trim((string) $message))
->filter()
->map(fn (string $message) => str_starts_with($message, '✘') ? $message : '✘ '.$message)
->values()
->all();
return implode(PHP_EOL, $prefixedMessages);
}
}
+1 -1
View File
@@ -87,7 +87,7 @@ class Version extends Command
$app_version = 'v'."$maj.".($min + 1).".$patch";
} elseif ($use_type == 'patch') {
$app_version = 'v'."$maj.$min.".($patch + 1);
// If nothing is passed, leave the version as it is, just increment the build
// If nothing is passed, leave the version as it is, just increment the build
} else {
$app_version = 'v'."$maj.$min.".$patch;
}
+1 -5
View File
@@ -2,9 +2,6 @@
namespace App\Console;
use App\Console\Commands\ImportLocations;
use App\Console\Commands\ReEncodeCustomFieldNames;
use App\Console\Commands\RestoreDeletedUsers;
use App\Models\Setting;
use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
@@ -14,12 +11,11 @@ class Kernel extends ConsoleKernel
/**
* Define the application's command schedule.
*
* @param \Illuminate\Console\Scheduling\Schedule $schedule
* @return void
*/
protected function schedule(Schedule $schedule)
{
if(Setting::getSettings()?->alerts_enabled === 1) {
if (Setting::getSettings()?->alerts_enabled === 1) {
$schedule->command('snipeit:inventory-alerts')->daily();
$schedule->command('snipeit:expiring-alerts')->daily();
$schedule->command('snipeit:expected-checkin')->daily();
+37
View File
@@ -0,0 +1,37 @@
<?php
namespace App\Enums;
enum ActionType: string
{
// General
case Create = 'create';
case Update = 'update';
case Delete = 'delete';
case Restore = 'restore';
// Assets/Accessories/Components/Licenses/Consumables
case Checkout = 'checkout';
case CheckinFrom = 'checkin from';
case ForceCheckin = 'force checkin';
case Requested = 'requested';
case RequestCanceled = 'request canceled';
case Accepted = 'accepted';
case Declined = 'declined';
case Audit = 'audit';
case NoteAdded = 'note added';
// Users
case TwoFactorReset = '2FA reset';
case Merged = 'merged';
case TokenRevoked = 'token revoked';
case TokenUnrevoked = 'token unrevoked';
// Licenses
case DeleteSeats = 'delete seats';
case AddSeats = 'add seats';
// File Uploads
case Uploaded = 'uploaded';
case UploadDeleted = 'upload deleted';
}
-1
View File
@@ -3,7 +3,6 @@
namespace App\Events;
use App\Models\CheckoutAcceptance;
use App\Models\Contracts\Acceptable;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Queue\SerializesModels;
-1
View File
@@ -3,7 +3,6 @@
namespace App\Events;
use App\Models\CheckoutAcceptance;
use App\Models\Contracts\Acceptable;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Queue\SerializesModels;
+5
View File
@@ -11,10 +11,15 @@ class CheckoutableCheckedIn
use Dispatchable, SerializesModels;
public $checkoutable;
public $checkedOutTo;
public $checkedInBy;
public $note;
public $action_date; // Date setted in the hardware.checkin view at the checkin_at input, for the action log
public $originalValues;
/**
+11 -1
View File
@@ -11,22 +11,32 @@ class CheckoutableCheckedOut
use Dispatchable, SerializesModels;
public $checkoutable;
public $checkedOutTo;
public $checkedOutBy;
public $note;
public $originalValues;
public int $quantity;
public bool $signInPlace;
/**
* Create a new event instance.
*
* @return void
*/
public function __construct($checkoutable, $checkedOutTo, User $checkedOutBy, $note, $originalValues = [])
public function __construct($checkoutable, $checkedOutTo, User $checkedOutBy, $note, $originalValues = [], $quantity = 1, bool $signInPlace = false)
{
$this->checkoutable = $checkoutable;
$this->checkedOutTo = $checkedOutTo;
$this->checkedOutBy = $checkedOutBy;
$this->note = $note;
$this->originalValues = $originalValues;
$this->quantity = $quantity;
$this->signInPlace = $signInPlace;
}
}
@@ -0,0 +1,23 @@
<?php
namespace App\Events;
use App\Models\User;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Collection;
class CheckoutablesCheckedOutInBulk
{
use Dispatchable, SerializesModels;
public function __construct(
public Collection $assets,
public Model $target,
public User $admin,
public string $checkout_at,
public string $expected_checkin,
public string $note,
) {}
}
+4 -4
View File
@@ -2,9 +2,9 @@
namespace App\Events;
use App\Models\User;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Queue\SerializesModels;
use App\Models\User;
class UserMerged
{
@@ -17,8 +17,8 @@ class UserMerged
*/
public function __construct(User $from_user, User $to_user, ?User $admin)
{
$this->merged_from = $from_user;
$this->merged_to = $to_user;
$this->admin = $admin;
$this->merged_from = $from_user;
$this->merged_to = $to_user;
$this->admin = $admin;
}
}
+1 -3
View File
@@ -4,6 +4,4 @@ namespace App\Exceptions;
use Exception;
class AssetNotRequestable extends Exception
{
}
class AssetNotRequestable extends Exception {}
+55 -45
View File
@@ -2,16 +2,25 @@
namespace App\Exceptions;
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
use App\Helpers\Helper;
use Illuminate\Validation\ValidationException;
use Illuminate\Auth\AuthenticationException;
use ArieTimmerman\Laravel\SCIMServer\Exceptions\SCIMException;
use Illuminate\Support\Facades\Log;
use Throwable;
use JsonException;
use Carbon\Exceptions\InvalidFormatException;
use Illuminate\Http\Exceptions\ThrottleRequestsException;
use Illuminate\Auth\Access\AuthorizationException;
use Illuminate\Auth\AuthenticationException;
use Illuminate\Database\Eloquent\ModelNotFoundException;
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Illuminate\Session\TokenMismatchException;
use Illuminate\Support\Facades\Log;
use Illuminate\Validation\ValidationException;
use Intervention\Image\Exception\NotSupportedException;
use JsonException;
use League\OAuth2\Server\Exception\OAuthServerException;
use Symfony\Component\HttpKernel\Exception\HttpException;
use Throwable;
class Handler extends ExceptionHandler
{
@@ -21,16 +30,16 @@ class Handler extends ExceptionHandler
* @var array
*/
protected $dontReport = [
\Illuminate\Auth\AuthenticationException::class,
\Illuminate\Auth\Access\AuthorizationException::class,
\Symfony\Component\HttpKernel\Exception\HttpException::class,
\Illuminate\Database\Eloquent\ModelNotFoundException::class,
\Illuminate\Session\TokenMismatchException::class,
\Illuminate\Validation\ValidationException::class,
\Intervention\Image\Exception\NotSupportedException::class,
\League\OAuth2\Server\Exception\OAuthServerException::class,
AuthenticationException::class,
AuthorizationException::class,
HttpException::class,
ModelNotFoundException::class,
TokenMismatchException::class,
ValidationException::class,
NotSupportedException::class,
OAuthServerException::class,
JsonException::class,
SCIMException::class, //these generally don't need to be reported
SCIMException::class, // these generally don't need to be reported
InvalidFormatException::class,
];
@@ -39,7 +48,6 @@ class Handler extends ExceptionHandler
*
* This is a great spot to send exceptions to Sentry, Bugsnag, etc.
*
* @param \Throwable $exception
* @return void
*/
public function report(Throwable $exception)
@@ -48,23 +56,23 @@ class Handler extends ExceptionHandler
if (class_exists(Log::class)) {
Log::error($exception);
}
return parent::report($exception);
}
}
/**
* Render an exception into an HTTP response.
*
* @param \Illuminate\Http\Request $request
*
* @param Request $request
* @param \Exception $e
* @return \Illuminate\Http\JsonResponse|\Illuminate\Http\RedirectResponse|\Illuminate\Http\Response
* @return JsonResponse|RedirectResponse|Response
*/
public function render($request, Throwable $e)
{
// CSRF token mismatch error
if ($e instanceof \Illuminate\Session\TokenMismatchException) {
if ($e instanceof TokenMismatchException) {
return redirect()->back()->with('error', trans('general.token_expired'));
}
@@ -78,9 +86,10 @@ class Handler extends ExceptionHandler
if ($e instanceof SCIMException) {
try {
$e->report(); // logs as 'debug', so shouldn't get too noisy
} catch(\Exception $reportException) {
//do nothing
} catch (\Exception $reportException) {
// do nothing
}
return $e->render($request); // ALL SCIMExceptions have the 'render()' method
}
@@ -98,9 +107,10 @@ class Handler extends ExceptionHandler
}
// Handle API requests that fail because the model doesn't exist
if ($e instanceof \Illuminate\Database\Eloquent\ModelNotFoundException) {
if ($e instanceof ModelNotFoundException) {
$className = last(explode('\\', $e->getModel()));
return response()->json(Helper::formatStandardApiResponse('error', null, $className . ' not found'), 200);
return response()->json(Helper::formatStandardApiResponse('error', null, $className.' not found'), 200);
}
// Handle API requests that fail because of an HTTP status code and return a useful error message
@@ -111,8 +121,8 @@ class Handler extends ExceptionHandler
// API throttle requests are handled in the RouteServiceProvider configureRateLimiting() method, so we don't need to handle them here
switch ($e->getStatusCode()) {
case '404':
return response()->json(Helper::formatStandardApiResponse('error', null, $statusCode . ' endpoint not found'), 404);
case '405':
return response()->json(Helper::formatStandardApiResponse('error', null, $statusCode.' endpoint not found'), 404);
case '405':
return response()->json(Helper::formatStandardApiResponse('error', null, 'Method not allowed'), 405);
default:
return response()->json(Helper::formatStandardApiResponse('error', null, $statusCode), $statusCode);
@@ -124,19 +134,20 @@ class Handler extends ExceptionHandler
// never even get to the controller where we normally nicely format JSON responses
if ($e instanceof ValidationException) {
$response = $this->invalidJson($request, $e);
return response()->json(Helper::formatStandardApiResponse('error', null, $e->errors()), 200);
return response()->json(Helper::formatStandardApiResponse('error', null, $e->errors()), 200);
}
}
// This is traaaaash but it handles models that are not found while using route model binding :(
// The only alternative is to set that at *each* route, which is crazypants
if ($e instanceof \Illuminate\Database\Eloquent\ModelNotFoundException) {
if ($e instanceof ModelNotFoundException) {
$ids = method_exists($e, 'getIds') ? $e->getIds() : [];
if (in_array('bulkedit', $ids, true)) {
$error_array = session()->get('bulk_asset_errors');
$error_array = session()->get('bulk_asset_errors');
return redirect()
->route('hardware.index')
->withErrors($error_array, 'bulk_asset_errors')
@@ -144,7 +155,7 @@ class Handler extends ExceptionHandler
}
// This gets the MVC model name from the exception and formats in a way that's less fugly
$model_name = trim(strtolower(implode(" ", preg_split('/(?=[A-Z])/', last(explode('\\', $e->getModel()))))));
$model_name = trim(strtolower(implode(' ', preg_split('/(?=[A-Z])/', last(explode('\\', $e->getModel()))))));
$route = str_plural(strtolower(last(explode('\\', $e->getModel())))).'.index';
// Sigh.
@@ -162,6 +173,8 @@ class Handler extends ExceptionHandler
$route = 'licenses.index';
} elseif (($route === 'customfieldsets.index') || ($route === 'customfields.index')) {
$route = 'fields.index';
} elseif ($route == 'actionlogs.index') {
$route = 'home';
}
return redirect()
@@ -169,28 +182,26 @@ class Handler extends ExceptionHandler
->withError(trans('general.generic_model_not_found', ['model' => $model_name]));
}
if ($this->isHttpException($e) && (isset($statusCode)) && ($statusCode == '404' )) {
if ($this->isHttpException($e) && (isset($statusCode)) && ($statusCode == '404')) {
return response()->view('layouts/basic', [
'content' => view('errors/404')
],$statusCode);
'content' => view('errors/404'),
], $statusCode);
}
return parent::render($request, $e);
}
/**
/**
* Convert an authentication exception into an unauthenticated response.
*
* @param \Illuminate\Http\Request $request
* @param \Illuminate\Auth\AuthenticationException $exception
* @return \Illuminate\Http\JsonResponse|\Illuminate\Http\RedirectResponse
*/
* @param Request $request
* @return JsonResponse|RedirectResponse
*/
protected function unauthenticated($request, AuthenticationException $exception)
{
if ($request->expectsJson()) {
return response()->json(['error' => 'Unauthorized or unauthenticated.'], 401);
return response()->json(['error' => trans('general.unauthorized')], 401);
}
return redirect()->guest('login');
@@ -201,8 +212,7 @@ class Handler extends ExceptionHandler
return response()->json(Helper::formatStandardApiResponse('error', null, $exception->errors()), 200);
}
/**
/**
* A list of the inputs that are never flashed for validation exceptions.
*
* @var array
@@ -0,0 +1,8 @@
<?php
namespace App\Exceptions;
class ItemStillHasAccessories extends ItemStillHasChildren
{
//
}
@@ -0,0 +1,8 @@
<?php
namespace App\Exceptions;
class ItemStillHasAssetModels extends ItemStillHasChildren
{
//
}
+5
View File
@@ -0,0 +1,5 @@
<?php
namespace App\Exceptions;
class ItemStillHasAssets extends ItemStillHasChildren {}
+14
View File
@@ -0,0 +1,14 @@
<?php
namespace App\Exceptions;
use Exception;
class ItemStillHasChildren extends Exception
{
// public function __construct($message, $code = 0, Exception $previous = null, $parent, $children)
// {
// trans()
//
// }
}
@@ -0,0 +1,8 @@
<?php
namespace App\Exceptions;
class ItemStillHasComponents extends ItemStillHasChildren
{
//
}
@@ -0,0 +1,8 @@
<?php
namespace App\Exceptions;
class ItemStillHasConsumables extends ItemStillHasChildren
{
//
}
+8
View File
@@ -0,0 +1,8 @@
<?php
namespace App\Exceptions;
class ItemStillHasLicenses extends ItemStillHasChildren
{
//
}
@@ -0,0 +1,8 @@
<?php
namespace App\Exceptions;
class ItemStillHasMaintenances extends ItemStillHasChildren
{
//
}
+1 -4
View File
@@ -4,7 +4,4 @@ namespace App\Exceptions;
use Exception;
class UserDoestExistException extends Exception
{
}
class UserDoestExistException extends Exception {}
+432 -283
View File
File diff suppressed because it is too large Load Diff
+103 -14
View File
@@ -4,18 +4,26 @@ namespace App\Helpers;
class IconHelper
{
public static function icon($type) {
public static function icon($type)
{
switch ($type) {
case 'apple':
return 'fa-brands fa-apple';
case 'google':
return 'fa-brands fa-google';
case 'checkout':
return 'fa-solid fa-rotate-left';
case 'checkin':
return 'fa-solid fa-rotate-right';
case 'edit':
case 'update':
return 'fas fa-pencil-alt';
case 'clone':
return 'far fa-clone';
case 'upload':
return 'fa-solid fa-file-circle-plus';
case 'delete':
case 'upload deleted':
return 'fas fa-trash';
case 'create':
return 'fa-solid fa-plus';
@@ -35,14 +43,20 @@ class IconHelper
return 'fa-solid fa-user';
case 'users':
return 'fas fa-users';
case 'supplier':
return 'fa-solid fa-store';
case 'restore':
return 'fa-solid fa-trash-arrow-up';
case 'external-link':
return 'fa fa-external-link';
case 'link':
return 'fa fa-link';
case 'email':
return 'fa-regular fa-envelope';
case 'phone':
return 'fa-solid fa-phone';
case 'fax':
return 'fa-solid fa-fax';
case 'mobile':
return 'fas fa-mobile-screen-button';
case 'long-arrow-right':
@@ -50,7 +64,7 @@ class IconHelper
case 'download':
return 'fas fa-download';
case 'checkmark':
return 'fas fa-check icon-white';
return 'fas fa-check';
case 'x':
return 'fas fa-times';
case 'logout':
@@ -64,6 +78,7 @@ class IconHelper
case 'angle-right':
return 'fas fa-angle-right';
case 'warning':
case 'alert':
return 'fas fa-exclamation-triangle';
case 'kits':
return 'fas fa-object-group';
@@ -82,8 +97,11 @@ class IconHelper
case 'licenses':
case 'license':
return 'far fa-save';
case 'requests':
case 'requestable':
return 'fas fa-laptop';
case 'request':
case 'requested':
return 'fa-solid fa-bell-concierge';
case 'reports':
return 'fas fa-chart-bar';
case 'heart':
@@ -103,13 +121,14 @@ class IconHelper
case 'password':
return 'fa-solid fa-key';
case 'api-key':
return 'fa-solid fa-user-secret';
return 'fas fa-user-secret';
case 'nav-toggle':
return 'fas fa-bars';
case 'dashboard':
return 'fas fa-tachometer-alt';
case 'info-circle':
return 'fas fa-info-circle';
case 'info':
return 'fas fa-info-circle';
case 'caret-right':
return 'fa fa-caret-right';
case 'caret-up':
@@ -127,19 +146,29 @@ class IconHelper
case 'paperclip':
return 'fas fa-paperclip';
case 'files':
return 'fa-regular fa-file';
return 'fa-solid fa-file-contract';
case 'contact-card':
return 'fa-regular fa-id-card';
case 'eula':
case 'eulas':
return 'fa-regular fa-handshake';
case 'star':
case 'vip':
return 'fa-solid fa-star';
case 'remote':
return 'fa-solid fa-house-laptop';
case 'more-info':
case 'help':
case 'support':
return 'far fa-life-ring';
case 'calendar':
return 'fas fa-calendar';
case 'plus':
return 'fas fa-plus';
case 'history':
return 'fas fa-history';
return 'fa-solid fa-timeline';
case 'more-files':
return 'fa-solid fa-laptop-file';
case 'maintenances':
return 'fas fa-wrench';
return 'fa-solid fa-screwdriver-wrench';
case 'seats':
return 'far fa-list-alt';
case 'globe-us':
@@ -185,15 +214,75 @@ class IconHelper
return 'fas fa-crosshairs';
case 'oauth':
return 'fas fa-user-secret';
case 'employee_num' :
case 'employee_num':
return 'fa-regular fa-id-card';
case 'department' :
case 'department':
return 'fa-solid fa-building-user';
case 'home' :
case 'home':
return 'fa-solid fa-house';
case 'note':
case 'notes':
return 'fas fa-sticky-note';
case 'tip':
return 'fa-solid fa-lightbulb';
case 'highlight':
return 'fa-solid fa-highlighter';
case 'manager':
return 'fa-solid fa-user-tie';
case 'company':
return 'fa-regular fa-building';
case 'parent':
return 'fa-solid fa-building-flag';
case 'number':
return 'fa-solid fa-hashtag';
case 'depreciation':
return 'fa-solid fa-arrows-down-to-line';
case 'calendar':
return 'fas fa-calendar';
case 'depreciation-calendar':
case 'expiration':
case 'terminates':
return 'fa-regular fa-calendar-xmark';
case 'deleted-date':
case 'end_date':
return 'fa-solid fa-calendar-xmark';
case 'expected_checkin':
case 'start_date':
return 'fa-solid fa-calendar-check';
case 'eol':
return 'fa-regular fa-calendar-days';
case 'manufacturer':
return 'fa-solid fa-industry';
case 'fieldset':
return 'fa-regular fa-rectangle-list';
case 'category':
return 'fa-solid fa-icons';
case 'cost':
return 'fa-solid fa-money-bills';
case 'available':
return 'fa-solid fa-box';
case 'checkedout':
return 'fa-solid fa-box-open';
case 'purchase_order':
return 'fa-solid fa-file-invoice-dollar';
case 'order':
return 'fa-solid fa-file-invoice';
case 'checkout-all':
return 'fa-solid fa-arrows-down-to-people';
case 'checkin-all':
return 'fa-solid fa-arrows-turn-right';
case 'square-right':
return 'fa-regular fa-square-caret-right';
case 'square-left':
return 'fa-regular fa-square-caret-left';
case 'square':
return 'fa-solid fa-square';
case 'models':
case 'model':
return 'fa-solid fa-boxes-stacked';
case 'min-qty':
return 'fa-solid fa-chart-pie';
}
}
}
+22 -43
View File
@@ -2,32 +2,39 @@
namespace App\Helpers;
use Illuminate\Support\Facades\Storage;
use Illuminate\Http\Response;
use Illuminate\Http\RedirectResponse;
use Illuminate\Support\Facades\Storage;
use Symfony\Component\HttpFoundation\BinaryFileResponse;
use Symfony\Component\HttpFoundation\StreamedResponse;
use Illuminate\Contracts\Filesystem\FileNotFoundException;
class StorageHelper
{
public static function downloader($filename, $disk = 'default') : BinaryFileResponse | RedirectResponse | StreamedResponse
public static function downloader($filename, $disk = 'default'): BinaryFileResponse|RedirectResponse|StreamedResponse
{
if ($disk == 'default') {
$disk = config('filesystems.default');
}
switch (config("filesystems.disks.$disk.driver")) {
case 'local':
return response()->download(Storage::disk($disk)->path($filename)); //works for PRIVATE or public?!
case 'local':
return response()->download(Storage::disk($disk)->path($filename)); // works for PRIVATE or public?!
case 's3':
return redirect()->away(Storage::disk($disk)->temporaryUrl($filename, now()->addMinutes(5))); //works for private or public, I guess?
case 's3':
Storage::disk($disk)->temporaryUrl(
$filename,
now()->addMinutes(5),
[
'ResponseContentType' => 'application/octet-stream',
'ResponseContentDisposition' => 'attachment; filename=download-file',
]
);
default:
return Storage::disk($disk)->download($filename);
default:
return Storage::disk($disk)->download($filename);
}
}
public static function getMediaType($file_with_path) {
public static function getMediaType($file_with_path)
{
// Get the file extension and determine the media type
if (Storage::exists($file_with_path)) {
@@ -64,6 +71,7 @@ class StorageHelper
return $extension; // Default for unknown types
}
}
return null;
}
@@ -72,8 +80,9 @@ class StorageHelper
* to determine that they are safe to display inline.
*
* @author <A. Gianotto> [<snipe@snipe.net]>
*
* @since v7.0.14
* @param $file_with_path
*
* @return bool
*/
public static function allowSafeInline($file_with_path)
@@ -96,11 +105,11 @@ class StorageHelper
'webp',
];
// The file exists and is allowed to be displayed inline
if (Storage::exists($file_with_path) && (in_array(pathinfo($file_with_path, PATHINFO_EXTENSION), $allowed_inline))) {
return true;
}
return false;
}
@@ -116,34 +125,4 @@ class StorageHelper
return null;
}
/**
* Decide whether to show the file inline or download it.
*/
public static function showOrDownloadFile($file, $filename)
{
$headers = [];
if (request('inline') == 'true') {
$headers = [
'Content-Disposition' => 'inline',
];
// This is NOT allowed as inline - force it to be displayed as text in the browser
if (self::allowSafeInline($file) != true) {
$headers = array_merge($headers, ['Content-Type' => 'text/plain']);
}
}
// Everything else seems okay, but the file doesn't exist on the server.
if (Storage::missing($file)) {
throw new FileNotFoundException();
}
return Storage::download($file, $filename, $headers);
}
}

Some files were not shown because too many files have changed in this diff Show More