Compare commits

...

465 Commits

Author SHA1 Message Date
snipe 28e8db400a Merge branch 'develop' into features/setting_for_username_display 2023-02-14 21:18:19 -08:00
snipe cde1ab241b This is broken right now :(
Signed-off-by: snipe <snipe@snipe.net>
2023-02-14 21:04:14 -08:00
snipe cc1f9451da Apply new settings option to name for accessories transformers
Signed-off-by: snipe <snipe@snipe.net>
2023-02-14 21:04:03 -08:00
snipe 5d16f5d0d8 Starting to unfuck consumables, but what a mess
Signed-off-by: snipe <snipe@snipe.net>
2023-02-14 20:54:27 -08:00
snipe 1d47e87d54 Added setting new setting to Settings save method
Signed-off-by: snipe <snipe@snipe.net>
2023-02-14 20:54:13 -08:00
snipe d2ab358c6a Use new compact user transformer
Signed-off-by: snipe <snipe@snipe.net>
2023-02-14 20:53:55 -08:00
snipe 6a6c356cf3 Removed BS table shim for usernames
Signed-off-by: snipe <snipe@snipe.net>
2023-02-14 20:52:46 -08:00
snipe 262204568e Added translations for new username display option
Signed-off-by: snipe <snipe@snipe.net>
2023-02-14 20:52:21 -08:00
snipe 3340d8ffcf Added compact user view in transformer
Signed-off-by: snipe <snipe@snipe.net>
2023-02-14 20:52:05 -08:00
snipe dd3fcdf018 Added checkbox and migration on how to show username
Signed-off-by: snipe <snipe@snipe.net>
2023-02-14 20:44:29 -08:00
snipe be404d34c5 Made method name more consistent
Signed-off-by: snipe <snipe@snipe.net>
2023-02-14 20:44:11 -08:00
snipe 79b9b097a8 Removed legacy API endpoint
Signed-off-by: snipe <snipe@snipe.net>
2023-02-14 20:34:15 -08:00
snipe 1ed57d30e0 Merge pull request #12516 from inietov/fixes/quotes_in_custom_field_custom_regex
Fixed #12252 Quotes in Custom Field regex are being HTML-escaped
2023-02-14 20:10:43 -08:00
snipe f7df2ae403 Merge pull request #12513 from Godmartinz/gh12493
adds a red icon next to the  undeployable status
2023-02-14 14:37:06 -08:00
Godfrey M 793cf4823b missing things like mr magoo 2023-02-14 14:35:54 -08:00
Godfrey M c0d8ff1676 simplified to an else instead of elseif 2023-02-14 14:21:24 -08:00
snipe b0b1c96ab5 Merge pull request #12514 from marcusmoore/fixes/preserve-asset-name-during-api-checkout
Fix asset names being removed during API checkout requests
2023-02-14 12:22:03 -08:00
Marcus Moore 8e00191b69 Add comment 2023-02-14 12:19:16 -08:00
Marcus Moore a94f19a68e Use name if provided by asset checkout request 2023-02-14 12:08:20 -08:00
Godfrey M 0cd558593d adds the red x icon to a false deployable status 2023-02-14 10:34:36 -08:00
Godfrey M d03e042eda adds a red icon next to broken- not fixable status label 2023-02-14 09:55:48 -08:00
snipe 1520c9c6a7 Merge pull request #12506 from marcusmoore/fix/use-translation-strings-for-importer-errors
Use translation strings for importer exceptions
2023-02-13 14:17:47 -08:00
Marcus Moore 4bdb1cf552 Improve error message wording 2023-02-13 13:34:20 -08:00
Marcus Moore 2349f54013 Use translation strings for importer exceptions 2023-02-13 13:30:36 -08:00
snipe 2bbbc8158b Merge pull request #12477 from akemidx/apple_warranty_link
Added functionality to Apple Warranty link
2023-02-13 13:02:33 -08:00
snipe 2f5b4c8e1b Merge pull request #12498 from akemidx/layout_trans
Translations for the layout setup
2023-02-13 13:01:58 -08:00
Ivan Nieto Vivanco 99122ccb50 Add migration to fix already escaped formats in the database 2023-02-12 17:40:04 -06:00
Ivan Nieto Vivanco 6936efd387 Remove e() function from customfield format input 2023-02-12 16:27:37 -06:00
akemidx 5714824aa7 translations for the layout setup 2023-02-09 17:24:34 -05:00
snipe e79818967d Merge pull request #12490 from akemidx/manufacturer_marker
Removed "required" marker for manufacturer on asset models (since it is not actually required)
2023-02-09 12:43:14 -08:00
akemidx 32ed70259e sweedish chef fixes up your typos 2023-02-09 15:39:10 -05:00
snipe 35ab4a4cce Merge pull request #12489 from marcusmoore/fix/encoding-errors-in-importer
Improve error messaging around invalid characters in import
2023-02-08 15:08:23 -08:00
akemidx 1a651b33fc manufacturer marker removal 2023-02-08 17:31:39 -05:00
Marcus Moore 73f355f3a8 Return 422 instead of 500 when import is invalid 2023-02-08 12:39:42 -08:00
Marcus Moore b3881a43a7 Fix return type 2023-02-08 12:34:25 -08:00
Marcus Moore c2c666aef0 Formatting 2023-02-08 12:32:57 -08:00
Marcus Moore 5962f1b627 Catch json encoding exceptions and display them to the user 2023-02-08 12:21:51 -08:00
snipe a4a3c03a7c Merge pull request #12478 from inietov/fixes/added_translation_strings_inventory_report
Fixed #12064 Mail-Template missing translation strings
2023-02-08 10:02:19 -08:00
snipe e883a61a48 Merge pull request #12480 from snipe/fixes/ui_fix_for_user_files
Fixed UI bug where download button was missing for non-images
2023-02-07 18:46:07 -08:00
snipe 16fcc6dc44 Fixed UI bug where download button was missing for non-images
Signed-off-by: snipe <snipe@snipe.net>
2023-02-07 18:40:00 -08:00
Ivan Nieto Vivanco 49b6a1cc53 Adds translation strings to theinventory report sent to users 2023-02-07 18:29:19 -06:00
akemidx 75f3cb3079 fixing external if statement 2023-02-07 19:02:12 -05:00
akemidx c0074baa26 functionality to Apple Warranty link 2023-02-07 17:27:39 -05:00
snipe 4b2d35e05d Merge pull request #12474 from snipe/fixes/destroy_method_for_fieldsets
Fixed mismatched field/fieldset
2023-02-07 13:33:38 -08:00
snipe c1d484b5df Fixed mismatched field/fieldset
Signed-off-by: snipe <snipe@snipe.net>
2023-02-07 13:31:50 -08:00
snipe b0f4015bb4 Merge pull request #12459 from snipe/fixes/broken_route_in_deleted_models
Updated model restore route
2023-02-02 23:40:39 -08:00
snipe dc414d3552 Updated model restore route
Signed-off-by: snipe <snipe@snipe.net>
2023-02-02 23:38:59 -08:00
snipe f9ef49f886 Merge pull request #12457 from snipe/fixed/regression_on_field_associations
Fixed regression in fieldset -> field association
2023-02-02 15:35:22 -08:00
snipe 51f3857a31 Fixed something I think I broke
Signed-off-by: snipe <snipe@snipe.net>
2023-02-02 15:32:45 -08:00
snipe bbf6e5e69e Merge pull request #12421 from akemidx/hardware_blades_translations
Fixed: translations added for the hardware blades
2023-02-02 13:02:46 -08:00
akemidx 37ce68af5b once again fixing an apostrophe 2023-02-02 15:54:05 -05:00
snipe 64aea8d374 Merge pull request #12456 from snipe/features/add_notes_to_user_history
Fixed #12449 - Added checkout/checkin  note to user history
2023-02-02 11:28:08 -08:00
snipe 7344bbdd7f Added checkout/checkin note to user history
Signed-off-by: snipe <snipe@snipe.net>
2023-02-02 11:26:33 -08:00
snipe 2d3318feb6 Merge pull request #12454 from snipe/fixes/fixed_500_when_userfile_does_not_exisy
Handle missing userfiles more gracefully
2023-02-02 11:08:54 -08:00
snipe 78dca7fd32 Handle missing userfiles more gracefully
Signed-off-by: snipe <snipe@snipe.net>
2023-02-02 10:49:36 -08:00
snipe 2a8851bbd7 Merge pull request #12342 from marcusmoore/fix/dusk-test-suite
Fixed Dusk Test Suite
2023-02-02 09:50:34 -08:00
snipe 2997de2a66 Merge pull request #12445 from snipe/fixes/exit_out_ldap
Added an exit for the LDAP disabled sync short-circuit
2023-02-01 16:48:00 -08:00
snipe 0cfeab8c50 Added an exit for the LDAP disabled sync short-circuit
Signed-off-by: snipe <snipe@snipe.net>
2023-02-01 16:46:58 -08:00
snipe 1432403c9f Merge pull request #12444 from snipe/fixes/only_fire_ldap_sync_in_console_if_enabled
Fixed: Short-circuit the LDAP sync is LDAP is disabled
2023-02-01 16:40:32 -08:00
snipe 67e6089805 Short circuit the LDAP sync is LDAP is disabled
Signed-off-by: snipe <snipe@snipe.net>
2023-02-01 16:36:30 -08:00
snipe ea4d5e69bc Merge pull request #12407 from akemidx/slack_message
Fixed: translation for slack message notification
2023-02-01 13:44:12 -08:00
snipe 2da4578aa5 Merge branch 'develop' into slack_message 2023-02-01 13:43:09 -08:00
snipe 1a8fb5bcfe Merge pull request #12423 from snipe/features/edit_fieldset_name
Fixed #12418 - added ability to edit custom field names via GUI
2023-02-01 13:39:39 -08:00
snipe 0d4ca218c5 Merge pull request #12437 from uberbrady/ldap_allow_undelegatable_users_to_login
Fixed: Active Directory "not-delegated+dont-expire-password+normal-accounts" can now login
2023-02-01 13:38:59 -08:00
snipe 4a6250a08c Merge pull request #12409 from akemidx/component_checkin_limit
Fixed: Checkin limit string translation for components
2023-02-01 13:37:56 -08:00
akemidx 0ffd40a217 fixing syntax 2023-02-01 16:30:07 -05:00
akemidx 33d819fd41 fixing pr 2023-02-01 16:13:53 -05:00
akemidx 90c1bfe03d fixing pr 2023-02-01 16:12:39 -05:00
akemidx 3702dd87ce fixing pr 2023-02-01 16:10:30 -05:00
akemidx 4d9d73483f fixing pr 2023-02-01 16:09:19 -05:00
akemidx 4e5b8fa213 fixing pr 2023-02-01 16:05:50 -05:00
akemidx a8643e5d35 cleaning up/adding variable 2023-02-01 15:55:16 -05:00
snipe 38f3843c23 Merge pull request #12386 from snipe/features/fixed_12382_added_checked_out_count_to_accessories
Fixed #12382 - added checked out count to accessories
2023-01-31 19:57:12 -08:00
snipe f7ae5db4f3 Merge branch 'develop' into features/fixed_12382_added_checked_out_count_to_accessories 2023-01-31 19:56:43 -08:00
snipe de1141491a Replaced help text
Signed-off-by: snipe <snipe@snipe.net>
2023-01-31 19:41:42 -08:00
snipe 2d45ebe103 Merge pull request #12433 from inietov/fixes/asset_declined_date_issues
Fixed Invalid date value on assets acceptance mail notification
2023-01-31 19:14:51 -08:00
snipe 656344b1c7 Merge pull request #12429 from svpernova09/benperiton/patch-1
Cherry-picked Feature: Add DB_PORT to pgsql connection
2023-01-31 19:10:17 -08:00
snipe 7a23398c0c Merge pull request #12439 from uberbrady/fix_bootstrap_username_doubling
Fixed: username doubles on 'checked-out-to' column if display is resized [sc-19869], [fd-33242]
2023-01-31 18:10:02 -08:00
Brady Wetherington 02ca5248b1 Don't append username to the user's name if it's already there 2023-01-31 17:44:09 -08:00
snipe b1179c7b1e Merge pull request #12438 from inietov/fixes/replace_ios_homescreen_logo
Fixed #9694 Replace iOS "Add to homescreen icon"
2023-01-31 17:02:05 -08:00
Brady Wetherington a4173e3881 Permit not-delegated+dont-expire-password+normal-accounts to login 2023-01-31 16:49:41 -08:00
snipe a2a078015f Merge pull request #12435 from lukasfehling/bugfix/fixed-endpoint-for-user-notification
Fixed the endpoint for user notification with all their assigned assets
2023-01-31 12:41:47 -08:00
lukasfehling cddae4869f fixed the endpoint for user notification with all their assigned assets 2023-01-31 18:27:25 +01:00
Ivan Nieto Vivanco a7a578bf51 Added head only logo to be used as default in apple-touch-icon 2023-01-31 00:13:44 -06:00
akemidx 214a1af61a apostrophe updates 2023-01-30 16:54:23 -05:00
Ivan Nieto Vivanco ccc7b78f62 Store the acceptance dates with format YYY-mm-dd 2023-01-30 15:11:41 -06:00
Ben Periton c2854f1bcb Update database.php
Although Postgres is not officially supported, it does seem to work ok, but to help a little bit with the Docker image, this is non-breaking change but allows the env file to specify the pgsql connection port
2023-01-29 19:28:04 -06:00
snipe 22b0b9b090 Fixed gates on fieldsets
Signed-off-by: snipe <snipe@snipe.net>
2023-01-26 17:05:41 -08:00
snipe 583a0412fe Added edit fieldsets translations
Signed-off-by: snipe <snipe@snipe.net>
2023-01-26 17:03:23 -08:00
snipe a16604285c Normalize the fieldset form
Signed-off-by: snipe <snipe@snipe.net>
2023-01-26 17:03:07 -08:00
snipe 37f5cfa8ce Added edit button for fieldsets
Signed-off-by: snipe <snipe@snipe.net>
2023-01-26 17:02:53 -08:00
akemidx 79d9cff22a translations added for the hardware blades 2023-01-26 16:26:31 -05:00
snipe cc370084d1 Merge pull request #12341 from uberbrady/redo_scim_config
Redo SCIM config; use latest laravel-scim-server from our fork
2023-01-26 12:57:29 -08:00
Brady Wetherington cd573c484d Change the SCIM_STANDARDS_COMPLIANCE config to default to 'true' 2023-01-26 12:48:41 -08:00
Brady Wetherington c5d3b3ab81 Change out the SCIM config for a fixed one; update our fork of the SCIM-server 2023-01-25 15:59:46 -08:00
Brady Wetherington cfe9c687f9 Mark a bunch of SCIM config as nullable 2023-01-25 15:54:57 -08:00
Brady Wetherington 91cf683f3d Re-do the entire SCIM config so it no longer inherits 2023-01-25 15:53:46 -08:00
snipe 6b729502c6 Rebuilt dev assets
Signed-off-by: snipe <snipe@snipe.net>
2023-01-24 19:13:40 -08:00
snipe f0b14513db Merge pull request #12411 from uberbrady/fix_rb_16746
Resolved Rollbar error 16746 - missing array key 'extension'
2023-01-24 18:24:18 -08:00
Brady Wetherington ab12ad1140 Resolves Rollbar error 16746 - missing array key 'extension' 2023-01-24 18:19:26 -08:00
akemidx 3ba79600fb checkin limit for the components checkin 2023-01-24 18:17:49 -05:00
snipe 935f5018cc Merge pull request #12405 from Godmartinz/high_contrast_color_adjustments
Fixed buttons colors in high contrast theme
2023-01-24 15:17:03 -08:00
akemidx cafe8f3074 notification for slack message 2023-01-24 16:20:20 -05:00
akemidx 19cf170dd9 Add VIP Checkbox 2023-01-24 15:30:21 -05:00
akemidx 596846a94a Add VIP Checkbox 2023-01-24 15:29:27 -05:00
Godfrey M 4b51424723 fixes a couple buttons color choices in high contrast 2023-01-24 09:42:03 -08:00
snipe dc155846ca Hoist the autorization higher in the stack so we’re not doing logic or math when the user isn’t authorized to touch this
Signed-off-by: snipe <snipe@snipe.net>
2023-01-23 21:49:17 -08:00
snipe 7a9ea91be0 Merge pull request #12387 from snipe/fixes/inconsistent_UI_for_image_delete
Updated - Refactored ImageHandler request to be more re-usable, and checkboxes with missing `minimal` class for iCheck
2023-01-23 21:39:55 -08:00
snipe 02dcb0fbd7 Shorten the additiona form request invocation to just ImageUploadRequest
We already have the `use App\Http\Requests\ImageUploadRequest` clause at the top of this file.

Signed-off-by: snipe <snipe@snipe.net>
2023-01-23 21:37:35 -08:00
snipe 690bfbe16a Merge pull request #12398 from akemidx/acceptance_translations
Fixed: translations for EULA Acceptance Summary
2023-01-23 21:28:59 -08:00
Marcus Moore cd582be851 Drop tables that may exist in down methods 2023-01-23 15:42:45 -08:00
Marcus Moore 760844de6f Add conditionals 2023-01-23 15:42:33 -08:00
Marcus Moore e6dc61d2cf Revert column names to legacy versions in down method 2023-01-23 15:42:05 -08:00
snipe 35dfaddd79 Merge pull request #12400 from snipe/jerm/fix-import-backup-checkbox
Fixed "Backup before importing?" checkbox on import page
2023-01-23 15:35:18 -08:00
Jeremy Price d3bcc48ae5 [imports] fix "Backup before importing?" checkbox on import page
We were always taking backups before import, no matter the status of
this box.

Turns out we were testing for the presence of the property defined by
the checkbox, rather than the value of the property, and as such were
always doing a backup.

We're now checking the status, and it behaves as expected
2023-01-23 15:08:59 -08:00
akemidx 25996cbe03 translating the quick info printed out on accept x eula blades 2023-01-23 16:18:21 -05:00
snipe 4b01909806 Merge pull request #12389 from snipe/fixes/livewire_ui
Fixed #12388 - Add CSS to the div to correct the weird indenting
2023-01-23 11:42:26 -08:00
snipe 72295c093a Add CSS to the div to correct the weird indenting - fixes #12388
Signed-off-by: snipe <snipe@snipe.net>
2023-01-21 18:24:23 -08:00
snipe cd8cb445ba Corrected fieldname for user fieldname for avatar in Controller
Signed-off-by: snipe <snipe@snipe.net>
2023-01-21 18:20:53 -08:00
snipe 2dc1182582 Don’t offer the delete option if there is no avatar currently
Signed-off-by: snipe <snipe@snipe.net>
2023-01-21 18:20:26 -08:00
snipe 93ad0d02b9 Use fieldname for aria labels too
Signed-off-by: snipe <snipe@snipe.net>
2023-01-21 18:20:02 -08:00
snipe 48c85966d7 Added gravatar and avatar as fillable
Signed-off-by: snipe <snipe@snipe.net>
2023-01-21 18:07:17 -08:00
snipe a0aed19f95 Refactor image handler
Signed-off-by: snipe <snipe@snipe.net>
2023-01-21 18:05:55 -08:00
snipe f77d871dff Use the imageHandler for profile avatar changes
Signed-off-by: snipe <snipe@snipe.net>
2023-01-21 18:05:20 -08:00
snipe 3674f46ce0 Added arial labels
Signed-off-by: snipe <snipe@snipe.net>
2023-01-21 16:42:44 -08:00
snipe cfa342c81a Updated HTML for “standard” image edit/delete
Signed-off-by: snipe <snipe@snipe.net>
2023-01-21 16:23:04 -08:00
snipe 563a252d18 Updated checkboxed with missing minimal class for iCheck
Signed-off-by: snipe <snipe@snipe.net>
2023-01-21 14:57:52 -08:00
snipe 2bdf3d3f44 Missed a few strong HTML tags
Signed-off-by: snipe <snipe@snipe.net>
2023-01-21 14:44:10 -08:00
snipe 60eab08735 Added ->with(‘users as users_count’) in Accessory query
Signed-off-by: snipe <snipe@snipe.net>
2023-01-21 14:41:07 -08:00
snipe 90c1631820 Added users_count to transformer for API
Signed-off-by: snipe <snipe@snipe.net>
2023-01-21 14:40:35 -08:00
snipe dceb77d4d4 Refactored numRemaining, removed unnecessary numCheckout
Signed-off-by: snipe <snipe@snipe.net>
2023-01-21 14:40:20 -08:00
snipe 46e3e8a3dd Added new users_count field to API
Signed-off-by: snipe <snipe@snipe.net>
2023-01-21 14:39:53 -08:00
snipe 56090bc645 Re-ordered notes to be more consistent, fixed missing iCheck class
Signed-off-by: snipe <snipe@snipe.net>
2023-01-21 14:38:35 -08:00
snipe fd73bee850 Fixed hardcoded string and added new checkout count to accessory view
Signed-off-by: snipe <snipe@snipe.net>
2023-01-21 14:38:05 -08:00
snipe b59dcc7b30 Merge pull request #12379 from marcusmoore/fix/row-divider-overflow
Fix minor visual bug on asset show page
2023-01-19 16:21:31 -08:00
snipe 69ab42b3f9 Merge pull request #12380 from snipe/maintenance/asset_updates
Updated dev assets
2023-01-19 15:53:55 -08:00
snipe 0080ac92e7 Updated dev assets
Signed-off-by: snipe <snipe@snipe.net>
2023-01-19 15:52:06 -08:00
snipe 9508a97852 Merge pull request #12378 from marcusmoore/fix/allow-removing-asset-name-during-checkout
Allow users to set a blank asset name during checkout
2023-01-19 14:50:58 -08:00
Marcus Moore 0fa956403c Fix row divider overflow 2023-01-19 14:16:28 -08:00
Marcus Moore 181f96ad33 Allow users to set a blank asset name during checkout 2023-01-19 12:35:44 -08:00
snipe 04e28c2d34 Merge pull request #12377 from inietov/fixes/visual_glitch_deleting_importing_files
Fixed #12340  Deleting imported files visually drops first element in table.
2023-01-19 11:59:40 -08:00
Ivan Nieto Vivanco f045008237 Add index to deleteFile() call, so it knows what element delete 2023-01-19 13:04:49 -06:00
snipe fa9116b184 Merge pull request #12369 from snipe/features/add_byod_to_assets
Added BYOD to assets
2023-01-18 16:09:45 -08:00
snipe 155977de2d Merge pull request #12370 from marcusmoore/fix/file-upload-tab-permissions
Fixed file uploads for accessories, components, and consumables
2023-01-18 16:08:53 -08:00
snipe 378dc968b7 Derp. Copypasta
Signed-off-by: snipe <snipe@snipe.net>
2023-01-18 15:44:28 -08:00
Marcus Moore c089f6eff2 Reference the accessory instance instead of the model 2023-01-18 13:48:01 -08:00
Marcus Moore e506ed7950 Remove extra quote 2023-01-18 13:42:09 -08:00
Marcus Moore 07744ca7bd Reference the consumable instance instead of the model 2023-01-18 13:41:58 -08:00
snipe 0c39c7a53d Updated blades to add byod as a “status”
Signed-off-by: snipe <snipe@snipe.net>
2023-01-18 13:25:46 -08:00
snipe fce620b54f Added byod to blades
Signed-off-by: snipe <snipe@snipe.net>
2023-01-18 13:11:02 -08:00
snipe 33fe2b57f7 Added new byod strings
Signed-off-by: snipe <snipe@snipe.net>
2023-01-18 13:10:48 -08:00
snipe 45019c65f1 BYOD migration
Signed-off-by: snipe <snipe@snipe.net>
2023-01-18 13:10:39 -08:00
snipe acd182e3d2 Added byod to presenter with boolean formatter
Signed-off-by: snipe <snipe@snipe.net>
2023-01-18 13:10:30 -08:00
snipe 48b8cfcef9 Added byod to model, removed duplicate validation rule
Signed-off-by: snipe <snipe@snipe.net>
2023-01-18 13:04:36 -08:00
snipe f626413502 Added byod to API transformer
Signed-off-by: snipe <snipe@snipe.net>
2023-01-18 13:04:02 -08:00
snipe b80d52a9c3 Added byod to asset controller for create and update methods
Signed-off-by: snipe <snipe@snipe.net>
2023-01-18 13:03:51 -08:00
snipe ee4b8f4694 Added byod to API controller
Signed-off-by: snipe <snipe@snipe.net>
2023-01-18 13:03:31 -08:00
Marcus Moore ca1198ceb2 Constrain the bottom bar to the content window 2023-01-18 12:55:20 -08:00
Marcus Moore b31e000165 Have Info and History tables in accessory show page span entire width of row 2023-01-18 12:54:52 -08:00
snipe 956bd384b0 Merge pull request #12364 from snipe/features/make_2fa_sortable
BREAKING: Partial fix for #12356: Make 2FA sortable in user list
2023-01-17 20:24:05 -08:00
snipe 7e22663326 Merge pull request #12363 from corydlamb/Ampersand-Patch
Fixed #12362: Bug With Passwords Including Ampersands?
2023-01-17 19:17:50 -08:00
snipe c3e4d9d773 Make column name consistent with field name (BREAKING)
Signed-off-by: snipe <snipe@snipe.net>
2023-01-17 18:27:47 -08:00
snipe f08babfa8a Just moved some stuff around - no actual meaningful code changes
Signed-off-by: snipe <snipe@snipe.net>
2023-01-17 17:22:03 -08:00
snipe 4ef0005e7c BREAKING: changed API fieldname result for 2FA
Signed-off-by: snipe <snipe@snipe.net>
2023-01-17 17:21:40 -08:00
snipe dbda288a44 Formatting changes only for readability
Signed-off-by: snipe <snipe@snipe.net>
2023-01-17 17:21:20 -08:00
snipe eaf9332096 Added filterability to 2FA fields
Signed-off-by: snipe <snipe@snipe.net>
2023-01-17 17:21:03 -08:00
Marcus Moore 5282ca47b3 Allow users with consumables.files ability to upload files for consumables 2023-01-17 17:16:50 -08:00
Marcus Moore 23a1b2d60a Register the consumables.files ability 2023-01-17 17:15:23 -08:00
Marcus Moore 1f12137245 Close divs in correct location 2023-01-17 17:09:55 -08:00
Marcus Moore 6c89f08193 Register the accessories.files ability and allow users with the ability to upload files for accessories 2023-01-17 16:59:50 -08:00
corydlamb 295f0dd1f5 Update WelcomeNotification.php
Used htmlspecialchars_decode to fix the issue I had involving Ampersands in the password field (and I'm assuming the other fields) of the welcome notification email. Changes are all in lines 22-26. Sorry if I'm not doing this very well as this is my first pull request.
2023-01-17 19:33:25 -05:00
Marcus Moore 1fef992fa8 Allow users with components.files ability to upload files for components 2023-01-17 15:58:11 -08:00
Marcus Moore e23ee7540d Register the components.files ability 2023-01-17 15:45:40 -08:00
snipe dd8c6e92db Merge pull request #12355 from snipe/features/make_category_visable_on_models_page_by_default
Added catergories to default visiable set on asset models
2023-01-15 17:09:00 -08:00
snipe f4630d67be Added catergories to default visiable set
Signed-off-by: snipe <snipe@snipe.net>
2023-01-15 17:07:50 -08:00
snipe 6f6f99f64e Merge pull request #12354 from uberbrady/fix_npm_dependencies
Backed out less-loader version requirement so that builds still work
2023-01-14 10:57:35 -08:00
Brady Wetherington 6f89e8b0d8 Backed out less-loader version requirement so that builds still work 2023-01-14 10:53:36 -08:00
snipe 6815a16a5f Merge pull request #12353 from snipe/fixes/rollbar_logging
Only add rollbar to the logging array if the app is in production
2023-01-13 13:53:30 -08:00
snipe 0c3d03a4ce Only add rollbar to the logging array if the app is in production
Signed-off-by: snipe <snipe@snipe.net>
2023-01-13 13:50:16 -08:00
snipe 8048d06853 Merge pull request #12352 from snipe/fixes/added_south_sudan_to_country_list
Added South Sudan to country list
2023-01-13 13:24:54 -08:00
snipe 50cc69c427 Added South Sudan to country list
Signed-off-by: snipe <snipe@snipe.net>
2023-01-13 13:23:57 -08:00
snipe 021e54adaa Merge pull request #12351 from snipe/fixes/check_filename_has_value_before_delete
Check that the `$use_db_field` has a value before attempting a delete
2023-01-13 11:29:31 -08:00
snipe 9d0a15990e Check that the $use_db_field has a value before attempting a delete
Signed-off-by: snipe <snipe@snipe.net>
2023-01-13 11:26:11 -08:00
Marcus Moore 51da747809 Add note about database requirements when running Dusk tests 2023-01-11 18:05:07 -08:00
Marcus Moore 0dd7cc9967 Add note about installing ChromeDriver to testing readme 2023-01-11 13:54:28 -08:00
Marcus Moore 49f2573f36 Update testing readme 2023-01-11 13:51:01 -08:00
Marcus Moore bc80f672ee Keep the example dusk environment file 2023-01-11 13:00:34 -08:00
Marcus Moore 49383ddbe0 Delete old dusk local configuration 2023-01-11 12:58:57 -08:00
Marcus Moore 9a3a796e17 Add dusk environment files to gitignore 2023-01-11 12:57:05 -08:00
Marcus Moore e8c2b84d24 Add example dusk environment file 2023-01-11 12:51:15 -08:00
snipe 4f8951f6f1 Merge pull request #12335 from uberbrady/windows_snipeit_restore
Fixed #12004: Snipe-IT restore didn't work on Windows
2023-01-11 11:03:44 -08:00
snipe 85b712e915 Merge pull request #12337 from snipe/docs/added_jamf_rename
Added jamf-snipe-rename script to third party list
2023-01-10 18:10:47 -08:00
snipe ca244911ed Added jamf-snipe-rename script to third party list
Signed-off-by: snipe <snipe@snipe.net>
2023-01-10 18:10:13 -08:00
snipe 942681bee5 Merge pull request #12336 from snipe/features/category_query_optimization
Refactor category API for fewer queries
2023-01-10 17:54:45 -08:00
snipe 459c95064e Fixed default
Signed-off-by: snipe <snipe@snipe.net>
2023-01-10 17:54:04 -08:00
Marcus Moore b5ea8b8a4f Conditionally drop table 2023-01-10 17:29:38 -08:00
Marcus Moore aec64fa64a Comment out migration's down method to match its up method 2023-01-10 17:25:25 -08:00
Marcus Moore 03938d0f32 Conditionally drop table 2023-01-10 17:24:38 -08:00
Marcus Moore 296c9a723d Reverse column rename in migration's down method 2023-01-10 17:22:29 -08:00
snipe 2eac03db4a Merge pull request #12329 from snipe/fixes/rollbar_integration
Fixed rollbar integration if ROLLBAR_TOKEN is provided
2023-01-10 17:21:52 -08:00
Marcus Moore c5b09ed955 Fix column name typo 2023-01-10 17:21:46 -08:00
Marcus Moore 4ee3cbf60e Comment out migration's down method to match its up method 2023-01-10 17:20:20 -08:00
Marcus Moore 39ab545cf5 Update alter statement to use correct suffix for column
This is brittle...
2023-01-10 17:08:28 -08:00
Marcus Moore e5cb68cc5e Move drop column command to correct migration 2023-01-10 17:06:16 -08:00
Marcus Moore b8b2543b0d Reference the correct table in migration down method 2023-01-10 17:04:21 -08:00
Marcus Moore bc0f666906 Create Setting in test to avoid being redirected to the setup screen 2023-01-10 17:03:09 -08:00
Marcus Moore 581655f756 Run database migrations for all Dusk tests 2023-01-10 17:02:11 -08:00
Marcus Moore 2aa50859b3 Bump Dusk version to fix broken macOS chrome driver link 2023-01-10 17:01:03 -08:00
snipe 0b0fdd8aa5 Small formatting fixes, fixed typo in comment
Signed-off-by: snipe <snipe@snipe.net>
2023-01-10 16:32:18 -08:00
snipe 8f3a237ea0 More comments
Signed-off-by: snipe <snipe@snipe.net>
2023-01-10 16:29:51 -08:00
snipe 151719a91c Added comments
Signed-off-by: snipe <snipe@snipe.net>
2023-01-10 16:24:46 -08:00
snipe 825df2cf75 Load up the item counts with the individual API methods for accurate numbers without n+1
Signed-off-by: snipe <snipe@snipe.net>
2023-01-10 16:17:03 -08:00
snipe b66cd313b9 Refactored itemCount() to use existing blah_count fields if they exist
Signed-off-by: snipe <snipe@snipe.net>
2023-01-10 16:16:25 -08:00
snipe d508374c57 Disallowed category type change string
Signed-off-by: snipe <snipe@snipe.net>
2023-01-10 16:15:51 -08:00
snipe f50b622eb8 Disallow editing of category type once created, added help text
Signed-off-by: snipe <snipe@snipe.net>
2023-01-10 16:15:40 -08:00
snipe bef4224e14 Added notes to itemCount()
Signed-off-by: snipe <snipe@snipe.net>
2023-01-10 13:50:24 -08:00
snipe 249b188654 Refactor category API and transformer for query optimization
Signed-off-by: snipe <snipe@snipe.net>
2023-01-10 13:30:01 -08:00
Brady Wetherington 2170343958 Fixed #12004: Snipe-IT restore didn't work on Windows 2023-01-10 13:06:47 -08:00
snipe 17c308f3ca Merge remote-tracking branch 'origin/master' into develop 2023-01-10 02:08:23 -08:00
snipe 35136cea07 Add @subdriven as a contributor 2023-01-10 02:07:48 -08:00
snipe 0db83ad8cb Merge pull request #12158 from subdriven/master
Updated installer script for multiple fixes and features
2023-01-10 02:04:29 -08:00
snipe 62bf7b1bce Merge remote-tracking branch 'origin/develop' 2023-01-10 01:56:27 -08:00
snipe 50fdf9c33b Merge pull request #12330 from snipe/fixes/custom_status_label_sidenav
Fixed UX issue where assets sidenav would collapse if custom status label is selected
2023-01-10 01:55:52 -08:00
snipe c5c37fa95f Fixed copypasta
Signed-off-by: snipe <snipe@snipe.net>
2023-01-10 01:54:26 -08:00
snipe 9dc016aecc Fixed issue where assets sidenav would collapse if custom status label is selected
Signed-off-by: snipe <snipe@snipe.net>
2023-01-10 01:31:00 -08:00
snipe 1cf7784bb8 Logging override if ROLLBAR_TOKEN is provided
Signed-off-by: snipe <snipe@snipe.net>
2023-01-10 00:20:56 -08:00
snipe 60dcaa9e94 Merge remote-tracking branch 'origin/develop'
Signed-off-by: snipe <snipe@snipe.net>

# Conflicts:
#	config/version.php
2023-01-09 21:11:29 -08:00
snipe 2e75bd6960 Bumped hash
Signed-off-by: snipe <snipe@snipe.net>
2023-01-09 21:11:00 -08:00
snipe 799c9c910e Merge remote-tracking branch 'origin/develop' 2023-01-09 21:09:46 -08:00
snipe 005d6d3b62 Merge pull request #12328 from snipe/fixes/revert_to_old_behavior_on_byserial
Fixed bySerial endpoint to always return a list
2023-01-09 21:09:25 -08:00
snipe 529b005d1e We were previously returning a collection - this reverts the change in the last PR to keep that behavior consistent
Signed-off-by: snipe <snipe@snipe.net>
2023-01-09 21:05:51 -08:00
snipe dd55aedb87 Merge remote-tracking branch 'origin/develop' 2023-01-09 20:47:46 -08:00
snipe be16fe948a Merge pull request #12327 from snipe/fixes/formatting_regression_with_bytag_api_response
Determine which transformer to use based on number of assets
2023-01-09 20:46:49 -08:00
snipe 7846251d25 Re-added return for no results (derp)
Signed-off-by: snipe <snipe@snipe.net>
2023-01-09 20:43:57 -08:00
snipe cc665d50ed One more refactor, hopefully simplifying
Signed-off-by: snipe <snipe@snipe.net>
2023-01-09 20:40:12 -08:00
snipe ae76d46f87 Small refactor to ALWAYS return deleted assets in a collection transformer
Signed-off-by: snipe <snipe@snipe.net>
2023-01-09 20:23:05 -08:00
snipe bf849128fc Replicate the response behavior in the bySerial endpoint
Signed-off-by: snipe <snipe@snipe.net>
2023-01-09 19:57:47 -08:00
snipe 44be8c8f60 Determine which transformer to use based on number of assets
Signed-off-by: snipe <snipe@snipe.net>
2023-01-09 19:54:21 -08:00
snipe bad1253682 Merge remote-tracking branch 'origin/develop' 2023-01-09 17:15:44 -08:00
snipe 20a9be2f6c Merge pull request #12326 from uberbrady/uncache_settings
The cache system in getSettings() cached values "forever." That's bad.
2023-01-09 17:14:22 -08:00
Brady Wetherington 39b1a5a8a0 Remove old cache key for settings 2023-01-09 16:19:25 -08:00
Brady Wetherington 2d0ac5b48b The cache system in getSettings() cached values "forever." That's bad. 2023-01-09 16:16:09 -08:00
snipe e67bd5a275 Merge remote-tracking branch 'origin/develop' 2023-01-09 16:00:33 -08:00
snipe 8d35583634 Merge pull request #12324 from snipe/features/add_username_to_asset_list
Added username to display in asset listings
2023-01-09 16:00:01 -08:00
snipe b39a9e0fe1 Merge remote-tracking branch 'origin/develop' 2023-01-09 15:54:04 -08:00
snipe ae04a8c872 Merge pull request #12325 from uberbrady/ldap_permissions_fix
Fixed #12288 - LDAP default group feature refactor
2023-01-09 15:52:02 -08:00
Brady Wetherington cbffd105a2 Fix LDAP default group feature 2023-01-09 15:23:19 -08:00
snipe a57315aed5 Added username to display in asset listings
Signed-off-by: snipe <snipe@snipe.net>
2023-01-09 12:58:58 -08:00
snipe e1263155b1 Merge pull request #12323 from snipe/translations/updated_strings
Updated language strings
2023-01-09 11:10:19 -08:00
snipe 014eab3abc Updated language strings
Signed-off-by: snipe <snipe@snipe.net>
2023-01-09 11:09:26 -08:00
snipe f1bc183043 Merge pull request #12320 from snipe/dependabot/github_actions/actions/checkout-3.3.0
Bump actions/checkout from 3.2.0 to 3.3.0
2023-01-09 10:17:06 -08:00
dependabot[bot] 2f20945516 Bump actions/checkout from 3.2.0 to 3.3.0
Bumps [actions/checkout](https://github.com/actions/checkout) from 3.2.0 to 3.3.0.
- [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/v3.2.0...v3.3.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-01-09 08:06:28 +00:00
snipe 91d0c383df Production assets
Signed-off-by: snipe <snipe@snipe.net>
2023-01-05 18:47:55 -08:00
snipe 886f2a0dec Merge pull request #12317 from snipe/fixes/shorten_url_display_on_view
Truncate URL with ellipsis if too long
2023-01-05 18:44:44 -08:00
snipe e05764ac34 Truncate URL with ellipsis if too long
Signed-off-by: snipe <snipe@snipe.net>
2023-01-05 18:42:26 -08:00
snipe a916c68f95 Merge remote-tracking branch 'origin/develop' 2023-01-05 18:07:59 -08:00
snipe 19e703980d Merge pull request #12316 from snipe/features/chunk_data_in_sync_script
Chunk sync script
2023-01-05 18:07:30 -08:00
snipe 6e42bce409 Removed $start variable from calback
Signed-off-by: snipe <snipe@snipe.net>
2023-01-05 18:04:06 -08:00
snipe 1a3c947b14 Chunk sync script
Signed-off-by: snipe <snipe@snipe.net>
2023-01-05 17:57:52 -08:00
snipe 4d0fc99773 Merge remote-tracking branch 'origin/develop' 2023-01-05 14:19:51 -08:00
snipe bd3f730cb2 Merge pull request #12315 from snipe/features/added_default_values_to_model_api
Features/added default values to model api
2023-01-05 14:11:24 -08:00
snipe 381f89c5a8 Added format to array
Signed-off-by: snipe <snipe@snipe.net>
2023-01-05 13:15:30 -08:00
snipe db43628bdc Added default field info to models API response
Signed-off-by: snipe <snipe@snipe.net>
2023-01-05 13:12:54 -08:00
snipe ace73acba1 Merge pull request #12263 from Godmartinz/gh12211_label_padding_adjustment
Fixed: page-break and padding at the end of document for labels
2023-01-05 09:59:35 -08:00
Godfrey M 301c4fda6e fixes conflicts 2023-01-05 09:55:25 -08:00
snipe 5898e384f8 Merge pull request #12308 from snipe/fixes/missing_translation_string
Fixed missing translation string
2023-01-04 15:13:36 -08:00
snipe 9c63f426d9 Added missing translation string
Signed-off-by: snipe <snipe@snipe.net>
2023-01-04 14:09:14 -08:00
snipe c575798b56 Merge pull request #12307 from snipe/fixes/update_less_and_css_loader
Updated less-loader and css-loader libraries
2023-01-04 14:01:03 -08:00
snipe 7123e7327f Updated less-loader and css-loader libraries
Signed-off-by: snipe <snipe@snipe.net>
2023-01-04 14:00:04 -08:00
snipe b36e81836f Merge pull request #12306 from snipe/fixes/weird_sentence_in_translations
Fixed incomplete sentence in translation file for audit interval
2023-01-04 13:57:14 -08:00
snipe b77d5801fa English is hard, apparently
Signed-off-by: snipe <snipe@snipe.net>
2023-01-04 13:56:16 -08:00
snipe 818db58a7b Merge pull request #12305 from uberbrady/fix_license_seat_reporting
Fixed: Change license_seat changing method to properly 'true up' license seats
2023-01-04 13:22:03 -08:00
Brady Wetherington c4f900e9af Change license_seat changing method to properly 'true up' license seats 2023-01-04 13:02:53 -08:00
snipe baf14c43ee Merge pull request #12298 from snipe/fixes/db_seeder_company_id
Fixed db seeder when company id is not present
2023-01-03 14:50:25 -08:00
snipe fa439a1928 Check that the array key exists before trying to seed it
Signed-off-by: snipe <snipe@snipe.net>
2023-01-03 14:45:23 -08:00
snipe d187174f00 Merge pull request #12090 from Godmartinz/deparmtnet_name_validator
Added: validation for department names at Company locations
2022-12-22 11:29:12 -08:00
snipe 6d3c5e0659 Merge pull request #12264 from Godmartinz/gh12253_display_notes_accessories
Added: notes to the accessories tab for user detail view
2022-12-21 19:04:11 -08:00
snipe c49d69c911 Merge branch 'develop' 2022-12-20 17:27:17 -08:00
snipe 685cc86d71 Sets the ldap_default_group field to nullable and default null
Signed-off-by: snipe <snipe@snipe.net>
2022-12-20 17:24:01 -08:00
snipe fb10a6f218 Merge pull request #12268 from inietov/fixes/people_count
Fixed: Dashboard user count scoping when full company support is enabled
2022-12-20 17:05:18 -08:00
Ivan Nieto Vivanco 3a9b8a4993 Calculate the proper amount of people in the dashboard if Full Company Support is enabled 2022-12-20 18:39:17 -06:00
snipe a6c7471bf5 Merge remote-tracking branch 'origin/develop' 2022-12-20 15:11:36 -08:00
snipe 128c21a905 Merge pull request #12266 from uberbrady/fix-select-all-bug
Fixed: There was a bug with BS tables' select-all which showed an incorrect list of elements
2022-12-20 15:09:30 -08:00
Brady Wetherington 75a757d6f5 There was a bug with select-all where some bits didn't quite work 2022-12-20 14:57:58 -08:00
Godfrey M e791e6592a adds notes to the accessories tab under users 2022-12-20 10:37:19 -08:00
Godfrey M 38575e93e8 fixes the rules for adding page-break and padding at the end of document 2022-12-20 09:45:41 -08:00
snipe 88291cadc1 Merge pull request #12254 from akemidx/documentating_something
Commenting on a scope in Models/Company.php
2022-12-19 12:41:32 -08:00
snipe cc40ecaa44 Merge pull request #12260 from snipe/dependabot/github_actions/actions/checkout-3.2.0
Bump actions/checkout from 3.1.0 to 3.2.0
2022-12-19 12:41:17 -08:00
akemidx 94afe2bc6a edits & typo fixes 2022-12-19 14:48:43 -05:00
dependabot[bot] 25b33d657e Bump actions/checkout from 3.1.0 to 3.2.0
Bumps [actions/checkout](https://github.com/actions/checkout) from 3.1.0 to 3.2.0.
- [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/v3.1.0...v3.2.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-12-19 08:07:03 +00:00
snipe 399c7590cd Merge pull request #12209 from snipe/fixes/error_downloading_unaccepted_assets
Fixed 500 when downloading the Unaccepted Assets report  [sc-19555]
2022-12-15 14:19:41 -08:00
snipe d0c5ba70f6 Merge pull request #12242 from inietov/features/add_purchase_cost_column
Added `purchase_cost` to user's default view [sc-19680]
2022-12-15 12:42:29 -08:00
akemidx 133d6ffa50 Commenting on a scope in Models/Company.php 2022-12-15 15:18:24 -05:00
Ivan Nieto Vivanco d9a21cce00 Add other items' purchase_cost columns to the same permission 2022-12-15 14:12:05 -06:00
snipe 29c2ff56ec Merge pull request #12188 from snipe/fixes/decrease_logging_for_saml_when_not_enabled
Removed extra logging case that was very noisy
2022-12-15 11:26:49 -08:00
snipe 3e7975b2c3 Merge pull request #12250 from akemidx/grey_out_pw_reset_button
Fixed: Grey out pw reset button for consistency
2022-12-15 11:25:53 -08:00
akemidx d870bc3b02 nested if loop 2022-12-15 14:19:51 -05:00
snipe 227fef76ee Merge pull request #11736 from Godmartinz/gh6508_ldap_default_group
Adds a permission group selection for directory sync
2022-12-15 11:06:53 -08:00
Godfrey M 9d44720ffd reverted changes to composer.lock 2022-12-15 11:02:34 -08:00
Godfrey M 9f3f0a25ed reverted changes to composer.lock 2022-12-15 10:53:45 -08:00
Godfrey M 2e228ccb0b redid a few things. should be good now :) 2022-12-15 10:45:42 -08:00
Godfrey M 3ee413f379 removes livewire stuff 2022-12-15 09:20:30 -08:00
Ivan Nieto Vivanco b142f8e012 Add the permission to show purchase cost column to non-admin sessions 2022-12-14 23:00:35 -06:00
snipe 418ddcfac3 Merge pull request #9876 from Toreg87/fixes/locations-deletable
Fixed #9875: Make locations deletable for non Superuser-Accounts with FullMultipleCompanySupport
2022-12-14 17:46:53 -08:00
snipe c342668f0f Update @scoo73r as a contributor 2022-12-14 17:25:39 -08:00
snipe 2f6a26ec7d Add @scoo73r as a contributor 2022-12-14 17:25:25 -08:00
snipe b89979fbec Merge remote-tracking branch 'origin/develop'
Signed-off-by: snipe <snipe@snipe.net>

# Conflicts:
#	public/js/build/app.js
#	public/js/dist/all.js
#	public/mix-manifest.json
2022-12-14 17:06:26 -08:00
snipe f635278010 Merge pull request #12251 from snipe/security/upgrade_font_awesome
Upgraded font awesome to 6.2.1
2022-12-14 16:42:41 -08:00
snipe 8043b86786 Upgraded font awesome to 6.2.1
Signed-off-by: snipe <snipe@snipe.net>
2022-12-14 16:41:56 -08:00
snipe d13a237000 Merge pull request #12205 from Godmartinz/sc19675_add_remote_to_importer
Adds remote field to the user importer
2022-12-14 12:13:18 -08:00
akemidx b114ffd2c3 Grey out button pw reset button for consistency
When user has no email in their profile, the box is greyed out for
consistency accross all buttons on the user profile
2022-12-14 14:48:59 -05:00
snipe fabefa61b0 Merge pull request #12243 from akemidx/new_grey_out_when_no_assets
Created method in users.php for adding up all assigned to user and pr…
2022-12-13 14:00:48 -08:00
akemidx f3e57d7dc0 fixing PR 2022-12-13 16:00:59 -05:00
snipe 389ec3a3cb Merge pull request #12247 from Godmartinz/gh12225_serial_added_to_components
adds serial to components tab of assets
2022-12-13 12:57:50 -08:00
Godfrey M 6a72c344b7 removed the cuddlers 2022-12-13 12:32:30 -08:00
Godfrey M 4442b446b9 adds serial to components tab of assets 2022-12-13 10:30:37 -08:00
snipe c432fb9d70 Merge pull request #12181 from Godmartinz/gh12163_asset_age
Adds asset age to asset index and asset view pages
2022-12-13 10:28:17 -08:00
akemi 07ae91b00f Created method in users.php for adding up all assigned to user and providing an integer value. this then used to grey out buttons on user view if user has nothing assigned. 2022-12-12 15:47:53 -05:00
Ivan Nieto Vivanco 450ad3dcec Added the column purchase_cost to user's default view 2022-12-12 14:17:08 -06:00
Godfrey M fa872b09a9 fixes a typo, the world is great again 2022-12-12 10:38:31 -08:00
snipe 9833ba4ab6 Merge remote-tracking branch 'origin/develop' 2022-12-09 16:08:56 -08:00
snipe 9e8fff6e5b Merge pull request #12238 from snipe/features/add_email_to_endpoint
Add email in assigned_to on asset transformer
2022-12-09 16:08:35 -08:00
snipe 4ac09ff4e4 Add email in assigned_to on asset transformer
Signed-off-by: snipe <snipe@snipe.net>
2022-12-09 16:07:17 -08:00
snipe e26036e998 Merge remote-tracking branch 'origin/develop' 2022-12-08 17:36:01 -08:00
snipe 1017148bad Merge pull request #12233 from snipe/fixes/translation_placeholder_for_ola_pt-BR
Fixed #12215 - string for “Hello, :name” in pt-BR was using `%`
2022-12-08 17:25:19 -08:00
snipe 00ed197651 Fixed #12215 - string for “Hello, :name” in pt-BR was using %
Signed-off-by: snipe <snipe@snipe.net>
2022-12-08 17:21:55 -08:00
snipe 66f8ac1cd1 Merge remote-tracking branch 'origin/develop' 2022-12-08 14:52:13 -08:00
snipe 775df0ab60 Merge pull request #12221 from snipe/fixes/throttles_reset_password_form
Add throttle for password reset form
2022-12-08 14:51:22 -08:00
snipe 687f8971b1 Merge remote-tracking branch 'origin/develop'
Signed-off-by: snipe <snipe@snipe.net>

# Conflicts:
#	config/version.php
2022-12-08 14:49:31 -08:00
snipe bc2a455a89 Bumped version
Signed-off-by: snipe <snipe@snipe.net>
2022-12-08 14:48:55 -08:00
snipe 97c28d9adc Add @oguzbilgic as a contributor 2022-12-08 14:44:28 -08:00
snipe 163b3f6c0b Merge remote-tracking branch 'origin/develop' 2022-12-08 14:37:35 -08:00
snipe 9b3df40ed6 Merge pull request #12231 from oguzbilgic/patch-2
Use `heroku-redis:mini` instead of `hobby` as It is deprecated
2022-12-08 11:22:14 -08:00
Oguz Bilgic 1c8ee0f706 Use heroku-redis:mini instead of hobby as It is deprecated
Heroku has renamed it's plan to `mini`.
2022-12-08 11:20:33 -08:00
snipe d7c5a6af71 Merge pull request #12224 from Godmartinz/gh12211_img_barcode_adjustment
Fixes the margin and padding for img barcode in labels
2022-12-07 16:35:04 -08:00
snipe 743264fd0e Merge remote-tracking branch 'origin/develop' 2022-12-07 16:23:50 -08:00
snipe f7da87520c Merge pull request #12134 from Godmartinz/custom_report_user_fields_missing
fixes a regression with the csv assigned to fields
2022-12-07 16:18:32 -08:00
Godfrey M ec854ddc1d adjusts the margin and padding for img barcode in labels 2022-12-07 14:52:23 -08:00
snipe 1a8b2a169b Merge pull request #12219 from snipe/fixes/typo_in_sr_text_for_apple
Fixed typo in screen reader text
2022-12-07 13:12:07 -08:00
snipe 43acd3b488 Fixed typo
Signed-off-by: snipe <snipe@snipe.net>
2022-12-07 13:11:17 -08:00
snipe c3a6874b16 Add throttle for password reset form
Signed-off-by: snipe <snipe@snipe.net>
2022-12-06 20:42:40 -08:00
Ivan Nieto Vivanco eb67d1b064 Filter items from the report if null returned 2022-12-06 18:00:16 -06:00
Godfrey M d0d0058e79 removed unwanted changes 2022-12-06 11:19:28 -08:00
Godfrey M bbd04f8876 adds the rest of the fields for Remote 2022-12-06 11:13:24 -08:00
snipe 97731cd7c8 Merge remote-tracking branch 'origin/develop'
Signed-off-by: snipe <snipe@snipe.net>

# Conflicts:
#	public/css/dist/skins/skin-black-dark.css
#	public/css/dist/skins/skin-black-dark.min.css
#	public/css/dist/skins/skin-black.css
#	public/css/dist/skins/skin-black.min.css
#	public/css/dist/skins/skin-blue-dark.css
#	public/css/dist/skins/skin-blue-dark.min.css
#	public/css/dist/skins/skin-blue.css
#	public/css/dist/skins/skin-blue.min.css
#	public/css/dist/skins/skin-green-dark.css
#	public/css/dist/skins/skin-green-dark.min.css
#	public/css/dist/skins/skin-green.css
#	public/css/dist/skins/skin-green.min.css
#	public/css/dist/skins/skin-orange-dark.css
#	public/css/dist/skins/skin-orange-dark.min.css
#	public/css/dist/skins/skin-orange.css
#	public/css/dist/skins/skin-orange.min.css
#	public/css/dist/skins/skin-purple-dark.css
#	public/css/dist/skins/skin-purple-dark.min.css
#	public/css/dist/skins/skin-purple.css
#	public/css/dist/skins/skin-purple.min.css
#	public/css/dist/skins/skin-red-dark.css
#	public/css/dist/skins/skin-red-dark.min.css
#	public/css/dist/skins/skin-red.css
#	public/css/dist/skins/skin-red.min.css
#	public/css/dist/skins/skin-yellow-dark.css
#	public/css/dist/skins/skin-yellow-dark.min.css
#	public/css/dist/skins/skin-yellow.css
#	public/css/dist/skins/skin-yellow.min.css
#	public/mix-manifest.json
2022-12-05 16:34:34 -08:00
Godfrey M 36901d271b adds csvmatch for remote. Im a bit lost though lol 2022-12-05 16:28:19 -08:00
snipe b7a5467f8b Merge pull request #12204 from akemidx/fixcurlyquotes
Fixed: curly quotes in #12182
2022-12-05 15:33:47 -08:00
akemi 2f8a435e18 fixing curly quotes 2022-12-05 18:06:28 -05:00
snipe 9ca40716ce Merge pull request #12197 from inietov/fixes/custom_regex_defaults_to_any
Fixed #11682  Custom field type of CUSTOM REGEX defaults back to ANY on editing
2022-12-05 13:24:22 -08:00
snipe 7518cab7c8 Merge pull request #12194 from Godmartinz/FDD32094_Icon_color_change
changes the life-ring icon color with themes
2022-12-01 10:04:55 -08:00
Ivan Nieto Vivanco 8d36971c8b Properly select 'CUSTOM REGEX' from the select list if the format declares onee 2022-11-30 16:21:23 -06:00
Godfrey M 371a5bf4d6 changes the icon color with themes 2022-11-30 10:37:47 -08:00
snipe cfc4229308 Add @akemidx as a contributor 2022-11-29 13:15:28 -08:00
snipe 8bf01715a9 Merge pull request #12182 from akemidx/translate_inventory_notification
Fixed #12119 - updated user inventory language to use strings
2022-11-29 13:14:32 -08:00
akemi 55f5e7866d edits for PR 2022-11-29 15:59:36 -05:00
Godfrey M 3206929ee4 adds AgeFormatter, not working yet 2022-11-29 09:51:42 -08:00
snipe 1fe0bfe17e Removed extra logging case that was very noisy
Signed-off-by: snipe <snipe@snipe.net>
2022-11-28 19:27:42 -08:00
snipe 9c205f63ae Merge remote-tracking branch 'origin/develop' 2022-11-28 19:21:19 -08:00
snipe 0cc7389b85 Merge pull request #12187 from snipe/features/added_jobtitle_to_print
Fixed #12133 - Added job title to header in print assets view
2022-11-28 19:20:46 -08:00
snipe e21d0729c1 Add jobh title to header in print assets view
Signed-off-by: snipe <snipe@snipe.net>
2022-11-28 19:19:42 -08:00
snipe c46dc99e86 Merge remote-tracking branch 'origin/develop' 2022-11-28 17:20:57 -08:00
snipe 64a8d1d207 Merge pull request #12185 from snipe/features/add_serial_to_inventory_email
Added serial number to emailed inventory report
2022-11-28 17:20:34 -08:00
snipe 8de59d117f Added serial number to emailed inventory report
Signed-off-by: snipe <snipe@snipe.net>
2022-11-28 17:14:38 -08:00
snipe d5e702ac74 Merge remote-tracking branch 'origin/develop' 2022-11-28 14:12:38 -08:00
snipe 6113afe36e Merge pull request #12125 from inietov/fixes/email_issues
Fixed #11699 and #12065 Email issues
2022-11-28 14:09:42 -08:00
snipe 305df42f92 Merge pull request #12167 from inietov/features/no_submit_until_status_selected
Fixed #11980 Submit button deactivated in Users' Bulk Checkin if no status selected
2022-11-28 13:17:33 -08:00
snipe 9aa0356de7 Merge pull request #12159 from uberbrady/upgrade_scim_server_to_upstream
Pulled in latest upstream changes for improved standards-compliance
2022-11-28 13:15:27 -08:00
snipe d2dcb29dcb Merge remote-tracking branch 'origin/develop'
Signed-off-by: snipe <snipe@snipe.net>

# Conflicts:
#	resources/views/models/custom_fields_form.blade.php
2022-11-28 12:27:36 -08:00
akemi 39e06a8856 Update to PR#12119, adding inventory notification to messages and changing code to be dynamicaly translated 2022-11-28 14:16:22 -05:00
Godfrey M 8d861cfd82 adds age to the asset table 2022-11-28 10:59:18 -08:00
Godfrey M 078e7281cd adds asset age to asset view 2022-11-28 10:45:58 -08:00
snipe 3ef578eb56 Merge pull request #12164 from Robert-Azelis/patch-7
Fix categories view columns matching
2022-11-23 18:47:02 -08:00
snipe 11a1ab971c Merge pull request #12166 from inietov/fixes/custom_fields_values_develop
Fixed #12046 #12137 Custom field checkboxes not holding value for develop
2022-11-23 18:44:23 -08:00
snipe d226cf189b Merge pull request #12168 from inietov/fixes/error_accepting_assets
Fixed #12161 500 error when accepting assets
2022-11-23 18:41:42 -08:00
Ivan Nieto Vivanco c082d8b90e Return empty string if no MAIL_REPLYTO_ADDR var set 2022-11-23 18:22:31 -06:00
Ivan Nieto Vivanco b1985a08c4 Checks the status before activate the submit button on users bulk-checkin 2022-11-23 17:45:59 -06:00
Ivan Nieto Vivanco 9bafe795b0 Corrected the view when editing custom fields values 2022-11-23 16:34:29 -06:00
snipe bb4c084435 Merge pull request #12165 from inietov/fixes/custom_fields_values
Fixed #12046 #12137 Custom field checkboxes not holding value
2022-11-23 15:09:58 -05:00
Ivan Nieto Vivanco feeb1c7ac8 Corrected the view when editing custom fields values 2022-11-23 12:21:07 -06:00
Robert-Azelis c2cfd8ff53 Update CategoryPresenter.php 2022-11-23 19:00:08 +01:00
Robert-Azelis 20ad4fb681 Update CategoryPresenter.php
Fix snipe#12153
2022-11-23 18:42:38 +01:00
Brady Wetherington 06a1fe5b38 Pulled in latest upstream changes for improved standards-compliance 2022-11-22 12:52:11 -08:00
snipe b6f87633f5 Merge remote-tracking branch 'origin/develop' 2022-11-22 12:36:00 -08:00
snipe e426846c23 Merge pull request #12157 from snipe/fixes/inherit_bgcolor_for_readonly
Fixed background color for readonly date picker fields
2022-11-22 16:57:34 +00:00
snipe 27898e660c Inherit the background color, since the field isn’t actually technically readonly
Signed-off-by: snipe <snipe@snipe.net>
2022-11-22 08:54:48 -08:00
Aaron 2c7364bdfe Fixed #11225: run_as_app_user unknown operand
Fixed #10581: installer does not work on CentOS7
Fixed #10105: php not found, composer failed
Fixed #9035: CentOS 7 IUS repos missing
2022-11-22 11:47:58 -05:00
snipe 0d9d02c6d6 Merge pull request #12148 from whalehub/develop
Fix restore icon in table view
2022-11-19 10:25:48 +00:00
Aaron 7c854c0a5c Fix restore icon in table view
Signed-off-by: Aaron <admin@datahoarder.dev>
2022-11-19 10:45:10 +01:00
snipe efc892cf5e Merge remote-tracking branch 'origin/develop' 2022-11-17 21:29:14 +00:00
snipe ba4c37a7f4 Merge pull request #12139 from snipe/fixes/custom_fields_api_patches
Fixed #9949 - PATCH to custom fields failing on validation (alt approach to #12011)
2022-11-17 21:28:39 +00:00
snipe f0c5560c1b Merge pull request #12141 from Godmartinz/adds_serial_number_to_history
Added `serial` column to the user history page
2022-11-17 21:15:26 +00:00
snipe 774962c122 Fixed typo
Signed-off-by: snipe <snipe@snipe.net>
2022-11-17 21:14:35 +00:00
Godfrey M 0a9fd0b867 adds serial to activity report page 2022-11-17 13:09:06 -08:00
Godfrey M 5c94ca1403 removes dead space 2022-11-17 13:06:07 -08:00
Godfrey M 86bc409d3a adds serial column to the action logs 2022-11-17 12:57:53 -08:00
snipe 24841a75d4 Move common things into the model level validation
Signed-off-by: snipe <snipe@snipe.net>
2022-11-17 19:41:10 +00:00
Godfrey M a02a04d601 fixes a regression with the csv assigned to fields 2022-11-16 16:34:57 -08:00
snipe 3997085faf Merge pull request #12122 from Godmartinz/fixes_checkout_to_all_description
fixes checkout to all description
2022-11-16 21:56:53 +00:00
snipe 3ac92e1425 Merge pull request #12127 from deloz/fix-Asset-checked-in-Email-Asset-Picture-Not-Displaying
Fixed #12095 - email logo still linking even if settings deny it
2022-11-16 21:55:59 +00:00
snipe 5661e69520 Merge remote-tracking branch 'origin/develop' 2022-11-16 17:49:14 +00:00
snipe cdcd19a7d8 Merge pull request #12132 from snipe/fixes/view_assets_page_error_when_no_custom_fields
Handle use case where there are no custom fields for any assigned models
2022-11-16 17:48:53 +00:00
snipe 489895a5fa Added comments and spacing for readability
Signed-off-by: snipe <snipe@snipe.net>
2022-11-16 17:48:28 +00:00
snipe 1122562b4e Handle use case where there are no custom fields for any assigned models
Signed-off-by: snipe <snipe@snipe.net>
2022-11-16 17:45:50 +00:00
snipe 65e46c914c Merge remote-tracking branch 'origin/develop' 2022-11-16 15:57:46 +00:00
snipe 4ffe13d3c2 Merge pull request #12131 from snipe/fixes/check_for_format_index_in_custom_field_api_call
Fixed 500 if `format` is not passed to the create custom field endpoint payload
2022-11-16 15:57:07 +00:00
snipe 5df76155ce Check for the format index in the $data array when creating a new custom field via API
Signed-off-by: snipe <snipe@snipe.net>
2022-11-16 15:53:16 +00:00
snipe e1c33d4eff Merge pull request #12129 from deloz/fix-remove-duplicate-column-checkin_email
Fixed #12109 - Duplicate column on Category listing
2022-11-16 11:41:55 +00:00
Instead of looking elsewhere, it is better to come here together 2fc7a15372 Fixed: #12109 2022-11-16 18:22:11 +08:00
Instead of looking elsewhere, it is better to come here together 9056d48775 Fixed: 12095 2022-11-16 18:16:45 +08:00
Godfrey M 9fefdea9de fixes checkout to all description 2022-11-15 12:50:46 -08:00
snipe 2239c6f7e2 Merge remote-tracking branch 'origin/develop' 2022-11-15 17:58:19 +00:00
snipe da0efaa278 Add @fernando-almeida as a contributor 2022-11-15 17:56:19 +00:00
snipe 69bde0443e Add @lukasfehling as a contributor 2022-11-15 17:56:01 +00:00
snipe 6400bdc266 Merge pull request #12120 from snipe/features/added_deleted_filter_to_search_by_tag
Added ability to include deleted items in tag search endpoint
2022-11-15 17:54:34 +00:00
snipe ffd252a00c Merge pull request #12119 from lukasfehling/feature/added-endpoint-for-user-notification
Added: API endpoint to trigger a user email notification with their assigned assets
2022-11-15 17:51:15 +00:00
snipe 7fcf6f2463 Removed deleted parameter
Signed-off-by: snipe <snipe@snipe.net>
2022-11-15 17:47:21 +00:00
snipe 5103f28598 Merge pull request #12121 from snipe/fixes/safer_file_existance_checking_for_model_files
Replace error suppression with better logic
2022-11-15 17:43:39 +00:00
snipe 60d7128a5e Replace error suppression with better logic
Signed-off-by: snipe <snipe@snipe.net>
2022-11-15 17:41:57 +00:00
snipe 2c5a0d370c Clean up API byserial and bytag, allow deleted param
Signed-off-by: snipe <snipe@snipe.net>
2022-11-15 17:33:56 +00:00
snipe bcbe517446 Added ability to include deleted items in tag search endpoint
Signed-off-by: snipe <snipe@snipe.net>
2022-11-15 17:18:09 +00:00
lukasfehling d9a9bd1c0d Added a api endpoint for sending email notifications to users with their assigned assets 2022-11-15 18:17:51 +01:00
snipe 2166fcec41 Merge pull request #12118 from snipe/features/adds_asset_tag_and_serial_to_api
Allow searching firectly for asset tag and serial
2022-11-15 17:16:17 +00:00
snipe 9a5d431962 Allow searching firectly for asset tag and serial
Signed-off-by: snipe <snipe@snipe.net>
2022-11-15 17:13:26 +00:00
snipe 6dc0846f38 Merge pull request #12117 from snipe/fixes/pr_12106_missing_slash_for_stdClass
Fixes PR #12106 missing slash for std class
2022-11-15 17:04:58 +00:00
snipe 50431c046f Fixed missing slash in stdClass
Signed-off-by: snipe <snipe@snipe.net>
2022-11-15 17:04:06 +00:00
Ivan Nieto Vivanco f0ecab7bb1 Fix typo in variable (ah-hyuck!) 2022-11-15 11:00:40 -06:00
Ivan Nieto Vivanco 7cc8b39863 Checks if settings let URL's be shown in email notifications 2022-11-15 10:55:54 -06:00
snipe ae259f36ae Merge pull request #12106 from fernando-almeida/develop
Fix HTTP AssetTransformer to generate an empty object for missing custom fields
2022-11-15 15:54:43 +00:00
Ivan Nieto Vivanco cd2997b674 Determine if email_logo or logo setting needs to be used in the Forgot Password email 2022-11-15 08:08:26 -06:00
snipe b4ff07ce9e Merge remote-tracking branch 'origin/develop' 2022-11-14 22:53:39 +00:00
snipe 8122236944 Merge pull request #12096 from snipe/features/add_custom_field_option_to_view_assets
Added custom field option to view assets
2022-11-14 22:45:26 +00:00
snipe 56c4fa7c27 Override display settings if field is encrypted
Signed-off-by: snipe <snipe@snipe.net>
2022-11-14 22:41:31 +00:00
snipe 602c2698d2 Fixed broken table header tag
Signed-off-by: snipe <snipe@snipe.net>
2022-11-14 22:06:23 +00:00
snipe ff0b68724f Merge pull request #12107 from snipe/fixes/500_on_missing_model_file
Fixed 500 error if model files are missing
2022-11-14 22:04:31 +00:00
snipe d4ac7530b6 Removed download button for files that don’t exist on the server
Signed-off-by: snipe <snipe@snipe.net>
2022-11-14 22:04:06 +00:00
snipe 4aded5e117 FIxed 500 error if model files are missing
Signed-off-by: snipe <snipe@snipe.net>
2022-11-14 22:01:33 +00:00
snipe 8d03ce5e2c Merge remote-tracking branch 'origin/develop' 2022-11-14 17:45:01 +00:00
snipe 15da39d44a Merge pull request #12105 from snipe/fixes/500_on_missing_license_files
Fixed 500 on missing license files
2022-11-14 17:44:16 +00:00
snipe 077d343f01 Prevent 500 if license file is missing
Signed-off-by: snipe <snipe@snipe.net>
2022-11-14 17:42:40 +00:00
Fernando Almeida 47ee2a8153 Fix HTTP AssetTransformer to generate an empty object for missing custom_fields instead of an empty array. 2022-11-14 16:31:08 +00:00
snipe ae95ee49f1 Hide the option if the field is encrypted
Signed-off-by: snipe <snipe@snipe.net>
2022-11-10 17:56:50 +00:00
snipe 2ac558494d Set column width instead of letting BS tables guess
Signed-off-by: snipe <snipe@snipe.net>
2022-11-10 17:21:07 +00:00
snipe ede16ad2c2 Removed unused block
Signed-off-by: snipe <snipe@snipe.net>
2022-11-10 17:19:35 +00:00
snipe 1e34398c99 Permissions check on the field itself
Signed-off-by: snipe <snipe@snipe.net>
2022-11-10 17:19:12 +00:00
snipe 7a5fcfb87a Loop through fields array
Signed-off-by: snipe <snipe@snipe.net>
2022-11-10 16:46:59 +00:00
snipe 1fa624420e Removed unneeded relationships
Signed-off-by: snipe <snipe@snipe.net>
2022-11-10 16:46:49 +00:00
Godfrey M 92ae271292 adds validation for department names at Company locations 2022-11-09 13:11:33 -08:00
snipe 6a9131e771 Merge pull request #12088 from uberbrady/minimal_scim_upgrade
Added new SCIM env vars; and upgraded SCIM library
2022-11-09 19:30:50 +00:00
Brady Wetherington 383bd6bb45 Add new SCIM env vars; upgrade SCIM library 2022-11-09 19:08:15 +00:00
snipe 097821b818 Slight revamping of column layouts and also added new general.display_in_user_view column
Signed-off-by: snipe <snipe@snipe.net>
2022-11-08 15:28:19 +00:00
snipe 2e56c9b521 Added new general.display_in_user_view field to form
Signed-off-by: snipe <snipe@snipe.net>
2022-11-08 15:27:59 +00:00
snipe b95d24b5eb Additional translations
Signed-off-by: snipe <snipe@snipe.net>
2022-11-08 15:27:44 +00:00
snipe f91e1d58ad Migration to add the field to the custom_fields table
Signed-off-by: snipe <snipe@snipe.net>
2022-11-08 15:27:34 +00:00
snipe 7c37c70164 Added new field to allowed_fields so that the API can change them if needed
Signed-off-by: snipe <snipe@snipe.net>
2022-11-08 15:27:22 +00:00
snipe 52dc5aa4ba Added field to controller and tranformer
Signed-off-by: snipe <snipe@snipe.net>
2022-11-08 15:26:59 +00:00
Godfrey M f2d4a61e3c removes dead space 2022-10-18 15:31:37 -07:00
Godfrey M 3f25a1bf61 removes dead code 2022-10-18 15:25:38 -07:00
Godfrey M f9ac447dd1 adds default group to LDAP 2022-10-18 15:18:09 -07:00
Godfrey M 9b448227f7 tinkering to no avail 2022-09-13 11:40:10 -07:00
Godfrey M 28bc97f29f one line away from this being over with 2022-09-12 11:40:16 -07:00
Godfrey M 193b31e427 select options working, testing sync then done 2022-08-31 12:58:33 -07:00
Godfrey M 70ac8af9c4 . 2022-08-31 09:53:20 -07:00
Godfrey M 0c362e8b57 gets the groups selector to appear but options are blank 2022-08-29 12:09:56 -07:00
Godfrey M fc6fefdb4e adds migration, variables, checkbox,working on groups 2022-08-25 15:19:38 -07:00
Tobias Regnery 1a908e361e Make locations deletable for non Superuser-Accounts with FullMultipleCompanySupport
locations->isDeletable() checks via gate::allows if a locations is deletable.
This calls SnipePermissionsPolicy->before() and checks for !Company::isCurrentUserHasAccess($item).
This returns false because locations don't have a company_id.

Check for this and return true if the item don't have a company_id.
2021-07-29 10:43:01 +02:00
754 changed files with 290214 additions and 3693 deletions
+54
View File
@@ -2783,6 +2783,60 @@
"contributions": [
"code"
]
},
{
"login": "lukasfehling",
"name": "Lukas Fehling",
"avatar_url": "https://avatars.githubusercontent.com/u/56871540?v=4",
"profile": "https://github.com/lukasfehling",
"contributions": [
"code"
]
},
{
"login": "fernando-almeida",
"name": "Fernando Almeida",
"avatar_url": "https://avatars.githubusercontent.com/u/1975990?v=4",
"profile": "https://github.com/fernando-almeida",
"contributions": [
"code"
]
},
{
"login": "akemidx",
"name": "akemidx",
"avatar_url": "https://avatars.githubusercontent.com/u/116301219?v=4",
"profile": "https://github.com/akemidx",
"contributions": [
"code"
]
},
{
"login": "oguzbilgic",
"name": "Oguz Bilgic",
"avatar_url": "https://avatars.githubusercontent.com/u/144778?v=4",
"profile": "http://oguz.site",
"contributions": [
"code"
]
},
{
"login": "scoo73r",
"name": "Scooter Crawford",
"avatar_url": "https://avatars.githubusercontent.com/u/9262438?v=4",
"profile": "https://github.com/scoo73r",
"contributions": [
"code"
]
},
{
"login": "subdriven",
"name": "subdriven",
"avatar_url": "https://avatars.githubusercontent.com/u/5957345?v=4",
"profile": "https://github.com/subdriven",
"contributions": [
"code"
]
}
]
}
+5 -5
View File
@@ -20,13 +20,13 @@ PUBLIC_FILESYSTEM_DISK=local_public
# REQUIRED: DATABASE SETTINGS
# --------------------------------------------
DB_CONNECTION=mysql
DB_HOST=localhost
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=snipeit-local
DB_USERNAME=snipeit-local
DB_PASSWORD=snipeit-local
DB_DATABASE=null
DB_USERNAME=null
DB_PASSWORD=null
DB_PREFIX=null
DB_DUMP_PATH='/Applications/MAMP/Library/bin'
#DB_DUMP_PATH=
# --------------------------------------------
# OPTIONAL: SSL DATABASE SETTINGS
+6
View File
@@ -174,3 +174,9 @@ REPORT_TIME_LIMIT=12000
REQUIRE_SAML=false
API_THROTTLE_PER_MINUTE=120
CSV_ESCAPE_FORMULAS=true
# --------------------------------------------
# OPTIONAL: SCIM
# --------------------------------------------
SCIM_TRACE=false
SCIM_STANDARDS_COMPLIANCE=false
+1 -1
View File
@@ -26,7 +26,7 @@ jobs:
language: [ 'javascript' ]
steps:
- name: Checkout repository
uses: actions/checkout@v3.1.0
uses: actions/checkout@v3.3.0
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
+1 -1
View File
@@ -32,7 +32,7 @@ jobs:
steps:
# Checkout the repository to the GitHub Actions runner
- name: Checkout code
uses: actions/checkout@v3.1.0
uses: actions/checkout@v3.3.0
# Execute Codacy Analysis CLI and generate a SARIF output with the security issues identified during the analysis
- name: Run Codacy Analysis CLI
+1 -1
View File
@@ -41,7 +41,7 @@ jobs:
steps:
# https://github.com/actions/checkout
- name: Checkout codebase
uses: actions/checkout@v3.1.0
uses: actions/checkout@v3.3.0
# https://github.com/docker/setup-buildx-action
- name: Setup Docker Buildx
+1 -1
View File
@@ -41,7 +41,7 @@ jobs:
steps:
# https://github.com/actions/checkout
- name: Checkout codebase
uses: actions/checkout@v3.1.0
uses: actions/checkout@v3.3.0
# https://github.com/docker/setup-buildx-action
- name: Setup Docker Buildx
+2
View File
@@ -1,6 +1,8 @@
.couscous
.DS_Store
.env
.env.dusk.*
!.env.dusk.example
.idea
/bin/
/bootstrap/compiled.php
+4 -2
View File
@@ -1,5 +1,5 @@
![Build Status](https://app.chipperci.com/projects/0e5f8979-31eb-4ee6-9abf-050b76ab0383/status/master) [![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/) [![Twitter Follow](https://img.shields.io/twitter/follow/snipeitapp.svg?style=social)](https://twitter.com/snipeitapp) [![Codacy Badge](https://api.codacy.com/project/badge/Grade/553ce52037fc43ea99149785afcfe641)](https://www.codacy.com/app/snipe/snipe-it?utm_source=github.com&amp;utm_medium=referral&amp;utm_content=snipe/snipe-it&amp;utm_campaign=Badge_Grade)
[![All Contributors](https://img.shields.io/badge/all_contributors-306-orange.svg?style=flat-square)](#contributors) [![Discord](https://badgen.net/badge/icon/discord?icon=discord&label)](https://discord.gg/yZFtShAcKk) [![huntr](https://cdn.huntr.dev/huntr_security_badge_mono.svg)](https://huntr.dev)
[![All Contributors](https://img.shields.io/badge/all_contributors-312-orange.svg?style=flat-square)](#contributors) [![Discord](https://badgen.net/badge/icon/discord?icon=discord&label)](https://discord.gg/yZFtShAcKk) [![huntr](https://cdn.huntr.dev/huntr_security_badge_mono.svg)](https://huntr.dev)
## Snipe-IT - Open Source Asset Management System
@@ -60,6 +60,7 @@ Since the release of the JSON REST API, several third-party developers have been
- [InQRy -unmaintained-](https://github.com/Microsoft/InQRy) by [@Microsoft](https://github.com/Microsoft)
- [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
- [Marksman](https://github.com/Scope-IT/marksman) - A Windows agent for Snipe-IT
- [Snipe-IT plugin for Jira Service Desk](https://marketplace.atlassian.com/apps/1220964/snipe-it-for-jira)
- [Python 3 CSV importer](https://github.com/gastamper/snipeit-csvimporter) - allows importing assets into Snipe-IT based on Item Name rather than Asset Tag.
@@ -138,7 +139,8 @@ Thanks goes to all of these wonderful people ([emoji key](https://github.com/ken
| [<img src="https://avatars.githubusercontent.com/u/38761237?v=4" width="110px;"/><br /><sub>Alex Janes</sub>](https://adagiohealth.org)<br />[💻](https://github.com/snipe/snipe-it/commits?author=adagioajanes "Code") | [<img src="https://avatars.githubusercontent.com/u/32387849?v=4" width="110px;"/><br /><sub>Nuraeil</sub>](https://github.com/nuraeil)<br />[💻](https://github.com/snipe/snipe-it/commits?author=nuraeil "Code") | [<img src="https://avatars.githubusercontent.com/u/48162670?v=4" width="110px;"/><br /><sub>TenOfTens</sub>](https://github.com/TenOfTens)<br />[💻](https://github.com/snipe/snipe-it/commits?author=TenOfTens "Code") | [<img src="https://avatars.githubusercontent.com/u/9415391?v=4" width="110px;"/><br /><sub>waffle</sub>](https://ditisjens.be/)<br />[💻](https://github.com/snipe/snipe-it/commits?author=insert-waffle "Code") | [<img src="https://avatars.githubusercontent.com/u/19945501?v=4" width="110px;"/><br /><sub>Yevhenii Huzii</sub>](https://github.com/QveenSi)<br />[💻](https://github.com/snipe/snipe-it/commits?author=QveenSi "Code") | [<img src="https://avatars.githubusercontent.com/u/3839381?v=4" width="110px;"/><br /><sub>Achmad Fienan Rahardianto</sub>](https://github.com/veenone)<br />[💻](https://github.com/snipe/snipe-it/commits?author=veenone "Code") | [<img src="https://avatars.githubusercontent.com/u/19945501?v=4" width="110px;"/><br /><sub>Yevhenii Huzii</sub>](https://github.com/QveenSi)<br />[💻](https://github.com/snipe/snipe-it/commits?author=QveenSi "Code") |
| [<img src="https://avatars.githubusercontent.com/u/97299851?v=4" width="110px;"/><br /><sub>Christian Weirich</sub>](https://github.com/chrisweirich)<br />[💻](https://github.com/snipe/snipe-it/commits?author=chrisweirich "Code") | [<img src="https://avatars.githubusercontent.com/u/1294403?v=4" width="110px;"/><br /><sub>denzfarid</sub>](https://github.com/denzfarid)<br /> | [<img src="https://avatars.githubusercontent.com/u/94018771?v=4" width="110px;"/><br /><sub>ntbutler-nbcs</sub>](https://github.com/ntbutler-nbcs)<br />[💻](https://github.com/snipe/snipe-it/commits?author=ntbutler-nbcs "Code") | [<img src="https://avatars.githubusercontent.com/u/172697?v=4" width="110px;"/><br /><sub>Naveen</sub>](https://naveensrinivasan.dev)<br />[💻](https://github.com/snipe/snipe-it/commits?author=naveensrinivasan "Code") | [<img src="https://avatars.githubusercontent.com/u/55674383?v=4" width="110px;"/><br /><sub>Mike Roquemore</sub>](https://github.com/mikeroq)<br />[💻](https://github.com/snipe/snipe-it/commits?author=mikeroq "Code") | [<img src="https://avatars.githubusercontent.com/u/7991086?v=4" width="110px;"/><br /><sub>Daniel Reeder</sub>](https://github.com/reederda)<br />[🌍](#translation-reederda "Translation") [🌍](#translation-reederda "Translation") [💻](https://github.com/snipe/snipe-it/commits?author=reederda "Code") | [<img src="https://avatars.githubusercontent.com/u/109422491?v=4" width="110px;"/><br /><sub>vickyjaura183</sub>](https://github.com/vickyjaura183)<br />[💻](https://github.com/snipe/snipe-it/commits?author=vickyjaura183 "Code") |
| [<img src="https://avatars.githubusercontent.com/u/32363424?v=4" width="110px;"/><br /><sub>Peace</sub>](https://github.com/julian-piehl)<br />[💻](https://github.com/snipe/snipe-it/commits?author=julian-piehl "Code") | [<img src="https://avatars.githubusercontent.com/u/231528?v=4" width="110px;"/><br /><sub>Kyle Gordon</sub>](https://github.com/kylegordon)<br />[💻](https://github.com/snipe/snipe-it/commits?author=kylegordon "Code") | [<img src="https://avatars.githubusercontent.com/u/53009155?v=4" width="110px;"/><br /><sub>Katharina Drexel</sub>](http://www.bfh.ch)<br />[💻](https://github.com/snipe/snipe-it/commits?author=sunflowerbofh "Code") | [<img src="https://avatars.githubusercontent.com/u/1931963?v=4" width="110px;"/><br /><sub>David Sferruzza</sub>](https://david.sferruzza.fr/)<br />[💻](https://github.com/snipe/snipe-it/commits?author=dsferruzza "Code") | [<img src="https://avatars.githubusercontent.com/u/19511639?v=4" width="110px;"/><br /><sub>Rick Nelson</sub>](https://github.com/rnelsonee)<br />[💻](https://github.com/snipe/snipe-it/commits?author=rnelsonee "Code") | [<img src="https://avatars.githubusercontent.com/u/94169344?v=4" width="110px;"/><br /><sub>BasO12</sub>](https://github.com/BasO12)<br />[💻](https://github.com/snipe/snipe-it/commits?author=BasO12 "Code") | [<img src="https://avatars.githubusercontent.com/u/111710123?v=4" width="110px;"/><br /><sub>Vautia</sub>](https://github.com/Vautia)<br />[💻](https://github.com/snipe/snipe-it/commits?author=Vautia "Code") |
| [<img src="https://avatars.githubusercontent.com/u/28321?v=4" width="110px;"/><br /><sub>Chris Hartjes</sub>](http://www.littlehart.net/atthekeyboard)<br />[💻](https://github.com/snipe/snipe-it/commits?author=chartjes "Code") | [<img src="https://avatars.githubusercontent.com/u/2404584?v=4" width="110px;"/><br /><sub>geo-chen</sub>](https://github.com/geo-chen)<br />[💻](https://github.com/snipe/snipe-it/commits?author=geo-chen "Code") | [<img src="https://avatars.githubusercontent.com/u/6006620?v=4" width="110px;"/><br /><sub>Phan Nguyen</sub>](https://github.com/nh314)<br />[💻](https://github.com/snipe/snipe-it/commits?author=nh314 "Code") | [<img src="https://avatars.githubusercontent.com/u/115993812?v=4" width="110px;"/><br /><sub>Iisakki Jaakkola</sub>](https://github.com/StarlessNights)<br />[💻](https://github.com/snipe/snipe-it/commits?author=StarlessNights "Code") | [<img src="https://avatars.githubusercontent.com/u/22633385?v=4" width="110px;"/><br /><sub>Ikko Ashimine</sub>](https://bandism.net/)<br />[💻](https://github.com/snipe/snipe-it/commits?author=eltociear "Code") |
| [<img src="https://avatars.githubusercontent.com/u/28321?v=4" width="110px;"/><br /><sub>Chris Hartjes</sub>](http://www.littlehart.net/atthekeyboard)<br />[💻](https://github.com/snipe/snipe-it/commits?author=chartjes "Code") | [<img src="https://avatars.githubusercontent.com/u/2404584?v=4" width="110px;"/><br /><sub>geo-chen</sub>](https://github.com/geo-chen)<br />[💻](https://github.com/snipe/snipe-it/commits?author=geo-chen "Code") | [<img src="https://avatars.githubusercontent.com/u/6006620?v=4" width="110px;"/><br /><sub>Phan Nguyen</sub>](https://github.com/nh314)<br />[💻](https://github.com/snipe/snipe-it/commits?author=nh314 "Code") | [<img src="https://avatars.githubusercontent.com/u/115993812?v=4" width="110px;"/><br /><sub>Iisakki Jaakkola</sub>](https://github.com/StarlessNights)<br />[💻](https://github.com/snipe/snipe-it/commits?author=StarlessNights "Code") | [<img src="https://avatars.githubusercontent.com/u/22633385?v=4" width="110px;"/><br /><sub>Ikko Ashimine</sub>](https://bandism.net/)<br />[💻](https://github.com/snipe/snipe-it/commits?author=eltociear "Code") | [<img src="https://avatars.githubusercontent.com/u/56871540?v=4" width="110px;"/><br /><sub>Lukas Fehling</sub>](https://github.com/lukasfehling)<br />[💻](https://github.com/snipe/snipe-it/commits?author=lukasfehling "Code") | [<img src="https://avatars.githubusercontent.com/u/1975990?v=4" width="110px;"/><br /><sub>Fernando Almeida</sub>](https://github.com/fernando-almeida)<br />[💻](https://github.com/snipe/snipe-it/commits?author=fernando-almeida "Code") |
| [<img src="https://avatars.githubusercontent.com/u/116301219?v=4" width="110px;"/><br /><sub>akemidx</sub>](https://github.com/akemidx)<br />[💻](https://github.com/snipe/snipe-it/commits?author=akemidx "Code") | [<img src="https://avatars.githubusercontent.com/u/144778?v=4" width="110px;"/><br /><sub>Oguz Bilgic</sub>](http://oguz.site)<br />[💻](https://github.com/snipe/snipe-it/commits?author=oguzbilgic "Code") | [<img src="https://avatars.githubusercontent.com/u/9262438?v=4" width="110px;"/><br /><sub>Scooter Crawford</sub>](https://github.com/scoo73r)<br />[💻](https://github.com/snipe/snipe-it/commits?author=scoo73r "Code") | [<img src="https://avatars.githubusercontent.com/u/5957345?v=4" width="110px;"/><br /><sub>subdriven</sub>](https://github.com/subdriven)<br />[💻](https://github.com/snipe/snipe-it/commits?author=subdriven "Code") |
<!-- ALL-CONTRIBUTORS-LIST:END -->
This project follows the [all-contributors](https://github.com/kentcdodds/all-contributors) specification. Contributions of any kind welcome!
+17 -7
View File
@@ -43,23 +43,33 @@ you want to run.
## Browser Tests
The browser tests use [Dusk](https://laravel.com/docs/8.x/dusk) to run them.
When troubleshooting any problems, make sure that your `.env` file is configured
correctly to run the existing application.
Browser tests are run via [Laravel Dusk](https://laravel.com/docs/8.x/dusk) and require Google Chrome to be installed.
Before attempting to run Dusk tests copy the example environment file for Dusk and update the values to match your environment:
`cp .env.dusk.example .env.dusk.local`
> `local` refers to the value of `APP_ENV` in your `.env` so if you have it set to `dev` then the file should be named `.env.dusk.dev`.
**Important**: Dusk tests cannot be run using an in-memory SQLite database. Additionally, the Dusk test suite uses the `DatabaseMigrations` trait which will leave the database in a fresh state after running. Therefore, it is recommended that you create a test database and point `DB_DATABASE` in `.env.dusk.local` to it.
### Test Setup
Your application needs to be configued and up and running in order for the browser
Your application needs to be configured and up and running in order for the browser
tests to actually run. When running the tests locally, you can start the application
using the following command:
`php artisan serve`
To run the test suite use the following command from another terminal tab or window:
Now you are ready to run the test suite. Use the following command from another terminal tab or window:
`php artisan dusk`
To run individual test files, you can pass the path to the test that you want to run.
To run individual test files, you can pass the path to the test that you want to run:
`php artisan dusk tests/Browser/LoginTest.php`
If you get an error when attempting to run Dusk tests that says `Couldn't connect to server` run:
`php artisan dusk:chrome-driver --detect`
This command will install the specific ChromeDriver Dusk needs for your operating system and Chrome version.
+2 -2
View File
@@ -148,7 +148,7 @@
"image": "heroku/php",
"addons": [
"cleardb:ignite",
"heroku-redis:hobby-dev",
"heroku-redis:mini",
"papertrail:choklad"
]
}
}
@@ -22,7 +22,7 @@ class CheckoutLicenseToAllUsers extends Command
*
* @var string
*/
protected $description = 'Command description';
protected $description = 'Checks out licenses to all users';
/**
* Create a new command instance.
+34 -10
View File
@@ -3,6 +3,7 @@
namespace App\Console\Commands;
use App\Models\Department;
use App\Models\Group;
use Illuminate\Console\Command;
use App\Models\Setting;
use App\Models\Ldap;
@@ -43,12 +44,18 @@ class LdapSync extends Command
*/
public function handle()
{
// 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') {
$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('memory_limit', env('LDAP_MEM_LIM', '500M'));
$ldap_result_username = Setting::getSettings()->ldap_username_field;
$ldap_result_last_name = Setting::getSettings()->ldap_lname_field;
$ldap_result_first_name = Setting::getSettings()->ldap_fname_field;
$ldap_result_active_flag = Setting::getSettings()->ldap_active_flag;
$ldap_result_emp_num = Setting::getSettings()->ldap_emp_num;
$ldap_result_email = Setting::getSettings()->ldap_email;
@@ -57,6 +64,7 @@ class LdapSync extends Command
$ldap_result_country = Setting::getSettings()->ldap_country;
$ldap_result_dept = Setting::getSettings()->ldap_dept;
$ldap_result_manager = Setting::getSettings()->ldap_manager;
$ldap_default_group = Setting::getSettings()->ldap_default_group;
try {
$ldapconn = Ldap::connectToLdap();
@@ -177,6 +185,16 @@ class LdapSync extends Command
$manager_cache = [];
if($ldap_default_group != null) {
$default = Group::find($ldap_default_group);
if (!$default) {
$ldap_default_group = null; // un-set the default group if that group doesn't exist
}
}
for ($i = 0; $i < $results['count']; $i++) {
$item = [];
$item['username'] = isset($results[$i][$ldap_result_username][0]) ? $results[$i][$ldap_result_username][0] : '';
@@ -192,6 +210,7 @@ class LdapSync extends Command
$item['department'] = isset($results[$i][$ldap_result_dept][0]) ? $results[$i][$ldap_result_dept][0] : '';
$item['manager'] = isset($results[$i][$ldap_result_manager][0]) ? $results[$i][$ldap_result_manager][0] : '';
$department = Department::firstOrCreate([
'name' => $item['department'],
]);
@@ -290,17 +309,18 @@ class LdapSync extends Command
$user->activated = 0;
} */
$enabled_accounts = [
'512', // 0x200 NORMAL_ACCOUNT
'544', // 0x220 NORMAL_ACCOUNT, PASSWD_NOTREQD
'66048', // 0x10200 NORMAL_ACCOUNT, DONT_EXPIRE_PASSWORD
'66080', // 0x10220 NORMAL_ACCOUNT, PASSWD_NOTREQD, DONT_EXPIRE_PASSWORD
'262656', // 0x40200 NORMAL_ACCOUNT, SMARTCARD_REQUIRED
'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
'512', // 0x200 NORMAL_ACCOUNT
'544', // 0x220 NORMAL_ACCOUNT, PASSWD_NOTREQD
'66048', // 0x10200 NORMAL_ACCOUNT, DONT_EXPIRE_PASSWORD
'66080', // 0x10220 NORMAL_ACCOUNT, PASSWD_NOTREQD, DONT_EXPIRE_PASSWORD
'262656', // 0x40200 NORMAL_ACCOUNT, SMARTCARD_REQUIRED
'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
'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,
];
$user->activated = (in_array($results[$i]['useraccountcontrol'][0], $enabled_accounts)) ? 1 : 0;
@@ -326,6 +346,10 @@ class LdapSync extends Command
if ($user->save()) {
$item['note'] = $item['createorupdate'];
$item['status'] = 'success';
if ( $item['createorupdate'] === 'created' && $ldap_default_group) {
$user->groups()->attach($ldap_default_group);
}
} else {
foreach ($user->getErrors()->getMessages() as $key => $err) {
$errors .= $err[0];
+2 -2
View File
@@ -149,7 +149,7 @@ class RestoreFromBackup extends Command
$boring_files[] = $raw_path;
continue;
}
if (@pathinfo($raw_path)['extension'] == 'sql') {
if (@pathinfo($raw_path, PATHINFO_EXTENSION) == 'sql') {
\Log::debug("Found a sql file!");
$sqlfiles[] = $raw_path;
$sqlfile_indices[] = $i;
@@ -214,7 +214,7 @@ class RestoreFromBackup extends Command
$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').'/mysql';
$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");
}
+26 -20
View File
@@ -39,33 +39,39 @@ class SyncAssetCounters extends Command
public function handle()
{
$start = microtime(true);
// We need the whole count of all assets in order to set up the progress bar
$assets_count = Asset::withTrashed()->count();
$bar = $this->output->createProgressBar($assets_count);
$assets = Asset::withCount('checkins as checkins_count', 'checkouts as checkouts_count', 'userRequests as user_requests_count')
->withTrashed()->get();
->withTrashed()->chunk(100, function ($assets) use ($bar) {
if ($assets) {
if ($assets->count() > 0) {
$bar = $this->output->createProgressBar($assets->count());
if ($assets->count() > 0) {
foreach ($assets as $asset) {
$asset->checkin_counter = (int) $asset->checkins_count;
$asset->checkout_counter = (int) $asset->checkouts_count;
$asset->requests_counter = (int) $asset->user_requests_count;
$asset->unsetEventDispatcher();
$asset->save();
$output['info'][] = 'Asset: '.$asset->id.' has '.$asset->checkin_counter.' checkins, '.$asset->checkout_counter.' checkouts, and '.$asset->requests_counter.' requests';
$bar->advance();
}
$bar->finish();
foreach ($assets as $asset) {
foreach ($output['info'] as $key => $output_text) {
$this->info($output_text);
}
$asset->checkin_counter = (int) $asset->checkins_count;
$asset->checkout_counter = (int) $asset->checkouts_count;
$asset->requests_counter = (int) $asset->user_requests_count;
$asset->unsetEventDispatcher();
$asset->save();
$bar->advance();
\Log::debug('Asset: '.$asset->id.' has '.$asset->checkin_counter.' checkins, '.$asset->checkout_counter.' checkouts, and '.$asset->requests_counter.' requests');
}
$time_elapsed_secs = microtime(true) - $start;
$this->info('Sync executed in '.$time_elapsed_secs.' seconds');
} 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');
}
}
+21
View File
@@ -12,6 +12,7 @@ use App\Models\Statuslabel;
use Crypt;
use Illuminate\Contracts\Encryption\DecryptException;
use Image;
use Carbon\Carbon;
class Helper
{
@@ -1125,5 +1126,25 @@ class Helper
return $settings;
}
public static function AgeFormat($date) {
$year = Carbon::parse($date)
->diff(now())->y;
$month = Carbon::parse($date)
->diff(now())->m;
$days = Carbon::parse($date)
->diff(now())->d;
$age='';
if ($year) {
$age .= $year.'y ';
}
if ($month) {
$age .= $month.'m ';
}
if ($days) {
$age .= $days.'d';
}
return $age;
}
}
@@ -63,6 +63,7 @@ class AccessoriesController extends Controller
public function store(ImageUploadRequest $request)
{
$this->authorize(Accessory::class);
// create a new model instance
$accessory = new Accessory();
@@ -82,7 +83,6 @@ class AccessoriesController extends Controller
$accessory->supplier_id = request('supplier_id');
$accessory->notes = request('notes');
$accessory = $request->handleImages($accessory);
// Was the accessory created?
@@ -127,45 +127,47 @@ class AccessoriesController extends Controller
*/
public function update(ImageUploadRequest $request, $accessoryId = null)
{
if (is_null($accessory = Accessory::find($accessoryId))) {
if ($accessory = Accessory::withCount('users as users_count')->find($accessoryId)) {
$this->authorize($accessory);
$validator = Validator::make($request->all(), [
"qty" => "required|numeric|min:$accessory->users_count"
]);
if ($validator->fails()) {
return redirect()->back()
->withErrors($validator)
->withInput();
}
// Update the accessory data
$accessory->name = request('name');
$accessory->location_id = request('location_id');
$accessory->min_amt = request('min_amt');
$accessory->category_id = request('category_id');
$accessory->company_id = Company::getIdForCurrentUser(request('company_id'));
$accessory->manufacturer_id = request('manufacturer_id');
$accessory->order_number = request('order_number');
$accessory->model_number = request('model_number');
$accessory->purchase_date = request('purchase_date');
$accessory->purchase_cost = Helper::ParseCurrency(request('purchase_cost'));
$accessory->qty = request('qty');
$accessory->supplier_id = request('supplier_id');
$accessory->notes = request('notes');
$accessory = $request->handleImages($accessory);
// Was the accessory updated?
if ($accessory->save()) {
return redirect()->route('accessories.index')->with('success', trans('admin/accessories/message.update.success'));
}
} else {
return redirect()->route('accessories.index')->with('error', trans('admin/accessories/message.does_not_exist'));
}
$min = $accessory->numCheckedOut();
$validator = Validator::make($request->all(), [
"qty" => "required|numeric|min:$min"
]);
if ($validator->fails()) {
return redirect()->back()
->withErrors($validator)
->withInput();
}
$this->authorize($accessory);
// Update the accessory data
$accessory->name = request('name');
$accessory->location_id = request('location_id');
$accessory->min_amt = request('min_amt');
$accessory->category_id = request('category_id');
$accessory->company_id = Company::getIdForCurrentUser(request('company_id'));
$accessory->manufacturer_id = request('manufacturer_id');
$accessory->order_number = request('order_number');
$accessory->model_number = request('model_number');
$accessory->purchase_date = request('purchase_date');
$accessory->purchase_cost = Helper::ParseCurrency(request('purchase_cost'));
$accessory->qty = request('qty');
$accessory->supplier_id = request('supplier_id');
$accessory->notes = request('notes');
$accessory = $request->handleImages($accessory);
// Was the accessory updated?
if ($accessory->save()) {
return redirect()->route('accessories.index')->with('success', trans('admin/accessories/message.update.success'));
}
return redirect()->back()->withInput()->withErrors($accessory->getErrors());
}
@@ -217,7 +219,7 @@ class AccessoriesController extends Controller
*/
public function show($accessoryID = null)
{
$accessory = Accessory::find($accessoryID);
$accessory = Accessory::withCount('users as users_count')->find($accessoryID);
$this->authorize('view', $accessory);
if (isset($accessory->id)) {
return view('accessories/view', compact('accessory'));
@@ -222,8 +222,8 @@ class AcceptanceController extends Controller
'item_model' => $display_model,
'item_serial' => $item->serial,
'eula' => $item->getEula(),
'check_out_date' => Carbon::parse($acceptance->created_at)->format($branding_settings->date_display_format),
'accepted_date' => Carbon::parse($acceptance->accepted_at)->format($branding_settings->date_display_format),
'check_out_date' => Carbon::parse($acceptance->created_at)->format('Y-m-d'),
'accepted_date' => Carbon::parse($acceptance->accepted_at)->format('Y-m-d'),
'assigned_to' => $assigned_to,
'company_name' => $branding_settings->site_name,
'signature' => ($sig_filename) ? storage_path() . '/private_uploads/signatures/' . $sig_filename : null,
@@ -273,7 +273,7 @@ class AcceptanceController extends Controller
'item_tag' => $item->asset_tag,
'item_model' => $display_model,
'item_serial' => $item->serial,
'declined_date' => Carbon::parse($acceptance->accepted_at)->format($branding_settings->date_display_format),
'declined_date' => Carbon::parse($acceptance->declined_at)->format('Y-m-d'),
'assigned_to' => $assigned_to,
'company_name' => $branding_settings->site_name,
'date_settings' => $branding_settings->date_display_format,
@@ -41,10 +41,13 @@ class AccessoriesController extends Controller
'min_amt',
'company_id',
'notes',
'users_count',
'qty',
];
$accessories = Accessory::select('accessories.*')->with('category', 'company', 'manufacturer', 'users', 'location', 'supplier');
$accessories = Accessory::select('accessories.*')->with('category', 'company', 'manufacturer', 'users', 'location', 'supplier')
->withCount('users as users_count');
if ($request->filled('search')) {
$accessories = $accessories->TextSearch($request->input('search'));
+57 -24
View File
@@ -100,6 +100,7 @@ class AssetsController extends Controller
'checkout_counter',
'checkin_counter',
'requests_counter',
'byod',
];
$filter = [];
@@ -120,7 +121,6 @@ class AssetsController extends Controller
if ($filter_non_deprecable_assets) {
$non_deprecable_models = AssetModel::select('id')->whereNotNull('depreciation_id')->get();
$assets->InModelList($non_deprecable_models->toArray());
}
@@ -141,6 +141,14 @@ class AssetsController extends Controller
$assets->where('assets.status_id', '=', $request->input('status_id'));
}
if ($request->filled('asset_tag')) {
$assets->where('assets.asset_tag', '=', $request->input('asset_tag'));
}
if ($request->filled('serial')) {
$assets->where('assets.serial', '=', $request->input('serial'));
}
if ($request->input('requestable') == 'true') {
$assets->where('assets.requestable', '=', '1');
}
@@ -182,6 +190,10 @@ class AssetsController extends Controller
$assets->ByDepreciationId($request->input('depreciation_id'));
}
if ($request->filled('byod')) {
$assets->where('assets.byod', '=', $request->input('byod'));
}
$request->filled('order_number') ? $assets = $assets->where('assets.order_number', '=', e($request->get('order_number'))) : '';
// Set the offset to the API call's offset, unless the offset is higher than the actual count of items in which
@@ -259,6 +271,11 @@ class AssetsController extends Controller
// more sad, horrible workarounds for laravel bugs when doing full text searches
$assets->where('assets.assigned_to', '>', '0');
break;
case 'byod':
// This is kind of redundant, since we already check for byod=1 above, but this keeps the
// sidebar nav links a little less chaotic
$assets->where('assets.byod', '=', '1');
break;
default:
if ((! $request->filled('status_id')) && ($settings->show_archived_in_list != '1')) {
@@ -357,19 +374,38 @@ class AssetsController extends Controller
/**
* Returns JSON with information about an asset (by tag) for detail view.
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @param string $tag
* @since [v4.2.1]
* @return JsonResponse
* @author [A. Gianotto] [<snipe@snipe.net>]
* @return \Illuminate\Http\JsonResponse
*/
public function showByTag(Request $request, $tag)
{
if ($asset = Asset::with('assetstatus')->with('assignedTo')->where('asset_tag', $tag)->first()) {
$this->authorize('view', $asset);
$this->authorize('index', Asset::class);
$assets = Asset::where('asset_tag', $tag)->with('assetstatus')->with('assignedTo');
return (new AssetsTransformer)->transformAsset($asset, $request);
// Check if they've passed ?deleted=true
if ($request->input('deleted', 'false') == 'true') {
$assets = $assets->withTrashed();
}
return response()->json(Helper::formatStandardApiResponse('error', null, 'Asset not found'), 200);
if (($assets = $assets->get()) && ($assets->count()) > 0) {
// If there is exactly one result and the deleted parameter is not passed, we should pull the first (and only)
// asset from the returned collection, since transformAsset() expects an Asset object, NOT a collection
if (($assets->count() == 1) && ($request->input('deleted') != 'true')) {
return (new AssetsTransformer)->transformAsset($assets->first());
// If there is more than one result OR if the endpoint is requesting deleted items (even if there is only one
// match, return the normal collection transformed.
} else {
return (new AssetsTransformer)->transformAssets($assets, $assets->count());
}
}
// If there are 0 results, return the "no such asset" response
return response()->json(Helper::formatStandardApiResponse('error', null, trans('admin/hardware/message.does_not_exist')), 200);
}
@@ -379,29 +415,25 @@ class AssetsController extends Controller
* @author [A. Gianotto] [<snipe@snipe.net>]
* @param string $serial
* @since [v4.2.1]
* @return JsonResponse
* @return \Illuminate\Http\JsonResponse
*/
public function showBySerial(Request $request, $serial)
{
$this->authorize('index', Asset::class);
if ($assets = Asset::with('assetstatus')->with('assignedTo')
->withTrashed()->where('serial', $serial)->get()) {
return (new AssetsTransformer)->transformAssets($assets, $assets->count());
}
return response()->json(Helper::formatStandardApiResponse('error', null, 'Asset not found'), 200);
$assets = Asset::where('serial', $serial)->with('assetstatus')->with('assignedTo');
$assets = Asset::with('assetstatus')->with('assignedTo');
if ($request->input('deleted', 'false') === 'true') {
// Check if they've passed ?deleted=true
if ($request->input('deleted', 'false') == 'true') {
$assets = $assets->withTrashed();
}
$assets = $assets->where('serial', $serial)->get();
if ($assets) {
return (new AssetsTransformer)->transformAssets($assets, $assets->count());
} else {
return response()->json(Helper::formatStandardApiResponse('error', null, 'Asset not found'), 200);
}
if (($assets = $assets->get()) && ($assets->count()) > 0) {
return (new AssetsTransformer)->transformAssets($assets, $assets->count());
}
// If there are 0 results, return the "no such asset" response
return response()->json(Helper::formatStandardApiResponse('error', null, trans('admin/hardware/message.does_not_exist')), 200);
}
/**
@@ -825,7 +857,8 @@ class AssetsController extends Controller
$checkout_at = request('checkout_at', date('Y-m-d H:i:s'));
$expected_checkin = request('expected_checkin', null);
$note = request('note', null);
$asset_name = request('name', null);
// Using `->has` preserves the asset name if the name parameter was not included in request.
$asset_name = request()->has('name') ? request('name') : $asset->name;
// Set the location ID to the RTD location id if there is one
// Wait, why are we doing this? This overrides the stuff we set further up, which makes no sense.
@@ -10,6 +10,7 @@ use App\Models\Category;
use Illuminate\Http\Request;
use App\Http\Requests\ImageUploadRequest;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Facades\Validator;
class CategoriesController extends Controller
{
@@ -107,7 +108,7 @@ class CategoriesController extends Controller
public function show($id)
{
$this->authorize('view', Category::class);
$category = Category::findOrFail($id);
$category = Category::withCount('assets as assets_count', 'accessories as accessories_count', 'consumables as consumables_count', 'components as components_count', 'licenses as licenses_count')->findOrFail($id);
return (new CategoriesTransformer)->transformCategory($category);
}
@@ -126,8 +127,14 @@ class CategoriesController extends Controller
{
$this->authorize('update', Category::class);
$category = Category::findOrFail($id);
// Don't allow the user to change the category_type once it's been created
if (($request->filled('category_type')) && ($category->category_type != $request->input('category_type'))) {
return response()->json(
Helper::formatStandardApiResponse('error', null, trans('admin/categories/message.update.cannot_change_category_type'))
);
}
$category->fill($request->all());
$category->category_type = strtolower($request->input('category_type'));
$category = $request->handleImages($category);
if ($category->save()) {
@@ -148,7 +155,7 @@ class CategoriesController extends Controller
public function destroy($id)
{
$this->authorize('delete', Category::class);
$category = Category::findOrFail($id);
$category = Category::withCount('assets as assets_count', 'accessories as accessories_count', 'consumables as consumables_count', 'components as components_count', 'licenses as licenses_count')->findOrFail($id);
if (! $category->isDeletable()) {
return response()->json(
@@ -4,6 +4,7 @@ namespace App\Http\Controllers\Api;
use App\Helpers\Helper;
use App\Http\Controllers\Controller;
use App\Http\Transformers\ComponentsTransformer;
use App\Http\Transformers\ConsumablesTransformer;
use App\Http\Transformers\SelectlistTransformer;
use App\Models\Company;
@@ -209,37 +210,23 @@ class ConsumablesController extends Controller
* @param int $consumableId
* @return array
*/
public function getDataView($consumableId)
public function checkedout($consumableId)
{
$consumable = Consumable::with(['consumableAssignments'=> function ($query) {
$query->orderBy($query->getModel()->getTable().'.created_at', 'DESC');
},
'consumableAssignments.admin'=> function ($query) {
},
'consumableAssignments.user'=> function ($query) {
},
])->find($consumableId);
$consumable = Consumable::with('users')->findOrFail($consumableId);
if (! Company::isCurrentUserHasAccess($consumable)) {
return ['total' => 0, 'rows' => []];
}
$this->authorize('view', Consumable::class);
$rows = [];
foreach ($consumable->consumableAssignments as $consumable_assignment) {
$rows[] = [
'avatar' => ($consumable_assignment->user) ? e($consumable_assignment->user->present()->gravatar) : '',
'name' => ($consumable_assignment->user) ? $consumable_assignment->user->present()->nameUrl() : 'Deleted User',
'created_at' => Helper::getFormattedDateObject($consumable_assignment->created_at, 'datetime'),
'note' => ($consumable_assignment->note) ? e($consumable_assignment->note) : null,
'admin' => ($consumable_assignment->admin) ? $consumable_assignment->admin->present()->nameUrl() : null,
];
$offset = request('offset', 0);
$limit = request('limit', 50);
$consumables_users = $consumable->users;
$total = $consumables_users->count();
if ($total < $offset) {
$offset = 0;
}
$consumableCount = $consumable->users->count();
$data = ['total' => $consumableCount, 'rows' => $rows];
return $data;
return (new ConsumablesTransformer)->transformCheckedoutConsumables($consumable, $consumables_users, $total);
}
/**
@@ -96,7 +96,7 @@ class CustomFieldsController extends Controller
$data = $request->all();
$regex_format = null;
if (str_contains($data['format'], 'regex:')) {
if ((array_key_exists('format', $data)) && (str_contains($data['format'], 'regex:'))) {
$regex_format = $data['format'];
}
@@ -33,7 +33,7 @@ class CustomFieldsetsController extends Controller
*/
public function index()
{
$this->authorize('index', CustomFieldset::class);
$this->authorize('index', CustomField::class);
$fieldsets = CustomFieldset::withCount('fields as fields_count', 'models as models_count')->get();
return (new CustomFieldsetsTransformer)->transformCustomFieldsets($fieldsets, $fieldsets->count());
@@ -49,7 +49,7 @@ class CustomFieldsetsController extends Controller
*/
public function show($id)
{
$this->authorize('view', CustomFieldset::class);
$this->authorize('view', CustomField::class);
if ($fieldset = CustomFieldset::find($id)) {
return (new CustomFieldsetsTransformer)->transformCustomFieldset($fieldset);
}
@@ -68,7 +68,7 @@ class CustomFieldsetsController extends Controller
*/
public function update(Request $request, $id)
{
$this->authorize('update', CustomFieldset::class);
$this->authorize('update', CustomField::class);
$fieldset = CustomFieldset::findOrFail($id);
$fieldset->fill($request->all());
@@ -89,7 +89,7 @@ class CustomFieldsetsController extends Controller
*/
public function store(Request $request)
{
$this->authorize('create', CustomFieldset::class);
$this->authorize('create', CustomField::class);
$fieldset = new CustomFieldset;
$fieldset->fill($request->all());
@@ -109,7 +109,7 @@ class CustomFieldsetsController extends Controller
*/
public function destroy($id)
{
$this->authorize('delete', CustomFieldset::class);
$this->authorize('delete', CustomField::class);
$fieldset = CustomFieldset::findOrFail($id);
$modelsCount = $fieldset->models->count();
@@ -136,7 +136,7 @@ class CustomFieldsetsController extends Controller
*/
public function fields($id)
{
$this->authorize('view', CustomFieldset::class);
$this->authorize('view', CustomField::class);
$set = CustomFieldset::findOrFail($id);
$fields = $set->fields;
@@ -153,7 +153,7 @@ class CustomFieldsetsController extends Controller
*/
public function fieldsWithDefaultValues($fieldsetId, $modelId)
{
$this->authorize('view', CustomFieldset::class);
$this->authorize('view', CustomField::class);
$set = CustomFieldset::findOrFail($fieldsetId);
+34 -10
View File
@@ -10,6 +10,7 @@ use App\Models\Asset;
use App\Models\Company;
use App\Models\Import;
use Artisan;
use Illuminate\Database\Eloquent\JsonEncodingException;
use Illuminate\Support\Facades\Request;
use Illuminate\Support\Facades\Session;
use Illuminate\Support\Facades\Storage;
@@ -35,7 +36,7 @@ class ImportController extends Controller
* Process and store a CSV upload file.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
* @return \Illuminate\Http\JsonResponse
*/
public function store()
{
@@ -56,7 +57,7 @@ class ImportController extends Controller
'text/tsv', ])) {
$results['error'] = 'File type must be CSV. Uploaded file is '.$file->getMimeType();
return response()->json(Helper::formatStandardApiResponse('error', null, $results['error']), 500);
return response()->json(Helper::formatStandardApiResponse('error', null, $results['error']), 422);
}
//TODO: is there a lighter way to do this?
@@ -64,7 +65,19 @@ class ImportController extends Controller
ini_set('auto_detect_line_endings', '1');
}
$reader = Reader::createFromFileObject($file->openFile('r')); //file pointer leak?
$import->header_row = $reader->fetchOne(0);
try {
$import->header_row = $reader->fetchOne(0);
} catch (JsonEncodingException $e) {
return response()->json(
Helper::formatStandardApiResponse(
'error',
null,
trans('admin/hardware/message.import.header_row_has_malformed_characters')
),
422
);
}
//duplicate headers check
$duplicate_headers = [];
@@ -82,11 +95,22 @@ class ImportController extends Controller
}
}
if (count($duplicate_headers) > 0) {
return response()->json(Helper::formatStandardApiResponse('error', null, implode('; ', $duplicate_headers)), 500); //should this be '4xx'?
return response()->json(Helper::formatStandardApiResponse('error', null, implode('; ', $duplicate_headers)),422);
}
// Grab the first row to display via ajax as the user picks fields
$import->first_row = $reader->fetchOne(1);
try {
// Grab the first row to display via ajax as the user picks fields
$import->first_row = $reader->fetchOne(1);
} catch (JsonEncodingException $e) {
return response()->json(
Helper::formatStandardApiResponse(
'error',
null,
trans('admin/hardware/message.import.content_row_has_malformed_characters')
),
422
);
}
$date = date('Y-m-d-his');
$fixed_filename = str_slug($file->getClientOriginalName());
@@ -108,12 +132,12 @@ class ImportController extends Controller
}
$results = (new ImportsTransformer)->transformImports($results);
return [
return response()->json([
'files' => $results,
];
]);
}
return response()->json(Helper::formatStandardApiResponse('error', null, trans('general.feature_disabled')), 500);
return response()->json(Helper::formatStandardApiResponse('error', null, trans('general.feature_disabled')), 422);
}
/**
@@ -127,7 +151,7 @@ class ImportController extends Controller
$this->authorize('import');
// Run a backup immediately before processing
if ($request->has('run-backup')) {
if ($request->get('run-backup')) {
\Log::debug('Backup manually requested via importer');
Artisan::call('backup:run');
} else {
+63 -6
View File
@@ -15,6 +15,7 @@ use App\Models\Asset;
use App\Models\Company;
use App\Models\License;
use App\Models\User;
use App\Notifications\CurrentInventory;
use Auth;
use Illuminate\Http\Request;
use App\Http\Requests\ImageUploadRequest;
@@ -148,6 +149,14 @@ class UsersController extends Controller
$users = $users->where('remote', '=', $request->input('remote'));
}
if ($request->filled('two_factor_enrolled')) {
$users = $users->where('two_factor_enrolled', '=', $request->input('two_factor_enrolled'));
}
if ($request->filled('two_factor_optin')) {
$users = $users->where('two_factor_optin', '=', $request->input('two_factor_optin'));
}
if ($request->filled('start_date')) {
$users = $users->where('users.start_date', '=', $request->input('start_date'));
}
@@ -156,7 +165,6 @@ class UsersController extends Controller
$users = $users->where('users.end_date', '=', $request->input('end_date'));
}
if ($request->filled('assets_count')) {
$users->has('assets', '=', $request->input('assets_count'));
}
@@ -207,11 +215,39 @@ class UsersController extends Controller
default:
$allowed_columns =
[
'last_name', 'first_name', 'email', 'jobtitle', 'username', 'employee_num',
'assets', 'accessories', 'consumables', 'licenses', 'groups', 'activated', 'created_at',
'two_factor_enrolled', 'two_factor_optin', 'last_login', 'assets_count', 'licenses_count',
'consumables_count', 'accessories_count', 'phone', 'address', 'city', 'state',
'country', 'zip', 'id', 'ldap_import', 'remote', 'start_date', 'end_date',
'last_name',
'first_name',
'email',
'jobtitle',
'username',
'employee_num',
'assets',
'accessories',
'consumables',
'licenses',
'groups',
'activated',
'created_at',
'two_factor_enrolled',
'two_factor_optin',
'last_login',
'assets_count',
'licenses_count',
'consumables_count',
'accessories_count',
'phone',
'address',
'city',
'state',
'country',
'zip',
'id',
'ldap_import',
'two_factor_optin',
'two_factor_enrolled',
'remote',
'start_date',
'end_date',
];
$sort = in_array($request->get('sort'), $allowed_columns) ? $request->get('sort') : 'first_name';
@@ -490,6 +526,27 @@ class UsersController extends Controller
return (new AssetsTransformer)->transformAssets($assets, $assets->count(), $request);
}
/**
* Notify a specific user via email with all of their assigned assets.
*
* @author [Lukas Fehling] [<lukas.fehling@adabay.rocks>]
* @since [v6.0.13]
* @param Request $request
* @param $id
* @return string JSON
*/
public function emailAssetList(Request $request, $id)
{
$user = User::findOrFail($id);
if (empty($user->email)) {
return response()->json(Helper::formatStandardApiResponse('error', null, trans('admin/users/message.inventorynotification.error')));
}
$user->notify((new CurrentInventory($user)));
return response()->json(Helper::formatStandardApiResponse('success', null, trans('admin/users/message.inventorynotification.success')));
}
/**
* Return JSON containing a list of consumables assigned to a user.
@@ -146,6 +146,7 @@ class AssetsController extends Controller
$asset->supplier_id = request('supplier_id', null);
$asset->requestable = request('requestable', 0);
$asset->rtd_location_id = request('rtd_location_id', null);
$asset->byod = request('byod', 0);
if (! empty($settings->audit_interval)) {
$asset->next_audit_date = Carbon::now()->addMonths($settings->audit_interval)->toDateString();
@@ -318,6 +319,7 @@ class AssetsController extends Controller
// If the box isn't checked, it's not in the request at all.
$asset->requestable = $request->filled('requestable');
$asset->rtd_location_id = $request->input('rtd_location_id', null);
$asset->byod = $request->input('byod', 0);
if ($asset->assigned_to == '') {
$asset->location_id = $request->input('rtd_location_id', null);
@@ -135,9 +135,7 @@ class LoginController extends Controller
} else {
// Better logging
if (!$saml->isEnabled()) {
\Log::debug("SAML page requested, but SAML does not seem to enabled.");
} else {
if (empty($samlData)) {
\Log::debug("SAML page requested, but samlData seems empty.");
}
}
@@ -41,6 +41,7 @@ class ResetPasswordController extends Controller
public function __construct()
{
$this->middleware('guest');
$this->middleware('throttle:10,1');
}
protected function rules()
@@ -116,7 +117,7 @@ class ResetPasswordController extends Controller
}
\Log::debug('Password reset for '.$user->username.' FAILED - this user exists but the token is not valid');
return redirect()->back()->withInput($request->only('email'))->with('error', trans('passwords.token'));
return redirect()->back()->withInput($request->only('email'))->with('success', trans('passwords.reset'));
}
@@ -86,22 +86,32 @@ class CustomFieldsController extends Controller
{
$this->authorize('create', CustomField::class);
$show_in_email = $request->get("show_in_email", 0);
$display_in_user_view = $request->get("display_in_user_view", 0);
// Override the display settings if the field is encrypted
if ($request->get("field_encrypted") == '1') {
$show_in_email = '0';
$display_in_user_view = '0';
}
$field = new CustomField([
"name" => trim($request->get("name")),
"element" => $request->get("element"),
"help_text" => $request->get("help_text"),
"field_values" => $request->get("field_values"),
"field_encrypted" => $request->get("field_encrypted", 0),
"show_in_email" => $request->get("show_in_email", 0),
"show_in_email" => $show_in_email,
"is_unique" => $request->get("is_unique", 0),
"display_in_user_view" => $display_in_user_view,
"user_id" => Auth::id()
]);
if ($request->filled('custom_format')) {
$field->format = e($request->get('custom_format'));
$field->format = $request->get('custom_format');
} else {
$field->format = e($request->get('format'));
$field->format = $request->get('format');
}
if ($field->save()) {
@@ -221,13 +231,24 @@ class CustomFieldsController extends Controller
$this->authorize('update', $field);
$show_in_email = $request->get("show_in_email", 0);
$display_in_user_view = $request->get("display_in_user_view", 0);
// Override the display settings if the field is encrypted
if ($request->get("field_encrypted") == '1') {
$show_in_email = '0';
$display_in_user_view = '0';
}
$field->name = trim(e($request->get("name")));
$field->element = e($request->get("element"));
$field->field_values = e($request->get("field_values"));
$field->user_id = Auth::id();
$field->help_text = $request->get("help_text");
$field->show_in_email = $request->get("show_in_email", 0);
$field->show_in_email = $show_in_email;
$field->is_unique = $request->get("is_unique", 0);
$field->display_in_user_view = $display_in_user_view;
if ($request->get('format') == 'CUSTOM REGEX') {
$field->format = e($request->get('custom_format'));
@@ -75,9 +75,9 @@ class CustomFieldsetsController extends Controller
*/
public function create()
{
$this->authorize('create', CustomFieldset::class);
$this->authorize('create', CustomField::class);
return view('custom_fields.fieldsets.edit');
return view('custom_fields.fieldsets.edit')->with('item', new CustomFieldset());
}
/**
@@ -91,7 +91,7 @@ class CustomFieldsetsController extends Controller
*/
public function store(Request $request)
{
$this->authorize('create', CustomFieldset::class);
$this->authorize('create', CustomField::class);
$cfset = new CustomFieldset([
'name' => e($request->get('name')),
@@ -110,31 +110,52 @@ class CustomFieldsetsController extends Controller
}
/**
* What the actual fuck, Brady?
* Presents edit form for fieldset
*
* @todo Uhh, build this?
* @author [Brady Wetherington] [<uberbrady@gmail.com>]
* @author [A. Gianotto] [<snipe@snipe.net>]
* @param int $id
* @since [v1.8]
* @return Fuckall
* @since [v6.0.14]
* @return Redirect
* @throws \Illuminate\Auth\Access\AuthorizationException
*/
public function edit($id)
{
//
$this->authorize('create', CustomField::class);
if ($fieldset = CustomFieldset::find($id)) {
return view('custom_fields.fieldsets.edit')->with('item', $fieldset);
}
return redirect()->route('fields.index')->with('error', trans('admin/custom_fields/general.fieldset_does_not_exist', ['id' => $id]));
}
/**
* GET IN THE SEA BRADY.
* Saves updated fieldset data
*
* @todo Uhh, build this too?
* @author [Brady Wetherington] [<uberbrady@gmail.com>]
* @author [A. Gianotto] [<snipe@snipe.net>]
* @param int $id
* @since [v1.8]
* @return Fuckall
* @since [v6.0.14]
* @return Redirect
* @throws \Illuminate\Auth\Access\AuthorizationException
*/
public function update($id)
public function update(Request $request, $id)
{
//
$this->authorize('create', CustomField::class);
if ($fieldset = CustomFieldset::find($id)) {
$fieldset->name = $request->input('name');
if ($fieldset->save()) {
return redirect()->route('fields.index')->with('success', trans('admin/custom_fields/general.fieldset_updated'));
}
return redirect()->back()->withInput()->withErrors($fieldset->getErrors());
}
return redirect()->route('fields.index')->with('error', trans('admin/custom_fields/general.fieldset_does_not_exist', ['id' => $id]));
}
/**
@@ -202,7 +223,7 @@ class CustomFieldsetsController extends Controller
*/
public function makeFieldRequired($fieldset_id, $field_id)
{
$this->authorize('update', CustomFieldset::class);
$this->authorize('update', CustomField::class);
$field = CustomField::findOrFail($field_id);
$fieldset = CustomFieldset::findOrFail($fieldset_id);
$fields[$field->id] = ['required' => 1];
@@ -220,7 +241,7 @@ class CustomFieldsetsController extends Controller
*/
public function makeFieldOptional($fieldset_id, $field_id)
{
$this->authorize('update', CustomFieldset::class);
$this->authorize('update', CustomField::class);
$field = CustomField::findOrFail($field_id);
$fieldset = CustomFieldset::findOrFail($fieldset_id);
$fields[$field->id] = ['required' => 0];
+1 -1
View File
@@ -34,7 +34,7 @@ class DashboardController extends Controller
$counts['license'] = \App\Models\License::assetcount();
$counts['consumable'] = \App\Models\Consumable::count();
$counts['component'] = \App\Models\Component::count();
$counts['user'] = \App\Models\User::count();
$counts['user'] = \App\Models\Company::scopeCompanyables(Auth::user())->count();
$counts['grand_total'] = $counts['asset'] + $counts['accessory'] + $counts['license'] + $counts['consumable'];
if ((! file_exists(storage_path().'/oauth-private.key')) || (! file_exists(storage_path().'/oauth-public.key'))) {
+2 -30
View File
@@ -67,37 +67,9 @@ class ProfileController extends Controller
$user->location_id = $request->input('location_id');
}
// Handle the avatar upload and/or delete if necessary
app('\App\Http\Requests\ImageUploadRequest')->handleImages($user, 600, 'avatar', 'avatars', 'avatar');
if ($request->input('avatar_delete') == 1) {
$user->avatar = null;
}
if ($request->hasFile('avatar')) {
$path = 'avatars';
if (! Storage::disk('public')->exists($path)) {
Storage::disk('public')->makeDirectory($path, 775);
}
$upload = $image = $request->file('avatar');
$ext = $image->getClientOriginalExtension();
$file_name = 'avatar-'.str_random(18).'.'.$ext;
if ($image->getClientOriginalExtension() != 'svg') {
$upload = Image::make($image->getRealPath())->resize(84, 84);
}
// This requires a string instead of an object, so we use ($string)
Storage::disk('public')->put($path.'/'.$file_name, (string) $upload->encode());
// Remove Current image if exists
if (($user->avatar) && (Storage::disk('public')->exists($path.'/'.$user->avatar))) {
Storage::disk('public')->delete($path.'/'.$user->avatar);
}
$user->avatar = $file_name;
}
if ($user->save()) {
return redirect()->route('profile')->with('success', 'Account successfully updated');
+18 -12
View File
@@ -763,7 +763,7 @@ class ReportsController extends Controller
if ($request->filled('username')) {
// Only works if we're checked out to a user, not anything else.
if ($asset->checkedOutToUser()) {
$row[] = ($asset->assignedTo) ? $asset->assignedTo->username : '';
$row[] = ($asset->assignedto) ? $asset->assignedto->username : '';
} else {
$row[] = ''; // Empty string if unassigned
}
@@ -772,7 +772,7 @@ class ReportsController extends Controller
if ($request->filled('employee_num')) {
// Only works if we're checked out to a user, not anything else.
if ($asset->checkedOutToUser()) {
$row[] = ($asset->assignedTo) ? $asset->assignedTo->employee_num : '';
$row[] = ($asset->assignedto) ? $asset->assignedto->employee_num : '';
} else {
$row[] = ''; // Empty string if unassigned
}
@@ -780,7 +780,7 @@ class ReportsController extends Controller
if ($request->filled('manager')) {
if ($asset->checkedOutToUser()) {
$row[] = (($asset->assignedTo) && ($asset->assignedTo->manager)) ? $asset->assignedTo->manager->present()->fullName : '';
$row[] = (($asset->assignedto) && ($asset->assignedto->manager)) ? $asset->assignedto->manager->present()->fullName : '';
} else {
$row[] = ''; // Empty string if unassigned
}
@@ -788,7 +788,7 @@ class ReportsController extends Controller
if ($request->filled('department')) {
if ($asset->checkedOutToUser()) {
$row[] = (($asset->assignedTo) && ($asset->assignedTo->department)) ? $asset->assignedTo->department->name : '';
$row[] = (($asset->assignedto) && ($asset->assignedto->department)) ? $asset->assignedto->department->name : '';
} else {
$row[] = ''; // Empty string if unassigned
}
@@ -796,7 +796,7 @@ class ReportsController extends Controller
if ($request->filled('title')) {
if ($asset->checkedOutToUser()) {
$row[] = ($asset->assignedTo) ? $asset->assignedTo->jobtitle : '';
$row[] = ($asset->assignedto) ? $asset->assignedto->jobtitle : '';
} else {
$row[] = ''; // Empty string if unassigned
}
@@ -1110,13 +1110,19 @@ class ReportsController extends Controller
$rows[] = implode(',', $header);
foreach ($assetsForReport as $item) {
$row = [ ];
$row[] = str_replace(',', '', e($item['assetItem']->model->category->name));
$row[] = str_replace(',', '', e($item['assetItem']->model->name));
$row[] = str_replace(',', '', e($item['assetItem']->name));
$row[] = str_replace(',', '', e($item['assetItem']->asset_tag));
$row[] = str_replace(',', '', e(($item['acceptance']->assignedTo) ? $item['acceptance']->assignedTo->present()->name() : trans('admin/reports/general.deleted_user')));
$rows[] = implode(',', $row);
if ($item['assetItem'] != null){
$row = [ ];
$row[] = str_replace(',', '', e($item['assetItem']->model->category->name));
$row[] = str_replace(',', '', e($item['assetItem']->model->name));
$row[] = str_replace(',', '', e($item['assetItem']->name));
$row[] = str_replace(',', '', e($item['assetItem']->asset_tag));
$row[] = str_replace(',', '', e(($item['acceptance']->assignedTo) ? $item['acceptance']->assignedTo->present()->name() : trans('admin/reports/general.deleted_user')));
$rows[] = implode(',', $row);
} else {
// Log the error maybe?
}
}
// spit out a csv
+6 -1
View File
@@ -7,6 +7,7 @@ use App\Helpers\StorageHelper;
use App\Http\Requests\ImageUploadRequest;
use App\Http\Requests\SettingsSamlRequest;
use App\Http\Requests\SetupUserRequest;
use App\Models\Group;
use App\Models\Setting;
use App\Models\Asset;
use App\Models\User;
@@ -339,6 +340,7 @@ class SettingsController extends Controller
$setting->email_format = $request->input('email_format');
$setting->username_format = $request->input('username_format');
$setting->require_accept_signature = $request->input('require_accept_signature');
$setting->display_username = $request->input('display_username', 0);
$setting->show_assigned_assets = $request->input('show_assigned_assets', '0');
if (! config('app.lock_passwords')) {
$setting->login_note = $request->input('login_note');
@@ -911,6 +913,8 @@ class SettingsController extends Controller
public function getLdapSettings()
{
$setting = Setting::getSettings();
$groups = Group::pluck('name', 'id');
/**
* This validator is only temporary (famous last words.) - @snipe
@@ -929,7 +933,7 @@ class SettingsController extends Controller
return view('settings.ldap', compact('setting'))->withErrors($validator);
return view('settings.ldap', compact('setting', 'groups'))->withErrors($validator);
}
/**
@@ -956,6 +960,7 @@ class SettingsController extends Controller
$setting->ldap_pword = Crypt::encrypt($request->input('ldap_pword'));
}
$setting->ldap_basedn = $request->input('ldap_basedn');
$setting->ldap_default_group = $request->input('ldap_default_group');
$setting->ldap_filter = $request->input('ldap_filter');
$setting->ldap_username_field = $request->input('ldap_username_field');
$setting->ldap_lname_field = $request->input('ldap_lname_field');
@@ -131,7 +131,7 @@ class UsersController extends Controller
$user->permissions = json_encode($permissions_array);
// we have to invoke the
app(\App\Http\Requests\ImageUploadRequest::class)->handleImages($user, 600, 'image', 'avatars', 'avatar');
app(ImageUploadRequest::class)->handleImages($user, 600, 'avatar', 'avatars', 'avatar');
if ($user->save()) {
if ($request->filled('groups')) {
@@ -296,7 +296,7 @@ class UsersController extends Controller
$user->permissions = json_encode($permissions_array);
// Handle uploaded avatar
app(\App\Http\Requests\ImageUploadRequest::class)->handleImages($user, 600, 'avatar', 'avatars', 'avatar');
app(ImageUploadRequest::class)->handleImages($user, 600, 'avatar', 'avatars', 'avatar');
//\Log::debug(print_r($user, true));
+27 -8
View File
@@ -8,6 +8,7 @@ use App\Models\AssetModel;
use App\Models\Company;
use App\Models\Setting;
use App\Models\User;
use App\Models\CustomField;
use App\Notifications\RequestAssetCancelation;
use App\Notifications\RequestAssetNotification;
use Illuminate\Http\Request;
@@ -29,23 +30,41 @@ class ViewAssetsController extends Controller
public function getIndex()
{
$user = User::with(
'assets',
'assets.model',
'assets.model.fieldset.fields',
'consumables',
'accessories',
'licenses',
'userloc',
'userlog'
)->withTrashed()->find(Auth::user()->id);
)->find(Auth::user()->id);
$userlog = $user->userlog->load('item', 'user', 'target');
$field_array = array();
// Loop through all the custom fields that are applied to any model the user has assigned
foreach ($user->assets as $asset) {
// Make sure the model has a custom fieldset before trying to loop through the associated fields
if ($asset->model->fieldset) {
foreach ($asset->model->fieldset->fields as $field) {
// check and make sure they're allowed to see the value of the custom field
if ($field->display_in_user_view == '1') {
$field_array[$field->db_column] = $field->name;
}
}
}
}
// Since some models may re-use the same fieldsets/fields, let's make the array unique so we don't repeat columns
array_unique($field_array);
if (isset($user->id)) {
return view('account/view-assets', compact('user', 'userlog'))
return view('account/view-assets', compact('user', 'field_array' ))
->with('settings', Setting::getSettings());
} else {
// Redirect to the user management page
return redirect()->route('users.index')->with('error', trans('admin/users/message.user_not_found', compact('id')));
}
// Redirect to the user management page
return redirect()->route('users.index')
->with('error', trans('admin/users/message.user_not_found', $user->id));
@@ -52,6 +52,13 @@ class AssetCountForSidebar
\Log::debug($e);
}
try {
$total_byod_sidebar = Asset::where('byod', '=', '1')->count();
view()->share('total_byod_sidebar', $total_byod_sidebar);
} catch (\Exception $e) {
\Log::debug($e);
}
return $next($request);
}
}
+25 -33
View File
@@ -63,11 +63,13 @@ class ImageUploadRequest extends Request
* @param string $path location for uploaded images, defaults to uploads/plural of item type.
* @return SnipeModel Target asset is being checked out to.
*/
public function handleImages($item, $w = 600, $form_fieldname = null, $path = null, $db_fieldname = 'image')
public function handleImages($item, $w = 600, $form_fieldname = 'image', $path = null, $db_fieldname = 'image')
{
$type = strtolower(class_basename(get_class($item)));
if (is_null($path)) {
$path = str_plural($type);
if ($type == 'assetmodel') {
@@ -79,42 +81,31 @@ class ImageUploadRequest extends Request
}
}
if (is_null($form_fieldname)) {
$form_fieldname = 'image';
}
// This is dumb, but we need it for overriding field names for exceptions like avatars and logo uploads
if (is_null($db_fieldname)) {
$use_db_field = $form_fieldname;
} else {
$use_db_field = $db_fieldname;
}
// ConvertBase64ToFiles just changes object type,
// as it cannot currently insert files to $this->files
if ($this->offsetGet($form_fieldname) instanceof UploadedFile) {
$image=$this->offsetGet($form_fieldname);
$image = $this->offsetGet($form_fieldname);
\Log::debug('Image is an instance of UploadedFile');
} elseif ($this->hasFile($form_fieldname)) {
$image = $this->file($form_fieldname);
\Log::debug('Just use regular upload for '.$form_fieldname);
} else {
if ($this->hasFile($form_fieldname)) {
$image = $this->file($form_fieldname);
}
\Log::debug('No image found for form fieldname: '.$form_fieldname);
}
if (isset($image)) {
\Log::debug($image);
if (!config('app.lock_passwords')) {
$ext = $image->getClientOriginalExtension();
$file_name = $type.'-'.$form_fieldname.'-'.str_random(10).'.'.$ext;
$file_name = $type.'-'.$form_fieldname.'-'.$item->id.'-'.str_random(10).'.'.$ext;
\Log::info('File name will be: '.$file_name);
\Log::debug('File extension is: '.$ext);
if (($image->getClientOriginalExtension() !== 'webp') && ($image->getClientOriginalExtension() !== 'svg')) {
\Log::debug('Not an SVG or webp - resize');
\Log::debug('Trying to upload to: '.$path.'/'.$file_name);
$upload = Image::make($image->getRealPath())->resize(null, $w, function ($constraint) {
$constraint->aspectRatio();
$constraint->upsize();
@@ -122,6 +113,7 @@ class ImageUploadRequest extends Request
// This requires a string instead of an object, so we use ($string)
Storage::disk('public')->put($path.'/'.$file_name, (string) $upload->encode());
} else {
// If the file is a webp, we need to just move it since webp support
// needs to be compiled into gd for resizing to be available
@@ -146,30 +138,30 @@ class ImageUploadRequest extends Request
}
// Remove Current image if exists
if (Storage::disk('public')->exists($path.'/'.$item->{$use_db_field})) {
if (($item->{$form_fieldname}!='') && (Storage::disk('public')->exists($path.'/'.$item->{$db_fieldname}))) {
\Log::debug('A file already exists that we are replacing - we should delete the old one.');
try {
Storage::disk('public')->delete($path.'/'.$item->{$use_db_field});
Storage::disk('public')->delete($path.'/'.$item->{$form_fieldname});
\Log::debug('Old file '.$path.'/'.$file_name.' has been deleted.');
} catch (\Exception $e) {
\Log::debug('Could not delete old file. '.$path.'/'.$file_name.' does not exist?');
}
}
$item->{$use_db_field} = $file_name;
$item->{$db_fieldname} = $file_name;
}
// If the user isn't uploading anything new but wants to delete their old image, do so
} else {
if ($this->input('image_delete') == '1') {
\Log::debug('Deleting image');
try {
Storage::disk('public')->delete($path.'/'.$item->{$use_db_field});
$item->{$use_db_field} = null;
} catch (\Exception $e) {
\Log::debug($e);
}
} elseif ($this->input('image_delete') == '1') {
\Log::debug('Deleting image');
try {
Storage::disk('public')->delete($path.'/'.$item->{$db_fieldname});
$item->{$db_fieldname} = null;
} catch (\Exception $e) {
\Log::debug($e);
}
}
return $item;
+1 -1
View File
@@ -49,7 +49,7 @@ class ItemImportRequest extends FormRequest
$errorMessage = null;
if (is_null($fieldValue)) {
$errorMessage = trans('validation.import_field_empty');
$errorMessage = trans('validation.import_field_empty', ['fieldname' => $field]);
$this->errorCallback($import, $field, $errorMessage);
return $this->errors;
@@ -4,6 +4,7 @@ namespace App\Http\Transformers;
use App\Helpers\Helper;
use App\Models\Accessory;
use App\Models\Setting;
use Gate;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Support\Facades\Storage;
@@ -22,6 +23,7 @@ class AccessoriesTransformer
public function transformAccessory(Accessory $accessory)
{
$array = [
'id' => $accessory->id,
'name' => e($accessory->name),
@@ -38,7 +40,8 @@ class AccessoriesTransformer
'purchase_cost' => Helper::formatCurrencyOutput($accessory->purchase_cost),
'order_number' => ($accessory->order_number) ? e($accessory->order_number) : null,
'min_qty' => ($accessory->min_amt) ? (int) $accessory->min_amt : null,
'remaining_qty' => $accessory->numRemaining(),
'remaining_qty' => (int) $accessory->numRemaining(),
'users_count' => $accessory->users_count,
'created_at' => Helper::getFormattedDateObject($accessory->created_at, 'datetime'),
'updated_at' => Helper::getFormattedDateObject($accessory->updated_at, 'datetime'),
@@ -65,6 +68,8 @@ class AccessoriesTransformer
public function transformCheckedoutAccessory($accessory, $accessory_users, $total)
{
$setting = Setting::getSettings();
$array = [];
foreach ($accessory_users as $user) {
@@ -73,7 +78,7 @@ class AccessoriesTransformer
'assigned_pivot_id' => $user->pivot->id,
'id' => (int) $user->id,
'username' => e($user->username),
'name' => e($user->getFullNameAttribute()),
'name' => ($setting->display_username == '1') ? e($user->getCompleteNameAttribute()) : e($user->getFullNameAttribute()),
'first_name'=> e($user->first_name),
'last_name'=> e($user->last_name),
'employee_number' => e($user->employee_num),
@@ -4,6 +4,7 @@ namespace App\Http\Transformers;
use App\Helpers\Helper;
use App\Models\Actionlog;
use App\Models\Setting;
use App\Models\User;
use Illuminate\Database\Eloquent\Collection;
class ActionlogsTransformer
@@ -85,6 +86,7 @@ class ActionlogsTransformer
'id' => (int) $actionlog->item->id,
'name' => ($actionlog->itemType()=='user') ? e($actionlog->item->getFullNameAttribute()) : e($actionlog->item->getDisplayNameAttribute()),
'type' => e($actionlog->itemType()),
'serial' =>e($actionlog->item->serial) ? e($actionlog->item->serial) : null
] : null,
'location' => ($actionlog->location) ? [
'id' => (int) $actionlog->location->id,
@@ -112,9 +114,7 @@ class ActionlogsTransformer
'log_meta' => ((isset($clean_meta)) && (is_array($clean_meta))) ? $clean_meta: null,
'action_date' => ($actionlog->action_date) ? Helper::getFormattedDateObject($actionlog->action_date, 'datetime'): Helper::getFormattedDateObject($actionlog->created_at, 'datetime'),
];
//\Log::info("Clean Meta is: ".print_r($clean_meta,true));
//dd($array);
return $array;
}
@@ -125,7 +125,7 @@ class ActionlogsTransformer
$array = array();
foreach ($accessories_users as $user) {
$array[] = (new UsersTransformer)->transformUser($user);
$array[] = (new UsersTransformer)->transformUserCompact($user);
}
return (new DatatablesTransformer)->transformDatatables($array, $total);
}
@@ -22,6 +22,22 @@ class AssetModelsTransformer
public function transformAssetModel(AssetModel $assetmodel)
{
$default_field_values = array();
// Reach into the custom fields and models_custom_fields pivot table to find the default values for this model
if ($assetmodel->fieldset) {
foreach($assetmodel->fieldset->fields AS $field) {
$default_field_values[] = [
'name' => e($field->name),
'db_column_name' => e($field->db_column_name()),
'default_value' => ($field->defaultValue($assetmodel->id)) ? e($field->defaultValue($assetmodel->id)) : null,
'format' => e($field->format),
'required' => ($field->pivot->required == '1') ? true : false,
];
}
}
$array = [
'id' => (int) $assetmodel->id,
'name' => e($assetmodel->name),
@@ -44,6 +60,7 @@ class AssetModelsTransformer
'id' => (int) $assetmodel->fieldset->id,
'name'=> e($assetmodel->fieldset->name),
] : null,
'default_fieldset_values' => $default_field_values,
'eol' => ($assetmodel->eol > 0) ? $assetmodel->eol.' months' : 'None',
'requestable' => ($assetmodel->requestable == '1') ? true : false,
'notes' => e($assetmodel->notes),
+8 -12
View File
@@ -8,6 +8,7 @@ use App\Models\Setting;
use Gate;
use Illuminate\Database\Eloquent\Collection;
class AssetsTransformer
{
public function transformAssets(Collection $assets, $total)
@@ -34,6 +35,8 @@ class AssetsTransformer
'id' => (int) $asset->model->id,
'name'=> e($asset->model->name),
] : null,
'byod' => ($asset->byod ? true : false),
'model_number' => (($asset->model) && ($asset->model->model_number)) ? e($asset->model->model_number) : null,
'eol' => ($asset->purchase_date != '') ? Helper::getFormattedDateObject($asset->present()->eol_date(), 'date') : null,
'status_label' => ($asset->assetstatus) ? [
@@ -71,7 +74,7 @@ class AssetsTransformer
'image' => ($asset->getImageUrl()) ? $asset->getImageUrl() : null,
'qr' => ($setting->qr_code=='1') ? config('app.url').'/uploads/barcodes/qr-'.str_slug($asset->asset_tag).'-'.str_slug($asset->id).'.png' : null,
'alt_barcode' => ($setting->alt_barcode_enabled=='1') ? config('app.url').'/uploads/barcodes/'.str_slug($setting->alt_barcode).'-'.str_slug($asset->asset_tag).'.png' : null,
'assigned_to' => $this->transformAssignedTo($asset),
'assigned_to' => $this->transformAssignedTo($asset, $setting),
'warranty_months' => ($asset->warranty_months > 0) ? e($asset->warranty_months.' '.trans('admin/hardware/form.months')) : null,
'warranty_expires' => ($asset->warranty_months > 0) ? Helper::getFormattedDateObject($asset->warranty_expires, 'date') : null,
'created_at' => Helper::getFormattedDateObject($asset->created_at, 'datetime'),
@@ -80,6 +83,7 @@ class AssetsTransformer
'next_audit_date' => Helper::getFormattedDateObject($asset->next_audit_date, 'date'),
'deleted_at' => Helper::getFormattedDateObject($asset->deleted_at, 'datetime'),
'purchase_date' => Helper::getFormattedDateObject($asset->purchase_date, 'date'),
'age' => $asset->purchase_date ? Helper::AgeFormat($asset->purchase_date) : '',
'last_checkout' => Helper::getFormattedDateObject($asset->last_checkout, 'datetime'),
'expected_checkin' => Helper::getFormattedDateObject($asset->expected_checkin, 'date'),
'purchase_cost' => Helper::formatCurrencyOutput($asset->purchase_cost),
@@ -131,7 +135,7 @@ class AssetsTransformer
$array['custom_fields'] = $fields_array;
}
} else {
$array['custom_fields'] = [];
$array['custom_fields'] = new \stdClass; // HACK to force generation of empty object instead of empty list
}
$permissions_array['available_actions'] = [
@@ -176,18 +180,10 @@ class AssetsTransformer
return (new DatatablesTransformer)->transformDatatables($assets);
}
public function transformAssignedTo($asset)
public function transformAssignedTo($asset, $setting)
{
if ($asset->checkedOutToUser()) {
return $asset->assigned ? [
'id' => (int) $asset->assigned->id,
'username' => e($asset->assigned->username),
'name' => e($asset->assigned->getFullNameAttribute()),
'first_name'=> e($asset->assigned->first_name),
'last_name'=> ($asset->assigned->last_name) ? e($asset->assigned->last_name) : null,
'employee_number' => ($asset->assigned->employee_num) ? e($asset->assigned->employee_num) : null,
'type' => 'user',
] : null;
return (new UsersTransformer)->transformUserCompact($asset->assigned);
}
return $asset->assigned ? [
@@ -22,6 +22,26 @@ class CategoriesTransformer
public function transformCategory(Category $category = null)
{
// We only ever use item_count for categories in this transformer, so it makes sense to keep it
// simple and do this switch here.
switch ($category->category_type) {
case 'asset':
$category->item_count = $category->assets_count;
break;
case 'accessory':
$category->item_count = $category->accessories_count;
break;
case 'consumable':
$category->item_count = $category->consumables_count;
break;
case 'component':
$category->item_count = $category->components_count;
break;
default:
$category->item_count = 0;
}
if ($category) {
$array = [
'id' => (int) $category->id,
@@ -33,7 +53,7 @@ class CategoriesTransformer
'eula' => ($category->getEula()),
'checkin_email' => ($category->checkin_email == '1'),
'require_acceptance' => ($category->require_acceptance == '1'),
'item_count' => (int) $category->itemCount(),
'item_count' => (int) $category->item_count,
'assets_count' => (int) $category->assets_count,
'accessories_count' => (int) $category->accessories_count,
'consumables_count' => (int) $category->consumables_count,
@@ -60,11 +60,11 @@ class ConsumablesTransformer
return $array;
}
public function transformCheckedoutConsumables(Collection $consumables_users, $total)
public function transformCheckedoutConsumables(Consumable $consumable, $consumables_users, $total)
{
$array = [];
foreach ($consumables_users as $user) {
$array[] = (new UsersTransformer)->transformUser($user);
foreach ($consumables_users as $consumables_user) {
$array[] = (new UsersTransformer)->transformUserCompact($consumables_user);
}
return (new DatatablesTransformer)->transformDatatables($array, $total);
@@ -47,6 +47,7 @@ class CustomFieldsTransformer
'field_values_array' => ($field->field_values) ? explode("\r\n", e($field->field_values)) : null,
'type' => e($field->element),
'required' => (($field->pivot) && ($field->pivot->required=='1')) ? true : false,
'display_in_user_view' => ($field->display_in_user_view =='1') ? true : false,
'created_at' => Helper::getFormattedDateObject($field->created_at, 'datetime'),
'updated_at' => Helper::getFormattedDateObject($field->updated_at, 'datetime'),
];
@@ -4,6 +4,7 @@ namespace App\Http\Transformers;
use App\Models\License;
use App\Models\LicenseSeat;
use App\Models\Setting;
use Gate;
use Illuminate\Database\Eloquent\Collection;
@@ -23,19 +24,12 @@ class LicenseSeatsTransformer
public function transformLicenseSeat(LicenseSeat $seat, $seat_count = 0)
{
$setting = Setting::getSettings();
$array = [
'id' => (int) $seat->id,
'license_id' => (int) $seat->license->id,
'assigned_user' => ($seat->user) ? [
'id' => (int) $seat->user->id,
'name'=> e($seat->user->present()->fullName),
'department'=> ($seat->user->department) ?
[
'id' => (int) $seat->user->department->id,
'name' => e($seat->user->department->name),
] : null,
] : null,
'assigned_user' => ($seat->user) ? (new UsersTransformer)->transformUserCompact($seat->user) : null,
'assigned_asset' => ($seat->asset) ? [
'id' => (int) $seat->asset->id,
'name'=> e($seat->asset->present()->fullName),
+31 -1
View File
@@ -3,6 +3,7 @@
namespace App\Http\Transformers;
use App\Helpers\Helper;
use App\Models\Setting;
use App\Models\User;
use Gate;
use Illuminate\Database\Eloquent\Collection;
@@ -21,6 +22,7 @@ class UsersTransformer
public function transformUser(User $user)
{
$array = [
'id' => (int) $user->id,
'avatar' => e($user->present()->gravatar),
@@ -56,8 +58,8 @@ class UsersTransformer
'permissions' => $user->decodePermissions(),
'activated' => ($user->activated == '1') ? true : false,
'ldap_import' => ($user->ldap_import == '1') ? true : false,
'two_factor_activated' => ($user->two_factor_active()) ? true : false,
'two_factor_enrolled' => ($user->two_factor_active_and_enrolled()) ? true : false,
'two_factor_optin' => ($user->two_factor_active()) ? true : false,
'assets_count' => (int) $user->assets_count,
'licenses_count' => (int) $user->licenses_count,
'accessories_count' => (int) $user->accessories_count,
@@ -101,6 +103,34 @@ class UsersTransformer
return $array;
}
public function transformUserCompact(User $user) {
$setting = Setting::getSettings();
return [
'new' => 'yep', // remove me
'id' => (int) $user->id,
'avatar' => e($user->present()->gravatar),
'username' => e($user->username),
'name' => ($setting->display_username == '1') ? e($user->getCompleteNameAttribute()) : e($user->getFullNameAttribute()),
'first_name'=> e($user->first_name),
'last_name'=> ($user->last_name) ? e($user->last_name) : null,
'email'=> ($user->email) ? e($user->email) : null,
'employee_num' => ($user->employee_num) ? e($user->employee_num) : null,
'manager' => ($user->manager) ? [
'id' => (int) $user->manager->id,
'name'=> e($user->manager->first_name).' '.e($user->manager->last_name),
] : null,
'department' => ($user->department) ? [
'id' => (int) $user->department->id,
'name'=> e($user->department->name),
] : null,
'location' => ($user->userloc) ? [
'id' => (int) $user->userloc->id,
'name'=> e($user->userloc->name),
] : null,
'type' => 'user',
];
}
public function transformUsersDatatable($users)
{
return (new DatatablesTransformer)->transformDatatables($users);
+2
View File
@@ -77,6 +77,7 @@ abstract class Importer
'manager_first_name' => 'manager first name',
'manager_last_name' => 'manager last name',
'min_amt' => 'minimum quantity',
'remote' => 'remote',
];
/**
* Map of item fields->csv names
@@ -288,6 +289,7 @@ abstract class Importer
'department_id' => '',
'username' => $this->findCsvMatch($row, 'username'),
'activated' => $this->fetchHumanBoolean($this->findCsvMatch($row, 'activated')),
'remote' => $this->fetchHumanBoolean(($this->findCsvMatch($row, 'remote'))),
];
// Maybe we're lucky and the user already exists.
+1
View File
@@ -57,6 +57,7 @@ class UserImporter extends ItemImporter
$this->item['employee_num'] = $this->findCsvMatch($row, 'employee_num');
$this->item['department_id'] = $this->createOrFetchDepartment($this->findCsvMatch($row, 'department'));
$this->item['manager_id'] = $this->fetchManager($this->findCsvMatch($row, 'manager_first_name'), $this->findCsvMatch($row, 'manager_last_name'));
$this->item['remote'] =($this->fetchHumanBoolean($this->findCsvMatch($row, 'remote')) ==1 ) ? '1' : 0;
$user_department = $this->findCsvMatch($row, 'department');
if ($this->shouldUpdateField($user_department)) {
+2 -16
View File
@@ -327,20 +327,6 @@ class Accessory extends SnipeModel
return null;
}
/**
* Check how many items within an accessory are checked out
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v5.0]
* @return int
*/
public function numCheckedOut()
{
$checkedout = 0;
$checkedout = $this->users->count();
return $checkedout;
}
/**
* Check how many items of an accessory remain
@@ -351,11 +337,11 @@ class Accessory extends SnipeModel
*/
public function numRemaining()
{
$checkedout = $this->users->count();
$checkedout = $this->users_count;
$total = $this->qty;
$remaining = $total - $checkedout;
return $remaining;
return (int) $remaining;
}
/**
+3 -6
View File
@@ -95,6 +95,7 @@ class Asset extends Depreciable
'location_id' => 'integer',
'rtd_company_id' => 'integer',
'supplier_id' => 'integer',
'byod' => 'boolean',
];
protected $rules = [
@@ -106,7 +107,6 @@ class Asset extends Depreciable
'physical' => 'numeric|max:1|nullable',
'checkout_date' => 'date|max:10|min:10|nullable',
'checkin_date' => 'date|max:10|min:10|nullable',
'supplier_id' => 'exists:suppliers,id|numeric|nullable',
'location_id' => 'exists:locations,id|nullable',
'rtd_location_id' => 'exists:locations,id|nullable',
'asset_tag' => 'required|min:1|max:255|unique_undeleted',
@@ -144,6 +144,7 @@ class Asset extends Depreciable
'requestable',
'last_checkout',
'expected_checkin',
'byod',
];
use Searchable;
@@ -315,14 +316,10 @@ class Asset extends Depreciable
}
$this->last_checkout = $checkout_at;
$this->name = $name;
$this->assignedTo()->associate($target);
if ($name != null) {
$this->name = $name;
}
if ($location != null) {
$this->location_id = $location;
} else {
+13 -2
View File
@@ -10,6 +10,7 @@ use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Support\Facades\Gate;
use Watson\Validating\ValidatingTrait;
use App\Helpers\Helper;
use Illuminate\Support\Str;
/**
* Model for Categories. Categories are a higher-level group
@@ -97,6 +98,7 @@ class Category extends SnipeModel
*/
public function isDeletable()
{
return Gate::allows('delete', $this)
&& ($this->itemCount() == 0);
}
@@ -150,7 +152,10 @@ class Category extends SnipeModel
}
/**
* Get the number of items in the category
* Get the number of items in the category. This should NEVER be used in
* a collection of categories, as you'll end up with an n+1 query problem.
*
* It should only be used in a single category context.
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v2.0]
@@ -158,6 +163,11 @@ class Category extends SnipeModel
*/
public function itemCount()
{
if (isset($this->{Str::plural($this->category_type).'_count'})) {
return $this->{Str::plural($this->category_type).'_count'};
}
switch ($this->category_type) {
case 'asset':
return $this->assets()->count();
@@ -169,9 +179,10 @@ class Category extends SnipeModel
return $this->consumables()->count();
case 'license':
return $this->licenses()->count();
default:
return 0;
}
return '0';
}
/**
+1 -1
View File
@@ -21,7 +21,7 @@ class CheckoutAcceptance extends Model
{
// At this point the endpoint is the same for everything.
// In the future this may want to be adapted for individual notifications.
return config('mail.reply_to.address');
return (config('mail.reply_to.address')) ? config('mail.reply_to.address') : '' ;
}
/**
+9
View File
@@ -73,6 +73,10 @@ final class Company extends SnipeModel
}
}
/**
* Scoping table queries, determining if a logged in user is part of a company, and only allows
* that user to see items associated with that company
*/
private static function scopeCompanyablesDirectly($query, $column = 'company_id', $table_name = null)
{
if (Auth::user()) {
@@ -127,6 +131,11 @@ final class Company extends SnipeModel
return false;
} elseif (! static::isFullMultipleCompanySupportEnabled()) {
return true;
} elseif (!$companyable instanceof Company && !\Schema::hasColumn($companyable->getModel()->getTable(), 'company_id')) {
// This is primary for the gate:allows-check in location->isDeletable()
// Locations don't have a company_id so without this it isn't possible to delete locations with FullMultipleCompanySupport enabled
// because this function is called by SnipePermissionsPolicy->before()
return true;
} else {
if (Auth::user()) {
$current_user_company_id = Auth::user()->company_id;
+7 -8
View File
@@ -48,7 +48,11 @@ class CustomField extends Model
*
* @var array
*/
protected $rules = [];
protected $rules = [
'name' => 'required|unique:custom_fields',
'element' => 'required|in:text,listbox,textarea,checkbox,radio',
'field_encrypted' => 'nullable|boolean',
];
/**
* The attributes that are mass assignable.
@@ -64,6 +68,7 @@ class CustomField extends Model
'help_text',
'show_in_email',
'is_unique',
'display_in_user_view',
];
/**
@@ -356,15 +361,9 @@ class CustomField extends Model
public function validationRules($regex_format = null)
{
return [
'name' => 'required|unique:custom_fields',
'element' => [
'required',
Rule::in(['text', 'listbox', 'textarea', 'checkbox', 'radio']),
],
'format' => [
Rule::in(array_merge(array_keys(self::PREDEFINED_FORMATS), self::PREDEFINED_FORMATS, [$regex_format])),
],
'field_encrypted' => 'nullable|boolean',
]
];
}
+1 -1
View File
@@ -29,7 +29,7 @@ class Department extends SnipeModel
];
protected $rules = [
'name' => 'required|max:255',
'name' => 'required|max:255|is_unique_department',
'location_id' => 'numeric|nullable',
'company_id' => 'numeric|nullable',
'manager_id' => 'numeric|nullable',
+10 -2
View File
@@ -123,12 +123,20 @@ class License extends Depreciable
static::created(function ($license) {
$newSeatCount = $license->getAttributes()['seats'];
return static::adjustSeatCount($license, $oldSeatCount = 0, $newSeatCount);
return static::adjustSeatCount($license, 0, $newSeatCount);
});
// However, we listen for updating to be able to prevent the edit if we cannot delete enough seats.
static::updating(function ($license) {
$newSeatCount = $license->getAttributes()['seats'];
$oldSeatCount = isset($license->getOriginal()['seats']) ? $license->getOriginal()['seats'] : 0;
//$oldSeatCount = isset($license->getOriginal()['seats']) ? $license->getOriginal()['seats'] : 0;
/*
That previous method *did* mostly work, but if you ever managed to get your $license->seats value out of whack
with your actual count of license_seats *records*, you would never manage to get back 'into whack'.
The below method actually grabs a count of existing license_seats records, so it will be more accurate.
This means that if your license_seats are out of whack, you can change the quantity and hit 'save' and it
will manage to 'true up' and make your counts line up correctly.
*/
$oldSeatCount = $license->license_seats_count;
return static::adjustSeatCount($license, $oldSeatCount, $newSeatCount);
});
+7 -7
View File
@@ -21,11 +21,10 @@ class Setting extends Model
use Notifiable, ValidatingTrait;
/**
* The app settings cache key name.
*
* @var string
* The cache property so that multiple invocations of this will only load the Settings record from disk only once
* @var self
*/
const APP_SETTINGS_KEY = 'snipeit_app_settings';
public static ?self $_cache = null;
/**
* The setup check cache key name.
@@ -98,14 +97,15 @@ class Setting extends Model
*/
public static function getSettings(): ?self
{
return Cache::rememberForever(self::APP_SETTINGS_KEY, function () {
if (!self::$_cache) {
// Need for setup as no tables exist
try {
return self::first();
self::$_cache = self::first();
} catch (\Throwable $th) {
return null;
}
});
}
return self::$_cache;
}
/**
+195 -133
View File
@@ -12,94 +12,9 @@ class SnipeSCIMConfig extends \ArieTimmerman\Laravel\SCIMServer\SCIMConfig
{
public function getUserConfig()
{
$config = parent::getUserConfig();
// Much of this is copied verbatim from the library, then adjusted for our needs
$config['class'] = SCIMUser::class;
unset($config['mapping']['example:name:space']);
$config['map_unmapped'] = false; // anything we don't explicitly map will _not_ show up.
$core_namespace = 'urn:ietf:params:scim:schemas:core:2.0:User';
$core = $core_namespace.':';
$mappings =& $config['mapping'][$core_namespace]; //grab this entire key, we don't want to be repeating ourselves
//username - *REQUIRED*
$config['validations'][$core.'userName'] = 'required';
$mappings['userName'] = AttributeMapping::eloquent('username');
//human name - *FIRST NAME REQUIRED*
$config['validations'][$core.'name.givenName'] = 'required';
$config['validations'][$core.'name.familyName'] = 'string'; //not required
$mappings['name']['familyName'] = AttributeMapping::eloquent("last_name");
$mappings['name']['givenName'] = AttributeMapping::eloquent("first_name");
$mappings['name']['formatted'] = (new AttributeMapping())->ignoreWrite()->setRead(
function (&$object) {
return $object->getFullNameAttribute();
}
);
// externalId support
$config['validations'][$core.'externalId'] = 'string|nullable'; // not required, but supported mostly just for Okta
// note that the mapping is *not* namespaced like the other $mappings
$config['mapping']['externalId'] = AttributeMapping::eloquent('scim_externalid');
$config['validations'][$core.'emails'] = 'nullable|array'; // emails are not required in Snipe-IT...
$config['validations'][$core.'emails.*.value'] = 'email'; // ...(had to remove the recommended 'required' here)
$mappings['emails'] = [[
"value" => AttributeMapping::eloquent("email"),
"display" => null,
"type" => AttributeMapping::constant("work")->ignoreWrite(),
"primary" => AttributeMapping::constant(true)->ignoreWrite()
]];
//active
$config['validations'][$core.'active'] = 'boolean';
$mappings['active'] = AttributeMapping::eloquent('activated');
//phone
$config['validations'][$core.'phoneNumbers'] = 'nullable|array';
$config['validations'][$core.'phoneNumbers.*.value'] = 'string'; // another one where want to say 'we don't _need_ a phone number, but if you have one it better have a value.
$mappings['phoneNumbers'] = [[
"value" => AttributeMapping::eloquent("phone"),
"display" => null,
"type" => AttributeMapping::constant("work")->ignoreWrite(),
"primary" => AttributeMapping::constant(true)->ignoreWrite()
]];
//address
$config['validations'][$core.'addresses'] = 'nullable|array';
$config['validations'][$core.'addresses.*.streetAddress'] = 'string';
$config['validations'][$core.'addresses.*.locality'] = 'string';
$config['validations'][$core.'addresses.*.region'] = 'nullable|string';
$config['validations'][$core.'addresses.*.postalCode'] = 'nullable|string';
$config['validations'][$core.'addresses.*.country'] = 'string';
$mappings['addresses'] = [[
'type' => AttributeMapping::constant("work")->ignoreWrite(),
'formatted' => AttributeMapping::constant("n/a")->ignoreWrite(), // TODO - is this right? This doesn't look right.
'streetAddress' => AttributeMapping::eloquent("address"),
'locality' => AttributeMapping::eloquent("city"),
'region' => AttributeMapping::eloquent("state"),
'postalCode' => AttributeMapping::eloquent("zip"),
'country' => AttributeMapping::eloquent("country"),
'primary' => AttributeMapping::constant(true)->ignoreWrite() //this isn't in the example?
]];
//title
$config['validations'][$core.'title'] = 'string';
$mappings['title'] = AttributeMapping::eloquent('jobtitle');
//Preferred Language
$config['validations'][$core.'preferredLanguage'] = 'string';
$mappings['preferredLanguage'] = AttributeMapping::eloquent('locale');
/*
/*
more snipe-it attributes I'd like to check out (to map to 'enterprise' maybe?):
- website
- notes?
@@ -108,66 +23,213 @@ class SnipeSCIMConfig extends \ArieTimmerman\Laravel\SCIMServer\SCIMConfig
- company_id to "organization?"
*/
$enterprise_namespace = 'urn:ietf:params:scim:schemas:extension:enterprise:2.0:User';
$ent = $enterprise_namespace.':';
// we remove the 'example' namespace and add the Enterprise one
$config['mapping']['schemas'] = AttributeMapping::constant( [$core_namespace, $enterprise_namespace] )->ignoreWrite();
$user_prefix = 'urn:ietf:params:scim:schemas:core:2.0:User:';
$enterprise_prefix = 'urn:ietf:params:scim:schemas:extension:enterprise:2.0:User:';
$config['validations'][$ent.'employeeNumber'] = 'string';
$config['validations'][$ent.'department'] = 'string';
$config['validations'][$ent.'manager'] = 'nullable';
$config['validations'][$ent.'manager.value'] = 'string';
return [
$config['mapping'][$enterprise_namespace] = [
'employeeNumber' => AttributeMapping::eloquent('employee_num'),
'department' =>(new AttributeMapping())->setAdd( // FIXME parent?
function ($value, &$object) {
$department = Department::where("name", $value)->first();
if ($department) {
$object->department_id = $department->id;
}
}
)->setReplace(
function ($value, &$object) {
$department = Department::where("name", $value)->first();
if ($department) {
$object->department_id = $department->id;
// Set to 'null' to make use of auth.providers.users.model (App\User::class)
'class' => SCIMUser::class,
'validations' => [
$user_prefix . 'userName' => 'required',
$user_prefix . 'name.givenName' => 'required',
$user_prefix . 'name.familyName' => 'nullable|string',
$user_prefix . 'externalId' => 'nullable|string',
$user_prefix . 'emails' => 'nullable|array',
$user_prefix . 'emails.*.value' => 'nullable|email',
$user_prefix . 'active' => 'boolean',
$user_prefix . 'phoneNumbers' => 'nullable|array',
$user_prefix . 'phoneNumbers.*.value' => 'nullable|string',
$user_prefix . 'addresses' => 'nullable|array',
$user_prefix . 'addresses.*.streetAddress' => 'nullable|string',
$user_prefix . 'addresses.*.locality' => 'nullable|string',
$user_prefix . 'addresses.*.region' => 'nullable|string',
$user_prefix . 'addresses.*.postalCode' => 'nullable|string',
$user_prefix . 'addresses.*.country' => 'nullable|string',
$user_prefix . 'title' => 'nullable|string',
$user_prefix . 'preferredLanguage' => 'nullable|string',
// Enterprise validations:
$enterprise_prefix . 'employeeNumber' => 'nullable|string',
$enterprise_prefix . 'department' => 'nullable|string',
$enterprise_prefix . 'manager' => 'nullable',
$enterprise_prefix . 'manager.value' => 'nullable|string'
],
'singular' => 'User',
'schema' => [Schema::SCHEMA_USER],
//eager loading
'withRelations' => [],
'map_unmapped' => false,
// 'unmapped_namespace' => 'urn:ietf:params:scim:schemas:laravel:unmapped',
'description' => 'User Account',
// Map a SCIM attribute to an attribute of the object.
'mapping' => [
'id' => AttributeMapping::eloquent("id")->disableWrite(),
'externalId' => AttributeMapping::eloquent('scim_externalid'), // FIXME - I have a PR that changes a lot of this.
'meta' => [
'created' => AttributeMapping::eloquent("created_at")->disableWrite(),
'lastModified' => AttributeMapping::eloquent("updated_at")->disableWrite(),
'location' => (new AttributeMapping())->setRead(
function ($object) {
return route(
'scim.resource',
[
'resourceType' => 'Users',
'resourceObject' => $object->id
]
);
}
}
)->setRead(
function (&$object) {
return $object->department ? $object->department->name : null;
}
),
'manager' => [
// FIXME - manager writes are disabled. This kinda works but it leaks errors all over the place. Not cool.
// '$ref' => (new AttributeMapping())->ignoreWrite()->ignoreRead(),
// 'displayName' => (new AttributeMapping())->ignoreWrite()->ignoreRead(),
// NOTE: you could probably do a 'plain' Eloquent mapping here, but we don't for future-proofing
'value' => (new AttributeMapping())->setAdd(
function ($value, &$object) {
$manager = User::find($value);
if ($manager) {
$object->manager_id = $manager->id;
)->disableWrite(),
'resourceType' => AttributeMapping::constant("User")
],
'schemas' => AttributeMapping::constant(
[
'urn:ietf:params:scim:schemas:core:2.0:User',
'urn:ietf:params:scim:schemas:extension:enterprise:2.0:User'
]
)->ignoreWrite(),
'urn:ietf:params:scim:schemas:core:2.0:User' => [
'userName' => AttributeMapping::eloquent("username"),
'name' => [
'formatted' => (new AttributeMapping())->ignoreWrite()->setRead(
function (&$object) {
return $object->getFullNameAttribute();
}
),
'familyName' => AttributeMapping::eloquent("last_name"),
'givenName' => AttributeMapping::eloquent("first_name"),
'middleName' => null,
'honorificPrefix' => null,
'honorificSuffix' => null
],
'displayName' => null,
'nickName' => null,
'profileUrl' => null,
'title' => AttributeMapping::eloquent('jobtitle'),
'userType' => null,
'preferredLanguage' => AttributeMapping::eloquent('locale'), // Section 5.3.5 of [RFC7231]
'locale' => null, // see RFC5646
'timezone' => null, // see RFC6557
'active' => AttributeMapping::eloquent('activated'),
'password' => AttributeMapping::eloquent('password')->disableRead(),
// Multi-Valued Attributes
'emails' => [[
"value" => AttributeMapping::eloquent("email"),
"display" => null,
"type" => AttributeMapping::constant("work")->ignoreWrite(),
"primary" => AttributeMapping::constant(true)->ignoreWrite()
]],
'phoneNumbers' => [[
"value" => AttributeMapping::eloquent("phone"),
"display" => null,
"type" => AttributeMapping::constant("work")->ignoreWrite(),
"primary" => AttributeMapping::constant(true)->ignoreWrite()
]],
'ims' => [[
"value" => null,
"display" => null,
"type" => null,
"primary" => null
]], // Instant messaging addresses for the User
'photos' => [[
"value" => null,
"display" => null,
"type" => null,
"primary" => null
]],
'addresses' => [[
'type' => AttributeMapping::constant("work")->ignoreWrite(),
'formatted' => AttributeMapping::constant("n/a")->ignoreWrite(), // TODO - is this right? This doesn't look right.
'streetAddress' => AttributeMapping::eloquent("address"),
'locality' => AttributeMapping::eloquent("city"),
'region' => AttributeMapping::eloquent("state"),
'postalCode' => AttributeMapping::eloquent("zip"),
'country' => AttributeMapping::eloquent("country"),
'primary' => AttributeMapping::constant(true)->ignoreWrite() //this isn't in the example?
]],
'groups' => [[
'value' => null,
'$ref' => null,
'display' => null,
'type' => null,
'type' => null
]],
'entitlements' => null,
'roles' => null,
'x509Certificates' => null
],
'urn:ietf:params:scim:schemas:extension:enterprise:2.0:User' => [
'employeeNumber' => AttributeMapping::eloquent('employee_num'),
'department' => (new AttributeMapping())->setAdd( // FIXME parent?
function ($value, &$object) {
$department = Department::where("name", $value)->first();
if ($department) {
$object->department_id = $department->id;
}
}
}
)->setReplace(
function ($value, &$object) {
$manager = User::find($value);
if ($manager) {
$object->manager_id = $manager->id;
$department = Department::where("name", $value)->first();
if ($department) {
$object->department_id = $department->id;
}
}
)->setRead(
function (&$object) {
return $object->manager_id;
}
return $object->department ? $object->department->name : null;
}
),
'manager' => [
// FIXME - manager writes are disabled. This kinda works but it leaks errors all over the place. Not cool.
// '$ref' => (new AttributeMapping())->ignoreWrite()->ignoreRead(),
// 'displayName' => (new AttributeMapping())->ignoreWrite()->ignoreRead(),
// NOTE: you could probably do a 'plain' Eloquent mapping here, but we don't for future-proofing
'value' => (new AttributeMapping())->setAdd(
function ($value, &$object) {
$manager = User::find($value);
if ($manager) {
$object->manager_id = $manager->id;
}
}
)->setReplace(
function ($value, &$object) {
$manager = User::find($value);
if ($manager) {
$object->manager_id = $manager->id;
}
}
)->setRead(
function (&$object) {
return $object->manager_id;
}
),
]
]
]
];
return $config;
}
}
Executable → Regular
+35 -13
View File
@@ -61,7 +61,9 @@ class User extends SnipeModel implements AuthenticatableContract, AuthorizableCo
'remote',
'start_date',
'end_date',
'scim_externalid'
'scim_externalid',
'avatar',
'gravatar',
];
protected $casts = [
@@ -338,6 +340,24 @@ class User extends SnipeModel implements AuthenticatableContract, AuthorizableCo
return $this->belongsToMany(\App\Models\License::class, 'license_seats', 'assigned_to', 'license_id')->withPivot('id');
}
/**
* Establishes a count of all items assigned
*
* @author J. Vinsmoke
* @since [v6.1]
* @return \Illuminate\Database\Eloquent\Relations\Relation
*/
Public function allAssignedCount() {
$assetsCount = $this->assets()->count();
$licensesCount = $this->licenses()->count();
$accessoriesCount = $this->accessories()->count();
$consumablesCount = $this->consumables()->count();
$totalCount = $assetsCount + $licensesCount + $accessoriesCount + $consumablesCount;
return (int) $totalCount;
}
/**
* Establishes the user -> actionlogs relationship
*
@@ -568,6 +588,7 @@ class User extends SnipeModel implements AuthenticatableContract, AuthorizableCo
if ((Setting::getSettings()->two_factor_enabled == '1') && ($this->two_factor_optin == '1')) {
return true;
}
// If the 2FA is required for everyone so is implicitly active
elseif (Setting::getSettings()->two_factor_enabled == '2') {
return true;
@@ -576,18 +597,6 @@ class User extends SnipeModel implements AuthenticatableContract, AuthorizableCo
return false;
}
/**
* Get the admin user who created this user
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v6.0.5]
* @return \Illuminate\Database\Eloquent\Relations\Relation
*/
public function createdBy()
{
return $this->belongsTo(\App\Models\User::class, 'created_by')->withTrashed();
}
/**
* Check whether two-factor authorization is required and the user has activated it
* and enrolled a device
@@ -616,6 +625,19 @@ class User extends SnipeModel implements AuthenticatableContract, AuthorizableCo
}
/**
* Get the admin user who created this user
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v6.0.5]
* @return \Illuminate\Database\Eloquent\Relations\Relation
*/
public function createdBy()
{
return $this->belongsTo(\App\Models\User::class, 'created_by')->withTrashed();
}
public function decodePermissions()
{
+1 -1
View File
@@ -44,7 +44,7 @@ class CurrentInventory extends Notification
'accessories' => $this->user->accessories,
'licenses' => $this->user->licenses,
])
->subject('Inventory Report');
->subject(trans('mail.inventory_report'));
return $message;
}
+5 -5
View File
@@ -19,11 +19,11 @@ class WelcomeNotification extends Notification
*/
public function __construct(array $content)
{
$this->_data['email'] = $content['email'];
$this->_data['first_name'] = $content['first_name'];
$this->_data['last_name'] = $content['last_name'];
$this->_data['username'] = $content['username'];
$this->_data['password'] = $content['password'];
$this->_data['email'] = htmlspecialchars_decode($content['email']);
$this->_data['first_name'] = htmlspecialchars_decode($content['first_name']);
$this->_data['last_name'] = htmlspecialchars_decode($content['last_name']);
$this->_data['username'] = htmlspecialchars_decode($content['username']);
$this->_data['password'] = htmlspecialchars_decode($content['password']);
$this->_data['url'] = url('/');
}
-1
View File
@@ -16,7 +16,6 @@ class SettingObserver
*/
public function saved(Setting $setting)
{
Cache::forget(Setting::APP_SETTINGS_KEY);
Cache::forget(Setting::SETUP_CHECK_KEY);
}
}
+12 -6
View File
@@ -80,19 +80,25 @@ class AccessoryPresenter extends Presenter
], [
'field' => 'qty',
'searchable' => false,
'sortable' => false,
'title' => trans('admin/accessories/general.total'),
], [
'field' => 'min_qty',
'searchable' => false,
'sortable' => true,
'title' => trans('general.min_amt'),
'title' => trans('admin/accessories/general.total'),
], [
'field' => 'remaining_qty',
'searchable' => false,
'sortable' => false,
'visible' => false,
'title' => trans('admin/accessories/general.remaining'),
],[
'field' => 'users_count',
'searchable' => false,
'sortable' => true,
'visible' => true,
'title' => trans('general.checked_out'),
], [
'field' => 'min_qty',
'searchable' => false,
'sortable' => true,
'title' => trans('general.min_amt'),
], [
'field' => 'purchase_date',
'searchable' => true,
+1 -1
View File
@@ -88,7 +88,7 @@ class AssetModelPresenter extends Presenter
'sortable' => true,
'switchable' => true,
'title' => trans('general.category'),
'visible' => false,
'visible' => true,
'formatter' => 'categoriesLinkObjFormatter',
],
[
+14
View File
@@ -140,6 +140,12 @@ class AssetPresenter extends Presenter
'visible' => false,
'title' => trans('general.purchase_date'),
'formatter' => 'dateDisplayFormatter',
], [
'field' => 'age',
'searchable' => true,
'sortable' => true,
'visible' => false,
'title' => trans('general.age'),
], [
'field' => 'purchase_cost',
'searchable' => true,
@@ -244,6 +250,14 @@ class AssetPresenter extends Presenter
'visible' => false,
'title' => trans('general.next_audit_date'),
'formatter' => 'dateDisplayFormatter',
], [
'field' => 'byod',
'searchable' => false,
'sortable' => true,
'visible' => false,
'title' => trans('general.byod'),
'formatter' => 'trueFalseFormatter',
],
];
+9 -23
View File
@@ -70,47 +70,33 @@ class CategoryPresenter extends Presenter
'visible' => true,
'formatter' => 'trueFalseFormatter',
], [
'field' => 'actions',
'searchable' => false,
'sortable' => false,
'switchable' => false,
'title' => trans('table.actions'),
],[
"field" => "use_default_eula",
"searchable" => false,
"sortable" => true,
"title" => trans('admin/categories/general.use_default_eula_column'),
'visible' => true,
"formatter" => 'trueFalseFormatter',
],[
"field" => "checkin_email",
"searchable" => false,
"sortable" => true,
"class" => 'css-envelope',
"title" => 'Send Email',
"visible" => true,
"formatter" => 'trueFalseFormatter',
],[
"field" => "require_acceptance",
"searchable" => false,
"sortable" => true,
'formatter' => 'categoriesActionsFormatter',
],
[
], [
'field' => 'created_at',
'searchable' => true,
'sortable' => true,
'visible' => false,
'title' => trans('general.created_at'),
'formatter' => 'dateDisplayFormatter',
],
[
], [
'field' => 'updated_at',
'searchable' => true,
'sortable' => true,
'visible' => false,
'title' => trans('general.updated_at'),
'formatter' => 'dateDisplayFormatter',
], [
'field' => 'actions',
'searchable' => false,
'sortable' => false,
'switchable' => false,
'title' => trans('table.actions'),
'formatter' => 'categoriesActionsFormatter',
],
];
+2 -2
View File
@@ -268,9 +268,9 @@ class UserPresenter extends Presenter
'formatter' => 'trueFalseFormatter',
],
[
'field' => 'two_factor_activated',
'field' => 'two_factor_optin',
'searchable' => false,
'sortable' => false,
'sortable' => true,
'switchable' => true,
'title' => trans('admin/users/general.two_factor_active'),
'visible' => false,
+22
View File
@@ -114,6 +114,24 @@ class AuthServiceProvider extends ServiceProvider
}
});
Gate::define('accessories.files', function ($user) {
if ($user->hasAccess('accessories.files')) {
return true;
}
});
Gate::define('components.files', function ($user) {
if ($user->hasAccess('components.files')) {
return true;
}
});
Gate::define('consumables.files', function ($user) {
if ($user->hasAccess('consumables.files')) {
return true;
}
});
// Can the user import CSVs?
Gate::define('import', function ($user) {
if ($user->hasAccess('import')) {
@@ -159,6 +177,10 @@ class AuthServiceProvider extends ServiceProvider
return $user->hasAccess('self.checkout_assets');
});
Gate::define('self.view_purchase_cost', function ($user) {
return $user->hasAccess('self.view_purchase_cost');
});
// This is largely used to determine whether to display the gear icon sidenav
// in the left-side navigation
Gate::define('backend.interact', function ($user) {
@@ -2,8 +2,10 @@
namespace App\Providers;
use App\Models\Department;
use DB;
use Illuminate\Support\ServiceProvider;
use Illuminate\Validation\Rule;
use Validator;
/**
@@ -213,6 +215,23 @@ class ValidationServiceProvider extends ServiceProvider
return true;
}
});
Validator::extend('is_unique_department', function ($attribute, $value, $parameters, $validator) {
$data = $validator->getData();
if ((array_key_exists('location_id', $data) && $data['location_id'] != null) && (array_key_exists('company_id', $data) && $data['company_id'] != null)) {
$count = Department::where('name', $data['name'])
->where('location_id', $data['location_id'])
->where('company_id', $data['company_id'])
->whereNotNull('company_id')
->whereNotNull('location_id')
->count('name');
return $count < 1;
}
else {
return true;
}
});
}
/**
+1 -1
View File
@@ -73,7 +73,7 @@
},
"require-dev": {
"fakerphp/faker": "^1.16",
"laravel/dusk": "^6.19",
"laravel/dusk": "^6.25",
"mockery/mockery": "^1.4",
"phpunit/php-token-stream": "^3.1",
"phpunit/phpunit": "^9.0",
Generated
+15 -15
View File
@@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "0c1f3848f8c9ede2b5f1513e4feaa7d7",
"content-hash": "4fed0ab76a34ef85a44568e470abab48",
"packages": [
{
"name": "alek13/slack",
@@ -78,19 +78,19 @@
"source": {
"type": "git",
"url": "https://github.com/grokability/laravel-scim-server.git",
"reference": "9e7a8fd51a7380bc18ca1f01256574d75a2c6b49"
"reference": "9e8dd2d3958d3c3c05d0a99fe6475361ad9e9419"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/grokability/laravel-scim-server/zipball/9e7a8fd51a7380bc18ca1f01256574d75a2c6b49",
"reference": "9e7a8fd51a7380bc18ca1f01256574d75a2c6b49",
"url": "https://api.github.com/repos/grokability/laravel-scim-server/zipball/9e8dd2d3958d3c3c05d0a99fe6475361ad9e9419",
"reference": "9e8dd2d3958d3c3c05d0a99fe6475361ad9e9419",
"shasum": ""
},
"require": {
"illuminate/console": "^6.0|^7.0|^8.0",
"illuminate/database": "^6.0|^7.0|^8.0",
"illuminate/support": "^6.0|^7.0|^8.0",
"php": "^7.4|^8.0",
"illuminate/console": "^6.0|^7.0|^8.0|^9.0",
"illuminate/database": "^6.0|^7.0|^8.0|^9.0",
"illuminate/support": "^6.0|^7.0|^8.0|^9.0",
"php": "^7.0|^8.0",
"tmilos/scim-filter-parser": "^1.3",
"tmilos/scim-schema": "^0.1.0"
},
@@ -133,7 +133,7 @@
"support": {
"source": "https://github.com/grokability/laravel-scim-server/tree/master"
},
"time": "2022-10-06T00:42:37+00:00"
"time": "2023-01-12T00:32:07+00:00"
},
{
"name": "asm89/stack-cors",
@@ -11847,16 +11847,16 @@
},
{
"name": "laravel/dusk",
"version": "v6.25.0",
"version": "v6.25.2",
"source": {
"type": "git",
"url": "https://github.com/laravel/dusk.git",
"reference": "b4632b7493a187d31afc5c9ddec437c81b16421a"
"reference": "25a595ac3dc82089a91af10dd23b0d58fd3f6d0b"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/laravel/dusk/zipball/b4632b7493a187d31afc5c9ddec437c81b16421a",
"reference": "b4632b7493a187d31afc5c9ddec437c81b16421a",
"url": "https://api.github.com/repos/laravel/dusk/zipball/25a595ac3dc82089a91af10dd23b0d58fd3f6d0b",
"reference": "25a595ac3dc82089a91af10dd23b0d58fd3f6d0b",
"shasum": ""
},
"require": {
@@ -11914,9 +11914,9 @@
],
"support": {
"issues": "https://github.com/laravel/dusk/issues",
"source": "https://github.com/laravel/dusk/tree/v6.25.0"
"source": "https://github.com/laravel/dusk/tree/v6.25.2"
},
"time": "2022-07-11T11:38:43+00:00"
"time": "2022-09-29T09:37:07+00:00"
},
{
"name": "mockery/mockery",
+1
View File
@@ -102,6 +102,7 @@ return [
'pgsql' => [
'driver' => 'pgsql',
'host' => env('DB_HOST', 'localhost'),
'port' => env('DB_PORT', '5432'),
'database' => env('DB_DATABASE', 'forge'),
'username' => env('DB_USERNAME', 'forge'),
'password' => env('DB_PASSWORD', ''),
+20 -2
View File
@@ -4,7 +4,7 @@ use Monolog\Handler\NullHandler;
use Monolog\Handler\StreamHandler;
use Monolog\Handler\SyslogUdpHandler;
return [
$config = [
/*
|--------------------------------------------------------------------------
@@ -35,6 +35,8 @@ return [
*/
'channels' => [
// This will get overwritten to 'single' AND 'rollbar' in the code at the bottom of this file
// if a ROLLBAR_TOKEN is given in the .env file
'stack' => [
'driver' => 'stack',
'channels' => ['single'],
@@ -104,7 +106,23 @@ return [
'scimtrace' => [
'driver' => 'single',
'path' => storage_path('logs/scim.log')
]
],
'rollbar' => [
'driver' => 'monolog',
'handler' => \Rollbar\Laravel\MonologHandler::class,
'access_token' => env('ROLLBAR_TOKEN'),
'level' => env('ROLLBAR_LEVEL', 'error'),
],
],
];
// Only add rollbar if the .env has a rollbar token
if ((env('APP_ENV')=='production') && (env('ROLLBAR_TOKEN'))) {
$config['channels']['stack']['channels'] = ['single', 'rollbar'];
}
return $config;
+7
View File
@@ -645,6 +645,13 @@ return [
'display' => true,
],
[
'permission' => 'self.view_purchase_cost',
'label' => 'View Purchase-Cost Column',
'note' => 'This user can see the purchase cost column of items assigned to them.',
'display' => true,
],
],
];
+3 -1
View File
@@ -1,6 +1,8 @@
<?php
return [
"trace" => env("SCIM_TRACE",false),
// below, if we ever get 'sure' that we can change this default to 'true' we should
"omit_main_schema_in_return" => env('SCIM_STANDARDS_COMPLIANCE', true),
"publish_routes" => false,
"trace" => env("SCIM_TRACE",false)
];
+5 -5
View File
@@ -1,10 +1,10 @@
<?php
return array (
'app_version' => 'v6.0.13',
'full_app_version' => 'v6.0.13 - build 8923-g30f4af3ac',
'build_version' => '8923',
'app_version' => 'v6.0.14',
'full_app_version' => 'v6.0.14 - build 9161-g799c9c910',
'build_version' => '9161',
'prerelease_version' => '',
'hash_version' => 'g30f4af3ac',
'full_hash' => 'v6.0.13-97-g30f4af3ac',
'hash_version' => 'g799c9c910',
'full_hash' => 'v6.0.14-117-g799c9c910',
'branch' => 'master',
);
@@ -44,6 +44,8 @@ class MigrationCartalystSentryInstallGroups extends Migration
*/
public function down()
{
Schema::drop('permission_groups');
// See 2014_11_04_231416_update_group_field_for_reporting.php and 2019_06_12_184327_rename_groups_table.php
Schema::dropIfExists('permission_groups');
Schema::dropIfExists('groups');
}
}
@@ -26,6 +26,6 @@ class AddPhysicalToAssets extends Migration
*/
public function down()
{
$table->dropColumn('physical');
// $table->dropColumn('physical');
}
}
@@ -37,7 +37,7 @@ class ReCreateLicensesTable extends Migration
*/
public function down()
{
//
Schema::drop('licenses');
// This was most likely handled in 2013_11_17_054359_drop_licenses_table.php
Schema::dropIfExists('licenses');
}
}
@@ -31,6 +31,6 @@ class CreateLicenseSeatsTable extends Migration
*/
public function down()
{
//
Schema::dropIfExists('license_seats');
}
}
@@ -23,6 +23,8 @@ class AlterWarrantyColumnOnAssets extends Migration
*/
public function down()
{
//
Schema::table('assets', function ($table) {
$table->renameColumn('warranty_months', 'warrantee_months');
});
}
}
@@ -24,7 +24,7 @@ class AddEolOnModelsTable extends Migration
public function down()
{
Schema::table('models', function ($table) {
$table->dropColumn('old');
$table->dropColumn('eol');
});
}
}
@@ -105,10 +105,10 @@
*/
public function down()
{
Schema::table('asset_logs', function (Blueprint $table) {
$table->dropIndex('thread_id');
$table->dropColumn('thread_id');
});
// Schema::table('asset_logs', function (Blueprint $table) {
// $table->dropIndex('thread_id');
// $table->dropColumn('thread_id');
// });
}
/**
@@ -48,13 +48,19 @@ class MigrateMacAddress extends Migration
*/
public function down()
{
//
$f = \App\Models\CustomFieldset::where(['name' => 'Asset with MAC Address'])->first();
$f->fields()->delete();
$f->delete();
if ($f) {
$f->fields()->delete();
$f->delete();
}
Schema::table('models', function (Blueprint $table) {
$table->renameColumn('deprecated_mac_address', 'show_mac_address');
});
DB::statement('ALTER TABLE assets CHANGE _snipeit_mac_address mac_address varchar(255)');
if (Schema::hasColumn('assets', '_snipeit_mac_address')) {
DB::statement('ALTER TABLE assets CHANGE _snipeit_mac_address mac_address varchar(255)');
}
}
}
@@ -25,7 +25,7 @@ class AddShowInNavToStatusLabels extends Migration
public function down()
{
Schema::table('status_labels', function (Blueprint $table) {
$table->dropColumn('show_in_nav', 'field_encrypted');
$table->dropColumn('show_in_nav');
});
}
}
@@ -4,6 +4,7 @@ use App\Models\CustomField;
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
use Illuminate\Support\Str;
/**
* Fixes issue #2551 where columns got donked if the field name in non-ascii
@@ -71,6 +72,25 @@ class FixUtf8CustomFieldColumnNames extends Migration
*/
public function down()
{
// In the up method above, updateLegacyColumnName is called and custom fields in the assets table are prefixed
// with "_snipe_it_", suffixed with "_{id of the CustomField}", and stored in custom_fields.db_column.
// The following reverses those changes.
foreach (CustomField::all() as $field) {
$currentColumnName = $field->db_column;
// "_snipeit_imei_1" becomes "_snipeit_imei"
$legacyColumnName = (string) Str::of($currentColumnName)->replaceMatches('/_(\d)+$/', '');
if (Schema::hasColumn(CustomField::$table_name, $currentColumnName)) {
Schema::table(CustomField::$table_name, function (Blueprint $table) use ($currentColumnName, $legacyColumnName) {
$table->renameColumn(
$currentColumnName,
$legacyColumnName
);
});
}
}
Schema::table('custom_fields', function ($table) {
$table->dropColumn('db_column');
$table->dropColumn('help_text');
@@ -28,7 +28,7 @@ class AddFieldsToManufacturer extends Migration
*/
public function down()
{
Schema::table('settings', function ($table) {
Schema::table('manufacturers', function ($table) {
$table->dropColumn('url');
$table->dropColumn('support_url');
$table->dropColumn('support_phone');
@@ -0,0 +1,33 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class AddsLdapDefaultGroupToSettingsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('settings', function (Blueprint $table) {
$table->integer('ldap_default_group')
->after('ldap_basedn')->default(null);
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('settings', function (Blueprint $table) {
$table->dropColumn('ldap_default_group');
});
}
}
@@ -0,0 +1,32 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class AddDisplayToUserInCustomFields extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('custom_fields', function (Blueprint $table) {
$table->boolean('display_in_user_view')->nullable()->default(0);
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('custom_fields', function (Blueprint $table) {
$table->dropColumn('display_in_user_view');
});
}
}
@@ -0,0 +1,30 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class FixNullableMigrationForSettings extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('settings', function (Blueprint $table) {
$table->string('ldap_default_group')->nullable()->default(null)->change();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
// nothing to do here - this is a hotfix
}
}
@@ -0,0 +1,34 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class AddByodToAssets extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('assets', function (Blueprint $table) {
$table->boolean('byod')->nullable()->default(0);
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('assets', function (Blueprint $table) {
if (Schema::hasColumn('assets', 'byod')) {
$table->dropColumn('byod');
}
});
}
}
@@ -0,0 +1,34 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class AddUsernameDisplayToSettings extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('settings', function (Blueprint $table) {
$table->boolean('display_username')->after('show_archived_in_list')->default(1)->nullable();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('settings', function (Blueprint $table) {
if (Schema::hasColumn('assets', 'display_username_in_list')) {
$table->dropColumn('display_username');
}
});
}
}
@@ -0,0 +1,33 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
use App\Models\CustomField;
class FixUnescapedCustomfieldsFormat extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
$customfields = CustomField::where('format', 'LIKE', '%&%')->get();
foreach($customfields as $customfield){
$customfield->update(['format' => html_entity_decode($customfield->format)]);
}
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
//
}
}
+93 -267
View File
@@ -1329,9 +1329,9 @@
"dev": true
},
"@fortawesome/fontawesome-free": {
"version": "6.2.0",
"resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-free/-/fontawesome-free-6.2.0.tgz",
"integrity": "sha512-CNR7qRIfCwWHNN7FnKUniva94edPdyQzil/zCwk3v6k4R6rR2Fr8i4s3PM7n/lyfPA6Zfko9z5WDzFxG9SW1uQ=="
"version": "6.2.1",
"resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-free/-/fontawesome-free-6.2.1.tgz",
"integrity": "sha512-viouXhegu/TjkvYQoiRZK3aax69dGXxgEjpvZW81wIJdxm5Fnvp3VVIP4VHKqX4SvFw6qpmkILkD4RJWAdrt7A=="
},
"@jridgewell/gen-mapping": {
"version": "0.1.1",
@@ -3588,9 +3588,9 @@
}
},
"camelcase": {
"version": "5.3.1",
"resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
"integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg=="
"version": "6.3.0",
"resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz",
"integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA=="
},
"caniuse-api": {
"version": "3.0.0",
@@ -4244,75 +4244,60 @@
}
},
"css-loader": {
"version": "3.6.0",
"resolved": "https://registry.npmjs.org/css-loader/-/css-loader-3.6.0.tgz",
"integrity": "sha512-M5lSukoWi1If8dhQAUCvj4H8vUt3vOnwbQBH9DdTm/s4Ym2B/3dPMtYZeJmq7Q3S3Pa+I94DcZ7pc9bP14cWIQ==",
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/css-loader/-/css-loader-4.3.0.tgz",
"integrity": "sha512-rdezjCjScIrsL8BSYszgT4s476IcNKt6yX69t0pHjJVnPUTDpn4WfIpDQTN3wCJvUvfsz/mFjuGOekf3PY3NUg==",
"requires": {
"camelcase": "^5.3.1",
"camelcase": "^6.0.0",
"cssesc": "^3.0.0",
"icss-utils": "^4.1.1",
"loader-utils": "^1.2.3",
"normalize-path": "^3.0.0",
"loader-utils": "^2.0.0",
"postcss": "^7.0.32",
"postcss-modules-extract-imports": "^2.0.0",
"postcss-modules-local-by-default": "^3.0.2",
"postcss-modules-local-by-default": "^3.0.3",
"postcss-modules-scope": "^2.2.0",
"postcss-modules-values": "^3.0.0",
"postcss-value-parser": "^4.1.0",
"schema-utils": "^2.7.0",
"semver": "^6.3.0"
"schema-utils": "^2.7.1",
"semver": "^7.3.2"
},
"dependencies": {
"ansi-styles": {
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
"integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
"loader-utils": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz",
"integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==",
"requires": {
"color-convert": "^1.9.0"
"big.js": "^5.2.2",
"emojis-list": "^3.0.0",
"json5": "^2.1.2"
}
},
"chalk": {
"version": "2.4.2",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
"integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
"requires": {
"ansi-styles": "^3.2.1",
"escape-string-regexp": "^1.0.5",
"supports-color": "^5.3.0"
},
"dependencies": {
"supports-color": {
"version": "5.5.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
"integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
"requires": {
"has-flag": "^3.0.0"
}
}
}
"picocolors": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz",
"integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA=="
},
"postcss": {
"version": "7.0.36",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.36.tgz",
"integrity": "sha512-BebJSIUMwJHRH0HAQoxN4u1CN86glsrwsW0q7T+/m44eXOUAxSNdHRkNZPYz5vVUbg17hFgOQDE7fZk7li3pZw==",
"version": "7.0.39",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz",
"integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==",
"requires": {
"chalk": "^2.4.2",
"source-map": "^0.6.1",
"supports-color": "^6.1.0"
"picocolors": "^0.2.1",
"source-map": "^0.6.1"
}
},
"semver": {
"version": "7.3.8",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz",
"integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==",
"requires": {
"lru-cache": "^6.0.0"
}
},
"source-map": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
},
"supports-color": {
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz",
"integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==",
"requires": {
"has-flag": "^3.0.0"
}
}
}
},
@@ -4936,7 +4921,8 @@
"escape-string-regexp": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
"integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ="
"integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
"dev": true
},
"escodegen": {
"version": "1.14.3",
@@ -15028,7 +15014,8 @@
"has-flag": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
"integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0="
"integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
"dev": true
},
"has-symbols": {
"version": "1.0.1",
@@ -15350,56 +15337,24 @@
"postcss": "^7.0.14"
},
"dependencies": {
"ansi-styles": {
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
"integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
"requires": {
"color-convert": "^1.9.0"
}
},
"chalk": {
"version": "2.4.2",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
"integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
"requires": {
"ansi-styles": "^3.2.1",
"escape-string-regexp": "^1.0.5",
"supports-color": "^5.3.0"
},
"dependencies": {
"supports-color": {
"version": "5.5.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
"integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
"requires": {
"has-flag": "^3.0.0"
}
}
}
"picocolors": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz",
"integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA=="
},
"postcss": {
"version": "7.0.36",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.36.tgz",
"integrity": "sha512-BebJSIUMwJHRH0HAQoxN4u1CN86glsrwsW0q7T+/m44eXOUAxSNdHRkNZPYz5vVUbg17hFgOQDE7fZk7li3pZw==",
"version": "7.0.39",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz",
"integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==",
"requires": {
"chalk": "^2.4.2",
"source-map": "^0.6.1",
"supports-color": "^6.1.0"
"picocolors": "^0.2.1",
"source-map": "^0.6.1"
}
},
"source-map": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
},
"supports-color": {
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz",
"integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==",
"requires": {
"has-flag": "^3.0.0"
}
}
}
},
@@ -15867,8 +15822,7 @@
"json5": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz",
"integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==",
"dev": true
"integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA=="
},
"jsonfile": {
"version": "6.1.0",
@@ -16453,7 +16407,6 @@
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
"integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
"dev": true,
"requires": {
"yallist": "^4.0.0"
}
@@ -17011,7 +16964,8 @@
"normalize-path": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
"integrity": "sha1-Dc1p/yOhybEf0JeDFmRKA4ghamU="
"integrity": "sha1-Dc1p/yOhybEf0JeDFmRKA4ghamU=",
"dev": true
},
"normalize-range": {
"version": "0.1.2",
@@ -17691,56 +17645,24 @@
"postcss": "^7.0.5"
},
"dependencies": {
"ansi-styles": {
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
"integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
"requires": {
"color-convert": "^1.9.0"
}
},
"chalk": {
"version": "2.4.2",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
"integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
"requires": {
"ansi-styles": "^3.2.1",
"escape-string-regexp": "^1.0.5",
"supports-color": "^5.3.0"
},
"dependencies": {
"supports-color": {
"version": "5.5.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
"integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
"requires": {
"has-flag": "^3.0.0"
}
}
}
"picocolors": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz",
"integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA=="
},
"postcss": {
"version": "7.0.36",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.36.tgz",
"integrity": "sha512-BebJSIUMwJHRH0HAQoxN4u1CN86glsrwsW0q7T+/m44eXOUAxSNdHRkNZPYz5vVUbg17hFgOQDE7fZk7li3pZw==",
"version": "7.0.39",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz",
"integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==",
"requires": {
"chalk": "^2.4.2",
"source-map": "^0.6.1",
"supports-color": "^6.1.0"
"picocolors": "^0.2.1",
"source-map": "^0.6.1"
}
},
"source-map": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
},
"supports-color": {
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz",
"integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==",
"requires": {
"has-flag": "^3.0.0"
}
}
}
},
@@ -17755,56 +17677,24 @@
"postcss-value-parser": "^4.1.0"
},
"dependencies": {
"ansi-styles": {
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
"integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
"requires": {
"color-convert": "^1.9.0"
}
},
"chalk": {
"version": "2.4.2",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
"integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
"requires": {
"ansi-styles": "^3.2.1",
"escape-string-regexp": "^1.0.5",
"supports-color": "^5.3.0"
},
"dependencies": {
"supports-color": {
"version": "5.5.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
"integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
"requires": {
"has-flag": "^3.0.0"
}
}
}
"picocolors": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz",
"integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA=="
},
"postcss": {
"version": "7.0.36",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.36.tgz",
"integrity": "sha512-BebJSIUMwJHRH0HAQoxN4u1CN86glsrwsW0q7T+/m44eXOUAxSNdHRkNZPYz5vVUbg17hFgOQDE7fZk7li3pZw==",
"version": "7.0.39",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz",
"integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==",
"requires": {
"chalk": "^2.4.2",
"source-map": "^0.6.1",
"supports-color": "^6.1.0"
"picocolors": "^0.2.1",
"source-map": "^0.6.1"
}
},
"source-map": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
},
"supports-color": {
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz",
"integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==",
"requires": {
"has-flag": "^3.0.0"
}
}
}
},
@@ -17817,56 +17707,24 @@
"postcss-selector-parser": "^6.0.0"
},
"dependencies": {
"ansi-styles": {
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
"integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
"requires": {
"color-convert": "^1.9.0"
}
},
"chalk": {
"version": "2.4.2",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
"integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
"requires": {
"ansi-styles": "^3.2.1",
"escape-string-regexp": "^1.0.5",
"supports-color": "^5.3.0"
},
"dependencies": {
"supports-color": {
"version": "5.5.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
"integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
"requires": {
"has-flag": "^3.0.0"
}
}
}
"picocolors": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz",
"integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA=="
},
"postcss": {
"version": "7.0.36",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.36.tgz",
"integrity": "sha512-BebJSIUMwJHRH0HAQoxN4u1CN86glsrwsW0q7T+/m44eXOUAxSNdHRkNZPYz5vVUbg17hFgOQDE7fZk7li3pZw==",
"version": "7.0.39",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz",
"integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==",
"requires": {
"chalk": "^2.4.2",
"source-map": "^0.6.1",
"supports-color": "^6.1.0"
"picocolors": "^0.2.1",
"source-map": "^0.6.1"
}
},
"source-map": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
},
"supports-color": {
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz",
"integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==",
"requires": {
"has-flag": "^3.0.0"
}
}
}
},
@@ -17879,56 +17737,24 @@
"postcss": "^7.0.6"
},
"dependencies": {
"ansi-styles": {
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
"integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
"requires": {
"color-convert": "^1.9.0"
}
},
"chalk": {
"version": "2.4.2",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
"integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
"requires": {
"ansi-styles": "^3.2.1",
"escape-string-regexp": "^1.0.5",
"supports-color": "^5.3.0"
},
"dependencies": {
"supports-color": {
"version": "5.5.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
"integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
"requires": {
"has-flag": "^3.0.0"
}
}
}
"picocolors": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz",
"integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA=="
},
"postcss": {
"version": "7.0.36",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.36.tgz",
"integrity": "sha512-BebJSIUMwJHRH0HAQoxN4u1CN86glsrwsW0q7T+/m44eXOUAxSNdHRkNZPYz5vVUbg17hFgOQDE7fZk7li3pZw==",
"version": "7.0.39",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz",
"integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==",
"requires": {
"chalk": "^2.4.2",
"source-map": "^0.6.1",
"supports-color": "^6.1.0"
"picocolors": "^0.2.1",
"source-map": "^0.6.1"
}
},
"source-map": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
},
"supports-color": {
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz",
"integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==",
"requires": {
"has-flag": "^3.0.0"
}
}
}
},
@@ -18714,7 +18540,8 @@
"semver": {
"version": "6.3.0",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
"integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw=="
"integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
"dev": true
},
"send": {
"version": "0.18.0",
@@ -20418,8 +20245,7 @@
"yallist": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
"dev": true
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
},
"yaml": {
"version": "1.10.2",
+3 -3
View File
@@ -24,7 +24,7 @@
"vue-template-compiler": "2.4.4"
},
"dependencies": {
"@fortawesome/fontawesome-free": "^6.2.0",
"@fortawesome/fontawesome-free": "^6.2.1",
"acorn": "^8.8.0",
"acorn-import-assertions": "^1.8.0",
"admin-lte": "^2.4.18",
@@ -36,7 +36,7 @@
"bootstrap-less": "^3.3.8",
"bootstrap-table": "1.20.2",
"chart.js": "^2.9.4",
"css-loader": "^3.6.0",
"css-loader": "^4.0.0",
"ekko-lightbox": "^5.1.1",
"icheck": "^1.0.2",
"imagemin": "^8.0.1",
@@ -47,7 +47,7 @@
"jquery.iframe-transport": "^1.0.0",
"jspdf-autotable": "^3.5.24",
"less": "^4.1.2",
"less-loader": "^5.0.0",
"less-loader": "^5.0",
"list.js": "^1.5.0",
"papaparse": "^4.3.3",
"select2": "4.0.13",
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long

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