mirror of
https://github.com/snipe/snipe-it.git
synced 2024-11-09 23:24:06 -08:00
Squashed commit of the following:
commite321aeabae
Merge:8ec99ff43
37568ae9e
Author: snipe <snipe@snipe.net> Date: Mon Aug 31 12:14:44 2020 -0700 Merge branch 'master' into integrations/2020-08-31-v5-rc # Conflicts: # .all-contributorsrc # .nvmrc # README.md # app/Console/Commands/LdapSync.php # app/Http/Controllers/Api/ConsumablesController.php # app/Http/Controllers/Api/ImportController.php # app/Http/Controllers/Assets/AssetsController.php # app/Http/Controllers/Auth/LoginController.php # app/Http/Controllers/CustomFieldsetsController.php # app/Http/Controllers/LicensesController.php # app/Http/Controllers/UsersController.php # app/Importer/import_mappings.md # app/Models/Ldap.php # app/Models/Loggable.php # composer.json # composer.lock # config/version.php # public/css/build/all.css # public/css/dist/all.css # public/css/skins/skin-contrast.css # public/css/skins/skin-contrast.css.map # public/js/build/all.js # public/js/build/vue.js # public/js/build/vue.js.map # public/js/dist/all.js # public/mix-manifest.json # resources/assets/js/components/importer/importer-file.vue # resources/assets/less/overrides.less # resources/macros/macros.php # resources/views/custom_fields/fieldsets/view.blade.php # resources/views/hardware/edit.blade.php # resources/views/hardware/labels.blade.php # resources/views/hardware/view.blade.php # resources/views/layouts/default.blade.php # resources/views/modals/model.blade.php # resources/views/modals/user.blade.php # resources/views/users/index.blade.php # routes/api.php # routes/web/fields.php # tests/unit/UserTest.php commit37568ae9ec
Merge:01a832169
32ad9050c
Author: snipe <snipe@snipe.net> Date: Tue Aug 25 20:49:37 2020 -0700 Merge pull request #8365 from snipe/fixes/8338_google_maps_CSP Fixed #8338 - Added google maps to CSP commit32ad9050cf
Author: snipe <snipe@snipe.net> Date: Tue Aug 25 20:48:53 2020 -0700 Added google maps to CSP commit01a832169c
Merge:bcad49ce7
3c6883489
Author: snipe <snipe@snipe.net> Date: Tue Aug 25 20:38:31 2020 -0700 Merge pull request #8364 from snipe/fixes/8335_assigned_to_null_on_status_assetlist Fixed #8335 - added assignedTo scope on status labels API call for assetlist commit3c6883489c
Author: snipe <snipe@snipe.net> Date: Tue Aug 25 20:37:30 2020 -0700 Added assignedTo scope commitbcad49ce79
Author: snipe <snipe@snipe.net> Date: Fri Aug 14 16:10:22 2020 -0700 Try to better handle slack “too many requests” issue commitb5acca89d7
Author: snipe <snipe@snipe.net> Date: Fri Aug 14 16:02:15 2020 -0700 Check for admin for slack notifications commite52919cf1b
Merge:714576be4
29f3a5c48
Author: snipe <snipe@snipe.net> Date: Fri Aug 14 15:35:15 2020 -0700 Merge pull request #8327 from snipe/features/checkin_license_from_all_users Checkin license from all users cli tool commit29f3a5c48f
Author: snipe <snipe@snipe.net> Date: Fri Aug 14 15:27:40 2020 -0700 Use more verbose annotation for Auth::user if/else commit134e8e6fb9
Author: snipe <snipe@snipe.net> Date: Fri Aug 14 15:25:07 2020 -0700 Moved user email nulling until after the save commit714576be45
Merge:b999c50a2
512899294
Author: Brady Wetherington <bwetherington@grokability.com> Date: Fri Aug 14 15:24:03 2020 -0700 Merge pull request #8328 from snipe/fix_deprecation_report Fix deprecation report for customers with many active assets commit5128992940
Author: Brady Wetherington <uberbrady@gmail.com> Date: Fri Aug 14 15:03:03 2020 -0700 Fix deprecation report for customers with many active assets commit0291323502
Author: snipe <snipe@snipe.net> Date: Fri Aug 14 14:57:58 2020 -0700 Use the user as the target commite0f6f9b839
Author: snipe <snipe@snipe.net> Date: Fri Aug 14 14:43:37 2020 -0700 Artisan command to check in licenses from all users commitf1a6308002
Author: snipe <snipe@snipe.net> Date: Fri Aug 14 14:43:07 2020 -0700 Check for Auth::user before trying to log id (for cli) commitb999c50a2e
Merge:9ca20e496
e3906b245
Author: snipe <snipe@snipe.net> Date: Wed Aug 12 12:37:47 2020 -0700 Merge pull request #8316 from Godmartinz/bug/ch15028/missing-or-incorrect-error-message-translation Looks great, thank you! commite3906b245c
Author: Godfrey M <godmartinz@gmail.com> Date: Wed Aug 12 12:27:18 2020 -0700 added translation for admin/licenses/message.not_found commit9ca20e4964
Merge:e0644dbbf
456a74d88
Author: Brady Wetherington <bwetherington@grokability.com> Date: Tue Aug 11 17:33:19 2020 -0700 Merge pull request #8313 from snipe/improve_ldap_search_error_reporting Improve ldap search error reporting commit456a74d88c
Author: Brady Wetherington <uberbrady@gmail.com> Date: Tue Aug 11 16:41:20 2020 -0700 De-merge out incorrectly merged files. Whoops! commit799c059070
Author: Brady Wetherington <uberbrady@gmail.com> Date: Tue Aug 11 16:21:18 2020 -0700 Add internationalized version of LDAP error message commitc62d43a778
Author: Brady Wetherington <uberbrady@gmail.com> Date: Mon Aug 10 17:04:17 2020 -0700 Improve Exception management in Artisan LDAP Sync method. Still need to localize this better commitb725bd0fae
Author: Brady Wetherington <uberbrady@gmail.com> Date: Mon Aug 10 17:23:04 2020 -0700 Add @PeterUpfold as a contributor commite0644dbbf6
Merge:5b6925b00
004ecad05
Author: Brady Wetherington <bwetherington@grokability.com> Date: Mon Aug 10 17:22:31 2020 -0700 Merge pull request #8105 from PeterUpfold/PeterUpfold-7661workaround Propose workaround for #7661 — suppress E_DEPRECATED on ldap_control_paged_result() commit5b6925b00c
Author: snipe <snipe@snipe.net> Date: Tue Aug 4 21:00:37 2020 -0700 Removed debugging :( commitdf17a859bf
Author: snipe <snipe@snipe.net> Date: Tue Aug 4 20:59:54 2020 -0700 Changed modal IDs so manager creation modal works on user creation main page commit24c43056ba
Author: snipe <snipe@snipe.net> Date: Tue Aug 4 20:58:28 2020 -0700 Moved pGenerator script to default layout footer This fixes an issue where the password generator wouldn’t load in a modal in Chrome commit606b7e905d
Author: snipe <snipe@snipe.net> Date: Fri Jul 31 17:02:33 2020 -0700 Small edits to PR template Slight text changes to ask specifics about versions commitd73ddad477
Author: snipe <snipe@snipe.net> Date: Fri Jul 31 16:59:26 2020 -0700 Created a PR template First draft of the PR guidelines template commit9a39cf721e
Merge:7410b1683
8994f3e15
Author: snipe <snipe@snipe.net> Date: Fri Jul 31 12:18:49 2020 -0700 Merge pull request #8258 from ballertv/features/consumable-api This looks great, thank you! commit7410b16835
Merge:e955c983a
b09e7d19b
Author: Brady Wetherington <bwetherington@grokability.com> Date: Fri Jul 24 16:22:44 2020 -0700 Merge pull request #8270 from snipe/improve_ad_useraccountcontrol_v4 Add new useraccountcontrol value for valid AD users commit8994f3e15e
Author: andres <andresgutierrez535@gmail.com> Date: Wed Jul 22 19:57:06 2020 -0400 cleanup commitd23f1a77ca
Author: andres <andresgutierrez535@gmail.com> Date: Wed Jul 22 18:46:02 2020 -0400 implement checkout API commite955c983a3
Merge:2fa17ac18
eed41e454
Author: snipe <snipe@snipe.net> Date: Wed Jul 22 13:43:29 2020 -0700 Merge pull request #8250 from snipe/features/adds_addr_city_state_to_importer Added address, city, state and country to importer and city to bulk editor commitb09e7d19b3
Author: Brady Wetherington <uberbrady@gmail.com> Date: Wed Jul 22 13:32:16 2020 -0700 Add new useraccountcontrol value for valid AD users; document algorithm and values commit2fa17ac185
Merge:b90515437
3b1e46f72
Author: snipe <snipe@snipe.net> Date: Wed Jul 22 12:06:31 2020 -0700 Merge pull request #8254 from Godmartinz/gmartinez_adds_email_formats Added firstinitial.lastname, lastname_firstinitial, firstnamelastname… commit3b1e46f72b
Author: Godfrey Martinez <47435081+Godmartinz@users.noreply.github.com> Date: Wed Jul 22 11:25:57 2020 -0700 Update general.php commit0c1a1de2a2
Author: Godfrey Martinez <47435081+Godmartinz@users.noreply.github.com> Date: Wed Jul 22 11:24:36 2020 -0700 Update general.php fixed typo commit20c9ae5818
Author: Godfrey M <godmartinz@gmail.com> Date: Wed Jul 22 10:21:19 2020 -0700 Added firstinitial.lastname, lastname_firstinitial, firstnamelastname and firstnamelastinitial to username formats commiteed41e4549
Author: snipe <snipe@snipe.net> Date: Tue Jul 21 16:57:32 2020 -0700 Moved address down further, fixed broken HTML commitb750f4754f
Author: snipe <snipe@snipe.net> Date: Tue Jul 21 16:49:54 2020 -0700 Added city to bulk user importer commitc17a06792a
Author: snipe <snipe@snipe.net> Date: Tue Jul 21 16:49:38 2020 -0700 Added address, city, state, country to user importer commit4f76cc6cfb
Author: snipe <snipe@snipe.net> Date: Tue Jul 21 16:46:13 2020 -0700 I don’t actually know what this file is for commitb905154373
Author: snipe <snipe@snipe.net> Date: Mon Jul 20 14:29:32 2020 -0700 Fixed #8247 - added notes field to user details display commitdaf748e531
Author: snipe <snipe@snipe.net> Date: Fri Jul 17 12:32:01 2020 -0700 Bumped hash commit799a93c46a
Author: snipe <snipe@snipe.net> Date: Fri Jul 17 12:11:32 2020 -0700 Allow for email/username search on users commit34aa12e229
Merge:81a633288
897757bd0
Author: snipe <snipe@snipe.net> Date: Thu Jul 16 17:44:13 2020 -0700 Merge pull request #8239 from snipe/fixes/api_rtd_to_location_on_create Set location_id to rtd_location_id on asset creation commit897757bd04
Author: snipe <snipe@snipe.net> Date: Thu Jul 16 17:43:44 2020 -0700 Removed added line for location commitc7125c3937
Author: snipe <snipe@snipe.net> Date: Thu Jul 16 16:34:39 2020 -0700 Set location_id to rtd_location_id on asset creation commit81a6332889
Author: snipe <snipe@snipe.net> Date: Tue Jul 14 13:55:38 2020 -0700 Removed license ID from seats table cookie info This typically wouldn’t be necessary, since most people would want to view the same *types* of data across licenses commit6e563f6e4b
Merge:5320f5c67
7f69ae953
Author: snipe <snipe@snipe.net> Date: Mon Jul 13 21:16:54 2020 -0700 Merge branch 'master' of https://github.com/snipe/snipe-it commit5320f5c67c
Author: snipe <snipe@snipe.net> Date: Mon Jul 13 21:16:45 2020 -0700 Disallow non-super users from editing their own permissions commit7f69ae953b
Merge:c79f8c1ba
17f6fbabf
Author: snipe <snipe@snipe.net> Date: Mon Jul 13 21:16:00 2020 -0700 Merge pull request #8227 from snipe/fix_select2_ajax_pulldowns Changes how we do AJAX calls via Select2 for dynamic drop-down menus commit17f6fbabfa
Author: Brady Wetherington <uberbrady@gmail.com> Date: Mon Jul 13 21:12:03 2020 -0700 Switch to 'items' to maintain compatbility with other internal API's commitc79f8c1baf
Merge:12c92e30b
536401fe0
Author: snipe <snipe@snipe.net> Date: Mon Jul 13 17:42:16 2020 -0700 Merge pull request #8207 from EDVLeer/patch-1 Update snipeit.sh commite7a820f7c9
Author: Brady Wetherington <uberbrady@gmail.com> Date: Mon Jul 13 17:14:31 2020 -0700 Changes how we do AJAX calls via Select2 for dynamic drop-down menus commit12c92e30b7
Author: snipe <snipe@snipe.net> Date: Fri Jul 10 16:21:27 2020 -0700 Show whether or not the user was imported via LDAP in the view page commitfd10b755b0
Author: snipe <snipe@snipe.net> Date: Fri Jul 10 11:30:01 2020 -0700 Removed the sr-only tag in table headers It was breaking Bootstrap Tables column selector :( commitdbbb7680d9
Author: snipe <snipe@snipe.net> Date: Thu Jul 9 21:12:50 2020 -0700 A few more fixes for the cli Do not check out a piece of software if it’s already been checked out to the user commitcf0dd5bbad
Author: snipe <snipe@snipe.net> Date: Thu Jul 9 20:43:13 2020 -0700 Small fixes for cli tool commit25e53d8c7f
Merge:ec6ed256f
89d433b41
Author: snipe <snipe@snipe.net> Date: Thu Jul 9 20:27:01 2020 -0700 Merge pull request #8216 from snipe/features/checkout_license_to_all_users Added CLI tool to checkout license to all users commit89d433b41a
Author: snipe <snipe@snipe.net> Date: Thu Jul 9 20:26:02 2020 -0700 Removed duplicate seat call commite2570ada6f
Author: snipe <snipe@snipe.net> Date: Thu Jul 9 20:04:05 2020 -0700 CLI tool to checkout a license to ALL users commit45afe725a1
Author: snipe <snipe@snipe.net> Date: Thu Jul 9 20:03:47 2020 -0700 Only try to get the company if there is an auth’d user (Needed for command line tools, where no Auth::user() is present) commit536401fe0f
Author: EDVLeer <32170051+EDVLeer@users.noreply.github.com> Date: Tue Jul 7 08:21:36 2020 +0200 Update snipeit.sh Ubuntu 20.04 commitec6ed256fb
Author: snipe <snipe@snipe.net> Date: Mon Jul 6 18:45:43 2020 -0700 Bumped minor version commit2aaa7bed2d
Merge:339bdddc3
cc9f1577a
Author: snipe <snipe@snipe.net> Date: Thu Jun 25 18:37:41 2020 -0700 Merge pull request #8183 from snipe/features/merge_users Added merge utility commitcc9f1577a4
Author: snipe <snipe@snipe.net> Date: Thu Jun 25 17:43:53 2020 -0700 Removed unused use directives commitab1fe8be0c
Author: snipe <snipe@snipe.net> Date: Thu Jun 25 17:42:39 2020 -0700 Added merge utility commit339bdddc38
Author: snipe <snipe@snipe.net> Date: Thu Jun 25 11:00:33 2020 -0700 Fix for Vue js not loading due to CSP :( commit35b9cf4b70
Author: snipe <snipe@snipe.net> Date: Tue Jun 23 02:41:59 2020 -0700 Fixed missing db prefix on scopeDueOrOverdueForAudit commit7ccb41371e
Author: snipe <snipe@snipe.net> Date: Tue Jun 23 01:09:39 2020 -0700 Removed unoptimized images directive securityheaders.com is claiming it’s onrecognized, even though I got that directive from their site, so… whatever. ¯\_(ツ)_/¯ commit2e60a457bf
Author: snipe <snipe@snipe.net> Date: Tue Jun 23 01:07:00 2020 -0700 Dumb fix for feature-policy being dumb. commit2390d2160b
Merge:b42801f6a
00b051b8c
Author: snipe <snipe@snipe.net> Date: Tue Jun 23 00:27:47 2020 -0700 Merge pull request #8164 from snipe/features/additional_security_headers Additional security headers commit00b051b8c7
Author: snipe <snipe@snipe.net> Date: Tue Jun 23 00:26:09 2020 -0700 Added a few more comments commit05b3a9ad7e
Author: snipe <snipe@snipe.net> Date: Mon Jun 22 23:17:27 2020 -0700 Config variable for HSTS commit4fb880384f
Author: snipe <snipe@snipe.net> Date: Mon Jun 22 22:37:14 2020 -0700 Changed comment commit43042ad841
Author: snipe <snipe@snipe.net> Date: Mon Jun 22 22:35:59 2020 -0700 Consolidated ReferrerPolicy into new SecurityHeaders file commita716382ac4
Author: snipe <snipe@snipe.net> Date: Mon Jun 22 22:33:37 2020 -0700 Removed CSP middleware (it’s added in the general header) commit36c8f7f4f1
Author: snipe <snipe@snipe.net> Date: Mon Jun 22 22:31:01 2020 -0700 Additional security headers commitb42801f6ae
Merge:de4934f21
946129f20
Author: snipe <snipe@snipe.net> Date: Mon Jun 22 20:47:35 2020 -0700 Merge pull request #8163 from snipe/fixes/fix-for-css-on-column-selector Fixed weird padlock display in asset listing with encrypted custom fields commit946129f206
Author: snipe <snipe@snipe.net> Date: Mon Jun 22 20:45:20 2020 -0700 Made quote style consistent commitb941ef1e08
Author: snipe <snipe@snipe.net> Date: Mon Jun 22 20:41:40 2020 -0700 Pulled CSS font awesome styles out of the blade and into overrides.css commitd1aa11ec89
Author: snipe <snipe@snipe.net> Date: Mon Jun 22 20:29:19 2020 -0700 Fix for weird padlock display in asset listing with encrypted custom fields commitde4934f21d
Merge:af06e4205
b10076b01
Author: snipe <snipe@snipe.net> Date: Mon Jun 22 17:28:38 2020 -0700 Merge pull request #8162 from Godmartinz/godfreymartinez-ghi-font-size-of-qr_text Fixed #8161 and #8114 - font-size for labels used static values in blade instead of using values from settings commitb10076b015
Author: Godfrey M <godmartinz@gmail.com> Date: Mon Jun 22 17:04:39 2020 -0700 corrected an error where font-size for labels were static in settings. commitaf06e42056
Author: snipe <snipe@snipe.net> Date: Wed Jun 17 11:17:25 2020 -0700 Bumped version commit9a2440dc4b
Merge:beae8efb2
2ac1c1636
Author: snipe <snipe@snipe.net> Date: Tue Jun 16 20:20:07 2020 -0700 Merge pull request #8141 from snipe/fixes/better_handling_when_license_is_invalid Better handle the logic to determine if we should display the license checkout blade [ch13792] commit2ac1c1636c
Author: snipe <snipe@snipe.net> Date: Tue Jun 16 16:12:57 2020 -0700 Better handle the logic to determine if we should display the license checkout blade commit004ecad059
Author: Peter Upfold <pgithub@upfold.org.uk> Date: Wed Jun 3 08:59:50 2020 +0100 Force suppress deprecation warning on ldap_control_paged_result() commitbeae8efb21
Merge:d14ab7e3e
9839e5e56
Author: snipe <snipe@snipe.net> Date: Wed May 27 23:01:33 2020 -0700 Merge pull request #8088 from Godmartinz/Label_Woes Barcode resizing and text adjustment commit9839e5e566
Author: Godfrey M <godmartinz@gmail.com> Date: Wed May 27 12:27:40 2020 -0700 adjusted for all label text, removed local variable commitd14ab7e3e1
Author: snipe <snipe@snipe.net> Date: Wed May 27 00:22:44 2020 -0700 Porting change from #8053 to master Signed-off-by: snipe <snipe@snipe.net> commite7f74d94c1
Author: Godfrey M <godmartinz@gmail.com> Date: Tue May 26 17:22:45 2020 -0700 Label_Woes commite97cf011b6
Author: Godfrey M <godmartinz@gmail.com> Date: Tue May 26 17:15:39 2020 -0700 Label_Woes commited23505054
Author: Godfrey M <godmartinz@gmail.com> Date: Tue May 26 17:10:45 2020 -0700 Label_Woes commit001e721530
Merge:f88683766
8210da6e8
Author: snipe <snipe@snipe.net> Date: Wed May 20 10:21:52 2020 -0700 Merge pull request #8063 from dmeltzer/backport-8092 BACKPORT: Fix Missing Category selection in Asset Model Modal dialog - [ch14635] commit8210da6e82
Author: Daniel Meltzer <dmeltzer.devel@gmail.com> Date: Wed May 20 10:29:27 2020 -0400 Fix Missing Category selection in Asset Model Modal dialog. A select html tag needs a full closing tag. is not valid. This was causing the select2 js to barf and eat additional information. commitf88683766b
Author: snipe <snipe@snipe.net> Date: Thu May 14 00:55:47 2020 -0700 Roll back previous change Signed-off-by: snipe <snipe@snipe.net> commite4385c0f8c
Author: snipe <snipe@snipe.net> Date: Thu May 14 00:48:30 2020 -0700 Fixes #8051 regression Signed-off-by: snipe <snipe@snipe.net> commit0550fe0ffa
Author: snipe <snipe@snipe.net> Date: Tue May 12 10:31:54 2020 -0700 Fix for session fixation vulnerability Signed-off-by: snipe <snipe@snipe.net> commit7fb3a9b82c
Merge:9a2ed804c
ecb1e87fe
Author: snipe <snipe@snipe.net> Date: Mon May 11 22:41:36 2020 -0700 Merge pull request #8043 from snipe/features/backup-optional-in-import-and-ldap Added option to disable backup in import commitecb1e87fe6
Author: snipe <snipe@snipe.net> Date: Mon May 11 20:45:15 2020 -0700 Updated assets Signed-off-by: snipe <snipe@snipe.net> commitf43df5f041
Author: snipe <snipe@snipe.net> Date: Mon May 11 20:44:46 2020 -0700 Fixed form label Signed-off-by: snipe <snipe@snipe.net> commit95cc48e422
Author: snipe <snipe@snipe.net> Date: Mon May 11 20:41:10 2020 -0700 Added option to disable backup in import Signed-off-by: snipe <snipe@snipe.net> commit9a2ed804ca
Author: snipe <snipe@snipe.net> Date: Mon May 11 20:28:42 2020 -0700 Fixed mismatched HTML header tags Signed-off-by: snipe <snipe@snipe.net> commitd20fad28e5
Author: snipe <snipe@snipe.net> Date: Mon May 11 20:28:24 2020 -0700 Use more modern request helper Signed-off-by: snipe <snipe@snipe.net> commitae813ddf75
Author: snipe <snipe@snipe.net> Date: Mon May 11 18:11:16 2020 -0700 Add @alek13 as a contributor commitbb42109c0c
Author: snipe <snipe@snipe.net> Date: Mon May 11 18:10:45 2020 -0700 Added a clarifying comment Signed-off-by: snipe <snipe@snipe.net> commitf46ecf8ec0
Author: snipe <snipe@snipe.net> Date: Mon May 11 18:07:20 2020 -0700 Updated composer lock Signed-off-by: snipe <snipe@snipe.net> commitb9e821c0e6
Author: snipe <snipe@snipe.net> Date: Mon May 11 18:07:14 2020 -0700 Small fix for Group Functional Tests Signed-off-by: snipe <snipe@snipe.net> commit9ee28c7513
Author: snipe <snipe@snipe.net> Date: Mon May 11 18:07:02 2020 -0700 Switched to use info instead of danger on undeployable statuses Signed-off-by: snipe <snipe@snipe.net> commit1a8ba06702
Merge:0fd232e70
ee4d69b1c
Author: snipe <snipe@snipe.net> Date: Mon May 11 17:53:32 2020 -0700 Merge branch 'master' of https://github.com/snipe/snipe-it commit0fd232e70d
Author: snipe <snipe@snipe.net> Date: Mon May 11 17:53:24 2020 -0700 Fixed group functional test (We had changed the minimum to 2 instead of 3) Signed-off-by: snipe <snipe@snipe.net> commitee4d69b1c5
Merge:31c535094
d1ad11194
Author: snipe <snipe@snipe.net> Date: Mon May 11 17:52:45 2020 -0700 Merge pull request #8041 from alek13/patch-1 use supported package for slack commitd1ad111949
Author: Alexander Chibrikin <alek13.me@gmail.com> Date: Mon May 11 20:31:13 2020 +0300 use supported package for slack see https://github.com/maknz/slack/issues/94 commit31c5350941
Author: snipe <snipe@snipe.net> Date: Fri May 1 01:05:48 2020 -0700 Fixed incorrect route for groups edit Signed-off-by: snipe <snipe@snipe.net> commit7eb70e17e0
Merge:5bb4f271a
3dfcb4699
Author: snipe <snipe@snipe.net> Date: Fri Apr 24 04:50:37 2020 -0700 Merge pull request #7993 from snipe/fixes/7989_column_selector Fixed #7989 - Converted table heading icons in People to CSS glyphs commit3dfcb46991
Author: snipe <snipe@snipe.net> Date: Fri Apr 24 04:41:08 2020 -0700 Minor formatting changes Signed-off-by: snipe <snipe@snipe.net> commit96eb96f964
Author: snipe <snipe@snipe.net> Date: Fri Apr 24 04:27:00 2020 -0700 Removed stray val (typo) Signed-off-by: snipe <snipe@snipe.net> commita2f08bd3ba
Author: snipe <snipe@snipe.net> Date: Fri Apr 24 04:08:54 2020 -0700 Added comments Signed-off-by: snipe <snipe@snipe.net> commite009fbe59f
Author: snipe <snipe@snipe.net> Date: Fri Apr 24 04:04:53 2020 -0700 Converted table heading icons in People to CSS glyphs Signed-off-by: snipe <snipe@snipe.net> commit5bb4f271aa
Author: snipe <snipe@snipe.net> Date: Fri Apr 24 00:47:19 2020 -0700 Fixed #7987 - allow toggle of required/optional in custom fields/fieldsets Signed-off-by: snipe <snipe@snipe.net>
This commit is contained in:
parent
8ec99ff433
commit
9c8ca6af21
|
@ -77,6 +77,7 @@ ALLOW_IFRAMING=false
|
|||
REFERRER_POLICY=same-origin
|
||||
ENABLE_CSP=false
|
||||
CORS_ALLOWED_ORIGINS=null
|
||||
ENABLE_HSTS=false
|
||||
|
||||
# --------------------------------------------
|
||||
# OPTIONAL: CACHE SETTINGS
|
||||
|
|
40
.github/pull_request_template.md
vendored
Normal file
40
.github/pull_request_template.md
vendored
Normal file
|
@ -0,0 +1,40 @@
|
|||
# Description
|
||||
|
||||
Please include a summary of the change and which issue is fixed. Please also include relevant motivation and context, providing screenshots where practical. List any dependencies that are required for this change.
|
||||
|
||||
Fixes # (issue)
|
||||
|
||||
## Type of change
|
||||
|
||||
Please delete options that are not relevant.
|
||||
|
||||
- [ ] Bug fix (non-breaking change which fixes an issue)
|
||||
- [ ] New feature (non-breaking change which adds functionality)
|
||||
- [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected)
|
||||
- [ ] This change requires a documentation update
|
||||
|
||||
# How Has This Been Tested?
|
||||
|
||||
Please describe the tests that you ran to verify your changes. Provide instructions so we can reproduce. Please also list any relevant details for your test configuration
|
||||
|
||||
- [ ] Test A
|
||||
- [ ] Test B
|
||||
|
||||
**Test Configuration**:
|
||||
* PHP version:
|
||||
* MySQL version
|
||||
* Webserver version
|
||||
* OS version
|
||||
|
||||
|
||||
# Checklist:
|
||||
|
||||
- [ ] I have read the Contributing documentation available here: https://snipe-it.readme.io/docs/contributing-overview
|
||||
- [ ] I have formatted this PR according to the project guidelines: https://snipe-it.readme.io/docs/contributing-overview#pull-request-guidelines
|
||||
- [ ] My code follows the style guidelines of this project
|
||||
- [ ] I have performed a self-review of my own code
|
||||
- [ ] I have commented my code, particularly in hard-to-understand areas
|
||||
- [ ] I have made corresponding changes to the documentation
|
||||
- [ ] My changes generate no new warnings
|
||||
- [ ] I have added tests that prove my fix is effective or that my feature works
|
||||
- [ ] New and existing unit tests pass locally with my changes
|
|
@ -1,4 +1,5 @@
|
|||
[![Build Status](https://travis-ci.org/snipe/snipe-it.svg?branch=master)](https://travis-ci.org/snipe/snipe-it) [![Crowdin](https://d322cqt584bo4o.cloudfront.net/snipe-it/localized.svg)](https://crowdin.com/project/snipe-it) [![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/snipe/snipe-it?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![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&utm_medium=referral&utm_content=snipe/snipe-it&utm_campaign=Badge_Grade)
|
||||
[![All Contributors](https://img.shields.io/badge/all_contributors-189-orange.svg?style=flat-square)](#contributors) [![Open Source Helpers](https://www.codetriage.com/snipe/snipe-it/badges/users.svg)](https://www.codetriage.com/snipe/snipe-it)
|
||||
[![All Contributors](https://img.shields.io/badge/all_contributors-212-orange.svg?style=flat-square)](#contributors) [![Open Source Helpers](https://www.codetriage.com/snipe/snipe-it/badges/users.svg)](https://www.codetriage.com/snipe/snipe-it)
|
||||
|
||||
|
||||
|
@ -114,6 +115,8 @@ Thanks goes to all of these wonderful people ([emoji key](https://github.com/ken
|
|||
| [<img src="https://avatars2.githubusercontent.com/u/982885?v=4" width="110px;"/><br /><sub>Martin Stub</sub>](http://martinstub.dk)<br />[🌍](#translation-stubben "Translation") | [<img src="https://avatars2.githubusercontent.com/u/28959963?v=4" width="110px;"/><br /><sub>Meyer Flavio</sub>](https://github.com/meyerf99)<br />[🌍](#translation-meyerf99 "Translation") | [<img src="https://avatars3.githubusercontent.com/u/796443?v=4" width="110px;"/><br /><sub>Micael Rodrigues</sub>](https://github.com/MicaelRodrigues)<br />[🌍](#translation-MicaelRodrigues "Translation") | [<img src="https://avatars0.githubusercontent.com/u/10481331?v=4" width="110px;"/><br /><sub>Mikael Rasmussen</sub>](http://rubixy.com/)<br />[🌍](#translation-mikaelssen "Translation") | [<img src="https://avatars1.githubusercontent.com/u/1544552?v=4" width="110px;"/><br /><sub>IxFail</sub>](https://github.com/IxFail)<br />[🌍](#translation-IxFail "Translation") | [<img src="https://avatars3.githubusercontent.com/u/18483118?v=4" width="110px;"/><br /><sub>Mohammed Fota</sub>](http://www.mohammedfota.com)<br />[🌍](#translation-MohammedFota "Translation") | [<img src="https://avatars0.githubusercontent.com/u/227080?v=4" width="110px;"/><br /><sub>Moayad Alserihi</sub>](https://github.com/omego)<br />[🌍](#translation-omego "Translation") |
|
||||
| [<img src="https://avatars0.githubusercontent.com/u/1680266?v=4" width="110px;"/><br /><sub>saymd</sub>](https://github.com/saymd)<br />[🌍](#translation-saymd "Translation") | [<img src="https://avatars0.githubusercontent.com/u/1826808?v=4" width="110px;"/><br /><sub>Patrik Larsson</sub>](https://nordsken.se)<br />[🌍](#translation-pooot "Translation") | [<img src="https://avatars1.githubusercontent.com/u/20584746?v=4" width="110px;"/><br /><sub>drcryo</sub>](https://github.com/drcryo)<br />[🌍](#translation-drcryo "Translation") | [<img src="https://avatars1.githubusercontent.com/u/19408004?v=4" width="110px;"/><br /><sub>pawel1615</sub>](https://github.com/pawel1615)<br />[🌍](#translation-pawel1615 "Translation") | [<img src="https://avatars2.githubusercontent.com/u/23340468?v=4" width="110px;"/><br /><sub>bodrovics</sub>](https://github.com/bodrovics)<br />[🌍](#translation-bodrovics "Translation") | [<img src="https://avatars0.githubusercontent.com/u/3257654?v=4" width="110px;"/><br /><sub>priatna</sub>](https://github.com/priatna)<br />[🌍](#translation-priatna "Translation") | [<img src="https://avatars1.githubusercontent.com/u/5358374?v=4" width="110px;"/><br /><sub>Fan Jiang</sub>](https://amayume.net)<br />[🌍](#translation-ProfFan "Translation") |
|
||||
| [<img src="https://avatars1.githubusercontent.com/u/22555451?v=4" width="110px;"/><br /><sub>ragnarcx</sub>](https://github.com/ragnarcx)<br />[🌍](#translation-ragnarcx "Translation") | [<img src="https://avatars2.githubusercontent.com/u/18654582?v=4" width="110px;"/><br /><sub>Rein van Haaren</sub>](http://www.reinvanhaaren.nl/)<br />[🌍](#translation-reinvanhaaren "Translation") | [<img src="https://avatars1.githubusercontent.com/u/386672?v=4" width="110px;"/><br /><sub>Teguh Dwicaksana</sub>](http://dheche.songolimo.net)<br />[🌍](#translation-dheche "Translation") | [<img src="https://avatars2.githubusercontent.com/u/2572552?v=4" width="110px;"/><br /><sub>fraccie</sub>](https://github.com/FRaccie)<br />[🌍](#translation-FRaccie "Translation") | [<img src="https://avatars0.githubusercontent.com/u/35182720?v=4" width="110px;"/><br /><sub>vinzruzell</sub>](https://github.com/vinzruzell)<br />[🌍](#translation-vinzruzell "Translation") | [<img src="https://avatars1.githubusercontent.com/u/7883603?v=4" width="110px;"/><br /><sub>Kevin Austin</sub>](http://kevinaustin.com)<br />[🌍](#translation-vipsystem "Translation") | [<img src="https://avatars3.githubusercontent.com/u/3861828?v=4" width="110px;"/><br /><sub>Wira Sandy</sub>](http://azuraweb.xyz)<br />[🌍](#translation-wira-sandy "Translation") |
|
||||
| [<img src="https://avatars2.githubusercontent.com/u/8663789?v=4" width="110px;"/><br /><sub>Илья</sub>](https://github.com/GrayHoax)<br />[🌍](#translation-GrayHoax "Translation") | [<img src="https://avatars3.githubusercontent.com/u/30119111?v=4" width="110px;"/><br /><sub>GodUseVPN</sub>](https://github.com/godusevpn)<br />[🌍](#translation-godusevpn "Translation") | [<img src="https://avatars1.githubusercontent.com/u/745576?v=4" width="110px;"/><br /><sub>周周</sub>](https://github.com/EngrZhou)<br />[🌍](#translation-EngrZhou "Translation") | [<img src="https://avatars3.githubusercontent.com/u/1631095?v=4" width="110px;"/><br /><sub>Sam</sub>](https://github.com/takuy)<br />[💻](https://github.com/snipe/snipe-it/commits?author=takuy "Code") | [<img src="https://avatars1.githubusercontent.com/u/264022?v=4" width="110px;"/><br /><sub>Azerothian</sub>](https://www.illisian.com.au)<br />[💻](https://github.com/snipe/snipe-it/commits?author=Azerothian "Code") | [<img src="https://avatars1.githubusercontent.com/u/7632599?v=4" width="110px;"/><br /><sub>Tim Farmer</sub>](https://github.com/timothyfarmer)<br />[💻](https://github.com/snipe/snipe-it/commits?author=timothyfarmer "Code") | [<img src="https://avatars0.githubusercontent.com/u/17459600?v=4" width="110px;"/><br /><sub>Marián Skrip</sub>](https://github.com/mskrip)<br />[💻](https://github.com/snipe/snipe-it/commits?author=mskrip "Code") |
|
||||
| [<img src="https://avatars2.githubusercontent.com/u/47435081?v=4" width="110px;"/><br /><sub>Godfrey Martinez</sub>](https://github.com/Godmartinz)<br />[💻](https://github.com/snipe/snipe-it/commits?author=Godmartinz "Code") | [<img src="https://avatars1.githubusercontent.com/u/2075128?v=4" width="110px;"/><br /><sub>bigtreeEdo</sub>](https://github.com/bigtreeEdo)<br />[💻](https://github.com/snipe/snipe-it/commits?author=bigtreeEdo "Code") | [<img src="https://avatars0.githubusercontent.com/u/5000430?v=4" width="110px;"/><br /><sub>Colin McNeil</sub>](https://colinmcneil.me/)<br />[💻](https://github.com/snipe/snipe-it/commits?author=ColinMcNeil "Code") | [<img src="https://avatars0.githubusercontent.com/u/421625?v=4" width="110px;"/><br /><sub>JoKneeMo</sub>](https://github.com/JoKneeMo)<br />[💻](https://github.com/snipe/snipe-it/commits?author=JoKneeMo "Code") | [<img src="https://avatars0.githubusercontent.com/u/54849013?v=4" width="110px;"/><br /><sub>Joshi</sub>](http://www.redbridge.se)<br />[💻](https://github.com/snipe/snipe-it/commits?author=joshi-redbridge "Code") | [<img src="https://avatars2.githubusercontent.com/u/15731458?v=4" width="110px;"/><br /><sub>Anthony Burns</sub>](https://github.com/anthonypburns)<br />[💻](https://github.com/snipe/snipe-it/commits?author=anthonypburns "Code") | [<img src="https://avatars2.githubusercontent.com/u/1972329?v=4" width="110px;"/><br /><sub>Alexander Chibrikin</sub>](http://phpprofi.ru/)<br />[💻](https://github.com/snipe/snipe-it/commits?author=alek13 "Code") |
|
||||
| [<img src="https://avatars2.githubusercontent.com/u/8663789?v=4" width="110px;"/><br /><sub>Илья</sub>](https://github.com/GrayHoax)<br />[🌍](#translation-GrayHoax "Translation") | [<img src="https://avatars3.githubusercontent.com/u/30119111?v=4" width="110px;"/><br /><sub>GodUseVPN</sub>](https://github.com/godusevpn)<br />[🌍](#translation-godusevpn "Translation") | [<img src="https://avatars1.githubusercontent.com/u/745576?v=4" width="110px;"/><br /><sub>周周</sub>](https://github.com/EngrZhou)<br />[🌍](#translation-EngrZhou "Translation") | [<img src="https://avatars3.githubusercontent.com/u/1631095?v=4" width="110px;"/><br /><sub>Sam</sub>](https://github.com/takuy)<br />[💻](https://github.com/snipe/snipe-it/commits?author=takuy "Code") | [<img src="https://avatars1.githubusercontent.com/u/264022?v=4" width="110px;"/><br /><sub>Azerothian</sub>](https://www.illisian.com.au)<br />[💻](https://github.com/snipe/snipe-it/commits?author=Azerothian "Code") | [<img src="https://avatars1.githubusercontent.com/u/4930051?v=4" width="110px;"/><br /><sub>Wes Hulette</sub>](http://macfoo.wordpress.com/)<br />[💻](https://github.com/snipe/snipe-it/commits?author=jwhulette "Code") | [<img src="https://avatars0.githubusercontent.com/u/8134591?v=4" width="110px;"/><br /><sub>patrict</sub>](https://github.com/patrict)<br />[💻](https://github.com/snipe/snipe-it/commits?author=patrict "Code") |
|
||||
| [<img src="https://avatars3.githubusercontent.com/u/2611616?v=4" width="110px;"/><br /><sub>Dmitriy Minaev</sub>](https://github.com/VELIKII-DIVAN)<br />[💻](https://github.com/snipe/snipe-it/commits?author=VELIKII-DIVAN "Code") | [<img src="https://avatars0.githubusercontent.com/u/5132245?v=4" width="110px;"/><br /><sub>liquidhorse</sub>](https://github.com/liquidhorse)<br />[💻](https://github.com/snipe/snipe-it/commits?author=liquidhorse "Code") | [<img src="https://avatars1.githubusercontent.com/u/183678?v=4" width="110px;"/><br /><sub>Jordi Boggiano</sub>](https://seld.be/)<br />[💻](https://github.com/snipe/snipe-it/commits?author=Seldaek "Code") | [<img src="https://avatars0.githubusercontent.com/u/653557?v=4" width="110px;"/><br /><sub>Ivan Nieto</sub>](https://github.com/inietov)<br />[💻](https://github.com/snipe/snipe-it/commits?author=inietov "Code") | [<img src="https://avatars2.githubusercontent.com/u/6764151?v=4" width="110px;"/><br /><sub>Ben RUBSON</sub>](https://github.com/benrubson)<br />[💻](https://github.com/snipe/snipe-it/commits?author=benrubson "Code") | [<img src="https://avatars2.githubusercontent.com/u/8554558?v=4" width="110px;"/><br /><sub>NMathar</sub>](https://github.com/NMathar)<br />[💻](https://github.com/snipe/snipe-it/commits?author=NMathar "Code") | [<img src="https://avatars1.githubusercontent.com/u/139566?v=4" width="110px;"/><br /><sub>Steffen</sub>](https://github.com/smb)<br />[💻](https://github.com/snipe/snipe-it/commits?author=smb "Code") |
|
||||
| [<img src="https://avatars0.githubusercontent.com/u/6609453?v=4" width="110px;"/><br /><sub>Sxderp</sub>](https://github.com/Sxderp)<br />[💻](https://github.com/snipe/snipe-it/commits?author=Sxderp "Code") | [<img src="https://avatars1.githubusercontent.com/u/4807843?v=4" width="110px;"/><br /><sub>fanta8897</sub>](https://github.com/fanta8897)<br />[💻](https://github.com/snipe/snipe-it/commits?author=fanta8897 "Code") | [<img src="https://avatars2.githubusercontent.com/u/2576509?v=4" width="110px;"/><br /><sub>Andrey Bolonin</sub>](https://andreybolonin.com/phpconsulting/)<br />[💻](https://github.com/snipe/snipe-it/commits?author=andreybolonin "Code") | [<img src="https://avatars3.githubusercontent.com/u/2173307?v=4" width="110px;"/><br /><sub>shinayoshi</sub>](http://www.shinayoshi.net/)<br />[💻](https://github.com/snipe/snipe-it/commits?author=shinayoshi "Code") | [<img src="https://avatars3.githubusercontent.com/u/2130159?v=4" width="110px;"/><br /><sub>Hubert</sub>](https://github.com/reuser)<br />[💻](https://github.com/snipe/snipe-it/commits?author=reuser "Code") | [<img src="https://avatars0.githubusercontent.com/u/6865789?v=4" width="110px;"/><br /><sub>KeenRivals</sub>](https://brashear.me)<br />[💻](https://github.com/snipe/snipe-it/commits?author=KeenRivals "Code") | [<img src="https://avatars3.githubusercontent.com/u/2902513?v=4" width="110px;"/><br /><sub>omyno</sub>](https://github.com/omyno)<br />[💻](https://github.com/snipe/snipe-it/commits?author=omyno "Code") |
|
||||
|
|
95
app/Console/Commands/CheckinLicensesFromAllUsers.php
Normal file
95
app/Console/Commands/CheckinLicensesFromAllUsers.php
Normal file
|
@ -0,0 +1,95 @@
|
|||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use App\Models\LicenseSeat;
|
||||
use Illuminate\Console\Command;
|
||||
use App\Models\User;
|
||||
use App\Models\License;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class CheckinLicensesFromAllUsers extends Command
|
||||
{
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'snipeit:checkin-from-all {--license_id=} {--notify}';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Checks in licenses from all users';
|
||||
|
||||
/**
|
||||
* Create a new command instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
|
||||
$license_id = $this->option('license_id');
|
||||
$notify = $this->option('notify');
|
||||
|
||||
if (!$license_id) {
|
||||
$this->error('ERROR: License ID is required.');
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
if (!$license = License::where('id','=',$license_id)->first()) {
|
||||
$this->error('Invalid license ID');
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->info('Checking in ALL seats for '.$license->name);
|
||||
|
||||
|
||||
$licenseSeats = LicenseSeat::where('license_id', '=', $license_id)
|
||||
->whereNotNull('assigned_to')
|
||||
->with('user')
|
||||
->get();
|
||||
|
||||
$this->info(' There are ' .$licenseSeats->count(). ' seats checked out: ');
|
||||
|
||||
if (!$notify) {
|
||||
$this->info('No mail will be sent.');
|
||||
}
|
||||
|
||||
foreach ($licenseSeats as $seat) {
|
||||
$this->info($seat->user->username .' has a license seat for '.$license->name);
|
||||
$seat->assigned_to = null;
|
||||
|
||||
if ($seat->save()) {
|
||||
|
||||
// Override the email address so we don't notify on checkin
|
||||
if (!$notify) {
|
||||
$seat->user->email = null;
|
||||
}
|
||||
|
||||
// Log the checkin
|
||||
$seat->logCheckin($seat->user, 'Checked in via cli tool');
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
112
app/Console/Commands/CheckoutLicenseToAllUsers.php
Normal file
112
app/Console/Commands/CheckoutLicenseToAllUsers.php
Normal file
|
@ -0,0 +1,112 @@
|
|||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use App\Models\LicenseSeat;
|
||||
use Illuminate\Console\Command;
|
||||
use App\Models\User;
|
||||
use App\Models\License;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class CheckoutLicenseToAllUsers extends Command
|
||||
{
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'snipeit:checkout-to-all {--license_id=} {--notify}';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Command description';
|
||||
|
||||
/**
|
||||
* Create a new command instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
|
||||
$license_id = $this->option('license_id');
|
||||
$notify = $this->option('notify');
|
||||
|
||||
if (!$license_id) {
|
||||
$this->error('ERROR: License ID is required.');
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
if (!$license = License::where('id','=',$license_id)->with('assignedusers')->first()) {
|
||||
$this->error('Invalid license ID');
|
||||
return false;
|
||||
}
|
||||
|
||||
$users = User::whereNull('deleted_at')->with('licenses')->get();
|
||||
|
||||
if ($users->count() > $license->getAvailSeatsCountAttribute()) {
|
||||
$this->info('You do not have enough free seats to complete this task, so we will check out as many as we can. ');
|
||||
}
|
||||
|
||||
$this->info('Checking out '.$users->count().' of '.$license->getAvailSeatsCountAttribute().' seats for '.$license->name);
|
||||
|
||||
if (!$notify) {
|
||||
$this->info('No mail will be sent.');
|
||||
}
|
||||
|
||||
foreach ($users as $user) {
|
||||
|
||||
// Check to make sure this user doesn't already have this license checked out
|
||||
// to them
|
||||
|
||||
if ($user->licenses->where('id', '=', $license_id)->count()) {
|
||||
$this->info($user->username .' already has this license checked out to them. Skipping... ');
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
// If the license is valid, check that there is an available seat
|
||||
if ($license->availCount()->count() < 1) {
|
||||
$this->error('ERROR: No available seats');
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->info($license->availCount()->count().' seats left');
|
||||
// Get the seat ID
|
||||
$licenseSeat = $license->freeSeat();
|
||||
|
||||
|
||||
// Update the seat with checkout info,
|
||||
$licenseSeat->assigned_to = $user->id;
|
||||
if ($licenseSeat->save()) {
|
||||
|
||||
// Temporarily null the user's email address so we don't send mail if we're not supposed to
|
||||
if (!$notify) {
|
||||
$user->email = null;
|
||||
}
|
||||
|
||||
// Log the checkout
|
||||
$licenseSeat->logCheckout('Checked out via cli tool', $user);
|
||||
$this->info('License '.$license_id.' seat '.$licenseSeat->id.' checked out to '.$user->username);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
109
app/Console/Commands/MergeUsersByUsername.php
Normal file
109
app/Console/Commands/MergeUsersByUsername.php
Normal file
|
@ -0,0 +1,109 @@
|
|||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use Illuminate\Console\Command;
|
||||
use App\Models\User;
|
||||
use Carbon\Carbon;
|
||||
|
||||
|
||||
class MergeUsersByUsername extends Command
|
||||
{
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'snipeit:merge-users';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'This command allows you to merge the history of users. It looks for users without an email address as their username and merges them into the version that does have an email username.';
|
||||
|
||||
/**
|
||||
* Create a new command instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
// Get the list of users who have an email address as their username
|
||||
$users = User::where('username', 'LIKE', '%@%')->whereNull('deleted_at')->get();
|
||||
|
||||
foreach ($users as $user) {
|
||||
$parts = explode("@", $user->username);
|
||||
$bad_users = User::where('username', '=', $parts[0])->whereNull('deleted_at')->with('assets', 'manager', 'userlog', 'licenses', 'consumables', 'accessories', 'managedLocations')->get();
|
||||
|
||||
foreach ($bad_users as $bad_user) {
|
||||
$this->info($bad_user->username.' ('.$bad_user->id.') will be merged into '.$user->username.' ('.$user->id.') ');
|
||||
|
||||
// Walk the list of assets
|
||||
foreach ($bad_user->assets as $asset) {
|
||||
$this->info( 'Updating asset '.$asset->asset_tag.' '.$asset->id.' to user '.$user->id);
|
||||
$asset->assigned_to = $user->id;
|
||||
$asset->save();
|
||||
}
|
||||
|
||||
// Walk the list of licenses
|
||||
foreach ($bad_user->licenses as $license) {
|
||||
$this->info( 'Updating license '.$license->name.' '.$license->id.' to user '.$user->id);
|
||||
$bad_user->licenses()->updateExistingPivot($license->id, ['assigned_to' => $user->id]);
|
||||
}
|
||||
|
||||
// Walk the list of consumables
|
||||
foreach ($bad_user->consumables as $consumable) {
|
||||
$this->info( 'Updating consumable '.$consumable->id.' to user '.$user->id);
|
||||
$bad_user->consumables()->updateExistingPivot($consumable->id, ['assigned_to' => $user->id]);
|
||||
}
|
||||
|
||||
// Walk the list of accessories
|
||||
foreach ($bad_user->accessories as $accessory) {
|
||||
$this->info( 'Updating accessory '.$accessory->id.' to user '.$user->id);
|
||||
$bad_user->accessories()->updateExistingPivot($accessory->id, ['assigned_to' => $user->id]);
|
||||
}
|
||||
|
||||
// Walk the list of logs
|
||||
foreach ($bad_user->userlog as $log) {
|
||||
$this->info( 'Updating action log record '.$log->id.' to user '.$user->id);
|
||||
$log->target_id = $user->id;
|
||||
$log->save();
|
||||
}
|
||||
|
||||
// Update any manager IDs
|
||||
$this->info( 'Updating managed user records to user '.$user->id);
|
||||
User::where('manager_id', '=', $bad_user->id)->update(['manager_id' => $user->id]);
|
||||
|
||||
|
||||
// Update location manager IDs
|
||||
foreach ($bad_user->managedLocations as $managedLocation) {
|
||||
$this->info( 'Updating managed location record '.$managedLocation->name.' to manager '.$user->id);
|
||||
$managedLocation->manager_id = $user->id;
|
||||
$managedLocation->save();
|
||||
}
|
||||
|
||||
// Mark the user as deleted
|
||||
$this->info( 'Marking the user as deleted');
|
||||
$bad_user->deleted_at = Carbon::now()->timestamp;
|
||||
$bad_user->save();
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
|
@ -457,6 +457,7 @@ class AssetsController extends Controller
|
|||
$asset->supplier_id = $request->get('supplier_id', 0);
|
||||
$asset->requestable = $request->get('requestable', 0);
|
||||
$asset->rtd_location_id = $request->get('rtd_location_id', null);
|
||||
$asset->location_id = $request->get('rtd_location_id', null);
|
||||
|
||||
if ($request->has('image_source') && $request->input('image_source') != "") {
|
||||
$saved_image_path = Helper::processUploadedImage(
|
||||
|
|
|
@ -8,7 +8,9 @@ use App\Http\Transformers\ConsumablesTransformer;
|
|||
use App\Http\Transformers\SelectlistTransformer;
|
||||
use App\Models\Company;
|
||||
use App\Models\Consumable;
|
||||
use Illuminate\Http\Request;
|
||||
use App\Models\User;
|
||||
use App\Http\Transformers\ConsumablesTransformer;
|
||||
use App\Helpers\Helper;
|
||||
|
||||
class ConsumablesController extends Controller
|
||||
{
|
||||
|
@ -198,6 +200,57 @@ class ConsumablesController extends Controller
|
|||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checkout a consumable
|
||||
*
|
||||
* @author [A. Gutierrez] [<andres@baller.tv>]
|
||||
* @param int $id
|
||||
* @since [v4.9.5]
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function checkout(Request $request, $id)
|
||||
{
|
||||
// Check if the consumable exists
|
||||
if (is_null($consumable = Consumable::find($id))) {
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, trans('admin/consumables/message.does_not_exist')));
|
||||
}
|
||||
|
||||
$this->authorize('checkout', $consumable);
|
||||
|
||||
if ($consumable->qty > 0) {
|
||||
|
||||
// Check if the user exists
|
||||
$assigned_to = $request->input('assigned_to');
|
||||
if (is_null($user = User::find($assigned_to))) {
|
||||
// Return error message
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, 'No user found'));
|
||||
}
|
||||
|
||||
// Update the consumable data
|
||||
$consumable->assigned_to = e($assigned_to);
|
||||
|
||||
$consumable->users()->attach($consumable->id, [
|
||||
'consumable_id' => $consumable->id,
|
||||
'user_id' => $user->id,
|
||||
'assigned_to' => $assigned_to
|
||||
]);
|
||||
|
||||
// Log checkout event
|
||||
$logaction = $consumable->logCheckout(e($request->input('note')), $user);
|
||||
$data['log_id'] = $logaction->id;
|
||||
$data['eula'] = $consumable->getEula();
|
||||
$data['first_name'] = $user->first_name;
|
||||
$data['item_name'] = $consumable->name;
|
||||
$data['checkout_date'] = $logaction->created_at;
|
||||
$data['note'] = $logaction->note;
|
||||
$data['require_acceptance'] = $consumable->requireAcceptance();
|
||||
|
||||
return response()->json(Helper::formatStandardApiResponse('success', null, trans('admin/consumables/message.checkout.success')));
|
||||
}
|
||||
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, 'No consumables remaining'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a paginated collection for the select2 menus
|
||||
*
|
||||
|
|
|
@ -78,6 +78,14 @@ class UsersController extends Controller
|
|||
$users = $users->where('users.location_id', '=', $request->input('location_id'));
|
||||
}
|
||||
|
||||
if ($request->filled('email')) {
|
||||
$users = $users->where('users.email', '=', $request->input('email'));
|
||||
}
|
||||
|
||||
if ($request->filled('username')) {
|
||||
$users = $users->where('users.username', '=', $request->input('username'));
|
||||
}
|
||||
|
||||
if ($request->filled('group_id')) {
|
||||
$users = $users->ByGroup($request->get('group_id'));
|
||||
}
|
||||
|
|
|
@ -385,6 +385,7 @@ class LoginController extends Controller
|
|||
|
||||
$request->session()->regenerate(true);
|
||||
|
||||
$request->session()->regenerate(true);
|
||||
Auth::logout();
|
||||
|
||||
if (!empty($sloRedirectUrl)) {
|
||||
|
|
|
@ -17,15 +17,12 @@ class Kernel extends HttpKernel
|
|||
\Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode::class,
|
||||
\Illuminate\Session\Middleware\StartSession::class,
|
||||
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
|
||||
\App\Http\Middleware\FrameGuard::class,
|
||||
\App\Http\Middleware\XssProtectHeader::class,
|
||||
\App\Http\Middleware\ReferrerPolicyHeader::class,
|
||||
\App\Http\Middleware\ContentSecurityPolicyHeader::class,
|
||||
\App\Http\Middleware\NosniffGuard::class,
|
||||
\Fideloper\Proxy\TrustProxies::class,
|
||||
\App\Http\Middleware\CheckForSetup::class,
|
||||
\App\Http\Middleware\CheckForDebug::class,
|
||||
\Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
|
||||
\App\Http\Middleware\SecurityHeaders::class,
|
||||
|
||||
];
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,35 +0,0 @@
|
|||
<?php
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Closure;
|
||||
|
||||
class ContentSecurityPolicyHeader
|
||||
{
|
||||
/**
|
||||
* Handle the given request and get the response.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Closure $next
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function handle($request, Closure $next)
|
||||
{
|
||||
if ((config('app.debug')=='true') || (config('app.enable_csp')!='true')) {
|
||||
$response = $next($request);
|
||||
return $response;
|
||||
}
|
||||
|
||||
$policy[] = "default-src 'self'";
|
||||
$policy[] = "style-src 'self' 'unsafe-inline' oss.maxcdn.com";
|
||||
$policy[] = "script-src 'self' 'unsafe-inline' 'unsafe-eval' cdnjs.cloudflare.com";
|
||||
$policy[] = "connect-src 'self'";
|
||||
$policy[] = "object-src 'none'";
|
||||
$policy[] = "font-src 'self' data:";
|
||||
$policy[] = "img-src 'self' data: gravatar.com";
|
||||
$policy = join(';', $policy);
|
||||
|
||||
$response = $next($request);
|
||||
$response->headers->set('Content-Security-Policy', $policy);
|
||||
return $response;
|
||||
}
|
||||
}
|
|
@ -1,24 +0,0 @@
|
|||
<?php
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Closure;
|
||||
|
||||
class FrameGuard
|
||||
{
|
||||
/**
|
||||
* Handle the given request and get the response.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Closure $next
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function handle($request, Closure $next)
|
||||
{
|
||||
$response = $next($request);
|
||||
if (config('app.allow_iframing') == false) {
|
||||
$response->headers->set('X-Frame-Options', 'SAMEORIGIN', false);
|
||||
}
|
||||
return $response;
|
||||
|
||||
}
|
||||
}
|
|
@ -1,21 +0,0 @@
|
|||
<?php
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Closure;
|
||||
|
||||
class NosniffGuard
|
||||
{
|
||||
/**
|
||||
* Handle the given request and get the response.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Closure $next
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function handle($request, Closure $next)
|
||||
{
|
||||
$response = $next($request);
|
||||
$response->headers->set('X-Content-Type-Options', 'nosniff', false);
|
||||
return $response;
|
||||
}
|
||||
}
|
|
@ -1,21 +0,0 @@
|
|||
<?php
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Closure;
|
||||
|
||||
class ReferrerPolicyHeader
|
||||
{
|
||||
/**
|
||||
* Handle the given request and get the response.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Closure $next
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function handle($request, Closure $next)
|
||||
{
|
||||
$response = $next($request);
|
||||
$response->headers->set('Referrer-Policy', config('app.referrer_policy'));
|
||||
return $response;
|
||||
}
|
||||
}
|
122
app/Http/Middleware/SecurityHeaders.php
Normal file
122
app/Http/Middleware/SecurityHeaders.php
Normal file
|
@ -0,0 +1,122 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Closure;
|
||||
|
||||
class SecurityHeaders
|
||||
{
|
||||
/**
|
||||
* Handle an incoming request.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Closure $next
|
||||
* @return mixed
|
||||
*/
|
||||
|
||||
// See https://securityheaders.com/
|
||||
private $unwantedHeaderList = [
|
||||
'X-Powered-By',
|
||||
'Server',
|
||||
];
|
||||
|
||||
public function handle($request, Closure $next)
|
||||
{
|
||||
$this->removeUnwantedHeaders($this->unwantedHeaderList);
|
||||
$response = $next($request);
|
||||
|
||||
$response->headers->set('X-Content-Type-Options', 'nosniff');
|
||||
$response->headers->set('X-XSS-Protection', '1; mode=block');
|
||||
|
||||
// Ugh. Feature-Policy is dumb and clumsy and mostly irrelevant for Snipe-IT,
|
||||
// since we don't provide any way to IFRAME anything in in the first place.
|
||||
// There is currently no easy way to default ALL THE THINGS to 'none', but
|
||||
// security audits will still ding you if you don't have this header, even
|
||||
// though we don't allow IFRAMING in the first place.
|
||||
//
|
||||
// So for security and compliance sake, here we are. Sigh.
|
||||
//
|
||||
// See also:
|
||||
// - https://developers.google.com/web/updates/2018/06/feature-policy
|
||||
// - https://scotthelme.co.uk/a-new-security-header-feature-policy/
|
||||
// - https://github.com/w3c/webappsec-feature-policy/issues/189
|
||||
|
||||
$feature_policy[] = "accelerometer 'none'";
|
||||
$feature_policy[] = "ambient-light-sensor 'none'";
|
||||
$feature_policy[] = "animations 'none'";
|
||||
$feature_policy[] = "autoplay 'none'";
|
||||
$feature_policy[] = "battery 'none'";
|
||||
$feature_policy[] = "camera 'none'";
|
||||
$feature_policy[] = "display-capture 'none'";
|
||||
$feature_policy[] = "document-domain 'none'";
|
||||
$feature_policy[] = "encrypted-media 'none'";
|
||||
$feature_policy[] = "fullscreen 'none'";
|
||||
$feature_policy[] = "geolocation 'none'";
|
||||
$feature_policy[] = "gyroscope 'none'";
|
||||
$feature_policy[] = "legacy-image-formats 'none'";
|
||||
$feature_policy[] = "magnetometer 'none'";
|
||||
$feature_policy[] = "microphone 'none'";
|
||||
$feature_policy[] = "midi 'none'";
|
||||
$feature_policy[] = "oversized-images 'none'";
|
||||
$feature_policy[] = "payment 'none'";
|
||||
$feature_policy[] = "picture-in-picture 'none'";
|
||||
$feature_policy[] = "publickey-credentials 'none'";
|
||||
$feature_policy[] = "sync-xhr 'none'";
|
||||
$feature_policy[] = "unsized-media 'none'";
|
||||
$feature_policy[] = "usb 'none'";
|
||||
$feature_policy[] = "vibrate 'none'";
|
||||
$feature_policy[] = "wake-lock 'none'";
|
||||
$feature_policy[] = "xr-spatial-tracking 'none'";
|
||||
|
||||
$feature_policy = join(';', $feature_policy);
|
||||
$response->headers->set('Feature-Policy', $feature_policy);
|
||||
|
||||
|
||||
|
||||
// Defaults to same-origin if REFERRER_POLICY is not set in the .env
|
||||
$response->headers->set('Referrer-Policy', config('app.referrer_policy'));
|
||||
|
||||
// The .env var ALLOW_IFRAMING defaults to false (which disallows IFRAMING)
|
||||
// if not present, but some unique cases require this to be enabled.
|
||||
// For example, some IT depts have IFRAMED Snipe-IT into their IT portal
|
||||
// for convenience so while it is normally disallowed, there is
|
||||
// an override that exists.
|
||||
|
||||
if (config('app.allow_iframing') == false) {
|
||||
$response->headers->set('X-Frame-Options', 'DENY');
|
||||
}
|
||||
|
||||
|
||||
// This defaults to false to maintain backwards compatibility for
|
||||
// people who are not running Snipe-IT over TLS (shame, shame, shame!)
|
||||
// Seriously though, please run Snipe-IT over TLS. Let's Encrypt is free.
|
||||
// https://letsencrypt.org
|
||||
|
||||
if (config('app.enable_hsts') === true) {
|
||||
$response->headers->set('Strict-Transport-Security', 'max-age=31536000; includeSubDomains');
|
||||
}
|
||||
|
||||
// We have to exclude debug mode here because debugbar pulls from a CDN or two
|
||||
// and it will break things.
|
||||
|
||||
if ((config('app.debug')!='true') || (config('app.enable_csp')=='true')) {
|
||||
$csp_policy[] = "default-src 'self'";
|
||||
$csp_policy[] = "style-src 'self' 'unsafe-inline'";
|
||||
$csp_policy[] = "script-src 'self' 'unsafe-inline' 'unsafe-eval'";
|
||||
$csp_policy[] = "connect-src 'self'";
|
||||
$csp_policy[] = "object-src 'none'";
|
||||
$csp_policy[] = "font-src 'self' data:";
|
||||
$csp_policy[] = "img-src 'self' data: gravatar.com maps.google.com maps.gstatic.com *.googleapis.com";
|
||||
$csp_policy = join(';', $csp_policy);
|
||||
$response->headers->set('Content-Security-Policy', $csp_policy);
|
||||
}
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
private function removeUnwantedHeaders($headerList)
|
||||
{
|
||||
foreach ($headerList as $header)
|
||||
header_remove($header);
|
||||
}
|
||||
}
|
|
@ -1,22 +0,0 @@
|
|||
<?php
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Closure;
|
||||
|
||||
class XssProtectHeader
|
||||
{
|
||||
/**
|
||||
* Handle the given request and get the response.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Closure $next
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function handle($request, Closure $next)
|
||||
{
|
||||
$mode = '1;mode=block';
|
||||
$response = $next($request);
|
||||
$response->headers->set('X-XSS-Protection', $mode);
|
||||
return $response;
|
||||
}
|
||||
}
|
|
@ -63,6 +63,10 @@ abstract class Importer
|
|||
'full_name' => 'full name',
|
||||
'email' => 'email',
|
||||
'username' => 'username',
|
||||
'address' => 'address',
|
||||
'city' => 'city',
|
||||
'state' => 'state',
|
||||
'country' => 'country',
|
||||
'jobtitle' => 'job title',
|
||||
'employee_num' => 'employee number',
|
||||
'phone_number' => 'phone number',
|
||||
|
|
|
@ -48,6 +48,10 @@ class UserImporter extends ItemImporter
|
|||
$this->item['email'] = $this->findCsvMatch($row, 'email');
|
||||
$this->item['phone'] = $this->findCsvMatch($row, 'phone_number');
|
||||
$this->item['jobtitle'] = $this->findCsvMatch($row, 'jobtitle');
|
||||
$this->item['address'] = $this->findCsvMatch($row, 'address');
|
||||
$this->item['city'] = $this->findCsvMatch($row, 'city');
|
||||
$this->item['state'] = $this->findCsvMatch($row, 'state');
|
||||
$this->item['country'] = $this->findCsvMatch($row, 'country');
|
||||
$this->item['activated'] = ($this->fetchHumanBoolean($this->findCsvMatch($row, 'activated')) == 1) ? '1' : 0;
|
||||
$this->item['employee_num'] = $this->findCsvMatch($row, 'employee_num');
|
||||
$this->item['department_id'] = $this->createOrFetchDepartment($this->findCsvMatch($row, 'department'));
|
||||
|
|
|
@ -7,13 +7,14 @@
|
|||
| department_id | | User ? All |
|
||||
| item name | item_name | All |
|
||||
| image | image | Asset |
|
||||
| department_id | | User ? All |
|
||||
| email | | |
|
||||
| expiration date | expiration_date | License |
|
||||
| location | location | All |
|
||||
| notes | notes | All |
|
||||
| licensed to email | license_email | License |
|
||||
| licensed to name | license_name | License |
|
||||
| maintained | maintained | License |
|
||||
| manager_id | | User |
|
||||
| manufacturer | manufacturer | All |
|
||||
| model name | asset_model | Asset |
|
||||
| model number | model_number | Asset |
|
||||
|
@ -34,4 +35,8 @@
|
|||
| name | | |
|
||||
| email | | |
|
||||
| username | | |
|
||||
| address | address | User |
|
||||
| city | city | User |
|
||||
| state | state | User |
|
||||
| country | country | User |
|
||||
|
||||
|
|
|
@ -1094,7 +1094,7 @@ class Asset extends Depreciable
|
|||
$interval = $settings->audit_warning_days ?? 0;
|
||||
|
||||
return $query->whereNotNull('assets.next_audit_date')
|
||||
->whereRaw("DATE_SUB(assets.next_audit_date, INTERVAL $interval DAY) <= '".Carbon::now()."'")
|
||||
->whereRaw("DATE_SUB(".DB::getTablePrefix()."assets.next_audit_date, INTERVAL $interval DAY) <= '".Carbon::now()."'")
|
||||
->where('assets.archived', '=', 0)
|
||||
->NotArchived();
|
||||
}
|
||||
|
|
|
@ -126,10 +126,13 @@ final class Company extends SnipeModel
|
|||
} elseif (!static::isFullMultipleCompanySupportEnabled()) {
|
||||
return true;
|
||||
} else {
|
||||
if (Auth::user()) {
|
||||
$current_user_company_id = Auth::user()->company_id;
|
||||
$companyable_company_id = $companyable->company_id;
|
||||
return ($current_user_company_id == null || $current_user_company_id == $companyable_company_id || Auth::user()->isSuperUser());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public static function isCurrentUserAuthorized()
|
||||
|
|
|
@ -28,8 +28,9 @@ trait Loggable
|
|||
{
|
||||
$log = new Actionlog;
|
||||
$log = $this->determineLogItemType($log);
|
||||
if(Auth::user())
|
||||
if (Auth::user()) {
|
||||
$log->user_id = Auth::user()->id;
|
||||
}
|
||||
|
||||
if (!isset($target)) {
|
||||
throw new \Exception('All checkout logs require a target.');
|
||||
|
@ -113,14 +114,45 @@ trait Loggable
|
|||
$log->location_id = null;
|
||||
$log->note = $note;
|
||||
|
||||
$log->action_date = $action_date;
|
||||
|
||||
if (!$log->action_date) {
|
||||
$log->action_date = date('Y-m-d H:i:s');
|
||||
}
|
||||
if (Auth::user()) {
|
||||
$log->user_id = Auth::user()->id;
|
||||
}
|
||||
|
||||
$log->logaction('checkin from');
|
||||
|
||||
$params = [
|
||||
'target' => $target,
|
||||
'item' => $log->item,
|
||||
'admin' => $log->user,
|
||||
'note' => $note,
|
||||
'target_type' => $log->target_type,
|
||||
'settings' => $settings,
|
||||
];
|
||||
|
||||
|
||||
$checkinClass = null;
|
||||
|
||||
if (method_exists($target, 'notify')) {
|
||||
try {
|
||||
$target->notify(new static::$checkinClass($params));
|
||||
} catch (\Exception $e) {
|
||||
\Log::debug($e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Send to the admin, if settings dictate
|
||||
$recipient = new \App\Models\Recipients\AdminRecipient();
|
||||
|
||||
if (($settings->admin_cc_email!='') && (static::$checkinClass!='')) {
|
||||
try {
|
||||
$recipient->notify(new static::$checkinClass($params));
|
||||
} catch (\Exception $e) {
|
||||
\Log::debug($e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return $log;
|
||||
}
|
||||
|
||||
|
|
|
@ -331,7 +331,7 @@ class User extends SnipeModel implements AuthenticatableContract, AuthorizableCo
|
|||
*/
|
||||
public function userlog()
|
||||
{
|
||||
return $this->hasMany('\App\Models\Actionlog', 'target_id')->orderBy('created_at', 'DESC')->withTrashed();
|
||||
return $this->hasMany('\App\Models\Actionlog', 'target_id')->where('target_type', '=', 'App\Models\User')->orderBy('created_at', 'DESC')->withTrashed();
|
||||
}
|
||||
|
||||
|
||||
|
@ -521,6 +521,18 @@ class User extends SnipeModel implements AuthenticatableContract, AuthorizableCo
|
|||
} elseif ($format=='firstname') {
|
||||
$username = str_slug($first_name);
|
||||
}
|
||||
elseif ($format=='firstinitial.lastname') {
|
||||
$username = str_slug(substr($first_name, 0, 1). '.' . str_slug($last_name));
|
||||
}
|
||||
elseif ($format=='lastname_firstinitial') {
|
||||
$username = str_slug($last_name).'_'.str_slug(substr($first_name, 0, 1));
|
||||
}
|
||||
elseif ($format=='firstnamelastname') {
|
||||
$username = str_slug($first_name) . str_slug($last_name);
|
||||
}
|
||||
elseif ($format=='firstnamelastinitial') {
|
||||
$username = str_slug(($first_name.substr($last_name, 0, 1)));
|
||||
}
|
||||
}
|
||||
|
||||
$user['first_name'] = $first_name;
|
||||
|
|
|
@ -67,10 +67,18 @@ class CheckinLicenseSeatNotification extends Notification
|
|||
$botname = ($this->settings->slack_botname) ? $this->settings->slack_botname : 'Snipe-Bot' ;
|
||||
|
||||
|
||||
if ($admin) {
|
||||
$fields = [
|
||||
'To' => '<'.$target->present()->viewUrl().'|'.$target->present()->fullName().'>',
|
||||
'By' => '<'.$admin->present()->viewUrl().'|'.$admin->present()->fullName().'>',
|
||||
];
|
||||
} else {
|
||||
$fields = [
|
||||
'To' => '<'.$target->present()->viewUrl().'|'.$target->present()->fullName().'>',
|
||||
'By' => 'CLI tool',
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -268,8 +268,11 @@ class AssetPresenter extends Presenter
|
|||
"searchable" => true,
|
||||
"sortable" => true,
|
||||
"switchable" => true,
|
||||
"title" => ($field->field_encrypted=='1') ?'<i class="fa fa-lock"></i> '.$field->name : $field->name,
|
||||
"formatter" => "customFieldsFormatter"
|
||||
"title" => $field->name,
|
||||
"formatter"=> 'customFieldsFormatter',
|
||||
"escape" => true,
|
||||
"class" => ($field->field_encrypted=='1') ? 'css-padlock' : '',
|
||||
"visible" => true,
|
||||
];
|
||||
|
||||
}
|
||||
|
|
|
@ -210,6 +210,20 @@ return [
|
|||
'allow_iframing' => env('ALLOW_IFRAMING', false),
|
||||
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| ENABLE HTTP Strict Transport Security (HSTS)
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| This is set to default false for backwards compatibilty but should be
|
||||
| set to true if the hosting environment allows it.
|
||||
|
|
||||
| See https://scotthelme.co.uk/hsts-the-missing-link-in-tls/
|
||||
|
|
||||
*/
|
||||
|
||||
'enable_hsts' => env('ENABLE_HSTS', false),
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| REFERRER-POLICY
|
||||
|
|
Binary file not shown.
Binary file not shown.
|
@ -1,9 +1,3 @@
|
|||
<style>
|
||||
tr {
|
||||
padding-left:30px;
|
||||
}
|
||||
</style>
|
||||
|
||||
<template>
|
||||
<div v-show="processDetail" class="col-md-6 col-md-offset-3">
|
||||
|
||||
|
@ -18,18 +12,14 @@ tr {
|
|||
</select2>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="dynamic-form-row">
|
||||
<div class="col-md-5 col-xs-12">
|
||||
<label for="import-update">Update Existing Values?</label>
|
||||
<label for="import-update">Update Existing Values?:</label>
|
||||
</div>
|
||||
<div class="col-md-7 col-xs-12">
|
||||
<input type="checkbox" class="minimal" name="import-update" v-model="options.update">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="dynamic-form-row">
|
||||
<div class="col-md-5 col-xs-12">
|
||||
<label for="send-welcome">Send Welcome Email for new Users?</label>
|
||||
|
@ -38,9 +28,6 @@ tr {
|
|||
<input type="checkbox" class="minimal" name="send-welcome" v-model="options.send_welcome">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
|
||||
<div class="dynamic-form-row">
|
||||
<div class="col-md-5 col-xs-12">
|
||||
<label for="run-backup">Backup before importing?</label>
|
||||
|
@ -50,7 +37,6 @@ tr {
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="alert col-md-8 col-md-offset-2" style="text-align:left"
|
||||
:class="alertClass"
|
||||
v-if="statusText">
|
||||
|
@ -58,16 +44,18 @@ tr {
|
|||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-12" style="padding-top: 30px;">
|
||||
<div class="col-md-2"></div>
|
||||
<div class="col-md-8" style="padding-top: 30px;">
|
||||
<div class="col-md-4 text-right"><h4>Header Field</h4></div>
|
||||
<div class="col-md-4 text-left"><h4>Import Field</h4></div>
|
||||
<div class="col-md-4 text-left"><h4>Sample Value</h4></div>
|
||||
<div class="col-md-4"><h4>Import Field</h4></div>
|
||||
<div class="col-md-4"><h4>Sample Value</h4></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<template v-for="(header, index) in file.header_row">
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<div class="col-md-2"></div>
|
||||
<div class="col-md-8">
|
||||
<div class="col-md-4 text-right">
|
||||
<label :for="header" class="control-label">{{ header }}</label>
|
||||
</div>
|
||||
|
@ -78,7 +66,7 @@ tr {
|
|||
</select2>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-4 text-left">
|
||||
<div class="col-md-4">
|
||||
<p class="form-control-static">{{ activeFile.first_row[index] }}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -93,7 +81,7 @@ tr {
|
|||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="alert col-md-12" style="padding-top: 20px;"
|
||||
<div class="alert col-md-8 col-md-offset-2" style="padding-top: 20px;"
|
||||
:class="alertClass"
|
||||
v-if="statusText">
|
||||
{{ this.statusText }}
|
||||
|
@ -181,6 +169,10 @@ tr {
|
|||
{id: 'manager_last_name', text: 'Manager Last Name' },
|
||||
{id: 'department', text: 'Department' },
|
||||
{id: 'activated', text: 'Activated' },
|
||||
{id: 'address', text: 'Address' },
|
||||
{id: 'city', text: 'City' },
|
||||
{id: 'state', text: 'State' },
|
||||
{id: 'country', text: 'Country' },
|
||||
|
||||
],
|
||||
customFields: this.customFields,
|
||||
|
|
|
@ -83,7 +83,7 @@
|
|||
<div class="modal-header">
|
||||
<button type="button " class="close" data-dismiss="modal" aria-hidden="true">×</button>
|
||||
|
||||
<h2 class="modal-title">
|
||||
<h4 class="modal-title">
|
||||
Create Client
|
||||
</h2>
|
||||
</div>
|
||||
|
@ -151,7 +151,7 @@
|
|||
<div class="modal-header">
|
||||
<button type="button " class="close" data-dismiss="modal" aria-hidden="true">×</button>
|
||||
|
||||
<h2 class="modal-title">
|
||||
<h4 class="modal-title">
|
||||
Edit Client
|
||||
</h2>
|
||||
</div>
|
||||
|
|
|
@ -466,6 +466,74 @@ h4 {
|
|||
display: table-cell;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
|
||||
COLUMN SELECTOR ICONS
|
||||
-----------------------------
|
||||
This is kind of weird, but it is necessary to prevent the column-selector code from barfing, since
|
||||
any HTML used in the UserPresenter "title" attribute breaks the column selector HTML.
|
||||
|
||||
Instead, we use CSS to add the icon into the table header, which leaves the column selector
|
||||
"title" text as-is.
|
||||
|
||||
See https://github.com/snipe/snipe-it/issues/7989
|
||||
|
||||
*/
|
||||
|
||||
th.css-barcode > .th-inner,
|
||||
th.css-license > .th-inner,
|
||||
th.css-consumable > .th-inner,
|
||||
th.css-accessory > .th-inner
|
||||
{
|
||||
font-size: 0px;
|
||||
line-height: 4!important;
|
||||
text-align: left;
|
||||
text-rendering: auto;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
|
||||
th.css-padlock > .th-inner::before,
|
||||
th.css-barcode > .th-inner::before,
|
||||
th.css-license > .th-inner::before,
|
||||
th.css-consumable > .th-inner::before,
|
||||
th.css-accessory > .th-inner::before
|
||||
|
||||
{
|
||||
display: inline-block;
|
||||
font: normal normal normal 14px/1 FontAwesome;
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
th.css-padlock > .th-inner::before
|
||||
{
|
||||
content: "\f023";
|
||||
padding-right: 2px;
|
||||
}
|
||||
|
||||
th.css-barcode > .th-inner::before
|
||||
{
|
||||
content: "\f02a";
|
||||
}
|
||||
|
||||
th.css-license > .th-inner::before
|
||||
{
|
||||
content: "\f0c7";
|
||||
}
|
||||
|
||||
th.css-consumable > .th-inner::before
|
||||
{
|
||||
content: "\f043";
|
||||
}
|
||||
|
||||
th.css-accessory > .th-inner::before
|
||||
{
|
||||
content: "\f11c";
|
||||
}
|
||||
.small-box .inner {
|
||||
padding-left: 15px;
|
||||
padding-right: 15px;
|
||||
|
|
|
@ -88,6 +88,9 @@
|
|||
'firstname_lastname_underscore_format' => 'First Name Last Name (jane_smith@example.com)',
|
||||
'lastnamefirstinitial_format' => 'Last Name First Initial (smithj@example.com)',
|
||||
'first' => 'First',
|
||||
'firstnamelastname' => 'First Name Last Name (janesmith@example.com)',
|
||||
'lastname_firstinitial' => 'Last Name First Initial (smith_j@example.com)',
|
||||
'firstinitial.lastname' => 'First Initial Last Name (j.smith@example.com)', 'first' => 'First',
|
||||
'first_name' => 'First Name',
|
||||
'first_name_format' => 'First Name (jane@example.com)',
|
||||
'files' => 'Files',
|
||||
|
|
|
@ -8,6 +8,7 @@ return array(
|
|||
'owner_doesnt_match_asset' => 'The asset you are trying to associate with this license is owned by somene other than the person selected in the assigned to dropdown.',
|
||||
'assoc_users' => 'This license is currently checked out to a user and cannot be deleted. Please check the license in first, and then try deleting again. ',
|
||||
'select_asset_or_person' => 'You must select an asset or a user, but not both.',
|
||||
'not_found' => 'License not found',
|
||||
|
||||
|
||||
'create' => array(
|
||||
|
|
|
@ -91,6 +91,11 @@
|
|||
'lastnamefirstinitial_format' => 'Last Name First Initial (smithj@example.com)',
|
||||
'firstintial_dot_lastname_format' => 'First Initial Last Name (j.smith@example.com)',
|
||||
'first' => 'First',
|
||||
'firstnamelastname' => 'First Name Last Name (janesmith@example.com)',
|
||||
'lastname_firstinitial' => 'Last Name First Initial (smith_j@example.com)',
|
||||
'firstinitial.lastname' => 'First Initial Last Name (j.smith@example.com)',
|
||||
'firstnamelastinitial' => 'First Name Last Initial (janes@example.com)',
|
||||
'first' => 'First',
|
||||
'first_name' => 'First Name',
|
||||
'first_name_format' => 'First Name (jane@example.com)',
|
||||
'files' => 'Files',
|
||||
|
|
|
@ -464,11 +464,14 @@ Form::macro('username_format', function ($name = "username_format", $selected =
|
|||
|
||||
$formats = array(
|
||||
'firstname.lastname' => trans('general.firstname_lastname_format'),
|
||||
'firstname_lastname' => trans('general.firstname_lastname_underscore_format'),
|
||||
'filastname' => trans('general.filastname_format'),
|
||||
'firstintial.lastname' => trans('general.firstintial_dot_lastname_format'),
|
||||
'firstname' => trans('general.first_name_format'),
|
||||
'filastname' => trans('general.filastname_format'),
|
||||
'lastnamefirstinitial' => trans('general.lastnamefirstinitial_format'),
|
||||
'firstname_lastname' => trans('general.firstname_lastname_underscore_format'),
|
||||
'firstinitial.lastname' => trans('general.firstinitial.lastname'),
|
||||
'lastname_firstinitial' => trans('general.lastname_firstinitial'),
|
||||
'firstnamelastname' => trans('general.firstnamelastname'),
|
||||
'firstnamelastinitial' => trans('general.firstnamelastinitial')
|
||||
);
|
||||
|
||||
$select = '<select name="'.$name.'" class="'.$class.'" style="width: 100%" aria-label="'.$name.'">';
|
||||
|
|
|
@ -314,7 +314,7 @@ View Assets for {{ $user->present()->fullName() }}
|
|||
}'>
|
||||
<thead>
|
||||
<tr>
|
||||
<th data-switchable="true" data-visible="true" data-field="icon" style="width: 40px;" class="hidden-xs" data-formatter="iconFormatter"><span class="sr-only">Icon</span></th>
|
||||
<th data-switchable="true" data-visible="true" data-field="icon" style="width: 40px;" class="hidden-xs" data-formatter="iconFormatter">Icon</th>
|
||||
<th data-switchable="true" data-visible="true" class="col-sm-3" data-field="created_at" data-formatter="dateDisplayFormatter">{{ trans('general.date') }}</th>
|
||||
<th data-switchable="true" data-visible="true" class="col-sm-3" data-field="admin" data-formatter="usersLinkObjFormatter">{{ trans('general.admin') }}</th>
|
||||
<th data-switchable="true" data-visible="true" class="col-sm-3" data-field="action_type">{{ trans('general.action') }}</th>
|
||||
|
|
|
@ -179,16 +179,18 @@
|
|||
$("#assignto_selector").show();
|
||||
$("#assigned_user").show();
|
||||
|
||||
$("#selected_status_status").removeClass('alert-msg');
|
||||
$("#selected_status_status").removeClass('text-danger');
|
||||
$("#selected_status_status").removeClass('text-warning');
|
||||
$("#selected_status_status").addClass('text-success');
|
||||
$("#selected_status_status").html('<i class="fa fa-check"></i> That status is deployable. This asset can be checked out.');
|
||||
|
||||
|
||||
} else {
|
||||
$("#assignto_selector").hide();
|
||||
$("#selected_status_status").removeClass('text-danger');
|
||||
$("#selected_status_status").removeClass('text-success');
|
||||
$("#selected_status_status").addClass('alert-msg');
|
||||
$("#selected_status_status").html('<i class="fa fa-times"></i> That asset status is not deployable. This asset cannot be checked out. ');
|
||||
$("#selected_status_status").addClass('text-warning');
|
||||
$("#selected_status_status").html('<i class="fa fa-warning"></i> That asset status is not deployable. This asset cannot be checked out. ');
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
@ -11,13 +11,10 @@
|
|||
$settings->labels_width = $settings->labels_width - $settings->labels_display_sgutter;
|
||||
$settings->labels_height = $settings->labels_height - $settings->labels_display_bgutter;
|
||||
// Leave space on bottom for 1D barcode if necessary
|
||||
$qr_size = ($settings->alt_barcode_enabled=='1') && ($settings->alt_barcode!='') ? $settings->labels_height - .3 : $settings->labels_height;
|
||||
// Leave space on left for QR code if necessary
|
||||
$qr_txt_size = ($settings->qr_code=='1' ? $settings->labels_width - $qr_size - .1 : $settings->labels_width);
|
||||
$qr_size = ($settings->alt_barcode_enabled=='1') && ($settings->alt_barcode!='') ? $settings->labels_height - .3 : $settings->labels_height - .3;
|
||||
?>
|
||||
|
||||
<style>
|
||||
|
||||
body {
|
||||
font-family: arial, helvetica, sans-serif;
|
||||
width: {{ $settings->labels_pagewidth }}in;
|
||||
|
@ -25,7 +22,6 @@
|
|||
margin: {{ $settings->labels_pmargin_top }}in {{ $settings->labels_pmargin_right }}in {{ $settings->labels_pmargin_bottom }}in {{ $settings->labels_pmargin_left }}in;
|
||||
font-size: {{ $settings->labels_fontsize }}pt;
|
||||
}
|
||||
|
||||
.label {
|
||||
width: {{ $settings->labels_width }}in;
|
||||
height: {{ $settings->labels_height }}in;
|
||||
|
@ -35,74 +31,52 @@
|
|||
display: inline-block;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.page-break {
|
||||
page-break-after:always;
|
||||
}
|
||||
|
||||
div.qr_img {
|
||||
width: {{ $qr_size }}in;
|
||||
height: {{ $qr_size }}in;
|
||||
|
||||
float: left;
|
||||
display: inline-block;
|
||||
padding-right: .04in;
|
||||
display: inline-flex;
|
||||
padding-right: .15in;
|
||||
}
|
||||
img.qr_img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
width: 120.79%;
|
||||
height: 120.79%;
|
||||
margin-top: -6.9%;
|
||||
margin-left: -6.9%;
|
||||
padding-bottom: .04in;
|
||||
}
|
||||
img.barcode {
|
||||
display:block;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
div.label-logo {
|
||||
float: right;
|
||||
display: inline-block;
|
||||
}
|
||||
img.label-logo {
|
||||
height: 0.5in;
|
||||
}
|
||||
|
||||
padding-top: .11in;
|
||||
width: 100%;
|
||||
}
|
||||
.qr_text {
|
||||
width: {{ $qr_txt_size }}in;
|
||||
height: {{ $qr_size }}in;
|
||||
padding-top: .10in;
|
||||
width: {{ $settings->labels_width }}in;
|
||||
height: {{ $settings->labels_height }}in;
|
||||
padding-top: {{$settings->labels_display_bgutter}}in;
|
||||
font-family: arial, helvetica, sans-serif;
|
||||
font-size: {{$settings->labels_fontsize}};
|
||||
padding-right: .01in;
|
||||
overflow: hidden !important;
|
||||
display: inline-block;
|
||||
display: inline;
|
||||
word-wrap: break-word;
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
div.barcode_container {
|
||||
float: left;
|
||||
|
||||
width: 100%;
|
||||
display: inline;
|
||||
height: 50px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.next-padding {
|
||||
margin: {{ $settings->labels_pmargin_top }}in {{ $settings->labels_pmargin_right }}in {{ $settings->labels_pmargin_bottom }}in {{ $settings->labels_pmargin_left }}in;
|
||||
}
|
||||
|
||||
.label-model::before {
|
||||
content: "M: "
|
||||
}
|
||||
.label-company::before {
|
||||
content: "C: "
|
||||
}
|
||||
.label-asset_tag::before {
|
||||
content: "T: "
|
||||
}
|
||||
.label-serial::before {
|
||||
content: "S: "
|
||||
}
|
||||
.label-name::before {
|
||||
content: "N: "
|
||||
}
|
||||
|
||||
@media print {
|
||||
.noprint {
|
||||
display: none !important;
|
||||
|
@ -112,7 +86,6 @@
|
|||
font-size: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen {
|
||||
.label {
|
||||
outline: .02in black solid; /* outline doesn't occupy space like border does */
|
||||
|
@ -122,11 +95,9 @@
|
|||
padding-bottom: 15px;
|
||||
}
|
||||
}
|
||||
|
||||
@if ($snipeSettings->custom_css)
|
||||
{!! $snipeSettings->show_custom_css() !!}
|
||||
{{ $snipeSettings->show_custom_css() }}
|
||||
@endif
|
||||
|
||||
</style>
|
||||
|
||||
@foreach ($assets as $asset)
|
||||
|
@ -134,63 +105,49 @@
|
|||
<div class="label">
|
||||
|
||||
@if ($settings->qr_code=='1')
|
||||
<div class="label-qr_img qr_img">
|
||||
@if ($bulkedit==False)
|
||||
<img src="./qr_code" class="qr_img">
|
||||
@else
|
||||
<div class="qr_img">
|
||||
<img src="./{{ $asset->id }}/qr_code" class="qr_img">
|
||||
@endif
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<div class="qr_text">
|
||||
@if ($settings->label_logo)
|
||||
<div class="label-logo">
|
||||
<img class="label-logo" src="{{ Storage::disk('public')->url('').e($snipeSettings->label_logo) }}">
|
||||
</div>
|
||||
@endif
|
||||
|
||||
@if ($settings->qr_text!='')
|
||||
<div class="label-qr_text pull-left">
|
||||
<div class="pull-left">
|
||||
<strong>{{ $settings->qr_text }}</strong>
|
||||
<br>
|
||||
</div>
|
||||
@endif
|
||||
@if (($settings->labels_display_company_name=='1') && ($asset->company))
|
||||
<div class="label-company pull-left">
|
||||
{{ $asset->company->name }}
|
||||
<div class="pull-left">
|
||||
C: {{ $asset->company->name }}
|
||||
</div>
|
||||
@endif
|
||||
@if (($settings->labels_display_name=='1') && ($asset->name!=''))
|
||||
<div class="label-name pull-left">
|
||||
{{ $asset->name }}
|
||||
<div class="pull-left">
|
||||
N: {{ $asset->name }}
|
||||
</div>
|
||||
@endif
|
||||
@if (($settings->labels_display_tag=='1') && ($asset->asset_tag!=''))
|
||||
<div class="label-asset_tag pull-left">
|
||||
{{ $asset->asset_tag }}
|
||||
<div class="pull-left">
|
||||
T: {{ $asset->asset_tag }}
|
||||
</div>
|
||||
@endif
|
||||
@if (($settings->labels_display_serial=='1') && ($asset->serial!=''))
|
||||
<div class="label-serial pull-left">
|
||||
{{ $asset->serial }}
|
||||
<div class="pull-left">
|
||||
S: {{ $asset->serial }}
|
||||
</div>
|
||||
@endif
|
||||
@if (($settings->labels_display_model=='1') && ($asset->model->name!=''))
|
||||
<div class="label-model pull-left">
|
||||
{{ $asset->model->name }} {{ $asset->model->model_number }}
|
||||
<div class="pull-left">
|
||||
M: {{ $asset->model->name }} {{ $asset->model->model_number }}
|
||||
</div>
|
||||
@endif
|
||||
|
||||
</div>
|
||||
|
||||
@if ((($settings->alt_barcode_enabled=='1') && $settings->alt_barcode!=''))
|
||||
<div class="label-alt_barcode barcode_container">
|
||||
@if ($bulkedit==False)
|
||||
<img src="./barcode" class="barcode">
|
||||
@else
|
||||
<div class="barcode_container">
|
||||
<img src="./{{ $asset->id }}/barcode" class="barcode">
|
||||
@endif
|
||||
</div>
|
||||
@endif
|
||||
|
||||
|
|
|
@ -995,7 +995,7 @@
|
|||
data-cookie-id-table="assetHistory">
|
||||
<thead>
|
||||
<tr>
|
||||
<th data-field="icon" data-visible="true" style="width: 40px;" class="hidden-xs" data-formatter="iconFormatter"><span class="sr-only">Icon</span></th>
|
||||
<th data-visible="true" style="width: 40px;" class="hidden-xs">Icon</th>
|
||||
<th class="col-sm-2" data-visible="true" data-field="created_at" data-formatter="dateDisplayFormatter">{{ trans('general.date') }}</th>
|
||||
<th class="col-sm-1" data-visible="true" data-field="admin" data-formatter="usersLinkObjFormatter">{{ trans('general.admin') }}</th>
|
||||
<th class="col-sm-1" data-visible="true" data-field="action_type">{{ trans('general.action') }}</th>
|
||||
|
|
|
@ -821,7 +821,7 @@
|
|||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
|
||||
<h2 class="modal-title" id="myModalLabel"> </h4>
|
||||
<h4 class="modal-title" id="myModalLabel"> </h4>
|
||||
</div>
|
||||
<div class="modal-body"></div>
|
||||
<div class="modal-footer">
|
||||
|
|
|
@ -326,9 +326,9 @@
|
|||
|
||||
<table
|
||||
data-columns="{{ \App\Presenters\LicensePresenter::dataTableLayoutSeats() }}"
|
||||
data-cookie-id-table="seatsTable-{{ $license->id }}"
|
||||
data-id-table="seatsTable-{{ $license->id }}"
|
||||
id="seatsTable-{{$license->id}}"
|
||||
data-cookie-id-table="seatsTable"
|
||||
data-id-table="seatsTable"
|
||||
id="seatsTable"
|
||||
data-pagination="true"
|
||||
data-search="false"
|
||||
data-side-pagination="server"
|
||||
|
@ -375,7 +375,7 @@
|
|||
}'>
|
||||
<thead>
|
||||
<tr>
|
||||
<th data-visible="true" aria-hidden="true"><span class="sr-only">Icon</span></th>
|
||||
<th data-visible="true" aria-hidden="true">Icon</th>
|
||||
<th class="col-md-4" data-field="file_name" data-visible="true" data-sortable="true" data-switchable="true">{{ trans('general.file_name') }}</th>
|
||||
<th class="col-md-4" data-field="notes" data-visible="true" data-sortable="true" data-switchable="true">{{ trans('general.notes') }}</th>
|
||||
<th class="col-md-2" data-field="created_at" data-visible="true" data-sortable="true" data-switchable="true">{{ trans('general.created_at') }}</th>
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
{{-- See snipeit_modals.js for what powers this --}}
|
||||
|
||||
<script nonce="{{ csrf_token() }}">
|
||||
$(document).ready(function () {
|
||||
|
||||
$('#genPassword').pGenerator({
|
||||
window.setTimeout(function () {
|
||||
$('#modal-genPassword').pGenerator({
|
||||
'bind': 'click',
|
||||
'passwordElement': '#modal-password',
|
||||
'displayElement': '#generated-password',
|
||||
'displayElement': '#modal-generated-password',
|
||||
'passwordLength': 16,
|
||||
'uppercase': true,
|
||||
'lowercase': true,
|
||||
|
@ -16,13 +16,14 @@
|
|||
$('#modal-password_confirmation').val($('#modal-password').val());
|
||||
}
|
||||
});
|
||||
});
|
||||
}, 1000);
|
||||
</script>
|
||||
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
|
||||
<h2 class="modal-title">{{ trans('admin/users/table.createuser') }}</h4>
|
||||
<h2 class="modal-title">{{ trans('admin/users/table.createuser') }}</h2>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<form action="{{ route('api.users.store') }}" onsubmit="return false">
|
||||
|
@ -46,14 +47,14 @@
|
|||
<div class="dynamic-form-row">
|
||||
<div class="col-md-4 col-xs-12"><label for="modal-password">{{ trans('admin/users/table.password') }}:</label></div>
|
||||
<div class="col-md-8 col-xs-12 required"><input type='password' name="password" id='modal-password' class="form-control">
|
||||
<a href="#" class="left" id="genPassword">Generate</a>
|
||||
<a href="#" class="left" id="modal-genPassword">Generate</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="dynamic-form-row">
|
||||
<div class="col-md-4 col-xs-12"><label for="modal-password_confirmation">{{ trans('admin/users/table.password_confirm') }}:</label></div>
|
||||
<div class="col-md-8 col-xs-12 required"><input type='password' name="password_confirmation" id='modal-password_confirmation' class="form-control">
|
||||
<div id="generated-password"></div>
|
||||
<div id="modal-generated-password"></div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
|
|
@ -37,7 +37,7 @@
|
|||
|
||||
<thead>
|
||||
<tr>
|
||||
<th data-field="icon" style="width: 40px;" class="hidden-xs" data-formatter="iconFormatter"><span class="sr-only">Icon</span></th>
|
||||
<th data-field="icon" style="width: 40px;" class="hidden-xs" data-formatter="iconFormatter">Icon</th>
|
||||
<th class="col-sm-3" data-searchable="false" data-sortable="true" data-field="created_at" data-formatter="dateDisplayFormatter">{{ trans('general.date') }}</th>
|
||||
<th class="col-sm-2" data-field="admin" data-formatter="usersLinkObjFormatter">{{ trans('general.admin') }}</th>
|
||||
<th class="col-sm-2" data-field="action_type">{{ trans('general.action') }}</th>
|
||||
|
|
|
@ -55,6 +55,15 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<!-- City -->
|
||||
<div class="form-group{{ $errors->has('city') ? ' has-error' : '' }}">
|
||||
<label class="col-md-3 control-label" for="city">{{ trans('general.city') }}</label>
|
||||
<div class="col-md-4">
|
||||
<input class="form-control" type="text" name="city" id="city" aria-label="city" />
|
||||
{!! $errors->first('city', '<span class="alert-msg" aria-hidden="true">:message</span>') !!}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- activated -->
|
||||
<div class="form-group">
|
||||
<div class="col-sm-3 control-label">
|
||||
|
|
|
@ -15,66 +15,6 @@
|
|||
|
||||
@section('header_right')
|
||||
|
||||
<style>
|
||||
/**
|
||||
This is kind of weird, but it is necessary to prevent the column-selector code from barfing, since
|
||||
any HTML used in the UserPresenter "title" attribute breaks the column selector HTML.
|
||||
|
||||
Instead, we use CSS to add the icon into the table header, which leaves the column selector
|
||||
"title" text as-is.
|
||||
|
||||
See https://github.com/snipe/snipe-it/issues/7989
|
||||
|
||||
*/
|
||||
th.css-barcode > .th-inner,
|
||||
th.css-license > .th-inner,
|
||||
th.css-consumable > .th-inner,
|
||||
th.css-accessory > .th-inner
|
||||
{
|
||||
font-size: 0px;
|
||||
line-height: 4!important;
|
||||
text-align: left;
|
||||
text-rendering: auto;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
|
||||
th.css-barcode > .th-inner::before,
|
||||
th.css-license > .th-inner::before,
|
||||
th.css-consumable > .th-inner::before,
|
||||
th.css-accessory > .th-inner::before
|
||||
|
||||
{
|
||||
display: inline-block;
|
||||
font: normal normal normal 14px/1 FontAwesome;
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
|
||||
th.css-barcode > .th-inner::before
|
||||
{
|
||||
content: "\f02a";
|
||||
}
|
||||
|
||||
th.css-license > .th-inner::before
|
||||
{
|
||||
content: "\f0c7";
|
||||
}
|
||||
|
||||
th.css-consumable > .th-inner::before
|
||||
{
|
||||
content: "\f043";
|
||||
}
|
||||
|
||||
th.css-accessory > .th-inner::before
|
||||
{
|
||||
content: "\f11c";
|
||||
}
|
||||
|
||||
|
||||
</style>
|
||||
|
||||
@can('create', \App\Models\User::class)
|
||||
@if ($snipeSettings->ldap_enabled == 1)
|
||||
<a href="{{ route('ldap/user') }}" class="btn btn-default pull-right"><span class="fa fa-sitemap"></span> LDAP Sync</a>
|
||||
|
@ -153,6 +93,7 @@
|
|||
|
||||
@section('moar_scripts')
|
||||
|
||||
|
||||
@include ('partials.bootstrap-table')
|
||||
|
||||
|
||||
|
|
|
@ -142,11 +142,31 @@
|
|||
<td class="text-nowrap">{{ trans('admin/users/table.name') }}</td>
|
||||
<td>{{ $user->present()->fullName() }}</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td class="text-nowrap">{{ trans('admin/users/table.username') }}</td>
|
||||
<td>{{ $user->username }}</td>
|
||||
</tr>
|
||||
@if (($user->address) || ($user->city) || ($user->state) || ($user->country))
|
||||
<tr>
|
||||
<td class="text-nowrap">{{ trans('general.address') }}</td>
|
||||
<td>
|
||||
@if ($user->address)
|
||||
{{ $user->address }} <br>
|
||||
@endif
|
||||
@if ($user->city)
|
||||
{{ $user->city }}
|
||||
@endif
|
||||
@if ($user->state)
|
||||
{{ $user->state }}
|
||||
@endif
|
||||
@if ($user->country)
|
||||
{{ $user->country }}
|
||||
@endif
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
@endif
|
||||
<tr>
|
||||
<td class="text-nowrap">{{ trans('general.groups') }}</td>
|
||||
<td>
|
||||
|
@ -244,6 +264,13 @@
|
|||
<td class="text-nowrap">{{ trans('general.login_enabled') }}</td>
|
||||
<td>{{ ($user->activated=='1') ? trans('general.yes') : trans('general.no') }}</td>
|
||||
</tr>
|
||||
@if ($user->ldap_import!='1')
|
||||
<tr>
|
||||
<td class="text-nowrap">LDAP</td>
|
||||
<td>{{ trans('general.yes') }}</td>
|
||||
</tr>
|
||||
@endif
|
||||
|
||||
|
||||
@if ($user->activated=='1')
|
||||
<tr>
|
||||
|
@ -278,6 +305,13 @@
|
|||
|
||||
@endif
|
||||
|
||||
@if ($user->notes)
|
||||
<tr>
|
||||
<td class="text-nowrap">{{ trans('admin/users/table.notes') }}</td>
|
||||
<td>{{ $user->notes }}</td>
|
||||
</tr>
|
||||
@endif
|
||||
|
||||
|
||||
</table>
|
||||
</div>
|
||||
|
@ -541,7 +575,7 @@
|
|||
}'>
|
||||
<thead>
|
||||
<tr>
|
||||
<th data-field="icon" style="width: 40px;" class="hidden-xs" data-formatter="iconFormatter"><span class="sr-only">Icon</span></th>
|
||||
<th data-field="icon" style="width: 40px;" class="hidden-xs" data-formatter="iconFormatter">Icon</th>
|
||||
<th class="col-sm-3" data-field="created_at" data-formatter="dateDisplayFormatter" data-sortable="true">{{ trans('general.date') }}</th>
|
||||
<th class="col-sm-2" data-field="admin" data-formatter="usersLinkObjFormatter">{{ trans('general.admin') }}</th>
|
||||
<th class="col-sm-2" data-field="action_type">{{ trans('general.action') }}</th>
|
||||
|
|
|
@ -233,13 +233,22 @@ Route::group(['prefix' => 'v1','namespace' => 'Api', 'middleware' => 'auth:api']
|
|||
]
|
||||
); // Consumables resource
|
||||
|
||||
Route::get('consumables/view/{id}/users',
|
||||
Route::group(['prefix' => 'consumables'], function () {
|
||||
Route::get('view/{id}/users',
|
||||
[
|
||||
'as' => 'api.consumables.showUsers',
|
||||
'uses' => 'ConsumablesController@getDataView'
|
||||
]
|
||||
);
|
||||
|
||||
Route::post('{consumable}/checkout',
|
||||
[
|
||||
'as' => 'api.consumables.checkout',
|
||||
'uses' => 'ConsumablesController@checkout'
|
||||
]
|
||||
);
|
||||
});
|
||||
|
||||
/*--- Depreciations API ---*/
|
||||
|
||||
Route::resource('depreciations', 'DepreciationsController',
|
||||
|
|
|
@ -17,7 +17,6 @@ Route::group([ 'prefix' => 'fields','middleware' => ['auth'] ], function () {
|
|||
'as' => 'fields.optional']
|
||||
);
|
||||
|
||||
|
||||
Route::get('{field_id}/fieldset/{fieldset_id}/disassociate',
|
||||
['uses' => 'CustomFieldsController@deleteFieldFromFieldset',
|
||||
'as' => 'fields.disassociate']
|
||||
|
|
|
@ -438,7 +438,7 @@ case $distro in
|
|||
fi
|
||||
;;
|
||||
ubuntu)
|
||||
if [ "$version" == "18.04" ]; then
|
||||
if [ "$version" -ge "18.04" ]; then
|
||||
# Install for Ubuntu 18.04
|
||||
tzone=$(cat /etc/timezone)
|
||||
|
||||
|
|
|
@ -33,7 +33,7 @@ class UserTest extends BaseTest
|
|||
$fullname = "Natalia Allanovna Romanova-O'Shostakova";
|
||||
$expected_firstname = 'Natalia';
|
||||
$expected_lastname = "Allanovna Romanova-O'Shostakova";
|
||||
$user = User::generateFormattedNameFromFullName($fullname, 'firstname');
|
||||
$user = User::generateFormattedNameFromFullName('firstname', $fullname);
|
||||
$this->assertEquals($expected_firstname, $user['first_name']);
|
||||
$this->assertEquals($expected_lastname, $user['last_name']);
|
||||
}
|
||||
|
@ -74,7 +74,7 @@ class UserTest extends BaseTest
|
|||
public function testFirstInitialUnderscoreLastName()
|
||||
{
|
||||
$fullname = "Natalia Allanovna Romanova-O'Shostakova";
|
||||
$expected_username = 'natalia_allanovna-romanova-oshostakova';
|
||||
$expected_username = 'n_allanovna-romanova-oshostakova';
|
||||
$user = User::generateFormattedNameFromFullName($fullname, 'firstname_lastname');
|
||||
$this->assertEquals($expected_username, $user['username']);
|
||||
}
|
||||
|
@ -83,9 +83,36 @@ class UserTest extends BaseTest
|
|||
{
|
||||
$fullname = "Natalia";
|
||||
$expected_username = 'natalia';
|
||||
$user = User::generateFormattedNameFromFullName($fullname, 'firstname_lastname');
|
||||
$user = User::generateFormattedNameFromFullName('firstname_lastname', $fullname);
|
||||
$this->assertEquals($expected_username, $user['username']);
|
||||
}
|
||||
public function firstInitialDotLastname()
|
||||
{
|
||||
$fullname = "Natalia Allanovna Romanova-O'Shostakova";
|
||||
$expected_username = 'n.allanovnaromanovaoshostakova';
|
||||
$user = User::generateFormattedNameFromFullName($fullname, 'firstinitial.lastname');
|
||||
$this->assertEquals($expected_username, $user['username']);
|
||||
}
|
||||
public function lastNameUnderscoreFirstInitial()
|
||||
{
|
||||
$fullname = "Natalia Allanovna Romanova-O'Shostakova";
|
||||
$expected_username = 'allanovnaromanovaoshostakova_n';
|
||||
$user = User::generateFormattedNameFromFullName($fullname, 'lastname_firstinitial');
|
||||
$this->assertEquals($expected_username, $user['username']);
|
||||
}
|
||||
public function firstNameLastName()
|
||||
{
|
||||
$fullname = "Natalia Allanovna Romanova-O'Shostakova";
|
||||
$expected_username = 'nataliaallanovnaromanovaoshostakova';
|
||||
$user = User::generateFormattedNameFromFullName($fullname, 'firstnamelastname)';
|
||||
$this->assertEquals($expected_username, $user['username']);
|
||||
}
|
||||
public function firstNameLastInitial()
|
||||
{
|
||||
$fullname = "Natalia Allanovna Romanova-O'Shostakova";
|
||||
$expected_username = 'nataliaa';
|
||||
$user = User::generateFormattedNameFromFullName($fullname, 'firstnamelastinitial');
|
||||
$this->assertEquals($expected_username, $user['username']);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue