Compare commits

..

214 Commits

Author SHA1 Message Date
snipe
74b26a349c Merge remote-tracking branch 'origin/develop'
# Conflicts:
#	config/version.php
2020-11-24 13:54:02 -08:00
snipe
e9bfb157bb Bumped version. Again. 2020-11-24 13:53:28 -08:00
snipe
ef957399aa Merge remote-tracking branch 'origin/develop' 2020-11-24 13:51:19 -08:00
snipe
973eacf6c3 Small fixes for SAML
The SAML routes are in a service provide (sigh), so they did not have the `web` middleware group assigned to it.

I also added some additional checks so that the setup blade won’t fail (the migrations wouldn’t have been run yet, so outside of a try/catch, it would return an error since those tables don’t exist.)
2020-11-24 13:51:02 -08:00
snipe
02fef7049f Merge remote-tracking branch 'origin/develop'
# Conflicts:
#	config/version.php
2020-11-24 12:17:38 -08:00
snipe
b2660002b9 Fixed #8781 - added asset count by status type (#8806) 2020-11-24 12:15:07 -08:00
snipe
2c0b9f959b Comment with possible alternatve to the custom undeleted validator 2020-11-24 12:01:09 -08:00
snipe
51286d2244 Merge branch 'develop' of https://github.com/snipe/snipe-it into develop 2020-11-24 11:40:35 -08:00
snipe
712363f861 Bumped version 2020-11-23 12:33:07 -08:00
johnson-yi
0cdd83aabf Fixes #8584, #8654, #8727 - fixes and improvements for saml (#8795)
* Let onelogin/php-saml know to use 'X-Forwarded-*' headers if it is from a trusted proxy

* Gracefully handle the case where openssl_csr_new fails when openssl.cnf is invalid/missing

* Improve ui of saml sp metadata by displaying it's url and a download button
2020-11-20 18:54:25 -08:00
snipe
98dfb9d1b5 Merge remote-tracking branch 'origin/develop' 2020-11-20 14:35:12 -08:00
snipe
ae5635ff97 Merge remote-tracking branch 'origin/develop' 2020-11-20 14:34:43 -08:00
snipe
8a38b9d018 Merge branch 'develop' of https://github.com/snipe/snipe-it into develop 2020-11-20 14:34:35 -08:00
Brady Wetherington
734cb941dd Fix for #8772 - initial LDAP import of users are deactivated (#8776) 2020-11-20 11:11:14 -08:00
snipe
c66f8c04c8 For for deleted user API 2020-11-18 14:57:44 -08:00
Brady Wetherington
fa24799d2b Change license serial type to TEXT for longer license files (#8782) 2020-11-18 14:22:51 -08:00
snipe
57d6a7d35e Fixed #8753 - create-asset-from-model did not preselect the model 2020-11-18 13:59:02 -08:00
snipe
9e2d402c3a Merge remote-tracking branch 'origin/develop' 2020-11-18 07:06:33 -08:00
snipe
551e28eec9 Fixed #8749 - added more default colors to prevent missing index in pie chart math 2020-11-18 07:06:14 -08:00
snipe
9e30be8a04 Merge remote-tracking branch 'origin/develop' 2020-11-17 22:31:46 -08:00
Brady Wetherington
8457207c8f Fix for 500-page on deactivated LDAP user trying to log in (#8774) 2020-11-17 22:31:22 -08:00
snipe
cc4f1a1485 Merge remote-tracking branch 'origin/develop' 2020-11-17 22:20:38 -08:00
snipe
2ea805b7ed Added search/sort by Location OU, added to listing 2020-11-17 22:17:07 -08:00
snipe
20ef74db42 Merge remote-tracking branch 'origin/develop' 2020-11-17 19:26:15 -08:00
Brady Wetherington
3dda4c9116 Add a new UAC setting to valid User Accounts for Active Directory (#8775) 2020-11-17 19:25:49 -08:00
snipe
e805feff9e Merge remote-tracking branch 'origin/develop' 2020-11-17 19:22:56 -08:00
snipe
0286cf6d46 Prevent license categories from being deleted if there are licenses in that category 2020-11-17 19:22:10 -08:00
snipe
6ebdfdbabb Merge remote-tracking branch 'origin/develop' 2020-11-17 16:16:11 -08:00
snipe
68487e1200 Added img-responsive class to preview images 2020-11-17 16:15:25 -08:00
snipe
f19b9a44fc Fixed #8773 - wrong path for suppliers image on suppliers edit 2020-11-17 16:10:54 -08:00
snipe
124af6ac6b Merge remote-tracking branch 'origin/develop' 2020-11-17 14:33:35 -08:00
snipe
7f126969d0 Fixed #8601 - Switched to “attachment” from “base64” 2020-11-17 14:33:16 -08:00
snipe
e4b0e9673d Merge remote-tracking branch 'origin/develop' 2020-11-17 13:43:46 -08:00
snipe
7ab44ca963 Ignore php-lint cache 2020-11-17 13:43:24 -08:00
snipe
4898b58bdb Fixed #8765 - UI not indicating model is required 2020-11-17 13:40:15 -08:00
snipe
9b1e7ba8a6 Updated translations with new strings 2020-11-17 13:22:53 -08:00
snipe
e3d2369151 Fixed #8769 - incorrect translation for “DELETE” in purge 2020-11-17 12:01:02 -08:00
snipe
e5f0a12c25 Updated version.php to master 2020-11-17 00:14:28 -08:00
Brady Wetherington
de6f3f866f Attempt to solve LDAP sync overriding administrator choices (#8742) 2020-11-17 00:11:00 -08:00
snipe
8444a60bc9 Merge branch 'develop' of https://github.com/snipe/snipe-it into develop 2020-11-16 23:57:23 -08:00
snipe
3237411b5d Bumped version 2020-11-16 23:57:17 -08:00
snipe
5ba1659563 Removed dupe date 2020-11-16 23:56:48 -08:00
snipe
6e068ec339 Add @chamilton-ccn as a contributor 2020-11-16 22:15:59 -08:00
Charles Hamilton
4fd666716f Fixed #8482 - Ubuntu version (#8598)
* Bash cannot compare floating point numbers natively. This modification addresses issue #8482 and retains the intended function of the previous code.

* Bash cannot compare floating point numbers natively. This modification addresses issue #8482 and retains the intended function of the previous code.

Co-authored-by: Charles Hamilton <chamilton@dyercpa.com>
2020-11-16 22:15:40 -08:00
snipe
6eb860ca24 Swapped travis build badge for chipper build badge 2020-11-16 21:49:57 -08:00
snipe
903698a7b0 Merge remote-tracking branch 'origin/develop' 2020-11-16 21:35:26 -08:00
snipe
513faf2db5 Merge branch 'develop' of https://github.com/snipe/snipe-it into develop 2020-11-16 21:34:59 -08:00
snipe
9e46bc6c28 Fix for spanish translation 2020-11-16 21:34:47 -08:00
NMC
402fecd408 Fixed #7850: allow xlsx file. (#8386)
Thanks!
2020-11-16 21:32:15 -08:00
Brady Wetherington
a97b15ec96 Re-add LDAP "test login" feature to LDAP settings (helps with #8751) (#8757)
* Start work on re-adding back the "Test LDAP logins" feature to develop

* Add back-end method to allow LDAP test users to try to log in.
2020-11-16 21:23:08 -08:00
snipe
8504c9e8b9 Added phplint to dev in composer 2020-11-16 19:08:04 -08:00
snipe
4ebfd6624c Merge remote-tracking branch 'origin/develop' 2020-11-16 17:24:57 -08:00
snipe
fbaf6e2494 Fixed #8747 - upload path for uploaded images 2020-11-16 16:39:02 -08:00
snipe
612d3f9b2a Merge remote-tracking branch 'origin/develop' 2020-11-16 13:32:53 -08:00
Brady Wetherington
6e4ab5cd96 Fix for #8746 - missing comma in a translation file (#8756) 2020-11-16 13:29:57 -08:00
snipe
849966d2c5 Merge remote-tracking branch 'origin/develop' 2020-11-13 16:48:58 -08:00
snipe
1f5bcf2475 Added option to download activity report 2020-11-13 16:25:05 -08:00
snipe
58c476195b Bumped hash 2020-11-13 14:14:27 -08:00
snipe
dcd98a7bf1 Bumped hash 2020-11-13 14:13:44 -08:00
snipe
686ab681e5 Removed duplicate badge 2020-11-13 13:54:27 -08:00
snipe
052f8e2c42 Addresses - not fixes - #8740
More investigation here is needed
2020-11-13 12:34:42 -08:00
snipe
e9578ba8a1 Fixed #8737 - incorrect validation string for components update 2020-11-13 12:09:48 -08:00
snipe
0c0de5e351 Added clarity in language as to what the activated flag does on LDAP screens 2020-11-13 11:52:34 -08:00
snipe
10cadecd14 Moved a few of the user edit fields to make more sense (optional stuff further down) 2020-11-13 11:52:09 -08:00
snipe
644084658a Merge remote-tracking branch 'origin/develop' 2020-11-13 04:30:03 -08:00
snipe
07936ea901 Changed asset name to asset tag in maintenances 2020-11-13 03:38:31 -08:00
snipe
08784f9cc5 Make expected_checkin fillable 2020-11-13 03:22:26 -08:00
snipe
a87e615e7f Fixed #8544 - escaping on maintenance notes 2020-11-12 23:55:16 -08:00
snipe
df5cc7525e Merge remote-tracking branch 'origin/develop' 2020-11-12 23:39:09 -08:00
snipe
75b8c3455c Fixed #8609 - custom fieldsets not draggable anymore (regression) 2020-11-12 23:38:12 -08:00
snipe
81d38a0ded Fixed #8733 - typo in unaccepted assets report 2020-11-12 23:26:05 -08:00
snipe
b2a8af2fa9 Fixed #8647 - Added additional help info on importer page 2020-11-12 22:46:51 -08:00
snipe
9d2363741e Improved 2FA reset layout 2020-11-12 22:25:07 -08:00
snipe
fc6a33ad38 Added some LDAP debugging - related to #8670 2020-11-12 22:19:16 -08:00
snipe
896ce3456e Possible fix for #8670 - LDAP users deactivated on login 2020-11-12 22:18:49 -08:00
snipe
9db191f0b2 Fixes for #8732 - Flysystem paths, migrator script 2020-11-12 21:46:06 -08:00
snipe
c7d752fb65 Added S3 url into CSP 2020-11-12 19:50:01 -08:00
snipe
5026177161 Added link to bricelabelle/snipe-it-bulkedit 2020-11-12 18:55:02 -08:00
snipe
d2805442ad Updated Laravel version 2020-11-12 18:54:49 -08:00
snipe
7765c87387 Fixed #8669 - Allow application/xml in SAML upload in Safari 2020-11-12 18:47:19 -08:00
snipe
6dccf399a5 Fixed offset issue for #8732 2020-11-12 15:51:31 -08:00
snipe
7432e3fb2d Add @dampfklon as a contributor 2020-11-12 15:28:29 -08:00
snipe
caeea9f530 Merge remote-tracking branch 'origin/develop' 2020-11-12 15:27:49 -08:00
snipe
0fdfd013e7 Fixed #8715 - wrong API url for unaccepted assets 2020-11-12 15:26:50 -08:00
snipe
d537fc5c32 Added linebreak to console confirmation 2020-11-12 15:21:00 -08:00
snipe
9164dda64f Added artisan command to purge logins 2020-11-12 15:20:15 -08:00
snipe
5ea9c31eab Removed debugging 2020-11-12 15:14:56 -08:00
snipe
c8572deb5c Merge branch 'develop' of https://github.com/snipe/snipe-it into develop 2020-11-12 15:13:50 -08:00
snipe
57d25ebb20 Fixed #8719 - use same convention for file names on licenses as we do on assets 2020-11-12 15:13:45 -08:00
Dampfklon
be114176a2 Refactor Expected Checkin Notification into markdown and enable translation (#8236)
Co-authored-by: snipe <snipe@snipe.net>
2020-11-12 15:09:40 -08:00
Dampfklon
1f9b04405c Enable translation of accept-asset page (#8237) 2020-11-12 15:07:45 -08:00
Dampfklon
4ef11c463c Enable translations of checkin notifications (#8235) 2020-11-12 15:05:57 -08:00
Dampfklon
5fb31a5a3f Use translated salutation from other notifications (#8234) 2020-11-12 15:05:22 -08:00
snipe
f0e04ab9e4 Fixed #8726 - disallow archived assets to be checked out 2020-11-12 15:01:13 -08:00
snipe
8a65081768 Possible fix for #8732 2020-11-12 14:47:38 -08:00
snipe
c451fde466 Fixed exception namespace 2020-11-12 14:27:59 -08:00
snipe
5098d69c05 Fixed stupid auto-indent 2020-11-12 14:20:54 -08:00
snipe
b12de13041 Fixed markdown in expiring licenses alert 2020-11-12 14:10:45 -08:00
snipe
72126f7d44 Removed duplicate extension checks 2020-11-12 13:24:53 -08:00
snipe
df000ce32f Merge branch 'develop' of https://github.com/snipe/snipe-it into develop 2020-11-12 13:22:54 -08:00
snipe
6a2e21f502 More in depth error reporting on mail test failure 2020-11-12 13:22:49 -08:00
Brady Wetherington
5ad6234584 Merge pull request #8730 from winstan/patch-1
Fixed #8699: exclude blank LDAP attributes from searches
2020-11-12 11:26:19 -08:00
Anthony Winstanley
cc79bb1449 Exclude blank LDAP attributes
Asking for '' attributes is an error for some LDAP servers.
2020-11-12 09:34:28 -08:00
snipe
c8d588871c Merge remote-tracking branch 'origin/develop' 2020-11-11 14:47:30 -08:00
snipe
8890372a69 Production assets with dark skin fixes 2020-11-11 14:47:13 -08:00
Godfrey Martinez
80f2d749a2 Corrected css to the bootstrap popovers for all dark mode skins (#8714)
* added css to the bootstrap popovers in dark blue

* corrects the tool tips css for all dark mode skins other than dark blue
2020-11-11 14:11:39 -08:00
snipe
7f7064c835 Make last_checkout fillable 2020-11-11 13:30:11 -08:00
snipe
31d0b4a46c Merge remote-tracking branch 'origin/develop' 2020-11-10 12:39:55 -08:00
snipe
5759d4819e Improved upgrade.php script to check for PHP extensions (#8712)
* Troubleshooting gd detection :(

* Welp, that didn’t work.

* Improvements to the update script that will make it easier to maintain

* Improved spacing

* Nicer intro

* Sorry for all the commits - I have to push in order to test :(

* More display improvements

* Phrasing!

* More formatting

* Removed extra line break

* Few more formatting changes

* Remove the config caching - it’s too confusing for users

* Added comments

* Temp required extension in the array so I can show output :)

* Added ascii x

* removed extra line break

* Made error message clearer

* Remove extra line

* Removed farts

* Changed phrasing for PHP upgrade warning

* Small tweaks per PR review

* Some spacing fixes

* Added confirmation of the either/ors

* Minor formatting tweaks

* Fixed weird indenting?

* Fixed missing $unused_file variable
2020-11-10 12:39:10 -08:00
snipe
c49788dd9f Fixed weird linebreaks in upgrade.php 2020-11-10 09:08:13 -08:00
snipe
3641a6d451 Additional extension checking 2020-11-10 09:06:44 -08:00
snipe
8c79070cd9 Added some extension checking for upgrade.php 2020-11-10 08:47:35 -08:00
snipe
f8563bec94 Added some extension checking for upgrade.php 2020-11-10 08:46:19 -08:00
snipe
fd7c0bc5fb Use newer blade facade for requests 2020-11-10 08:36:18 -08:00
snipe
7d708572fc Slightly nicer formatting for query 2020-11-10 07:43:54 -08:00
snipe
ea68ff1284 Sigh. Typo 2020-11-10 06:51:40 -08:00
snipe
66ccf4da03 Merge remote-tracking branch 'origin/develop' 2020-11-10 06:44:10 -08:00
snipe
0b4a13156f Added more detail and dryrun to assigned_to vs log checker script 2020-11-10 06:43:36 -08:00
snipe
a8a3962008 Merge remote-tracking branch 'origin/develop' 2020-11-10 06:17:04 -08:00
snipe
e110a7b15e Experimental script to find mismatched IDs based on logs 2020-11-10 06:16:15 -08:00
snipe
30d68309a9 Add ability to checkout an asset if the user it’s assigned_to isn’t valid
This would only happen if a merge-users went wonky
2020-11-10 05:06:47 -08:00
snipe
547d1a5a93 Merge remote-tracking branch 'origin/develop' 2020-11-10 04:43:20 -08:00
snipe
adf64361e8 Updated most recent translations 2020-11-10 04:43:02 -08:00
snipe
a43fb060f4 Throw an error if the asset cannot be updated in the merge 2020-11-10 04:41:40 -08:00
snipe
c607d89817 Merge remote-tracking branch 'origin/develop' 2020-11-10 01:59:18 -08:00
snipe
8c19b11e73 Fixed #8448 - “undefined” when testing email from quickstart 2020-11-10 01:48:18 -08:00
snipe
178ed82dc4 Fixed [ch9336] - Removed time stamp in Depreciation report 2020-11-10 01:13:13 -08:00
snipe
6757df5a2d Added Checkout Date Time to Asset Details Page [ch1418] 2020-11-10 01:02:08 -08:00
snipe
044dfe2620 Fixed [ch945] - Status colors are not displaying correctly in the chart on the dashboard 2020-11-10 00:54:39 -08:00
snipe
9e319e91d6 Merge remote-tracking branch 'origin/develop' 2020-11-09 23:56:33 -08:00
snipe
895a544d4c Fixed [ch15347] - added status in Depreciation Report 2020-11-09 23:56:16 -08:00
snipe
2aa9412565 Bumped version
# Conflicts:
#	config/version.php
2020-11-09 23:09:46 -08:00
snipe
35ab5c7df0 Bumped version 2020-11-09 23:09:10 -08:00
snipe
8a7cd87644 Merge remote-tracking branch 'origin/develop' 2020-11-09 23:05:40 -08:00
snipe
1cdf6f8263 Fixed #8673 - added category to accessories listing on Account > Assigned Assets 2020-11-09 23:05:19 -08:00
snipe
b8ad930690 Merge remote-tracking branch 'origin/develop' 2020-11-09 22:55:42 -08:00
snipe
ec14a117b7 Display on the API token page the expiration in years
TODO: Translate these strings
2020-11-09 22:55:27 -08:00
snipe
b7cc12a466 Merge remote-tracking branch 'origin/develop' 2020-11-09 22:53:23 -08:00
snipe
f4080a7aa9 Fixed created_at and expired_at order in API token screen 2020-11-09 22:53:07 -08:00
snipe
5abfbdd1d2 Allow API token expiration in years to be configured via env 2020-11-09 22:52:55 -08:00
snipe
31bbb2d035 Merge remote-tracking branch 'origin/develop' 2020-11-09 22:43:41 -08:00
snipe
33dca84ec7 Show expiry and created at date on API token page 2020-11-09 22:43:27 -08:00
snipe
460485d843 Make API tokens expire in 20 years
TODO: Make this configurable and report the expiration in the UI
2020-11-09 22:33:43 -08:00
snipe
b59269d5e2 Bumped version 2020-11-09 21:46:42 -08:00
snipe
118931b6fb Merge remote-tracking branch 'origin/develop' 2020-11-09 21:46:26 -08:00
snipe
8bbf8409b1 Bumped hash 2020-11-09 21:46:08 -08:00
snipe
b2101a5188 Merge remote-tracking branch 'origin/develop' 2020-11-09 21:09:05 -08:00
snipe
ede20523f2 Fixed #8680 - location image path 2020-11-09 21:08:19 -08:00
snipe
89d9b830a0 Updated PHP requirement 2020-11-09 21:05:41 -08:00
snipe
d76eea53c4 Bumped hash 2020-11-09 19:45:27 -08:00
snipe
63a8535de1 Merge remote-tracking branch 'origin/develop' 2020-11-09 19:11:37 -08:00
snipe
ef7434b7ac Updated template 2020-11-09 19:11:18 -08:00
snipe
148b375ec2 Make 600 a string for ini_set 2020-11-09 19:11:00 -08:00
snipe
d49bc33b54 Merge branch 'develop' of https://github.com/snipe/snipe-it into develop 2020-11-09 18:21:15 -08:00
snipe
5bff5cb8c0 Updated Crowdin file 2020-11-09 18:21:10 -08:00
snipe
c8634d85f5 Merge pull request #8706 from uberbrady/fix_bootstrap_tables_empty_fields
Potential fix for empty-page problem in Assets view
2020-11-09 18:19:42 -08:00
Brady Wetherington
a5423649f4 This is the smallest set of changes we can use to work around a change in functionality
in Bootstrap Tables. This should remedy some of the issues we've been having with large
GET strings being sent to the back-end by the Assets system.
2020-11-09 17:36:07 -08:00
snipe
b026953190 Merge pull request #8688 from sanjay900/patch-1
Fix AD Accounts with delegation disabled
2020-11-09 16:13:13 -08:00
snipe
3c209b29b1 Merge remote-tracking branch 'origin/develop' 2020-11-09 15:09:05 -08:00
snipe
c0fb87c7f9 Merge pull request #8702 from uberbrady/ldap_time_limit_sync
Restore the LDAP_TIME_LIM .env var
2020-11-09 15:08:17 -08:00
snipe
48c3d0fd19 Merge remote-tracking branch 'origin/develop'
# Conflicts:
#	resources/lang/es-VE/general.php
2020-11-09 14:55:11 -08:00
snipe
67f60127be Updated translations with latest from CrowdIn 2020-11-09 14:52:11 -08:00
snipe
4a8a98a7d3 Fixed user test 2020-11-09 14:17:45 -08:00
snipe
4b8e9a962b Fixed Venezuelan translation file 2020-11-09 14:05:31 -08:00
Brady Wetherington
966179290b Restore the LDAP_TIME_LIM env var for ldap sync of very large directories 2020-11-09 11:11:42 -08:00
snipe
6618e88a9a Fixed spanish translation parse error 2020-11-06 10:19:32 -08:00
Sanjay Govind
ab6d2987a4 Include documentation from @uberbrady
Previously on v4 this was all documented, so i have copied that documentation across to v5
2020-11-06 12:31:33 +13:00
Sanjay Govind
45c140814f Fix AD Accounts with delegation disabled 2020-11-06 12:02:19 +13:00
snipe
467ff045aa Moved the BACKUP_ENV to new BACKUP block 2020-11-03 14:58:19 -08:00
snipe
e0103a7fbd Fixed #8595 - Updated spatie settings 2020-11-03 14:50:02 -08:00
snipe
432263f09f Merge pull request #8671 from mzack5020/patch-1
Fixed #8624 #8312: Re-Added Accessories API
2020-11-03 13:50:38 -08:00
Matthew Zackschewski
911841d188 Re-Added Accessories API
#8312 #8624 Removed unnecessary duplicate licenses endpoint and re-added the user accessories endpoint which was left off.
2020-11-03 16:40:43 -05:00
snipe
e8fd2a7fe8 Merge remote-tracking branch 'origin/develop' 2020-11-03 13:07:31 -08:00
snipe
df5972c4fa Fixed send creds checkbox in create user form 2020-11-03 13:07:15 -08:00
snipe
4d003ac97a Merge remote-tracking branch 'origin/develop'
# Conflicts:
#	app/Http/Controllers/Auth/ResetPasswordController.php
#	config/version.php
2020-11-03 11:49:34 -08:00
snipe
9f4a212b44 Bumped hash 2020-11-03 11:47:58 -08:00
snipe
12667f41b9 bumped hash 2020-11-03 11:47:13 -08:00
snipe
a8390ce4bd Removed debugging 2020-11-03 11:45:19 -08:00
snipe
cfc1e1366c Added new password complexity rules to forgot password 2020-11-03 11:42:42 -08:00
snipe
44e5fec707 Fixed #8603 - Use correct CSS path for signature-pad.min.css 2020-11-03 10:01:55 -08:00
snipe
f138d3b781 Fixed typo 2020-11-03 01:00:37 -08:00
snipe
bbd7a752a0 Minor cleanup 2020-11-02 23:58:49 -08:00
snipe
a66a22ffb2 Updated passwordComplexityRulesSaving() signature so it isn’t nullable 2020-11-02 23:58:37 -08:00
snipe
b29f794b35 password.expire updated for forgotten password token expiration 2020-11-02 23:58:09 -08:00
snipe
410c99da17 Added signature-pad.min.css to the css directory - should possibly fix #8603 2020-11-02 23:57:39 -08:00
snipe
c800662f0c Use username for forgotten password
Since emails are not required to be unique
2020-11-02 23:57:00 -08:00
snipe
b828985151 Fixed strpos to !== FALSE in ProfileController for complexity eval 2020-11-02 22:28:56 -08:00
snipe
e6f53a53bc Updated min requirement for passwords in lang files 2020-11-02 22:15:01 -08:00
snipe
0c2800c7dd Removed debugging line 2020-11-02 21:26:13 -08:00
snipe
a8f9f5239c Merge pull request #8662 from snipe/features/disallow_password_equal_to_username_etc
Fixed #8661 - Added feature to disallow password equal to username, email, etc
2020-11-02 21:09:31 -08:00
snipe
63bb2de4d4 Derp. Check and make sure that setting is actually on 2020-11-02 20:13:54 -08:00
snipe
c4b2ef5660 Removed debugging code 2020-11-02 20:10:18 -08:00
snipe
296655542d Added comments 2020-11-02 20:07:39 -08:00
snipe
a55694da2f Added validation to disallow password to be the same as username, email, etc 2020-11-02 20:03:26 -08:00
snipe
33bda9b6d1 Added blade option for same_pwd_as_user_fields
Disallows password form value to be the same as username, email, first name or last name
2020-11-02 17:47:25 -08:00
snipe
42347d0f0c Added validation language for same_pwd_as_user_fields 2020-11-02 17:46:30 -08:00
snipe
6554903aeb Removed “use slack” debugging code 2020-11-02 17:46:09 -08:00
snipe
502322be4b Fixed v5 500 server error when requesting multiple [ch15345] 2020-11-02 16:08:38 -08:00
snipe
72facffcbe Fixed demo settings value for support_footer 2020-10-26 15:09:02 -07:00
snipe
001bb3cbe2 Bumped version to “pre” 2020-10-26 15:04:22 -07:00
snipe
f42bd3a144 Fixed #8613 - Added deleted_at to user API response, added all=true to include deleted and not-deleted in one call 2020-10-26 14:58:45 -07:00
snipe
b9330cf6b1 Fixed #8613 - 500 error on deleted users API call 2020-10-26 14:55:18 -07:00
snipe
2844800caf Merge remote-tracking branch 'origin/develop'
# Conflicts:
#	config/version.php
2020-10-26 14:26:05 -07:00
snipe
b7e8b9bad7 Merge branch 'develop' of https://github.com/snipe/snipe-it into develop 2020-10-26 14:24:43 -07:00
snipe
a7ecaa6ebc Merge pull request #8619 from uberbrady/fix_ldap_paging
Fixed #8563 - Clean up AdLdap2 integration to better handle paged result-sets
2020-10-26 14:24:34 -07:00
snipe
7937258f6e Bumped version 2020-10-26 14:24:19 -07:00
Brady Wetherington
cce0739bb7 Clean up AdLdap2 integration to better handle paged result-sets 2020-10-26 12:53:45 -07:00
snipe
c93f4ef0d5 Merge remote-tracking branch 'origin/develop' 2020-10-23 19:50:56 -07:00
snipe
89e36dbc42 Merge pull request #8606 from uberbrady/fix_cant_manage_self
Add a new custom validator for Users
2020-10-23 19:16:11 -07:00
snipe
d317052ede Updated CSS assets with green skin edits 2020-10-23 18:55:00 -07:00
snipe
8ee9e5e059 Fixed #8537 - wrong sorting on dashboard 2020-10-23 18:33:10 -07:00
snipe
2602e4d602 Exclude the config directory from backups
Everything there is handled via .env anyway
2020-10-23 18:21:32 -07:00
snipe
f357d9fc90 Include audit settings text in settings overview so they get picked up by the filter box 2020-10-23 18:13:28 -07:00
Brady Wetherington
0eda53c484 Add a new custom validator for Users to prevent someone from managing themselves 2020-10-23 16:55:10 -07:00
1361 changed files with 16203 additions and 5569 deletions

View File

@@ -1938,6 +1938,24 @@
"contributions": [
"code"
]
},
{
"login": "dampfklon",
"name": "Dampfklon",
"avatar_url": "https://avatars1.githubusercontent.com/u/1733625?v=4",
"profile": "https://github.com/dampfklon",
"contributions": [
"code"
]
},
{
"login": "chamilton-ccn",
"name": "Charles Hamilton",
"avatar_url": "https://avatars2.githubusercontent.com/u/52973156?v=4",
"profile": "https://communityclosing.com",
"contributions": [
"code"
]
}
]
}

View File

@@ -51,7 +51,7 @@ MAIL_FROM_ADDR=you@example.com
MAIL_FROM_NAME='Snipe-IT'
MAIL_REPLYTO_ADDR=you@example.com
MAIL_REPLYTO_NAME='Snipe-IT'
MAIL_BACKUP_NOTIFICATION_ADDRESS=you@example.com
MAIL_AUTO_EMBED_METHOD='attachment'
# --------------------------------------------
# REQUIRED: IMAGE LIBRARY
@@ -59,6 +59,15 @@ MAIL_BACKUP_NOTIFICATION_ADDRESS=you@example.com
# --------------------------------------------
IMAGE_LIB=gd
# --------------------------------------------
# OPTIONAL: BACKUP SETTINGS
# --------------------------------------------
MAIL_BACKUP_NOTIFICATION_DRIVER=null
MAIL_BACKUP_NOTIFICATION_ADDRESS=null
BACKUP_ENV=true
# --------------------------------------------
# OPTIONAL: SESSION SETTINGS
# --------------------------------------------
@@ -68,6 +77,7 @@ ENCRYPT=false
COOKIE_NAME=snipeit_session
COOKIE_DOMAIN=null
SECURE_COOKIES=false
API_TOKEN_EXPIRATION_YEARS=40
# --------------------------------------------
# OPTIONAL: SECURITY HEADER SETTINGS
@@ -125,6 +135,7 @@ PRIVATE_AWS_BUCKET_ROOT=null
# --------------------------------------------
LOGIN_MAX_ATTEMPTS=5
LOGIN_LOCKOUT_DURATION=60
RESET_PASSWORD_LINK_EXPIRES=900
# --------------------------------------------
# OPTIONAL: MISC
@@ -134,6 +145,5 @@ APP_LOG_MAX_FILES=10
APP_LOCKED=false
APP_CIPHER=AES-256-CBC
GOOGLE_MAPS_API=
BACKUP_ENV=true
LDAP_MEM_LIM=500M
LDAP_TIME_LIM=600

View File

@@ -48,6 +48,7 @@ If applicable, add screenshots to help explain your problem.
- Any errors that appear in your browser's error console.
- Confirm whether the error is reproducible on the demo: https://snipeitapp.com/demo.
- Include any additional information you can find in `storage/logs` and your webserver's logs.
- Include the output from `php -m` (this should display what modules you have enabled.)
**Additional context**
- Is this a fresh install or an upgrade?

1
.gitignore vendored
View File

@@ -60,3 +60,4 @@ phpmd\.xml
_ide_helper.php
.phpstorm.meta.php
_ide_helper_models.php
/.phplint-cache

View File

@@ -1,80 +0,0 @@
addons:
code_climate:
repo_token:
secure: "C/bUAEpwfZB82dkzI2Nxx3PW5w/BzbKkSyCkp6YjT046jD2/QKvz6ngCFlt3tAWV11TXWFI6D8DzkMmdWOrQl3SGlPZXRD8QOvCiz0HiGMDvlxjAaPaQecGaQZdx/H4m6xTUXRNUVaYmxlMgkkFCWhAp+HZDs0iyOEVamp0Jszg="
hosts:
- localhost
sudo: false
# see http://about.travis-ci.org/docs/user/languages/php/ for more hints
language: php
services:
- mysql
# list any PHP version you want to test against
php:
- 7.2
- 7.3.0
- 7.4
# execute any number of scripts before the test run, custom env's are available as variables
before_script:
- phpenv config-add .github/travis-memory.ini
- phantomjs --webdriver=4444 &
- sleep 4
- mysql -e 'CREATE DATABASE snipeit_unit;'
- mysql -e 'CREATE USER "travis'@'localhost";'
- mysql -e 'GRANT ALL PRIVILEGES ON * . * TO "travis'@'localhost";'
- mysql -e 'FLUSH PRIVILEGES;'
- cp .env.testing-ci .env
- composer self-update
- composer install -n --prefer-source
- chmod -R 777 storage
- php artisan migrate --env=testing-ci --database=mysql --force
- ./vendor/bin/codecept build
- php artisan --env=testing-ci key:generate
- php artisan --env=testing-ci snipeit:travisci-install
- php artisan --env=testing-ci db:seed --database=mysql --force
- php artisan --env=testing-ci snipeit:create-admin --first_name=Alison --last_name=Foobar --email=me@example.com --username=snipe --password=password
- php artisan --env=testing-ci passport:install
- php artisan serve --env=testing-ci --port=8000 --host=localhost &
- sleep 5
- pip install --user codecov
- sleep 5
# omitting "script:" will default to phpunit
# use the $DB env variable to determine the phpunit.xml to use
# script: ./vendor/bin/codecept run --env testing-ci
script:
- ./vendor/bin/codecept run unit
# - ./vendor/bin/codecept run acceptance --env=testing-ci
- ./vendor/bin/codecept run functional --env=functional-travis -g func1
- ./vendor/bin/codecept run functional --env=functional-travis -g func2
- ./vendor/bin/codecept run api --env=functional-travis
after_script:
- vendor/bin/test-reporter
after_success:
- codecov
after_failure:
- cat tests/_output/*.fail.html
- curl http://localhost:8000/login
- cat storage/logs/laravel.log
# configure notifications (email, IRC, campfire etc)
notifications:
email: false
slack:
secure: vv9we1RxB9RsrMbomSdq6D7vz/okobw87pEkgIZjB+hj1QpQ2by90gsPsOa+NgsJEFaEP7e4KlT6SH8kK+zhbmuKaUd3d1//XdcancE22LZXi6tkiB5yuR/Jhhb1LLDqyGJTB4D92hMnnCPiUjpxNA3r437ttNeYRdYIEEP3drA=
webhooks:
urls:
- https://webhooks.gitter.im/e/5e136eb0c1965f3918d0
on_success: change # options: [always|never|change] default: always
on_failure: change # options: [always|never|change] default: always
on_start: false # default: false

View File

@@ -1,13 +1,11 @@
[![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&amp;utm_medium=referral&amp;utm_content=snipe/snipe-it&amp;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)
![Build Status](https://app.chipperci.com/projects/0e5f8979-31eb-4ee6-9abf-050b76ab0383/status/master) [![Crowdin](https://d322cqt584bo4o.cloudfront.net/snipe-it/localized.svg)](https://crowdin.com/project/snipe-it) [![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&amp;utm_medium=referral&amp;utm_content=snipe/snipe-it&amp;utm_campaign=Badge_Grade)
[![All Contributors](https://img.shields.io/badge/all_contributors-214-orange.svg?style=flat-square)](#contributors)
## Snipe-IT - Open Source Asset Management System
This is a FOSS project for asset management in IT Operations. Knowing who has which laptop, when it was purchased in order to depreciate it correctly, handling software licenses, etc.
It is built on [Laravel 5.5](http://laravel.com).
It is built on [Laravel 6](http://laravel.com).
Snipe-IT is actively developed and we [release quite frequently](https://github.com/snipe/snipe-it/releases). ([Check out the live demo here](https://snipeitapp.com/demo/).)
@@ -64,7 +62,8 @@ Since the release of the JSON REST API, several third-party developers have been
- [Snipe-IT plugin for Jira Service Desk (beta)](https://marketplace.atlassian.com/apps/1220379/snipe-it-for-jira-service-desk-beta?hosting=cloud&tab=overview) - for the upcoming Snipe-IT v5 only
- [Python 3 CSV importer](https://github.com/gastamper/snipeit-csvimporter) - allows importing assets into Snipe-IT based on Item Name rather than Asset Tag.
- [Snipe-IT Kubernetes Helm Chart](https://github.com/t3n/helm-charts/tree/master/snipeit) - For more information, [click here](https://hub.helm.sh/charts/t3n/snipeit).
- [Snipe-IT Bulk Edit](https://github.com/bricelabelle/snipe-it-bulkedit) - Google Script files to use Google Sheets as a bulk checkout/checkin/edit tool for Snipe-it.
As these were created by third-parties, Snipe-IT cannot provide support for these project, and you should contact the developers directly if you need assistance. Additionally, Snipe-IT makes no guarantees as to the reliability, accuracy or maintainability of these libraries. Use at your own risk. :)
-----
@@ -115,14 +114,12 @@ 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") |
| [<img src="https://avatars1.githubusercontent.com/u/6271335?v=4" width="110px;"/><br /><sub>Evgeny</sub>](https://github.com/jackka)<br />[💻](https://github.com/snipe/snipe-it/commits?author=jackka "Code") | [<img src="https://avatars2.githubusercontent.com/u/1169963?v=4" width="110px;"/><br /><sub>Colin Campbell</sub>](https://digitalist.se)<br />[💻](https://github.com/snipe/snipe-it/commits?author=colin-campbell "Code") | [<img src="https://avatars3.githubusercontent.com/u/2872098?v=4" width="110px;"/><br /><sub>Ľubomír Kučera</sub>](https://github.com/lubo)<br />[💻](https://github.com/snipe/snipe-it/commits?author=lubo "Code") | [<img src="https://avatars3.githubusercontent.com/u/570639?v=4" width="110px;"/><br /><sub>Martin Meredith</sub>](https://www.sourceguru.net)<br />[💻](https://github.com/snipe/snipe-it/commits?author=Mezzle "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://avatars1.githubusercontent.com/u/63399474?v=4" width="110px;"/><br /><sub>johnson-yi</sub>](https://github.com/johnson-yi)<br />[💻](https://github.com/snipe/snipe-it/commits?author=johnson-yi "Code") | [<img src="https://avatars1.githubusercontent.com/u/1862720?v=4" width="110px;"/><br /><sub>Sanjay Govind</sub>](https://tangentmc.net)<br />[💻](https://github.com/snipe/snipe-it/commits?author=sanjay900 "Code") |
| [<img src="https://avatars0.githubusercontent.com/u/1255375?v=4" width="110px;"/><br /><sub>Peter Upfold</sub>](https://peter.upfold.org.uk/)<br />[💻](https://github.com/snipe/snipe-it/commits?author=PeterUpfold "Code") | [<img src="https://avatars2.githubusercontent.com/u/961717?v=4" width="110px;"/><br /><sub>Jared Biel</sub>](https://github.com/jbiel)<br />[💻](https://github.com/snipe/snipe-it/commits?author=jbiel "Code") |
| [<img src="https://avatars0.githubusercontent.com/u/1255375?v=4" width="110px;"/><br /><sub>Peter Upfold</sub>](https://peter.upfold.org.uk/)<br />[💻](https://github.com/snipe/snipe-it/commits?author=PeterUpfold "Code") | [<img src="https://avatars2.githubusercontent.com/u/961717?v=4" width="110px;"/><br /><sub>Jared Biel</sub>](https://github.com/jbiel)<br />[💻](https://github.com/snipe/snipe-it/commits?author=jbiel "Code") | [<img src="https://avatars1.githubusercontent.com/u/1733625?v=4" width="110px;"/><br /><sub>Dampfklon</sub>](https://github.com/dampfklon)<br />[💻](https://github.com/snipe/snipe-it/commits?author=dampfklon "Code") | [<img src="https://avatars2.githubusercontent.com/u/52973156?v=4" width="110px;"/><br /><sub>Charles Hamilton</sub>](https://communityclosing.com)<br />[💻](https://github.com/snipe/snipe-it/commits?author=chamilton-ccn "Code") |
<!-- ALL-CONTRIBUTORS-LIST:END -->
This project follows the [all-contributors](https://github.com/kentcdodds/all-contributors) specification. Contributions of any kind welcome!

View File

@@ -0,0 +1,105 @@
<?php
namespace App\Console\Commands;
use App\Models\Actionlog;
use App\Models\Asset;
use Illuminate\Console\Command;
class FixMismatchedAssetsAndLogs extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'snipeit:fix-assets-and-logs {--dryrun : Run the sync process but don\'t update the database}';
/**
* The console command description.
*
* @var string
*/
protected $description = 'This script attempts to check the log table and check that the assets.assigned_to matches the last checkout.';
/**
* Is dry-run?
*
* @var bool
*/
private $dryrun = false;
/**
* Create a new command instance.
*
* @return void
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
*
* @return mixed
*/
public function handle()
{
if ($this->option('dryrun')) {
$this->dryrun = true;
}
if ($this->dryrun) {
$this->info('This is a DRY RUN - no changes will be saved.' );
}
$mismatch_count = 0;
$assets = Asset::whereNotNull('assigned_to')
->where('assigned_type', '=', 'App\\Models\\User')
->orderBy('id', 'ASC')->get();
foreach ($assets as $asset) {
// get the last checkout of the asset
if ($checkout_log = Actionlog::where('target_type', '=', 'App\\Models\\User')
->where('action_type', '=', 'checkout')
->where('item_id', '=', $asset->id)
->orderBy('created_at', 'DESC')
->first()) {
// Now check for a subsequent checkin log - we want to ignore those
if (!$checkin_log = Actionlog::where('target_type', '=', 'App\\Models\\User')
->where('action_type', '=', 'checkin from')
->where('item_id', '=', $asset->id)
->whereDate('created_at', '>', $checkout_log->created_at)
->orderBy('created_at', 'DESC')
->first()) {
//print_r($asset);
if ($checkout_log->target_id != $asset->assigned_to) {
$this->error('Log ID: '.$checkout_log->id.' -- Asset ID '. $checkout_log->item_id.' SHOULD BE checked out to User '.$checkout_log->target_id.' but its assigned_to is '.$asset->assigned_to );
if (!$this->dryrun) {
$asset->assigned_to = $checkout_log->target_id;
if ($asset->save()) {
$this->info('Asset record updated.');
} else {
$this->error('Error updating asset: '.$asset->getErrors());
}
}
$mismatch_count++;
}
} else {
//$this->info('Asset ID '.$asset->id.': There is a checkin '.$checkin_log->created_at.' after this checkout '.$checkout_log->created_at);
}
}
}
$this->info($mismatch_count.' mismatched assets.');
}
}

View File

@@ -108,7 +108,7 @@ class LdapSync extends Command
*/
public function handle()
{
ini_set('max_execution_time', '600'); //600 seconds = 10 minutes
ini_set('max_execution_time', env('LDAP_TIME_LIM', "600")); //600 seconds = 10 minutes
ini_set('memory_limit', '500M');
$old_error_reporting = error_reporting(); // grab old error_reporting .ini setting, for later re-enablement
error_reporting($old_error_reporting & ~E_DEPRECATED); // disable deprecation warnings, for LDAP in PHP 7.4 (and greater)
@@ -221,12 +221,11 @@ class LdapSync extends Command
*
* @since 5.0.0
*
* @param int $page The page to get the result set
*/
private function processLdapUsers(int $page=0): void
private function processLdapUsers(): void
{
try {
$ldapUsers = $this->ldap->getLdapUsers($page);
$ldapUsers = $this->ldap->getLdapUsers();
} catch (Exception $e) {
$this->outputError($e);
exit($e->getMessage());
@@ -242,15 +241,9 @@ class LdapSync extends Command
}
// Process each individual users
foreach ($ldapUsers as $user) {
foreach ($ldapUsers->getResults() as $user) { // AdLdap2's paginate() method is weird, it gets *everything* and ->getResults() returns *everything*
$this->updateCreateUser($user);
}
if ($ldapUsers->getCurrentPage() < $ldapUsers->getPages()-1) {
$current_page = $ldapUsers->getCurrentPage();
unset($ldapUsers); //deliberately unset the variable so we don't OOM
$this->processLdapUsers($current_page + 1); //this recursive call means that the $ldapUsers variable is not going to get GC'ed until everything returns. Blech.
}
}
/**

View File

@@ -54,7 +54,10 @@ class MergeUsersByUsername extends Command
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();
if (!$asset->save()) {
$this->error( 'Could not update assigned_to field on asset '.$asset->asset_tag.' '.$asset->id.' to user '.$user->id);
$this->error( 'Error saving: '.$asset->getErrors());
}
}
// Walk the list of licenses

View File

@@ -47,33 +47,33 @@ class MoveUploadsToNewDisk extends Command
}
$delete_local = $this->argument('delete_local');
$public_uploads['accessories'] = glob('storage/app/public/accessories'."/*.*");
$public_uploads['assets'] = glob('storage/app/public/assets'."/*.*");
$public_uploads['avatars'] = glob('storage/app/public/avatars'."/*.*");
$public_uploads['categories'] = glob('storage/app/public/categories'."/*.*");
$public_uploads['companies'] = glob('storage/app/public/companies'."/*.*");
$public_uploads['components'] = glob('storage/app/public/components'."/*.*");
$public_uploads['consumables'] = glob('storage/app/public/consumables'."/*.*");
$public_uploads['departments'] = glob('storage/app/public/departments'."/*.*");
$public_uploads['locations'] = glob('storage/app/public/locations'."/*.*");
$public_uploads['manufacturers'] = glob('storage/app/public/manufacturers'."/*.*");
$public_uploads['suppliers'] = glob('storage/app/public/suppliers'."/*.*");
$public_uploads['assetmodels'] = glob('storage/app/public/models'."/*.*");
$public_uploads['accessories'] = glob('public/accessories'."/*.*");
$public_uploads['assets'] = glob('public/assets'."/*.*");
$public_uploads['avatars'] = glob('public/avatars'."/*.*");
$public_uploads['categories'] = glob('public/categories'."/*.*");
$public_uploads['companies'] = glob('public/companies'."/*.*");
$public_uploads['components'] = glob('public/components'."/*.*");
$public_uploads['consumables'] = glob('public/consumables'."/*.*");
$public_uploads['departments'] = glob('public/departments'."/*.*");
$public_uploads['locations'] = glob('public/locations'."/*.*");
$public_uploads['manufacturers'] = glob('public/manufacturers'."/*.*");
$public_uploads['suppliers'] = glob('public/suppliers'."/*.*");
$public_uploads['assetmodels'] = glob('public/models'."/*.*");
// iterate files
foreach($public_uploads as $public_type => $public_upload)
{
$type_count = 0;
$this->info("\nThere are ".count($public_upload).' PUBLIC '.$public_type.' files.');
$this->info("- There are ".count($public_upload).' PUBLIC '.$public_type.' files.');
for ($i = 0; $i < count($public_upload); $i++) {
$type_count++;
$filename = basename($public_upload[$i]);
try {
Storage::disk('public')->put($public_type.'/'.$filename, file_get_contents($public_upload[$i]));
$new_url = Storage::disk('public')->url($public_type.'/'.$filename, $filename);
Storage::disk('public')->put('uploads/'.public_type.'/'.$filename, file_get_contents($public_upload[$i]));
$new_url = Storage::disk('public')->url('uploads/'.$public_type.'/'.$filename, $filename);
$this->info($type_count.'. PUBLIC: '.$filename.' was copied to '.$new_url);
} catch (\Exception $e) {
\Log::debug($e);
@@ -84,15 +84,16 @@ class MoveUploadsToNewDisk extends Command
}
$logos = glob('public/uploads'."/setting*.*");
$this->info("\nThere are ".count($logos).' files that might be logos.');
$logos = glob("public/uploads/setting*.*");
$this->info("- There are ".count($logos).' files that might be logos.');
$type_count = 0;
for ($l = 0; $l < count($logos); $l++) {
foreach ($logos as $logo) {
$this->info($logo);
$type_count++;
$filename = basename($logos[$l]);
$new_url = Storage::disk('public')->url($logos[$l], file_get_contents($public_upload[$i]));
$this->info($type_count.'. LOGO: '.$filename.' was copied to '.$new_url);
$filename = basename($logo);
Storage::disk('public')->put('uploads/'.$filename, file_get_contents($logo));
$this->info($type_count.'. LOGO: '.$filename.' was copied to '.env('PUBLIC_AWS_URL').'/uploads/'.$filename);
}
$private_uploads['assets'] = glob('storage/private_uploads/assets'."/*.*");
@@ -107,8 +108,7 @@ class MoveUploadsToNewDisk extends Command
foreach($private_uploads as $private_type => $private_upload)
{
$this->info("\nThere are ".count($private_upload).' PRIVATE '.$private_type.' files.');
// $this->info(print_r($private_upload, true));
$this->info("- There are ".count($private_upload).' PRIVATE '.$private_type.' files.');
$type_count = 0;
for ($x = 0; $x < count($private_upload); $x++) {
@@ -116,7 +116,7 @@ class MoveUploadsToNewDisk extends Command
$filename = basename($private_upload[$x]);
try {
Storage::disk('private_uploads')->put($private_type.'/'.$filename, file_get_contents($public_upload[$i]));
Storage::put($private_type.'/'.$filename, file_get_contents($private_upload[$i]));
$new_url = Storage::url($private_type.'/'.$filename, $filename);
$this->info($type_count.'. PRIVATE: '.$filename.' was copied to '.$new_url);

View File

@@ -55,8 +55,10 @@ class ObjectImportCommand extends Command
->setShouldNotify($this->option('send-welcome'))
->setUsernameFormat($this->option('username_format'));
$logFile = $this->option('logfile');
\Log::useFiles($logFile);
// This $logFile/useFiles() bit is currently broken, so commenting it out for now
// $logFile = $this->option('logfile');
// \Log::useFiles($logFile);
$this->comment('======= Importing Items from '.$filename.' =========');
$importer->import();

View File

@@ -0,0 +1,44 @@
<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
class PurgeLoginAttempts extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'snipeit:purge-logins';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Clears the login_attempts table';
/**
* Create a new command instance.
*
* @return void
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
*
* @return mixed
*/
public function handle()
{
if ($this->confirm("\n****************************************************\nTHIS WILL DELETE ALL OF THE YOUR LOGIN ATTEMPT RECORDS. \nThere is NO undo! \n****************************************************\n\nDo you wish to continue? No backsies! [y|N]")) {
\DB::statement('delete from login_attempts');
}
}
}

View File

@@ -64,7 +64,7 @@ class ResetDemoSettings extends Command
$settings->thumbnail_max_h = '30';
$settings->locale = 'en';
$settings->version_footer = 'on';
$settings->support_footer = 'on';
$settings->support_footer = null;
$settings->saml_enabled = '0';
$settings->saml_sp_entitiyid = '0';
$settings->saml_sp_acs_url = null;

View File

@@ -55,27 +55,313 @@ class Helper
/**
* Static colors for pie charts.
* This is inelegant, and could be refactored later.
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v3.3]
* @return Array
*/
public static function chartColors()
public static function defaultChartColors($index = 0)
{
$colors = [
'#f56954',
'#00a65a',
'#f39c12',
'#00c0ef',
'#3c8dbc',
'#d2d6de',
'#3c8dbc',
'#3c8dbc',
'#3c8dbc',
"#008941",
"#FF4A46",
"#006FA6",
"#A30059",
"#1CE6FF",
"#FFDBE5",
"#7A4900",
"#0000A6",
"#63FFAC",
"#B79762",
"#004D43",
"#8FB0FF",
"#997D87",
"#5A0007",
"#809693",
"#FEFFE6",
"#1B4400",
"#4FC601",
"#3B5DFF",
"#4A3B53",
"#FF2F80",
"#61615A",
"#BA0900",
"#6B7900",
"#00C2A0",
"#FFAA92",
"#FF90C9",
"#B903AA",
"#D16100",
"#DDEFFF",
"#000035",
"#7B4F4B",
"#A1C299",
"#300018",
"#0AA6D8",
"#013349",
"#00846F",
"#372101",
"#FFB500",
"#C2FFED",
"#A079BF",
"#CC0744",
"#C0B9B2",
"#C2FF99",
"#001E09",
"#00489C",
"#6F0062",
"#0CBD66",
"#EEC3FF",
"#456D75",
"#B77B68",
"#7A87A1",
"#788D66",
"#885578",
"#FAD09F",
"#FF8A9A",
"#D157A0",
"#BEC459",
"#456648",
"#0086ED",
"#886F4C",
"#34362D",
"#B4A8BD",
"#00A6AA",
"#452C2C",
"#636375",
"#A3C8C9",
"#FF913F",
"#938A81",
"#575329",
"#00FECF",
"#B05B6F",
"#8CD0FF",
"#3B9700",
"#04F757",
"#C8A1A1",
"#1E6E00",
"#7900D7",
"#A77500",
"#6367A9",
"#A05837",
"#6B002C",
"#772600",
"#D790FF",
"#9B9700",
"#549E79",
"#FFF69F",
"#201625",
"#72418F",
"#BC23FF",
"#99ADC0",
"#3A2465",
"#922329",
"#5B4534",
"#FDE8DC",
"#404E55",
"#0089A3",
"#CB7E98",
"#A4E804",
"#324E72",
"#6A3A4C",
"#83AB58",
"#001C1E",
"#D1F7CE",
"#004B28",
"#C8D0F6",
"#A3A489",
"#806C66",
"#222800",
"#BF5650",
"#E83000",
"#66796D",
"#DA007C",
"#FF1A59",
"#8ADBB4",
"#1E0200",
"#5B4E51",
"#C895C5",
"#320033",
"#FF6832",
"#66E1D3",
"#CFCDAC",
"#D0AC94",
"#7ED379",
"#012C58",
"#7A7BFF",
"#D68E01",
"#353339",
"#78AFA1",
"#FEB2C6",
"#75797C",
"#837393",
"#943A4D",
"#B5F4FF",
"#D2DCD5",
"#9556BD",
"#6A714A",
"#001325",
"#02525F",
"#0AA3F7",
"#E98176",
"#DBD5DD",
"#5EBCD1",
"#3D4F44",
"#7E6405",
"#02684E",
"#962B75",
"#8D8546",
"#9695C5",
"#E773CE",
"#D86A78",
"#3E89BE",
"#CA834E",
"#518A87",
"#5B113C",
"#55813B",
"#E704C4",
"#00005F",
"#A97399",
"#4B8160",
"#59738A",
"#FF5DA7",
"#F7C9BF",
"#643127",
"#513A01",
"#6B94AA",
"#51A058",
"#A45B02",
"#1D1702",
"#E20027",
"#E7AB63",
"#4C6001",
"#9C6966",
"#64547B",
"#97979E",
"#006A66",
"#391406",
"#F4D749",
"#0045D2",
"#006C31",
"#DDB6D0",
"#7C6571",
"#9FB2A4",
"#00D891",
"#15A08A",
"#BC65E9",
"#FFFFFE",
"#C6DC99",
"#203B3C",
"#671190",
"#6B3A64",
"#F5E1FF",
"#FFA0F2",
"#CCAA35",
"#374527",
"#8BB400",
"#797868",
"#C6005A",
"#3B000A",
"#C86240",
"#29607C",
"#402334",
"#7D5A44",
"#CCB87C",
"#B88183",
"#AA5199",
"#B5D6C3",
"#A38469",
"#9F94F0",
"#A74571",
"#B894A6",
"#71BB8C",
"#00B433",
"#789EC9",
"#6D80BA",
"#953F00",
"#5EFF03",
"#E4FFFC",
"#1BE177",
"#BCB1E5",
"#76912F",
"#003109",
"#0060CD",
"#D20096",
"#895563",
"#29201D",
"#5B3213",
"#A76F42",
"#89412E",
"#1A3A2A",
"#494B5A",
"#A88C85",
"#F4ABAA",
"#A3F3AB",
"#00C6C8",
"#EA8B66",
"#958A9F",
"#BDC9D2",
"#9FA064",
"#BE4700",
"#658188",
"#83A485",
"#453C23",
"#47675D",
"#3A3F00",
"#061203",
"#DFFB71",
"#868E7E",
"#98D058",
"#6C8F7D",
"#D7BFC2",
"#3C3E6E",
"#D83D66",
"#2F5D9B",
"#6C5E46",
"#D25B88",
"#5B656C",
"#00B57F",
"#545C46",
"#866097",
"#365D25",
"#252F99",
"#00CCFF",
"#674E60",
"#FC009C",
"#92896B",
];
return $colors;
return $colors[$index];
}
/**
* Increases or decreases the brightness of a color by a percentage of the current brightness.
*
* @param string $hexCode Supported formats: `#FFF`, `#FFFFFF`, `FFF`, `FFFFFF`
* @param float $adjustPercent A number between -1 and 1. E.g. 0.3 = 30% lighter; -0.4 = 40% darker.
*
* @return string
*/
public static function adjustBrightness($hexCode, $adjustPercent) {
$hexCode = ltrim($hexCode, '#');
if (strlen($hexCode) == 3) {
$hexCode = $hexCode[0] . $hexCode[0] . $hexCode[1] . $hexCode[1] . $hexCode[2] . $hexCode[2];
}
$hexCode = array_map('hexdec', str_split($hexCode, 2));
foreach ($hexCode as & $color) {
$adjustableLimit = $adjustPercent < 0 ? $color : 255 - $color;
$adjustAmount = ceil($adjustableLimit * $adjustPercent);
$color = str_pad(dechex($color + $adjustAmount), 2, '0', STR_PAD_LEFT);
}
return '#' . implode($hexCode);
}

View File

@@ -26,7 +26,7 @@ class LocationsController extends Controller
$allowed_columns = [
'id','name','address','address2','city','state','country','zip','created_at',
'updated_at','manager_id','image',
'assigned_assets_count','users_count','assets_count','currency'];
'assigned_assets_count','users_count','assets_count','currency','ldap_ou'];
$locations = Location::with('parent', 'manager', 'children')->select([
'locations.id',
@@ -42,6 +42,7 @@ class LocationsController extends Controller
'locations.created_at',
'locations.updated_at',
'locations.image',
'locations.ldap_ou',
'locations.currency'
])->withCount('assignedAssets as assigned_assets_count')
->withCount('assets as assets_count')

View File

@@ -15,6 +15,7 @@ use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Notification;
use GuzzleHttp\Client;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Facades\Validator;
class SettingsController extends Controller
{
@@ -93,6 +94,51 @@ class SettingsController extends Controller
return response()->json($message, 200);
}
public function ldaptestlogin(Request $request, LdapAd $ldap)
{
if (Setting::getSettings()->ldap_enabled!='1') {
\Log::debug('LDAP is not enabled. Cannot test.');
return response()->json(['message' => 'LDAP is not enabled, cannot test.'], 400);
}
$rules = array(
'ldaptest_user' => 'required',
'ldaptest_password' => 'required'
);
$validator = Validator::make($request->all(), $rules);
if ($validator->fails()) {
\Log::debug('LDAP Validation test failed.');
$validation_errors = implode(' ',$validator->errors()->all());
return response()->json(['message' => $validator->errors()->all()], 400);
}
\Log::debug('Preparing to test LDAP login');
try {
DB::beginTransaction(); //this was the easiest way to invoke a full test of an LDAP login without adding new users to the DB (which may not be desired)
// $results = $ldap->ldap->auth()->attempt($request->input('ldaptest_username'), $request->input('ldaptest_password'), true);
// can't do this because that's a protected property.
$results = $ldap->ldapLogin($request->input('ldaptest_user'), $request->input('ldaptest_password')); // this would normally create a user on success (if they didn't already exist), but for the transaction
if($results) {
return response()->json(['message' => 'It worked! '. $request->input('ldaptest_user').' successfully binded to LDAP.'], 200);
} else {
return response()->json(['message' => 'Login Failed. '. $request->input('ldaptest_user').' did not successfully bind to LDAP.'], 400);
}
} catch (\Exception $e) {
\Log::debug('Connection failed');
return response()->json(['message' => $e->getMessage()], 400);
} finally {
DB::rollBack(); // ALWAYS rollback, whether success or failure
}
}
public function slacktest(Request $request)
{
@@ -137,7 +183,7 @@ class SettingsController extends Controller
try {
Notification::send(Setting::first(), new MailTest());
return response()->json(['message' => 'Mail sent to '.config('mail.reply_to.address')], 200);
} catch (Exception $e) {
} catch (\Exception $e) {
return response()->json(['message' => $e->getMessage()], 500);
}
}

View File

@@ -167,25 +167,30 @@ class StatuslabelsController extends Controller
{
$this->authorize('view', Statuslabel::class);
$statuslabels = Statuslabel::with('assets')->groupBy('id')->withCount('assets as assets_count')->get();
$statuslabels = Statuslabel::with('assets')
->groupBy('id')
->withCount('assets as assets_count')
->get();
$labels=[];
$points=[];
$colors=[];
$default_color_count = 0;
foreach ($statuslabels as $statuslabel) {
if ($statuslabel->assets_count > 0) {
$labels[]=$statuslabel->name. ' ('.number_format($statuslabel->assets_count).')';
$points[]=$statuslabel->assets_count;
if ($statuslabel->color!='') {
$colors[]=$statuslabel->color;
$colors_array[] = $statuslabel->color;
} else {
$colors_array[] = Helper::defaultChartColors($default_color_count);
$default_color_count++;
}
}
}
$colors_array = array_merge($colors, Helper::chartColors());
$result= [
"labels" => $labels,
"datasets" => [ [

View File

@@ -67,7 +67,9 @@ class UsersController extends Controller
if (($request->filled('deleted')) && ($request->input('deleted')=='true')) {
$users = $users->GetDeleted();
$users = $users->onlyTrashed();
} elseif (($request->filled('all')) && ($request->input('all')=='true')) {
$users = $users->withTrashed();
}
if ($request->filled('company_id')) {

View File

@@ -100,9 +100,9 @@ class AssetMaintenancesController extends Controller
$assetMaintenance = new AssetMaintenance();
$assetMaintenance->supplier_id = $request->input('supplier_id');
$assetMaintenance->is_warranty = $request->input('is_warranty');
$assetMaintenance->cost = e($request->input('cost'));
$assetMaintenance->notes = e($request->input('notes'));
$asset = Asset::find(e($request->input('asset_id')));
$assetMaintenance->cost = $request->input('cost');
$assetMaintenance->notes = $request->input('notes');
$asset = Asset::find($request->input('asset_id'));
if ((!Company::isCurrentUserHasAccess($asset)) && ($asset!=null)) {
return static::getInsufficientPermissionsRedirect();

View File

@@ -5,7 +5,6 @@ namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\SendsPasswordResetEmails;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;
class ForgotPasswordController extends Controller
{
@@ -60,7 +59,7 @@ class ForgotPasswordController extends Controller
*/
$request->validate([
'email' => ['required', 'email', 'max:255'],
'username' => ['required', 'max:255'],
]);
@@ -74,16 +73,16 @@ class ForgotPasswordController extends Controller
*/
$response = $this->broker()->sendResetLink(
array_merge(
$request->only('email'),
$request->only('username'),
['activated' => '1'],
['ldap_import' => '0']
)
);
if ($response === \Password::RESET_LINK_SENT) {
\Log::info('Password reset attempt: User '.$request->input('email').' found, password reset sent');
\Log::info('Password reset attempt: User '.$request->input('username').' WAS found, password reset sent');
} else {
\Log::info('Password reset attempt: User '.$request->input('email').' not found or user is inactive');
\Log::info('Password reset attempt: User matching username '.$request->input('username').' NOT FOUND or user is inactive');
}

View File

@@ -234,6 +234,7 @@ class LoginController extends Controller
if ($user = Auth::user()) {
$user->last_login = \Carbon::now();
$user->activated = 1;
$user->save();
}
// Redirect to the users page

View File

@@ -3,9 +3,13 @@
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use App\Http\Requests\SaveUserRequest;
use App\Models\Setting;
use App\Models\User;
use Illuminate\Foundation\Auth\ResetsPasswords;
use Illuminate\Http\Request;
use Illuminate\Validation\Rule;
use Illuminate\Validation\Validator;
class ResetPasswordController extends Controller
{
@@ -29,6 +33,8 @@ class ResetPasswordController extends Controller
*/
protected $redirectTo = '/';
protected $username = 'username';
/**
* Create a new controller instance.
*
@@ -44,7 +50,7 @@ class ResetPasswordController extends Controller
return [
'token' => 'required',
'username' => 'required',
'password' => 'required|confirmed|'.Setting::passwordComplexityRulesSaving('update'),
'password' => 'confirmed|'.Setting::passwordComplexityRulesSaving('store'),
];
}
@@ -55,7 +61,7 @@ class ResetPasswordController extends Controller
'username', 'password', 'password_confirmation', 'token'
);
}
public function showResetForm(Request $request, $token = null)
{
@@ -67,11 +73,48 @@ class ResetPasswordController extends Controller
);
}
public function reset(Request $request)
{
$messages = [
'password.not_in' => trans('validation.disallow_same_pwd_as_user_fields'),
];
$request->validate($this->rules(), $request->all(), $this->validationErrorMessages());
// Check to see if the user even exists
$user = User::where('username', '=', $request->input('username'))->first();
$broker = $this->broker();
if (strpos(Setting::passwordComplexityRulesSaving('store'), 'disallow_same_pwd_as_user_fields') !== FALSE) {
$request->validate(
[
'password' => 'required|notIn:["'.$user->email.'","'.$user->username.'","'.$user->first_name.'","'.$user->last_name.'"'
], $messages);
}
$response = $broker->reset(
$this->credentials($request), function ($user, $password) {
$this->resetPassword($user, $password);
}
);
return $response == \Password::PASSWORD_RESET
? $this->sendResetResponse($request, $response)
: $this->sendResetFailedResponse($request, $response);
}
protected function sendResetFailedResponse(Request $request, $response)
{
return redirect()->back()
->withInput(['username'=> $request->input('username')])
->withErrors(['username' => trans($response)]);
->withErrors(['username' => trans($response), 'password' => trans($response)]);
}
}
}

View File

@@ -53,8 +53,10 @@ class SamlController extends Controller
if (empty($metadata)) {
return response()->view('errors.403', [], 403);
}
return response($metadata)->header('Content-Type', 'text/xml');
return response()->streamDownload(function () use ($metadata) {
echo $metadata;
}, 'snipe-it-metadata.xml', ['Content-Type' => 'text/xml']);
}
/**

View File

@@ -124,7 +124,7 @@ class ComponentsController extends Controller
}
$min = $component->numCHeckedOut();
$validator = Validator::make($request->all(), [
"qty" => "required|numeric|gt:$min"
"qty" => "required|numeric|min:$min"
]);
if ($validator->fails()) {

View File

@@ -39,7 +39,8 @@ class LicenseFilesController extends Controller
$upload_success = false;
foreach ($request->file('file') as $file) {
$file_name = 'license-'.date('Y-m-d-His').'-'.$file->getBasename().'.'.$file->getClientOriginalExtension();
$file_name = 'license-'.$license->id.'-'.str_random(8).'-'.str_slug(basename($file->getClientOriginalName(), '.'.$file->getClientOriginalExtension())).'.'.$file->getClientOriginalExtension();
$upload_success = $file->storeAs('private_uploads/licenses', $file_name);

View File

@@ -156,6 +156,28 @@ class ProfileController extends Controller
if (!Hash::check($request->input('current_password'), $user->password)) {
$validator->errors()->add('current_password', trans('validation.hashed_pass'));
}
// This checks to make sure that the user's password isn't the same as their username,
// email address, first name or last name (see https://github.com/snipe/snipe-it/issues/8661)
// While this is handled via SaveUserRequest form request in other places, we have to do this manually
// here because we don't have the username, etc form fields available in the profile password change
// form.
// There may be a more elegant way to do this in the future.
// First let's see if that option is enabled in the settings
if (strpos(Setting::passwordComplexityRulesSaving('store'), 'disallow_same_pwd_as_user_fields') !== FALSE) {
if (($request->input('password') == $user->username) ||
($request->input('password') == $user->email) ||
($request->input('password') == $user->first_name) ||
($request->input('password') == $user->last_name))
{
$validator->errors()->add('password', trans('validation.disallow_same_pwd_as_user_fields'));
}
}
});

View File

@@ -217,6 +217,99 @@ class ReportsController extends Controller
}
/**
* Exports the activity report to CSV
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v5.0.7]
* @return \Illuminate\Http\Response
*/
public function postActivityReport(Request $request)
{
ini_set('max_execution_time', 12000);
$this->authorize('reports.view');
\Debugbar::disable();
$response = new StreamedResponse(function () {
\Log::debug('Starting streamed response');
// Open output stream
$handle = fopen('php://output', 'w');
stream_set_timeout($handle, 2000);
$header = [
trans('general.date'),
trans('general.admin'),
trans('general.action'),
trans('general.type'),
trans('general.item'),
'To',
trans('general.notes'),
'Changed',
];
$executionTime = microtime(true) - $_SERVER["REQUEST_TIME_FLOAT"];
\Log::debug('Starting headers: '.$executionTime);
fputcsv($handle, $header);
$executionTime = microtime(true) - $_SERVER["REQUEST_TIME_FLOAT"];
\Log::debug('Added headers: '.$executionTime);
$actionlogs = Actionlog::with('item', 'user', 'target','location')
->orderBy('created_at', 'DESC')
->chunk(20, function($actionlogs) use($handle) {
$executionTime = microtime(true) - $_SERVER["REQUEST_TIME_FLOAT"];
\Log::debug('Walking results: '.$executionTime);
$count = 0;
foreach ($actionlogs as $actionlog) {
$count++;
$target_name = '';
if ($actionlog->target) {
if ($actionlog->targetType()=='user') {
$target_name = $actionlog->target->getFullNameAttribute();
} else {
$target_name = $actionlog->target->getDisplayNameAttribute();
}
}
$row = [
$actionlog->created_at,
($actionlog->user) ? e($actionlog->user->getFullNameAttribute()) : '',
$actionlog->present()->actionType(),
e($actionlog->itemType()),
($actionlog->itemType()=='user') ? $actionlog->filename : e($actionlog->item->getDisplayNameAttribute()),
$target_name,
($actionlog->note) ? e($actionlog->note): '',
$actionlog->log_meta,
];
fputcsv($handle, $row);
}
});
// Close the output stream
fclose($handle);
$executionTime = microtime(true) - $_SERVER["REQUEST_TIME_FLOAT"];
\Log::debug('-- SCRIPT COMPLETED IN '. $executionTime);
}, 200, [
'Content-Type' => 'text/csv',
'Content-Disposition'
=> 'attachment; filename="activity-report-'.date('Y-m-d-his').'.csv"',
]);
return $response;
}
/**
* Displays license report
*

View File

@@ -10,8 +10,7 @@ use App\Models\User;
use App\Notifications\RequestAssetCancelation;
use App\Notifications\RequestAssetNotification;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Input;
use Redirect;
use Illuminate\Http\Request;
/**
* This controller handles all actions related to the ability for users

View File

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

View File

@@ -0,0 +1,58 @@
<?php
namespace App\Http\Middleware;
use Auth;
use App\Models\Asset;
use Closure;
class AssetCountForSidebar
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
try
{
$total_rtd_sidebar = Asset::RTD()->count();
view()->share('total_rtd_sidebar', $total_rtd_sidebar);
} catch (\Exception $e) {
\Log::debug($e);
}
try {
$total_deployed_sidebar = Asset::Deployed()->count();
view()->share('total_deployed_sidebar', $total_deployed_sidebar);
} catch (\Exception $e) {
\Log::debug($e);
}
try {
$total_archived_sidebar = Asset::Archived()->count();
view()->share('total_archived_sidebar', $total_archived_sidebar);
} catch (\Exception $e) {
\Log::debug($e);
}
try {
$total_pending_sidebar = Asset::Pending()->count();
view()->share('total_pending_sidebar', $total_pending_sidebar);
} catch (\Exception $e) {
\Log::debug($e);
}
try {
$total_undeployable_sidebar = Asset::Undeployable()->count();
view()->share('total_undeployable_sidebar', $total_undeployable_sidebar);
} catch (\Exception $e) {
\Log::debug($e);
}
return $next($request);
}
}

View File

@@ -106,7 +106,7 @@ class SecurityHeaders
$csp_policy[] = "connect-src 'self'";
$csp_policy[] = "object-src 'none'";
$csp_policy[] = "font-src 'self' data:";
$csp_policy[] = "img-src 'self' data: ".config('app.url')." https://secure.gravatar.com http://gravatar.com maps.google.com maps.gstatic.com *.googleapis.com";
$csp_policy[] = "img-src 'self' data: ".config('app.url')." ".env('PUBLIC_AWS_URL')." https://secure.gravatar.com http://gravatar.com maps.google.com maps.gstatic.com *.googleapis.com";
$csp_policy = join(';', $csp_policy);
$response->headers->set('Content-Security-Policy', $csp_policy);
}

View File

@@ -24,7 +24,7 @@ class AssetFileRequest extends Request
{
$max_file_size = \App\Helpers\Helper::file_upload_max_size();
return [
'file.*' => 'required|mimes:png,gif,jpg,svg,jpeg,doc,docx,pdf,txt,zip,rar,xls,lic,xml,rtf|max:'.$max_file_size,
'file.*' => 'required|mimes:png,gif,jpg,svg,jpeg,doc,docx,pdf,txt,zip,rar,xls,xlsx,lic,xml,rtf|max:'.$max_file_size,
];
}
}

View File

@@ -70,22 +70,27 @@ class SettingsSamlRequest extends FormRequest
]);
$csr = openssl_csr_new($dn, $pkey, ['digest_alg' => 'sha256']);
$x509 = openssl_csr_sign($csr, null, $pkey, 3650, ['digest_alg' => 'sha256']);
openssl_x509_export($x509, $x509cert);
openssl_pkey_export($pkey, $privateKey);
if ($csr) {
$errors = [];
while (($error = openssl_error_string() !== false)) {
$errors[] = $error;
}
if (!(empty($x509cert) && empty($privateKey))) {
$this->merge([
'saml_sp_x509cert' => $x509cert,
'saml_sp_privatekey' => $privateKey,
]);
$x509 = openssl_csr_sign($csr, null, $pkey, 3650, ['digest_alg' => 'sha256']);
openssl_x509_export($x509, $x509cert);
openssl_pkey_export($pkey, $privateKey);
$errors = [];
while (($error = openssl_error_string() !== false)) {
$errors[] = $error;
}
if (!(empty($x509cert) && empty($privateKey))) {
$this->merge([
'saml_sp_x509cert' => $x509cert,
'saml_sp_privatekey' => $privateKey,
]);
}
} else {
$validator->errors()->add('saml_integration', 'openssl.cnf is missing/invalid');
}
}

View File

@@ -47,6 +47,7 @@ class LocationsTransformer
'assets_count' => (int) $location->assets_count,
'users_count' => (int) $location->users_count,
'currency' => ($location->currency) ? e($location->currency) : null,
'ldap_ou' => ($location->ldap_ou) ? e($location->ldap_ou) : null,
'created_at' => Helper::getFormattedDateObject($location->created_at, 'datetime'),
'updated_at' => Helper::getFormattedDateObject($location->updated_at, 'datetime'),
'parent' => ($location->parent) ? [

View File

@@ -54,7 +54,6 @@ class UsersTransformer
'activated' => ($user->activated =='1') ? true : false,
'two_factor_activated' => ($user->two_factor_active()) ? true : false,
'two_factor_enrolled' => ($user->two_factor_active_and_enrolled()) ? true : false,
'assets_count' => (int) $user->assets_count,
'licenses_count' => (int) $user->licenses_count,
'accessories_count' => (int) $user->accessories_count,
@@ -63,6 +62,7 @@ class UsersTransformer
'created_at' => Helper::getFormattedDateObject($user->created_at, 'datetime'),
'updated_at' => Helper::getFormattedDateObject($user->updated_at, 'datetime'),
'last_login' => Helper::getFormattedDateObject($user->last_login, 'datetime'),
'deleted_at' => ($user->deleted_at) ? Helper::getFormattedDateObject($user->deleted_at, 'datetime') : null,
];
$permissions_array['available_actions'] = [

View File

@@ -130,6 +130,8 @@ class Asset extends Depreciable
'supplier_id',
'warranty_months',
'requestable',
'last_checkout',
'expected_checkin',
];
use Searchable;
@@ -232,7 +234,10 @@ class Asset extends Depreciable
}
/**
* Determines if an asset is available for checkout
* Determines if an asset is available for checkout.
* This checks to see if the it's checked out to an invalid (deleted) user
* OR if the assigned_to and deleted_at fields on the asset are empty AND
* that the status is deployable
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v3.0]
@@ -241,9 +246,10 @@ class Asset extends Depreciable
public function availableForCheckout()
{
if (
(empty($this->assigned_to)) &&
((!$this->assignedTo) && ($this->assetstatus->archived == 0)) ||
((empty($this->assigned_to)) &&
(empty($this->deleted_at)) &&
(($this->assetstatus) && ($this->assetstatus->deployable == 1)))
(($this->assetstatus) && ($this->assetstatus->deployable == 1))))
{
return true;
}
@@ -424,7 +430,7 @@ class Asset extends Depreciable
*/
public function assignedTo()
{
return $this->morphTo('assigned', 'assigned_type', 'assigned_to');
return $this->morphTo('assigned', 'assigned_type', 'assigned_to')->withTrashed();
}
/**

View File

@@ -165,6 +165,8 @@ class Category extends SnipeModel
return $this->components()->count();
case 'consumable':
return $this->consumables()->count();
case 'license':
return $this->licenses()->count();
}
return '0';
}

View File

@@ -76,7 +76,7 @@ class Location extends SnipeModel
*
* @var array
*/
protected $searchableAttributes = ['name', 'address', 'city', 'state', 'zip', 'created_at'];
protected $searchableAttributes = ['name', 'address', 'city', 'state', 'zip', 'created_at', 'ldap_ou'];
/**
* The relations and their attributes that should be included when searching the model.

View File

@@ -26,10 +26,13 @@ class User extends SnipeModel implements AuthenticatableContract, AuthorizableCo
use UniqueUndeletedTrait;
use Notifiable;
use Presentable;
use Searchable;
protected $dates = ['deleted_at'];
protected $hidden = ['password','remember_token','permissions','reset_password_code','persist_code'];
protected $table = 'users';
protected $injectUniqueIdentifier = true;
protected $fillable = [
'activated',
'address',
@@ -67,6 +70,7 @@ class User extends SnipeModel implements AuthenticatableContract, AuthorizableCo
* @var array
*/
// 'username' => 'required|string|min:1|unique:users,username,NULL,id,deleted_at,NULL',
protected $rules = [
'first_name' => 'required|string|min:1',
'username' => 'required|string|min:1|unique_undeleted',
@@ -74,11 +78,10 @@ class User extends SnipeModel implements AuthenticatableContract, AuthorizableCo
'password' => 'required|min:8',
'locale' => 'max:10|nullable',
'website' => 'url|nullable',
'manager_id' => 'nullable|exists:users,id',
'manager_id' => 'nullable|exists:users,id|cant_manage_self',
'location_id' => 'exists:locations,id|nullable',
];
use Searchable;
/**
* The attributes that should be included when searching the model.
@@ -107,7 +110,8 @@ class User extends SnipeModel implements AuthenticatableContract, AuthorizableCo
'groups' => ['name'],
'company' => ['name'],
'manager' => ['first_name', 'last_name', 'username']
];
];
/**
* Check user permissions

View File

@@ -111,7 +111,7 @@ class CheckinAccessoryNotification extends Notification
];
return (new SlackMessage)
->content(':arrow_down: :keyboard: Accessory Checked In')
->content(':arrow_down: :keyboard: '.trans('mail.Accessory_Checkin_Notification'))
->from($botname)
->attachment(function ($attachment) use ($item, $note, $admin, $fields) {
$attachment->title(htmlspecialchars_decode($item->present()->name), $item->present()->viewUrl())
@@ -135,7 +135,7 @@ class CheckinAccessoryNotification extends Notification
'note' => $this->note,
'target' => $this->target,
])
->subject('Accessory checked in');
->subject(trans('mail.Accessory_Checkin_Notification'));
}
}

View File

@@ -79,7 +79,7 @@ class CheckinAssetNotification extends Notification
];
return (new SlackMessage)
->content(':arrow_down: :computer: Asset Checked In')
->content(':arrow_down: :computer: '.trans('mail.Asset_Checkin_Notification'))
->from($botname)
->attachment(function ($attachment) use ($item, $note, $admin, $fields) {
$attachment->title(htmlspecialchars_decode($item->present()->name), $item->present()->viewUrl())
@@ -113,7 +113,7 @@ class CheckinAssetNotification extends Notification
'fields' => $fields,
'expected_checkin' => $this->expected_checkin,
])
->subject('Asset checked in');
->subject(trans('mail.Asset_Checkin_Notification'));
return $message;

View File

@@ -83,7 +83,7 @@ class CheckinLicenseSeatNotification extends Notification
return (new SlackMessage)
->content(':arrow_down: :floppy_disk: License Checked In')
->content(':arrow_down: :floppy_disk: '.trans('mail.License_Checkin_Notification'))
->from($botname)
->attachment(function ($attachment) use ($item, $note, $admin, $fields) {
$attachment->title(htmlspecialchars_decode($item->present()->name), $item->present()->viewUrl())
@@ -106,7 +106,7 @@ class CheckinLicenseSeatNotification extends Notification
'note' => $this->note,
'target' => $this->target,
])
->subject('License checked in');
->subject(trans('mail.License_Checkin_Notification'));
}

View File

@@ -48,7 +48,7 @@ class ExpectedCheckinAdminNotification extends Notification
[
'assets' => $this->assets,
])
->subject('Expected asset checkin report');
->subject(trans('mail.Expected_Checkin_Report'));
return $message;

View File

@@ -2,7 +2,7 @@
namespace App\Notifications;
use Carbon\Carbon;
use App\Helpers\Helper;
use Illuminate\Bus\Queueable;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Notification;
@@ -46,16 +46,18 @@ class ExpectedCheckinNotification extends Notification
*/
public function toMail()
{
$formatted_due = Carbon::parse($this->params->expected_checkin)->format('D, M j, Y');
return (new MailMessage)
->error()
->subject('Reminder: '.$this->params->present()->name().' checkin deadline approaching')
->line('Hi, '.$this->params->assignedto->first_name.' '.$this->params->assignedto->last_name)
->greeting('An asset checked out to you is due to be checked back in on '.$formatted_due.'.')
->line('Asset: '.$this->params->present()->name())
->line('Serial: '.$this->params->serial)
->line('Asset Tag: '.$this->params->asset_tag)
->action('View Your Assets', route('view-assets'));
$message = (new MailMessage)->markdown('notifications.markdown.expected-checkin',
[
'date' => Helper::getFormattedDateObject($this->params->expected_checkin, 'date', false),
'asset' => $this->params->present()->name(),
'serial' => $this->params->serial,
'asset_tag' => $this->params->asset_tag
])
->subject(trans('mail.Expected_Checkin_Notification', ['name' => $this->params->present()->name()]));
return $message;
}
}

View File

@@ -62,11 +62,9 @@ class RequestAssetNotification extends Notification
$notifyBy = [];
if (Setting::getSettings()->slack_endpoint!='') {
\Log::debug('use slack');
$notifyBy[] = 'slack';
}
$notifyBy[] = 'mail';
return $notifyBy;

View File

@@ -123,7 +123,16 @@ class LocationPresenter extends Presenter
"switchable" => true,
"title" => trans('admin/locations/table.country'),
"visible" => false,
],[
],
[
"field" => "ldap_ou",
"searchable" => true,
"sortable" => true,
"switchable" => true,
"title" => trans('admin/locations/table.ldap_ou'),
"visible" => false,
],
[
"field" => "manager",
"searchable" => false,
"sortable" => true,

View File

@@ -87,8 +87,9 @@ class AuthServiceProvider extends ServiceProvider
$this->registerPolicies();
Passport::routes();
Passport::tokensExpireIn(Carbon::now()->addYears(20));
Passport::refreshTokensExpireIn(Carbon::now()->addYears(20));
Passport::tokensExpireIn(Carbon::now()->addYears(config('passport.expiration_years')));
Passport::refreshTokensExpireIn(Carbon::now()->addYears(config('passport.expiration_years')));
Passport::personalAccessTokensExpireIn(Carbon::now()->addYears(config('passport.expiration_years')));
Passport::withCookieSerialization();

View File

@@ -49,7 +49,7 @@ class SamlServiceProvider extends ServiceProvider
'uses' => 'Auth\SamlController@login' ]
);
Route::group(['prefix' => 'admin','middleware' => ['auth', 'authorize:superuser']], function () {
Route::group(['prefix' => 'admin','middleware' => ['web','auth', 'authorize:superuser']], function () {
Route::get('saml', ['as' => 'settings.saml.index','uses' => 'SettingsController@getSamlSettings' ]);
Route::post('saml', ['as' => 'settings.saml.save','uses' => 'SettingsController@postSamlSettings' ]);

View File

@@ -91,6 +91,42 @@ class ValidationServiceProvider extends ServiceProvider
});
// This ONLY works for create/update user forms, since the Update Profile Password form doesn't
// include any of these additional validator fields
Validator::extend('disallow_same_pwd_as_user_fields', function ($attribute, $value, $parameters, $validator) {
$data = $validator->getData();
if (array_key_exists("username", $data)) {
if ($data['username'] == $data['password']) {
return false;
}
}
if (array_key_exists("email", $data)) {
if ($data['email'] == $data['password']) {
return false;
}
}
if (array_key_exists("first_name", $data)) {
if ($data['first_name'] == $data['password']) {
return false;
}
}
if (array_key_exists("last_name", $data)) {
if ($data['last_name'] == $data['password']) {
return false;
}
}
return true;
});
Validator::extend('letters', function ($attribute, $value, $parameters) {
return preg_match('/\pL/', $value);
});
@@ -107,6 +143,27 @@ class ValidationServiceProvider extends ServiceProvider
return preg_match('/\p{Z}|\p{S}|\p{P}/', $value);
});
Validator::extend('cant_manage_self', function ($attribute, $value, $parameters, $validator) {
// $value is the actual *value* of the thing that's being validated
// $attribute is the name of the field that the validation is running on - probably manager_id in our case
// $parameters are the optional parameters - an array for everything, split on commas. But we don't take any params here.
// $validator gives us proper access to the rest of the actual data
$data = $validator->getData();
if(array_key_exists("id", $data)) {
if ($value && $value == $data['id']) {
// if you definitely have an ID - you're saving an existing user - and your ID matches your manager's ID - fail.
return false;
} else {
return true;
}
} else {
// no 'id' key to compare against (probably because this is a new user)
// so it automatically passes this validation
return true;
}
});
}

View File

@@ -23,10 +23,34 @@ use Illuminate\Support\Facades\Log;
*/
class LdapAd extends LdapAdConfiguration
{
/**
* @see https://wdmsb.wordpress.com/2014/12/03/descriptions-of-active-directory-useraccountcontrol-value/
*/
const AD_USER_ACCOUNT_CONTROL_FLAGS = ['512', '544', '66048', '66080', '262656', '262688', '328192', '328224'];
/* The following is _probably_ the correct logic, but we can't use it because
some users may have been dependent upon the previous behavior, and this
could cause additional access to be available to users they don't want
to allow to log in.
$useraccountcontrol = $results[$i]['useraccountcontrol'][0];
if(
// based on MS docs at: https://support.microsoft.com/en-us/help/305144/how-to-use-useraccountcontrol-to-manipulate-user-account-properties
($useraccountcontrol & 0x200) && // is a NORMAL_ACCOUNT
!($useraccountcontrol & 0x02) && // *and* _not_ ACCOUNTDISABLE
!($useraccountcontrol & 0x10) // *and* _not_ LOCKOUT
) {
$user->activated = 1;
} else {
$user->activated = 0;
} */
const AD_USER_ACCOUNT_CONTROL_FLAGS = [
'512', // 0x200 NORMAL_ACCOUNT
'544', // 0x220 NORMAL_ACCOUNT, PASSWD_NOTREQD
'66048', // 0x10200 NORMAL_ACCOUNT, DONT_EXPIRE_PASSWORD
'66080', // 0x10220 NORMAL_ACCOUNT, PASSWD_NOTREQD, DONT_EXPIRE_PASSWORD
'262656', // 0x40200 NORMAL_ACCOUNT, SMARTCARD_REQUIRED
'262688', // 0x40220 NORMAL_ACCOUNT, PASSWD_NOTREQD, SMARTCARD_REQUIRED
'328192', // 0x50200 NORMAL_ACCOUNT, SMARTCARD_REQUIRED, DONT_EXPIRE_PASSWORD
'328224', // 0x50220 NORMAL_ACCOUNT, PASSWD_NOT_REQD, SMARTCARD_REQUIRED, DONT_EXPIRE_PASSWORD
'4260352',// 0x410200 NORMAL_ACCOUNT, DONT_EXPIRE_PASSWORD, DONT_REQ_PREAUTH
'1049088',// 0x100200 NORMAL_ACCOUNT, NOT_DELEGATED
'1114624',// 0x110200 NORMAL_ACCOUNT, NOT_DELEGATED, DONT_EXPIRE_PASSWORD
];
/**
* The LDAP results per page.
@@ -122,9 +146,17 @@ class LdapAd extends LdapAdConfiguration
throw new Exception('Unable to find user in LDAP directory!');
}
return User::where('username', $username)
$user = User::where('username', $username)
->whereNull('deleted_at')->where('ldap_import', '=', 1)
->where('activated', '=', '1')->first();
/* Above, I could've just done ->firstOrFail() which would've been cleaner, but it would've been miserable to
troubleshoot if it ever came up (giving a really generic and untraceable error message)
*/
if (!$user) {
throw new Exception("User is either deleted, not activated (can't log in), not from LDAP, or can't be found in database");
}
return $user;
}
/**
@@ -142,7 +174,7 @@ class LdapAd extends LdapAdConfiguration
*/
public function processUser(AdldapUser $user, ?Collection $defaultLocation=null, ?Collection $mappedLocations=null): ?User
{
// Only sync active users
// Only sync active users <- I think this actually means 'existing', not 'activated/deactivated'
if(!$user) {
return null;
}
@@ -154,8 +186,26 @@ class LdapAd extends LdapAdConfiguration
$snipeUser['email'] = $user->{$this->ldapSettings['ldap_email']}[0] ?? '';
$snipeUser['title'] = $user->getTitle() ?? '';
$snipeUser['telephonenumber'] = $user->getTelephoneNumber() ?? '';
$snipeUser['location_id'] = $this->getLocationId($user, $defaultLocation, $mappedLocations);
$snipeUser['activated'] = $this->getActiveStatus($user);
/*
* $locationId being 'null' means we have no per-OU location information,
* but instead of explicitly setting it to null - which would override any admin-generated
* location assignments - we just don't set it at all. For a brand new User, the 'default null'
* on the column will cover us. For an already existing user, this will not override any
* locations that were explicitly chosen by the administrators.
*
* When syncing with a particular 'default location' in mind, those should still be respected
* and it *will* override the administrators previous choices. I think this is a fair compromise.
*/
$locationId = $this->getLocationId($user, $defaultLocation, $mappedLocations);
if ($locationId !== null ) {
$snipeUser['location_id'] = $locationId;
}
$activeStatus = $this->getActiveStatus($user);
if ($activeStatus !== null) {
$snipeUser['activated'] = $activeStatus;
}
return $this->setUserModel($snipeUser);
}
@@ -185,8 +235,14 @@ class LdapAd extends LdapAdConfiguration
$user->employee_num = trim($userInfo['employee_number']);
$user->jobtitle = trim($userInfo['title']);
$user->phone = trim($userInfo['telephonenumber']);
$user->activated = $userInfo['activated'];
$user->location_id = $userInfo['location_id'];
if(array_key_exists('activated',$userInfo)) {
$user->activated = $userInfo['activated'];
} else if ( !$user->exists ) { // no 'activated' flag was set or unset, *AND* this user is new - activate by default.
$user->activated = 1;
}
if(array_key_exists('location_id',$userInfo)) {
$user->location_id = $userInfo['location_id'];
}
$user->notes = 'Imported from LDAP';
$user->ldap_import = 1;
@@ -252,6 +308,8 @@ class LdapAd extends LdapAdConfiguration
/**
* Set the active status of the user.
* Returns 0 or 1 if the user is deactivated or activated
* or returns null if we just don't know
*
* @author Wes Hulette <jwhulette@gmail.com>
*
@@ -259,22 +317,45 @@ class LdapAd extends LdapAdConfiguration
*
* @param \Adldap\Models\User $user
*
* @return int
* @return int (or null)
*/
private function getActiveStatus(AdldapUser $user): int
private function getActiveStatus(AdldapUser $user): ?int
{
$activeStatus = 0;
/*
* Check to see if we are connected to an AD server
* if so, check the Active Directory User Account Control Flags
* If the admin has set their own 'active flag' - respect that instead
* (this may work to allow AD users to ignore the built-in UAC stuff that AD does)
*/
if ($user->hasAttribute($user->getSchema()->userAccountControl())) {
if ($user->hasAttribute($user->getSchema()->userAccountControl()) && !$this->ldapSettings['ldap_active_flag']) {
\Log::debug('This is AD - userAccountControl is'. $user->getSchema()->userAccountControl());
$activeStatus = (in_array($user->getUserAccountControl(), self::AD_USER_ACCOUNT_CONTROL_FLAGS)) ? 1 : 0;
} else {
// If there is no activated flag, assume this is handled via the OU and activate the users
// If there is no activated flag, then we can't make any determination about activated/deactivated
if (false == $this->ldapSettings['ldap_active_flag']) {
$activeStatus = 1;
\Log::debug('ldap_active_flag is false - no ldap_active_flag is set');
return null;
}
// If there *is* an activated flag, then respect it *only* if it is actually present. If it's not there, ignore it.
if (!$user->hasAttribute($this->ldapSettings['ldap_active_flag'])) {
return null; // 'active' flag is defined, but does not exist on returned user record. So we don't know if they're active or not.
}
// if $user has the flag *AND* that flag has exactly one value -
if ( $user->{$this->ldapSettings['ldap_active_flag']} && count($user->{$this->ldapSettings['ldap_active_flag']}) == 1 ) {
$active_flag_value = $user->{$this->ldapSettings['ldap_active_flag']}[0];
// if the value of that flag is case-insensitively the string 'false' or boolean false
if ( strcasecmp($active_flag_value, "false") == 0 || $active_flag_value === false ) {
return 0; // then make them INACTIVE
} else {
return 1; // otherwise active
}
}
return 1; // fail 'open' (active) if we have the attribute and it's multivalued or empty; that's weird
}
return $activeStatus;
@@ -375,7 +456,7 @@ class LdapAd extends LdapAdConfiguration
{
/** @var Schema $schema */
$schema = new $this->ldapConfig['schema'];
return [
return array_values(array_filter([
$this->ldapSettings['ldap_username_field'],
$this->ldapSettings['ldap_fname_field'],
$this->ldapSettings['ldap_lname_field'],
@@ -386,7 +467,7 @@ class LdapAd extends LdapAdConfiguration
$schema->userAccountControl(),
$schema->title(),
$schema->telephone(),
];
]));
}
/**
@@ -416,7 +497,7 @@ class LdapAd extends LdapAdConfiguration
public function testLdapAdUserConnection(): void
{
try {
$this->ldap->connect(); //uh, this doesn't seem to exist :/
$this->ldap->connect();
} catch (\Adldap\Auth\BindException $e) {
Log::error($e);
throw new Exception('Unable to connect to LDAP directory!');

View File

@@ -5,6 +5,7 @@ namespace App\Services;
use OneLogin\Saml2\Auth as OneLogin_Saml2_Auth;
use OneLogin\Saml2\IdPMetadataParser as OneLogin_Saml2_IdPMetadataParser;
use OneLogin\Saml2\Settings as OneLogin_Saml2_Settings;
use OneLogin\Saml2\Utils as OneLogin_Saml2_Utils;
use App\Models\Setting;
use App\Models\User;
use Exception;
@@ -153,6 +154,9 @@ class Saml
$this->_enabled = $setting->saml_enabled == '1';
if ($this->isEnabled()) {
//Let onelogin/php-saml know to use 'X-Forwarded-*' headers if it is from a trusted proxy
OneLogin_Saml2_Utils::setProxyVars(request()->isFromTrustedProxy());
data_set($settings, 'sp.entityId', url('/'));
data_set($settings, 'sp.assertionConsumerService.url', route('saml.acs'));
data_set($settings, 'sp.singleLogoutService.url', route('saml.sls'));

View File

@@ -65,6 +65,7 @@
"codeception/module-rest": "^1.2",
"codeception/module-webdriver": "^1.0",
"fzaninotto/faker": "^1.9",
"overtrue/phplint": "^2.2",
"phpunit/php-token-stream": "^3.1",
"phpunit/phpunit": "^8.5",
"squizlabs/php_codesniffer": "^3.5",

114
composer.lock generated
View File

@@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "3fe8a441e49d1299687346810b350e00",
"content-hash": "68cf0fb2c06b12c9f8b58efbca2cd72b",
"packages": [
{
"name": "adldap2/adldap2",
@@ -8476,6 +8476,116 @@
],
"time": "2020-01-17T21:11:47+00:00"
},
{
"name": "n98/junit-xml",
"version": "1.0.0",
"source": {
"type": "git",
"url": "https://github.com/cmuench/junit-xml.git",
"reference": "7df0dbaf413fcaa1a63ffbcef18654e7a4cceb46"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/cmuench/junit-xml/zipball/7df0dbaf413fcaa1a63ffbcef18654e7a4cceb46",
"reference": "7df0dbaf413fcaa1a63ffbcef18654e7a4cceb46",
"shasum": ""
},
"require-dev": {
"phpunit/phpunit": "3.7.*"
},
"type": "library",
"autoload": {
"psr-0": {
"N98\\JUnitXml": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Christian Münch",
"email": "c.muench@netz98.de"
}
],
"description": "JUnit XML Document generation library",
"support": {
"issues": "https://github.com/cmuench/junit-xml/issues",
"source": "https://github.com/cmuench/junit-xml/tree/master"
},
"time": "2013-11-23T13:11:26+00:00"
},
{
"name": "overtrue/phplint",
"version": "2.2.0",
"source": {
"type": "git",
"url": "https://github.com/overtrue/phplint.git",
"reference": "dcbb1b9c728de2f05ce6208db7dacb8b3df1c446"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/overtrue/phplint/zipball/dcbb1b9c728de2f05ce6208db7dacb8b3df1c446",
"reference": "dcbb1b9c728de2f05ce6208db7dacb8b3df1c446",
"shasum": ""
},
"require": {
"ext-json": "*",
"n98/junit-xml": "1.0.0",
"php": ">=5.5.9",
"symfony/console": "^3.2|^4.0|^5.0",
"symfony/finder": "^3.0|^4.0|^5.0",
"symfony/process": "^3.3|^4.0|^5.0",
"symfony/yaml": "^3.0|^4.0|^5.0"
},
"require-dev": {
"brainmaestro/composer-git-hooks": "^2.7",
"friendsofphp/php-cs-fixer": "^2.16",
"jakub-onderka/php-console-highlighter": "^0.3.2 || ^0.4"
},
"bin": [
"bin/phplint"
],
"type": "library",
"extra": {
"hooks": {
"pre-commit": [
"composer fix-style"
],
"pre-push": [
"composer check-style"
]
}
},
"autoload": {
"psr-4": {
"Overtrue\\PHPLint\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "overtrue",
"email": "anzhengchao@gmail.com"
}
],
"description": "`phplint` is a tool that can speed up linting of php files by running several lint processes at once.",
"keywords": [
"check",
"lint",
"phplint",
"syntax"
],
"support": {
"issues": "https://github.com/overtrue/phplint/issues",
"source": "https://github.com/overtrue/phplint/tree/2.2.0"
},
"time": "2020-11-04T23:50:40+00:00"
},
{
"name": "phar-io/manifest",
"version": "1.0.3",
@@ -9618,5 +9728,5 @@
"platform-overrides": {
"php": "7.2"
},
"plugin-api-version": "1.1.0"
"plugin-api-version": "2.0.0"
}

View File

@@ -102,7 +102,7 @@ return [
'provider' => 'users',
'email' => 'auth.emails.password',
'table' => 'password_resets',
'expire' => env('LOGIN_LOCKOUT_DURATION', 60),
'expire' => env('RESET_PASSWORD_LINK_EXPIRES', 900),
'throttle' => env('LOGIN_MAX_ATTEMPTS', 60),
],
],
@@ -120,4 +120,5 @@ return [
'password_timeout' => 10800,
];

View File

@@ -48,34 +48,21 @@ return [
*/
'exclude' => [
base_path('vendor'),
base_path('config'),
base_path('node_modules'),
],
/*
* Determines if symlinks should be followed.
*/
'followLinks' => false,
'follow_links' => false,
/*
* Determines if it should avoid unreadable folders.
*/
'ignore_unreadable_directories' => false,
],
/*
* The names of the connections to the databases that should be backed up
* MySQL, PostgreSQL, SQLite and Mongo databases are supported.
*
* The content of the database dump may be customized for each connection
* by adding a 'dump' key to the connection settings in config/database.php.
* E.g.
* 'mysql' => [
* ...
* 'dump' => [
* 'excludeTables' => [
* 'table_to_exclude_from_backup',
* 'another_table_to_exclude'
* ]
* ]
* ],
*
* For a complete list of available customization options, see https://github.com/spatie/db-dumper
*/
'databases' => [
env('DB_CONNECTION', 'mysql'),
],
@@ -117,7 +104,7 @@ return [
/*
* You can get notified when specific events occur. Out of the box you can use 'mail' and 'slack'.
* For Slack you need to install guzzlehttp/guzzle.
* For Slack you need to install guzzlehttp/guzzle and laravel/slack-notification-channel.
*
* You can also use your own notification classes, just make sure the class is named after one of
* the `Spatie\Backup\Events` classes.
@@ -125,12 +112,12 @@ return [
'notifications' => [
'notifications' => [
\Spatie\Backup\Notifications\Notifications\BackupHasFailed::class => ['mail'],
\Spatie\Backup\Notifications\Notifications\UnhealthyBackupWasFound::class => ['mail'],
\Spatie\Backup\Notifications\Notifications\CleanupHasFailed::class => ['mail'],
\Spatie\Backup\Notifications\Notifications\BackupWasSuccessful::class => ['mail'],
\Spatie\Backup\Notifications\Notifications\HealthyBackupWasFound::class => ['mail'],
\Spatie\Backup\Notifications\Notifications\CleanupWasSuccessful::class => ['mail'],
\Spatie\Backup\Notifications\Notifications\BackupHasFailed::class => [env('MAIL_BACKUP_NOTIFICATION_DRIVER', null)],
\Spatie\Backup\Notifications\Notifications\UnhealthyBackupWasFound::class => [env('MAIL_BACKUP_NOTIFICATION_DRIVER', null)],
\Spatie\Backup\Notifications\Notifications\CleanupHasFailed::class => [env('MAIL_BACKUP_NOTIFICATION_DRIVER', null)],
\Spatie\Backup\Notifications\Notifications\BackupWasSuccessful::class => [env('MAIL_BACKUP_NOTIFICATION_DRIVER', null)],
\Spatie\Backup\Notifications\Notifications\HealthyBackupWasFound::class => [env('MAIL_BACKUP_NOTIFICATION_DRIVER', null)],
\Spatie\Backup\Notifications\Notifications\CleanupWasSuccessful::class => [env('MAIL_BACKUP_NOTIFICATION_DRIVER', null)],
],
/*
@@ -163,22 +150,16 @@ return [
* If a backup does not meet the specified requirements the
* UnHealthyBackupWasFound event will be fired.
*/
'monitorBackups' => [
'monitor_backups' => [
[
'name' => config('app.name'),
'disks' => [env('PRIVATE_FILESYSTEM_DISK', 'local')],
'newestBackupsShouldNotBeOlderThanDays' => 1,
'storageUsedMayNotBeHigherThanMegabytes' => 5000,
'health_checks' => [
\Spatie\Backup\Tasks\Monitor\HealthChecks\MaximumAgeInDays::class => 1,
\Spatie\Backup\Tasks\Monitor\HealthChecks\MaximumStorageInMegabytes::class => 5000,
],
],
/*
[
'name' => 'name of the second app',
'disks' => ['local', 's3'],
'newestBackupsShouldNotBeOlderThanDays' => 1,
'storageUsedMayNotBeHigherThanMegabytes' => 5000,
],
*/
],
'cleanup' => [
@@ -193,38 +174,39 @@ return [
*/
'strategy' => \Spatie\Backup\Tasks\Cleanup\Strategies\DefaultStrategy::class,
'defaultStrategy' => [
'default_strategy' => [
/*
* The number of days for which backups must be kept.
*/
'keepAllBackupsForDays' => 7,
'keep_all_backups_for_days' => 7,
/*
* The number of days for which daily backups must be kept.
*/
'keepDailyBackupsForDays' => 16,
'keep_daily_backups_for_days' => 16,
/*
* The number of weeks for which one weekly backup must be kept.
*/
'keepWeeklyBackupsForWeeks' => 8,
'keep_weekly_backups_for_weeks' => 8,
/*
* The number of months for which one monthly backup must be kept.
*/
'keepMonthlyBackupsForMonths' => 3,
'keep_monthly_backups_for_months' => 4,
/*
* The number of years for which one yearly backup must be kept.
*/
'keepYearlyBackupsForYears' => 2,
'keep_yearly_backups_for_years' => 2,
/*
* After cleaning up the backups remove the oldest backup until
* this amount of megabytes has been reached.
*/
'deleteOldestBackupsWhenUsingMoreMegabytesThan' => 5000,
'delete_oldest_backups_when_using_more_megabytes_than' => 5000,
],
],
];
];

View File

@@ -23,6 +23,6 @@ return [
|
*/
'method' => env('MAIL_AUTO_EMBED_METHOD', 'base64'),
'method' => env('MAIL_AUTO_EMBED_METHOD', 'attachment'),
];

View File

@@ -12,4 +12,5 @@ return [
*/
'private_key' => env('PASSPORT_PRIVATE_KEY'),
'public_key' => env('PASSPORT_PUBLIC_KEY'),
'expiration_years' => env('API_TOKEN_EXPIRATION_YEARS', 20),
];

View File

@@ -1,10 +1,10 @@
<?php
return array (
'app_version' => 'v5.0.3',
'full_app_version' => 'v5.0.3 - build 5443-g5f8221470',
'build_version' => '5443',
'app_version' => 'v5.0.9',
'full_app_version' => 'v5.0.9 - build 5616-973eacf6c3',
'build_version' => '5616',
'prerelease_version' => '',
'hash_version' => 'g5f8221470',
'full_hash' => 'v5.0.2-27-g5f8221470',
'hash_version' => '973eacf6c3',
'full_hash' => 'v5.0.9-87-973eacf6c3',
'branch' => 'master',
);

View File

@@ -1,3 +1,8 @@
files:
- source: /resources/lang/en/**/*.php
translation: '**/%original_file_name%'
"commit_message": "Fixed: New translations %original_file_name% from Crowdin"
"files": [
{
"source" : "/resources/lang/en/**/*.php",
"translation" : "/resources/lang/%locale%/%original_file_name%"
}
]

View File

@@ -0,0 +1,32 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class WidenLicenseSerialField extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('licenses', function (Blueprint $table) {
$table->text('serial')->nullable()->default(null)->change();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('licenses', function (Blueprint $table) {
$table->string('serial', 2048)->nullable()->default(null)->change();
});
}
}

50
package-lock.json generated
View File

@@ -4170,7 +4170,8 @@
"ansi-regex": {
"version": "2.1.1",
"bundled": true,
"dev": true
"dev": true,
"optional": true
},
"aproba": {
"version": "1.2.0",
@@ -4191,12 +4192,14 @@
"balanced-match": {
"version": "1.0.0",
"bundled": true,
"dev": true
"dev": true,
"optional": true
},
"brace-expansion": {
"version": "1.1.11",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
@@ -4211,17 +4214,20 @@
"code-point-at": {
"version": "1.1.0",
"bundled": true,
"dev": true
"dev": true,
"optional": true
},
"concat-map": {
"version": "0.0.1",
"bundled": true,
"dev": true
"dev": true,
"optional": true
},
"console-control-strings": {
"version": "1.1.0",
"bundled": true,
"dev": true
"dev": true,
"optional": true
},
"core-util-is": {
"version": "1.0.2",
@@ -4338,7 +4344,8 @@
"inherits": {
"version": "2.0.4",
"bundled": true,
"dev": true
"dev": true,
"optional": true
},
"ini": {
"version": "1.3.5",
@@ -4350,6 +4357,7 @@
"version": "1.0.0",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"number-is-nan": "^1.0.0"
}
@@ -4364,6 +4372,7 @@
"version": "3.0.4",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"brace-expansion": "^1.1.7"
}
@@ -4371,12 +4380,14 @@
"minimist": {
"version": "1.2.5",
"bundled": true,
"dev": true
"dev": true,
"optional": true
},
"minipass": {
"version": "2.9.0",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"safe-buffer": "^5.1.2",
"yallist": "^3.0.0"
@@ -4395,6 +4406,7 @@
"version": "0.5.3",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"minimist": "^1.2.5"
}
@@ -4456,7 +4468,8 @@
"npm-normalize-package-bin": {
"version": "1.0.1",
"bundled": true,
"dev": true
"dev": true,
"optional": true
},
"npm-packlist": {
"version": "1.4.8",
@@ -4484,7 +4497,8 @@
"number-is-nan": {
"version": "1.0.1",
"bundled": true,
"dev": true
"dev": true,
"optional": true
},
"object-assign": {
"version": "4.1.1",
@@ -4496,6 +4510,7 @@
"version": "1.4.0",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"wrappy": "1"
}
@@ -4573,7 +4588,8 @@
"safe-buffer": {
"version": "5.1.2",
"bundled": true,
"dev": true
"dev": true,
"optional": true
},
"safer-buffer": {
"version": "2.1.2",
@@ -4609,6 +4625,7 @@
"version": "1.0.2",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"code-point-at": "^1.0.0",
"is-fullwidth-code-point": "^1.0.0",
@@ -4628,6 +4645,7 @@
"version": "3.0.1",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"ansi-regex": "^2.0.0"
}
@@ -4671,12 +4689,14 @@
"wrappy": {
"version": "1.0.2",
"bundled": true,
"dev": true
"dev": true,
"optional": true
},
"yallist": {
"version": "3.1.1",
"bundled": true,
"dev": true
"dev": true,
"optional": true
}
}
},
@@ -5826,7 +5846,8 @@
},
"js-yaml": {
"version": "3.7.0",
"resolved": "",
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.7.0.tgz",
"integrity": "sha1-XJZ93YN6m/3KXy3oQlOr6KHAO4A=",
"dev": true,
"requires": {
"argparse": "^1.0.7",
@@ -6035,7 +6056,6 @@
"integrity": "sha512-J9X76xnncMw+wIqb15HeWfPMqPwYxSpPY8yWPJ7rAZN/ZDzFkjCSZObryCyUe8zbrVRNiuCnIeQteCzMn7GnWw==",
"requires": {
"canvg": "1.5.3",
"file-saver": "github:eligrey/FileSaver.js#e865e37af9f9947ddcced76b549e27dc45c1cb2e",
"html2canvas": "1.0.0-alpha.12",
"omggif": "1.0.7",
"promise-polyfill": "8.1.0",
@@ -6044,7 +6064,7 @@
"dependencies": {
"file-saver": {
"version": "github:eligrey/FileSaver.js#e865e37af9f9947ddcced76b549e27dc45c1cb2e",
"from": "github:eligrey/FileSaver.js#1.3.8"
"from": "github:eligrey/FileSaver.js#e865e37af9f9947ddcced76b549e27dc45c1cb2e"
}
}
},

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

135
public/css/signature-pad.min.css vendored Executable file
View File

@@ -0,0 +1,135 @@
#signature-pad {
padding-top: 250px;
margin: auto;
}
.m-signature-pad {
position: relative;
font-size: 10px;
width: 100%;
height: 300px;
border: 1px solid #e8e8e8;
background-color: #fff;
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.27), 0 0 40px rgba(0, 0, 0, 0.08) inset;
border-radius: 4px;
}
.m-signature-pad:before, .m-signature-pad:after {
position: absolute;
z-index: -1;
content: "";
width: 40%;
height: 10px;
left: 20px;
bottom: 10px;
background: transparent;
-webkit-transform: skew(-3deg) rotate(-3deg);
-moz-transform: skew(-3deg) rotate(-3deg);
-ms-transform: skew(-3deg) rotate(-3deg);
-o-transform: skew(-3deg) rotate(-3deg);
transform: skew(-3deg) rotate(-3deg);
box-shadow: 0 8px 12px rgba(0, 0, 0, 0.4);
}
.m-signature-pad:after {
left: auto;
right: 20px;
-webkit-transform: skew(3deg) rotate(3deg);
-moz-transform: skew(3deg) rotate(3deg);
-ms-transform: skew(3deg) rotate(3deg);
-o-transform: skew(3deg) rotate(3deg);
transform: skew(3deg) rotate(3deg);
}
.m-signature-pad--body {
position: absolute;
top: 20px;
bottom: 60px;
border: 1px solid #f4f4f4;
background-color: white;
}
.m-signature-pad--body
canvas {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
border-radius: 4px;
box-shadow: 0 0 5px rgba(0, 0, 0, 0.02) inset;
}
.m-signature-pad--footer {
position: absolute;
left: 20px;
right: 20px;
bottom: 20px;
height: 40px;
}
.m-signature-pad--footer
.description {
color: #C3C3C3;
text-align: center;
font-size: 1.2em;
margin-top: 1.8em;
}
.m-signature-pad--footer
.button {
position: absolute;
bottom: 0;
}
.m-signature-pad--footer
.button.clear {
left: 0;
}
.m-signature-pad--footer
.button.save {
right: 0;
}
@media screen and (max-width: 1024px) {
.m-signature-pad {
top: 0;
left: 0;
right: 0;
bottom: 0;
width: auto;
height: auto;
min-width: 250px;
min-height: 140px;
margin: 5%;
}
}
@media screen and (min-device-width: 768px) and (max-device-width: 1024px) {
.m-signature-pad {
margin: 10%;
}
}
@media screen and (max-height: 320px) {
.m-signature-pad--body {
left: 0;
right: 0;
top: 0;
bottom: 32px;
}
.m-signature-pad--footer {
left: 20px;
right: 20px;
bottom: 4px;
height: 28px;
}
.m-signature-pad--footer
.description {
font-size: 1em;
margin-top: 1em;
}
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

60
public/js/dist/all.js vendored

File diff suppressed because one or more lines are too long

View File

@@ -1,5 +1,5 @@
{
"/js/build/app.js": "/js/build/app.js?id=fc54bb0c7977c14f519b",
"/js/build/app.js": "/js/build/app.js?id=648e026d19aa24504e0f",
"/css/build/AdminLTE.css": "/css/build/AdminLTE.css?id=59413334823616b81341",
"/css/build/app.css": "/css/build/app.css?id=032fd8c3fce99c7fd862",
"/css/build/overrides.css": "/css/build/overrides.css?id=0b4aefd7ef0c117ef23a",
@@ -7,32 +7,32 @@
"/css/dist/skins/skin-red.css": "/css/dist/skins/skin-red.css?id=747948e5f269f64047f7",
"/css/dist/skins/skin-contrast.css": "/css/dist/skins/skin-contrast.css?id=d7996d850e8bcdc4e167",
"/css/dist/skins/skin-green.css": "/css/dist/skins/skin-green.css?id=eb25d2ec49f730d09431",
"/css/dist/skins/skin-green-dark.css": "/css/dist/skins/skin-green-dark.css?id=0cfa39cacd9c83b4f53b",
"/css/dist/skins/skin-green-dark.css": "/css/dist/skins/skin-green-dark.css?id=eb4404a7b646ea42e025",
"/css/dist/skins/skin-black.css": "/css/dist/skins/skin-black.css?id=35602987835e5d50d162",
"/css/dist/skins/skin-black-dark.css": "/css/dist/skins/skin-black-dark.css?id=6bd9c2420a41eaf96f0b",
"/css/dist/skins/skin-red-dark.css": "/css/dist/skins/skin-red-dark.css?id=60de5bc2660c35544c4d",
"/css/dist/skins/skin-black-dark.css": "/css/dist/skins/skin-black-dark.css?id=5789dd8af07b08034581",
"/css/dist/skins/skin-red-dark.css": "/css/dist/skins/skin-red-dark.css?id=2e9f90ff200d4e9f45a8",
"/css/dist/skins/skin-purple.css": "/css/dist/skins/skin-purple.css?id=b6dcb6d5c666fc5c8cc0",
"/css/dist/skins/skin-purple-dark.css": "/css/dist/skins/skin-purple-dark.css?id=9dd1dc817a71431e5904",
"/css/dist/skins/skin-purple-dark.css": "/css/dist/skins/skin-purple-dark.css?id=8150adf2e5f70ec3eb00",
"/css/dist/skins/skin-yellow.css": "/css/dist/skins/skin-yellow.css?id=cb85a4e40e784319e878",
"/css/dist/skins/skin-yellow-dark.css": "/css/dist/skins/skin-yellow-dark.css?id=4a19f5ae861f98f40bab",
"/css/dist/skins/skin-yellow-dark.css": "/css/dist/skins/skin-yellow-dark.css?id=5fc4a3cf9407c6a9d398",
"/css/dist/skins/skin-blue-dark.css": "/css/dist/skins/skin-blue-dark.css?id=2f665cf40d7348b3f94c",
"/css/dist/skins/skin-orange-dark.css": "/css/dist/skins/skin-orange-dark.css?id=71c178700d68294e3413",
"/css/dist/skins/skin-orange-dark.css": "/css/dist/skins/skin-orange-dark.css?id=5267e92a8df9ba833e01",
"/css/dist/skins/skin-orange.css": "/css/dist/skins/skin-orange.css?id=b4fc4a74e1f6367dc3e2",
"/css/dist/all.css": "/css/dist/all.css?id=6e3b75006f2b19d69f37",
"/css/blue.png": "/css/blue.png?id=e83a6c29e04fe851f212",
"/css/blue@2x.png": "/css/blue@2x.png?id=51135dd4d24f88f5de0b",
"/css/dist/skins/skin-green-dark.min.css": "/css/dist/skins/skin-green-dark.min.css?id=0cfa39cacd9c83b4f53b",
"/css/dist/skins/skin-black-dark.min.css": "/css/dist/skins/skin-black-dark.min.css?id=6bd9c2420a41eaf96f0b",
"/css/dist/all.css": "/css/dist/all.css?id=199fdf677ce0dce6cef8",
"/css/blue.png": "/css/blue.png?id=4c85d6a97173123bd14a",
"/css/blue@2x.png": "/css/blue@2x.png?id=62c67c6a822439e8a4ac",
"/css/dist/skins/skin-green-dark.min.css": "/css/dist/skins/skin-green-dark.min.css?id=eb4404a7b646ea42e025",
"/css/dist/skins/skin-black-dark.min.css": "/css/dist/skins/skin-black-dark.min.css?id=5789dd8af07b08034581",
"/css/dist/skins/skin-blue-dark.min.css": "/css/dist/skins/skin-blue-dark.min.css?id=2f665cf40d7348b3f94c",
"/css/dist/skins/skin-yellow-dark.min.css": "/css/dist/skins/skin-yellow-dark.min.css?id=4a19f5ae861f98f40bab",
"/css/dist/skins/skin-red-dark.min.css": "/css/dist/skins/skin-red-dark.min.css?id=60de5bc2660c35544c4d",
"/css/dist/skins/skin-purple-dark.min.css": "/css/dist/skins/skin-purple-dark.min.css?id=9dd1dc817a71431e5904",
"/css/dist/skins/skin-orange-dark.min.css": "/css/dist/skins/skin-orange-dark.min.css?id=71c178700d68294e3413",
"/css/dist/skins/skin-yellow-dark.min.css": "/css/dist/skins/skin-yellow-dark.min.css?id=5fc4a3cf9407c6a9d398",
"/css/dist/skins/skin-red-dark.min.css": "/css/dist/skins/skin-red-dark.min.css?id=2e9f90ff200d4e9f45a8",
"/css/dist/skins/skin-purple-dark.min.css": "/css/dist/skins/skin-purple-dark.min.css?id=8150adf2e5f70ec3eb00",
"/css/dist/skins/skin-orange-dark.min.css": "/css/dist/skins/skin-orange-dark.min.css?id=5267e92a8df9ba833e01",
"/css/dist/skins/skin-contrast.min.css": "/css/dist/skins/skin-contrast.min.css?id=d7996d850e8bcdc4e167",
"/css/dist/signature-pad.css": "/css/dist/signature-pad.css?id=6a89d3cd901305e66ced",
"/css/build/signature-pad.min.css": "/css/build/signature-pad.min.css?id=d41d8cd98f00b204e980",
"/css/dist/bootstrap-table.css": "/css/dist/bootstrap-table.css?id=1e77fde04b3f42432581",
"/js/build/vendor.js": "/js/build/vendor.js?id=aff75d5aad5e7b429723",
"/js/build/vendor.js": "/js/build/vendor.js?id=b93877b4a88a76e1b18b",
"/js/dist/bootstrap-table.js": "/js/dist/bootstrap-table.js?id=58d95c93430f2ae33392",
"/js/dist/all.js": "/js/dist/all.js?id=0a2c2c95ab18fa16faa1"
"/js/dist/all.js": "/js/dist/all.js?id=b4627a6533d841cd8fdf"
}

View File

@@ -1,6 +1,6 @@
<template>
<div v-show="processDetail" class="col-md-6 col-md-offset-3">
<div v-show="processDetail" class="col-md-12">
<div class="row">
<div class="dynamic-form-row">
@@ -50,8 +50,7 @@
</div> <!-- /div row -->
<div class="row">
<div class="col-md-2"></div>
<div class="col-md-8" style="padding-top: 30px;">
<div class="col-md-12" style="padding-top: 30px;">
<div class="col-md-4 text-right"><h4>Header Field</h4></div>
<div class="col-md-4"><h4>Import Field</h4></div>
<div class="col-md-4"><h4>Sample Value</h4></div>
@@ -60,8 +59,7 @@
<template v-for="(header, index) in file.header_row">
<div class="row">
<div class="col-md-2"></div>
<div class="col-md-8">
<div class="col-md-12">
<div class="col-md-4 text-right">
<label :for="header" class="control-label">{{ header }}</label>
</div>

View File

@@ -31,8 +31,10 @@
<table class="table table-borderless m-b-none" v-if="tokens.length > 0">
<thead>
<tr>
<th class="col-md-9">Name</th>
<th class="col-md-3"><span class="sr-only">Delete</span></th>
<th class="col-md-3">Name</th>
<th class="col-md-2">Created</th>
<th class="col-md-2">Expires</th>
<th class="col-md-2"><span class="sr-only">Delete</span></th>
</tr>
</thead>
@@ -43,6 +45,14 @@
{{ token.name }}
</td>
<td style="vertical-align: middle;">
{{ token.created_at }}
</td>
<td style="vertical-align: middle;">
{{ token.expires_at }}
</td>
<!-- Delete Button -->
<td style="vertical-align: middle;" class="text-right">
<a class="action-link btn btn-danger btn-sm" @click="revoke(token)">

View File

@@ -131,6 +131,12 @@ a {
background-color: var(--back-main);
color: var(--text-main);
}
.popover {
background-color:var(--back-main);
}
.popover-title {
background-color: #111;
}
a, a:link, a:visited, .btn-primary.hover {
color: var(--header);

View File

@@ -131,6 +131,12 @@ a {
background-color: var(--back-main);
color: var(--text-main);
}
.popover {
background-color:var(--back-main);
}
.popover-title {
background-color: #00a65a;
}
a, a:link, a:visited, .btn-primary.hover {
color: var(--header);

View File

@@ -131,6 +131,12 @@ a {
background-color: var(--back-main);
color: var(--text-main);
}
.popover {
background-color:var(--back-main);
}
.popover-title {
background-color: #ff8c00;
}
a, a:link, a:visited, .btn-primary.hover {
color: var(--header);

View File

@@ -131,6 +131,12 @@ a {
background-color: var(--back-main);
color: var(--text-main);
}
.popover {
background-color:var(--back-main);
}
.popover-title {
background-color: #605ca8;
}
a, a:link, a:visited, .btn-primary.hover {
color: var(--header);

View File

@@ -258,6 +258,12 @@ input[type=text], input[type=search] {
background-color: var(--back-main);
color: var(--header);
}
.popover {
background-color:var(--back-main);
}
.popover-title {
background-color: #dd4b39;
}
.select2-container--default .select2-results__option[aria-selected=true], .select2-container--default .select2-results__option[aria-selected=true]:hover {
background-color: var(--back-sub);
color: var(--header);

View File

@@ -258,6 +258,12 @@ input[type=text], input[type=search] {
background-color: var(--back-main);
color: var(--header);
}
.popover {
background-color:var(--back-main);
}
.popover-title {
background-color: #f39c12;
}
.select2-container--default .select2-results__option[aria-selected=true], .select2-container--default .select2-results__option[aria-selected=true]:hover {
background-color: var(--back-sub);
color: var(--header);

View File

@@ -1,8 +1,6 @@
<?php
return array(
'about_accessories_title' => 'Oor Toebehore',
'about_accessories_text' => 'Toebehore is enigiets wat jy aan gebruikers uitreik, maar dit het nie \'n reeksnommer (of jy gee nie om om hulle unieke te volg nie). Byvoorbeeld, rekenaarmuise of sleutelborde.',
'accessory_category' => 'Toebehore Kategorie',
'accessory_name' => 'Toebehore Naam',
'checkout' => 'Checkout Accessory',

View File

@@ -2,7 +2,7 @@
return array(
'does_not_exist' => 'Die accessoire bestaan nie.',
'does_not_exist' => 'The accessory [:id] does not exist.',
'assoc_users' => 'Hierdie bykomstige het tans: tel items wat uitgekontroleer is aan gebruikers. Kontroleer asseblief die bykomstighede en en probeer weer.',
'create' => array(

View File

@@ -7,5 +7,8 @@
'view' => 'Bekyk Bate Onderhoud Besonderhede',
'repair' => 'herstel',
'maintenance' => 'onderhoud',
'upgrade' => 'opgradering'
'upgrade' => 'opgradering',
'calibration' => 'Calibration',
'software_support' => 'Software Support',
'hardware_support' => 'Hardware Support',
];

View File

@@ -1,8 +1,6 @@
<?php
return array(
'about_categories_title' => 'Oor Kategorieë',
'about_categories' => 'Kategorieë help jou om jou items te organiseer. Sommige voorbeeldkategorieë kan wees &quot;Desktops&quot;, &quot;Laptops&quot;, &quot;Mobile Phones&quot;, &quot;Tablets&quot;, ensovoorts, maar jy kan kategorieë gebruik wat vir jou sin maak.',
'asset_categories' => 'Bate kategorieë',
'category_name' => 'Kategorie Naam',
'checkin_email' => 'Stuur e-pos aan gebruiker by aanmelding/afmelding.',

View File

@@ -1,6 +1,4 @@
<?php
return [
'about_companies_title' => 'Oor Maatskappye',
'about_companies_text' => 'Maatskappye kan gebruik word as \'n eenvoudige identifikasie veld, of kan gebruik word om sigbaarheid van bates, gebruikers, ens beperk as volle maatskappy ondersteuning geaktiveer is in jou Admin instellings.',
'select_company' => 'Kies Maatskappy',
];

View File

@@ -1,8 +1,6 @@
<?php
return array(
'about_components_title' => 'Oor komponente',
'about_components_text' => 'Komponente is items wat deel van \'n bate is, byvoorbeeld HDD, RAM, ens.',
'component_name' => 'Komponentnaam',
'checkin' => 'Checkin-komponent',
'checkout' => 'Afhandelingskomponent',

View File

@@ -1,8 +1,6 @@
<?php
return array(
'about_consumables_title' => 'Oor Verbruiksgoedere',
'about_consumables_text' => 'Verbruiksgoedere word enigiets aangekoop wat oor tyd gebruik sal word. Byvoorbeeld, drukker ink of kopieermapier.',
'checkout' => 'Afhandeling Verbruiker na Gebruiker',
'consumable_name' => 'Verbruikbare Naam',
'create' => 'Skep Verbruik',

View File

@@ -19,6 +19,7 @@ return array(
'status' => 'status',
'title' => 'bate',
'image' => 'Toestelbeeld',
'days_without_acceptance' => 'Dae sonder aanvaarding'
'days_without_acceptance' => 'Dae sonder aanvaarding',
'monthly_depreciation' => 'Monthly Depreciation'
);

View File

@@ -0,0 +1,17 @@
<?php
return array(
'about_kits_title' => 'About Predefined Kits',
'about_kits_text' => 'Predefined Kits let you quickly check out a collection of items (assets, licenses, etc) to a user. This can be helpful when your onboarding process is consistent across many users and all users receive the same items.',
'checkout' => 'Checkout Kit ',
'create_success' => 'Kit was successfully created.',
'create' => 'Create Predefined Kit',
'update' => 'Update Predefined Kit',
'delete_success' => 'Kit was successfully deleted.',
'update_success' => 'Kit was successfully updated.',
'none_models' => 'There are not enough available assets for :model to checkout. :qty are required. ',
'none_licenses' => 'There are not enough available seats for :license to checkout. :qty are required. ',
'none_consumables' => 'There are not enough available units of :consumable to checkout. :qty are required. ',
'none_accessory' => 'There are not enough available units of :accessory to checkout. :qty are required. ',
);

View File

@@ -8,6 +8,7 @@ return array(
'owner_doesnt_match_asset' => 'Die bate wat u met hierdie lisensie probeer assosieer, is in besit van ander as die persoon wat in die opdrag toegeken is.',
'assoc_users' => 'Hierdie lisensie word tans na \'n gebruiker nagegaan en kan nie uitgevee word nie. Gaan asseblief die lisensie eers in, en probeer dan weer uitvee.',
'select_asset_or_person' => 'Jy moet \'n bate of \'n gebruiker kies, maar nie albei nie.',
'not_found' => 'License not found',
'create' => array(

View File

@@ -4,50 +4,60 @@ return array(
'ad' => 'Aktiewe gids',
'ad_domain' => 'Active Directory-domein',
'ad_domain_help' => 'Dit is soms dieselfde as jou e-pos domein, maar nie altyd nie.',
'ad_append_domain_label' => 'Append domain name',
'ad_append_domain' => 'Append domain name to username field',
'ad_append_domain_help' => 'User isn\'t required to write "username@domain.local", they can just type "username".' ,
'admin_cc_email' => 'CC Email',
'admin_cc_email_help' => 'If you would like to send a copy of checkin/checkout emails that are sent to users to an additional email account, enter it here. Otherwise leave this field blank.',
'is_ad' => 'Dit is \'n Active Directory-bediener',
'alert_email' => 'Stuur kennisgewings aan',
'alerts_enabled' => 'Alerts aangeskakel',
'alert_interval' => 'Uitgaande Alert Drempel (in dae)',
'alert_inv_threshold' => 'Voorraadwaarskuwingsdrempel',
'asset_ids' => 'Bate ID\'s',
'audit_interval' => 'Ouditinterval',
'alert_email' => 'Stuur kennisgewings aan',
'alerts_enabled' => 'Alerts aangeskakel',
'alert_interval' => 'Uitgaande Alert Drempel (in dae)',
'alert_inv_threshold' => 'Voorraadwaarskuwingsdrempel',
'asset_ids' => 'Bate ID\'s',
'audit_interval' => 'Ouditinterval',
'audit_interval_help' => 'As u gereeld u bates fisies moet kontroleer, vul die interval in maande in.',
'audit_warning_days' => 'Oudit Waarskuwing Drempel',
'audit_warning_days' => 'Oudit Waarskuwing Drempel',
'audit_warning_days_help' => 'Hoeveel dae vooruit moet ons u waarsku wanneer bates verskuldig is vir ouditering?',
'auto_increment_assets' => 'Genereer outomaties inkrementele bate-ID\'s',
'auto_increment_prefix' => 'Voorvoegsel (opsioneel)',
'auto_incrementing_help' => 'Aktiveer outomaties inkrementering van bate ID\'s om dit te stel',
'backups' => 'rugsteun',
'barcode_settings' => 'Barcode-instellings',
'auto_increment_assets' => 'Genereer outomaties inkrementele bate-ID\'s',
'auto_increment_prefix' => 'Voorvoegsel (opsioneel)',
'auto_incrementing_help' => 'Aktiveer outomaties inkrementering van bate ID\'s om dit te stel',
'backups' => 'rugsteun',
'barcode_settings' => 'Barcode-instellings',
'confirm_purge' => 'Bevestig skoonmaak',
'confirm_purge_help' => 'Tik die teks "DELETE" in die onderstaande blokkie om jou geskrapde rekords te verwyder. Hierdie handeling kan nie ongedaan gemaak word nie.',
'custom_css' => 'Aangepaste CSS',
'custom_css_help' => 'Voer enige aangepaste CSS-oortredings in wat u graag wil gebruik. Moenie die &lt;style&gt;&lt;/style&gt;-etikette insluit nie.',
'confirm_purge_help' => 'Enter the text "DELETE" in the box below to purge your deleted records. This action cannot be undone and will PERMANENTLY delete all soft-deleted items and users. (You should make a backup first, just to be safe.)',
'custom_css' => 'Aangepaste CSS',
'custom_css_help' => 'Voer enige aangepaste CSS-oortredings in wat u graag wil gebruik. Moenie die &lt;style&gt;&lt;/style&gt;-etikette insluit nie.',
'custom_forgot_pass_url' => 'Custom Password Reset URL',
'custom_forgot_pass_url_help' => 'This replaces the built-in forgotten password URL on the login screen, useful to direct people to internal or hosted LDAP password reset functionality. It will effectively disable local user forgotten password functionality.',
'dashboard_message' => 'Dashboard Message',
'dashboard_message_help' => 'This text will appear on the dashboard for anyone with permission to view the dashboard.',
'default_currency' => 'Verstek Geld',
'default_eula_text' => 'Standaard EULA',
'default_language' => 'Verstek taal',
'default_eula_help_text' => 'U kan ook aangepaste EULA\'s aan spesifieke batekategorieë assosieer.',
'default_currency' => 'Verstek Geld',
'default_eula_text' => 'Standaard EULA',
'default_language' => 'Verstek taal',
'default_eula_help_text' => 'U kan ook aangepaste EULA\'s aan spesifieke batekategorieë assosieer.',
'display_asset_name' => 'Wys bate naam',
'display_checkout_date' => 'Vertoon Checkout Date',
'display_eol' => 'Wys EOL in tabelweergawe',
'display_qr' => 'Vertoon vierkante kodes',
'display_alt_barcode' => 'Wys 1D strepieskode',
'barcode_type' => '2D Barcode Type',
'alt_barcode_type' => '1D barcode tipe',
'display_alt_barcode' => 'Wys 1D strepieskode',
'email_logo' => 'Email Logo',
'barcode_type' => '2D Barcode Type',
'alt_barcode_type' => '1D barcode tipe',
'email_logo_size' => 'Square logos in email look best. ',
'eula_settings' => 'EULA-instellings',
'eula_markdown' => 'Hierdie EULA laat <a href="https://help.github.com/articles/github-flavored-markdown/">Github-geurde markdown</a> toe.',
'favicon' => 'Favicon',
'favicon_format' => 'Accepted filetypes are ico, png, and gif. Other image formats may not work in all browsers.',
'favicon_size' => 'Favicons should be square images, 16x16 pixels.',
'footer_text' => 'Additional Footer Text ',
'footer_text_help' => 'This text will appear in the right-side footer. Links are allowed using <a href="https://help.github.com/articles/github-flavored-markdown/">Github flavored markdown</a>. Line breaks, headers, images, etc may result in unpredictable results.',
'general_settings' => 'Algemene instellings',
'generate_backup' => 'Genereer rugsteun',
'generate_backup' => 'Genereer rugsteun',
'header_color' => 'Opskrif Kleur',
'info' => 'Met hierdie instellings kan u sekere aspekte van u installasie aanpas.',
'label_logo' => 'Label Logo',
'label_logo_size' => 'Square logos look best - will be displayed in the top right of each asset label. ',
'laravel' => 'Laravel Weergawe',
'ldap_enabled' => 'LDAP aangeskakel',
'ldap_integration' => 'LDAP-integrasie',
@@ -56,9 +66,9 @@ return array(
'ldap_login_sync_help' => 'This only tests that LDAP can sync correctly. If your LDAP Authentication query is not correct, users may still not be able to login. YOU MUST SAVE YOUR UPDATED LDAP SETTINGS FIRST.',
'ldap_server' => 'LDAP-bediener',
'ldap_server_help' => 'Dit moet begin met ldap: // (vir unencrypted of TLS) of ldaps: // (vir SSL)',
'ldap_server_cert' => 'LDAP SSL-sertifikaat-validering',
'ldap_server_cert_ignore' => 'Laat ongeldige SSL-sertifikaat toe',
'ldap_server_cert_help' => 'Kies hierdie boks as u \'n self-ondertekende SSL-sertifikaat gebruik en graag \'n ongeldige SSL-sertifikaat aanvaar.',
'ldap_server_cert' => 'LDAP SSL-sertifikaat-validering',
'ldap_server_cert_ignore' => 'Laat ongeldige SSL-sertifikaat toe',
'ldap_server_cert_help' => 'Kies hierdie boks as u \'n self-ondertekende SSL-sertifikaat gebruik en graag \'n ongeldige SSL-sertifikaat aanvaar.',
'ldap_tls' => 'Gebruik TLS',
'ldap_tls_help' => 'Dit moet slegs nagegaan word as u STARTTLS op u LDAP-bediener uitvoer.',
'ldap_uname' => 'LDAP Bind Gebruikersnaam',
@@ -73,6 +83,7 @@ return array(
'ldap_auth_filter_query' => 'LDAP-verifikasie navraag',
'ldap_version' => 'LDAP-weergawe',
'ldap_active_flag' => 'LDAP-aktiewe vlag',
'ldap_activated_flag_help' => 'This flag is used to determine whether a user can login to Snipe-IT and does not affect the ability to check items in or out to them.',
'ldap_emp_num' => 'LDAP Werknemersnommer',
'ldap_email' => 'LDAP-e-pos',
'license' => 'Software License',
@@ -87,6 +98,8 @@ return array(
'login_common_disabled_help' => 'This option disables other authentication mechanisms. Just enable this option if you are sure that your REMOTE_USER login is already working',
'login_remote_user_custom_logout_url_text' => 'Custom logout URL',
'login_remote_user_custom_logout_url_help' => 'If a url is provided here, users will get redirected to this URL after the user logs out of Snipe-IT. This is useful to close the user sessions of your Authentication provider correctly.',
'login_remote_user_header_name_text' => 'Custom user name header',
'login_remote_user_header_name_help' => 'Use the specified header instead of REMOTE_USER',
'logo' => 'logo',
'logo_print_assets' => 'Use in Print',
'logo_print_assets_help' => 'Use branding on printable asset lists ',
@@ -101,16 +114,36 @@ return array(
'pwd_secure_complexity' => 'Wagwoord Kompleksiteit',
'pwd_secure_complexity_help' => 'Kies watter wagwoord kompleksiteit reëls jy wil afdwing.',
'pwd_secure_min' => 'Wagwoord minimum karakters',
'pwd_secure_min_help' => 'Minimum toelaatbare waarde is 5',
'pwd_secure_min_help' => 'Minimum permitted value is 8',
'pwd_secure_uncommon' => 'Voorkom algemene wagwoorde',
'pwd_secure_uncommon_help' => 'Dit sal gebruikers nie toelaat om algemene wagwoorde te gebruik van die top 10,000 wagwoorde wat in oortredings gerapporteer is nie.',
'qr_help' => 'Aktiveer QR-kodes eers om dit te stel',
'qr_text' => 'QR Kode Teks',
'saml_enabled' => 'SAML enabled',
'saml_integration' => 'SAML Integration',
'saml_sp_entityid' => 'Entity ID',
'saml_sp_acs_url' => 'Assertion Consumer Service (ACS) URL',
'saml_sp_sls_url' => 'Single Logout Service (SLS) URL',
'saml_sp_x509cert' => 'Public Certificate',
'saml_idp_metadata' => 'SAML IdP Metadata',
'saml_idp_metadata_help' => 'You can specify the IdP metadata using a URL or XML file.',
'saml_attr_mapping_username' => 'Attribute Mapping - Username',
'saml_attr_mapping_username_help' => 'NameID will be used if attribute mapping is unspecified or invalid.',
'saml_forcelogin_label' => 'SAML Force Login',
'saml_forcelogin' => 'Make SAML the primary login',
'saml_forcelogin_help' => 'You can use \'/login?nosaml\' to get to the normal login page.',
'saml_slo_label' => 'SAML Single Log Out',
'saml_slo' => 'Send a LogoutRequest to IdP on Logout',
'saml_slo_help' => 'This will cause the user to be first redirected to the IdP on logout. Leave unchecked if the IdP doesn\'t correctly support SP-initiated SAML SLO.',
'saml_custom_settings' => 'SAML Custom Settings',
'saml_custom_settings_help' => 'You can specify additional settings to the onelogin/php-saml library. Use at your own risk.',
'setting' => 'omgewing',
'settings' => 'instellings',
'show_alerts_in_menu' => 'Show alerts in top menu',
'show_archived_in_list' => 'Archived Assets',
'show_archived_in_list_text' => 'Show archived assets in the "all assets" listing',
'show_assigned_assets' => 'Show assets assigned to assets',
'show_assigned_assets_help' => 'Display assets which were assigned to the other assets in View User -> Assets, View User -> Info -> Print All Assigned and in Account -> View Assigned Assets.',
'show_images_in_email' => 'Show images in emails',
'show_images_in_email_help' => 'Uncheck this box if your Snipe-IT installation is behind a VPN or closed network and users outside the network will not be able to load images served from this installation in their emails.',
'site_name' => 'Site Naam',
@@ -118,7 +151,7 @@ return array(
'slack_channel' => 'Slack Channel',
'slack_endpoint' => 'Slack Endpoint',
'slack_integration' => 'Slack Settings',
'slack_integration_help' => 'Slap integrasie is opsioneel, maar die eindpunt en die kanaal word benodig as u dit wil gebruik. Om Slack integrasie te konfigureer, moet jy eers <a href=":slack_link" target="_new">\'n inkomende webhook</a> op jou Slack-rekening skep.',
'slack_integration_help' => 'Slack integration is optional, however the endpoint and channel are required if you wish to use it. To configure Slack integration, you must first <a href=":slack_link" target="_new" rel="noopener">create an incoming webhook</a> on your Slack account. Click on the <strong>Test Slack Integration</strong> button to confirm your settings are correct before saving. ',
'slack_integration_help_button' => 'Once you have saved your Slack information, a test button will appear.',
'slack_test_help' => 'Test whether your Slack integration is configured correctly. YOU MUST SAVE YOUR UPDATED SLACK SETTINGS FIRST.',
'snipe_version' => 'Snipe-IT-weergawe',
@@ -130,6 +163,7 @@ return array(
'update' => 'Opdateer instellings',
'value' => 'waarde',
'brand' => 'Handelsmerk',
'web_brand' => 'Web Branding Type',
'about_settings_title' => 'Oor instellings',
'about_settings_text' => 'Met hierdie instellings kan u sekere aspekte van u installasie aanpas.',
'labels_per_page' => 'Etikette per bladsy',
@@ -184,4 +218,5 @@ return array(
'unique_serial' => 'Unique serial numbers',
'unique_serial_help_text' => 'Checking this box will enforce a uniqueness constraint on asset serials',
'zerofill_count' => 'Lengte van bate-etikette, insluitend zerofill',
'username_format_help' => 'This setting will only be used by the import process if a username is not provided and we have to generate a username for you.',
);

View File

@@ -19,6 +19,7 @@ return array(
'ldap_config_text' => 'LDAP-konfigurasie-instellings kan Admin> Instellings gevind word. Die (opsionele) gekose ligging sal vir alle ingevoerde gebruikers gestel word.',
'print_assigned' => 'Print All Assigned',
'software_user' => 'Sagteware Uitgesoek na: naam',
'send_email_help' => 'You must provide an email address for this user to send them credentials. Emailing credentials can only be done on user creation. Passwords are stored in a one-way hash and cannot be retrieved once saved.',
'view_user' => 'Sien gebruiker: naam',
'usercsv' => 'CSV-lêer',
'two_factor_admin_optin_help' => 'Jou huidige administrasie-instellings laat selektiewe handhawing van twee-faktor-verifikasie toe.',

View File

@@ -12,6 +12,7 @@ return array(
'insufficient_permissions' => 'Onvoldoende Toestemmings.',
'user_deleted_warning' => 'Hierdie gebruiker is verwyder. Jy sal hierdie gebruiker moet herstel om hulle te wysig of nuwe bates toe te ken.',
'ldap_not_configured' => 'LDAP-integrasie is nie vir hierdie installasie gekonfigureer nie.',
'password_resets_sent' => 'The selected users who are activated and have a valid email addresses have been sent a password reset link.',
'success' => array(

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