Compare commits

...

762 Commits

Author SHA1 Message Date
snipe
adec86f1ef Changed the method name, since it will return an entire collection
Signed-off-by: snipe <snipe@snipe.net>
2023-01-10 12:18:27 -08:00
snipe
46e17f7e77 Adds the filename for the acceptance PDF to asset payload
Signed-off-by: snipe <snipe@snipe.net>
2023-01-10 12:12:08 -08:00
snipe
772d3c1da9 Removed duplicate validation
Signed-off-by: snipe <snipe@snipe.net>
2023-01-10 12:12:04 -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
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
snipe
23cbee9493 Merge remote-tracking branch 'origin/develop'
Signed-off-by: snipe <snipe@snipe.net>

# Conflicts:
#	config/version.php
2022-11-03 14:18:55 -07:00
snipe
7c21158680 Bumped version
Signed-off-by: snipe <snipe@snipe.net>
2022-11-03 14:18:13 -07:00
snipe
30f4af3ac2 Merge remote-tracking branch 'origin/develop' 2022-11-03 14:14:23 -07:00
snipe
b1fa50cde2 Merge pull request #12067 from snipe/fixes/modelfile_image_path
Fixed model file image path/variable
2022-11-03 14:13:54 -07:00
snipe
236684ec92 Fixed model file image path/variable
Signed-off-by: snipe <snipe@snipe.net>
2022-11-03 14:12:49 -07:00
snipe
c45e777324 Merge remote-tracking branch 'origin/develop' 2022-11-03 14:10:08 -07:00
snipe
53499b1e29 Merge pull request #12066 from snipe/fixes/small_uploads_fixes
Fixed - small uploads fixes
2022-11-03 14:08:52 -07:00
snipe
04b6f023ae Use new upload string
Signed-off-by: snipe <snipe@snipe.net>
2022-11-03 13:57:50 -07:00
snipe
3c7d63c060 Disallow uploads if app is locked
Signed-off-by: snipe <snipe@snipe.net>
2022-11-03 13:52:23 -07:00
snipe
7cb1ca8754 Fixed image path to show preview
Signed-off-by: snipe <snipe@snipe.net>
2022-11-03 13:51:48 -07:00
snipe
52e33a8b0e Merge remote-tracking branch 'origin/develop' 2022-11-03 13:27:21 -07:00
snipe
0f5fbb6a04 Re-added gitignore
Signed-off-by: snipe <snipe@snipe.net>
2022-11-03 13:27:06 -07:00
snipe
6d5ace0458 Merge pull request #12049 from uberbrady/improve_scim_externalid_support
Fixed writes to the `externalId` from SCIM
2022-11-02 15:43:55 -07:00
snipe
6f14355cbc Merge pull request #12060 from snipe/features/added_accessories_file_uploads
Added accessories file uploads
2022-11-01 19:51:38 -07:00
snipe
eb81c290dc Accessory file upload
Signed-off-by: snipe <snipe@snipe.net>
2022-11-01 19:50:39 -07:00
snipe
2f9e097854 Merge pull request #12059 from snipe/fixes/consumables_files_translations
Use the generic file uploads strings
2022-11-01 19:32:35 -07:00
snipe
97aeb1fcec Use the generic file uploads strings
Signed-off-by: snipe <snipe@snipe.net>
2022-11-01 19:31:23 -07:00
snipe
e6d259bac0 Merge pull request #12058 from snipe/features/added_uploads_to_components
Added uploads to components
2022-11-01 19:30:17 -07:00
snipe
8887d40b86 Added gitignore
Signed-off-by: snipe <snipe@snipe.net>
2022-11-01 19:29:21 -07:00
snipe
3d8e0b707e Fixed component file route controller names
Signed-off-by: snipe <snipe@snipe.net>
2022-11-01 19:29:13 -07:00
snipe
71a7176a6e Updated component blade
Signed-off-by: snipe <snipe@snipe.net>
2022-11-01 19:28:57 -07:00
snipe
def89bfa0c Added some generic file translations
Signed-off-by: snipe <snipe@snipe.net>
2022-11-01 19:28:49 -07:00
snipe
f1cb7ee410 Fixed some translations
Signed-off-by: snipe <snipe@snipe.net>
2022-11-01 19:28:39 -07:00
snipe
84c0f50266 Added ComponentFilesController
Signed-off-by: snipe <snipe@snipe.net>
2022-11-01 19:10:04 -07:00
snipe
f51b312843 Added component routes for uploads
Signed-off-by: snipe <snipe@snipe.net>
2022-11-01 19:09:51 -07:00
snipe
3d3a4b02fc Added helper method for uploads
Signed-off-by: snipe <snipe@snipe.net>
2022-11-01 19:09:34 -07:00
snipe
276f534ded Updated permissions
Signed-off-by: snipe <snipe@snipe.net>
2022-11-01 19:09:21 -07:00
snipe
1d47d9e52b Merge pull request #12057 from snipe/features/add_uploads_to_components
Added uploads to components
2022-11-01 19:07:42 -07:00
snipe
2106b64da6 Fixed some layout issues
Signed-off-by: snipe <snipe@snipe.net>
2022-11-01 19:06:49 -07:00
snipe
fa79a6c15f Skip storage:: facade on missing images
Signed-off-by: snipe <snipe@snipe.net>
2022-11-01 18:19:13 -07:00
snipe
761da534f3 Updated consumables UI to allow uploads and display files
Signed-off-by: snipe <snipe@snipe.net>
2022-11-01 17:53:08 -07:00
snipe
b362951c95 Added consumables permissions
Signed-off-by: snipe <snipe@snipe.net>
2022-11-01 17:52:45 -07:00
snipe
25f69a7bd2 Added consumable methods for uploads
Signed-off-by: snipe <snipe@snipe.net>
2022-11-01 17:52:28 -07:00
snipe
f6a6478804 Added consumable uploads gitignore
Signed-off-by: snipe <snipe@snipe.net>
2022-11-01 17:52:04 -07:00
snipe
3282702c73 Added consumables upload routes
Signed-off-by: snipe <snipe@snipe.net>
2022-11-01 17:51:53 -07:00
Brady Wetherington
4e5c878b73 Needed to fix the way we write externalId from SCIM 2022-10-31 19:15:08 -07:00
snipe
5711706367 Merge remote-tracking branch 'origin/develop' 2022-10-31 12:17:06 -07:00
snipe
a930661150 Check for valid category
Signed-off-by: snipe <snipe@snipe.net>
2022-10-31 12:16:39 -07:00
snipe
7cb4740359 Merge pull request #11766 from snipe/fixes/wtf_method_names_derp
Fixed (?) method name?
2022-10-26 17:39:11 -07:00
snipe
9f8f028484 Merge remote-tracking branch 'origin/develop' 2022-10-26 12:21:20 -07:00
snipe
d0b9e956df Merge pull request #12042 from snipe/fixes/added_missing_hashed_password_string
Corrected string for invalid current password
2022-10-26 12:20:35 -07:00
snipe
c1eee2cc72 Corrected string for invalid current password
Signed-off-by: snipe <snipe@snipe.net>
2022-10-26 12:18:29 -07:00
snipe
f32183d51b Merge remote-tracking branch 'origin/develop' 2022-10-26 10:58:52 -07:00
snipe
73f30c0a41 Merge pull request #12041 from snipe/features/reflect_status_label_color_in_sidenav
Fixed #12009 - Added ability to reflect color in sidenav if one is given
2022-10-26 10:58:19 -07:00
snipe
c233d7fb1c Removed extra spaces
Signed-off-by: snipe <snipe@snipe.net>
2022-10-26 10:51:06 -07:00
snipe
dea0fcefbd Reflect color in sidenav if one is given
Signed-off-by: snipe <snipe@snipe.net>
2022-10-26 10:48:42 -07:00
snipe
38678d4646 Bumped hash
Signed-off-by: snipe <snipe@snipe.net>

# Conflicts:
#	config/version.php
2022-10-26 09:50:44 -07:00
snipe
476a5cbc02 Bumped hash
Signed-off-by: snipe <snipe@snipe.net>
2022-10-26 09:49:50 -07:00
snipe
bc4c6abe06 Merge remote-tracking branch 'origin/develop' 2022-10-26 09:43:33 -07:00
snipe
73f61ce032 Merge pull request #12040 from snipe/fixes/locations_asset_count
Renamed column back to assets_count for legacy
2022-10-26 09:43:01 -07:00
snipe
12c7223bcd Renamed column back to assets_count for legacy
Signed-off-by: snipe <snipe@snipe.net>
2022-10-26 09:39:03 -07:00
snipe
de856d6045 Merge remote-tracking branch 'origin/develop' 2022-10-26 00:57:17 -07:00
snipe
b7efb58733 Merge pull request #12038 from snipe/fixes/clear_expected_checkin_on_checkin_action
Added - set `expected_checkin` to `null` on user bulk checkin and delete
2022-10-26 00:56:43 -07:00
snipe
28b0d8cf0f Null expected_checkin on user bulk checkin and delete
Signed-off-by: snipe <snipe@snipe.net>
2022-10-26 00:54:37 -07:00
snipe
88ae8858e8 Merge remote-tracking branch 'origin/develop' 2022-10-26 00:32:39 -07:00
snipe
0bc0a116aa Merge pull request #12035 from snipe/features/added_new_tab_to_locations
Features/added new tab to locations
2022-10-26 00:32:07 -07:00
snipe
e670ffe349 Added Assets Assigned to tab
Signed-off-by: snipe <snipe@snipe.net>
2022-10-26 00:16:06 -07:00
snipe
a94f1c4a64 Cleaned up and added comments
Signed-off-by: snipe <snipe@snipe.net>
2022-10-26 00:15:52 -07:00
snipe
b503b672ba Merge pull request #11951 from Godmartinz/AccessKey_shortcuts
adds shortcuts for listing, creating, and saving
2022-10-25 15:53:57 -07:00
snipe
72296eea5c Merge remote-tracking branch 'origin/develop' 2022-10-25 15:46:26 -07:00
snipe
bc023a2566 Add @eltociear as a contributor 2022-10-25 15:46:07 -07:00
snipe
2f7e22be1e Fixed all-contributors type
Signed-off-by: snipe <snipe@snipe.net>
2022-10-25 15:46:07 -07:00
snipe
9409965239 Merge pull request #11928 from eltociear/patch-1
Fix typo in Dockerfile.fpm-alpine
2022-10-25 15:45:42 -07:00
snipe
f54c92ade2 Merge pull request #12028 from StarlessNights/feature/add-memcached-php-extensions-to-docker-images
Fixed #12027: Add memcached php extensions to docker images
2022-10-25 15:42:15 -07:00
snipe
b1fb70cb7b Merge remote-tracking branch 'origin/develop' 2022-10-25 15:35:04 -07:00
snipe
9e08936cbc Merge pull request #12030 from uberbrady/scim_externalid_support
Added externalId support to SCIM integration
2022-10-25 14:51:52 -07:00
Brady Wetherington
cd385e0865 Set scim_externalid to nullable, default null 2022-10-25 14:38:19 -07:00
Brady Wetherington
1e3281c76c Add externalId support to SCIM integration 2022-10-25 14:19:01 -07:00
Iisakki Jaakkola
af4d62759f Added php memcached extension to docker Alpine image. 2022-10-25 16:16:25 +03:00
Iisakki Jaakkola
9452973845 Added php memcached extension to the docker image. 2022-10-25 16:16:25 +03:00
snipe
8e23787888 Merge remote-tracking branch 'origin/develop' 2022-10-21 17:44:04 -07:00
snipe
3b16157d6b Fixed typo
Signed-off-by: snipe <snipe@snipe.net>
2022-10-21 17:43:53 -07:00
snipe
3ec3d38c9f Merge remote-tracking branch 'origin/develop' 2022-10-21 17:01:00 -07:00
snipe
ae430959a4 Merge pull request #12015 from snipe/fixes/revert_processing_button
Changed button icon for importer
2022-10-21 17:00:22 -07:00
snipe
85a85082b7 Changed button icon for importer
Signed-off-by: snipe <snipe@snipe.net>
2022-10-21 16:59:19 -07:00
snipe
5acb493efd Merge pull request #12008 from snipe/features/add_default_loc_to_location_view
Added default tab to locations
2022-10-21 16:43:24 -07:00
snipe
515b14a001 Updated JS to better handle input IDs
Signed-off-by: snipe <snipe@snipe.net>
2022-10-20 19:21:09 -07:00
snipe
4eed2baa31 Added default tab to locations
Signed-off-by: snipe <snipe@snipe.net>
2022-10-20 19:06:58 -07:00
snipe
453f2c3b0e Merge pull request #12006 from uberbrady/ldap_manager_cache
Added cache manager lookups in LDAP for performance boost
2022-10-20 17:06:23 -07:00
Brady Wetherington
bc78d341a0 Caches manager lookups in LDAP for performance boost 2022-10-20 16:52:40 -07:00
snipe
da579a302c Merge remote-tracking branch 'origin/develop' 2022-10-19 19:09:34 -07:00
snipe
edf191b724 Merge pull request #11995 from uberbrady/ldap_manager_fix
Fixed: Okta LDAP Manager Attribute - Try to better-handle LDAP Manager settings
2022-10-19 19:04:10 -07:00
Brady Wetherington
12d86bd6e2 Erroneous line-break removal - re-add 2022-10-19 19:01:52 -07:00
Brady Wetherington
c4f11de90d Remove incorrect comment. 2022-10-19 18:49:19 -07:00
Brady Wetherington
8fb61cf5f8 Try to better handle LDAP Manager settings that don't line up with what we expect 2022-10-19 18:36:16 -07: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
snipe
4e83b06d71 Merge remote-tracking branch 'origin/develop' 2022-10-18 15:00:51 -07:00
snipe
23e613f903 Fixed kit parse error on model edit
Signed-off-by: snipe <snipe@snipe.net>
2022-10-18 15:00:33 -07:00
snipe
f1c82ca732 Merge pull request #11988 from snipe/fixes/wrong_icons_for_mobile_location_view
Fixed wrong icons for mobile view for locations listing
2022-10-17 20:14:01 -07:00
snipe
2543fa6b98 Fixed user icon for tab
Signed-off-by: snipe <snipe@snipe.net>
2022-10-17 20:04:42 -07:00
snipe
7c34652da0 Fixed incorrect icons for mobile view on location tabs
Signed-off-by: snipe <snipe@snipe.net>
2022-10-17 20:02:27 -07:00
snipe
aa3f94973f Merge remote-tracking branch 'origin/develop' 2022-10-17 14:45:05 -07:00
snipe
1ec303931a Merge pull request #11986 from Godmartinz/FD31357_depreciation
Fixes the calc of months and fixes typo of the word depreciation
2022-10-17 14:44:46 -07:00
Godfrey M
d359bcb88d adds proper spacing 2022-10-17 13:15:10 -07:00
Godfrey M
28059c878a gets the proper amount of months and fixes typo of the word depreciation 2022-10-17 11:16:29 -07:00
snipe
b7bcfaccc9 Merge pull request #11834 from uberbrady/try_catch_notifications
try/catch wrap notifications on checkin/checkout
2022-10-13 14:20:22 -07:00
snipe
f4a3f896bd Merge remote-tracking branch 'origin/develop'
Signed-off-by: snipe <snipe@snipe.net>

# Conflicts:
#	config/version.php
2022-10-13 13:20:35 -07:00
snipe
0303df4b25 Bumped version
Signed-off-by: snipe <snipe@snipe.net>
2022-10-13 13:19:51 -07:00
snipe
9151868839 Merge remote-tracking branch 'origin/develop' 2022-10-13 13:06:52 -07:00
snipe
8c6aaec9ce Merge pull request #11971 from snipe/localization/new_translations
Added new translations
2022-10-13 13:06:16 -07:00
snipe
fb228d6ded Updated strings
Signed-off-by: snipe <snipe@snipe.net>
2022-10-13 12:57:10 -07:00
snipe
1360ce90a5 Updated strings
Signed-off-by: snipe <snipe@snipe.net>
2022-10-13 12:52:45 -07:00
snipe
3549afe157 Added strings
Signed-off-by: snipe <snipe@snipe.net>
2022-10-13 12:43:24 -07:00
snipe
cfb780b20b Remove unused files
Signed-off-by: snipe <snipe@snipe.net>
2022-10-13 12:39:10 -07:00
snipe
eb9f17122e Updated strings
Signed-off-by: snipe <snipe@snipe.net>
2022-10-13 12:21:09 -07:00
snipe
2ef45afb2b Removed extraneous files
Signed-off-by: snipe <snipe@snipe.net>
2022-10-13 12:18:57 -07:00
snipe
c8baf4c6ad Updated prod assets
Signed-off-by: snipe <snipe@snipe.net>
2022-10-12 16:25:43 -07:00
snipe
0b20cf6d70 Merge remote-tracking branch 'origin/develop' 2022-10-12 16:24:46 -07:00
snipe
ecc6bd8a24 Updated dev assets
Signed-off-by: snipe <snipe@snipe.net>
2022-10-12 16:24:31 -07:00
snipe
3c9c89355e Aaaand master again
Signed-off-by: snipe <snipe@snipe.net>
2022-10-12 16:01:55 -07:00
snipe
43479efed0 Merge remote-tracking branch 'origin/develop' 2022-10-12 16:01:17 -07:00
snipe
80279a95ae Merge pull request #11964 from snipe/fixes/audit_admin_presenting
Use admin ID for audit log notification
2022-10-12 16:00:50 -07:00
snipe
ac055c01dc Use admin ID for audit log notification
Signed-off-by: snipe <snipe@snipe.net>
2022-10-12 15:59:43 -07:00
snipe
5ff72420a6 Set branch back to develop
I hads to switch branches because the automated GH action script always targets masterb

Signed-off-by: snipe <snipe@snipe.net>
2022-10-12 11:00:06 -07:00
snipe
55b33c1042 Merge pull request #11944 from snipe/dependabot/github_actions/actions/checkout-3.1.0
Bump actions/checkout from 2 to 3.1.0
2022-10-12 10:59:21 -07:00
snipe
a499a92bb7 Added @nh314 as a contributor
Signed-off-by: snipe <snipe@snipe.net>
2022-10-12 10:57:50 -07:00
snipe
e7ae7742b0 Merge pull request #11949 from nh314/Remove-required-mark
Remove required mark
2022-10-12 10:55:49 -07:00
snipe
98f2e0271b Merge pull request #11942 from nh314/develop
Correct comparison logic
2022-10-12 10:55:29 -07:00
snipe
e721665fd8 Merge remote-tracking branch 'origin/develop' 2022-10-12 10:53:42 -07:00
snipe
cd43fc50fb Merge pull request #11960 from snipe/fixes/better_validation_for_ldap_filter
Sets nullable attribute on validation
2022-10-12 10:53:08 -07:00
snipe
06803092c5 Merge pull request #11952 from snipe/features/clearer_activated_helptext
Added clearer LDAP activated helptext
2022-10-12 10:52:56 -07:00
snipe
0312ecf09d Sets nullable attribute on validation
Signed-off-by: snipe <snipe@snipe.net>
2022-10-12 10:30:47 -07:00
snipe
0ed50f4e58 Merge remote-tracking branch 'origin/develop' 2022-10-12 10:22:48 -07:00
snipe
3f105cd3b2 Merge pull request #11959 from inietov/fixes/depreciation_date
Fixed Depreciation date diff readable precision
2022-10-12 10:21:37 -07:00
Ivan Nieto Vivanco
ab0c5bcd9d Add precision parameter to the diffForHumans() Carbon function to report 2022-10-12 12:16:13 -05:00
snipe
5ba01728d9 More text tweaking
Signed-off-by: snipe <snipe@snipe.net>
2022-10-11 12:51:25 -07:00
snipe
ae0eb378e4 Additional clarification
Signed-off-by: snipe <snipe@snipe.net>
2022-10-11 12:43:54 -07:00
snipe
ad8a2387f0 Updated help text to be more clear
Signed-off-by: snipe <snipe@snipe.net>
2022-10-11 12:38:37 -07:00
Godfrey M
4fa01350c3 adds shortcuts for listing, creating, and saving 2022-10-11 12:00:15 -07:00
Phan Nguyen
d3161fad02 Remove required mark
Because it actually not required by model.
2022-10-11 15:49:56 +07:00
dependabot[bot]
36eb51b52f Bump actions/checkout from 2 to 3.1.0
Bumps [actions/checkout](https://github.com/actions/checkout) from 2 to 3.1.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/v2...v3.1.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-10-10 08:36:34 +00:00
Phan Nguyen
8ff109e9da Correct comparison logic
Comparison operator should be greater than or equal
2022-10-08 12:54:15 +07:00
snipe
15da3b831d Merge pull request #11937 from Godmartinz/gh11868_sidebar_unclickable
Fixes the margin top adjustment for desktop
2022-10-06 10:43:27 -07:00
Godfrey M
0c6441ebed removes the margin top adjustment for desktop 2022-10-06 10:35:28 -07:00
snipe
fbfc9d123c Merge remote-tracking branch 'origin/develop' 2022-10-06 09:26:07 -07:00
snipe
cd942196cc Merge pull request #11933 from inietov/fixes/500_creating_new_user_undefined_variable_item
Fixed Error 500 undefined variable item creating a new user.
2022-10-06 09:07:18 -07:00
Ivan Nieto Vivanco
f1edbc9810 Send item variable that the datepicker needs 2022-10-06 09:15:00 -05:00
Ikko Ashimine
66e64cb136 Fix typo in Dockerfile.fpm-alpine
enviroment -> environment
2022-10-06 11:53:13 +09:00
snipe
1ef3eb94db Merge remote-tracking branch 'origin/develop' 2022-10-05 17:55:33 -07:00
snipe
25e4b7d59d Merge pull request #11927 from uberbrady/use_improved_scim
Use the new scim-trace feature from our fork of laravel-scim-server lib
2022-10-05 17:53:20 -07:00
Brady Wetherington
9605dec22a Use the new scim-trace feature from our fork of laravel-scim-server lib 2022-10-05 17:43:59 -07:00
snipe
ca937667b4 Indented divs per @uberbrady
Signed-off-by: snipe <snipe@snipe.net>
2022-10-05 17:21:39 -07:00
snipe
e9c61903f1 Merge pull request #11926 from snipe/features/add_start_and_term_dates_to_users
Added start and end dates to users
2022-10-05 17:20:37 -07:00
snipe
14b7319b63 Added start/end to sortable columns
Signed-off-by: snipe <snipe@snipe.net>
2022-10-05 17:07:07 -07:00
snipe
9d641573b5 Make the APU return null instead of blank
Signed-off-by: snipe <snipe@snipe.net>
2022-10-05 17:01:04 -07:00
snipe
3605aa8f5a Added clear button to generic datepicker and made it wider
Signed-off-by: snipe <snipe@snipe.net>
2022-10-05 16:59:06 -07:00
snipe
0817308822 Added start/end to edit/view screens
Signed-off-by: snipe <snipe@snipe.net>
2022-10-05 16:58:49 -07:00
snipe
bdfac1a345 Added start/end to the users API
Signed-off-by: snipe <snipe@snipe.net>
2022-10-05 16:58:37 -07:00
snipe
f7a9be92ca Store data for start and end
Signed-off-by: snipe <snipe@snipe.net>
2022-10-05 16:58:26 -07:00
snipe
56ba8a7e24 Added API select fields and filters
Signed-off-by: snipe <snipe@snipe.net>
2022-10-05 16:58:16 -07:00
snipe
cf62761d18 Added date casting and fillable to models
Signed-off-by: snipe <snipe@snipe.net>
2022-10-05 16:57:59 -07:00
snipe
d23e178c62 Adde language strings
Signed-off-by: snipe <snipe@snipe.net>
2022-10-05 16:56:10 -07:00
snipe
7353ecd388 Added start_date and end_date migration to users table
Signed-off-by: snipe <snipe@snipe.net>
2022-10-05 16:55:59 -07:00
snipe
18663c2599 Merge pull request #11925 from inietov/fixes/checkbox_customfields_comma_issues
Fixed #11710 - Validation of checkbox data with multiple values
2022-10-05 16:48:32 -07:00
Ivan Nieto Vivanco
5b8e0b3af1 Use a regex (gulp) to admit ',' (comma) and ', '(comma plus space) as customfields checkbox value delimiter 2022-10-05 18:40:07 -05:00
snipe
dab83091d2 Merge remote-tracking branch 'origin/develop' 2022-10-05 12:12:27 -07:00
snipe
4c0be7ec98 Merge pull request #11924 from snipe/features/autoglossonym_locales
Added autoglossonyms for locales and translations for countries
2022-10-05 12:09:29 -07:00
snipe
018f71a157 Switched to translations for better autoglossonym support
Signed-off-by: snipe <snipe@snipe.net>
2022-10-05 11:46:42 -07:00
snipe
9f03f0f6f6 Updated link
Signed-off-by: snipe <snipe@snipe.net>
2022-10-04 23:39:47 -07:00
snipe
da40c0ad48 Dev assets
Signed-off-by: snipe <snipe@snipe.net>
2022-10-04 18:09:18 -07:00
snipe
c70c8ce856 Merge pull request #11916 from Godmartinz/gh11868_sidebar_unclickable
fixes mobile views and clickability of sidebar menu
2022-10-04 18:07:02 -07:00
snipe
fe49ac79d1 Updated all contributors
Signed-off-by: snipe <snipe@snipe.net>
2022-10-04 18:06:09 -07:00
snipe
687a764fc1 Dev to master in version.php
Signed-off-by: snipe <snipe@snipe.net>
2022-10-04 17:53:16 -07:00
snipe
81be84568e Bumped version
Signed-off-by: snipe <snipe@snipe.net>
2022-10-04 17:52:24 -07:00
snipe
61fa0bda4d Merge pull request #11917 from snipe/updates/updated_language_strings
Updated lnaguage strings
2022-10-04 17:49:27 -07:00
snipe
81d2a3acda Updated lnaguage strings
Signed-off-by: snipe <snipe@snipe.net>
2022-10-04 17:48:43 -07:00
snipe
931d81d825 Merge pull request #11908 from snipe/features/nicer_view_assets_ui_for_regular_users
Overhaul of UI for unprivileged users
2022-10-04 16:41:44 -07:00
snipe
bcebc1e33b Stylistic refactoring
Signed-off-by: snipe <snipe@snipe.net>
2022-10-04 16:37:33 -07:00
snipe
ba0483b33e Phrasing!
Signed-off-by: snipe <snipe@snipe.net>
2022-10-04 16:21:10 -07:00
snipe
97b9f96030 Added nag alert for unaccepted assets
Signed-off-by: snipe <snipe@snipe.net>
2022-10-04 16:16:21 -07:00
snipe
891b5b2882 Added routes, language
Signed-off-by: snipe <snipe@snipe.net>
2022-10-04 15:45:25 -07:00
Godfrey M
e21660ae05 off by a pixel 2022-10-04 12:11:37 -07:00
Godfrey M
53392d6069 fixes mobile views and clickability of sidebar menu 2022-10-04 12:01:13 -07:00
snipe
3469e49470 First UI overhaul
Signed-off-by: snipe <snipe@snipe.net>
2022-10-03 21:28:22 -07:00
snipe
e9224f094e Merge pull request #11906 from inietov/fixes/server_error_downloading_unaccepted_assets
Fixed error 500 when downloading asset acceptance report. [sc-19555]
2022-10-03 16:40:28 -07:00
Ivan Nieto Vivanco
25c10c3819 Filter non-asset items from download unaccepted assets report 2022-10-03 18:12:30 -05:00
snipe
b9419c7454 Merge pull request #11901 from snipe/security/escape_formats_in_csv
Use `EscapeFormula()` in CSV export
2022-09-30 11:59:11 -07:00
snipe
b07c4caa37 Extra whitespace
Signed-off-by: snipe <snipe@snipe.net>
2022-09-30 11:47:27 -07:00
snipe
aa52bc6c6a Added Vautia
Signed-off-by: snipe <snipe@snipe.net>
2022-09-30 11:47:20 -07:00
snipe
5a7e35c0e8 Made a conditional escape according to .env
Signed-off-by: snipe <snipe@snipe.net>
2022-09-30 09:48:43 -07:00
snipe
bae200edd7 Use EscapeFormula() in CSV export
Signed-off-by: snipe <snipe@snipe.net>
2022-09-30 09:29:17 -07:00
snipe
2fd197c2db Merge pull request #11896 from snipe/fixes/500_on_depreciation
Fixed depreciation API call
2022-09-29 17:09:39 -07:00
snipe
36484d50ef Fixed depreciation API call
Signed-off-by: snipe <snipe@snipe.net>
2022-09-29 17:07:42 -07:00
snipe
2b7c8cf82b Merge pull request #11895 from uberbrady/switch_dashboard_piechart_to_percent
Modified dashboard tooltips to add percentage as well as count
2022-09-29 14:11:16 -07:00
Brady Wetherington
0424308863 Modified dashboard tooltips to add percentage as well as count 2022-09-29 13:46:56 -07:00
snipe
78580136f6 Merge pull request #11894 from uberbrady/improve_piechart_labels_legends
Added counts to Dashboard Pie Chart legends and tooltips
2022-09-29 13:27:28 -07:00
Brady Wetherington
420c216973 Added counts to Dashboard Pie Chart legends and tooltips 2022-09-29 13:20:58 -07:00
snipe
9c6fa18454 Merge pull request #11893 from snipe/features/switch_dash_pie_to_status_type
Fixed #11521 - Add option to switch to using status meta from status label name
2022-09-29 13:02:28 -07:00
snipe
70c766e8b3 Added setting to choose dashboard type
Signed-off-by: snipe <snipe@snipe.net>
2022-09-29 04:16:46 -07:00
snipe
0b2ce7be07 Fixed #11521 - switch to using status meta from status label name
Signed-off-by: snipe <snipe@snipe.net>
2022-09-29 03:48:58 -07:00
snipe
3d48dd19cb Merge pull request #11890 from snipe/fixes/statuslabels_assetlist
Fixed #11889 - API route for status labels asset listing
2022-09-29 00:51:25 -07:00
snipe
08bab4f101 Fixed #11889 - API route for status labels asset listing
Signed-off-by: snipe <snipe@snipe.net>
2022-09-29 00:50:07 -07:00
snipe
95b49f8deb Merge pull request #11886 from sunflowerbofh/tmp-replace-patchwork-utf8
Tmp replace patchwork utf8
2022-09-28 10:32:07 -07:00
Katharina Drexel
4f5d536e32 Fixed: #11871 Replacing (deprecated) patchwork/utf8 by polyfill/mbstring. 2022-09-28 14:52:02 +02:00
snipe
9dbc5070f8 Remove phplint (for now)
Signed-off-by: snipe <snipe@snipe.net>
2022-09-27 16:47:09 -07:00
snipe
055a2f827f Merge pull request #11872 from sunflowerbofh/tmp-replace-patchwork-utf8
Fixed #11871 Replacing (deprecated) patchwork/utf8 by polyfill/mbstring.
2022-09-27 16:46:12 -07:00
snipe
8d3fe423e1 Merge pull request #11671 from chartjes/ch-fix-tests
Fixed unit test suite that was not running, added working browser test
2022-09-27 16:20:56 -07:00
snipe
1377725a97 Dev assets
Signed-off-by: snipe <snipe@snipe.net>
2022-09-27 14:53:47 -07:00
snipe
58ccfe9226 Updated prod assets
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-blue-dark.css
#	public/css/dist/skins/skin-blue-dark.min.css
#	public/css/dist/skins/skin-green-dark.css
#	public/css/dist/skins/skin-green-dark.min.css
#	public/css/dist/skins/skin-orange-dark.css
#	public/css/dist/skins/skin-orange-dark.min.css
#	public/css/dist/skins/skin-purple-dark.css
#	public/css/dist/skins/skin-purple-dark.min.css
#	public/css/dist/skins/skin-red-dark.css
#	public/css/dist/skins/skin-red-dark.min.css
#	public/css/dist/skins/skin-yellow-dark.css
#	public/css/dist/skins/skin-yellow-dark.min.css
#	public/mix-manifest.json
2022-09-27 14:51:19 -07:00
snipe
05ac9f4a68 Updated dev assets
Signed-off-by: snipe <snipe@snipe.net>
2022-09-27 14:47:54 -07:00
snipe
0889cd61cf Updated skins
Signed-off-by: snipe <snipe@snipe.net>
2022-09-27 14:47:09 -07:00
snipe
8168ca4074 Merge pull request #11853 from Godmartinz/ldap_test_results_color
Fixes the color choice for the ldap_test_results
2022-09-27 14:46:46 -07:00
snipe
de399a9f8f Merge remote-tracking branch 'origin/develop'
Signed-off-by: snipe <snipe@snipe.net>

# Conflicts:
#	public/css/dist/all.css
#	public/js/build/app.js
#	public/js/dist/all.js
#	public/mix-manifest.json
2022-09-27 14:46:30 -07:00
snipe
af150f0192 Add @BasO12 as a contributor 2022-09-27 14:44:32 -07:00
snipe
c194c8a0c8 Merge pull request #11764 from BasO12/master
Added notes to audit mail notification
2022-09-27 14:43:50 -07:00
snipe
a7b83fc531 Merge pull request #11854 from inietov/fixes/location_issue_during_import
Fixed #11847 404 error during Import if a checkout type of location is specified and no checkout location is passed
2022-09-27 14:34:26 -07:00
snipe
ef22da622d Merge pull request #11870 from snipe/dependabot/github_actions/codacy/codacy-analysis-cli-action-4.2.0
Bump codacy/codacy-analysis-cli-action from 4.1.0 to 4.2.0
2022-09-27 14:33:53 -07:00
dependabot[bot]
8443796cbe Bump codacy/codacy-analysis-cli-action from 4.1.0 to 4.2.0
Bumps [codacy/codacy-analysis-cli-action](https://github.com/codacy/codacy-analysis-cli-action) from 4.1.0 to 4.2.0.
- [Release notes](https://github.com/codacy/codacy-analysis-cli-action/releases)
- [Commits](https://github.com/codacy/codacy-analysis-cli-action/compare/v4.1.0...v4.2.0)

---
updated-dependencies:
- dependency-name: codacy/codacy-analysis-cli-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-09-27 21:33:19 +00:00
snipe
ac996a771c Merge pull request #11882 from snipe/security/upgraded_fontawesome
Upgraded fontawesome
2022-09-27 14:27:22 -07:00
snipe
942eaac2ee Upgraded fontawesome
Signed-off-by: snipe <snipe@snipe.net>
2022-09-27 14:25:44 -07:00
snipe
ada2a2cd43 Merge pull request #11878 from inietov/fixes/asset_importer_duplicate_fields
Delete duplicate fields from the importer dropdown menu [sc-19547]
2022-09-27 14:21:30 -07:00
Ivan Nieto Vivanco
06ba9356ca Delete another set of duplicates 2022-09-26 18:57:35 -05:00
Ivan Nieto Vivanco
e034f7b674 Delete another duplicate that somehow has survived 2022-09-26 18:56:24 -05:00
Ivan Nieto Vivanco
4d14243f57 Delete duplicate fields from the importer dropdown menu 2022-09-26 18:51:13 -05:00
snipe
88a371082d Merge remote-tracking branch 'origin/develop' 2022-09-26 16:29:21 -07:00
snipe
ee7e26ae8d Merge pull request #11877 from snipe/features/use_built_in_clear_on_datepicker
Use BS datepicker’s built in clear button
2022-09-26 16:23:27 -07:00
snipe
9d93c72534 Use BS datepicker’s built in clear button
Signed-off-by: snipe <snipe@snipe.net>
2022-09-26 14:34:35 -07:00
snipe
44b72e0f5f Merge remote-tracking branch 'origin/develop' 2022-09-26 13:49:48 -07:00
snipe
d91d226652 Merge pull request #11857 from inietov/fixes/throw_exception_instead_of_redirect_when_no_available_licenseseats
Fixed #11827 Throw exception when there are no available seats for checkout.
2022-09-26 13:43:57 -07:00
snipe
091ef62cbe Merge pull request #11856 from inietov/fixes/purchase_date_not_nullable
Fixed Purchase date "readonly" value makes purchase date unable to be nulled in update form [sc-19540]
2022-09-26 13:38:24 -07:00
Katharina Drexel
8316a4eb92 Fixed: #11871 Replacing (deprecated) patchwork/utf8 by polyfill/mbstring. 2022-09-26 12:06:06 +02:00
snipe
b4518677bd Merge pull request #11762 from geo-chen/master
correcting default mysql port from 3309 to 3306
2022-09-22 15:12:11 -07:00
Ivan Nieto Vivanco
23cf556a8b Adds cursor:pointer to indicate a clickable link 2022-09-20 22:24:52 -05:00
Ivan Nieto Vivanco
c0f83a7927 Delete not necessary conditional 2022-09-20 19:02:01 -05:00
Ivan Nieto Vivanco
5a1062f0f4 Delete debugging symbols (just kidding, it's just a dd() function) 2022-09-20 18:58:31 -05:00
Ivan Nieto Vivanco
c32676596c Redirect correctly if not enough license seats exists to be checkout 2022-09-20 18:55:53 -05:00
Ivan Nieto Vivanco
f75917d34d Add a link used to clear the purchase date input 2022-09-20 17:53:55 -05:00
Godfrey M
c55f2d5417 corrects color for query and results of ldap sync test 2022-09-20 10:35:55 -07:00
Ivan Nieto Vivanco
e267f5491a Adds a check for empty location values on import 2022-09-19 19:05:48 -05:00
Godfrey M
571ce5b741 corrects the color choice for the ldap_test_results 2022-09-19 11:59:02 -07:00
snipe
733b0750a2 Merge remote-tracking branch 'origin/develop' 2022-09-16 14:20:25 -07:00
snipe
9369165007 Merge pull request #11842 from snipe/security/license_file_access
Check for `licenses.files` permissions
2022-09-16 14:19:37 -07:00
snipe
f75d348dc0 Fixed license policy method
Signed-off-by: snipe <snipe@snipe.net>
2022-09-16 14:06:46 -07:00
snipe
dcab1381e7 Check for licenses.files permissions
Signed-off-by: snipe <snipe@snipe.net>
2022-09-16 14:00:27 -07:00
snipe
0924d2144b Merge remote-tracking branch 'origin/develop'
Signed-off-by: snipe <snipe@snipe.net>

# Conflicts:
#	public/css/build/app.css
#	public/css/build/overrides.css
#	public/css/dist/all.css
#	public/mix-manifest.json
2022-09-15 21:47:14 -07:00
snipe
9cae4f1d1b Merge pull request #11838 from snipe/features/larger_checkboxes_in_lists
Larger checkbox in lists
2022-09-15 21:44:42 -07:00
snipe
ca70988879 Larger checkbox in lists
Signed-off-by: snipe <snipe@snipe.net>
2022-09-15 21:42:16 -07:00
snipe
421c9baecc # Conflicts:
Signed-off-by: snipe <snipe@snipe.net>
#	public/css/dist/all.css
#	public/css/dist/bootstrap-table.css
#	public/js/dist/bootstrap-table.js
#	public/mix-manifest.json
2022-09-15 20:11:07 -07:00
snipe
5c9e84f663 Bumped hash
Signed-off-by: snipe <snipe@snipe.net>
2022-09-15 20:09:00 -07:00
snipe
fbb5f1445a Merge pull request #11837 from snipe/fixes/disappearing_checkboxes
Downgraded BS Tables
2022-09-15 20:06:42 -07:00
snipe
07e0fec1de Downgraded BS Tables
Signed-off-by: snipe <snipe@snipe.net>
2022-09-15 20:05:29 -07:00
snipe
c6cbf3712e Merge remote-tracking branch 'origin/develop' 2022-09-15 16:22:47 -07:00
snipe
0f777b3168 Merge pull request #11836 from snipe/fixes/500_if_image_is_missing
Fixed 500 error if uploaded file is missing from asset view
2022-09-15 16:21:13 -07:00
snipe
62ad3fad1c Remove DL button if file doesn’t exist
Signed-off-by: snipe <snipe@snipe.net>
2022-09-15 16:11:27 -07:00
snipe
eb1e287c15 Better handle missing files
Signed-off-by: snipe <snipe@snipe.net>
2022-09-15 16:08:13 -07:00
snipe
3eab44f748 Merge pull request #11835 from snipe/fixes/depreciation_when_no_purchase_date
Fixes 500 in depreciation on asset view when no purchase date
2022-09-15 15:52:58 -07:00
snipe
1885e73704 Ignore warning icon if no purchase date
Signed-off-by: snipe <snipe@snipe.net>
2022-09-15 15:42:47 -07:00
snipe
24910433a1 Fixed 500 when depreciation is set but no purchase_date
Signed-off-by: snipe <snipe@snipe.net>
2022-09-15 15:39:47 -07:00
Brady Wetherington
1899e4d1e8 try/catch wrap notifications on checkin/checkout 2022-09-15 13:18:42 -07:00
snipe
481eb2c7f0 Merge remote-tracking branch 'origin/develop' 2022-09-15 11:40:33 -07:00
snipe
51d7f2b97b Merge pull request #11830 from inietov/fixes/default_values_for_checkboxes_unaccessible
Fixed #9801 #11199 Default Values for Checkbox Field Types Unaccessible
2022-09-15 11:28:15 -07:00
Ivan Nieto Vivanco
9b2eda2d70 Save and show the default values properly on custom fields of type checkbox 2022-09-15 11:52:49 -05:00
Ivan Nieto Vivanco
41b75704e3 Removes format when changing to custom fields elements that doesn't need it 2022-09-15 11:21:02 -05:00
Ivan Nieto Vivanco
20220764bb Add possible values for custom fields of type checkbox 2022-09-15 11:18:54 -05:00
snipe
abd2349604 Add @rnelsonee as a contributor 2022-09-14 20:08:39 -07:00
snipe
ac4f91918e Merge pull request #11771 from rnelsonee/PAT_test
Fixed #11769: PAT Test hardcoded text
2022-09-14 20:01:18 -07:00
snipe
28f0b72bcd Merge remote-tracking branch 'origin/develop' 2022-09-14 19:56:16 -07:00
snipe
ad7bc6f38a Merge pull request #11825 from snipe/features/added_applecare_lookup_link
Added Applecare lookup link if manufacturer is apple
2022-09-14 19:54:47 -07:00
snipe
72feaee6c0 Added Applecare lookup link if manufacturer is apple
Signed-off-by: snipe <snipe@snipe.net>
2022-09-14 19:43:48 -07:00
snipe
4ac3650d64 Merge remote-tracking branch 'origin/develop' 2022-09-14 18:21:40 -07:00
snipe
3877770160 Merge pull request #11824 from snipe/fixes/removed_assetlog_from_custom_report
Fixed custom asset report timeout - removed assetlog
2022-09-14 18:20:14 -07:00
snipe
3192a68b06 Pulled assetlog from custom report controller
Signed-off-by: snipe <snipe@snipe.net>
2022-09-14 18:17:52 -07:00
snipe
284b4d869f Merge pull request #11823 from Godmartinz/gh11822_depreciation_calc_off
Fixes depreciation calculations off
2022-09-14 17:39:59 -07:00
Godfrey M
6b6a079440 fixes current value and monthly depreciation on reports and calculations 2022-09-14 17:01:18 -07:00
Godfrey M
a0624fe179 reworks the depreciation formula, includes months passed instead of months remaining 2022-09-14 16:00:21 -07:00
snipe
d598f75721 Merge pull request #11811 from inietov/fixes/min_qty_not_importing_consumables
Fixed Mini quantity field values are not importing into Snipe-IT
2022-09-14 12:12:52 -07:00
Godfrey M
9b448227f7 tinkering to no avail 2022-09-13 11:40:10 -07:00
Ivan Nieto Vivanco
d51eca20f0 Add min_amt field in Consumables and Accessories imports 2022-09-12 18:11:48 -05:00
snipe
9b5790b7e6 Merge pull request #11072 from snipe/fixes/support_apache_24
YOLO
2022-09-12 14:26:43 -07:00
Godfrey M
28bc97f29f one line away from this being over with 2022-09-12 11:40:16 -07:00
snipe
a8a00f0a79 Updated prod JS assets
Signed-off-by: snipe <snipe@snipe.net>
2022-09-12 11:08:29 -07:00
snipe
cbd16174d8 Merge pull request #11810 from snipe/maintenance/updated_dev_assets
Updated compiled assets
2022-09-12 10:55:40 -07:00
snipe
448aefac28 Updated compiled assets
Signed-off-by: snipe <snipe@snipe.net>
2022-09-12 10:54:54 -07:00
snipe
b23cd6d4f0 Merge pull request #11808 from snipe/snyk-upgrade-390057161cf95c21d9a4b53f57207321
[Snyk] Upgrade bootstrap-table from 1.20.2 to 1.21.0
2022-09-11 16:56:22 -07:00
snyk-bot
b0ea1a31dc fix: upgrade bootstrap-table from 1.20.2 to 1.21.0
Snyk has created this PR to upgrade bootstrap-table from 1.20.2 to 1.21.0.

See this package in npm:
https://www.npmjs.com/package/bootstrap-table

See this project in Snyk:
https://app.snyk.io/org/snipe/project/3d53e1dd-b8bf-46b5-ba61-18ce26933166?utm_source=github&utm_medium=referral&page=upgrade-pr
2022-09-11 23:55:26 +00:00
snipe
11a2f96b4f Merge pull request #11806 from snipe/snyk-upgrade-390057161cf95c21d9a4b53f57207321
[Snyk] Upgrade bootstrap-table from 1.20.2 to 1.21.0
2022-09-11 01:30:34 -07:00
snyk-bot
7361977cdc fix: upgrade bootstrap-table from 1.20.2 to 1.21.0
Snyk has created this PR to upgrade bootstrap-table from 1.20.2 to 1.21.0.

See this package in npm:
https://www.npmjs.com/package/bootstrap-table

See this project in Snyk:
https://app.snyk.io/org/snipe/project/3d53e1dd-b8bf-46b5-ba61-18ce26933166?utm_source=github&utm_medium=referral&page=upgrade-pr
2022-09-10 23:32:02 +00:00
snipe
659703bd7d Merge pull request #11790 from inietov/fixes/double_login_issue_when_switching_users
Fixed Double login when switching users
2022-09-06 17:03:21 -07:00
Ivan Nieto Vivanco
3aff97ace1 Remove the previous user hashed password 2022-09-06 18:43:35 -05:00
Rick Nelson
6e82de2f47 Fixed #11769: PAT Test hardcoded text 2022-09-01 11:21:02 -04:00
snipe
ae505ef44d Literally have no idea how this ever worked
Signed-off-by: snipe <snipe@snipe.net>
2022-08-31 19:20:35 -07:00
snipe
e86e96e159 Merge pull request #11765 from snipe/fixes/colspan_for_delete_checkboxes
Increased colspan for checkboxes
2022-08-31 13:35:21 -07:00
snipe
93428e1ed4 Increased colspan for checkboxes
Signed-off-by: snipe <snipe@snipe.net>
2022-08-31 13:34:27 -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
BasO12
61e1650542 Add files via upload 2022-08-31 13:08:09 +02:00
BasO12
ab54ac9408 Add files via upload 2022-08-31 13:07:05 +02:00
snipe
dcbd407698 Merge pull request #11661 from inietov/fixes/notifications_asset_acceptance
Send notifications when Acceptance Assets actions occur [sc-9917]
2022-08-30 12:14:58 -07:00
geo-chen
4e7fea3468 correcting default mysql port from 3309 to 3306
installation breaks using default config and manual edits to correct the port is currently required
2022-08-30 20:40:49 +08:00
geo-chen
3ef25c3a4d correcting default mysql port from 3309 to 3306
installation breaks using default config and manual edits to correct the port is currently required
2022-08-30 20:40:35 +08:00
geo-chen
22596f4bb8 correcting default mysql port from 3309 to 3306
installation breaks using default config and manual edits to correct the port is currently required
2022-08-30 20:40:19 +08:00
geo-chen
8fdca7f42b correcting default mysql port from 3309 to 3306
installation breaks using default config and manual edits to correct the port is currently required
2022-08-30 20:40:04 +08:00
geo-chen
1f04cfdb44 correcting default mysql port from 3309 to 3306
installation breaks using default config and manual edits to correct the port is currently required
2022-08-30 20:39:50 +08:00
geo-chen
04c130e596 correcting default mysql port from 3309 to 3306
installation breaks using default config and manual edits to correct the port is currently required
2022-08-30 20:39:34 +08:00
snipe
7fa9214beb Merge pull request #11489 from Godmartinz/bug/sc-19333/expiring-assets-report-email-content-ordering
Fixed the order expiring assets are listed in notifications
2022-08-29 12:37:01 -07:00
Godfrey M
ea63049b4b removed redundancy with raw query 2022-08-29 12:33:51 -07:00
Godfrey M
0c362e8b57 gets the groups selector to appear but options are blank 2022-08-29 12:09:56 -07:00
snipe
e94b5ac435 Merge pull request #11758 from snipe/security/xss_on_dashboard_note
Fixed possible XSS on dashboard note
2022-08-29 11:50:48 -07:00
snipe
9cf5f30c77 Set safeMode to true and use helper for all parsedown
Signed-off-by: snipe <snipe@snipe.net>
2022-08-29 11:26:47 -07:00
snipe
e8f2e50ada Add @dsferruzza as a contributor 2022-08-29 10:10:13 -07:00
snipe
3527902ba3 Merge pull request #11752 from dsferruzza/fixes/s3-file-size
Fixed #11742: display correct file sizes when using S3(-like) storage
2022-08-29 10:08:10 -07:00
David Sferruzza
f60ea9581d Fixed #11742: display correct file sizes when using S3(-like) storage 2022-08-28 12:07:14 +02:00
Chris Hartjes
74fe3dc733 Updated testing-related documentation 2022-08-26 13:55:12 -04:00
snipe
96ec96ff7f Merge pull request #11737 from inietov/fixes/validation_error_still_without_required_rule
Fixed Validation error when empty default customfield values
2022-08-25 17:54:04 -07:00
snipe
4fd1827576 Merge pull request #11738 from inietov/fixes/problem_checkin_and_delete_users
Fixed #11695 Problem with checkin all and delete user.
2022-08-25 17:52:51 -07:00
Ivan Nieto Vivanco
0d4e9c183b Save correct id in action log if the bulk-checkin is of type license 2022-08-25 19:16:48 -05:00
Ivan Nieto Vivanco
1ff2d15c4a Replace 'required' rule with 'nullable' to allow blank default customfields values 2022-08-25 18:16:50 -05:00
Godfrey M
fc6fefdb4e adds migration, variables, checkbox,working on groups 2022-08-25 15:19:38 -07:00
snipe
482a7b2a3a Merge pull request #11700 from inietov/fixes/unaccepted_assets_reminder_500
Fixed 500 error when sending unaccepted assets reminder
2022-08-25 14:00:00 -07:00
snipe
6f0f6c8042 Don’t prevent deletion if user has consumables checked out
Signed-off-by: snipe <snipe@snipe.net>
2022-08-25 12:51:02 -07:00
snipe
4cc9b5a5a2 Merge remote-tracking branch 'origin/develop'
Signed-off-by: snipe <snipe@snipe.net>

# Conflicts:
#	config/version.php
2022-08-25 12:34:38 -07:00
snipe
8720a58b51 Bumped version
Signed-off-by: snipe <snipe@snipe.net>
2022-08-25 12:34:02 -07:00
snipe
22710afee3 Merge remote-tracking branch 'origin/develop' 2022-08-25 12:28:06 -07:00
snipe
968f8fb554 Merge pull request #11735 from snipe/security/logout_other_devices
Fixed: Log user out of other devices when they change their password
2022-08-25 12:26:13 -07:00
snipe
6fde72a693 Log user out of other devices when they change their password
Signed-off-by: snipe <snipe@snipe.net>
2022-08-25 12:24:26 -07:00
snipe
afb7fa2e81 Merge remote-tracking branch 'origin/develop' 2022-08-24 18:12:26 -07:00
snipe
c9ef49ec65 Merge pull request #11731 from snipe/fixes/add_sig_column_to_user_history
Fixed #10593 - added signature column to user history
2022-08-24 18:08:41 -07:00
snipe
36ab794adc Added signature field to user history
Signed-off-by: snipe <snipe@snipe.net>
2022-08-24 18:05:43 -07:00
snipe
2ad9c39090 Merge pull request #11730 from inietov/fixes/importing_licenses_field_mismatch
Fixed #11679 Importing Licenses - Field Mismatch
2022-08-24 17:31:12 -07:00
Ivan Nieto Vivanco
c59fd7b8da Fix importer field mapping for command line 2022-08-24 19:20:23 -05:00
snipe
44e598b0dc Updated branch name in version
Signed-off-by: snipe <snipe@snipe.net>
2022-08-24 17:17:38 -07:00
snipe
ffd38292cf Merge pull request #11729 from uberbrady/improve_docker_assetmodels_restore
Fixed #11708 - pre-create private_storage directories for Docker restores
2022-08-24 17:16:21 -07:00
snipe
660c1429b2 Merge pull request #11728 from snipe/fixes/adds_style_to_readonly_date_fields
Added style to readonly date fields
2022-08-24 17:14:16 -07:00
Brady Wetherington
8ad5fb34d3 Fixed #11708 - pre-create private_storage directories for Docker restores 2022-08-24 17:11:21 -07:00
snipe
a5fd9ebbb1 Added style to readonly datetime picker field
Signed-off-by: snipe <snipe@snipe.net>
2022-08-24 17:10:15 -07:00
snipe
49d2aef831 Merge pull request #11726 from inietov/fixes/customfields_date_format_issue
Fixed #11709 Dates in custom fields not always stored in the correct format
2022-08-24 16:46:35 -07:00
snipe
74f5980af7 Merge pull request #11724 from inietov/fixes/remove_required_rule_for_default_custom_values
Fixed Validation error when creating custom fields' default values
2022-08-24 16:44:46 -07:00
snipe
1a47e1000d Merge pull request #11727 from snipe/security/updated_compiled_assets
Updated compiled assets
2022-08-24 16:43:08 -07:00
snipe
ab60fa08df Updated dev assets
Signed-off-by: snipe <snipe@snipe.net>
2022-08-24 16:38:11 -07:00
snipe
8a312f69a6 Bumped hash
Signed-off-by: snipe <snipe@snipe.net>
2022-08-24 16:37:22 -07:00
Ivan Nieto Vivanco
581cae94ab Add readonly property to datepickers 2022-08-24 18:21:54 -05:00
Ivan Nieto Vivanco
6e85c2e5cb Delete unused import 2022-08-24 16:30:25 -05:00
Ivan Nieto Vivanco
30d0125cbd Remove the rule 'required' for default values, if custom field is obligatory 2022-08-24 16:18:11 -05:00
snipe
e2dec5d5d7 Merge pull request #11723 from snipe/fixes/fail_with_error_when_uploaded_file_does_not_exist
Fixed crash on Asset View if file doesn’t exist on server
2022-08-24 13:50:26 -07:00
snipe
af34fc207c Suppress error output if file doesn’t exist on server
Signed-off-by: snipe <snipe@snipe.net>
2022-08-24 13:47:56 -07:00
snipe
cca531f8ca Add @sunflowerbofh as a contributor 2022-08-22 16:32:30 -07:00
snipe
45f17fea8a Merge pull request #11510 from sunflowerbofh/tmp-ldap
Fixed #11509 allow-ldap-anonymous-bind
2022-08-22 16:32:07 -07:00
snipe
3ac84eab58 Merge pull request #11651 from inietov/fixes/activity_report_search
Fixed Search in activity report for full name in relation
2022-08-22 16:23:50 -07:00
snipe
15af4ea56e Add @kylegordon as a contributor 2022-08-22 16:21:20 -07:00
snipe
d649c65508 Merge pull request #11669 from kylegordon/master
Declare DB_PORT in all .env files
2022-08-22 16:20:40 -07:00
snipe
0965ac9592 Merge pull request #11680 from snipe/snyk-upgrade-3dd3b8528a5a6c5104f99fc833e3820e
[Snyk] Upgrade @fortawesome/fontawesome-free from 6.1.1 to 6.1.2
2022-08-22 16:18:15 -07:00
snipe
bfadc69d73 Merge pull request #11681 from snipe/snyk-upgrade-ce70c2a6ece4c881ee4f6267e992332c
[Snyk] Upgrade webpack from 5.73.0 to 5.74.0
2022-08-22 16:17:53 -07:00
snipe
41be3f7208 Add @julian-piehl as a contributor 2022-08-22 16:17:24 -07:00
snipe
906a36dc1a Merge pull request #11703 from julian-piehl/fixes/wrong-trans-string
Fixed Translation String: wrong key at request canceled message
2022-08-22 16:16:10 -07:00
snipe
aba8449dc6 Merge pull request #11707 from wewhite/manager_name
Fixed #11706 Manager name
2022-08-22 16:15:52 -07:00
snipe
861283b874 Merge pull request #11712 from Godmartinz/gh11711Admin_options_disappear
Fixed #11711 clearfix missing on admin settings page  to prevent blanking divs
2022-08-22 16:15:06 -07:00
Godfrey M
2994c3613a adds clearfix to settings page 2022-08-22 10:46:15 -07:00
Warren White
ba7d6dde3f Fixed #11706: changes the display of managers username to First Last name 2022-08-19 10:17:25 -07:00
Warren White
4b9a91f55b Fixed #10565, #11086: correctly looks up Manager DN from AD Manager attribute and sets manager id 2022-08-19 09:09:03 -07:00
Peace
94bbf2bf2f fixed translation string for canceled requests 2022-08-19 13:59:01 +02:00
Ivan Nieto Vivanco
e5cc6ec972 Fixes error 500 if checkout_acceptances table have a created_at null column 2022-08-17 22:02:13 -05:00
snyk-bot
e97c526050 fix: upgrade webpack from 5.73.0 to 5.74.0
Snyk has created this PR to upgrade webpack from 5.73.0 to 5.74.0.

See this package in npm:
https://www.npmjs.com/package/webpack

See this project in Snyk:
https://app.snyk.io/org/snipe/project/3d53e1dd-b8bf-46b5-ba61-18ce26933166?utm_source=github&utm_medium=referral&page=upgrade-pr
2022-08-15 23:41:31 +00:00
snyk-bot
7b45328fcc fix: upgrade @fortawesome/fontawesome-free from 6.1.1 to 6.1.2
Snyk has created this PR to upgrade @fortawesome/fontawesome-free from 6.1.1 to 6.1.2.

See this package in npm:
https://www.npmjs.com/package/@fortawesome/fontawesome-free

See this project in Snyk:
https://app.snyk.io/org/snipe/project/3d53e1dd-b8bf-46b5-ba61-18ce26933166?utm_source=github&utm_medium=referral&page=upgrade-pr
2022-08-15 23:41:27 +00:00
snipe
40bc13a946 Merge pull request #11676 from snipe/fixes/added_category_to_model_info
Adds the category in the side info on Models > View
2022-08-14 14:03:09 -07:00
snipe
368bd5da3f Adds the category in the side info on Models > View
Signed-off-by: snipe <snipe@snipe.net>
2022-08-14 14:01:58 -07:00
snipe
1763bbfbd3 Merge pull request #11662 from octobunny/patch-1
Fixed #6899 Docker container's php configuration isn't congruent with snipe-it uploads setting size.
2022-08-14 13:46:38 -07:00
snipe
7b44afc43c Merge pull request #11666 from snipe/features/add_null_option_for_purchase_expected_dates
Added `null` option for `purchase_date` and `expected_checkin` dates
2022-08-14 13:43:03 -07:00
snipe
13b6c281df Merge pull request #11675 from snipe/revert-11663-fixes/user_cant_be_deleted_if_has_consumables
Revert "Prevent to delete a user if still has consumables associated to them"
2022-08-14 13:42:45 -07:00
snipe
5feea17f8d Revert "Prevent to delete a user if still has consumables associated to them" 2022-08-14 13:42:14 -07:00
snipe
60d1578a01 Merge pull request #11663 from inietov/fixes/user_cant_be_deleted_if_has_consumables
Prevent to delete a user if still has consumables associated to them
2022-08-14 13:41:09 -07:00
Chris Hartjes
07585809b3 Got unit and browser tests working, added documentation 2022-08-12 13:00:26 -04:00
Kyle Gordon
98a111796b Declare DB_PORT in all .env files 2022-08-12 15:07:02 +01:00
snipe
7b3be076b4 Make location field the same width
Signed-off-by: snipe <snipe@snipe.net>
2022-08-11 18:38:34 -07:00
snipe
2c68ec927a Use trans_choice for string
Signed-off-by: snipe <snipe@snipe.net>
2022-08-11 18:30:59 -07:00
snipe
a0ba33ed7c Added checkboxes
Signed-off-by: snipe <snipe@snipe.net>
2022-08-11 18:25:22 -07:00
snipe
70bb4cd746 Added translation
Signed-off-by: snipe <snipe@snipe.net>
2022-08-11 18:25:15 -07:00
snipe
91e824c5b0 Check for nullifying checkboxes
Signed-off-by: snipe <snipe@snipe.net>
2022-08-11 18:25:07 -07:00
snipe
491cdd4de6 Merge pull request #11664 from snipe/snyk-upgrade-bcc306620433a4ebeaaed8c3e4d4c9eb
[Snyk] Upgrade acorn from 8.7.1 to 8.8.0
2022-08-11 16:59:45 -07:00
snyk-bot
3454cdd2a0 fix: upgrade acorn from 8.7.1 to 8.8.0
Snyk has created this PR to upgrade acorn from 8.7.1 to 8.8.0.

See this package in npm:
https://www.npmjs.com/package/acorn

See this project in Snyk:
https://app.snyk.io/org/snipe/project/3d53e1dd-b8bf-46b5-ba61-18ce26933166?utm_source=github&utm_medium=referral&page=upgrade-pr
2022-08-11 23:58:21 +00:00
Ivan Nieto Vivanco
db53a00d3f Prevent to delete a user if still has consumables associated to them 2022-08-11 17:01:52 -05:00
octobunny
8324b94022 Change PHP post_max_size
Must change post_max_size in addition to upload_max_filesize to increase total upload size to greater than 8MB.
2022-08-11 17:07:46 -04:00
Ivan Nieto Vivanco
a33ca39237 Figure out declined notifications 2022-08-11 16:00:21 -05:00
Ivan Nieto Vivanco
98bcd82108 Add the mail recipient from configuration in the CheckoutAcceptance model 2022-08-11 15:33:18 -05:00
Ivan Nieto Vivanco
d2c486bb1e Create the mail template for the acceptance 2022-08-11 15:28:30 -05:00
snipe
8c579d693a Merge pull request #11660 from Godmartinz/departments_location_and_company_updates_with_null
Fixes Departments update/store  to allow company and/or location ids to be null
2022-08-11 13:04:45 -07:00
Godfrey M
814992eb7d allows company and location ids to be null 2022-08-11 12:47:40 -07:00
Ivan Nieto Vivanco
267997f0a6 Customize the notifications with the needed data 2022-08-11 14:01:11 -05:00
Ivan Nieto Vivanco
0172fe6403 Add Notifiable trait to the CheckoutAcceptance Model 2022-08-11 13:02:25 -05:00
Ivan Nieto Vivanco
509bbbc685 Create Notifications classes for accepted and declined and add some necesary lang strings 2022-08-11 13:01:21 -05:00
Ivan Nieto Vivanco
8cee5060af Remove unused DB statement 2022-08-10 19:16:04 -05:00
Ivan Nieto Vivanco
a7de97f060 Found a better place for the where condition 2022-08-10 19:13:28 -05:00
Ivan Nieto Vivanco
c1074000f9 Add a concat to search for full name when the relationship search in the users table 2022-08-10 18:27:28 -05:00
snipe
c7d9baad8e Merge remote-tracking branch 'origin/master' into develop 2022-08-10 16:11:29 -07:00
snipe
c77d763f05 Merge pull request #11650 from snipe/fixes/6877_add_notes_to_consumables
Fixed #6877 - Added notes to consumables, components on checkout
2022-08-10 16:11:08 -07:00
snipe
ef099aa644 Reverted notes to note since pivot
Signed-off-by: snipe <snipe@snipe.net>
2022-08-10 16:09:56 -07:00
snipe
acd666fdf5 Added notes to user consumables tab
Signed-off-by: snipe <snipe@snipe.net>
2022-08-10 15:34:07 -07:00
snipe
8de7e9a2ab Use route name in case the user biffs the checkout twice
Signed-off-by: snipe <snipe@snipe.net>
2022-08-10 15:17:52 -07:00
snipe
dd0260c3be Use old note on validation failure
Signed-off-by: snipe <snipe@snipe.net>
2022-08-10 15:15:29 -07:00
snipe
512348cc5a Added withInput()
Signed-off-by: snipe <snipe@snipe.net>
2022-08-10 15:15:09 -07:00
snipe
fb3d7bf82e Made button wider
Signed-off-by: snipe <snipe@snipe.net>
2022-08-10 15:07:58 -07:00
snipe
e3293151a2 Added note on checkout
Signed-off-by: snipe <snipe@snipe.net>
2022-08-10 15:04:59 -07:00
snipe
3ec77724d8 Added note pivot
Signed-off-by: snipe <snipe@snipe.net>
2022-08-10 15:04:34 -07:00
snipe
024a014298 Changed notes to note
Signed-off-by: snipe <snipe@snipe.net>
2022-08-10 15:04:19 -07:00
snipe
c1e5d03340 Added pivot for note
Signed-off-by: snipe <snipe@snipe.net>
2022-08-10 15:03:41 -07:00
snipe
fb2fe61daf Use a less stupid URL for this endpoint
Signed-off-by: snipe <snipe@snipe.net>
2022-08-10 15:03:26 -07:00
snipe
0d9eccb7eb Addeed note field
Signed-off-by: snipe <snipe@snipe.net>
2022-08-10 15:03:12 -07:00
snipe
f9956cc5df Added DB migration
Signed-off-by: snipe <snipe@snipe.net>
2022-08-10 14:54:33 -07:00
snipe
f7cceaedd5 Merge pull request #11649 from snipe/features/add_url_in_export
Fixed #8928 - add URL and ID to custom asset report
2022-08-10 13:58:22 -07:00
snipe
e7c47408a7 Derp
Signed-off-by: snipe <snipe@snipe.net>
2022-08-10 13:57:42 -07:00
snipe
637604dfaf Fixed #8928 - add URL and ID to custom asset report
Signed-off-by: snipe <snipe@snipe.net>
2022-08-10 13:51:47 -07:00
snipe
f66df4d468 Merge pull request #11648 from uberbrady/reimplement_active_flag
Fixed the active flag to be as it was in later v5 releases
2022-08-10 13:32:52 -07:00
Brady Wetherington
b6adfa294c Fixed the active flag to be as it was in later v5 releases
Originally implemented here:

https://github.com/snipe/snipe-it/pull/10610/files
2022-08-10 12:55:30 -07:00
snipe
f374f231d4 Added ERD link
Signed-off-by: snipe <snipe@snipe.net>
2022-08-10 11:37:17 -07:00
snipe
d4e60a46c1 Merge remote-tracking branch 'origin/develop' 2022-08-09 15:15:31 -07:00
snipe
a834ac6ec2 Merge pull request #11642 from Godmartinz/monthly_depreciation_calculation
Fixes Monthly depreciation calculation if EOL is blank
2022-08-09 15:14:57 -07:00
Godfrey M
92e6ea96b2 if eol is missing from asset model monthly depreciation will be recalculated 2022-08-09 15:05:15 -07:00
snipe
de449fd1c2 Merge pull request #11635 from exula/fix/missing_closing_div_in_general_admin_settings
Added a closing div tag around the mail text help block, this was cau…
2022-08-09 11:07:19 -07:00
Brad Coudriet
77a1fcb1fc There was actually a missing p tag too 2022-08-09 06:36:53 -04:00
Brad Coudriet
0cf0598936 Added a closing div tag around the mail text help block, this was causing labels further down the page to be formatted in correctly 2022-08-09 06:32:03 -04:00
snipe
80d91c0c51 Merge remote-tracking branch 'origin/develop'
Signed-off-by: snipe <snipe@snipe.net>

# Conflicts:
#	config/version.php
2022-08-08 15:33:10 -07:00
snipe
c39bf7b7e6 Added German (Informal) to select list
Signed-off-by: snipe <snipe@snipe.net>
2022-08-08 15:30:58 -07:00
snipe
9db0b038a5 Updated translation strings
Signed-off-by: snipe <snipe@snipe.net>
2022-08-08 15:29:28 -07:00
snipe
4f4c4ed5be Bumped version
Signed-off-by: snipe <snipe@snipe.net>
2022-08-08 14:35:04 -07:00
snipe
51f7298720 Merge remote-tracking branch 'origin/develop' 2022-08-05 18:16:20 -07:00
snipe
bc4032c2cd Merge pull request #11617 from inietov/fixes/components_wrong_remaining_inventory
Fixed wrong calculation of assigned components
2022-08-05 18:05:21 -07:00
Ivan Nieto Vivanco
c055c91739 Change db query for an existing method 2022-08-04 09:20:20 -05:00
Ivan Nieto Vivanco
ea8f12579d Calculate the proper amount of assigned components 2022-08-04 07:58:25 -05:00
snipe
88db2d9e18 Merge remote-tracking branch 'origin/develop' 2022-08-03 17:57:07 -07:00
snipe
5f93d7b3be Merge pull request #11615 from inietov/fixes/autoincrement_in_importer
Fix auto incrementing in CSV importer [sc-19366]
2022-08-03 17:50:23 -07:00
snipe
1875ed55cc Merge pull request #11612 from snipe/fixes/improved_report_search
Added relations to report search
2022-08-03 17:49:59 -07:00
Ivan Nieto Vivanco
9f0ecba9b9 Add autoincrementing asset tags to the import if the CSV column is empty 2022-08-03 12:48:48 -05:00
snipe
9acfceba29 Added relations to report search
Signed-off-by: snipe <snipe@snipe.net>
2022-08-02 23:50:10 -07:00
snipe
92bf8b4436 Merge remote-tracking branch 'origin/develop' 2022-08-02 20:22:02 -07:00
snipe
b52c00d49b Merge pull request #11611 from snipe/fixes/added_configuration_change_to_maintenance_types
Added configuration change to maintenance types
2022-08-02 20:21:25 -07:00
snipe
20fcf7a1e9 Added configuration change to maintenance types
Signed-off-by: snipe <snipe@snipe.net>
2022-08-02 20:19:43 -07:00
snipe
095dd3ecf2 Added configuration, PAT test strings
Signed-off-by: snipe <snipe@snipe.net>
2022-08-02 20:19:28 -07:00
snipe
5a1b8bc4b6 Fixed icheck checkbox class
Signed-off-by: snipe <snipe@snipe.net>
2022-08-02 20:19:19 -07:00
snipe
eadb36cb26 Merge remote-tracking branch 'origin/develop' 2022-08-02 20:00:13 -07:00
snipe
6eac133caf Merge pull request #11610 from snipe/fixes/adds_deleted_at_to_custom_report_export
Added deleted at to custom report export
2022-08-02 19:59:39 -07:00
snipe
cc92d342ea Added deleted at value
Signed-off-by: snipe <snipe@snipe.net>
2022-08-02 19:58:37 -07:00
snipe
02caa13222 Removed debugging
Signed-off-by: snipe <snipe@snipe.net>
2022-08-02 19:58:30 -07:00
snipe
975b4dee2f Added deleted header
Signed-off-by: snipe <snipe@snipe.net>
2022-08-02 19:58:17 -07:00
snipe
65f0a3f535 Merge pull request #11609 from snipe/fixes/checkboxes_on_custom_report
Fixed labels on radio buttons in custom report
2022-08-02 19:54:14 -07:00
snipe
9ae7c66b77 Fixed indenting
Signed-off-by: snipe <snipe@snipe.net>
2022-08-02 19:50:21 -07:00
snipe
77ab4ac1b5 Fixed labels on radio buttons in custom report
Signed-off-by: snipe <snipe@snipe.net>
2022-08-02 19:48:41 -07:00
snipe
b0e66ae445 Merge remote-tracking branch 'origin/develop'
Signed-off-by: snipe <snipe@snipe.net>

# Conflicts:
#	resources/views/locations/print.blade.php
2022-08-02 19:41:17 -07:00
snipe
5fe8db541e Merge pull request #11608 from snipe/features/add_time_diff_to_eol
Added time diff to EOL in asset view
2022-08-02 19:40:10 -07:00
snipe
87bed9b294 Fixed typo in code comments
Signed-off-by: snipe <snipe@snipe.net>
2022-08-02 19:24:46 -07:00
snipe
da1c1dbdd9 Added warning icon
Signed-off-by: snipe <snipe@snipe.net>
2022-08-02 19:19:08 -07:00
snipe
56b6904564 Added time difference
Signed-off-by: snipe <snipe@snipe.net>
2022-08-02 19:13:02 -07:00
snipe
10e64deafe Updated method name in mail
Signed-off-by: snipe <snipe@snipe.net>
2022-08-02 19:12:44 -07:00
snipe
ac72b69ece Update method name
Signed-off-by: snipe <snipe@snipe.net>
2022-08-02 19:12:28 -07:00
snipe
8e18ce74b2 Update method name
Signed-off-by: snipe <snipe@snipe.net>
2022-08-02 19:12:18 -07:00
snipe
254ce72415 Add @vickyjaura183 as a contributor 2022-08-02 17:20:51 -07:00
snipe
1b657ee995 Merge pull request #11601 from vickyjaura183/bugfix/error_404_bulkcheckout
Error 404 fixed on submitting without mandatory field
2022-08-02 17:19:22 -07:00
snipe
71facb1850 Merge pull request #11596 from snipe/fixes/unique_undeleted_for_custom_fields
Use unique_undeleted instead of unique for custom fields
2022-08-02 17:16:12 -07:00
snipe
8d8c502546 Merge pull request #11605 from snipe/fixes/really_disable_consumable_checkout
Disallow checkout if qty = 0
2022-08-02 12:31:29 -07:00
snipe
0a9bd07f20 Disallow checkout if qty = 0
Signed-off-by: snipe <snipe@snipe.net>
2022-08-02 12:27:58 -07:00
snipe
688577c1ed Merge pull request #11604 from snipe/fixes/only_show_requested_if_requestable_perms
Hide requested assets if the user cannot see requestable items
2022-08-02 11:49:22 -07:00
snipe
8027039754 Hide requested assets if the user cannot see requestable items
Signed-off-by: snipe <snipe@snipe.net>
2022-08-02 11:48:45 -07:00
snipe
031b7998c9 Merge pull request #11603 from inietov/fixes/actions_on_licenses
Use apropiate string for license actions
2022-08-02 10:40:20 -07:00
Ivan Nieto Vivanco
13053b85ef Remove Actions button and pass the correct variable to the routes 2022-08-02 12:37:27 -05:00
snipe
e3b13143bf Merge pull request #11594 from Godmartinz/adds_deleted_asset_options_to_custom_reports
Adds options to include Deleted assets to custom asset reports
2022-08-02 10:33:57 -07:00
Godfrey M
e150ab58e9 reworded trans 2022-08-02 10:31:06 -07:00
Godfrey M
ff080a2d8f replace checkboxes with radiobuttons 2022-08-02 10:27:55 -07:00
Ivan Nieto Vivanco
a63d00bb5c Use apropiate string for license actions 2022-08-02 11:55:11 -05:00
vishalkumar183
96b40a5edd Error 404 fixed on sumitting witout mandtory field 2022-08-02 18:44:16 +05:30
Katharina Drexel
8596c54d6a Fixing query order (otherwise you run into app_key exception before anonymous ldap applied).
Signed-off-by: Katharina Drexel <katharina.drexel@bfh.ch>
2022-08-02 14:24:00 +02:00
snipe
e07532dd1b Applied master fix to develop
Signed-off-by: snipe <snipe@snipe.net>
2022-08-01 18:55:28 -07:00
snipe
04a467bdc7 One more
Signed-off-by: snipe <snipe@snipe.net>
2022-08-01 18:53:00 -07:00
snipe
06d60bb1d1 Applied date formatter PR to master
Signed-off-by: snipe <snipe@snipe.net>
2022-08-01 18:49:56 -07:00
snipe
9c6c01bab1 Merge pull request #11597 from snipe/fixes/missed_date_formatting_on_print
Fixed date format for Current Date output on location print assigned
2022-08-01 18:48:41 -07:00
snipe
4133ac6ef0 Applied date formatter to Current Date output on location print assigned
Signed-off-by: snipe <snipe@snipe.net>
2022-08-01 18:47:29 -07:00
snipe
4834c33861 Missed a named route
Signed-off-by: snipe <snipe@snipe.net>
2022-08-01 18:43:54 -07:00
snipe
904b5c2886 Merge pull request #11595 from snipe/fixes/fix_routes_for_optimize
Fixed routes for optimize
2022-08-01 17:55:34 -07:00
snipe
e79a819724 Fixed inconsistency in naming
Signed-off-by: snipe <snipe@snipe.net>
2022-08-01 17:45:39 -07:00
snipe
0fdbd410b6 Use unique_undeleted instead of unique for custom fields
Signed-off-by: snipe <snipe@snipe.net>
2022-08-01 17:10:39 -07:00
snipe
af7ccf3beb Handle logout route names
Signed-off-by: snipe <snipe@snipe.net>
2022-08-01 16:17:40 -07:00
snipe
3e48f436af Handled user route names
Signed-off-by: snipe <snipe@snipe.net>
2022-08-01 16:13:30 -07:00
snipe
5e488bd81f Handle components route names
Signed-off-by: snipe <snipe@snipe.net>
2022-08-01 16:10:39 -07:00
snipe
53ff28d2b0 Handle consumables route names
Signed-off-by: snipe <snipe@snipe.net>
2022-08-01 16:07:56 -07:00
snipe
4a4636bd03 Handle accessories route names
Signed-off-by: snipe <snipe@snipe.net>
2022-08-01 16:06:28 -07:00
snipe
744d0d299e Handle model route names
Signed-off-by: snipe <snipe@snipe.net>
2022-08-01 16:03:45 -07:00
snipe
b035003546 Handled hardware route names
Signed-off-by: snipe <snipe@snipe.net>
2022-08-01 15:59:54 -07:00
Godfrey M
842dafefec adds options to include Deleted assets to custom asset reports 2022-08-01 14:52:12 -07:00
snipe
375963f92d Merge remote-tracking branch 'origin/develop' 2022-08-01 14:08:16 -07:00
snipe
a51b446a10 Merge pull request #11578 from snipe/fixes/conditionally_add_nbsp
Switched to conditionally adding the nbsp; that the table needs for proper layout if cell is empty
2022-08-01 14:07:50 -07:00
snipe
371aba9912 Merge pull request #11593 from snipe/fixes/add_bulk_assets_to_company_view
Added bulk edit to company view
2022-08-01 14:07:14 -07:00
snipe
8b30992a11 Added bulk edit to company view
Signed-off-by: snipe <snipe@snipe.net>
2022-08-01 14:06:18 -07:00
snipe
33de45d8fb Swirtched to conditionally adding the nbsp; that the table needs for proper layout if cell is empty
Signed-off-by: snipe <snipe@snipe.net>
2022-07-29 00:57:20 -07:00
snipe
d7d0056b73 Merge remote-tracking branch 'origin/develop' 2022-07-27 15:10:38 -07:00
snipe
7d2fcef807 Merge pull request #11562 from uberbrady/clarify_logging
Fixed inconsistent `*_LOG_LEVEL` variables; set reasonable defaults
2022-07-25 20:02:37 -07:00
Brady Wetherington
1981b79557 Good catch! APP_LOG -> LOG_CHANNEL 2022-07-25 19:57:14 -07:00
Brady Wetherington
0c7d4a709a Cleaned up more logging options 2022-07-25 19:25:06 -07:00
snipe
6c8d226b21 Merge pull request #11561 from snipe/features/added_perl_module_link
Added link to SEDC / perl-www-snipe
2022-07-25 18:54:57 -07:00
snipe
211bbeda5b Added link to SEDC / perl-www-snipe
Signed-off-by: snipe <snipe@snipe.net>
2022-07-25 18:53:17 -07:00
Brady Wetherington
7057cb0104 Make all *_LOG_LEVEL vars consistent; set default to 'warning' 2022-07-25 18:44:37 -07:00
snipe
658edb64d6 Merge remote-tracking branch 'origin/develop' 2022-07-22 19:06:28 -07:00
snipe
dc06f14505 Merge pull request #11554 from snipe/security/upgrade_dompdf
Bumped packages
2022-07-22 18:21:51 -07:00
snipe
f446314ce6 Merge pull request #11547 from snipe/fixes/midnight_timestamp
Applies current time to checkin date
2022-07-22 17:58:45 -07:00
snipe
443b1df5e1 Bumped packages
Signed-off-by: snipe <snipe@snipe.net>
2022-07-22 17:55:19 -07:00
snipe
3c22e0d203 Merge remote-tracking branch 'origin/develop' 2022-07-22 17:28:43 -07:00
snipe
d636ad8e09 Merge pull request #11553 from snipe/security/upgrade_imagemin
Upgraded imagemin
2022-07-22 17:27:35 -07:00
snipe
adfdbf3d44 Upgraded imagemin
Signed-off-by: snipe <snipe@snipe.net>
2022-07-22 17:26:47 -07:00
snipe
8b03abde8d Production assets for dark skin fix
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-blue-dark.css
#	public/css/dist/skins/skin-blue-dark.min.css
#	public/css/dist/skins/skin-green-dark.css
#	public/css/dist/skins/skin-green-dark.min.css
#	public/css/dist/skins/skin-orange-dark.css
#	public/css/dist/skins/skin-orange-dark.min.css
#	public/css/dist/skins/skin-purple-dark.css
#	public/css/dist/skins/skin-purple-dark.min.css
#	public/css/dist/skins/skin-red-dark.css
#	public/css/dist/skins/skin-red-dark.min.css
#	public/css/dist/skins/skin-yellow-dark.css
#	public/css/dist/skins/skin-yellow-dark.min.css
#	public/mix-manifest.json
2022-07-22 15:39:46 -07:00
snipe
67320dc024 Merge pull request #11551 from snipe/fixes/dark_skin_dropdowns
Fixed #11549 - dark skin dropdown menu fixes
2022-07-22 15:38:02 -07:00
snipe
c5530104ff Fixed #11549 - dark skin dropdowbn menu fixes
Signed-off-by: snipe <snipe@snipe.net>
2022-07-22 15:36:51 -07:00
snipe
78097df7ff Aplpies current time to checkin date
Signed-off-by: snipe <snipe@snipe.net>
2022-07-21 21:45:25 -07:00
snipe
072e6029b6 Merge remote-tracking branch 'origin/develop' 2022-07-21 12:20:24 -07:00
snipe
5926441984 Merge pull request #11542 from snipe/features/users_checkin_without_delete
Features/users checkin without delete
2022-07-20 18:59:45 -07:00
snipe
a1fe2a8d58 Fixed translation reference
Signed-off-by: snipe <snipe@snipe.net>
2022-07-20 18:01:55 -07:00
snipe
25cc46e416 Fixed button string
Signed-off-by: snipe <snipe@snipe.net>
2022-07-20 18:01:41 -07:00
snipe
458d61fafe Front-end updates for checkin without delete
Signed-off-by: snipe <snipe@snipe.net>
2022-07-20 17:57:39 -07:00
snipe
32010d5387 Updated language strings
Signed-off-by: snipe <snipe@snipe.net>
2022-07-20 17:57:27 -07:00
snipe
7313bca403 Checkin without deleting
Signed-off-by: snipe <snipe@snipe.net>
2022-07-20 17:57:19 -07:00
snipe
b7c7e6c623 Added/updated language strings
Signed-off-by: snipe <snipe@snipe.net>
2022-07-20 17:56:58 -07:00
snipe
0b4d243bf0 Merge pull request #11541 from Godmartinz/gh11540_Error_405_when_checking_out_Accessory
Fixes #11540 - accessory api routes from get to posts
2022-07-20 14:14:15 -07:00
Godfrey M
377c0e7075 fixes component routes 2022-07-20 13:41:35 -07:00
Godfrey M
0c4c4fc352 changes api checkin and checkout routes to post 2022-07-20 11:52:54 -07:00
Katharina Drexel
9d627936e6 Fixed #11509: Allow LDAP anonymous bind. 2022-07-20 17:24:20 +02:00
snipe
29a32c4726 Merge remote-tracking branch 'origin/develop' 2022-07-19 12:46:05 -07:00
snipe
e72c4f989f Merge pull request #11528 from uberbrady/upgrade_laravel_scim_server
Upgraded our fork of laravel-scim-server to better support scim creates
2022-07-18 19:56:06 -07:00
snipe
0d656e3963 Production assets
Signed-off-by: snipe <snipe@snipe.net>
2022-07-18 17:29:37 -07:00
snipe
50ce471dc6 Production assets
Signed-off-by: snipe <snipe@snipe.net>

# Conflicts:
#	public/js/build/app.js
#	public/js/dist/all.js
#	public/mix-manifest.json
2022-07-18 17:29:29 -07:00
snipe
8113838eee Merge pull request #11531 from snipe/security/upgrade_jquery_ui
Upgraded jquery-UI
2022-07-18 17:28:22 -07:00
snipe
a92bb80055 Upgraded jquery-UI
Signed-off-by: snipe <snipe@snipe.net>
2022-07-18 17:27:54 -07:00
Brady Wetherington
b2112e6792 Whoops, bump version to have the right syntax! 2022-07-18 15:16:45 -07:00
Brady Wetherington
250db10249 Upgrade our fork of laravel-scim-server to better support scim creates 2022-07-18 15:05:42 -07:00
Godfrey M
309229619b fixes the order expiring assets are listed in notifications 2022-07-11 12:25:38 -07:00
snipe
157944b774 Try conditiinal formatting to support apache 2.2 and 2.4
Signed-off-by: snipe <snipe@snipe.net>
2022-05-13 18:01:06 -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
1438 changed files with 35217 additions and 6849 deletions

View File

@@ -2662,8 +2662,179 @@
"avatar_url": "https://avatars.githubusercontent.com/u/7991086?v=4",
"profile": "https://github.com/reederda",
"contributions": [
"translations",
"translation",
"translation",
"code"
]
},
{
"login": "vickyjaura183",
"name": "vickyjaura183",
"avatar_url": "https://avatars.githubusercontent.com/u/109422491?v=4",
"profile": "https://github.com/vickyjaura183",
"contributions": [
"code"
]
},
{
"login": "julian-piehl",
"name": "Peace",
"avatar_url": "https://avatars.githubusercontent.com/u/32363424?v=4",
"profile": "https://github.com/julian-piehl",
"contributions": [
"code"
]
},
{
"login": "kylegordon",
"name": "Kyle Gordon",
"avatar_url": "https://avatars.githubusercontent.com/u/231528?v=4",
"profile": "https://github.com/kylegordon",
"contributions": [
"code"
]
},
{
"login": "sunflowerbofh",
"name": "Katharina Drexel",
"avatar_url": "https://avatars.githubusercontent.com/u/53009155?v=4",
"profile": "http://www.bfh.ch",
"contributions": [
"code"
]
},
{
"login": "dsferruzza",
"name": "David Sferruzza",
"avatar_url": "https://avatars.githubusercontent.com/u/1931963?v=4",
"profile": "https://david.sferruzza.fr/",
"contributions": [
"code"
]
},
{
"login": "rnelsonee",
"name": "Rick Nelson",
"avatar_url": "https://avatars.githubusercontent.com/u/19511639?v=4",
"profile": "https://github.com/rnelsonee",
"contributions": [
"code"
]
},
{
"login": "BasO12",
"name": "BasO12",
"avatar_url": "https://avatars.githubusercontent.com/u/94169344?v=4",
"profile": "https://github.com/BasO12",
"contributions": [
"code"
]
},
{
"login": "Vautia",
"name": "Vautia",
"avatar_url": "https://avatars.githubusercontent.com/u/111710123?v=4",
"profile": "https://github.com/Vautia",
"contributions": [
"code"
]
},
{
"login": "chartjes",
"name": "Chris Hartjes",
"avatar_url": "https://avatars.githubusercontent.com/u/28321?v=4",
"profile": "http://www.littlehart.net/atthekeyboard",
"contributions": [
"code"
]
},
{
"login": "geo-chen",
"name": "geo-chen",
"avatar_url": "https://avatars.githubusercontent.com/u/2404584?v=4",
"profile": "https://github.com/geo-chen",
"contributions": [
"code"
]
},
{
"login": "nh314",
"name": "Phan Nguyen",
"avatar_url": "https://avatars.githubusercontent.com/u/6006620?v=4",
"profile": "https://github.com/nh314",
"contributions": [
"code"
]
},
{
"login": "StarlessNights",
"name": "Iisakki Jaakkola",
"avatar_url": "https://avatars.githubusercontent.com/u/115993812?v=4",
"profile": "https://github.com/StarlessNights",
"contributions": [
"code"
]
},
{
"login": "eltociear",
"name": "Ikko Ashimine",
"avatar_url": "https://avatars.githubusercontent.com/u/22633385?v=4",
"profile": "https://bandism.net/",
"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"
]
}

View File

@@ -155,8 +155,8 @@ RESET_PASSWORD_LINK_EXPIRES=900
# --------------------------------------------
# OPTIONAL: MISC
# --------------------------------------------
APP_LOG=stderr
APP_LOG_MAX_FILES=10
LOG_CHANNEL=stderr
LOG_MAX_DAYS=10
APP_LOCKED=false
APP_CIPHER=AES-256-CBC
GOOGLE_MAPS_API=

View File

@@ -21,6 +21,7 @@ PUBLIC_FILESYSTEM_DISK=local_public
# --------------------------------------------
DB_CONNECTION=mysql
DB_HOST=localhost
DB_PORT=3306
DB_DATABASE=snipeit-local
DB_USERNAME=snipeit-local
DB_PASSWORD=snipeit-local
@@ -93,7 +94,7 @@ DISABLE_NOSAML_LOCAL_LOGIN=true
# --------------------------------------------
# OPTIONAL: MISC
# --------------------------------------------
APP_LOG=single
LOG_CHANNEL=single
LOG_LEVEL=debug
LOG_CHANNEL=stack
LOG_SLACK_WEBHOOK_URL=null

View File

@@ -24,6 +24,7 @@ PUBLIC_FILESYSTEM_DISK=local_public
# --------------------------------------------
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=null
DB_USERNAME=null
DB_PASSWORD=null
@@ -158,8 +159,8 @@ PASSWORD_RESET_MAX_ATTEMPTS_PER_MIN=50
# --------------------------------------------
# OPTIONAL: MISC
# --------------------------------------------
APP_LOG=single
APP_LOG_MAX_FILES=10
LOG_CHANNEL=single
LOG_MAX_DAYS=10
APP_LOCKED=false
APP_CIPHER=AES-256-CBC
APP_FORCE_TLS=false
@@ -172,3 +173,10 @@ IMPORT_MEMORY_LIMIT=500M
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

View File

@@ -14,6 +14,7 @@ FILESYSTEM_DISK=local
# --------------------------------------------
DB_CONNECTION=sqlite_testing
DB_HOST=localhost
DB_PORT=3306
DB_DATABASE=testing.sqlite
DB_USERNAME=null
DB_PASSWORD=null
@@ -70,5 +71,5 @@ SECURE_COOKIES=false
# --------------------------------------------
# OPTIONAL: APP LOG FORMAT
# --------------------------------------------
APP_LOG=single
APP_LOG_LEVEL=debug
LOG_CHANNEL=single
LOG_LEVEL=debug

View File

@@ -14,6 +14,7 @@ FILESYSTEM_DISK=local
# --------------------------------------------
DB_CONNECTION=sqlite
DB_HOST=localhost
DB_PORT=3306
DB_DATABASE='sqlite_testing'
DB_USERNAME=root
DB_PASSWORD=null
@@ -34,4 +35,4 @@ IMAGE_LIB=gd
# --------------------------------------------
# OPTIONAL: APP LOG FORMAT
# --------------------------------------------
APP_LOG=single
LOG_CHANNEL=single

View File

@@ -4,6 +4,7 @@ APP_URL=http://snipe-it.localapp
DB_CONNECTION=mysql
DB_DEFAULT=mysql
DB_HOST=localhost
DB_PORT=3306
DB_DATABASE=snipeittests
DB_USERNAME=snipeit
DB_PASSWORD=snipe

View File

@@ -4,6 +4,7 @@ APP_URL=http://snipe-it.localapp
DB_CONNECTION=sqlite_testing
DB_DEFAULT=sqlite_testing
DB_HOST=localhost
DB_PORT=3306
APP_KEY=base64:tu9NRh/a6+dCXBDGvg0Gv/0TcABnFsbT4AKxrr8mwQo=

View File

@@ -26,7 +26,7 @@ jobs:
language: [ 'javascript' ]
steps:
- name: Checkout repository
uses: actions/checkout@v2
uses: actions/checkout@v3.3.0
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL

View File

@@ -32,11 +32,11 @@ jobs:
steps:
# Checkout the repository to the GitHub Actions runner
- name: Checkout code
uses: actions/checkout@v2
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
uses: codacy/codacy-analysis-cli-action@v4.1.0
uses: codacy/codacy-analysis-cli-action@v4.2.0
with:
# Check https://github.com/codacy/codacy-analysis-cli#project-token to get your project token from your Codacy repository
# You can also omit the token and run the tools that support default configurations

View File

@@ -41,7 +41,7 @@ jobs:
steps:
# https://github.com/actions/checkout
- name: Checkout codebase
uses: actions/checkout@v2
uses: actions/checkout@v3.3.0
# https://github.com/docker/setup-buildx-action
- name: Setup Docker Buildx

View File

@@ -41,7 +41,7 @@ jobs:
steps:
# https://github.com/actions/checkout
- name: Checkout codebase
uses: actions/checkout@v2
uses: actions/checkout@v3.3.0
# https://github.com/docker/setup-buildx-action
- name: Setup Docker Buildx

View File

@@ -24,6 +24,7 @@ php7.4-mbstring \
php7.4-zip \
php7.4-bcmath \
php7.4-redis \
php-memcached \
patch \
curl \
wget \
@@ -139,4 +140,4 @@ RUN chmod +x /startup.sh /usr/bin/supervisor-exit-event-listener
CMD ["/startup.sh"]
EXPOSE 80
EXPOSE 443
EXPOSE 443

View File

@@ -28,6 +28,7 @@ RUN apk add --no-cache \
php7-xmlreader \
php7-sodium \
php7-redis \
php7-pecl-memcached \
curl \
wget \
vim \
@@ -85,4 +86,4 @@ ENTRYPOINT ["/sbin/tini", "--"]
CMD ["/entrypoint.sh"]
EXPOSE 80
EXPOSE 80

View File

@@ -75,14 +75,14 @@ RUN set -eux; \
rm snipeit.tar.gz; \
# Install composer php dependencies
if [ "$ENVIRONMENT" = "production" ]; then \
echo "production enviroment detected!"; \
echo "production environment detected!"; \
composer update \
--no-cache \
--no-dev \
--optimize-autoloader \
--working-dir=/var/www/html; \
else \
echo "development enviroment detected!"; \
echo "development environment detected!"; \
apk add --no-cache \
${DEV_PACKAGES}; \
composer update \
@@ -100,4 +100,4 @@ COPY --chown=www-data:www-data docker/docker-secrets.env /var/www/html/.env
COPY --chmod=655 docker/docker-entrypoint.sh /usr/local/bin/docker-snipeit-entrypoint
COPY docker/column-statistics.cnf /etc/mysql/conf.d/column-statistics.cnf
ENTRYPOINT [ "/usr/local/bin/docker-snipeit-entrypoint" ]
CMD [ "/usr/local/bin/docker-php-entrypoint", "php-fpm" ]
CMD [ "/usr/local/bin/docker-php-entrypoint", "php-fpm" ]

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-292-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
@@ -59,15 +59,16 @@ Since the release of the JSON REST API, several third-party developers have been
- [SnipeSharp - .NET module in C#](https://github.com/barrycarey/SnipeSharp) by [@barrycarey](https://github.com/barrycarey)
- [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/ParadoxGuitarist/jamf2snipe) by [@ParadoxGuitarist](https://github.com/ParadoxGuitarist) - Python script to sync assets between a JAMFPro instance and a Snipe-IT instance
- [jamf2snipe](https://github.com/grokability/jamf2snipe) - Python script to sync assets between a JAMFPro instance and a Snipe-IT instance
- [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.
- [Snipe-IT Kubernetes Helm Chart](https://github.com/t3n/helm-charts/tree/master/snipeit) - For more information, [click here](https://hub.helm.sh/charts/t3n/snipeit).
- [Snipe-IT Bulk Edit](https://github.com/bricelabelle/snipe-it-bulkedit) - Google Script files to use Google Sheets as a bulk checkout/checkin/edit tool for Snipe-it.
- [MosyleSnipeSync](https://github.com/RodneyLeeBrands/MosyleSnipeSync) by [@RodneyLeeBrands](https://github.com/RodneyLeeBrands) - Python script to synchronize information between Mosyle and Snipe-IT
- [WWW::SnipeIT](https://github.com/SEDC/perl-www-snipeit) by [@SEDC](https://github.com/SEDC) - perl module for accessing the API
As these were created by third-parties, Snipe-IT cannot provide support for these project, and you should contact the developers directly if you need assistance. Additionally, Snipe-IT makes no guarantees as to the reliability, accuracy or maintainability of these libraries. Use at your own risk. :)
As these were created by third-parties, Snipe-IT cannot provide support for these project, and you should contact the developers directly if you need assistance. Additionally, Snipe-IT makes no guarantees as to the reliability, accuracy or maintainability of these libraries. Use at your own risk. :)
-----
@@ -78,6 +79,8 @@ Please see the documentation on [contributing and developing for Snipe-IT](https
Please note that this project is released with a [Contributor Code of Conduct](CODE_OF_CONDUCT.md). By participating in this project you agree to abide by its terms.
The ERD is available [online here](https://drawsql.app/templates/snipe-it).
-----
### Security
@@ -133,7 +136,10 @@ Thanks goes to all of these wonderful people ([emoji key](https://github.com/ken
| [<img src="https://avatars.githubusercontent.com/u/84392209?v=4" width="110px;"/><br /><sub>Toreg87</sub>](https://github.com/Toreg87)<br />[💻](https://github.com/snipe/snipe-it/commits?author=Toreg87 "Code") | [<img src="https://avatars.githubusercontent.com/u/67638596?v=4" width="110px;"/><br /><sub>Matthew Nickson</sub>](https://github.com/Computroniks)<br />[💻](https://github.com/snipe/snipe-it/commits?author=Computroniks "Code") | [<img src="https://avatars.githubusercontent.com/u/1646397?v=4" width="110px;"/><br /><sub>Jethro Nederhof</sub>](https://jethron.id.au)<br />[💻](https://github.com/snipe/snipe-it/commits?author=jethron "Code") | [<img src="https://avatars.githubusercontent.com/u/23289826?v=4" width="110px;"/><br /><sub>Oskar Stenberg</sub>](https://github.com/01ste02)<br />[💻](https://github.com/snipe/snipe-it/commits?author=01ste02 "Code") | [<img src="https://avatars.githubusercontent.com/u/82208283?v=4" width="110px;"/><br /><sub>Robert-Azelis</sub>](https://github.com/Robert-Azelis)<br />[💻](https://github.com/snipe/snipe-it/commits?author=Robert-Azelis "Code") | [<img src="https://avatars.githubusercontent.com/u/60648387?v=4" width="110px;"/><br /><sub>Alexander William Smith</sub>](https://github.com/alwism)<br />[💻](https://github.com/snipe/snipe-it/commits?author=alwism "Code") | [<img src="https://avatars.githubusercontent.com/u/24418301?v=4" width="110px;"/><br /><sub>LEITWERK AG</sub>](https://www.leitwerk.de/)<br />[💻](https://github.com/snipe/snipe-it/commits?author=leitwerk-ag "Code") |
| [<img src="https://avatars.githubusercontent.com/u/1911435?v=4" width="110px;"/><br /><sub>Adam</sub>](http://www.aboutcher.co.uk)<br />[💻](https://github.com/snipe/snipe-it/commits?author=adamboutcher "Code") | [<img src="https://avatars.githubusercontent.com/u/16104273?v=4" width="110px;"/><br /><sub>Ian</sub>](https://snksrv.com)<br />[💻](https://github.com/snipe/snipe-it/commits?author=sneak-it "Code") | [<img src="https://avatars.githubusercontent.com/u/4023909?v=4" width="110px;"/><br /><sub>Shao Yu-Lung (Allen)</sub>](http://blog.bestlong.idv.tw/)<br />[💻](https://github.com/snipe/snipe-it/commits?author=bestlong "Code") | [<img src="https://avatars.githubusercontent.com/u/76475453?v=4" width="110px;"/><br /><sub>Haxatron</sub>](https://github.com/Haxatron)<br />[💻](https://github.com/snipe/snipe-it/commits?author=Haxatron "Code") | [<img src="https://avatars.githubusercontent.com/u/88776392?v=4" width="110px;"/><br /><sub>PlaneNuts</sub>](https://github.com/PlaneNuts)<br />[💻](https://github.com/snipe/snipe-it/commits?author=PlaneNuts "Code") | [<img src="https://avatars.githubusercontent.com/u/3842948?v=4" width="110px;"/><br /><sub>Bradley Coudriet</sub>](http://bjcpgd.cias.rit.edu)<br />[💻](https://github.com/snipe/snipe-it/commits?author=exula "Code") | [<img src="https://avatars.githubusercontent.com/u/21966173?v=4" width="110px;"/><br /><sub>Dalton Durst</sub>](https://daltondur.st)<br />[💻](https://github.com/snipe/snipe-it/commits?author=UniversalSuperBox "Code") |
| [<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/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/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!

65
TESTING.md Normal file
View File

@@ -0,0 +1,65 @@
# Using the Test Suite
This document is targeted at developers looking to make modifications to
this application's code base and want to run the existing test suite.
## Setup
Follow the instructions for installing the application locally,
making sure to have also run the [database migrations](link to db migrations).
## Unit Tests
The application will use values in the `.env.testing` file located
in the root directory to override the
default settings and/or other values that exist in your `.env` files.
Make sure to modify the section in `.env.testing` that has the
database settings. In the example below, it is connecting to the
[MariaDB](link-to-maria-db) server that is used if you install the
application using [Docker](https://docker.com).
```dotenv
# --------------------------------------------
# REQUIRED: DATABASE SETTINGS
# --------------------------------------------
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_DATABASE=snipeit
DB_USERNAME=root
DB_PASSWORD=changeme1234
```
To run the entire unit test suite, use the following command from your terminal:
`php artisan test --env=testing`
To run individual test files, you can pass the path to the test that
you want to run.
`php artisan test --env=testing tests/Unit/AccessoryTest.php`
## 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.
### Test Setup
Your application needs to be configued 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:
`php artisan dusk`
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`

View File

@@ -118,7 +118,7 @@
"description": "The duration (in seconds) that the user should be blocked from attempting to authenticate again.",
"value": "60"
},
"APP_LOG": {
"LOG_CHANNEL": {
"description": "Driver to send logs to. (errorlog for stderr)",
"value": "errorlog"
},
@@ -148,7 +148,7 @@
"image": "heroku/php",
"addons": [
"cleardb:ignite",
"heroku-redis:hobby-dev",
"heroku-redis:mini",
"papertrail:choklad"
]
}
}

View File

@@ -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.

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;
@@ -49,7 +50,7 @@ class LdapSync extends Command
$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_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;
$ldap_result_phone = Setting::getSettings()->ldap_phone_field;
@@ -57,6 +58,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();
@@ -175,8 +177,19 @@ class LdapSync extends Command
$tmp_pass = substr(str_shuffle('0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'), 0, 20);
$pass = bcrypt($tmp_pass);
$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++) {
if (empty($ldap_result_active_flag) || $results[$i][$ldap_result_active_flag][0] == 'TRUE') {
$item = [];
$item['username'] = isset($results[$i][$ldap_result_username][0]) ? $results[$i][$ldap_result_username][0] : '';
$item['employee_number'] = isset($results[$i][$ldap_result_emp_num][0]) ? $results[$i][$ldap_result_emp_num][0] : '';
@@ -191,6 +204,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'],
]);
@@ -203,7 +217,7 @@ class LdapSync extends Command
// Creating a new user.
$user = new User;
$user->password = $pass;
$user->activated = 0;
$user->activated = 1; // newly created users can log in by default, unless AD's UAC is in use, or an active flag is set (below)
$item['createorupdate'] = 'created';
}
@@ -218,19 +232,61 @@ class LdapSync extends Command
$user->department_id = $department->id;
if($item['manager'] != null) {
//Captures only the Canonical Name
$item['manager'] = ltrim($item['manager'], "CN=");
$item['manager'] = substr($item['manager'],0, strpos($item['manager'], ','));
$ldap_manager = User::where('username', $item['manager'])->first();
if ( $ldap_manager && isset($ldap_manager->id) ) {
$user->manager_id = $ldap_manager->id;
// Check Cache first
if (isset($manager_cache[$item['manager']])) {
// found in cache; use that and avoid extra lookups
$user->manager_id = $manager_cache[$item['manager']];
} else {
// Get the LDAP Manager
try {
$ldap_manager = Ldap::findLdapUsers($item['manager'], -1, $this->option('filter'));
} catch (\Exception $e) {
\Log::warning("Manager lookup caused an exception: " . $e->getMessage() . ". Falling back to direct username lookup");
// Hail-mary for Okta manager 'shortnames' - will only work if
// Okta configuration is using full email-address-style usernames
$ldap_manager = [
"count" => 1,
0 => [
$ldap_result_username => [$item['manager']]
]
];
}
if ($ldap_manager["count"] > 0) {
// Get the Manager's username
// PHP LDAP returns every LDAP attribute as an array, and 90% of the time it's an array of just one item. But, hey, it's an array.
$ldapManagerUsername = $ldap_manager[0][$ldap_result_username][0];
// Get User from Manager username.
$ldap_manager = User::where('username', $ldapManagerUsername)->first();
if ($ldap_manager && isset($ldap_manager->id)) {
// Link user to manager id.
$user->manager_id = $ldap_manager->id;
}
}
$manager_cache[$item['manager']] = $ldap_manager && isset($ldap_manager->id) ? $ldap_manager->id : null; // Store results in cache, even if 'failed'
}
}
// Sync activated state for Active Directory.
if (array_key_exists('useraccountcontrol', $results[$i])) {
/* The following is _probably_ the correct logic, but we can't use it because
if ( !empty($ldap_result_active_flag)) { // IF we have an 'active' flag set....
// ....then *most* things that are truthy will activate the user. Anything falsey will deactivate them.
// (Specifically, we don't handle a value of '0.0' correctly)
$raw_value = @$results[$i][$ldap_result_active_flag][0];
$filter_var = filter_var($raw_value, FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE);
$boolean_cast = (bool)$raw_value;
$user->activated = $filter_var ?? $boolean_cast; // if filter_var() was true or false, use that. If it's null, use the $boolean_cast
} elseif (array_key_exists('useraccountcontrol', $results[$i]) ) {
// ....otherwise, (ie if no 'active' LDAP flag is defined), IF the UAC setting exists,
// ....then use the UAC setting on the account to determine can-log-in vs. cannot-log-in
/* The following is _probably_ the correct logic, but we can't use it because
some users may have been dependent upon the previous behavior, and this
could cause additional access to be available to users they don't want
to allow to log in.
@@ -260,12 +316,11 @@ class LdapSync extends Command
'1049088', // 0x100200 NORMAL_ACCOUNT, NOT_DELEGATED
];
$user->activated = (in_array($results[$i]['useraccountcontrol'][0], $enabled_accounts)) ? 1 : 0;
}
// If we're not using AD, and there isn't an activated flag set, activate all users
elseif (empty($ldap_result_active_flag)) {
$user->activated = 1;
}
} /* implied 'else' here - leave the $user->activated flag alone. Newly-created accounts will be active.
already-existing accounts will be however the administrator has set them */
if ($item['ldap_location_override'] == true) {
$user->location_id = $item['location_id'];
@@ -284,6 +339,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];
@@ -293,7 +352,6 @@ class LdapSync extends Command
}
array_push($summary, $item);
}
}
if ($this->option('summary')) {

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');
}
}

View File

@@ -12,6 +12,7 @@ use App\Models\Statuslabel;
use Crypt;
use Illuminate\Contracts\Encryption\DecryptException;
use Image;
use Carbon\Carbon;
class Helper
{
@@ -22,12 +23,13 @@ class Helper
* @since [v2.0]
* @return string
*/
public static function parseEscapedMarkedown($str)
public static function parseEscapedMarkedown($str = null)
{
$Parsedown = new \Parsedown();
$Parsedown->setSafeMode(true);
if ($str) {
return $Parsedown->text(e($str));
return $Parsedown->text($str);
}
}
@@ -623,7 +625,7 @@ class Helper
{
$consumables = Consumable::withCount('consumableAssignments as consumable_assignments_count')->whereNotNull('min_amt')->get();
$accessories = Accessory::withCount('users as users_count')->whereNotNull('min_amt')->get();
$components = Component::withCount('assets as assets_count')->whereNotNull('min_amt')->get();
$components = Component::whereNotNull('min_amt')->get();
$avail_consumables = 0;
$items_array = [];
@@ -668,7 +670,7 @@ class Helper
}
foreach ($components as $component) {
$avail = $component->qty - $component->assets_count;
$avail = $component->numRemaining();
if ($avail < ($component->min_amt) + \App\Models\Setting::getSettings()->alert_threshold) {
if ($component->qty > 0) {
$percent = number_format((($avail / $component->qty) * 100), 0);
@@ -1124,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;
}
}

View File

@@ -0,0 +1,186 @@
<?php
namespace App\Http\Controllers\Accessories;
use App\Helpers\StorageHelper;
use App\Http\Controllers\Controller;
use App\Http\Requests\AssetFileRequest;
use App\Models\Actionlog;
use App\Models\Accessory;
use Illuminate\Support\Facades\Response;
use Illuminate\Support\Facades\Storage;
use Symfony\Accessory\HttpFoundation\JsonResponse;
use enshrined\svgSanitize\Sanitizer;
class AccessoriesFilesController extends Controller
{
/**
* Validates and stores files associated with a accessory.
*
* @todo Switch to using the AssetFileRequest form request validator.
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v1.0]
* @param AssetFileRequest $request
* @param int $accessoryId
* @return \Illuminate\Http\RedirectResponse
* @throws \Illuminate\Auth\Access\AuthorizationException
*/
public function store(AssetFileRequest $request, $accessoryId = null)
{
if (config('app.lock_passwords')) {
return redirect()->route('accessories.show', ['accessory'=>$accessoryId])->with('error', trans('general.feature_disabled'));
}
$accessory = Accessory::find($accessoryId);
if (isset($accessory->id)) {
$this->authorize('accessories.files', $accessory);
if ($request->hasFile('file')) {
if (! Storage::exists('private_uploads/accessories')) {
Storage::makeDirectory('private_uploads/accessories', 775);
}
foreach ($request->file('file') as $file) {
$extension = $file->getClientOriginalExtension();
$file_name = 'accessory-'.$accessory->id.'-'.str_random(8).'-'.str_slug(basename($file->getClientOriginalName(), '.'.$extension)).'.'.$extension;
// Check for SVG and sanitize it
if ($extension == 'svg') {
\Log::debug('This is an SVG');
\Log::debug($file_name);
$sanitizer = new Sanitizer();
$dirtySVG = file_get_contents($file->getRealPath());
$cleanSVG = $sanitizer->sanitize($dirtySVG);
try {
Storage::put('private_uploads/accessories/'.$file_name, $cleanSVG);
} catch (\Exception $e) {
\Log::debug('Upload no workie :( ');
\Log::debug($e);
}
} else {
Storage::put('private_uploads/accessories/'.$file_name, file_get_contents($file));
}
//Log the upload to the log
$accessory->logUpload($file_name, e($request->input('notes')));
}
return redirect()->route('accessories.show', $accessory->id)->with('success', trans('general.file_upload_success'));
}
return redirect()->route('accessories.show', $accessory->id)->with('error', trans('general.no_files_uploaded'));
}
// Prepare the error message
return redirect()->route('accessories.index')
->with('error', trans('general.file_does_not_exist'));
}
/**
* Deletes the selected accessory file.
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v1.0]
* @param int $accessoryId
* @param int $fileId
* @return \Illuminate\Http\RedirectResponse
* @throws \Illuminate\Auth\Access\AuthorizationException
*/
public function destroy($accessoryId = null, $fileId = null)
{
$accessory = Accessory::find($accessoryId);
// the asset is valid
if (isset($accessory->id)) {
$this->authorize('update', $accessory);
$log = Actionlog::find($fileId);
// Remove the file if one exists
if (Storage::exists('accessories/'.$log->filename)) {
try {
Storage::delete('accessories/'.$log->filename);
} catch (\Exception $e) {
\Log::debug($e);
}
}
$log->delete();
return redirect()->back()
->with('success', trans('admin/hardware/message.deletefile.success'));
}
// Redirect to the licence management page
return redirect()->route('accessories.index')->with('error', trans('general.file_does_not_exist'));
}
/**
* Allows the selected file to be viewed.
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v1.4]
* @param int $accessoryId
* @param int $fileId
* @return \Symfony\Accessory\HttpFoundation\Response
* @throws \Illuminate\Auth\Access\AuthorizationException
*/
public function show($accessoryId = null, $fileId = null, $download = true)
{
\Log::debug('Private filesystem is: '.config('filesystems.default'));
$accessory = Accessory::find($accessoryId);
// the accessory is valid
if (isset($accessory->id)) {
$this->authorize('view', $accessory);
$this->authorize('accessories.files', $accessory);
if (! $log = Actionlog::find($fileId)) {
return response('No matching record for that asset/file', 500)
->header('Content-Type', 'text/plain');
}
$file = 'private_uploads/accessories/'.$log->filename;
if (Storage::missing($file)) {
\Log::debug('FILE DOES NOT EXISTS for '.$file);
\Log::debug('URL should be '.Storage::url($file));
return response('File '.$file.' ('.Storage::url($file).') not found on server', 404)
->header('Content-Type', 'text/plain');
} else {
// We have to override the URL stuff here, since local defaults in Laravel's Flysystem
// won't work, as they're not accessible via the web
if (config('filesystems.default') == 'local') { // TODO - is there any way to fix this at the StorageHelper layer?
return StorageHelper::downloader($file);
} else {
if ($download != 'true') {
\Log::debug('display the file');
if ($contents = file_get_contents(Storage::url($file))) { // TODO - this will fail on private S3 files or large public ones
return Response::make(Storage::url($file)->header('Content-Type', mime_content_type($file)));
}
return JsonResponse::create(['error' => 'Failed validation: '], 500);
}
return StorageHelper::downloader($file);
}
}
}
return redirect()->route('accessories.index')->with('error', trans('general.file_does_not_exist', ['id' => $fileId]));
}
}

View File

@@ -63,7 +63,7 @@ class AccessoryCheckoutController extends Controller
$this->authorize('checkout', $accessory);
if (! $user = User::find($request->input('assigned_to'))) {
return redirect()->route('checkout/accessory', $accessory->id)->with('error', trans('admin/accessories/message.checkout.user_does_not_exist'));
return redirect()->route('accessories.checkout.show', $accessory->id)->with('error', trans('admin/accessories/message.checkout.user_does_not_exist'));
}
// Update the accessory data

View File

@@ -19,6 +19,8 @@ use App\Models\Accessory;
use App\Models\License;
use App\Models\Component;
use App\Models\Consumable;
use App\Notifications\AcceptanceAssetAcceptedNotification;
use App\Notifications\AcceptanceAssetDeclinedNotification;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
@@ -236,12 +238,49 @@ class AcceptanceController extends Controller
}
$acceptance->accept($sig_filename, $item->getEula(), $pdf_filename);
$acceptance->notify(new AcceptanceAssetAcceptedNotification($data));
event(new CheckoutAccepted($acceptance));
$return_msg = trans('admin/users/message.accepted');
} else {
// Format the data to send the declined notification
$branding_settings = SettingsController::getPDFBranding();
// This is the most horriblest
switch($acceptance->checkoutable_type){
case 'App\Models\Asset':
$assigned_to = User::find($acceptance->assigned_to_id)->present()->fullName;
break;
case 'App\Models\Accessory':
$assigned_to = User::find($item->assignedTo);
break;
case 'App\Models\LicenseSeat':
$assigned_to = User::find($acceptance->assigned_to_id)->present()->fullName;
break;
case 'App\Models\Component':
$assigned_to = User::find($acceptance->assigned_to_id)->present()->fullName;
break;
case 'App\Models\Consumable':
$assigned_to = User::find($acceptance->assigned_to_id)->present()->fullName;
break;
}
$data = [
'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),
'assigned_to' => $assigned_to,
'company_name' => $branding_settings->site_name,
'date_settings' => $branding_settings->date_display_format,
];
$acceptance->decline($sig_filename);
$acceptance->notify(new AcceptanceAssetDeclinedNotification($data));
event(new CheckoutDeclined($acceptance));
$return_msg = trans('admin/users/message.declined');
}

View File

@@ -120,7 +120,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 +140,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');
}
@@ -357,19 +364,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 +405,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);
}
/**
@@ -885,11 +907,9 @@ class AssetsController extends Controller
if ($request->has('status_id')) {
$asset->status_id = $request->input('status_id');
}
$checkin_at = $request->filled('checkin_at') ? $request->input('checkin_at').' '. date('H:i:s') : date('Y-m-d H:i:s');
$checkin_at = null;
if ($request->filled('checkin_at')) {
$checkin_at = $request->input('checkin_at');
}
if ($asset->save()) {
event(new CheckoutableCheckedIn($asset, $target, Auth::user(), $request->input('note'), $checkin_at));
@@ -912,7 +932,7 @@ class AssetsController extends Controller
$this->authorize('checkin', Asset::class);
$asset = Asset::where('asset_tag', $request->input('asset_tag'))->first();
if($asset) {
if ($asset) {
return $this->checkin($request, $asset->id);
}

View File

@@ -246,7 +246,8 @@ class ComponentsController extends Controller
'created_at' => \Carbon::now(),
'assigned_qty' => $request->get('assigned_qty', 1),
'user_id' => \Auth::id(),
'asset_id' => $request->get('assigned_to')
'asset_id' => $request->get('assigned_to'),
'note' => $request->get('note'),
]);
$component->logCheckout($request->input('note'), $asset);

View File

@@ -228,9 +228,11 @@ class ConsumablesController extends Controller
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'),
'admin' => ($consumable_assignment->admin) ? $consumable_assignment->admin->present()->nameUrl() : '',
'note' => ($consumable_assignment->note) ? e($consumable_assignment->note) : null,
'admin' => ($consumable_assignment->admin) ? $consumable_assignment->admin->present()->nameUrl() : null,
];
}
@@ -273,6 +275,7 @@ class ConsumablesController extends Controller
'consumable_id' => $consumable->id,
'user_id' => $user->id,
'assigned_to' => $assigned_to,
'note' => $request->input('note'),
]);
// Log checkout event

View File

@@ -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'];
}

View File

@@ -39,7 +39,7 @@ class LicenseSeatsController extends Controller
}
$total = $seats->count();
$offset = (($seats) && (request('offset') > $total)) ? 0 : request('offset', 0);
$offset = (($seats) && (request('offset') >= $total)) ? 0 : request('offset', 0);
$limit = request('limit', 50);
$seats = $seats->skip($offset)->take($limit)->get();

View File

@@ -27,7 +27,7 @@ class LocationsController extends Controller
$allowed_columns = [
'id', 'name', 'address', 'address2', 'city', 'state', 'country', 'zip', 'created_at',
'updated_at', 'manager_id', 'image',
'assigned_assets_count', 'users_count', 'assets_count', 'currency', 'ldap_ou', ];
'assigned_assets_count', 'users_count', 'assets_count','assigned_assets_count', 'assets_count', 'rtd_assets_count', 'currency', 'ldap_ou', ];
$locations = Location::with('parent', 'manager', 'children')->select([
'locations.id',
@@ -47,6 +47,7 @@ class LocationsController extends Controller
'locations.currency',
])->withCount('assignedAssets as assigned_assets_count')
->withCount('assets as assets_count')
->withCount('rtd_assets as rtd_assets_count')
->withCount('users as users_count');
if ($request->filled('search')) {
@@ -157,7 +158,9 @@ class LocationsController extends Controller
])
->withCount('assignedAssets as assigned_assets_count')
->withCount('assets as assets_count')
->withCount('users as users_count')->findOrFail($id);
->withCount('rtd_assets as rtd_assets_count')
->withCount('users as users_count')
->findOrFail($id);
return (new LocationsTransformer)->transformLocation($location);
}

View File

@@ -20,7 +20,7 @@ class ReportsController extends Controller
{
$this->authorize('reports.view');
$actionlogs = Actionlog::with('item', 'user', 'target', 'location');
$actionlogs = Actionlog::with('item', 'user', 'admin', 'target', 'location');
if ($request->filled('search')) {
$actionlogs = $actionlogs->TextSearch(e($request->input('search')));

View File

@@ -9,6 +9,8 @@ use App\Http\Transformers\StatuslabelsTransformer;
use App\Models\Asset;
use App\Models\Statuslabel;
use Illuminate\Http\Request;
use App\Http\Transformers\PieChartTransformer;
use Illuminate\Support\Arr;
class StatuslabelsController extends Controller
{
@@ -188,43 +190,54 @@ class StatuslabelsController extends Controller
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v3.0]
* @return \Illuminate\Http\Response
* @return array
*/
public function getAssetCountByStatuslabel()
{
$this->authorize('view', Statuslabel::class);
$statuslabels = Statuslabel::withCount('assets')->get();
$labels = [];
$points = [];
$default_color_count = 0;
$colors_array = [];
foreach ($statuslabels as $statuslabel) {
if ($statuslabel->assets_count > 0) {
$labels[] = $statuslabel->name.' ('.number_format($statuslabel->assets_count).')';
$points[] = $statuslabel->assets_count;
if ($statuslabel->color != '') {
$colors_array[] = $statuslabel->color;
} else {
$colors_array[] = Helper::defaultChartColors($default_color_count);
}
$default_color_count++;
$total[$statuslabel->name]['label'] = $statuslabel->name;
$total[$statuslabel->name]['count'] = $statuslabel->assets_count;
if ($statuslabel->color != '') {
$total[$statuslabel->name]['color'] = $statuslabel->color;
}
}
$result = [
'labels' => $labels,
'datasets' => [[
'data' => $points,
'backgroundColor' => $colors_array,
'hoverBackgroundColor' => $colors_array,
]],
];
return (new PieChartTransformer())->transformPieChartDate($total);
return $result;
}
/**
* Show a count of assets by meta status type for pie chart
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v6.0.11]
* @return array
*/
public function getAssetCountByMetaStatus()
{
$this->authorize('view', Statuslabel::class);
$total['rtd']['label'] = trans('general.ready_to_deploy');
$total['rtd']['count'] = Asset::RTD()->count();
$total['deployed']['label'] = trans('general.deployed');
$total['deployed']['count'] = Asset::Deployed()->count();
$total['archived']['label'] = trans('general.archived');
$total['archived']['count'] = Asset::Archived()->count();
$total['pending']['label'] = trans('general.pending');
$total['pending']['count'] = Asset::Pending()->count();
$total['undeployable']['label'] = trans('general.undeployable');
$total['undeployable']['count'] = Asset::Undeployable()->count();
return (new PieChartTransformer())->transformPieChartDate($total);
}
/**

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;
@@ -66,6 +67,8 @@ class UsersController extends Controller
'users.zip',
'users.remote',
'users.ldap_import',
'users.start_date',
'users.end_date',
])->with('manager', 'groups', 'userloc', 'company', 'department', 'assets', 'licenses', 'accessories', 'consumables', 'createdBy',)
->withCount('assets as assets_count', 'licenses as licenses_count', 'accessories as accessories_count', 'consumables as consumables_count');
@@ -146,6 +149,15 @@ class UsersController extends Controller
$users = $users->where('remote', '=', $request->input('remote'));
}
if ($request->filled('start_date')) {
$users = $users->where('users.start_date', '=', $request->input('start_date'));
}
if ($request->filled('end_date')) {
$users = $users->where('users.end_date', '=', $request->input('end_date'));
}
if ($request->filled('assets_count')) {
$users->has('assets', '=', $request->input('assets_count'));
}
@@ -200,7 +212,7 @@ class UsersController extends Controller
'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',
'country', 'zip', 'id', 'ldap_import', 'remote', 'start_date', 'end_date',
];
$sort = in_array($request->get('sort'), $allowed_columns) ? $request->get('sort') : 'first_name';
@@ -479,6 +491,26 @@ 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')));
}
return response()->Helper::formatStandardApiResponse('success', null, trans('admin/users/message.inventorynotification.success'));
}
/**
* Return JSON containing a list of consumables assigned to a user.

View File

@@ -463,7 +463,18 @@ class AssetModelsController extends Controller
$data[$customField->db_column] = $defaultValue;
}
$rules = $model->fieldset->validation_rules();
$fieldsets = $model->fieldset->validation_rules();
$rules = array();
foreach ($fieldsets as $fieldset => $validation){
// If the field is marked as required, eliminate the rule so it doesn't interfere with the default values
// (we are at model level, the rule still applies when creating a new asset using this model)
$index = array_search('required', $validation);
if ($index !== false){
$validation[$index] = 'nullable';
}
$rules[$fieldset] = $validation;
}
$validator = Validator::make($data, $rules);

View File

@@ -62,7 +62,7 @@ class AssetModelsFilesController extends Controller
$model->logUpload($file_name, e($request->get('notes')));
}
return redirect()->back()->with('success', trans('admin/hardware/message.upload.success'));
return redirect()->back()->with('success', trans('general.file_upload_success'));
}
return redirect()->back()->with('error', trans('admin/hardware/message.upload.nofiles'));

View File

@@ -12,6 +12,7 @@ use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Session;
use App\Http\Requests\AssetCheckoutRequest;
class BulkAssetsController extends Controller
{
@@ -32,7 +33,6 @@ class BulkAssetsController extends Controller
if (! $request->filled('ids')) {
return redirect()->back()->with('error', trans('admin/hardware/message.update.no_assets_selected'));
}
// Figure out where we need to send the user after the update is complete, and store that in the session
@@ -102,6 +102,8 @@ class BulkAssetsController extends Controller
|| ($request->filled('company_id'))
|| ($request->filled('status_id'))
|| ($request->filled('model_id'))
|| ($request->filled('null_purchase_date'))
|| ($request->filled('null_expected_checkin_date'))
) {
foreach ($assets as $assetId) {
@@ -116,6 +118,14 @@ class BulkAssetsController extends Controller
->conditionallyAddItem('supplier_id')
->conditionallyAddItem('warranty_months');
if ($request->input('null_purchase_date')=='1') {
$this->update_array['purchase_date'] = null;
}
if ($request->input('null_expected_checkin_date')=='1') {
$this->update_array['expected_checkin'] = null;
}
if ($request->filled('purchase_cost')) {
$this->update_array['purchase_cost'] = Helper::ParseCurrency($request->input('purchase_cost'));
}
@@ -239,7 +249,7 @@ class BulkAssetsController extends Controller
* Process Multiple Checkout Request
* @return View
*/
public function storeCheckout(Request $request)
public function storeCheckout(AssetCheckoutRequest $request)
{
$this->authorize('checkout', Asset::class);
@@ -250,7 +260,7 @@ class BulkAssetsController extends Controller
$target = $this->determineCheckoutTarget();
if (! is_array($request->get('selected_assets'))) {
return redirect()->route('hardware/bulkcheckout')->withInput()->with('error', trans('admin/hardware/message.checkout.no_assets_selected'));
return redirect()->route('hardware.bulkcheckout.show')->withInput()->with('error', trans('admin/hardware/message.checkout.no_assets_selected'));
}
$asset_ids = array_filter($request->get('selected_assets'));
@@ -297,9 +307,9 @@ class BulkAssetsController extends Controller
return redirect()->to('hardware')->with('success', trans('admin/hardware/message.checkout.success'));
}
// Redirect to the asset management page with error
return redirect()->to('hardware/bulk-checkout')->with('error', trans('admin/hardware/message.checkout.error'))->withErrors($errors);
return redirect()->route('hardware.bulkcheckout.show')->with('error', trans('admin/hardware/message.checkout.error'))->withErrors($errors);
} catch (ModelNotFoundException $e) {
return redirect()->to('hardware/bulk-checkout')->with('error', $e->getErrors());
return redirect()->route('hardware.bulkcheckout.show')->with('error', $e->getErrors());
}
}
}

View File

@@ -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.");
}
}
@@ -473,6 +471,11 @@ class LoginController extends Controller
}
$request->session()->regenerate(true);
if ($request->session()->has('password_hash_'.Auth::getDefaultDriver())){
$request->session()->remove('password_hash_'.Auth::getDefaultDriver());
}
Auth::logout();
if (! empty($sloRedirectUrl)) {

View File

@@ -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'));
}

View File

@@ -142,6 +142,6 @@ class SamlController extends Controller
return view('errors.403');
}
return redirect()->route('logout')->with(['saml_logout' => true,'saml_slo_redirect_url' => $sloUrl]);
return redirect()->route('logout.get')->with(['saml_logout' => true,'saml_slo_redirect_url' => $sloUrl]);
}
}

View File

@@ -87,6 +87,7 @@ class ComponentCheckoutController extends Controller
'created_at' => date('Y-m-d H:i:s'),
'assigned_qty' => $request->input('assigned_qty'),
'asset_id' => $asset_id,
'note' => $request->input('note'),
]);
event(new CheckoutableCheckedOut($component, $asset, Auth::user(), $request->input('note')));

View File

@@ -0,0 +1,180 @@
<?php
namespace App\Http\Controllers\Components;
use App\Helpers\StorageHelper;
use App\Http\Controllers\Controller;
use App\Http\Requests\AssetFileRequest;
use App\Models\Actionlog;
use App\Models\Component;
use Illuminate\Support\Facades\Response;
use Illuminate\Support\Facades\Storage;
use Symfony\Component\HttpFoundation\JsonResponse;
use enshrined\svgSanitize\Sanitizer;
class ComponentsFilesController extends Controller
{
/**
* Validates and stores files associated with a component.
*
* @todo Switch to using the AssetFileRequest form request validator.
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v1.0]
* @param AssetFileRequest $request
* @param int $componentId
* @return \Illuminate\Http\RedirectResponse
* @throws \Illuminate\Auth\Access\AuthorizationException
*/
public function store(AssetFileRequest $request, $componentId = null)
{
if (config('app.lock_passwords')) {
return redirect()->route('components.show', ['component'=>$componentId])->with('error', trans('general.feature_disabled'));
}
$component = Component::find($componentId);
if (isset($component->id)) {
$this->authorize('update', $component);
if ($request->hasFile('file')) {
if (! Storage::exists('private_uploads/components')) {
Storage::makeDirectory('private_uploads/components', 775);
}
foreach ($request->file('file') as $file) {
$extension = $file->getClientOriginalExtension();
$file_name = 'component-'.$component->id.'-'.str_random(8).'-'.str_slug(basename($file->getClientOriginalName(), '.'.$extension)).'.'.$extension;
// Check for SVG and sanitize it
if ($extension == 'svg') {
\Log::debug('This is an SVG');
\Log::debug($file_name);
$sanitizer = new Sanitizer();
$dirtySVG = file_get_contents($file->getRealPath());
$cleanSVG = $sanitizer->sanitize($dirtySVG);
try {
Storage::put('private_uploads/components/'.$file_name, $cleanSVG);
} catch (\Exception $e) {
\Log::debug('Upload no workie :( ');
\Log::debug($e);
}
} else {
Storage::put('private_uploads/components/'.$file_name, file_get_contents($file));
}
//Log the upload to the log
$component->logUpload($file_name, e($request->input('notes')));
}
return redirect()->route('components.show', $component->id)->with('success', trans('general.file_upload_success'));
}
return redirect()->route('components.show', $component->id)->with('error', trans('general.no_files_uploaded'));
}
// Prepare the error message
return redirect()->route('components.index')
->with('error', trans('general.file_does_not_exist'));
}
/**
* Deletes the selected component file.
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v1.0]
* @param int $componentId
* @param int $fileId
* @return \Illuminate\Http\RedirectResponse
* @throws \Illuminate\Auth\Access\AuthorizationException
*/
public function destroy($componentId = null, $fileId = null)
{
$component = Component::find($componentId);
// the asset is valid
if (isset($component->id)) {
$this->authorize('update', $component);
$log = Actionlog::find($fileId);
// Remove the file if one exists
if (Storage::exists('components/'.$log->filename)) {
try {
Storage::delete('components/'.$log->filename);
} catch (\Exception $e) {
\Log::debug($e);
}
}
$log->delete();
return redirect()->back()
->with('success', trans('admin/hardware/message.deletefile.success'));
}
// Redirect to the licence management page
return redirect()->route('components.index')->with('error', trans('general.file_does_not_exist'));
}
/**
* Allows the selected file to be viewed.
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v1.4]
* @param int $componentId
* @param int $fileId
* @return \Symfony\Component\HttpFoundation\Response
* @throws \Illuminate\Auth\Access\AuthorizationException
*/
public function show($componentId = null, $fileId = null, $download = true)
{
\Log::debug('Private filesystem is: '.config('filesystems.default'));
$component = Component::find($componentId);
// the component is valid
if (isset($component->id)) {
$this->authorize('view', $component);
$this->authorize('components.files', $component);
if (! $log = Actionlog::find($fileId)) {
return response('No matching record for that asset/file', 500)
->header('Content-Type', 'text/plain');
}
$file = 'private_uploads/components/'.$log->filename;
if (Storage::missing($file)) {
\Log::debug('FILE DOES NOT EXISTS for '.$file);
\Log::debug('URL should be '.Storage::url($file));
return response('File '.$file.' ('.Storage::url($file).') not found on server', 404)
->header('Content-Type', 'text/plain');
} else {
if (config('filesystems.default') == 'local') { // TODO - is there any way to fix this at the StorageHelper layer?
return StorageHelper::downloader($file);
} else {
if ($download != 'true') {
\Log::debug('display the file');
if ($contents = file_get_contents(Storage::url($file))) { // TODO - this will fail on private S3 files or large public ones
return Response::make(Storage::url($file)->header('Content-Type', mime_content_type($file)));
}
return JsonResponse::create(['error' => 'Failed validation: '], 500);
}
return StorageHelper::downloader($file);
}
}
}
return redirect()->route('components.index')->with('error', trans('general.file_does_not_exist', ['id' => $fileId]));
}
}

View File

@@ -56,7 +56,7 @@ class ConsumableCheckoutController extends Controller
// Check if the user exists
if (is_null($user = User::find($assigned_to))) {
// Redirect to the consumable management page with error
return redirect()->route('checkout/consumable', $consumable)->with('error', trans('admin/consumables/message.checkout.user_does_not_exist'));
return redirect()->route('consumables.checkout.show', $consumable)->with('error', trans('admin/consumables/message.checkout.user_does_not_exist'))->withInput();
}
// Update the consumable data
@@ -66,6 +66,7 @@ class ConsumableCheckoutController extends Controller
'consumable_id' => $consumable->id,
'user_id' => $admin_user->id,
'assigned_to' => e($request->input('assigned_to')),
'note' => $request->input('note'),
]);
event(new CheckoutableCheckedOut($consumable, $user, Auth::user(), $request->input('note')));

View File

@@ -0,0 +1,180 @@
<?php
namespace App\Http\Controllers\Consumables;
use App\Helpers\StorageHelper;
use App\Http\Controllers\Controller;
use App\Http\Requests\AssetFileRequest;
use App\Models\Actionlog;
use App\Models\Consumable;
use Illuminate\Support\Facades\Response;
use Illuminate\Support\Facades\Storage;
use Symfony\Consumable\HttpFoundation\JsonResponse;
use enshrined\svgSanitize\Sanitizer;
class ConsumablesFilesController extends Controller
{
/**
* Validates and stores files associated with a consumable.
*
* @todo Switch to using the AssetFileRequest form request validator.
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v1.0]
* @param AssetFileRequest $request
* @param int $consumableId
* @return \Illuminate\Http\RedirectResponse
* @throws \Illuminate\Auth\Access\AuthorizationException
*/
public function store(AssetFileRequest $request, $consumableId = null)
{
if (config('app.lock_passwords')) {
return redirect()->route('consumables.show', ['consumable'=>$consumableId])->with('error', trans('general.feature_disabled'));
}
$consumable = Consumable::find($consumableId);
if (isset($consumable->id)) {
$this->authorize('update', $consumable);
if ($request->hasFile('file')) {
if (! Storage::exists('private_uploads/consumables')) {
Storage::makeDirectory('private_uploads/consumables', 775);
}
foreach ($request->file('file') as $file) {
$extension = $file->getClientOriginalExtension();
$file_name = 'consumable-'.$consumable->id.'-'.str_random(8).'-'.str_slug(basename($file->getClientOriginalName(), '.'.$extension)).'.'.$extension;
// Check for SVG and sanitize it
if ($extension == 'svg') {
\Log::debug('This is an SVG');
\Log::debug($file_name);
$sanitizer = new Sanitizer();
$dirtySVG = file_get_contents($file->getRealPath());
$cleanSVG = $sanitizer->sanitize($dirtySVG);
try {
Storage::put('private_uploads/consumables/'.$file_name, $cleanSVG);
} catch (\Exception $e) {
\Log::debug('Upload no workie :( ');
\Log::debug($e);
}
} else {
Storage::put('private_uploads/consumables/'.$file_name, file_get_contents($file));
}
//Log the upload to the log
$consumable->logUpload($file_name, e($request->input('notes')));
}
return redirect()->route('consumables.show', $consumable->id)->with('success', trans('general.file_upload_success'));
}
return redirect()->route('consumables.show', $consumable->id)->with('error', trans('general.no_files_uploaded'));
}
// Prepare the error message
return redirect()->route('consumables.index')
->with('error', trans('general.file_does_not_exist'));
}
/**
* Deletes the selected consumable file.
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v1.0]
* @param int $consumableId
* @param int $fileId
* @return \Illuminate\Http\RedirectResponse
* @throws \Illuminate\Auth\Access\AuthorizationException
*/
public function destroy($consumableId = null, $fileId = null)
{
$consumable = Consumable::find($consumableId);
// the asset is valid
if (isset($consumable->id)) {
$this->authorize('update', $consumable);
$log = Actionlog::find($fileId);
// Remove the file if one exists
if (Storage::exists('consumables/'.$log->filename)) {
try {
Storage::delete('consumables/'.$log->filename);
} catch (\Exception $e) {
\Log::debug($e);
}
}
$log->delete();
return redirect()->back()
->with('success', trans('admin/hardware/message.deletefile.success'));
}
// Redirect to the licence management page
return redirect()->route('consumables.index')->with('error', trans('general.file_does_not_exist'));
}
/**
* Allows the selected file to be viewed.
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v1.4]
* @param int $consumableId
* @param int $fileId
* @return \Symfony\Consumable\HttpFoundation\Response
* @throws \Illuminate\Auth\Access\AuthorizationException
*/
public function show($consumableId = null, $fileId = null, $download = true)
{
$consumable = Consumable::find($consumableId);
// the consumable is valid
if (isset($consumable->id)) {
$this->authorize('view', $consumable);
$this->authorize('consumables.files', $consumable);
if (! $log = Actionlog::find($fileId)) {
return response('No matching record for that asset/file', 500)
->header('Content-Type', 'text/plain');
}
$file = 'private_uploads/consumables/'.$log->filename;
if (Storage::missing($file)) {
\Log::debug('FILE DOES NOT EXISTS for '.$file);
\Log::debug('URL should be '.Storage::url($file));
return response('File '.$file.' ('.Storage::url($file).') not found on server', 404)
->header('Content-Type', 'text/plain');
} else {
// We have to override the URL stuff here, since local defaults in Laravel's Flysystem
// won't work, as they're not accessible via the web
if (config('filesystems.default') == 'local') { // TODO - is there any way to fix this at the StorageHelper layer?
return StorageHelper::downloader($file);
} else {
if ($download != 'true') {
\Log::debug('display the file');
if ($contents = file_get_contents(Storage::url($file))) { // TODO - this will fail on private S3 files or large public ones
return Response::make(Storage::url($file)->header('Content-Type', mime_content_type($file)));
}
return JsonResponse::create(['error' => 'Failed validation: '], 500);
}
return StorageHelper::downloader($file);
}
}
}
return redirect()->route('consumables.index')->with('error', trans('general.file_does_not_exist', ['id' => $fileId]));
}
}

View File

@@ -86,14 +86,24 @@ 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()
]);
@@ -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'));
@@ -235,6 +256,10 @@ class CustomFieldsController extends Controller
$field->format = e($request->get('format'));
}
if($field->element == 'checkbox' || $field->element == 'radio'){
$field->format = 'ANY';
}
if ($field->save()) {
return redirect()->route('fields.index')->with('success', trans('admin/custom_fields/message.field.update.success'));
}

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'))) {

View File

@@ -54,7 +54,8 @@ class DepartmentsController extends Controller
$department->fill($request->all());
$department->user_id = Auth::user()->id;
$department->manager_id = ($request->filled('manager_id') ? $request->input('manager_id') : null);
$department->location_id = ($request->filled('location_id') ? $request->input('location_id') : null);
$department->company_id = ($request->filled('company_id') ? $request->input('company_id') : null);
$department = $request->handleImages($department);
if ($department->save()) {
@@ -167,6 +168,8 @@ class DepartmentsController extends Controller
$department->fill($request->all());
$department->manager_id = ($request->filled('manager_id') ? $request->input('manager_id') : null);
$department->location_id = ($request->filled('location_id') ? $request->input('location_id') : null);
$department->company_id = ($request->filled('company_id') ? $request->input('company_id') : null);
$department = $request->handleImages($department);

View File

@@ -61,6 +61,7 @@ class LicenseCheckoutController extends Controller
$licenseSeat = $this->findLicenseSeatToCheckout($license, $seatId);
$licenseSeat->user_id = Auth::id();
$checkoutMethod = 'checkoutTo'.ucwords(request('checkout_to_type'));
if ($this->$checkoutMethod($licenseSeat)) {
@@ -76,14 +77,14 @@ class LicenseCheckoutController extends Controller
if (! $licenseSeat) {
if ($seatId) {
return redirect()->route('licenses.index')->with('error', 'This Seat is not available for checkout.');
throw new \Illuminate\Http\Exceptions\HttpResponseException(redirect()->route('licenses.index')->with('error', 'This Seat is not available for checkout.'));
}
return redirect()->route('licenses.index')->with('error', 'There are no available seats for this license');
throw new \Illuminate\Http\Exceptions\HttpResponseException(redirect()->route('licenses.index')->with('error', 'There are no available seats for this license.'));
}
if (! $licenseSeat->license->is($license)) {
return redirect()->route('licenses.index')->with('error', 'The license seat provided does not match the license.');
throw new \Illuminate\Http\Exceptions\HttpResponseException(redirect()->route('licenses.index')->with('error', 'The license seat provided does not match the license.'));
}
return $licenseSeat;

View File

@@ -135,6 +135,7 @@ class LicenseFilesController extends Controller
// the license is valid
if (isset($license->id)) {
$this->authorize('view', $license);
$this->authorize('licenses.files', $license);
if (! $log = Actionlog::find($fileId)) {
return response('No matching record for that asset/file', 500)
@@ -171,6 +172,6 @@ class LicenseFilesController extends Controller
}
}
return redirect()->route('license.index')->with('error', trans('admin/licenses/message.does_not_exist', ['id' => $fileId]));
return redirect()->route('licenses.index')->with('error', trans('admin/licenses/message.does_not_exist', ['id' => $fileId]));
}
}

View File

@@ -3,8 +3,11 @@
namespace App\Http\Controllers;
use App\Http\Requests\ImageUploadRequest;
use App\Models\Asset;
use App\Models\Setting;
use Auth;
use App\Models\User;
use App\Notifications\CurrentInventory;
use Illuminate\Support\Facades\Auth;
use Gate;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
@@ -133,7 +136,7 @@ class ProfileController extends Controller
public function password()
{
$user = Auth::user();
return view('account/change-password', compact('user'));
}
@@ -161,7 +164,7 @@ class ProfileController extends Controller
$validator = \Validator::make($request->all(), $rules);
$validator->after(function ($validator) use ($request, $user) {
if (! Hash::check($request->input('current_password'), $user->password)) {
$validator->errors()->add('current_password', trans('validation.hashed_pass'));
$validator->errors()->add('current_password', trans('validation.custom.hashed_pass'));
}
// This checks to make sure that the user's password isn't the same as their username,
@@ -186,6 +189,9 @@ class ProfileController extends Controller
if (! $validator->fails()) {
$user->password = Hash::make($request->input('password'));
$user->save();
// Log the user out of other devices
Auth::logoutOtherDevices($request->input('password'));
return redirect()->route('account.password.index')->with('success', 'Password updated!');
}
@@ -213,4 +219,47 @@ class ProfileController extends Controller
$request->session()->put('menu_state', 'closed');
}
}
/**
* Print inventory
*
* @author A. Gianotto
* @since [v6.0.12]
* @return Illuminate\View\View
*/
public function printInventory()
{
$show_user = Auth::user();
return view('users/print')
->with('assets', Auth::user()->assets)
->with('licenses', $show_user->licenses()->get())
->with('accessories', $show_user->accessories()->get())
->with('consumables', $show_user->consumables()->get())
->with('show_user', $show_user)
->with('settings', Setting::getSettings());
}
/**
* Emails user a list of assigned assets
*
* @author A. Gianotto
* @since [v6.0.12]
* @return \Illuminate\Http\RedirectResponse
*/
public function emailAssetList()
{
if (!$user = User::find(Auth::user()->id)) {
return redirect()->back()
->with('error', trans('admin/users/message.user_not_found', ['id' => $id]));
}
if (empty($user->email)) {
return redirect()->back()->with('error', trans('admin/users/message.user_has_no_email'));
}
$user->notify((new CurrentInventory($user)));
return redirect()->back()->with('success', trans('admin/users/general.user_notified'));
}
}

View File

@@ -22,6 +22,8 @@ use Illuminate\Support\Facades\View;
use Input;
use League\Csv\Reader;
use Symfony\Component\HttpFoundation\StreamedResponse;
use League\Csv\EscapeFormula;
/**
* This controller handles all actions related to Reports for
@@ -411,6 +413,7 @@ class ReportsController extends Controller
$customfields = CustomField::get();
$response = new StreamedResponse(function () use ($customfields, $request) {
\Log::debug('Starting streamed response');
\Log::debug('CSV escaping is set to: '.config('app.escape_formulas'));
// Open output stream
$handle = fopen('php://output', 'w');
@@ -422,6 +425,9 @@ class ReportsController extends Controller
$header = [];
if ($request->filled('id')) {
$header[] = trans('general.id');
}
if ($request->filled('company')) {
$header[] = trans('general.company');
@@ -552,6 +558,10 @@ class ReportsController extends Controller
$header[] = trans('general.updated_at');
}
if ($request->filled('deleted_at')) {
$header[] = trans('general.deleted');
}
if ($request->filled('last_audit_date')) {
$header[] = trans('general.last_audit');
}
@@ -564,6 +574,10 @@ class ReportsController extends Controller
$header[] = trans('general.notes');
}
if ($request->filled('url')) {
$header[] = trans('admin/manufacturers/table.url');
}
foreach ($customfields as $customfield) {
if ($request->input($customfield->db_column_name()) == '1') {
@@ -578,7 +592,7 @@ class ReportsController extends Controller
\Log::debug('Added headers: '.$executionTime);
$assets = \App\Models\Company::scopeCompanyables(Asset::select('assets.*'))->with(
'location', 'assetstatus', 'assetlog', 'company', 'defaultLoc', 'assignedTo',
'location', 'assetstatus', 'company', 'defaultLoc', 'assignedTo',
'model.category', 'model.manufacturer', 'supplier');
if ($request->filled('by_location_id')) {
@@ -586,7 +600,6 @@ class ReportsController extends Controller
}
if ($request->filled('by_rtd_location_id')) {
\Log::debug('RTD location should match: '.$request->input('by_rtd_location_id'));
$assets->where('assets.rtd_location_id', $request->input('by_rtd_location_id'));
}
@@ -607,7 +620,6 @@ class ReportsController extends Controller
}
if ($request->filled('by_dept_id')) {
\Log::debug('Only users in dept '.$request->input('by_dept_id'));
$assets->CheckedOutToTargetInDepartment($request->input('by_dept_id'));
}
@@ -642,19 +654,32 @@ class ReportsController extends Controller
if (($request->filled('next_audit_start')) && ($request->filled('next_audit_end'))) {
$assets->whereBetween('assets.next_audit_date', [$request->input('next_audit_start'), $request->input('next_audit_end')]);
}
if($request->filled('exclude_archived')){
if ($request->filled('exclude_archived')) {
$assets->notArchived();
}
if ($request->input('deleted_assets') == '1') {
$assets->withTrashed();
}
if ($request->input('deleted_assets') == '0') {
$assets->onlyTrashed();
}
$assets->orderBy('assets.id', 'ASC')->chunk(20, function ($assets) use ($handle, $customfields, $request) {
$executionTime = microtime(true) - $_SERVER['REQUEST_TIME_FLOAT'];
\Log::debug('Walking results: '.$executionTime);
$count = 0;
$formatter = new EscapeFormula("`");
foreach ($assets as $asset) {
$count++;
$row = [];
if ($request->filled('id')) {
$row[] = ($asset->id) ? $asset->id : '';
}
if ($request->filled('company')) {
$row[] = ($asset->company) ? $asset->company->name : '';
}
@@ -783,7 +808,7 @@ class ReportsController extends Controller
if ($request->filled('warranty')) {
$row[] = ($asset->warranty_months) ? $asset->warranty_months : '';
$row[] = $asset->present()->warrantee_expires();
$row[] = $asset->present()->warranty_expires();
}
if ($request->filled('depreciation')) {
@@ -810,6 +835,10 @@ class ReportsController extends Controller
$row[] = ($asset->updated_at) ? $asset->updated_at : '';
}
if ($request->filled('deleted_at')) {
$row[] = ($asset->deleted_at) ? $asset->deleted_at : '';
}
if ($request->filled('last_audit_date')) {
$row[] = ($asset->last_audit_date) ? $asset->last_audit_date : '';
}
@@ -822,13 +851,27 @@ class ReportsController extends Controller
$row[] = ($asset->notes) ? $asset->notes : '';
}
if ($request->filled('url')) {
$row[] = config('app.url').'/hardware/'.$asset->id ;
}
foreach ($customfields as $customfield) {
$column_name = $customfield->db_column_name();
if ($request->filled($customfield->db_column_name())) {
$row[] = $asset->$column_name;
}
}
fputcsv($handle, $row);
// CSV_ESCAPE_FORMULAS is set to false in the .env
if (config('app.escape_formulas') === false) {
fputcsv($handle, $row);
// CSV_ESCAPE_FORMULAS is set to true or is not set in the .env
} else {
fputcsv($handle, $formatter->escapeRecord($row));
}
$executionTime = microtime(true) - $_SERVER['REQUEST_TIME_FLOAT'];
\Log::debug('-- Record '.$count.' Asset ID:'.$asset->id.' in '.$executionTime);
}
@@ -979,7 +1022,11 @@ class ReportsController extends Controller
}
$assetItem = $acceptance->checkoutable;
$logItem = $assetItem->checkouts()->where('created_at', '=', $acceptance->created_at)->get()[0];
if (is_null($acceptance->created_at)){
return redirect()->route('reports/unaccepted_assets')->with('error', trans('general.bad_data'));
} else {
$logItem = $assetItem->checkouts()->where('created_at', '=', $acceptance->created_at)->get()[0];
}
if(!$assetItem->assignedTo->locale){
Notification::locale(Setting::getSettings()->locale)->send(
@@ -1036,9 +1083,9 @@ class ReportsController extends Controller
* Get all assets with pending checkout acceptances
*/
if($showDeleted) {
$acceptances = CheckoutAcceptance::pending()->withTrashed()->with(['assignedTo', 'checkoutable.assignedTo', 'checkoutable.model'])->get();
$acceptances = CheckoutAcceptance::pending()->where('checkoutable_type', 'App\Models\Asset')->withTrashed()->with(['assignedTo', 'checkoutable.assignedTo', 'checkoutable.model'])->get();
} else {
$acceptances = CheckoutAcceptance::pending()->with(['assignedTo', 'checkoutable.assignedTo', 'checkoutable.model'])->get();
$acceptances = CheckoutAcceptance::pending()->where('checkoutable_type', 'App\Models\Asset')->with(['assignedTo', 'checkoutable.assignedTo', 'checkoutable.model'])->get();
}
$assetsForReport = $acceptances
@@ -1063,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

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;
@@ -349,6 +350,7 @@ class SettingsController extends Controller
$setting->privacy_policy_link = $request->input('privacy_policy_link');
$setting->depreciation_method = $request->input('depreciation_method');
$setting->dash_chart_type = $request->input('dash_chart_type');
if ($request->input('per_page') != '') {
$setting->per_page = $request->input('per_page');
@@ -910,6 +912,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
@@ -922,13 +926,13 @@ class SettingsController extends Controller
$validator = Validator::make($setting->toArray(), [
'ldap_username_field' => 'not_in:sAMAccountName',
'ldap_auth_filter_query' => 'not_in:uid=samaccountname',
'ldap_filter' => 'regex:"^[^(]"',
'ldap_auth_filter_query' => 'not_in:uid=samaccountname|required_if:ldap_enabled,1',
'ldap_filter' => 'nullable|regex:"^[^(]"|required_if:ldap_enabled,1',
], $messages);
return view('settings.ldap', compact('setting'))->withErrors($validator);
return view('settings.ldap', compact('setting', 'groups'))->withErrors($validator);
}
/**
@@ -955,6 +959,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');

View File

@@ -5,10 +5,13 @@ namespace App\Http\Controllers\Users;
use App\Helpers\Helper;
use App\Http\Controllers\Controller;
use App\Models\Accessory;
use App\Models\License;
use App\Models\Actionlog;
use App\Models\Asset;
use App\Models\Group;
use App\Models\LicenseSeat;
use App\Models\ConsumableAssignment;
use App\Models\Consumable;
use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
@@ -162,13 +165,11 @@ class BulkUsersController extends Controller
if ((! $request->filled('ids')) || (count($request->input('ids')) == 0)) {
return redirect()->back()->with('error', 'No users selected');
}
if ((! $request->filled('status_id')) || ($request->input('status_id') == '')) {
return redirect()->route('users.index')->with('error', 'No status selected');
}
if (config('app.lock_passwords')) {
return redirect()->route('users.index')->with('error', 'Bulk delete is not enabled in this installation');
}
$user_raw_array = request('ids');
if (($key = array_search(Auth::id(), $user_raw_array)) !== false) {
@@ -179,27 +180,48 @@ class BulkUsersController extends Controller
$assets = Asset::whereIn('assigned_to', $user_raw_array)->where('assigned_type', \App\Models\User::class)->get();
$accessories = DB::table('accessories_users')->whereIn('assigned_to', $user_raw_array)->get();
$licenses = DB::table('license_seats')->whereIn('assigned_to', $user_raw_array)->get();
$consumables = DB::table('consumables_users')->whereIn('assigned_to', $user_raw_array)->get();
if ((($assets->count() > 0) && ((!$request->filled('status_id')) || ($request->input('status_id') == '')))) {
return redirect()->route('users.index')->with('error', 'No status selected');
}
$this->logItemCheckinAndDelete($assets, Asset::class);
$this->logItemCheckinAndDelete($accessories, Accessory::class);
$this->logItemCheckinAndDelete($licenses, LicenseSeat::class);
$this->logItemCheckinAndDelete($licenses, License::class);
$this->logItemCheckinAndDelete($consumables, Consumable::class);
Asset::whereIn('id', $assets->pluck('id'))->update([
'status_id' => e(request('status_id')),
'assigned_to' => null,
'assigned_type' => null,
'expected_checkin' => null,
]);
LicenseSeat::whereIn('id', $licenses->pluck('id'))->update(['assigned_to' => null]);
ConsumableAssignment::whereIn('id', $consumables->pluck('id'))->delete();
foreach ($users as $user) {
$user->consumables()->sync([]);
$user->accessories()->sync([]);
$user->delete();
if ($request->input('delete_user')=='1') {
$user->delete();
}
}
return redirect()->route('users.index')->with('success', 'Your selected users have been deleted and their assets have been updated.');
$msg = trans('general.bulk_checkin_success');
if ($request->input('delete_user')=='1') {
$msg = trans('general.bulk_checkin_delete_success');
}
return redirect()->route('users.index')->with('success', $msg);
}
/**
@@ -210,14 +232,20 @@ class BulkUsersController extends Controller
protected function logItemCheckinAndDelete($items, $itemType)
{
foreach ($items as $item) {
$item_id = $item->id;
$logAction = new Actionlog();
$logAction->item_id = $item->id;
if ($itemType == License::class){
$item_id = $item->license_id;
}
$logAction->item_id = $item_id;
// We can't rely on get_class here because the licenses/accessories fetched above are not eloquent models, but simply arrays.
$logAction->item_type = $itemType;
$logAction->target_id = $item->assigned_to;
$logAction->target_type = User::class;
$logAction->user_id = Auth::id();
$logAction->note = 'Bulk checkin items and delete user';
$logAction->note = 'Bulk checkin items';
$logAction->logaction('checkin from');
}
}

View File

@@ -119,6 +119,8 @@ class UsersController extends Controller
$user->remote = $request->input('remote', 0);
$user->website = $request->input('website', null);
$user->created_by = Auth::user()->id;
$user->start_date = $request->input('start_date', null);
$user->end_date = $request->input('end_date', null);
// Strip out the superuser permission if the user isn't a superadmin
$permissions_array = $request->input('permission');
@@ -270,6 +272,8 @@ class UsersController extends Controller
$user->zip = $request->input('zip', null);
$user->remote = $request->input('remote', 0);
$user->website = $request->input('website', null);
$user->start_date = $request->input('start_date', null);
$user->end_date = $request->input('end_date', null);
// Update the location of any assets checked out to this user
Asset::where('assigned_type', User::class)
@@ -594,7 +598,7 @@ class UsersController extends Controller
}
/**
* LDAP form processing.
* Print inventory
*
* @author Aladin Alaily
* @since [v1.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));
@@ -165,7 +184,7 @@ class ViewAssetsController extends Controller
$settings->notify(new RequestAssetCancelation($data));
return redirect()->route('requestable-assets')
->with('success')->with('success', trans('admin/hardware/message.requests.cancel'));
->with('success')->with('success', trans('admin/hardware/message.requests.canceled'));
}
$logaction->logaction('requested');

View File

@@ -43,6 +43,7 @@ class Kernel extends HttpKernel
\App\Http\Middleware\CheckForTwoFactor::class,
\Laravel\Passport\Http\Middleware\CreateFreshApiToken::class,
\App\Http\Middleware\AssetCountForSidebar::class,
\Illuminate\Session\Middleware\AuthenticateSession::class,
],
'api' => [

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;

View File

@@ -85,6 +85,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,
@@ -95,11 +96,11 @@ class ActionlogsTransformer
'next_audit_date' => ($actionlog->itemType()=='asset') ? Helper::getFormattedDateObject($actionlog->calcNextAuditDate(null, $actionlog->item), 'date'): null,
'days_to_next_audit' => $actionlog->daysUntilNextAudit($settings->audit_interval, $actionlog->item),
'action_type' => $actionlog->present()->actionType(),
'admin' => ($actionlog->user) ? [
'id' => (int) $actionlog->user->id,
'name' => e($actionlog->user->getFullNameAttribute()),
'first_name'=> e($actionlog->user->first_name),
'last_name'=> e($actionlog->user->last_name)
'admin' => ($actionlog->admin) ? [
'id' => (int) $actionlog->admin->id,
'name' => e($actionlog->admin->getFullNameAttribute()),
'first_name'=> e($actionlog->admin->first_name),
'last_name'=> e($actionlog->admin->last_name)
] : null,
'target' => ($actionlog->target) ? [
'id' => (int) $actionlog->target->id,

View File

@@ -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),

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)
@@ -80,6 +81,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 +133,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'] = [
@@ -185,8 +187,11 @@ class AssetsTransformer
'name' => e($asset->assigned->getFullNameAttribute()),
'first_name'=> e($asset->assigned->first_name),
'last_name'=> ($asset->assigned->last_name) ? e($asset->assigned->last_name) : null,
'email'=> ($asset->assigned->email) ? e($asset->assigned->email) : null,
'employee_number' => ($asset->assigned->employee_num) ? e($asset->assigned->employee_num) : null,
'type' => 'user',
'eula_pdf' => e($asset->acceptanceLog->last()->filename),
'signature_file' => e($asset->acceptanceLog->last()->accept_signature),
] : null;
}

View File

@@ -26,6 +26,7 @@ class ComponentsAssetsTransformer
'created_at' => $asset->created_at->format('Y-m-d'),
'qty' => $asset->components()->count(),
'user_can_checkout' => $asset->availableForCheckout(),
'note' => e($asset->note),
];
$permissions_array['available_actions'] = [

View File

@@ -71,6 +71,7 @@ class ComponentsTransformer
'id' => (int) $asset->id,
'name' => e($asset->model->present()->name).' '.e($asset->present()->name),
'qty' => $asset->pivot->assigned_qty,
'note' => $asset->pivot->note,
'type' => 'asset',
'created_at' => Helper::getFormattedDateObject($asset->pivot->created_at, 'datetime'),
'available_actions' => ['checkin' => true],

View File

@@ -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'),
];

View File

@@ -63,10 +63,16 @@ class DepreciationReportTransformer
*/
if (($asset->model) && ($asset->model->depreciation)) {
$depreciated_value = Helper::formatCurrencyOutput($asset->getDepreciatedValue());
$monthly_depreciation = Helper::formatCurrencyOutput(($asset->model->eol > 0 ? ($asset->purchase_cost / $asset->model->eol) : 0));
if($asset->model->eol==0 || $asset->model->eol==null ){
$monthly_depreciation = Helper::formatCurrencyOutput($asset->purchase_cost / $asset->model->depreciation->months);
}
else {
$monthly_depreciation = Helper::formatCurrencyOutput(($asset->model->eol > 0 ? ($asset->purchase_cost / $asset->model->eol) : 0));
}
$diff = Helper::formatCurrencyOutput(($asset->purchase_cost - $asset->getDepreciatedValue()));
}
if ($asset->assigned) {
$checkout_target = $asset->assigned->name;
if ($asset->checkedOutToUser()) {

View File

@@ -3,6 +3,7 @@
namespace App\Http\Transformers;
use App\Helpers\Helper;
use App\Models\Depreciable;
use App\Models\Depreciation;
use Gate;
use Illuminate\Database\Eloquent\Collection;

View File

@@ -45,6 +45,7 @@ class LocationsTransformer
'zip' => ($location->zip) ? e($location->zip) : null,
'assigned_assets_count' => (int) $location->assigned_assets_count,
'assets_count' => (int) $location->assets_count,
'rtd_assets_count' => (int) $location->rtd_assets_count,
'users_count' => (int) $location->users_count,
'currency' => ($location->currency) ? e($location->currency) : null,
'ldap_ou' => ($location->ldap_ou) ? e($location->ldap_ou) : null,

View File

@@ -0,0 +1,55 @@
<?php
namespace App\Http\Transformers;
use App\Helpers\Helper;
/**
* Class PieChartTransformer
*
* This handles the standardized formatting of the API response we need to provide for
* the pie charts
*
* @return \Illuminate\Http\Response
* @since [v6.0.11]
* @author [A. Gianotto] [<snipe@snipe.net>]
*/
class PieChartTransformer
{
public function transformPieChartDate($totals)
{
$labels = [];
$counts = [];
$default_color_count = 0;
$colors_array = [];
foreach ($totals as $total) {
if ($total['count'] > 0) {
$labels[] = $total['label']." (".$total['count'].")";
$counts[] = $total['count'];
if (isset($total['color'])) {
$colors_array[] = $total['color'];
} else {
$colors_array[] = Helper::defaultChartColors($default_color_count);
$default_color_count++;
}
}
}
$results = [
'labels' => $labels,
'datasets' => [[
'data' => $counts,
'backgroundColor' => $colors_array,
'hoverBackgroundColor' => $colors_array,
]],
];
return $results;
}
}

View File

@@ -30,10 +30,10 @@ class UsersTransformer
'username' => e($user->username),
'remote' => ($user->remote == '1') ? true : false,
'locale' => ($user->locale) ? e($user->locale) : null,
'employee_num' => e($user->employee_num),
'employee_num' => ($user->employee_num) ? e($user->employee_num) : null,
'manager' => ($user->manager) ? [
'id' => (int) $user->manager->id,
'name'=> e($user->manager->username),
'name'=> e($user->manager->first_name).' '.e($user->manager->last_name),
] : null,
'jobtitle' => ($user->jobtitle) ? e($user->jobtitle) : null,
'phone' => ($user->phone) ? e($user->phone) : null,
@@ -43,7 +43,7 @@ class UsersTransformer
'state' => ($user->state) ? e($user->state) : null,
'country' => ($user->country) ? e($user->country) : null,
'zip' => ($user->zip) ? e($user->zip) : null,
'email' => e($user->email),
'email' => ($user->email) ? e($user->email) : null,
'department' => ($user->department) ? [
'id' => (int) $user->department->id,
'name'=> e($user->department->name),
@@ -69,13 +69,15 @@ class UsersTransformer
] : null,
'created_at' => Helper::getFormattedDateObject($user->created_at, 'datetime'),
'updated_at' => Helper::getFormattedDateObject($user->updated_at, 'datetime'),
'start_date' => Helper::getFormattedDateObject($user->start_date, 'date'),
'end_date' => Helper::getFormattedDateObject($user->end_date, 'date'),
'last_login' => Helper::getFormattedDateObject($user->last_login, 'datetime'),
'deleted_at' => ($user->deleted_at) ? Helper::getFormattedDateObject($user->deleted_at, 'datetime') : null,
];
$permissions_array['available_actions'] = [
'update' => (Gate::allows('update', User::class) && ($user->deleted_at == '')),
'delete' => (Gate::allows('delete', User::class) && ($user->assets_count == 0) && ($user->licenses_count == 0) && ($user->accessories_count == 0) && ($user->consumables_count == 0)),
'delete' => (Gate::allows('delete', User::class) && ($user->assets_count == 0) && ($user->licenses_count == 0) && ($user->accessories_count == 0)),
'clone' => (Gate::allows('create', User::class) && ($user->deleted_at == '')),
'restore' => (Gate::allows('create', User::class) && ($user->deleted_at != '')),
];

View File

@@ -43,6 +43,7 @@ class AccessoryImporter extends ItemImporter
$this->log('No Matching Accessory, Creating a new one');
$accessory = new Accessory();
$this->item['model_number'] = $this->findCsvMatch($row, "model_number");
$this->item['min_amt'] = $this->findCsvMatch($row, "min_amt");
$accessory->fill($this->sanitizeItemForStoring($accessory));
//FIXME: this disables model validation. Need to find a way to avoid double-logs without breaking everything.

View File

@@ -55,6 +55,11 @@ class AssetImporter extends ItemImporter
{
$editingAsset = false;
$asset_tag = $this->findCsvMatch($row, 'asset_tag');
if(empty($asset_tag)){
$asset_tag = Asset::autoincrement_asset();
}
$asset = Asset::where(['asset_tag'=> $asset_tag])->first();
if ($asset) {
if (! $this->updating) {

View File

@@ -43,6 +43,7 @@ class ConsumableImporter extends ItemImporter
$consumable = new Consumable();
$this->item['model_number'] = $this->findCsvMatch($row, 'model_number');
$this->item['item_no'] = $this->findCsvMatch($row, 'item_number');
$this->item['min_amt'] = $this->findCsvMatch($row, "min_amt");
$consumable->fill($this->sanitizeItemForStoring($consumable));
//FIXME: this disables model validation. Need to find a way to avoid double-logs without breaking everything.
$consumable->unsetEventDispatcher();

View File

@@ -56,7 +56,7 @@ abstract class Importer
'reassignable' => 'reassignable',
'requestable' => 'requestable',
'seats' => 'seats',
'serial_number' => 'serial number',
'serial' => 'serial number',
'status' => 'status',
'supplier' => 'supplier',
'termination_date' => 'termination date',
@@ -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.

View File

@@ -90,7 +90,7 @@ class ItemImporter extends Importer
$this->item['qty'] = $this->findCsvMatch($row, 'quantity');
$this->item['requestable'] = $this->findCsvMatch($row, 'requestable');
$this->item['user_id'] = $this->user_id;
$this->item['serial'] = $this->findCsvMatch($row, 'serial');
$this->item['serial'] = $this->findCsvMatch($row, 'serial number');
// NO need to call this method if we're running the user import.
// TODO: Merge these methods.
$this->item['checkout_class'] = $this->findCsvMatch($row, 'checkout_class');
@@ -112,7 +112,7 @@ class ItemImporter extends Importer
return $this->createOrFetchUser($row);
}
if (strtolower($this->item['checkout_class']) === 'location') {
if (strtolower($this->item['checkout_class']) === 'location' && $this->findCsvMatch($row, 'checkout_location') != null ) {
return Location::findOrFail($this->createOrFetchLocation($this->findCsvMatch($row, 'checkout_location')));
}

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)) {

View File

@@ -20,6 +20,8 @@ use App\Notifications\CheckoutConsumableNotification;
use App\Notifications\CheckoutLicenseNotification;
use App\Notifications\CheckoutLicenseSeatNotification;
use Illuminate\Support\Facades\Notification;
use Exception;
use Log;
class CheckoutableListener
{
@@ -43,16 +45,20 @@ class CheckoutableListener
*/
$acceptance = $this->getCheckoutAcceptance($event);
if (! $event->checkedOutTo->locale) {
Notification::locale(Setting::getSettings()->locale)->send(
$this->getNotifiables($event),
$this->getCheckoutNotification($event, $acceptance)
);
} else {
Notification::send(
$this->getNotifiables($event),
$this->getCheckoutNotification($event, $acceptance)
);
try {
if (! $event->checkedOutTo->locale) {
Notification::locale(Setting::getSettings()->locale)->send(
$this->getNotifiables($event),
$this->getCheckoutNotification($event, $acceptance)
);
} else {
Notification::send(
$this->getNotifiables($event),
$this->getCheckoutNotification($event, $acceptance)
);
}
} catch (Exception $e) {
Log::error("Exception caught during checkout notification: ".$e->getMessage());
}
}
@@ -83,17 +89,21 @@ class CheckoutableListener
}
}
// Use default locale
if (! $event->checkedOutTo->locale) {
Notification::locale(Setting::getSettings()->locale)->send(
$this->getNotifiables($event),
$this->getCheckinNotification($event)
);
} else {
Notification::send(
$this->getNotifiables($event),
$this->getCheckinNotification($event)
);
try {
// Use default locale
if (! $event->checkedOutTo->locale) {
Notification::locale(Setting::getSettings()->locale)->send(
$this->getNotifiables($event),
$this->getCheckinNotification($event)
);
} else {
Notification::send(
$this->getNotifiables($event),
$this->getCheckinNotification($event)
);
}
} catch (Exception $e) {
Log::error("Exception caught during checkin notification: ".$e->getMessage());
}
}

View File

@@ -2,6 +2,7 @@
namespace App\Models;
use App\Helpers\Helper;
use App\Models\Traits\Acceptable;
use App\Models\Traits\Searchable;
use App\Presenters\Presentable;
@@ -100,6 +101,23 @@ class Accessory extends SnipeModel
/**
* Establishes the accessories -> action logs -> uploads relationship
*
* @author A. Gianotto <snipe@snipe.net>
* @since [v6.1.13]
* @return \Illuminate\Database\Eloquent\Relations\Relation
*/
public function uploads()
{
return $this->hasMany(\App\Models\Actionlog::class, 'item_id')
->where('item_type', '=', self::class)
->where('action_type', '=', 'uploaded')
->whereNotNull('filename')
->orderBy('created_at', 'desc');
}
/**
* Establishes the accessory -> supplier relationship
*
@@ -299,15 +317,14 @@ class Accessory extends SnipeModel
*/
public function getEula()
{
$Parsedown = new \Parsedown();
if ($this->category->eula_text) {
return $Parsedown->text(e($this->category->eula_text));
return Helper::parseEscapedMarkedown($this->category->eula_text);
} elseif ((Setting::getSettings()->default_eula_text) && ($this->category->use_default_eula == '1')) {
return $Parsedown->text(e(Setting::getSettings()->default_eula_text));
return Helper::parseEscapedMarkedown(Setting::getSettings()->default_eula_text);
}
return null;
return null;
}
/**

View File

@@ -43,7 +43,9 @@ class Actionlog extends SnipeModel
*/
protected $searchableRelations = [
'company' => ['name'],
'user' => ['first_name','last_name','username'],
'admin' => ['first_name','last_name','username', 'email'],
'user' => ['first_name','last_name','username', 'email'],
'assets' => ['asset_tag','name'],
];
/**
@@ -95,6 +97,19 @@ class Actionlog extends SnipeModel
return $this->hasMany(\App\Models\Company::class, 'id', 'company_id');
}
/**
* Establishes the actionlog -> asset relationship
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v3.0]
* @return \Illuminate\Database\Eloquent\Relations\Relation
*/
public function assets()
{
return $this->hasMany(\App\Models\Asset::class, 'id', 'item_id');
}
/**
* Establishes the actionlog -> item type relationship
*
@@ -154,6 +169,19 @@ class Actionlog extends SnipeModel
return $this->target();
}
/**
* Establishes the actionlog -> admin user relationship
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v3.0]
* @return \Illuminate\Database\Eloquent\Relations\Relation
*/
public function admin()
{
return $this->belongsTo(User::class, 'user_id')
->withTrashed();
}
/**
* Establishes the actionlog -> user relationship
*
@@ -163,8 +191,8 @@ class Actionlog extends SnipeModel
*/
public function user()
{
return $this->belongsTo(User::class, 'user_id')
->withTrashed();
return $this->belongsTo(User::class, 'target_id')
->withTrashed();
}
/**

View File

@@ -5,6 +5,7 @@ namespace App\Models;
use App\Events\AssetCheckedOut;
use App\Events\CheckoutableCheckedOut;
use App\Exceptions\CheckoutNotAllowed;
use App\Helpers\Helper;
use App\Http\Traits\UniqueSerialTrait;
use App\Http\Traits\UniqueUndeletedTrait;
use App\Models\Traits\Acceptable;
@@ -105,7 +106,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',
@@ -587,6 +587,24 @@ class Asset extends Depreciable
->withTrashed();
}
/**
* Get the log info for acceptances on this asset.
* To use this as a single record, invoke it using ->last(), for
* example, $asset->lastAcceptedLog->last().
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v6.0.14]
* @return \Illuminate\Database\Eloquent\Relations\Relation
*/
public function acceptanceLog()
{
return $this->hasMany(\App\Models\Actionlog::class, 'item_id')
->where('item_type', '=', self::class)
->where('action_type', '=', 'accepted')
->orderBy('created_at', 'desc')
->withTrashed();
}
/**
* Get the list of checkouts for this asset
*
@@ -694,15 +712,15 @@ class Asset extends Depreciable
public static function getExpiringWarrantee($days = 30)
{
$days = (is_null($days)) ? 30 : $days;
return self::where('archived', '=', '0')
->whereNotNull('warranty_months')
->whereNotNull('purchase_date')
->whereNull('deleted_at')
->whereRaw(\DB::raw('DATE_ADD(`purchase_date`,INTERVAL `warranty_months` MONTH) <= DATE(NOW() + INTERVAL '
->whereRaw('DATE_ADD(`purchase_date`,INTERVAL `warranty_months` MONTH) <= DATE(NOW() + INTERVAL '
. $days
. ' DAY) AND DATE_ADD(`purchase_date`, INTERVAL `warranty_months` MONTH) > NOW()'))
->orderBy('purchase_date', 'ASC')
. ' DAY) AND DATE_ADD(`purchase_date`, INTERVAL `warranty_months` MONTH) > NOW()')
->orderByRaw('DATE_ADD(`purchase_date`,INTERVAL `warranty_months` MONTH)')
->get();
}
@@ -875,13 +893,12 @@ class Asset extends Depreciable
*/
public function getEula()
{
$Parsedown = new \Parsedown();
if (($this->model) && ($this->model->category)) {
if ($this->model->category->eula_text) {
return $Parsedown->text(e($this->model->category->eula_text));
return Helper::parseEscapedMarkedown($this->model->category->eula_text);
} elseif ($this->model->category->use_default_eula == '1') {
return $Parsedown->text(e(Setting::getSettings()->default_eula_text));
return Helper::parseEscapedMarkedown(Setting::getSettings()->default_eula_text);
} else {
return false;
}

View File

@@ -74,10 +74,11 @@ class AssetMaintenance extends Model implements ICompanyableChild
trans('admin/asset_maintenances/general.maintenance') => trans('admin/asset_maintenances/general.maintenance'),
trans('admin/asset_maintenances/general.repair') => trans('admin/asset_maintenances/general.repair'),
trans('admin/asset_maintenances/general.upgrade') => trans('admin/asset_maintenances/general.upgrade'),
'PAT test' => 'PAT test',
trans('admin/asset_maintenances/general.pat_test') => trans('admin/asset_maintenances/general.pat_test'),
trans('admin/asset_maintenances/general.calibration') => trans('admin/asset_maintenances/general.calibration'),
'Software Support' => trans('admin/asset_maintenances/general.software_support'),
'Hardware Support' => trans('admin/asset_maintenances/general.hardware_support'),
trans('admin/asset_maintenances/general.software_support') => trans('admin/asset_maintenances/general.software_support'),
trans('admin/asset_maintenances/general.hardware_support') => trans('admin/asset_maintenances/general.hardware_support'),
trans('admin/asset_maintenances/general.configuration_change') => trans('admin/asset_maintenances/general.configuration_change'),
];
}

View File

@@ -9,6 +9,7 @@ use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Support\Facades\Gate;
use Watson\Validating\ValidatingTrait;
use App\Helpers\Helper;
/**
* Model for Categories. Categories are a higher-level group
@@ -207,12 +208,11 @@ class Category extends SnipeModel
*/
public function getEula()
{
$Parsedown = new \Parsedown();
if ($this->eula_text) {
return $Parsedown->text(e($this->eula_text));
return Helper::parseEscapedMarkedown($this->eula_text);
} elseif ((Setting::getSettings()->default_eula_text) && ($this->use_default_eula == '1')) {
return $Parsedown->text(e(Setting::getSettings()->default_eula_text));
return Helper::parseEscapedMarkedown(Setting::getSettings()->default_eula_text);
} else {
return null;
}

View File

@@ -5,16 +5,25 @@ namespace App\Models;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Notifications\Notifiable;
class CheckoutAcceptance extends Model
{
use SoftDeletes;
use SoftDeletes, Notifiable;
protected $casts = [
'accepted_at' => 'datetime',
'declined_at' => 'datetime',
];
// Get the mail recipient from the config
public function routeNotificationForMail(): string
{
// 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')) ? config('mail.reply_to.address') : '' ;
}
/**
* The resource that was is out
*

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;

View File

@@ -88,6 +88,24 @@ class Component extends SnipeModel
'location' => ['name'],
];
/**
* Establishes the components -> action logs -> uploads relationship
*
* @author A. Gianotto <snipe@snipe.net>
* @since [v6.1.13]
* @return \Illuminate\Database\Eloquent\Relations\Relation
*/
public function uploads()
{
return $this->hasMany(\App\Models\Actionlog::class, 'item_id')
->where('item_type', '=', self::class)
->where('action_type', '=', 'uploaded')
->whereNotNull('filename')
->orderBy('created_at', 'desc');
}
/**
* Establishes the component -> location relationship
*
@@ -109,7 +127,7 @@ class Component extends SnipeModel
*/
public function assets()
{
return $this->belongsToMany(\App\Models\Asset::class, 'components_assets')->withPivot('id', 'assigned_qty', 'created_at', 'user_id');
return $this->belongsToMany(\App\Models\Asset::class, 'components_assets')->withPivot('id', 'assigned_qty', 'created_at', 'user_id', 'note');
}
/**

View File

@@ -2,6 +2,7 @@
namespace App\Models;
use App\Helpers\Helper;
use App\Models\Traits\Acceptable;
use App\Models\Traits\Searchable;
use App\Presenters\Presentable;
@@ -95,6 +96,24 @@ class Consumable extends SnipeModel
'manufacturer' => ['name'],
];
/**
* Establishes the components -> action logs -> uploads relationship
*
* @author A. Gianotto <snipe@snipe.net>
* @since [v6.1.13]
* @return \Illuminate\Database\Eloquent\Relations\Relation
*/
public function uploads()
{
return $this->hasMany(\App\Models\Actionlog::class, 'item_id')
->where('item_type', '=', self::class)
->where('action_type', '=', 'uploaded')
->whereNotNull('filename')
->orderBy('created_at', 'desc');
}
/**
* Sets the attribute of whether or not the consumable is requestable
*
@@ -265,12 +284,10 @@ class Consumable extends SnipeModel
*/
public function getEula()
{
$Parsedown = new \Parsedown();
if ($this->category->eula_text) {
return $Parsedown->text(e($this->category->eula_text));
return Helper::parseEscapedMarkedown($this->category->eula_text);
} elseif ((Setting::getSettings()->default_eula_text) && ($this->category->use_default_eula == '1')) {
return $Parsedown->text(e(Setting::getSettings()->default_eula_text));
return Helper::parseEscapedMarkedown(Setting::getSettings()->default_eula_text);
} else {
return null;
}

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',
];
/**
@@ -338,7 +343,7 @@ class CustomField extends Model
$id = $this->id ? $this->id : 'xx';
if (! function_exists('transliterator_transliterate')) {
$long_slug = '_snipeit_'.str_slug(\Patchwork\Utf8::utf8_encode(trim($name)), '_');
$long_slug = '_snipeit_'.str_slug(mb_convert_encoding(trim($name),"UTF-8"), '_');
} else {
$long_slug = '_snipeit_'.Utf8Slugger::slugify($name, '_');
}
@@ -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',
]
];
}

View File

@@ -87,7 +87,7 @@ class CustomFieldset extends Model
}
if ($field->is_unique == '1') {
$rule[] = 'unique';
$rule[] = 'unique_undeleted';
}
array_push($rule, $field->attributes['format']);

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',

View File

@@ -68,21 +68,37 @@ class Depreciable extends SnipeModel
*/
public function getLinearDepreciatedValue() // TODO - for testing it might be nice to have an optional $relative_to param here, defaulted to 'now'
{
$months_remaining = $this->time_until_depreciated()->m + 12 * $this->time_until_depreciated()->y; //UGlY
$current_value = round(($months_remaining / $this->get_depreciation()->months) * $this->purchase_cost, 2);
if($this->get_depreciation()->depreciation_min > $current_value) {
$current_value=round($this->get_depreciation()->depreciation_min,2);
if ($this->purchase_date) {
$months_passed = ($this->purchase_date->diff(now())->m)+($this->purchase_date->diff(now())->y*12);
} else {
return null;
}
if ($current_value < 0) {
$current_value = 0;
if ($months_passed >= $this->get_depreciation()->months){
//if there is a floor use it
if(!$this->get_depreciation()->depreciation_min == null) {
$current_value = $this->get_depreciation()->depreciation_min;
}else{
$current_value = 0;
}
}
else {
// The equation here is (Purchase_Cost-Floor_min)*(Months_passed/Months_til_depreciated)
$current_value = round(($this->purchase_cost-($this->purchase_cost - ($this->get_depreciation()->depreciation_min)) * ($months_passed / $this->get_depreciation()->months)), 2);
}
return $current_value;
}
public function getMonthlyDepreciation(){
return ($this->purchase_cost-$this->get_depreciation()->depreciation_min)/$this->get_depreciation()->months;
}
/**
* @param onlyHalfFirstYear Boolean always applied only second half of the first year
* @return float|int

View File

@@ -169,23 +169,29 @@ class Ldap extends Model
{
$ldap_username = Setting::getSettings()->ldap_uname;
// Lets return some nicer messages for users who donked their app key, and disable LDAP
try {
$ldap_pass = \Crypt::decrypt(Setting::getSettings()->ldap_pword);
} catch (Exception $e) {
throw new Exception('Your app key has changed! Could not decrypt LDAP password using your current app key, so LDAP authentication has been disabled. Login with a local account, update the LDAP password and re-enable it in Admin > Settings.');
}
if (! $ldapbind = @ldap_bind($connection, $ldap_username, $ldap_pass)) {
throw new Exception('Could not bind to LDAP: '.ldap_error($connection));
}
// TODO - this just "falls off the end" but the function states that it should return true or false
// unfortunately, one of the use cases for this function is wrong and *needs* for that failure mode to fire
// so I don't want to fix this right now.
// this method MODIFIES STATE on the passed-in $connection and just returns true or false (or, in this case, undefined)
// at the next refactor, this should be appropriately modified to be more consistent.
}
if ( $ldap_username ) {
// Lets return some nicer messages for users who donked their app key, and disable LDAP
try {
$ldap_pass = \Crypt::decrypt(Setting::getSettings()->ldap_pword);
} catch (Exception $e) {
throw new Exception('Your app key has changed! Could not decrypt LDAP password using your current app key, so LDAP authentication has been disabled. Login with a local account, update the LDAP password and re-enable it in Admin > Settings.');
}
if (! $ldapbind = @ldap_bind($connection, $ldap_username, $ldap_pass)) {
throw new Exception('Could not bind to LDAP: '.ldap_error($connection));
}
// TODO - this just "falls off the end" but the function states that it should return true or false
// unfortunately, one of the use cases for this function is wrong and *needs* for that failure mode to fire
// so I don't want to fix this right now.
// this method MODIFIES STATE on the passed-in $connection and just returns true or false (or, in this case, undefined)
// at the next refactor, this should be appropriately modified to be more consistent.
} else {
// LDAP should also work with anonymous bind (no dn, no password available)
if (! $ldapbind = @ldap_bind($connection )) {
throw new Exception('Could not bind to LDAP: '.ldap_error($connection));
}
}
}
/**
* Parse and map LDAP attributes based on settings

View File

@@ -2,6 +2,7 @@
namespace App\Models;
use App\Helpers\Helper;
use App\Models\Traits\Searchable;
use App\Presenters\Presentable;
use Carbon\Carbon;
@@ -122,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);
});
@@ -337,12 +346,11 @@ class License extends Depreciable
*/
public function getEula()
{
$Parsedown = new \Parsedown();
if ($this->category->eula_text) {
return $Parsedown->text(e($this->category->eula_text));
return Helper::parseEscapedMarkedown($this->category->eula_text);
} elseif ($this->category->use_default_eula == '1') {
return $Parsedown->text(e(Setting::getSettings()->default_eula_text));
return Helper::parseEscapedMarkedown(Setting::getSettings()->default_eula_text);
} else {
return false;
}

View File

@@ -90,6 +90,14 @@ class Location extends SnipeModel
'parent' => ['name'],
];
/**
* Determine whether or not this location can be deleted
*
* @author A. Gianotto <snipe@snipe.net>
* @since [v3.0]
* @return bool
*/
public function isDeletable()
{
return Gate::allows('delete', $this)
@@ -98,12 +106,25 @@ class Location extends SnipeModel
&& ($this->users()->count() === 0);
}
/**
* Establishes the user -> location relationship
*
* @author A. Gianotto <snipe@snipe.net>
* @since [v3.0]
* @return \Illuminate\Database\Eloquent\Relations\Relation
*/
public function users()
{
return $this->hasMany(\App\Models\User::class, 'location_id');
}
/**
* Find assets with this location as their location_id
*
* @author A. Gianotto <snipe@snipe.net>
* @since [v3.0]
* @return \Illuminate\Database\Eloquent\Relations\Relation
*/
public function assets()
{
return $this->hasMany(\App\Models\Asset::class, 'location_id')
@@ -114,6 +135,14 @@ class Location extends SnipeModel
});
}
/**
* Establishes the asset -> rtd_location relationship
*
* @author A. Gianotto <snipe@snipe.net>
* @since [v3.0]
* @return \Illuminate\Database\Eloquent\Relations\Relation
*/
public function rtd_assets()
{
/* This used to have an ...->orHas() clause that referred to
@@ -123,48 +152,93 @@ class Location extends SnipeModel
It is arguable that we should have a '...->whereNull('assigned_to')
bit in there, but that isn't always correct either (in the case
where a user has no location, for example).
In all likelyhood, we need to denorm an "effective_location" column
into Assets to make this slightly less miserable.
*/
return $this->hasMany(\App\Models\Asset::class, 'rtd_location_id');
}
/**
* Establishes the consumable -> location relationship
*
* @author A. Gianotto <snipe@snipe.net>
* @since [v3.0]
* @return \Illuminate\Database\Eloquent\Relations\Relation
*/
public function consumables()
{
return $this->hasMany(\App\Models\Consumable::class, 'location_id');
}
/**
* Establishes the component -> location relationship
*
* @author A. Gianotto <snipe@snipe.net>
* @since [v3.0]
* @return \Illuminate\Database\Eloquent\Relations\Relation
*/
public function components()
{
return $this->hasMany(\App\Models\Component::class, 'location_id');
}
/**
* Establishes the component -> accessory relationship
*
* @author A. Gianotto <snipe@snipe.net>
* @since [v3.0]
* @return \Illuminate\Database\Eloquent\Relations\Relation
*/
public function accessories()
{
return $this->hasMany(\App\Models\Accessory::class, 'location_id');
}
/**
* Find the parent of a location
*
* @author A. Gianotto <snipe@snipe.net>
* @since [v2.0]
* @return \Illuminate\Database\Eloquent\Relations\Relation
*/
public function parent()
{
return $this->belongsTo(self::class, 'parent_id', 'id')
->with('parent');
}
/**
* Find the manager of a location
*
* @author A. Gianotto <snipe@snipe.net>
* @since [v2.0]
* @return \Illuminate\Database\Eloquent\Relations\Relation
*/
public function manager()
{
return $this->belongsTo(\App\Models\User::class, 'manager_id');
}
/**
* Find children of a location
*
* @author A. Gianotto <snipe@snipe.net>
* @since [v2.0]
* @return \Illuminate\Database\Eloquent\Relations\Relation
*/
public function children()
{
return $this->hasMany(self::class, 'parent_id')
->with('children');
}
// I don't think we need this anymore since we de-normed location_id in assets?
/**
* Establishes the asset -> location assignment relationship
*
* @author A. Gianotto <snipe@snipe.net>
* @since [v3.0]
* @return \Illuminate\Database\Eloquent\Relations\Relation
*/
public function assignedAssets()
{
return $this->morphMany(\App\Models\Asset::class, 'assigned', 'assigned_type', 'assigned_to')->withTrashed();

View File

@@ -189,7 +189,7 @@ trait Loggable
$params = [
'item' => $log->item,
'filename' => $log->filename,
'admin' => $log->user,
'admin' => $log->admin,
'location' => ($location) ? $location->name : '',
'note' => $note,
];

View File

@@ -8,9 +8,10 @@ use Illuminate\Notifications\Notifiable;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\Cache;
use Parsedown;
use App\Helpers\Helper;
use Watson\Validating\ValidatingTrait;
/**
* Settings model.
*/
@@ -20,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.
@@ -97,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;
}
/**
@@ -135,7 +136,6 @@ class Setting extends Model
public function lar_ver(): string
{
$app = App::getFacadeApplication();
return $app::VERSION;
}
@@ -147,9 +147,7 @@ class Setting extends Model
public static function getDefaultEula(): ?string
{
if (self::getSettings()->default_eula_text) {
$parsedown = new Parsedown();
return $parsedown->text(e(self::getSettings()->default_eula_text));
return Helper::parseEscapedMarkedown(self::getSettings()->default_eula_text);
}
return null;

View File

@@ -41,6 +41,11 @@ class SnipeSCIMConfig extends \ArieTimmerman\Laravel\SCIMServer\SCIMConfig
}
);
// 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)

View File

@@ -162,6 +162,10 @@ trait Searchable
$query->orWhere($table.'.'.$column, 'LIKE', '%'.$term.'%');
}
}
// I put this here because I only want to add the concat one time in the end of the user relation search
if($relation == 'user') {
$query->orWhereRaw('CONCAT (users.first_name, " ", users.last_name) LIKE ?', ["%$term%"]);
}
});
}

View File

@@ -59,6 +59,9 @@ class User extends SnipeModel implements AuthenticatableContract, AuthorizableCo
'username',
'zip',
'remote',
'start_date',
'end_date',
'scim_externalid'
];
protected $casts = [
@@ -68,6 +71,16 @@ class User extends SnipeModel implements AuthenticatableContract, AuthorizableCo
'company_id' => 'integer',
];
protected $dates = [
'created_at',
'updated_at',
'deleted_at',
'start_date',
'end_date',
];
/**
* Model validation rules
*
@@ -83,6 +96,8 @@ class User extends SnipeModel implements AuthenticatableContract, AuthorizableCo
'website' => 'url|nullable|max:191',
'manager_id' => 'nullable|exists:users,id|cant_manage_self',
'location_id' => 'exists:locations,id|nullable',
'start_date' => 'nullable|date',
'end_date' => 'nullable|date|after_or_equal:start_date',
];
/**
@@ -308,7 +323,7 @@ class User extends SnipeModel implements AuthenticatableContract, AuthorizableCo
*/
public function consumables()
{
return $this->belongsToMany(\App\Models\Consumable::class, 'consumables_users', 'assigned_to', 'consumable_id')->withPivot('id','created_at')->withTrashed();
return $this->belongsToMany(\App\Models\Consumable::class, 'consumables_users', 'assigned_to', 'consumable_id')->withPivot('id','created_at','note')->withTrashed();
}
/**
@@ -323,6 +338,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
*

View File

@@ -0,0 +1,72 @@
<?php
namespace App\Notifications;
use App\Helpers\Helper;
use App\Models\Setting;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Messages\SlackMessage;
use Illuminate\Notifications\Notification;
class AcceptanceAssetAcceptedNotification extends Notification
{
use Queueable;
/**
* Create a new notification instance.
*
* @return void
*/
public function __construct($params)
{
$this->item_tag = $params['item_tag'];
$this->item_model = $params['item_model'];
$this->item_serial = $params['item_serial'];
$this->accepted_date = Helper::getFormattedDateObject($params['accepted_date'], 'date', false);
$this->assigned_to = $params['assigned_to'];
$this->company_name = $params['company_name'];
$this->settings = Setting::getSettings();
}
/**
* Get the notification's delivery channels.
*
* @param mixed $notifiable
* @return array
*/
public function via()
{
$notifyBy[] = 'mail';
return $notifyBy;
}
/**
* Get the mail representation of the notification.
*
* @param mixed $notifiable
* @return \Illuminate\Notifications\Messages\MailMessage
*/
public function toMail()
{
$message = (new MailMessage)->markdown('notifications.markdown.asset-acceptance',
[
'item_tag' => $this->item_tag,
'item_model' => $this->item_model,
'item_serial' => $this->item_serial,
'accepted_date' => $this->accepted_date,
'assigned_to' => $this->assigned_to,
'company_name' => $this->company_name,
'intro_text' => trans('mail.acceptance_asset_accepted'),
])
->subject(trans('mail.acceptance_asset_accepted'));
return $message;
}
}

View File

@@ -0,0 +1,70 @@
<?php
namespace App\Notifications;
use App\Helpers\Helper;
use App\Models\Setting;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Messages\SlackMessage;
use Illuminate\Notifications\Notification;
class AcceptanceAssetDeclinedNotification extends Notification
{
use Queueable;
/**
* Create a new notification instance.
*
* @return void
*/
public function __construct($params)
{
$this->item_tag = $params['item_tag'];
$this->item_model = $params['item_model'];
$this->item_serial = $params['item_serial'];
$this->declined_date = Helper::getFormattedDateObject($params['declined_date'], 'date', false);
$this->assigned_to = $params['assigned_to'];
$this->company_name = $params['company_name'];
$this->settings = Setting::getSettings();
}
/**
* Get the notification's delivery channels.
*
* @param mixed $notifiable
* @return array
*/
public function via($notifiable)
{
$notifyBy[] = 'mail';
return $notifyBy;
}
/**
* Get the mail representation of the notification.
*
* @param mixed $notifiable
* @return \Illuminate\Notifications\Messages\MailMessage
*/
public function toMail($notifiable)
{
$message = (new MailMessage)->markdown('notifications.markdown.asset-acceptance',
[
'item_tag' => $this->item_tag,
'item_model' => $this->item_model,
'item_serial' => $this->item_serial,
'declined_date' => $this->declined_date,
'assigned_to' => $this->assigned_to,
'company_name' => $this->company_name,
'intro_text' => trans('mail.acceptance_asset_declined'),
])
->subject(trans('mail.acceptance_asset_declined'));
return $message;
}
}

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);
}
}

View File

@@ -42,8 +42,12 @@ class LicensePolicy extends CheckoutablePermissionsPolicy
* @param \App\Models\User $user
* @return mixed
*/
public function files(User $user)
public function files(User $user, $license = null)
{
return $user->hasAccess($this->columnName().'.files');
if ($user->hasAccess('licenses.files')) {
return true;
}
return false;
}
}

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