Compare commits

...

450 Commits

Author SHA1 Message Date
snipe 4913e56086 Merge remote-tracking branch 'origin/develop'
Signed-off-by: snipe <snipe@snipe.net>

# Conflicts:
#	config/version.php
2024-05-06 18:43:48 +01:00
snipe 4d00bb98d1 Bumped version
Signed-off-by: snipe <snipe@snipe.net>
2024-05-06 18:39:55 +01:00
snipe db2baae758 Merge remote-tracking branch 'origin/develop'
Signed-off-by: snipe <snipe@snipe.net>

# Conflicts:
#	public/css/dist/all.css
#	public/js/dist/bootstrap-table.js
#	public/mix-manifest.json
2024-05-06 18:37:52 +01:00
snipe fdecdf4b15 Merge pull request #14689 from KorvinSzanto/develop
Capitalize `N` instead of `y` since no is default
2024-05-06 17:48:16 +01:00
Korvin Szanto 5c1d4aff23 Capitalize N instead of y since no is default 2024-05-06 09:00:33 -07:00
snipe bf0edcb92e docs: add @gitgrimbo as a contributor 2024-05-06 12:59:26 +01:00
snipe 39fa8ef3c0 docs: add @chandanchowdhury as a contributor 2024-05-06 12:55:47 +01:00
snipe 9e8a369bc8 docs: add @PP-JN-RL as a contributor 2024-05-06 12:54:35 +01:00
snipe 3f3fe8935f docs: add @jeffclay as a contributor 2024-05-06 12:54:20 +01:00
snipe 82387630c7 docs: add @squintfox as a contributor 2024-05-06 12:54:06 +01:00
snipe 16c5033514 docs: add @Q4kK as a contributor 2024-05-06 12:53:34 +01:00
snipe 46ffaee1e4 docs: add @franceslui as a contributor 2024-05-06 12:53:06 +01:00
snipe d936f92a7d docs: add @mustafa-online as a contributor 2024-05-06 12:52:46 +01:00
snipe b424ddf42d docs: add @koiakoia as a contributor 2024-05-06 12:51:40 +01:00
snipe b3d5a893fc Fixed text
via (@koiakoia )

Signed-off-by: snipe <snipe@snipe.net>
2024-05-06 12:49:54 +01:00
snipe 69ea6eebae Merge pull request #14688 from snipe/security/Upgrade-tableexport.jquery.plugin-from-1.28.0-to-1.30.0
[Snyk] Upgrade tableexport.jquery.plugin from 1.28.0 to 1.30.0 #14656
2024-05-06 12:47:01 +01:00
snipe 0892c34125 [Snyk] Upgrade tableexport.jquery.plugin from 1.28.0 to 1.30.0 #14656
Signed-off-by: snipe <snipe@snipe.net>
2024-05-06 12:45:33 +01:00
snipe 52e14d501f Merge pull request #14687 from snipe/security/upgrade_fontawesome_from-6.5.1-to-6.5.2
Upgrade fontawesome from 6.5.1 to 6.5.2
2024-05-06 12:22:50 +01:00
snipe 4d093160fc Upgrade @fortawesome/fontawesome-free from 6.5.1 to 6.5.2 #14647
Signed-off-by: snipe <snipe@snipe.net>
2024-05-06 12:21:34 +01:00
snipe 0bcca99573 Merge pull request #14686 from snipe/security/upgrade_alpine_to_3.13.8
[Snyk] Upgrade alpinejs from 3.13.5 to 3.13.8 #14646
2024-05-06 12:16:00 +01:00
snipe 63516c4a4f [Snyk] Upgrade alpinejs from 3.13.5 to 3.13.8 #14646
Signed-off-by: snipe <snipe@snipe.net>
2024-05-06 12:12:59 +01:00
snipe 19fb79ffff Merge pull request #14661 from ubc-cpsc/bugfix/CVE-2024-32489
Upgrade tecnickcom/tcpdf from version 6.7.4 to 6.7.5 to address the security vulnerability CVE-2024-22640
2024-05-06 11:58:31 +01:00
snipe 02835de13d Merge pull request #14679 from mustafa-online/develop
Improve RTL support
2024-05-04 15:47:14 +01:00
Mustafa Online 55b004d53d Improve RTL support 2024-05-04 13:32:42 +02:00
Mustafa Online c1b72a8ce6 Revert "Improve RTL support"
This reverts commit fa0bea87e6.
2024-05-04 13:31:52 +02:00
Mustafa Online fa0bea87e6 Improve RTL support
I'm starting to make some improvements to RTL support, more PR's to come to address other parts.
2024-05-04 13:17:48 +02:00
snipe d146426dd8 Updated prod assets
Signed-off-by: snipe <snipe@snipe.net>
2024-05-02 14:02:53 +01:00
snipe 1e1782c232 Merge remote-tracking branch 'origin/develop'
Signed-off-by: snipe <snipe@snipe.net>

# Conflicts:
#	public/css/build/app.css
#	public/css/build/overrides.css
#	public/css/dist/all.css
#	public/mix-manifest.json
2024-05-02 14:02:36 +01:00
snipe dab5874fd7 Merge pull request #14391 from snipe/features/add_Brother_188mm_tape_label
Added Brother 18mm label type
2024-05-02 13:14:04 +01:00
snipe 4850227c04 Merge pull request #14655 from snipe/feature/sc-25381/simpler_overdue_endpoints
Refactored due/overdue for audit, added due/overdue for checkin API endpoint and GUI
2024-05-02 13:11:51 +01:00
snipe eb9a654cc3 Moved settings call higher
Signed-off-by: snipe <snipe@snipe.net>
2024-05-02 12:37:41 +01:00
snipe 4224bc0c43 Removed extra settings param
Signed-off-by: snipe <snipe@snipe.net>
2024-05-02 12:36:57 +01:00
snipe f893b23129 Refactored title blade areas
Signed-off-by: snipe <snipe@snipe.net>
2024-05-02 12:35:52 +01:00
snipe 8c65880504 Changed badge to span in default blade
Signed-off-by: snipe <snipe@snipe.net>
2024-05-02 12:35:41 +01:00
snipe 53cadf80fa Removed assertions for factories
Signed-off-by: snipe <snipe@snipe.net>
2024-05-02 12:24:31 +01:00
Frances Lui 8b3bfc6bc9 Fixes CVE-2024-32489 2024-04-29 16:33:00 -07:00
snipe 19cff25300 Merge pull request #14651 from marcusmoore/bug/sc-25402
Fixed `purchase_cost` not being allowed to be a string when creating asset via api
2024-04-27 03:39:10 +01:00
snipe 848e1fe1f6 Refactored audit alerts
Signed-off-by: snipe <snipe@snipe.net>
2024-04-26 21:26:00 +01:00
snipe fe147adec3 Refactor checkin alert
Signed-off-by: snipe <snipe@snipe.net>
2024-04-26 21:10:54 +01:00
snipe 103809b65f Removed debugging
Signed-off-by: snipe <snipe@snipe.net>
2024-04-26 21:01:43 +01:00
snipe a398496dd4 Added comments
Signed-off-by: snipe <snipe@snipe.net>
2024-04-26 21:01:27 +01:00
snipe 839db8ef44 Refactored due-or-overdue methods
Signed-off-by: snipe <snipe@snipe.net>
2024-04-26 20:59:27 +01:00
snipe bfd0530597 Fixed notification
Signed-off-by: snipe <snipe@snipe.net>
2024-04-26 20:59:13 +01:00
snipe 494ec5cd9c Added tests for due-or-overdue
Signed-off-by: snipe <snipe@snipe.net>
2024-04-26 20:59:04 +01:00
snipe fc61a4b88d Fixed badge HTML
Signed-off-by: snipe <snipe@snipe.net>
2024-04-26 19:50:58 +01:00
snipe 50d8b02f8b Removed unused scope
Signed-off-by: snipe <snipe@snipe.net>
2024-04-26 19:23:27 +01:00
snipe 860764a436 Use totals for sidebar
Signed-off-by: snipe <snipe@snipe.net>
2024-04-26 19:12:21 +01:00
snipe 52d6a8990a Check that the asset is not already checked in
Signed-off-by: snipe <snipe@snipe.net>
2024-04-26 19:06:46 +01:00
snipe 87de67e4a9 Fixed test for checkin
Signed-off-by: snipe <snipe@snipe.net>
2024-04-26 19:06:26 +01:00
snipe 8356b57fb4 Added translations
Signed-off-by: snipe <snipe@snipe.net>
2024-04-26 19:01:34 +01:00
snipe 3f04afee5c Removed unused method
Signed-off-by: snipe <snipe@snipe.net>
2024-04-26 19:01:26 +01:00
snipe 2117f61e8c More view sharing for sidebar
Signed-off-by: snipe <snipe@snipe.net>
2024-04-26 19:01:15 +01:00
snipe d40604b574 Removed debugging, added date cast
Signed-off-by: snipe <snipe@snipe.net>
2024-04-26 19:01:05 +01:00
snipe 76129e9011 Use trans_choice for title
Signed-off-by: snipe <snipe@snipe.net>
2024-04-26 18:59:13 +01:00
snipe 9c8411c7ff Added checkin due blade
Signed-off-by: snipe <snipe@snipe.net>
2024-04-26 18:58:56 +01:00
snipe c661d732b3 Refactored sidenav links for audit
Signed-off-by: snipe <snipe@snipe.net>
2024-04-26 18:58:44 +01:00
snipe fbe9daace6 Use pattern in API route
Signed-off-by: snipe <snipe@snipe.net>
2024-04-26 18:58:29 +01:00
snipe 651001bf6e Removed duplicate routes
Signed-off-by: snipe <snipe@snipe.net>
2024-04-26 18:58:15 +01:00
snipe 9167f8a3ba Cleaned up tests
Signed-off-by: snipe <snipe@snipe.net>
2024-04-26 18:57:07 +01:00
snipe 6dc9ccffcd Refactor api for handling audit/expected checkins
Signed-off-by: snipe <snipe@snipe.net>
2024-04-26 18:56:57 +01:00
snipe 4b4e3badb7 Removed hardware audit overdue blade
Signed-off-by: snipe <snipe@snipe.net>
2024-04-26 18:53:36 +01:00
snipe fe4dd23d39 Removed “all” text
Signed-off-by: snipe <snipe@snipe.net>
2024-04-26 15:49:12 +01:00
snipe de6d71cc3b Use plural api endpoints in blades
Signed-off-by: snipe <snipe@snipe.net>
2024-04-26 15:47:19 +01:00
snipe 9e44052709 Switch to plural route name for API endpoint
Signed-off-by: snipe <snipe@snipe.net>
2024-04-26 15:46:58 +01:00
snipe 2d112f227a Call the asset factory directly
Signed-off-by: snipe <snipe@snipe.net>
2024-04-26 15:44:37 +01:00
snipe bd8737d986 Changed sidenav badge class
Signed-off-by: snipe <snipe@snipe.net>
2024-04-26 15:44:21 +01:00
snipe 4b6d236eb7 Added class for sidebar menu badges
Signed-off-by: snipe <snipe@snipe.net>
2024-04-26 15:44:06 +01:00
snipe bf058bd5c6 Use updated scopes
Signed-off-by: snipe <snipe@snipe.net>
2024-04-26 14:02:56 +01:00
snipe dfaf01e8aa Updated asset counters
Signed-off-by: snipe <snipe@snipe.net>
2024-04-26 14:02:47 +01:00
snipe 2888dd6fd8 Added translation
Signed-off-by: snipe <snipe@snipe.net>
2024-04-26 14:02:37 +01:00
snipe 2e92ee8eee Switch to whereBetween so tests run on sqlite
Signed-off-by: snipe <snipe@snipe.net>
2024-04-26 14:02:23 +01:00
snipe 14b6a75507 Updated routes
Signed-off-by: snipe <snipe@snipe.net>
2024-04-26 14:01:38 +01:00
snipe 2484a9db2c Added tests
Signed-off-by: snipe <snipe@snipe.net>
2024-04-26 14:01:29 +01:00
snipe bfc30794c5 Updated badge styling
Signed-off-by: snipe <snipe@snipe.net>
2024-04-26 14:01:22 +01:00
snipe 27bc7a847b Updated routes
Signed-off-by: snipe <snipe@snipe.net>
2024-04-26 14:01:11 +01:00
Marcus Moore 2a71877bec Add additional condition 2024-04-25 17:04:07 -07:00
Marcus Moore 30bd920497 Add conditional 2024-04-25 16:24:12 -07:00
Marcus Moore 1d5b48b88d Add comment and improve method 2024-04-25 16:22:15 -07:00
Marcus Moore 4295bad12f Separate test cases 2024-04-25 14:07:56 -07:00
Marcus Moore 3a2eeaea7a WIP: Future-proof rules being converted to array syntax 2024-04-24 17:40:40 -07:00
Marcus Moore 12418ae91b WIP: allow EU style purchase cost via api 2024-04-24 17:18:29 -07:00
Marcus Moore 783a24eb68 Add test for ParseCurrencyMethod 2024-04-24 17:17:42 -07:00
snipe 2439758ef3 Merge pull request #14587 from Godmartinz/License-export-button
Added a License Export function and button
2024-04-24 04:42:56 +01:00
snipe 685f1cbfb8 Merge pull request #14499 from Godmartinz/remove_encrpyt_from_labels
Removed encrypted fields from label options
2024-04-23 13:31:38 +01:00
snipe e2d1e6b0c5 Merge pull request #14608 from akemidx/bug/sc-25232
Left Sidebar Was Not Respecting Theme
2024-04-23 12:32:48 +01:00
snipe 56cb9a0f4e Merge remote-tracking branch 'origin/develop'
Signed-off-by: snipe <snipe@snipe.net>

# Conflicts:
#	config/version.php
#	public/css/dist/skins/skin-black-dark.css
#	public/css/dist/skins/skin-black-dark.min.css
#	public/css/dist/skins/skin-blue-dark.css
#	public/css/dist/skins/skin-blue-dark.min.css
#	public/css/dist/skins/skin-green-dark.css
#	public/css/dist/skins/skin-green-dark.min.css
#	public/css/dist/skins/skin-orange-dark.css
#	public/css/dist/skins/skin-orange-dark.min.css
#	public/css/dist/skins/skin-purple-dark.css
#	public/css/dist/skins/skin-purple-dark.min.css
#	public/css/dist/skins/skin-red-dark.css
#	public/css/dist/skins/skin-red-dark.min.css
#	public/css/dist/skins/skin-yellow-dark.css
#	public/css/dist/skins/skin-yellow-dark.min.css
#	public/mix-manifest.json
2024-04-23 10:28:50 +01:00
snipe c8c81a360c Dev assets
Signed-off-by: snipe <snipe@snipe.net>
2024-04-23 10:26:43 +01:00
snipe bdd43b7134 Merge pull request #14602 from uberbrady/fix_saving_encrypted_custom_fields
Re-enabled updating encrypted custom fields via API [sc-41465]
2024-04-23 10:20:55 +01:00
snipe c50d5a678a Merge pull request #14616 from akemidx/bug/sc-25235
REMOVED: Dark Theme Button Text Coloring
2024-04-23 09:20:57 +01:00
Godfrey M 96b3af7cbc fixed view from sending all custom fields 2024-04-22 18:27:34 -07:00
Godfrey Martinez 9e7bbc968d Merge pull request #15 from Godmartinz/License-export-button_p2
adds licenses available, updated teranslations
2024-04-22 17:59:52 -07:00
Godfrey M 5fc6771543 adds licenses available, updated teranslations 2024-04-22 17:58:49 -07:00
Marcus Moore 155f5f35cd Remove todo 2024-04-22 15:47:05 -07:00
snipe 7ad6caf30a Merge pull request #14632 from marcusmoore/bug/sc-25384
Added "select" option to top of data sources in new label engine
2024-04-22 20:40:31 +01:00
Marcus Moore ac8aab0043 Add default "select an option" to data source options 2024-04-22 12:22:10 -07:00
Godfrey M 14ddf36d46 removed two duplicate translations 2024-04-22 10:43:11 -07:00
Godfrey M 25f1167c9d adds company scoping to license export 2024-04-22 10:38:55 -07:00
Godfrey M 420225c2d5 Merge branch 'refs/heads/develop' into License-export-button 2024-04-22 10:33:30 -07:00
Marcus Moore 45f5eaac5b Extract CanSkipTests trait 2024-04-22 10:32:37 -07:00
snipe 5229dd65ce Merge remote-tracking branch 'origin/develop' 2024-04-22 15:02:51 +01:00
snipe cfe39afc11 Merge pull request #14630 from snipe/bug/sc-25377/double_encoding_assets_and_model_notes_on_upload
Removed escaping on notes for file uploads
2024-04-22 14:59:55 +01:00
snipe 2aa3ce15bd Removed escaping on notes for file uploads
Signed-off-by: snipe <snipe@snipe.net>
2024-04-22 14:55:02 +01:00
snipe c9873da732 Merge pull request #14628 from snipe/bug/sc-25375/icon_mimetype_validation_fix
Added `ico`, `image/x-icon`, `image/vnd.microsoft.icon` to favicon validation
2024-04-22 13:58:08 +01:00
snipe 8dd71f99cc Added ico, image/x-icon,image/vnd.microsoft.icon to favicon validation
Signed-off-by: snipe <snipe@snipe.net>
2024-04-22 13:54:19 +01:00
Brady Wetherington ab45975883 Mark custom fields tests as 'incomplete' if the DB is mysql 2024-04-22 13:11:36 +01:00
snipe 7f38ca239e Merge remote-tracking branch 'origin/develop'
Signed-off-by: snipe <snipe@snipe.net>

# Conflicts:
#	public/css/build/app.css
#	public/css/build/overrides.css
#	public/css/dist/all.css
#	public/mix-manifest.json
2024-04-19 16:24:32 +01:00
snipe c3b982e759 Merge pull request #14622 from snipe/bug/sc-25363/z-index-bs-table-check-boxes-fix
Reeduced z-index of bs table override
2024-04-19 16:11:21 +01:00
snipe e330e80c46 Reeduced z-index of bs table override
Signed-off-by: snipe <snipe@snipe.net>
2024-04-19 16:06:43 +01:00
akemidx f0836d4d3a changes for button hover, removing text color changes. also added in a border for yellow and black themes 2024-04-18 19:36:35 -04:00
akemidx 1289920217 black button border 2024-04-18 19:29:56 -04:00
snipe a6a58094c9 Merge remote-tracking branch 'origin/develop' 2024-04-18 14:26:53 +01:00
snipe 424cbd3248 Removed noisy debug
Signed-off-by: snipe <snipe@snipe.net>
2024-04-18 14:25:54 +01:00
snipe e59b9627c7 Merge pull request #14511 from jeffclay/features/14508_pdo_ssl_verify
Fixed #14508: Added PDO::MYSQL_ATTR_SSL_VERIFY_SERVER_CERT options to database.php …
2024-04-18 14:23:00 +01:00
snipe f080c0cdcd Merge pull request #14578 from Q4kK/features/add_no_interactive
Feat: add no-interactive flag for `upgrade.php`
2024-04-18 14:19:38 +01:00
snipe 29bda2ef7d Merge pull request #14613 from marcusmoore/additional-test-cases
Added test cases around modifying user groups via api
2024-04-18 13:53:03 +01:00
Marcus Moore 1d64692fd6 Add two test cases 2024-04-17 15:23:26 -07:00
snipe 6f195cb8ec Merge pull request #14591 from snipe/bug/sc-25258/naive_fix_for_user_scoping
First fix for user FMCS scoping
2024-04-17 21:49:53 +01:00
snipe 4c02a63acc Removed activated attribute on test users
Signed-off-by: snipe <snipe@snipe.net>
2024-04-17 20:29:51 +01:00
snipe 0fc9fc7516 Minor updates to tests
Signed-off-by: snipe <snipe@snipe.net>
2024-04-17 20:29:01 +01:00
snipe 4450351b75 Only sync groups if API user is superadmin
Signed-off-by: snipe <snipe@snipe.net>
2024-04-17 11:06:50 +01:00
snipe 9bb15aaf1b Added individual gates to keep response consistent with other company-ed things
Signed-off-by: snipe <snipe@snipe.net>
2024-04-17 10:57:49 +01:00
snipe 65dd729e19 Additional gates
Signed-off-by: snipe <snipe@snipe.net>
2024-04-17 10:57:20 +01:00
snipe c21142605d Added strings
Signed-off-by: snipe <snipe@snipe.net>
2024-04-17 10:47:56 +01:00
snipe 86e274faa3 Added API tests
Signed-off-by: snipe <snipe@snipe.net>
2024-04-17 10:47:48 +01:00
snipe 5e8c129c7f Revert accidental commit
Signed-off-by: snipe <snipe@snipe.net>
2024-04-17 09:26:50 +01:00
snipe ab3b5ca4ef Fixed tests
Signed-off-by: snipe <snipe@snipe.net>
2024-04-17 09:26:07 +01:00
Marcus Moore 60a5afd752 Merge branch 'factory-refactors' into fix_saving_encrypted_custom_fields 2024-04-16 17:15:22 -07:00
Marcus Moore 9d0ea857fe Import facade 2024-04-16 17:14:17 -07:00
Marcus Moore f763aea4fc Update tests to send post request 2024-04-16 17:13:18 -07:00
Marcus Moore e16c04250e Improve model factories 2024-04-16 16:58:28 -07:00
Marcus Moore ad99aa460b Remove unneeded imports 2024-04-16 15:09:49 -07:00
Marcus Moore e47f64f62d Separate test methods 2024-04-16 15:03:05 -07:00
Marcus Moore c6d9da1571 Remove unneeded fields in factory state 2024-04-16 12:36:41 -07:00
Marcus Moore ab561d1ce8 Simplify factory state 2024-04-16 12:36:13 -07:00
akemidx f39ba0136c errant carraige return 2024-04-16 14:26:18 -04:00
akemidx df60045bfe sidebar hover fix 2024-04-16 14:21:47 -04:00
akemidx 5e122f780f sidebar_hover_color 2024-04-16 14:00:20 -04:00
Marcus Moore eefe377159 Correct order of arguments 2024-04-16 10:51:33 -07:00
q4kK 20920c262d Feat: add no-interactive flag for upgrade.php
Having a no-interactive flag is useful because attempting
to automate snipe-it upgrades is currently extremely janky.
You have to either:
  a) read the prompts and pass in the input (the "correct" way)
  b) pipe in input, e.g. `yes` and hope no new prompts
  are added.

With the `no-interactive` flag, this can be fixed by both
allowing new prompts to be added without conflict
to user prompts, but also allowing automated upgrades (you could
choose to crash, or assign defaults).
2024-04-16 11:54:50 -05:00
Brady Wetherington 870612be1c Break 'update' API statements into its own test file. Split tests up 2024-04-16 15:34:28 +01:00
Brady Wetherington 266424ff0e Some simple renames for better readability as suggested by Marcus 2024-04-16 15:17:02 +01:00
snipe a8d48b758e Merge pull request #14594 from marcusmoore/bug/sc-25314/multiple-label-fields-on-one-row
Fixed label fields only showing first option
2024-04-15 18:53:03 +01:00
Brady Wetherington 67a8e0b5c6 This re-enables the ability to update encrypted custom fields via the API 2024-04-15 18:46:11 +01:00
snipe 7b7d424962 Merge pull request #13880 from Godmartinz/department-validation-bug
Fixed department validation to allow updates
2024-04-12 10:50:26 +01:00
Marcus Moore a4e959818a Add comment 2024-04-11 17:23:28 -07:00
Marcus Moore c3a71cc182 Improve variable names and add comment 2024-04-11 16:44:13 -07:00
Marcus Moore da03cfdbe5 Formatting 2024-04-11 16:39:29 -07:00
Marcus Moore 2b137d76fa Trim string to avoid leading whitespace if label is empty 2024-04-11 16:38:22 -07:00
Marcus Moore 81b8c111ca Allow multiple fields to be displayed in one row 2024-04-11 15:00:14 -07:00
snipe fce98b9ca4 Merge remote-tracking branch 'origin/develop'
Signed-off-by: snipe <snipe@snipe.net>

# Conflicts:
#	public/css/dist/skins/skin-black-dark.css
#	public/css/dist/skins/skin-black-dark.min.css
#	public/css/dist/skins/skin-blue-dark.css
#	public/css/dist/skins/skin-blue-dark.min.css
#	public/css/dist/skins/skin-green-dark.css
#	public/css/dist/skins/skin-green-dark.min.css
#	public/css/dist/skins/skin-orange-dark.css
#	public/css/dist/skins/skin-orange-dark.min.css
#	public/css/dist/skins/skin-purple-dark.css
#	public/css/dist/skins/skin-purple-dark.min.css
#	public/css/dist/skins/skin-red-dark.css
#	public/css/dist/skins/skin-red-dark.min.css
#	public/css/dist/skins/skin-yellow-dark.css
#	public/css/dist/skins/skin-yellow-dark.min.css
#	public/mix-manifest.json
2024-04-11 18:58:50 +01:00
snipe c0dcae16f7 Updated dev assets
Signed-off-by: snipe <snipe@snipe.net>
2024-04-11 18:57:06 +01:00
snipe c604f08749 Small tweaks for troubleshooting :(
Signed-off-by: snipe <snipe@snipe.net>
2024-04-11 18:47:55 +01:00
snipe da21424416 Merge pull request #14581 from marcusmoore/bug/sc-25237
Fixed assigned to field in new label engine
2024-04-11 15:36:18 +01:00
snipe b5c83721ad Merge pull request #14577 from Godmartinz/signature_pad_upgrade
Upgraded Signature-pad.js  && Fixed Resizing Canvas on mobile
2024-04-11 15:35:47 +01:00
snipe 9b21fca1a0 Merge pull request #14558 from akemidx/bug/sc-25192
Fixed: Header Dropdown Menus had no hover coloring in dark themes
2024-04-11 15:35:33 +01:00
snipe af94b07771 Merge pull request #14582 from akemidx/feature/sc-25288
Reduce Extra Space in Header Dropdown
2024-04-11 15:35:11 +01:00
snipe 0d23d28a65 Added comments
Signed-off-by: snipe <snipe@snipe.net>
2024-04-11 15:15:56 +01:00
snipe 710370ac24 Added scoping for destroy
Signed-off-by: snipe <snipe@snipe.net>
2024-04-11 14:58:25 +01:00
snipe ed0a441e4d Refactor destroy method
Signed-off-by: snipe <snipe@snipe.net>
2024-04-11 14:52:03 +01:00
snipe 24e87cc0bb Updated comment
Signed-off-by: snipe <snipe@snipe.net>
2024-04-11 14:51:49 +01:00
snipe 460693c153 Added comment
Signed-off-by: snipe <snipe@snipe.net>
2024-04-11 14:40:13 +01:00
snipe f54a94bd4c Refactorered methods
Signed-off-by: snipe <snipe@snipe.net>
2024-04-11 14:40:00 +01:00
snipe a19b86add0 Re-ordered scoping for admins, added comments
Signed-off-by: snipe <snipe@snipe.net>
2024-04-11 14:39:37 +01:00
snipe 570944a48b Updated translation
Signed-off-by: snipe <snipe@snipe.net>
2024-04-11 14:38:52 +01:00
snipe 5829b02323 Added translation
Signed-off-by: snipe <snipe@snipe.net>
2024-04-11 14:38:47 +01:00
Godfrey M a2bca0e358 fixed comments 2024-04-10 15:05:21 -07:00
Godfrey M 133fdd7a37 fix conditional 2024-04-10 12:31:04 -07:00
Godfrey M 0849262243 fixed notes 2024-04-10 12:19:34 -07:00
Godfrey M 17095feb33 fix typo 2024-04-10 12:15:48 -07:00
Godfrey M f42ae46338 exports all licenses 2024-04-10 12:14:44 -07:00
Godfrey M e2679852ce added export button, half the logic for export method 2024-04-10 11:31:30 -07:00
snipe 989dab6259 Moved company scoping methods to group them together
Signed-off-by: snipe <snipe@snipe.net>
2024-04-10 14:35:13 +01:00
snipe adacdc038d Apply company scoping for users
Signed-off-by: snipe <snipe@snipe.net>
2024-04-10 12:34:32 +01:00
akemidx f0aefaac42 padding fix 2024-04-09 17:51:42 -04:00
Marcus Moore 1aeaa0094a Fix assigned to in labels 2024-04-09 13:52:54 -07:00
akemidx 6d3fa12f37 white texty for dropdown lists 2024-04-09 14:52:43 -04:00
Godfrey M 052f1eedd0 fixes signature canvas refresh on mobile 2024-04-09 10:30:33 -07:00
Godfrey M 858da800be attempting to lock screen orientation 2024-04-09 09:40:39 -07:00
snipe 954cac3af7 Merge remote-tracking branch 'origin/develop' 2024-04-08 10:56:04 +01:00
snipe d0f171ebc6 Merge pull request #14567 from snipe/bug/sc-25257
Remove city as required field on location modal
2024-04-08 10:54:09 +01:00
snipe 90cf612ac7 Remove city as required field on location modal
Signed-off-by: snipe <snipe@snipe.net>
2024-04-08 10:50:52 +01:00
snipe 802b5863ab Merge remote-tracking branch 'origin/develop' 2024-04-08 08:49:54 +01:00
snipe 4baa949a99 Merge pull request #14557 from Godmartinz/add-audit-date-to-labels
Added audit dates to label options
2024-04-08 04:59:53 +01:00
snipe 3bed04a6d3 Merge pull request #14559 from Godmartinz/ldap_location_bug
Fixed  ldap location syncing incorrect locations for users.
2024-04-08 04:59:27 +01:00
Godfrey M d548b800d5 nullifies location after ldap user sync 2024-04-04 15:43:33 -07:00
akemidx f7f199d929 black hover bg for dark yellow theme 2024-04-04 15:51:46 -04:00
akemidx 5519fddb78 new clean branch for color change 2024-04-04 15:50:30 -04:00
Godfrey M a9ed748fb2 adds audit dates to label options 2024-04-04 11:39:49 -07:00
snipe dcba2bfd25 Merge pull request #14529 from mauro-miatello/develop
Hide/Show encrypted values in hardware list
2024-04-04 15:07:58 +01:00
snipe 72c91ead8b Merge remote-tracking branch 'origin/develop'
Signed-off-by: snipe <snipe@snipe.net>

# Conflicts:
#	public/css/build/app.css
#	public/css/build/overrides.css
#	public/css/dist/all.css
#	public/mix-manifest.json
2024-04-04 15:06:37 +01:00
snipe 774d0aa90c Updated dev assets
Signed-off-by: snipe <snipe@snipe.net>
2024-04-04 15:05:35 +01:00
snipe 2eea67ce34 Merge pull request #14547 from Godmartinz/user-dropdown-media-change
Fixed alignment of dropdown menu for user in nav bar
2024-04-04 15:04:36 +01:00
snipe db1c44f921 Merge pull request #14552 from snipe/bug/sc-25229/redirect_if_already_checked_in
Redirect on checkin if the asset is already checked in
2024-04-04 15:01:43 +01:00
snipe e11287ec25 Redirect on checkin if the asset is already checked in
Signed-off-by: snipe <snipe@snipe.net>
2024-04-04 15:00:55 +01:00
snipe 4f10adfb76 Merge remote-tracking branch 'origin/develop' 2024-04-04 14:27:35 +01:00
snipe f22803c59f Merge pull request #14551 from snipe/bug/sc-25221/ambiguous_id_in_custom_report
Fixed ambiguous id clause in custom report
2024-04-04 14:25:43 +01:00
snipe a72d4e5dc1 Fixed ambiguous id clause in custom report
Signed-off-by: snipe <snipe@snipe.net>
2024-04-04 14:23:58 +01:00
Godfrey M df5cacf8a2 removed front end if statement 2024-04-03 11:06:05 -07:00
Godfrey M bb2c73348d only grabs custom Fields that are not encrpyted 2024-04-03 11:03:58 -07:00
Godfrey M 4327653d70 remove db cleaner for encrypted selections 2024-04-03 10:57:41 -07:00
Godfrey M 5f7f4c9b91 aligns dropdown menu for user in nav 2024-04-03 10:41:50 -07:00
snipe d44202e55b Merge remote-tracking branch 'origin/develop'
Signed-off-by: snipe <snipe@snipe.net>

# Conflicts:
#	public/css/build/app.css
#	public/css/build/overrides.css
#	public/css/dist/all.css
#	public/mix-manifest.json
2024-04-03 13:09:48 +01:00
snipe df95447ea4 New dev assets
Signed-off-by: snipe <snipe@snipe.net>
2024-04-03 13:08:08 +01:00
snipe 01852c7188 Merge pull request #14520 from Godmartinz/loading_overlap_bug
fixes z-index of table load
2024-04-03 13:07:14 +01:00
snipe 79c5697042 Fixed dev - take 2!
Signed-off-by: snipe <snipe@snipe.net>
2024-04-03 13:06:49 +01:00
MrM 658ba092e2 Hide encrypted values in hardware list
Encrypted values are now hidden also in hardware list, clicking on them show the decrypted value
2024-03-31 18:55:58 +02:00
MrM b221d99e7b Encrypted values enhancement
Show asterisks instead of the value, respecting the length of the field
2024-03-31 12:27:35 +02:00
snipe b7af049589 Merge remote-tracking branch 'origin/develop'
Signed-off-by: snipe <snipe@snipe.net>

# Conflicts:
#	config/version.php
2024-03-29 13:20:22 +00:00
snipe c2d863da99 Bumped version
Signed-off-by: snipe <snipe@snipe.net>
2024-03-29 13:19:22 +00:00
snipe 6f9ba6ede4 Merge remote-tracking branch 'origin/develop' 2024-03-29 12:49:22 +00:00
snipe df4e6a0023 Fixed typo in Polish
I will fix this in CrowdIn shortly

Signed-off-by: snipe <snipe@snipe.net>
2024-03-29 12:47:43 +00:00
snipe d60fa65f85 Merge remote-tracking branch 'origin/develop' 2024-03-28 21:59:36 +00:00
snipe 8081a82fe4 Merge branch 'develop' of https://github.com/snipe/snipe-it into develop 2024-03-28 21:58:58 +00:00
snipe f42e5d5292 Reverting the store/update asset API responses for now
This currently breaks the Jamf integration - need a better longer term plan.

Signed-off-by: snipe <snipe@snipe.net>
2024-03-28 21:58:49 +00:00
snipe 5a3f5b03d0 Merge pull request #14456 from akemidx/feature/sc-25079/legacy-locations
Default Locale value changed to en-US
2024-03-28 21:47:40 +00:00
Godfrey M a450530c74 fixes z-index of table load 2024-03-28 11:44:55 -07:00
snipe 2b4886f37f Commented out Heroic deploy for now 2024-03-28 17:43:18 +00:00
snipe b45de3e17f Update README.md
Added alert notations
2024-03-28 17:41:46 +00:00
snipe b2eea3e5a5 Merge remote-tracking branch 'origin/develop'
Signed-off-by: snipe <snipe@snipe.net>

# Conflicts:
#	public/js/dist/all-defer.js
#	public/mix-manifest.json
2024-03-28 13:02:51 +00:00
snipe f411c0fdd8 Merge pull request #14518 from snipe/fixes/downgrade_alpine
Downgrade alpine to 3.13.5
2024-03-28 12:59:52 +00:00
snipe 74d8431d01 Downgrade alpine to 3.13.5
Signed-off-by: snipe <snipe@snipe.net>
2024-03-28 12:58:43 +00:00
snipe 3ea0cd75a5 Merge remote-tracking branch 'origin/develop' 2024-03-28 12:27:24 +00:00
snipe 5f6c746d25 Merge pull request #14517 from snipe/bug/sc-25186/label_index
Check that the array key exists in the label engine
2024-03-28 12:26:20 +00:00
snipe 1f2d30ebf4 Check that the array key exists
Signed-off-by: snipe <snipe@snipe.net>
2024-03-28 12:25:29 +00:00
snipe 6dd6b45829 Merge remote-tracking branch 'origin/develop' 2024-03-27 20:43:34 +00:00
snipe e5800a2dac Merge pull request #14516 from snipe/fixes/fixed_sorting_on_last_checkin_assets_api
Fixes/fixed sorting on last checkin assets api
2024-03-27 20:39:12 +00:00
snipe 0d3d172108 Make last_checkin searchable and fillable
Signed-off-by: snipe <snipe@snipe.net>
2024-03-27 20:37:40 +00:00
snipe 86677b5f13 Make last_checkin sortable
Signed-off-by: snipe <snipe@snipe.net>
2024-03-27 20:37:25 +00:00
snipe 3f5b94f8ad Merge remote-tracking branch 'origin/develop' 2024-03-27 19:52:23 +00:00
snipe cf8cb8521b Merge pull request #14515 from squintfox/fixes-results-not-limited-by-api-params
Fixes #14289: /reports/activity API endpoint returns too many results due to orwhere
2024-03-27 19:51:58 +00:00
Robert Spadaro ccd00caa70 Wrap where logic in additional where statement to protect appended params 2024-03-27 15:36:00 -04:00
snipe 57010b4c23 Merge pull request #14500 from Godmartinz/add-accessory-signature-to-print-all
Added signature to user print report for Accessories and Consumables
2024-03-27 19:02:59 +00:00
snipe 545a185614 Merge pull request #14262 from akemidx/bug/sc-24812
Last Checkin Date added to Hardware View and Index
2024-03-27 19:02:25 +00:00
snipe 1572e339f9 Merge pull request #14514 from snipe/localizations/new_translations_march_224
Updated translations
2024-03-27 19:01:23 +00:00
snipe 7782e5cc93 Updated translations
Signed-off-by: snipe <snipe@snipe.net>
2024-03-27 18:59:28 +00:00
Jeff Clay 1b8c7ff4ec Added PDO::MYSQL_ATTR_SSL_VERIFY_SERVER_CERT options to database.php and updated .env files to provide value for the new option. 2024-03-27 11:38:13 -05:00
snipe 3bb81d1e4d Merge remote-tracking branch 'origin/develop'
Signed-off-by: snipe <snipe@snipe.net>

# Conflicts:
#	public/js/dist/all-defer.js
#	public/mix-manifest.json
2024-03-27 16:18:28 +00:00
snipe 756c44fcba Merge pull request #14510 from snipe/snyk/Upgrade-alpinejs-from-3.13.5-to-3.13.6
[Snyk] Upgrade alpinejs from 3.13.5 to 3.13.6
2024-03-27 16:14:53 +00:00
snipe befa4428d0 Merge pull request #14509 from snipe/feature/sc-25173/filter_assigned_user_assets_by_category_id
Added ability to filter in user's assigned assets by category ID and model ID
2024-03-27 16:13:51 +00:00
snipe 60c678680a [Snyk] Upgrade alpinejs from 3.13.5 to 3.13.6
Signed-off-by: snipe <snipe@snipe.net>
2024-03-27 16:12:57 +00:00
snipe 8bc9688d71 Added ability to filter on category ID and model ID from user’s asset API
Signed-off-by: snipe <snipe@snipe.net>
2024-03-27 16:04:00 +00:00
Godfrey M aa8af2220c trying to remove an encrypted field but not all fields 2024-03-26 16:10:08 -07:00
akemidx b124b9af4d adding in change to settings table 2024-03-26 16:50:39 -04:00
snipe ae403da8c1 Merge pull request #14502 from marcusmoore/bug/sc-25004/pwd_secure_complexity-validation
Added validation around `pwd_secure_complexity`
2024-03-26 20:05:04 +00:00
Marcus Moore b5b8777c94 Extract translation string 2024-03-26 12:23:57 -07:00
snipe 850f85ff59 Merge pull request #14369 from spencerrlongg/bug/sc-24343
Add new validator for custom field checkboxes and fix asset model default updates
2024-03-26 19:22:29 +00:00
Godfrey M 84cc88831d adds signature for components 2024-03-26 12:18:10 -07:00
Godfrey M f4f9b165a7 moves signature check inside of td 2024-03-26 11:24:34 -07:00
Godfrey M 3222d4c8df adds signature check 2024-03-26 09:18:34 -07:00
Godfrey M 3173ead2e7 adds accessory signature to user print report 2024-03-26 09:11:54 -07:00
Godfrey M 040f826c52 removes encrypted fields as a selectable option for labels 2024-03-26 08:57:18 -07:00
snipe 89d733d442 Merge remote-tracking branch 'origin/develop' 2024-03-26 14:53:24 +00:00
snipe df49e8350f Merge pull request #14498 from snipe/features/limit_report_by_admin
Fixed #14495 - Allow user_id to be passed to limit to only specific admins
2024-03-26 14:52:03 +00:00
snipe 3ced85080a Fixed #14495 - Allow user_id to be passed to limit to only specific admins
Signed-off-by: snipe <snipe@snipe.net>
2024-03-26 14:45:20 +00:00
snipe 0611ab9b4c Merge remote-tracking branch 'origin/develop' 2024-03-26 12:29:39 +00:00
snipe f450cafe3e Fixed missing div
Signed-off-by: snipe <snipe@snipe.net>
2024-03-26 12:29:25 +00:00
snipe 1f29eb1875 Merge pull request #14494 from snipe/features/add_supplier_address_to_licenses
Added supplier details to license view
2024-03-26 12:20:57 +00:00
snipe a4e5ae0938 Removed duplicates
Signed-off-by: snipe <snipe@snipe.net>
2024-03-26 12:20:27 +00:00
snipe 77dacfcc30 Show if deleted supplier
Signed-off-by: snipe <snipe@snipe.net>
2024-03-26 12:19:29 +00:00
snipe 0d9b6eaf71 Added supplier details to license view
Signed-off-by: snipe <snipe@snipe.net>
2024-03-26 12:18:04 +00:00
snipe 7060ffaf34 Merge remote-tracking branch 'origin/develop'
Signed-off-by: snipe <snipe@snipe.net>

# Conflicts:
#	config/version.php
#	public/js/dist/bootstrap-table.js
#	public/mix-manifest.json
2024-03-26 11:17:07 +00:00
snipe 02a37e2f89 Bumped hash
Signed-off-by: snipe <snipe@snipe.net>
2024-03-26 10:16:46 +00:00
snipe 9c1b1bc2b5 Removed fre-order columns - it’s not currently used
Signed-off-by: snipe <snipe@snipe.net>
2024-03-26 10:15:46 +00:00
snipe b34156ca25 Merge remote-tracking branch 'origin/develop'
Signed-off-by: snipe <snipe@snipe.net>

# Conflicts:
#	public/js/dist/bootstrap-table.js
#	public/mix-manifest.json
2024-03-26 09:58:35 +00:00
snipe 61bdb57b5d Merge pull request #14492 from snipe/feature/sc-25142/deeplink_search_urls
Fixed #14483 - adds deeplinking to search/sort/pagination
2024-03-26 09:55:50 +00:00
snipe 9df84e235c Check for config variable
Signed-off-by: snipe <snipe@snipe.net>
2024-03-26 09:54:40 +00:00
snipe 566ba4783e Fixed #14483 - adds deeplinking to search/sort/pagination
Signed-off-by: snipe <snipe@snipe.net>
2024-03-26 09:50:01 +00:00
snipe b41b4b1732 Merge remote-tracking branch 'origin/develop' 2024-03-26 08:48:44 +00:00
snipe ccf9457c45 Merge pull request #14491 from PP-JN-RL/patch-1
Added Dymo Labelwriter 1933081
2024-03-26 08:46:03 +00:00
snipe 53aabdab66 Merge remote-tracking branch 'origin/develop' 2024-03-26 08:33:40 +00:00
snipe 8ff85c952e Fixed labelwriter 2112283 namespace
Signed-off-by: snipe <snipe@snipe.net>
2024-03-26 08:33:30 +00:00
Phil J R afe1cb8234 Create LabelWriter_1933081.php
Added a longer version of the existing label (25 x 54mm vs. 25 x 89mm) due to better availability and to support longer asset names.
2024-03-26 08:29:47 +00:00
snipe bd42505799 Merge remote-tracking branch 'origin/develop' 2024-03-26 08:23:40 +00:00
snipe 6c735c97c6 Merge pull request #14490 from snipe/bug/sc-25141/bad_method_call_model_restore_from_view
Fixed #14482 - bad method call model restore from view
2024-03-26 08:21:27 +00:00
snipe 31a57cdf14 Fixed #14482 - bad method call on restore from view
Signed-off-by: snipe <snipe@snipe.net>
2024-03-26 08:18:59 +00:00
snipe 7ebbef25e7 Standardize button styling
Signed-off-by: snipe <snipe@snipe.net>
2024-03-26 08:18:36 +00:00
Phil J R f836342194 Rename Label_Writer_2112283.php to LabelWriter_2112283.php
Fix the name of LabelWWriter_2112283 to be consistent with the existing one.
2024-03-26 08:16:00 +00:00
spencerrlongg 5cf1a6c300 new validator for radio buttons 2024-03-25 21:03:13 -05:00
Marcus Moore bd506820b7 Display error message 2024-03-25 17:59:39 -07:00
Marcus Moore 5815607924 Add validation for pwd_secure_complexity 2024-03-25 17:45:41 -07:00
spencerrlongg 9b40c9788f rm commented tests 2024-03-25 18:58:49 -05:00
snipe 67b5e9093e Merge pull request #14488 from marcusmoore/bug/pass-last-audit-date-through-for-validation
Handle badly formatted `last_audit_date` in `StoreAssetRequest`
2024-03-25 20:57:20 +00:00
Marcus Moore 57d1c036ec Improve method name 2024-03-25 13:53:30 -07:00
Marcus Moore 71722b753d Little bit of clean up 2024-03-25 13:49:03 -07:00
Marcus Moore a2625c889a Improve comment 2024-03-25 13:48:32 -07:00
Marcus Moore c98b9da612 Pass last_audit_date through for model level validation if not a date 2024-03-25 13:47:24 -07:00
Marcus Moore 675717ff82 Add failing test 2024-03-25 13:46:22 -07:00
snipe 83ef7c6fe8 Merge pull request #14486 from marcusmoore/bug/sc-25139
Fixes `last_audit_date` not being stored via API correctly
2024-03-25 19:49:54 +00:00
Marcus Moore 5f4c964309 Account for last_audit_date not being provided 2024-03-25 12:45:11 -07:00
Marcus Moore 66ba96d531 Set last_audit_date to valid format in StoreAssetRequest 2024-03-25 12:38:12 -07:00
snipe d67b2da064 Merge pull request #14485 from PP-JN-RL/patch-1
Created Dymo LabelWriter Label 2112283
2024-03-25 16:50:10 +00:00
Phil J R e45fd4088f Created Dymo LabelWriter Label 2112283
I have added the layout for the Dymo LabelWriter 2112283 Labels.
They are: DYMO 2112283 DURABLE SMALL MULTI PURPOSE LABELS (160 LABELS) - 25 X 54MM
2024-03-25 16:31:20 +00:00
spencerrlongg 7e4a0eedf0 rm dumb note 2024-03-25 10:46:26 -05:00
snipe 3f812f696d Merge pull request #14472 from snipe/fixes/last_audit_date_via_api
Added validation for last_audit_date and next_audit_date
2024-03-25 14:35:42 +00:00
snipe e9e6f925bf Updated validation
Signed-off-by: snipe <snipe@snipe.net>
2024-03-21 18:34:39 +00:00
snipe 828b84084d Added validation for last_audit_date and next_audit_date
Signed-off-by: snipe <snipe@snipe.net>
2024-03-21 18:29:38 +00:00
snipe a6a0bfacc2 Merge remote-tracking branch 'origin/develop' 2024-03-21 18:03:19 +00:00
snipe c4b7e77498 Merge pull request #14089 from spencerrlongg/bug/escaped_quotes_in_listbox
Use `htmlentities()` instead of `htmlspecialcharacters()` on Custom Field Listbox Values
2024-03-21 12:55:25 +00:00
snipe 91c7180bfd Merge pull request #14469 from snipe/feature/sc-19515/2fa_reset_log
Added 2FA reset log entry
2024-03-21 12:52:22 +00:00
snipe 7c39f516b9 Merge pull request #14421 from marcusmoore/fixes/add-minimal-validation-around-asset-tags
Adds a minimal amount of validation around asset_tags in AssetsController
2024-03-21 00:04:44 +00:00
snipe ce1ddcfcee Merge pull request #14438 from marcusmoore/chore/sc-25071
Removed the need to add `InteractsWithSettings` to each test case
2024-03-21 00:03:34 +00:00
snipe 945e8b402f Only offer the 2FA reset if the user already has 2FA set up
Signed-off-by: snipe <snipe@snipe.net>
2024-03-20 23:52:51 +00:00
snipe 5ed2bd0fb7 Skip the normal edit observer
Signed-off-by: snipe <snipe@snipe.net>
2024-03-20 23:52:22 +00:00
snipe bc908b854d Added icon
Signed-off-by: snipe <snipe@snipe.net>
2024-03-20 23:44:47 +00:00
snipe 2067b1138a Added the log item
Signed-off-by: snipe <snipe@snipe.net>
2024-03-20 23:43:58 +00:00
snipe 1ffbdee156 Updated 2FA text to not be google authenticator specific
Signed-off-by: snipe <snipe@snipe.net>
2024-03-20 23:43:30 +00:00
snipe bd2812cac1 Added new string
Signed-off-by: snipe <snipe@snipe.net>
2024-03-20 23:43:12 +00:00
snipe f2a5eac256 Tightened up 2FA text
Signed-off-by: snipe <snipe@snipe.net>
2024-03-20 23:43:05 +00:00
snipe b4e647dbd1 Merge remote-tracking branch 'origin/develop' 2024-03-20 21:31:04 +00:00
snipe de18e449a6 Merge pull request #14464 from snipe/features/toggle_all_columns
Added "toggle all" to column selector
2024-03-20 21:26:23 +00:00
snipe dce19e0bea Set names and actions to switchable = false
Signed-off-by: snipe <snipe@snipe.net>
2024-03-20 21:25:50 +00:00
snipe 1f586d3102 Removed data-show-columns-toggle-all data attribute
Signed-off-by: snipe <snipe@snipe.net>
2024-03-20 21:25:16 +00:00
snipe e5d01170d2 Fixed locale, added showColumnsToggleAll and minimumCountColumns
Signed-off-by: snipe <snipe@snipe.net>
2024-03-20 21:24:59 +00:00
snipe 0f11963127 Merge remote-tracking branch 'origin/develop' 2024-03-20 19:01:03 +00:00
snipe d8378f2a10 Merge pull request #14468 from snipe/features/added_default_location_to_print_all_assigned
Added default location to print all assigned
2024-03-20 18:57:01 +00:00
snipe a0a5480c97 Added default location to print all assigned
Signed-off-by: snipe <snipe@snipe.net>
2024-03-20 18:55:47 +00:00
snipe 3391108551 Merge remote-tracking branch 'origin/develop' 2024-03-20 12:57:30 +00:00
snipe 52551dad0f Merge pull request #14465 from snipe/features/14460_add_avif_format
Added #14460 add avif format
2024-03-20 12:39:14 +00:00
snipe 321414f6e3 Updated comment
Signed-off-by: snipe <snipe@snipe.net>
2024-03-20 12:38:48 +00:00
snipe 7787fe42c8 Added avif to helpers
Signed-off-by: snipe <snipe@snipe.net>
2024-03-20 12:30:28 +00:00
snipe 3b66912742 Fixed #14460 - added support for avif
Signed-off-by: snipe <snipe@snipe.net>
2024-03-20 12:25:02 +00:00
snipe 278a25c63b Added toggle all to column selector
Signed-off-by: snipe <snipe@snipe.net>
2024-03-20 12:14:41 +00:00
snipe 0d124bb5a1 Fixed indent
Signed-off-by: snipe <snipe@snipe.net>
2024-03-20 12:08:35 +00:00
snipe 417caae589 Added translation
Signed-off-by: snipe <snipe@snipe.net>
2024-03-20 12:07:18 +00:00
snipe 3d306aacc5 Fixed mismatched HTML tag
Signed-off-by: snipe <snipe@snipe.net>
2024-03-20 11:52:51 +00:00
snipe ea4ecaea03 Merge remote-tracking branch 'origin/develop'
Signed-off-by: snipe <snipe@snipe.net>

# Conflicts:
#	public/css/dist/all.css
#	public/css/dist/bootstrap-table.css
#	public/js/dist/bootstrap-table.js
#	public/mix-manifest.json
2024-03-20 11:04:34 +00:00
snipe 6c90f9e395 Merge pull request #14462 from snipe/fixes/small_ui_tweaks_for_country_dropdown
Wider country dropdown
2024-03-20 11:01:39 +00:00
snipe ddf81ba135 Wider country dropdown
Signed-off-by: snipe <snipe@snipe.net>
2024-03-20 11:00:06 +00:00
snipe 8ebb41caa6 Merge pull request #14461 from snipe/security/update_bs_tables
[Snyk] Upgrade bootstrap-table from 1.22.2 to 1.22.3 #14455
2024-03-20 10:39:05 +00:00
snipe faf48b1684 [Snyk] Upgrade bootstrap-table from 1.22.2 to 1.22.3 #14455
Signed-off-by: snipe <snipe@snipe.net>
2024-03-20 10:37:53 +00:00
snipe b8232d205b Merge pull request #14457 from Godmartinz/bulk_delete_locations_bug
Fixed Bulk delete locations bug
2024-03-20 10:35:45 +00:00
Godfrey M 62745923cf fixes API location delete 2024-03-19 15:25:28 -07:00
Godfrey M 090466123f add withCount to query instead 2024-03-19 15:18:18 -07:00
Godfrey M 38a3e36cd6 fixes translation usage 2024-03-19 14:32:21 -07:00
Godfrey M e8dc634a40 fixes translation usage 2024-03-19 14:30:53 -07:00
Godfrey M 0d0984a400 Bulk Delete Locations does not work [sc-25100] 2024-03-19 14:26:40 -07:00
akemidx 8640cad033 was using lcoations and not locale. fixed 2024-03-19 16:11:32 -04:00
akemidx dc29717623 fixing default 2024-03-19 15:51:05 -04:00
snipe 814914924f Merge remote-tracking branch 'origin/develop' 2024-03-19 15:51:07 +00:00
snipe c7083488b2 Merge pull request #14447 from snipe/feature/sc-25020_better_print_view
Add additional options to print all assigned view
2024-03-19 15:01:50 +00:00
snipe 4b4d383509 Removed - it’s for another PR
Signed-off-by: snipe <snipe@snipe.net>
2024-03-19 15:00:26 +00:00
akemidx 3680e04817 migration to set legacy locations to an standardized format 2024-03-18 18:29:59 -04:00
snipe 21e23baa37 Fixed ternary
Signed-off-by: snipe <snipe@snipe.net>
2024-03-18 21:28:46 +00:00
snipe fcd130ae15 Layout improvements
Signed-off-by: snipe <snipe@snipe.net>
2024-03-18 21:17:46 +00:00
Marcus Moore d1dffb84dc Remove InteractsWithSettings trait for remaining tests 2024-03-18 12:33:45 -07:00
Marcus Moore 541350916d Merge branch 'develop' into chore/sc-25071
# Conflicts:
#	tests/Feature/Api/Users/UpdateUserApiTest.php
#	tests/Feature/Notifications/AccessoryWebhookTest.php
#	tests/Feature/Notifications/AssetWebhookTest.php
#	tests/Feature/Notifications/ComponentWebhookTest.php
#	tests/Feature/Notifications/ConsumableWebhookTest.php
#	tests/Feature/Notifications/LicenseWebhookTest.php
2024-03-18 12:33:31 -07:00
snipe 002fd4ce30 Nicer formatting for signoff
Signed-off-by: snipe <snipe@snipe.net>
2024-03-18 13:44:51 +00:00
snipe 7b4ecb275f Use trans choice for language
Signed-off-by: snipe <snipe@snipe.net>
2024-03-18 13:29:01 +00:00
snipe 2df5d3a8ff Fixed column selector
Signed-off-by: snipe <snipe@snipe.net>
2024-03-18 13:06:08 +00:00
snipe 7070bad53b Merge remote-tracking branch 'origin/develop'
Signed-off-by: snipe <snipe@snipe.net>

# Conflicts:
#	public/css/build/app.css
#	public/css/build/overrides.css
#	public/css/dist/all.css
#	public/mix-manifest.json
2024-03-18 12:32:22 +00:00
snipe da62d6af26 Merge pull request #14445 from snipe/fixes/check_for_valid_license_category_on_view_assets
Make sure the category is still valid before displaying on view assets
2024-03-18 12:30:15 +00:00
snipe d0d4d14787 Make sure the category is still valid before displaying on view assets
Signed-off-by: snipe <snipe@snipe.net>
2024-03-18 12:29:00 +00:00
snipe 09d69b214b Merge pull request #14436 from marcusmoore/chore/sc-24901
Organized notification test cases
2024-03-18 12:20:23 +00:00
snipe 0e2aaebda4 Merge pull request #14406 from mauro-miatello/develop
Hide/Show ecnrypted values when click on the lock icon
2024-03-18 12:19:54 +00:00
snipe ec2c58163f Merge pull request #14437 from marcusmoore/chore/sc-25070
Removed dead test code
2024-03-18 12:19:35 +00:00
Marcus Moore a28bee86ba Extract method 2024-03-14 16:33:49 -07:00
Marcus Moore fb64892971 Re-order 2024-03-14 16:26:27 -07:00
Marcus Moore 95ff692b14 Improve InteractsWithSettings name 2024-03-14 15:06:52 -07:00
Marcus Moore 8003615b1f Move InteractsWithSettings to TestCase 2024-03-14 14:15:11 -07:00
Marcus Moore 948dc3c974 Remove duplicate trait 2024-03-14 13:11:53 -07:00
Marcus Moore 1afb724606 Remove commented (and old) test cases 2024-03-14 13:11:43 -07:00
Marcus Moore 451281d833 Delete test cases with only commented code 2024-03-14 13:11:27 -07:00
Marcus Moore 485f11c945 Move trait usage to parent TestCase 2024-03-14 12:56:49 -07:00
Marcus Moore dbc79655b0 Cleanup 2024-03-14 12:02:56 -07:00
Marcus Moore 02f6aa6161 Add group tag for new test case 2024-03-14 11:19:36 -07:00
Marcus Moore 07c5264b41 Organize email check in notifications test 2024-03-14 11:17:47 -07:00
Marcus Moore 7c178a6a78 Merge branch 'develop' into chore/sc-24901
# Conflicts:
#	tests/Feature/Notifications/AssetWebhookTest.php
2024-03-14 11:13:14 -07:00
snipe f56d53d7c1 Prod assets
Signed-off-by: snipe <snipe@snipe.net>
2024-03-14 17:14:33 +00:00
snipe 4cd4a936d8 Updated dev assets
Signed-off-by: snipe <snipe@snipe.net>
2024-03-14 15:43:47 +00:00
snipe 7bae4c39c6 Merge pull request #14401 from uberbrady/fix_locale_warning
Fix [sc-25008] - correct and improve legacy language warnings
2024-03-14 15:42:28 +00:00
snipe d55d95bbea Merge pull request #14415 from Godmartinz/date_picker_z_order
Fixed z-index of date-picker
2024-03-14 15:39:11 +00:00
snipe 5e48d56561 Merge pull request #14427 from marcusmoore/bug/sc-25014
Removes the unused `mediconesystems/livewire-datatables` package
2024-03-14 15:35:53 +00:00
snipe 6a5098fb0c Merge remote-tracking branch 'origin/develop' 2024-03-14 13:26:38 +00:00
snipe 4e835e1772 Merge pull request #14430 from snipe/bug/sc-25066/fixed_requestable_search
Move requestable scope below sorting, etc
2024-03-14 13:25:44 +00:00
snipe cce8cb4f5e Move requestable scope below sorting, etc
Signed-off-by: snipe <snipe@snipe.net>
2024-03-14 13:24:22 +00:00
Marcus Moore 8aed26aab1 Remove unneeded test cases 2024-03-13 16:56:54 -07:00
Marcus Moore 01d5d4c2c8 Improve data provider name 2024-03-13 16:37:50 -07:00
Marcus Moore 592385cb07 Remove mediconesystems/livewire-datatables package 2024-03-13 11:58:03 -07:00
snipe 85123b3e66 Rework print page
Still seeing a weird error tho, not done yet

Signed-off-by: snipe <snipe@snipe.net>
2024-03-13 12:36:17 +00:00
Marcus Moore 0fcf223960 Add minimal validation for asset_tags 2024-03-12 12:00:10 -07:00
Godfrey M bf0bd06f20 put important back 2024-03-11 15:56:53 -07:00
Godfrey M f07b0b6bd7 removed important 2024-03-11 15:54:59 -07:00
Godfrey M 717b26c834 fixes z-index of date-picker 2024-03-11 15:53:59 -07:00
snipe 8bb8eab69b Merge remote-tracking branch 'origin/develop' 2024-03-11 15:00:38 +00:00
snipe 693d1c9452 Merge pull request #14413 from snipe/fixes/deprecation_on_strtoupper
Fixed deprecation warning on `strtoupper()`
2024-03-11 14:59:55 +00:00
snipe b049bb1d5c Check for null on select
Signed-off-by: snipe <snipe@snipe.net>
2024-03-11 14:55:49 +00:00
snipe c5c6b3bbc6 Starting the revised print page
Signed-off-by: snipe <snipe@snipe.net>
2024-03-11 14:23:25 +00:00
snipe 1df56a7cab Merge pull request #14407 from snipe/bug/sc-25019_added_created_at_pivot
Added created_at to license pivot
2024-03-10 16:40:56 +00:00
snipe 3f5cc2507d Used updated_at instead
Signed-off-by: snipe <snipe@snipe.net>
2024-03-10 16:39:49 +00:00
snipe 5a85424295 Added created_at to license pivot
Signed-off-by: snipe <snipe@snipe.net>
2024-03-10 16:33:04 +00:00
snipe a53a8cca74 Merge remote-tracking branch 'origin/develop' 2024-03-10 14:40:41 +00:00
snipe 3fdee881f9 Merge pull request #14404 from snipe/fixes/Uninitialized-string-offset-0-in-labels
Fixed uninitialized offset in labels in new label engine
2024-03-10 14:40:12 +00:00
snipe a289dfaf88 Cleanup
Signed-off-by: snipe <snipe@snipe.net>
2024-03-10 14:33:53 +00:00
MrM 8abd359b5b Script to hide / show encrypted values in web ui
added a function to show/hide encrypted values with a simple trick because ClipboardJS can't copy display:none element's value
2024-03-10 15:18:54 +01:00
MrM 9359809b4f Hide / Show encrypted values in web ui
added a span element to hide encrypted values
2024-03-10 15:09:46 +01:00
snipe cde5502f94 Handle blank labels on asset label fields
Signed-off-by: snipe <snipe@snipe.net>
2024-03-10 14:03:21 +00:00
spencerrlongg 04e0a9d4a5 commented tests for now 2024-03-08 13:14:59 -06:00
snipe 28ec0b8ebb Removed debugging console lines
Signed-off-by: snipe <snipe@snipe.net>
2024-03-08 17:19:31 +00:00
snipe 37dfecf098 Fixed uninitialized offset in labels
Signed-off-by: snipe <snipe@snipe.net>
2024-03-08 16:46:56 +00:00
snipe 9d8ce872a4 Merge remote-tracking branch 'origin/develop' 2024-03-08 14:56:21 +00:00
snipe 07880dfe50 Merge pull request #14400 from snipe/localizations/updated_strings
Updated language strings, added Somali
2024-03-08 14:07:32 +00:00
snipe 7eed9f8542 Added Somali
Signed-off-by: snipe <snipe@snipe.net>
2024-03-08 14:06:21 +00:00
Brady Wetherington a2e70dd6b2 Fix [sc-25008] - correct and improve legacy language warnings
The legacy language warning was misfiring when a user's language
didn't match the APP_LOCALE from .env.

Additionally, we weren't properly warning when the legacy-language
came from Settings or from the user themselves. Both of which should
be impossible but still probably not a bad idea to warn on it, anyways
2024-03-08 14:04:21 +00:00
snipe b9aeded957 Updated strings
Signed-off-by: snipe <snipe@snipe.net>
2024-03-08 14:01:34 +00:00
snipe 7939c691f7 Added Brother 18mm label type
Signed-off-by: snipe <snipe@snipe.net>
2024-03-07 22:04:12 +00:00
spencerrlongg 3a0a13d06d tests written but something not working... 2024-03-05 16:35:06 -06:00
spencerrlongg a251e61d73 rm commented code and add comment 2024-03-05 13:40:44 -06:00
spencerrlongg af06b1cd06 hide encryption option for checkbox and radio 2024-03-05 13:37:30 -06:00
spencerrlongg ad0f873ece rm validation stuff 2024-03-05 11:58:00 -06:00
akemidx eb0657c953 Merge branch 'develop' into bug/sc-24812 2024-02-28 17:22:16 -05:00
Marcus Moore 551354b1bb Add group annotation for tests 2024-02-27 18:05:18 -08:00
Marcus Moore 03b7891edc Remove unneeded factory states 2024-02-27 18:03:53 -08:00
Marcus Moore 8978dff054 Consolidate helpers into trait 2024-02-27 18:01:08 -08:00
Marcus Moore d20844fefa Improve readability by extracting additional helpers 2024-02-27 17:57:12 -08:00
Marcus Moore cd579a04dd Improve readability by extracting fireCheckOutEvent method 2024-02-27 17:52:18 -08:00
Marcus Moore 15b8140bff Fix test helper 2024-02-27 17:48:17 -08:00
Marcus Moore 9a93ad2e06 Remove unneeded factory state 2024-02-27 17:46:27 -08:00
Marcus Moore bd4d3aa52b Improve readability by extracting additional helpers 2024-02-27 17:44:19 -08:00
Marcus Moore bf32ab177f Improve readability by extracting fireCheckInEvent method 2024-02-27 17:37:07 -08:00
Marcus Moore 2ea883aa15 Move Notification::fake() to setUp method 2024-02-27 17:23:30 -08:00
Marcus Moore 43cc296582 Consolidate additional tests 2024-02-27 17:14:35 -08:00
Marcus Moore 4c1aadd74e Improve naming and inline helper 2024-02-27 17:09:22 -08:00
Marcus Moore 7d3719bf70 Consolidate some slack notification tests 2024-02-27 17:07:40 -08:00
Marcus Moore c08164d864 Update test names 2024-02-27 16:48:17 -08:00
Marcus Moore b156aa74a5 Update helper name 2024-02-27 16:45:49 -08:00
spencerrlongg b6fa6cba22 note before switching tasks 2024-02-22 15:01:14 -06:00
spencerrlongg 14358651e4 pushing to test other branches 2024-02-22 13:28:23 -06:00
spencerrlongg 20dbacd22f store good, update needs work 2024-02-21 21:33:34 -06:00
spencerrlongg d67ff54f4b temporary decrypt, almost there 2024-02-20 16:20:03 -06:00
spencerrlongg 26728a85ad this seems to work for patches 2024-02-20 13:18:40 -06:00
spencerrlongg c6d85a1b0b allows arrays on checkbox values 2024-02-20 12:23:24 -06:00
spencerrlongg 115e0fc119 implode submitted arrays to save 2024-02-14 13:15:23 -06:00
spencerrlongg 1ceb703129 rm var 2024-02-14 12:44:09 -06:00
spencerrlongg fb28882f65 trim potential spaces 2024-02-14 11:59:14 -06:00
spencerrlongg d9c61fdb02 validation msg 2024-02-14 11:52:25 -06:00
spencerrlongg 72c118a70f cleanup 2024-02-14 11:41:46 -06:00
spencerrlongg 25241542d2 progress, going to sleep 2024-02-14 02:12:31 -06:00
spencerrlongg 57a75e68b9 maybe i do the inverse here? 2024-02-14 00:52:50 -06:00
spencerrlongg dcf2168454 initial stuff, need to switch branches 2024-02-13 19:35:37 -06:00
akemidx c5e8d1c276 custom report tinker 2024-02-13 17:09:51 -05:00
akemidx 4093327b7f adding in Last Checkin Date to Hardware view and index 2024-02-13 16:52:12 -05:00
spencerrlongg d55358652b cleanup for pr 2024-02-13 13:45:56 -06:00
spencerrlongg bcfa913450 condition makes this work, needs more testing 2024-02-07 20:03:37 -06:00
spencerrlongg 43d8474caa a note to remember this tomorrow 2024-02-06 17:45:46 -06:00
spencerrlongg 1248260df3 i don't think the output needs to separately escaped, the entire statement is already wrapped in {{}} 2024-01-26 12:33:35 -06:00
spencerrlongg 4cb804cf03 get rid of e() on store and update 2024-01-26 11:56:02 -06:00
spencerrlongg 2b0dd8851c probably needs more testing... but should work 2024-01-26 11:47:09 -06:00
spencerrlongg 41e0275c95 htmlentities() 2024-01-03 12:42:36 -06:00
Godfrey M c9d46856a3 added name back 2023-11-14 15:00:11 -08:00
Godfrey M 6d65f6646f allows validation to ignore self and update 2023-11-14 14:55:51 -08:00
608 changed files with 7638 additions and 5802 deletions
+81
View File
@@ -3018,6 +3018,87 @@
"contributions": [
"code"
]
},
{
"login": "koiakoia",
"name": "koiakoia",
"avatar_url": "https://avatars.githubusercontent.com/u/60405354?v=4",
"profile": "https://github.com/koiakoia",
"contributions": [
"code"
]
},
{
"login": "mustafa-online",
"name": "Mustafa Online",
"avatar_url": "https://avatars.githubusercontent.com/u/5323832?v=4",
"profile": "https://github.com/mustafa-online",
"contributions": [
"code"
]
},
{
"login": "franceslui",
"name": "franceslui",
"avatar_url": "https://avatars.githubusercontent.com/u/104601439?v=4",
"profile": "https://github.com/franceslui",
"contributions": [
"code"
]
},
{
"login": "Q4kK",
"name": "Q4kK",
"avatar_url": "https://avatars.githubusercontent.com/u/125313163?v=4",
"profile": "https://github.com/Q4kK",
"contributions": [
"code"
]
},
{
"login": "squintfox",
"name": "squintfox",
"avatar_url": "https://avatars.githubusercontent.com/u/55590532?v=4",
"profile": "https://github.com/squintfox",
"contributions": [
"code"
]
},
{
"login": "jeffclay",
"name": "Jeff Clay",
"avatar_url": "https://avatars.githubusercontent.com/u/1380084?v=4",
"profile": "https://github.com/jeffclay",
"contributions": [
"code"
]
},
{
"login": "PP-JN-RL",
"name": "Phil J R",
"avatar_url": "https://avatars.githubusercontent.com/u/52716446?v=4",
"profile": "https://github.com/PP-JN-RL",
"contributions": [
"code"
]
},
{
"login": "chandanchowdhury",
"name": "i_virus",
"avatar_url": "https://avatars.githubusercontent.com/u/1496725?v=4",
"profile": "https://www.corelight.com/",
"contributions": [
"code"
]
},
{
"login": "gitgrimbo",
"name": "Paul Grime",
"avatar_url": "https://avatars.githubusercontent.com/u/1020541?v=4",
"profile": "https://github.com/gitgrimbo",
"contributions": [
"code"
]
}
]
}
+1
View File
@@ -45,6 +45,7 @@ DB_SSL_KEY_PATH=null
DB_SSL_CERT_PATH=null
DB_SSL_CA_PATH=null
DB_SSL_CIPHER=null
DB_SSL_VERIFY_SERVER=null
# --------------------------------------------
# REQUIRED: OUTGOING MAIL SERVER SETTINGS
+1
View File
@@ -36,6 +36,7 @@ DB_SSL_KEY_PATH=null
DB_SSL_CERT_PATH=null
DB_SSL_CA_PATH=null
DB_SSL_CIPHER=null
DB_SSL_VERIFY_SERVER=null
# --------------------------------------------
# REQUIRED: OUTGOING MAIL SERVER SETTINGS
+2
View File
@@ -42,6 +42,7 @@ DB_SSL_KEY_PATH=null
DB_SSL_CERT_PATH=null
DB_SSL_CA_PATH=null
DB_SSL_CIPHER=null
DB_SSL_VERIFY_SERVER=null
# --------------------------------------------
# REQUIRED: OUTGOING MAIL SERVER SETTINGS
@@ -86,6 +87,7 @@ COOKIE_DOMAIN=null
SECURE_COOKIES=false
API_TOKEN_EXPIRATION_YEARS=15
BS_TABLE_STORAGE=cookieStorage
BS_TABLE_DEEPLINK=true
# --------------------------------------------
# OPTIONAL: SECURITY HEADER SETTINGS
+11
View File
@@ -432,6 +432,17 @@ Thanks goes to all of these wonderful people ([emoji key](https://github.com/ken
<td align="center" valign="top" width="14.28%"><a href="https://github.com/bilias"><img src="https://avatars.githubusercontent.com/u/47315739?v=4?s=110" width="110px;" alt="bilias"/><br /><sub><b>bilias</b></sub></a><br /><a href="https://github.com/snipe/snipe-it/commits?author=bilias" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/coach1988"><img src="https://avatars.githubusercontent.com/u/2565989?v=4?s=110" width="110px;" alt="coach1988"/><br /><sub><b>coach1988</b></sub></a><br /><a href="https://github.com/snipe/snipe-it/commits?author=coach1988" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/mauro-miatello"><img src="https://avatars.githubusercontent.com/u/11910225?v=4?s=110" width="110px;" alt="MrM"/><br /><sub><b>MrM</b></sub></a><br /><a href="https://github.com/snipe/snipe-it/commits?author=mauro-miatello" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/koiakoia"><img src="https://avatars.githubusercontent.com/u/60405354?v=4?s=110" width="110px;" alt="koiakoia"/><br /><sub><b>koiakoia</b></sub></a><br /><a href="https://github.com/snipe/snipe-it/commits?author=koiakoia" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/mustafa-online"><img src="https://avatars.githubusercontent.com/u/5323832?v=4?s=110" width="110px;" alt="Mustafa Online"/><br /><sub><b>Mustafa Online</b></sub></a><br /><a href="https://github.com/snipe/snipe-it/commits?author=mustafa-online" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/franceslui"><img src="https://avatars.githubusercontent.com/u/104601439?v=4?s=110" width="110px;" alt="franceslui"/><br /><sub><b>franceslui</b></sub></a><br /><a href="https://github.com/snipe/snipe-it/commits?author=franceslui" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Q4kK"><img src="https://avatars.githubusercontent.com/u/125313163?v=4?s=110" width="110px;" alt="Q4kK"/><br /><sub><b>Q4kK</b></sub></a><br /><a href="https://github.com/snipe/snipe-it/commits?author=Q4kK" title="Code">💻</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/squintfox"><img src="https://avatars.githubusercontent.com/u/55590532?v=4?s=110" width="110px;" alt="squintfox"/><br /><sub><b>squintfox</b></sub></a><br /><a href="https://github.com/snipe/snipe-it/commits?author=squintfox" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/jeffclay"><img src="https://avatars.githubusercontent.com/u/1380084?v=4?s=110" width="110px;" alt="Jeff Clay"/><br /><sub><b>Jeff Clay</b></sub></a><br /><a href="https://github.com/snipe/snipe-it/commits?author=jeffclay" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/PP-JN-RL"><img src="https://avatars.githubusercontent.com/u/52716446?v=4?s=110" width="110px;" alt="Phil J R"/><br /><sub><b>Phil J R</b></sub></a><br /><a href="https://github.com/snipe/snipe-it/commits?author=PP-JN-RL" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://www.corelight.com/"><img src="https://avatars.githubusercontent.com/u/1496725?v=4?s=110" width="110px;" alt="i_virus"/><br /><sub><b>i_virus</b></sub></a><br /><a href="https://github.com/snipe/snipe-it/commits?author=chandanchowdhury" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/gitgrimbo"><img src="https://avatars.githubusercontent.com/u/1020541?v=4?s=110" width="110px;" alt="Paul Grime"/><br /><sub><b>Paul Grime</b></sub></a><br /><a href="https://github.com/snipe/snipe-it/commits?author=gitgrimbo" title="Code">💻</a></td>
</tr>
</tbody>
</table>
+11 -7
View File
@@ -11,7 +11,8 @@ It is built on [Laravel 8](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/).)
__This is web-based software__. This means there is no executable file (aka no .exe files), and it must be run on a web server and accessed through a web browser. It runs on any Mac OSX, flavor of Linux, as well as Windows, and we have a [Docker image](https://snipe-it.readme.io/docs/docker) available if that's what you're into.
> [!TIP]
> __This is web-based software__. This means there is no executable file (aka no .exe files), and it must be run on a web server and accessed through a web browser. It runs on any Mac OSX, any flavor of Linux, as well as Windows, and we have a [Docker image](https://snipe-it.readme.io/docs/docker) available if that's what you're into.
-----
@@ -21,7 +22,7 @@ For instructions on installing and configuring Snipe-IT on your server, check ou
If you're having trouble with the installation, please check the [Common Issues](https://snipe-it.readme.io/docs/common-issues) and [Getting Help](https://snipe-it.readme.io/docs/getting-help) documentation, and search this repository's open *and* closed issues for help.
[![Deploy](https://www.herokucdn.com/deploy/button.svg)](https://heroku.com/deploy)
<!-- [![Deploy](https://www.herokucdn.com/deploy/button.svg)](https://heroku.com/deploy) -->
-----
### User's Manual
@@ -32,8 +33,9 @@ For help using Snipe-IT, check out the [user's manual](https://snipe-it.readme.i
Feel free to check out the [GitHub Issues for this project](https://github.com/snipe/snipe-it/issues) to open a bug report or see what open issues you can help with. Please search through existing issues (open *and* closed) to see if your question has already been answered before opening a new issue.
**PLEASE see the [Getting Help Guidelines](https://snipe-it.readme.io/docs/getting-help) and [Common Issues](https://snipe-it.readme.io/docs/common-issues) before opening a ticket, and be sure to complete all of the questions in the Github Issue template to help us to help you as quickly as possible.**
> [!IMPORTANT]
> **PLEASE see the [Getting Help Guidelines](https://snipe-it.readme.io/docs/getting-help) and [Common Issues](https://snipe-it.readme.io/docs/common-issues) before opening a ticket, and be sure to complete all of the questions in the Github Issue template to help us to help you as quickly as possible.**
>
-----
### Upgrading
@@ -57,6 +59,9 @@ Please see the [translations documentation](https://snipe-it.readme.io/docs/tran
Since the release of the JSON REST API, several third-party developers have been developing modules and libraries to work with Snipe-IT.
> [!NOTE]
> 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. :)
- [Python Module](https://github.com/jbloomer/SnipeIT-PythonAPI) by [@jbloomer](https://github.com/jbloomer)
- [SnipeSharp - .NET module in C#](https://github.com/barrycarey/SnipeSharp) by [@barrycarey](https://github.com/barrycarey)
- [InQRy -unmaintained-](https://github.com/Microsoft/InQRy) by [@Microsoft](https://github.com/Microsoft)
@@ -73,8 +78,6 @@ Since the release of the JSON REST API, several third-party developers have been
- [UniFi to Snipe-IT](https://github.com/RodneyLeeBrands/UnifiSnipeSync) by [@karpadiem](https://github.com/karpadiem) - Python script that synchronizes UniFi devices with Snipe-IT.
- [Kandji2Snipe](https://github.com/grokability/kandji2snipe) by [@briangoldstein](https://github.com/briangoldstein) - Python script that synchronizes Kandji with Snipe-IT.
- [SnipeAgent](https://github.com/ReticentRobot/SnipeAgent) by @ReticentRobot - Windows agent 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. :)
-----
@@ -92,4 +95,5 @@ The ERD is available [online here](https://drawsql.app/templates/snipe-it).
### Security
To report a security vulnerability, please email security@snipeitapp.com instead of using the issue tracker.
> [!IMPORTANT]
> **To report a security vulnerability, please email security@snipeitapp.com instead of using the issue tracker.**
+1 -1
View File
@@ -390,7 +390,7 @@ class LdapSync extends Command
$user->location_id = $location->id;
}
}
$location = null;
$user->ldap_import = 1;
$errors = '';
@@ -9,7 +9,6 @@ use App\Notifications\ExpectedCheckinAdminNotification;
use App\Notifications\ExpectedCheckinNotification;
use Carbon\Carbon;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Log;
class SendExpectedCheckinAlerts extends Command
{
@@ -43,25 +42,31 @@ class SendExpectedCheckinAlerts extends Command
public function handle()
{
$settings = Setting::getSettings();
$whenNotify = Carbon::now();
$assets = Asset::with('assignedTo')->whereNotNull('assigned_to')->whereNotNull('expected_checkin')->where('expected_checkin', '<=', $whenNotify)->get();
$interval = $settings->audit_warning_days ?? 0;
$today = Carbon::now();
$interval_date = $today->copy()->addDays($interval);
$assets = Asset::whereNull('deleted_at')->DueOrOverdueForCheckin($settings)->orderBy('assets.expected_checkin', 'desc')->get();
$this->info($assets->count().' assets must be checked in on or before '.$interval_date.' is deadline');
$this->info($whenNotify.' is deadline');
$this->info($assets->count().' assets');
foreach ($assets as $asset) {
if ($asset->assigned && $asset->checkedOutToUser()) {
Log::info('Sending ExpectedCheckinNotification to ' . $asset->assigned->email);
$asset->assigned->notify((new ExpectedCheckinNotification($asset)));
if ($asset->assignedTo && (isset($asset->assignedTo->email)) && ($asset->assignedTo->email!='') && $asset->checkedOutToUser()) {
$this->info('Sending User ExpectedCheckinNotification to: '.$asset->assignedTo->email);
$asset->assignedTo->notify((new ExpectedCheckinNotification($asset)));
}
}
if (($assets) && ($assets->count() > 0) && ($settings->alert_email != '')) {
// Send a rollup to the admin, if settings dictate
$recipients = collect(explode(',', $settings->alert_email))->map(function ($item, $key) {
$recipients = collect(explode(',', $settings->alert_email))->map(function ($item) {
return new AlertRecipient($item);
});
$this->info('Sending Admin ExpectedCheckinNotification to: '.$settings->alert_email);
\Notification::send($recipients, new ExpectedCheckinAdminNotification($assets));
}
}
}
@@ -3,10 +3,8 @@
namespace App\Console\Commands;
use App\Models\Asset;
use App\Models\License;
use App\Models\Recipients;
use App\Models\Recipients\AlertRecipient;
use App\Models\Setting;
use App\Notifications\ExpiringAssetsNotification;
use App\Notifications\SendUpcomingAuditNotification;
use Carbon\Carbon;
use DB;
@@ -45,40 +43,26 @@ class SendUpcomingAuditReport extends Command
*/
public function handle()
{
$interval = $settings->audit_warning_days ?? 0;
$today = Carbon::now();
$interval_date = $today->copy()->addDays($interval);
$settings = Setting::getSettings();
$assets = Asset::whereNull('deleted_at')->DueOrOverdueForAudit($settings)->orderBy('assets.next_audit_date', 'desc')->get();
$this->info($assets->count().' assets must be audited in on or before '.$interval_date.' is deadline');
if (($settings->alert_email != '') && ($settings->audit_warning_days) && ($settings->alerts_enabled == 1)) {
if (($assets) && ($assets->count() > 0) && ($settings->alert_email != '')) {
// Send a rollup to the admin, if settings dictate
$recipients = collect(explode(',', $settings->alert_email))->map(function ($item, $key) {
return new \App\Models\Recipients\AlertRecipient($item);
$recipients = collect(explode(',', $settings->alert_email))->map(function ($item) {
return new AlertRecipient($item);
});
// Assets due for auditing
$this->info('Sending Admin SendUpcomingAuditNotification to: '.$settings->alert_email);
\Notification::send($recipients, new SendUpcomingAuditNotification($assets, $settings->audit_warning_days));
$assets = Asset::whereNotNull('next_audit_date')
->DueOrOverdueForAudit($settings)
->orderBy('last_audit_date', 'asc')->get();
if ($assets->count() > 0) {
$this->info(trans_choice('mail.upcoming-audits', $assets->count(),
['count' => $assets->count(), 'threshold' => $settings->audit_warning_days]));
\Notification::send($recipients, new SendUpcomingAuditNotification($assets, $settings->audit_warning_days));
$this->info('Audit report sent to '.$settings->alert_email);
} else {
$this->info('No assets to be audited. No report sent.');
}
} elseif ($settings->alert_email == '') {
$this->error('Could not send email. No alert email configured in settings');
} elseif (! $settings->audit_warning_days) {
$this->error('No audit warning days set in Admin Notifications. No mail will be sent.');
} elseif ($settings->alerts_enabled != 1) {
$this->info('Alerts are disabled in the settings. No mail will be sent');
} else {
$this->error('Something went wrong. :( ');
$this->error('Admin Notifications Email Setting: '.$settings->alert_email);
$this->error('Admin Audit Warning Setting: '.$settings->audit_warning_days);
$this->error('Admin Alerts Emnabled: '.$settings->alerts_enabled);
}
}
}
+5 -1
View File
@@ -842,7 +842,7 @@ class Helper
$filetype = @finfo_file($finfo, $file);
finfo_close($finfo);
if (($filetype == 'image/jpeg') || ($filetype == 'image/jpg') || ($filetype == 'image/png') || ($filetype == 'image/bmp') || ($filetype == 'image/gif')) {
if (($filetype == 'image/jpeg') || ($filetype == 'image/jpg') || ($filetype == 'image/png') || ($filetype == 'image/bmp') || ($filetype == 'image/gif') || ($filetype == 'image/avif')) {
return $filetype;
}
@@ -1106,6 +1106,8 @@ class Helper
'jpeg' => 'far fa-image',
'gif' => 'far fa-image',
'png' => 'far fa-image',
'webp' => 'far fa-image',
'avif' => 'far fa-image',
// word
'doc' => 'far fa-file-word',
'docx' => 'far fa-file-word',
@@ -1141,6 +1143,8 @@ class Helper
case 'jpeg':
case 'gif':
case 'png':
case 'webp':
case 'avif':
return true;
break;
default:
+67 -18
View File
@@ -59,7 +59,7 @@ class AssetsController extends Controller
* @since [v4.0]
* @return \Illuminate\Http\JsonResponse
*/
public function index(Request $request, $audit = null)
public function index(Request $request, $action = null, $upcoming_status = null)
{
$filter_non_deprecable_assets = false;
@@ -94,6 +94,7 @@ class AssetsController extends Controller
'serial',
'model_number',
'last_checkout',
'last_checkin',
'notes',
'expected_checkin',
'order_number',
@@ -154,17 +155,44 @@ class AssetsController extends Controller
$assets->TextSearch($request->input('search'));
}
// This is used by the audit reporting routes
if (Gate::allows('audit', Asset::class)) {
switch ($audit) {
case 'due':
$assets->DueOrOverdueForAudit($settings);
break;
case 'overdue':
$assets->overdueForAudit($settings);
break;
/**
* Handle due and overdue audits and checkin dates
*/
switch ($action) {
case 'audits':
switch ($upcoming_status) {
case 'due':
$assets->DueForAudit($settings);
break;
case 'overdue':
$assets->OverdueForAudit();
break;
case 'due-or-overdue':
$assets->DueOrOverdueForAudit($settings);
break;
}
break;
case 'checkins':
switch ($upcoming_status) {
case 'due':
$assets->DueForCheckin($settings);
break;
case 'overdue':
$assets->OverdueForCheckin();
break;
case 'due-or-overdue':
$assets->DueOrOverdueForCheckin($settings);
break;
}
break;
}
}
/**
* End handling due and overdue audits and checkin dates
*/
// This is used by the sidenav, mostly
@@ -591,6 +619,11 @@ class AssetsController extends Controller
}
}
}
if ($field->element == 'checkbox') {
if(is_array($field_val)) {
$field_val = implode(',', $field_val);
}
}
$asset->{$field->db_column} = $field_val;
@@ -614,6 +647,8 @@ class AssetsController extends Controller
}
return response()->json(Helper::formatStandardApiResponse('success', $asset, trans('admin/hardware/message.create.success')));
return response()->json(Helper::formatStandardApiResponse('success', (new AssetsTransformer)->transformAsset($asset), trans('admin/hardware/message.create.success')));
}
return response()->json(Helper::formatStandardApiResponse('error', null, $asset->getErrors()), 200);
@@ -657,16 +692,26 @@ class AssetsController extends Controller
$model = AssetModel::find($asset->model_id);
// Update custom fields
$problems_updating_encrypted_custom_fields = false;
if (($model) && (isset($model->fieldset))) {
foreach ($model->fieldset->fields as $field) {
$field_val = $request->input($field->db_column, null);
if ($request->has($field->db_column)) {
if ($field->element == 'checkbox') {
if(is_array($field_val)) {
$field_val = implode(',', $field_val);
}
}
if ($field->field_encrypted == '1') {
if (Gate::allows('admin')) {
$asset->{$field->db_column} = \Crypt::encrypt($request->input($field->db_column));
$field_val = Crypt::encrypt($field_val);
} else {
$problems_updating_encrypted_custom_fields = true;
continue;
}
} else {
$asset->{$field->db_column} = $request->input($field->db_column);
}
$asset->{$field->db_column} = $field_val;
}
}
}
@@ -692,7 +737,11 @@ class AssetsController extends Controller
$asset->image = $asset->getImageUrl();
}
return response()->json(Helper::formatStandardApiResponse('success', $asset, trans('admin/hardware/message.update.success')));
if ($problems_updating_encrypted_custom_fields) {
return response()->json(Helper::formatStandardApiResponse('success', $asset, trans('admin/hardware/message.update.encrypted_warning')));
} else {
return response()->json(Helper::formatStandardApiResponse('success', $asset, trans('admin/hardware/message.update.success')));
}
}
return response()->json(Helper::formatStandardApiResponse('error', null, $asset->getErrors()), 200);
@@ -1062,8 +1111,7 @@ class AssetsController extends Controller
$assets = Asset::select('assets.*')
->with('location', 'assetstatus', 'assetlog', 'company','assignedTo',
'model.category', 'model.manufacturer', 'model.fieldset', 'supplier', 'requests')
->requestableAssets();
'model.category', 'model.manufacturer', 'model.fieldset', 'supplier', 'requests');
@@ -1071,7 +1119,7 @@ class AssetsController extends Controller
if ($request->filled('search')) {
$assets->TextSearch($request->input('search'));
}
// Search custom fields by column name
foreach ($all_custom_fields as $field) {
if ($request->filled($field->db_column_name())) {
@@ -1101,6 +1149,7 @@ class AssetsController extends Controller
break;
}
$assets->requestableAssets();
// Make sure the offset and limit are actually integers and do not exceed system limits
$offset = ($request->input('offset') > $assets->count()) ? $assets->count() : app('api_offset_value');
@@ -235,7 +235,13 @@ class LocationsController extends Controller
public function destroy($id)
{
$this->authorize('delete', Location::class);
$location = Location::findOrFail($id);
$location = Location::withCount('assignedAssets as assigned_assets_count')
->withCount('assets as assets_count')
->withCount('rtd_assets as rtd_assets_count')
->withCount('children as children_count')
->withCount('users as users_count')
->findOrFail($id);
if (! $location->isDeletable()) {
return response()
->json(Helper::formatStandardApiResponse('error', null, trans('admin/companies/message.assoc_users')));
@@ -32,19 +32,26 @@ class ReportsController extends Controller
}
if (($request->filled('item_type')) && ($request->filled('item_id'))) {
$actionlogs = $actionlogs->where('item_id', '=', $request->input('item_id'))
$actionlogs = $actionlogs->where(function($query) use ($request)
{
$query->where('item_id', '=', $request->input('item_id'))
->where('item_type', '=', 'App\\Models\\'.ucwords($request->input('item_type')))
->orWhere(function($query) use ($request)
{
$query->where('target_id', '=', $request->input('item_id'))
->where('target_type', '=', 'App\\Models\\'.ucwords($request->input('item_type')));
});
});
}
if ($request->filled('action_type')) {
$actionlogs = $actionlogs->where('action_type', '=', $request->input('action_type'))->orderBy('created_at', 'desc');
}
if ($request->filled('user_id')) {
$actionlogs = $actionlogs->where('user_id', '=', $request->input('user_id'));
}
if ($request->filled('action_source')) {
$actionlogs = $actionlogs->where('action_source', '=', $request->input('action_source'))->orderBy('created_at', 'desc');
}
+94 -30
View File
@@ -273,6 +273,7 @@ class UsersController extends Controller
$users = $users->withTrashed();
}
// Apply companyable scope
$users = Company::scopeCompanyables($users);
@@ -403,7 +404,10 @@ class UsersController extends Controller
public function show($id)
{
$this->authorize('view', User::class);
$user = User::withCount('assets as assets_count', 'licenses as licenses_count', 'accessories as accessories_count', 'consumables as consumables_count')->findOrFail($id);
$user = Company::scopeCompanyables($user)->find($id);
$this->authorize('update', $user);
return (new UsersTransformer)->transformUser($user);
}
@@ -423,6 +427,8 @@ class UsersController extends Controller
$this->authorize('update', User::class);
$user = User::findOrFail($id);
$user = Company::scopeCompanyables($user)->find($id);
$this->authorize('update', $user);
/**
* This is a janky hack to prevent people from changing admin demo user data on the public demo.
@@ -459,6 +465,7 @@ class UsersController extends Controller
if (! Auth::user()->isSuperUser()) {
unset($permissions_array['superuser']);
}
$user->permissions = $permissions_array;
}
@@ -481,6 +488,7 @@ class UsersController extends Controller
// Check if the request has groups passed and has a value
if ($request->filled('groups')) {
$validator = Validator::make($request->all(), [
'groups.*' => 'integer|exists:permission_groups,id',
]);
@@ -488,10 +496,19 @@ class UsersController extends Controller
if ($validator->fails()){
return response()->json(Helper::formatStandardApiResponse('error', null, $user->getErrors()));
}
$user->groups()->sync($request->input('groups'));
// Only save groups if the user is a superuser
if (Auth::user()->isSuperUser()) {
$user->groups()->sync($request->input('groups'));
}
// The groups field has been passed but it is null, so we should blank it out
} elseif ($request->has('groups')) {
$user->groups()->sync([]);
// Only save groups if the user is a superuser
if (Auth::user()->isSuperUser()) {
$user->groups()->sync($request->input('groups'));
}
}
@@ -512,37 +529,43 @@ class UsersController extends Controller
public function destroy($id)
{
$this->authorize('delete', User::class);
$user = User::findOrFail($id);
$user = User::with('assets', 'assets.model', 'consumables', 'accessories', 'licenses', 'userloc')->withTrashed();
$user = Company::scopeCompanyables($user)->find($id);
$this->authorize('delete', $user);
if (($user->assets) && ($user->assets->count() > 0)) {
return response()->json(Helper::formatStandardApiResponse('error', null, trans('admin/users/message.error.delete_has_assets')));
}
if ($user) {
if (($user->licenses) && ($user->licenses->count() > 0)) {
return response()->json(Helper::formatStandardApiResponse('error', null, 'This user still has '.$user->licenses->count().' license(s) associated with them and cannot be deleted.'));
}
if (($user->accessories) && ($user->accessories->count() > 0)) {
return response()->json(Helper::formatStandardApiResponse('error', null, 'This user still has '.$user->accessories->count().' accessories associated with them.'));
}
if (($user->managedLocations()) && ($user->managedLocations()->count() > 0)) {
return response()->json(Helper::formatStandardApiResponse('error', null, 'This user still has '.$user->managedLocations()->count().' locations that they manage.'));
}
if ($user->delete()) {
// Remove the user's avatar if they have one
if (Storage::disk('public')->exists('avatars/'.$user->avatar)) {
try {
Storage::disk('public')->delete('avatars/'.$user->avatar);
} catch (\Exception $e) {
\Log::debug($e);
}
$this->authorize('delete', $user);
if (($user->assets) && ($user->assets->count() > 0)) {
return response()->json(Helper::formatStandardApiResponse('error', null, trans('admin/users/message.error.delete_has_assets')));
}
return response()->json(Helper::formatStandardApiResponse('success', null, trans('admin/users/message.success.delete')));
if (($user->licenses) && ($user->licenses->count() > 0)) {
return response()->json(Helper::formatStandardApiResponse('error', null, 'This user still has ' . $user->licenses->count() . ' license(s) associated with them and cannot be deleted.'));
}
if (($user->accessories) && ($user->accessories->count() > 0)) {
return response()->json(Helper::formatStandardApiResponse('error', null, 'This user still has ' . $user->accessories->count() . ' accessories associated with them.'));
}
if (($user->managedLocations()) && ($user->managedLocations()->count() > 0)) {
return response()->json(Helper::formatStandardApiResponse('error', null, 'This user still has ' . $user->managedLocations()->count() . ' locations that they manage.'));
}
if ($user->delete()) {
// Remove the user's avatar if they have one
if (Storage::disk('public')->exists('avatars/' . $user->avatar)) {
try {
Storage::disk('public')->delete('avatars/' . $user->avatar);
} catch (\Exception $e) {
\Log::debug($e);
}
}
return response()->json(Helper::formatStandardApiResponse('success', null, trans('admin/users/message.success.delete')));
}
}
return response()->json(Helper::formatStandardApiResponse('error', null, trans('admin/users/message.error.delete')));
@@ -560,7 +583,31 @@ class UsersController extends Controller
{
$this->authorize('view', User::class);
$this->authorize('view', Asset::class);
$assets = Asset::where('assigned_to', '=', $id)->where('assigned_type', '=', User::class)->with('model')->get();
$user = User::with('assets', 'assets.model', 'consumables', 'accessories', 'licenses', 'userloc')->withTrashed();
$user = Company::scopeCompanyables($user)->find($id);
$this->authorize('view', $user);
$assets = Asset::where('assigned_to', '=', $id)->where('assigned_type', '=', User::class)->with('model');
// Filter on category ID
if ($request->filled('category_id')) {
$assets = $assets->InCategory($request->input('category_id'));
}
// Filter on model ID
if ($request->filled('model_id')) {
$model_ids = $request->input('model_id');
if (!is_array($model_ids)) {
$model_ids = array($model_ids);
}
$assets = $assets->InModelList($model_ids);
}
$assets = $assets->get();
return (new AssetsTransformer)->transformAssets($assets, $assets->count(), $request);
}
@@ -576,7 +623,10 @@ class UsersController extends Controller
*/
public function emailAssetList(Request $request, $id)
{
$this->authorize('update', User::class);
$user = User::findOrFail($id);
$user = Company::scopeCompanyables($user)->find($id);
$this->authorize('update', $user);
if (empty($user->email)) {
return response()->json(Helper::formatStandardApiResponse('error', null, trans('admin/users/message.inventorynotification.error')));
@@ -600,6 +650,7 @@ class UsersController extends Controller
$this->authorize('view', User::class);
$this->authorize('view', Consumable::class);
$user = User::findOrFail($id);
$this->authorize('update', $user);
$consumables = $user->consumables;
return (new ConsumablesTransformer)->transformConsumables($consumables, $consumables->count(), $request);
}
@@ -616,6 +667,7 @@ class UsersController extends Controller
{
$this->authorize('view', User::class);
$user = User::findOrFail($id);
$this->authorize('view', $user);
$this->authorize('view', Accessory::class);
$accessories = $user->accessories;
@@ -636,6 +688,7 @@ class UsersController extends Controller
$this->authorize('view', License::class);
if ($user = User::where('id', $id)->withTrashed()->first()) {
$this->authorize('update', $user);
$licenses = $user->licenses()->get();
return (new LicensesTransformer())->transformLicenses($licenses, $licenses->count());
}
@@ -659,9 +712,20 @@ class UsersController extends Controller
if ($request->filled('id')) {
try {
$user = User::find($request->get('id'));
$this->authorize('update', $user);
$user->two_factor_secret = null;
$user->two_factor_enrolled = 0;
$user->save();
$user->saveQuietly();
// Log the reset
$logaction = new Actionlog();
$logaction->target_type = User::class;
$logaction->target_id = $user->id;
$logaction->item_type = User::class;
$logaction->item_id = $user->id;
$logaction->created_at = date('Y-m-d H:i:s');
$logaction->user_id = Auth::user()->id;
$logaction->logaction('2FA reset');
return response()->json(['message' => trans('admin/settings/general.two_factor_reset_success')], 200);
} catch (\Exception $e) {
@@ -7,6 +7,7 @@ use App\Http\Requests\ImageUploadRequest;
use App\Models\Actionlog;
use App\Models\Asset;
use App\Models\AssetModel;
use App\Models\CustomField;
use App\Models\User;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
@@ -486,11 +487,11 @@ class AssetModelsController extends Controller
* @param array $defaultValues
* @return void
*/
private function assignCustomFieldsDefaultValues(AssetModel $model, array $defaultValues)
private function assignCustomFieldsDefaultValues(AssetModel $model, array $defaultValues): bool
{
$data = array();
foreach ($defaultValues as $customFieldId => $defaultValue) {
$customField = \App\Models\CustomField::find($customFieldId);
$customField = CustomField::find($customFieldId);
$data[$customField->db_column] = $defaultValue;
}
@@ -38,7 +38,7 @@ class AssetModelsFilesController extends Controller
$file_name = $request->handleFile('private_uploads/assetmodels/','model-'.$model->id,$file);
$model->logUpload($file_name, e($request->get('notes')));
$model->logUpload($file_name, $request->get('notes'));
}
return redirect()->back()->with('success', trans('general.file_upload_success'));
@@ -39,6 +39,12 @@ class AssetCheckinController extends Controller
$this->authorize('checkin', $asset);
// This asset is already checked in, redirect
if (is_null($asset->assignedTo)) {
return redirect()->route('hardware.index')->with('error', trans('admin/hardware/message.checkin.already_checked_in'));
}
return view('hardware/checkin', compact('asset'))->with('statusLabel_list', Helper::statusLabelList())->with('backto', $backto);
}
@@ -38,7 +38,7 @@ class AssetFilesController extends Controller
foreach ($request->file('file') as $file) {
$file_name = $request->handleFile('private_uploads/assets/','hardware-'.$asset->id, $file);
$asset->logUpload($file_name, e($request->get('notes')));
$asset->logUpload($file_name, $request->get('notes'));
}
return redirect()->back()->with('success', trans('admin/hardware/message.upload.success'));
@@ -102,6 +102,10 @@ class AssetsController extends Controller
{
$this->authorize(Asset::class);
// There are a lot more rules to add here but prevents
// errors around `asset_tags` not being present below.
$this->validate($request, ['asset_tags' => ['required', 'array']]);
// Handle asset tags - there could be one, or potentially many.
// This is only necessary on create, not update, since bulk editing is handled
// differently
@@ -850,11 +854,11 @@ class AssetsController extends Controller
return view('hardware/audit-due');
}
public function overdueForAudit()
public function dueForCheckin()
{
$this->authorize('audit', Asset::class);
$this->authorize('checkin', Asset::class);
return view('hardware/audit-overdue');
return view('hardware/checkin-due');
}
@@ -260,7 +260,7 @@ class CustomFieldsController extends Controller
$field->name = trim(e($request->get("name")));
$field->element = e($request->get("element"));
$field->field_values = e($request->get("field_values"));
$field->field_values = $request->get("field_values");
$field->user_id = Auth::id();
$field->help_text = $request->get("help_text");
$field->show_in_email = $show_in_email;
+11 -8
View File
@@ -14,6 +14,7 @@ use App\Models\Setting;
use App\Models\Supplier;
use App\Models\User;
use App\View\Label as LabelView;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Storage;
class LabelsController extends Controller
@@ -21,9 +22,9 @@ class LabelsController extends Controller
/**
* Returns the Label view with test data
*
* @author Grant Le Roux <grant.leroux+snipe-it@gmail.com>
* @param string $labelName
* @param string $labelName
* @return \Illuminate\Contracts\View\View
* @author Grant Le Roux <grant.leroux+snipe-it@gmail.com>
*/
public function show(string $labelName)
{
@@ -66,16 +67,18 @@ class LabelsController extends Controller
$exampleAsset->model->category->id = 999999;
$exampleAsset->model->category->name = trans('admin/labels/table.example_category');
$customFieldColumns = CustomField::all()->pluck('db_column');
$customFieldColumns = CustomField::where('field_encrypted', '=', 0)->pluck('db_column');
collect(explode(';', Setting::getSettings()->label2_fields))
->filter()
->each(function ($item) use ($customFieldColumns, $exampleAsset) {
$pair = explode('=', $item);
if ($customFieldColumns->contains($pair[1])) {
$exampleAsset->{$pair[1]} = "{{$pair[0]}}";
}
$pair = explode('=', $item);
if (array_key_exists(1, $pair)) {
if ($customFieldColumns->contains($pair[1])) {
$exampleAsset->{$pair[1]} = "{{$pair[0]}}";
}
}
});
$settings = Setting::getSettings();
@@ -11,6 +11,7 @@ use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Symfony\Component\HttpFoundation\StreamedResponse;
/**
* This controller handles all actions related to Licenses for
@@ -289,4 +290,106 @@ class LicensesController extends Controller
->with('item', $license)
->with('maintained_list', $maintained_list);
}
/**
* Exports Licenses to CSV
*
* @author [G. Martinez]
* @since [v6.3]
* @return StreamedResponse
* @throws \Illuminate\Auth\Access\AuthorizationException
*/
public function getExportLicensesCsv()
{
$this->authorize('view', License::class);
\Debugbar::disable();
$response = new StreamedResponse(function () {
// Open output stream
$handle = fopen('php://output', 'w');
$licenses= License::with('company',
'manufacturer',
'category',
'supplier',
'adminuser',
'assignedusers')
->orderBy('created_at', 'DESC');
Company::scopeCompanyables($licenses)
->chunk(500, function ($licenses) use ($handle) {
$headers = [
// strtolower to prevent Excel from trying to open it as a SYLK file
strtolower(trans('general.id')),
trans('general.company'),
trans('general.name'),
trans('general.serial_number'),
trans('general.purchase_date'),
trans('general.purchase_cost'),
trans('general.order_number'),
trans('general.licenses_available'),
trans('admin/licenses/table.seats'),
trans('general.created_by'),
trans('general.depreciation'),
trans('general.updated_at'),
trans('admin/licenses/table.deleted_at'),
trans('general.email'),
trans('admin/hardware/form.fully_depreciated'),
trans('general.supplier'),
trans('admin/licenses/form.expiration'),
trans('admin/licenses/form.purchase_order'),
trans('admin/licenses/form.termination_date'),
trans('admin/licenses/form.maintained'),
trans('general.manufacturer'),
trans('general.category'),
trans('general.min_amt'),
trans('admin/licenses/form.reassignable'),
trans('general.notes'),
trans('general.created_at'),
];
fputcsv($handle, $headers);
foreach ($licenses as $license) {
// Add a new row with data
$values = [
$license->id,
$license->company ? $license->company->name: '',
$license->name,
$license->serial,
$license->purchase_date,
$license->purchase_cost,
$license->order_number,
$license->free_seat_count,
$license->seats,
$license->adminuser->present()->fullName(),
$license->depreciation ? $license->depreciation->name: '',
$license->updated_at,
$license->deleted_at,
$license->email,
( $license->depreciate == '1') ? trans('general.yes') : trans('general.no'),
($license->supplier) ? $license->supplier->name: '',
$license->expiration_date,
$license->purchase_order,
$license->termination_date,
( $license->maintained == '1') ? trans('general.yes') : trans('general.no'),
$license->manufacturer ? $license->manufacturer->name: '',
$license->category ? $license->category->name: '',
$license->min_amt,
( $license->reassignable == '1') ? trans('general.yes') : trans('general.no'),
$license->notes,
$license->created_at,
];
fputcsv($handle, $values);
}
});
// Close the output stream
fclose($handle);
}, 200, [
'Content-Type' => 'text/csv; charset=UTF-8',
'Content-Disposition' => 'attachment; filename="licenses-'.date('Y-m-d-his').'.csv"',
]);
return $response;
}
}
+7 -2
View File
@@ -320,7 +320,12 @@ class LocationsController extends Controller
$locations_raw_array = $request->input('ids');
if ((is_array($locations_raw_array)) && (count($locations_raw_array) > 0)) {
$locations = Location::whereIn('id', $locations_raw_array)->get();
$locations = Location::whereIn('id', $locations_raw_array)
->withCount('assignedAssets as assigned_assets_count')
->withCount('assets as assets_count')
->withCount('rtd_assets as rtd_assets_count')
->withCount('children as children_count')
->withCount('users as users_count')->get();
$success_count = 0;
$error_count = 0;
@@ -351,7 +356,7 @@ class LocationsController extends Controller
if ($error_count > 0) {
return redirect()
->route('locations.index')
->with('warning', trans('general.bulk.partial_success',
->with('warning', trans('general.bulk.delete.partial',
['success' => $success_count, 'error' => $error_count, 'object_type' => trans('general.locations')]
));
}
+7 -6
View File
@@ -696,16 +696,17 @@ class ReportsController extends Controller
->whereBetween('action_date',[$checkout_start, $checkout_end])
->pluck('item_id');
$assets->whereIn('id',$actionlogassets);
$assets->whereIn('assets.id',$actionlogassets);
}
if (($request->filled('checkin_date_start'))) {
$assets->whereBetween('last_checkin', [
Carbon::parse($request->input('checkin_date_start'))->startOfDay(),
// use today's date if `checkin_date_end` is not provided
Carbon::parse($request->input('checkin_date_end', now()))->endOfDay(),
]);
$checkin_start = \Carbon::parse($request->input('checkin_date_start'))->startOfDay();
// use today's date is `checkin_date_end` is not provided
$checkin_end = \Carbon::parse($request->input('checkin_date_end', now()))->endOfDay();
$assets->whereBetween('assets.last_checkin', [$checkin_start, $checkin_end ]);
}
//last checkin is exporting, but currently is a date and not a datetime in the custom report ONLY.
if (($request->filled('expected_checkin_start')) && ($request->filled('expected_checkin_end'))) {
$assets->whereBetween('assets.expected_checkin', [$request->input('expected_checkin_start'), $request->input('expected_checkin_end')]);
+17 -4
View File
@@ -20,6 +20,7 @@ use DB;
use enshrined\svgSanitize\Sanitizer;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage;
use Illuminate\Validation\Rule;
use Image;
use Input;
use Redirect;
@@ -499,6 +500,19 @@ class SettingsController extends Controller
*/
public function postSecurity(Request $request)
{
$this->validate($request, [
'pwd_secure_complexity' => 'array',
'pwd_secure_complexity.*' => [
Rule::in([
'disallow_same_pwd_as_user_fields',
'letters',
'numbers',
'symbols',
'case_diff',
])
]
]);
if (is_null($setting = Setting::getSettings())) {
return redirect()->to('admin')->with('error', trans('admin/settings/message.update.error'));
}
@@ -790,10 +804,9 @@ class SettingsController extends Controller
*/
public function getLabels()
{
return view('settings.labels', [
'setting' => Setting::getSettings(),
'customFields' => CustomField::all(),
]);
return view('settings.labels')
->with('setting', Setting::getSettings())
->with('customFields', CustomField::where('field_encrypted', '=', 0)->get());
}
/**
+177 -173
View File
@@ -182,8 +182,13 @@ class UsersController extends Controller
*/
public function edit($id)
{
if ($user = User::find($id)) {
$this->authorize('update', $user);
$this->authorize('update', User::class);
$user = User::with('assets', 'assets.model', 'consumables', 'accessories', 'licenses', 'userloc')->withTrashed();
$user = Company::scopeCompanyables($user)->find($id);
if ($user) {
$permissions = config('permissions');
$groups = Group::pluck('name', 'id');
@@ -210,106 +215,109 @@ class UsersController extends Controller
*/
public function update(SaveUserRequest $request, $id = null)
{
// We need to reverse the UI specific logic for our
// permissions here before we update the user.
$permissions = $request->input('permissions', []);
app('request')->request->set('permissions', $permissions);
$this->authorize('update', User::class);
// This is a janky hack to prevent people from changing admin demo user data on the public demo.
// The $ids 1 and 2 are special since they are seeded as superadmins in the demo seeder.
// Thanks, jerks. You are why we can't have nice things. - snipe
if ((($id == 1) || ($id == 2)) && (config('app.lock_passwords'))) {
return redirect()->route('users.index')->with('error', 'Permission denied. You cannot update user information for superadmins on the demo.');
return redirect()->route('users.index')->with('error', trans('general.permission_denied_superuser_demo'));
}
try {
$user = User::findOrFail($id);
} catch (ModelNotFoundException $e) {
return redirect()->route('users.index')
->with('error', trans('admin/users/message.user_not_found', compact('id')));
}
$this->authorize('update', $user);
// Figure out of this user was an admin before this edit
$orig_permissions_array = $user->decodePermissions();
$orig_superuser = '0';
if (is_array($orig_permissions_array)) {
if (array_key_exists('superuser', $orig_permissions_array)) {
$orig_superuser = $orig_permissions_array['superuser'];
// We need to reverse the UI specific logic for our
// permissions here before we update the user.
$permissions = $request->input('permissions', []);
app('request')->request->set('permissions', $permissions);
$user = User::with('assets', 'assets.model', 'consumables', 'accessories', 'licenses', 'userloc')->withTrashed();
$user = Company::scopeCompanyables($user)->find($id);
// User is valid - continue...
if ($user) {
$this->authorize('update', $user);
// Figure out of this user was an admin before this edit
$orig_permissions_array = $user->decodePermissions();
$orig_superuser = '0';
if (is_array($orig_permissions_array)) {
if (array_key_exists('superuser', $orig_permissions_array)) {
$orig_superuser = $orig_permissions_array['superuser'];
}
}
}
// Only save groups if the user is a super user
if (Auth::user()->isSuperUser()) {
$user->groups()->sync($request->input('groups'));
}
// Only save groups if the user is a superuser
if (Auth::user()->isSuperUser()) {
$user->groups()->sync($request->input('groups'));
}
// Update the user
if ($request->filled('username')) {
// Update the user fields
$user->username = trim($request->input('username'));
}
$user->email = trim($request->input('email'));
$user->first_name = $request->input('first_name');
$user->last_name = $request->input('last_name');
$user->two_factor_optin = $request->input('two_factor_optin') ?: 0;
$user->locale = $request->input('locale');
$user->employee_num = $request->input('employee_num');
$user->activated = $request->input('activated', 0);
$user->jobtitle = $request->input('jobtitle', null);
$user->phone = $request->input('phone');
$user->location_id = $request->input('location_id', null);
$user->company_id = Company::getIdForUser($request->input('company_id', null));
$user->manager_id = $request->input('manager_id', null);
$user->notes = $request->input('notes');
$user->department_id = $request->input('department_id', null);
$user->address = $request->input('address', null);
$user->city = $request->input('city', null);
$user->state = $request->input('state', null);
$user->country = $request->input('country', null);
// if a user is editing themselves we should always keep activated true
$user->activated = $request->input('activated', $request->user()->is($user) ? 1 : 0);
$user->zip = $request->input('zip', null);
$user->remote = $request->input('remote', 0);
$user->vip = $request->input('vip', 0);
$user->website = $request->input('website', null);
$user->start_date = $request->input('start_date', null);
$user->end_date = $request->input('end_date', null);
$user->autoassign_licenses = $request->input('autoassign_licenses', 0);
$user->email = trim($request->input('email'));
$user->first_name = $request->input('first_name');
$user->last_name = $request->input('last_name');
$user->two_factor_optin = $request->input('two_factor_optin') ?: 0;
$user->locale = $request->input('locale');
$user->employee_num = $request->input('employee_num');
$user->activated = $request->input('activated', 0);
$user->jobtitle = $request->input('jobtitle', null);
$user->phone = $request->input('phone');
$user->location_id = $request->input('location_id', null);
$user->company_id = Company::getIdForUser($request->input('company_id', null));
$user->manager_id = $request->input('manager_id', null);
$user->notes = $request->input('notes');
$user->department_id = $request->input('department_id', null);
$user->address = $request->input('address', null);
$user->city = $request->input('city', null);
$user->state = $request->input('state', null);
$user->country = $request->input('country', null);
// if a user is editing themselves we should always keep activated true
$user->activated = $request->input('activated', $request->user()->is($user) ? 1 : 0);
$user->zip = $request->input('zip', null);
$user->remote = $request->input('remote', 0);
$user->vip = $request->input('vip', 0);
$user->website = $request->input('website', null);
$user->start_date = $request->input('start_date', null);
$user->end_date = $request->input('end_date', null);
$user->autoassign_licenses = $request->input('autoassign_licenses', 0);
// Update the location of any assets checked out to this user
Asset::where('assigned_type', User::class)
->where('assigned_to', $user->id)
->update(['location_id' => $request->input('location_id', null)]);
// Do we want to update the user password?
if ($request->filled('password')) {
$user->password = bcrypt($request->input('password'));
}
$permissions_array = $request->input('permission');
// Strip out the superuser permission if the user isn't a superadmin
if (! Auth::user()->isSuperUser()) {
unset($permissions_array['superuser']);
$permissions_array['superuser'] = $orig_superuser;
}
$user->permissions = json_encode($permissions_array);
// Handle uploaded avatar
app(ImageUploadRequest::class)->handleImages($user, 600, 'avatar', 'avatars', 'avatar');
if ($user->save()) {
// Redirect to the user page
return redirect()->route('users.index')
->with('success', trans('admin/users/message.success.update'));
}
return redirect()->back()->withInput()->withErrors($user->getErrors());
// Update the location of any assets checked out to this user
Asset::where('assigned_type', User::class)
->where('assigned_to', $user->id)
->update(['location_id' => $request->input('location_id', null)]);
// Do we want to update the user password?
if ($request->filled('password')) {
$user->password = bcrypt($request->input('password'));
}
$permissions_array = $request->input('permission');
// Strip out the superuser permission if the user isn't a superadmin
if (! Auth::user()->isSuperUser()) {
unset($permissions_array['superuser']);
$permissions_array['superuser'] = $orig_superuser;
}
$user->permissions = json_encode($permissions_array);
// Handle uploaded avatar
app(ImageUploadRequest::class)->handleImages($user, 600, 'avatar', 'avatars', 'avatar');
//\Log::debug(print_r($user, true));
// Was the user updated?
if ($user->save()) {
// Redirect to the user page
return redirect()->route('users.index')
->with('success', trans('admin/users/message.success.update'));
}
return redirect()->back()->withInput()->withErrors($user->getErrors());
return redirect()->route('users.index')->with('error', trans('admin/users/message.user_not_found', compact('id')));
}
/**
@@ -323,12 +331,13 @@ class UsersController extends Controller
*/
public function destroy($id = null)
{
try {
// Get user information
$user = User::findOrFail($id);
// Authorize takes care of many of our logic checks now.
$this->authorize('delete', User::class);
$this->authorize('delete', User::class);
$user = User::with('assets', 'assets.model', 'consumables', 'accessories', 'licenses', 'userloc')->withTrashed();
$user = Company::scopeCompanyables($user)->find($id);
if ($user) {
// Check if we are not trying to delete ourselves
if ($user->id === Auth::id()) {
// Redirect to the user management page
@@ -362,16 +371,12 @@ class UsersController extends Controller
// Delete the user
$user->delete();
// Prepare the success message
// Redirect to the user management page
return redirect()->route('users.index')->with('success', trans('admin/users/message.success.delete'));
} catch (ModelNotFoundException $e) {
// Prepare the error message
// Redirect to the user management page
return redirect()->route('users.index')
->with('error', trans('admin/users/message.user_not_found', compact('id')));
}
return redirect()->route('users.index')
->with('error', trans('admin/users/message.user_not_found', compact('id')));
}
/**
@@ -427,59 +432,25 @@ class UsersController extends Controller
*/
public function show($userId = null)
{
if (! $user = User::with('assets', 'assets.model', 'consumables', 'accessories', 'licenses', 'userloc')->withTrashed()->find($userId)) {
// Redirect to the user management page
return redirect()->route('users.index')
->with('error', trans('admin/users/message.user_not_found', ['id' => $userId]));
}
// Make sure the user can view users at all
$this->authorize('view', User::class);
$userlog = $user->userlog->load('item');
$user = User::with('assets', 'assets.model', 'consumables', 'accessories', 'licenses', 'userloc')->withTrashed();
$user = Company::scopeCompanyables($user)->find($userId);
// Make sure they can view this particular user
$this->authorize('view', $user);
return view('users/view', compact('user', 'userlog'))
->with('settings', Setting::getSettings());
}
/**
* Unsuspend a user.
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v1.0]
* @param int $id
* @return Redirect
* @throws \Illuminate\Auth\Access\AuthorizationException
*/
public function getUnsuspend($id = null)
{
try {
// Get user information
$user = User::findOrFail($id);
$this->authorize('update', $user);
// Check if we are not trying to unsuspend ourselves
if ($user->id === Auth::id()) {
// Prepare the error message
$error = trans('admin/users/message.error.unsuspend');
// Redirect to the user management page
return redirect()->route('users.index')->with('error', $error);
}
// Do we have permission to unsuspend this user?
if ($user->isSuperUser() && ! Auth::user()->isSuperUser()) {
// Redirect to the user management page
return redirect()->route('users.index')->with('error', 'Insufficient permissions!');
}
// Redirect to the user management page
return redirect()->route('users.index')->with('success', trans('admin/users/message.success.unsuspend'));
} catch (ModelNotFoundException $e) {
// Redirect to the user management page
return redirect()->route('users.index')
->with('error', trans('admin/users/message.user_not_found', compact('id')));
if ($user) {
$userlog = $user->userlog->load('item');
return view('users/view', compact('user', 'userlog'))->with('settings', Setting::getSettings());
}
return redirect()->route('users.index')->with('error', trans('admin/users/message.user_not_found', ['id' => $userId]));
}
/**
* Return a view containing a pre-populated new user form,
* populated with some fields from an existing user.
@@ -493,22 +464,34 @@ class UsersController extends Controller
public function getClone(Request $request, $id = null)
{
$this->authorize('create', User::class);
// We need to reverse the UI specific logic for our
// permissions here before we update the user.
$permissions = $request->input('permissions', []);
app('request')->request->set('permissions', $permissions);
try {
// Get the user information
$user_to_clone = User::withTrashed()->find($id);
$user_to_clone = User::with('assets', 'assets.model', 'consumables', 'accessories', 'licenses', 'userloc')->withTrashed();
$user_to_clone = Company::scopeCompanyables($user_to_clone)->find($id);
// Make sure they can view this particular user
$this->authorize('view', $user_to_clone);
if ($user_to_clone) {
$user = clone $user_to_clone;
// Blank out some fields
$user->first_name = '';
$user->last_name = '';
$user->email = substr($user->email, ($pos = strpos($user->email, '@')) !== false ? $pos : 0);
$user->id = null;
// Get this user groups
// Get this user's groups
$userGroups = $user_to_clone->groups()->pluck('name', 'id');
// Get all the available permissions
$permissions = config('permissions');
$clonedPermissions = $user_to_clone->decodePermissions();
@@ -517,16 +500,14 @@ class UsersController extends Controller
// Show the page
return view('users/edit', compact('permissions', 'userPermissions'))
->with('user', $user)
->with('groups', Group::pluck('name', 'id'))
->with('userGroups', $userGroups)
->with('clone_user', $user_to_clone);
} catch (ModelNotFoundException $e) {
// Prepare the error message
// Redirect to the user management page
return redirect()->route('users.index')
->with('error', trans('admin/users/message.user_not_found', compact('id')));
->with('user', $user)
->with('groups', Group::pluck('name', 'id'))
->with('userGroups', $userGroups)
->with('clone_user', $user_to_clone);
}
return redirect()->route('users.index')->with('error', trans('admin/users/message.user_not_found', compact('id')));
}
/**
@@ -546,8 +527,20 @@ class UsersController extends Controller
// Open output stream
$handle = fopen('php://output', 'w');
User::with('assets', 'accessories', 'consumables', 'department', 'licenses', 'manager', 'groups', 'userloc', 'company')
->orderBy('created_at', 'DESC')
$users = User::with(
'assets',
'accessories',
'consumables',
'department',
'licenses',
'manager',
'groups',
'userloc',
'company'
)->orderBy('created_at', 'DESC');
// FMCS scoping
Company::scopeCompanyables($users)
->chunk(500, function ($users) use ($handle) {
$headers = [
// strtolower to prevent Excel from trying to open it as a SYLK file
@@ -565,7 +558,7 @@ class UsersController extends Controller
trans('general.licenses'),
trans('general.accessories'),
trans('general.consumables'),
trans('admin/users/table.groups'),
trans('general.groups'),
trans('general.notes'),
trans('admin/users/table.activated'),
trans('general.created_at'),
@@ -626,7 +619,11 @@ class UsersController extends Controller
public function printInventory($id)
{
$this->authorize('view', User::class);
$show_user = User::where('id', $id)->withTrashed()->first();
$show_user = Company::scopeCompanyables(User::where('id', $id)->withTrashed()->first());
// Make sure they can view this particular user
$this->authorize('view', $show_user);
$assets = Asset::where('assigned_to', $id)->where('assigned_type', User::class)->with('model', 'model.category')->get();
$accessories = $show_user->accessories()->get();
$consumables = $show_user->consumables()->get();
@@ -651,16 +648,23 @@ class UsersController extends Controller
{
$this->authorize('view', User::class);
if (!$user = User::find($id)) {
return redirect()->back()
->with('error', trans('admin/users/message.user_not_found', ['id' => $id]));
}
if (empty($user->email)) {
return redirect()->back()->with('error', trans('admin/users/message.user_has_no_email'));
$user = Company::scopeCompanyables(User::find($id));
// Make sure they can view this particular user
$this->authorize('view', $user);
if ($user) {
if (empty($user->email)) {
return redirect()->back()->with('error', trans('admin/users/message.user_has_no_email'));
}
$user->notify((new CurrentInventory($user)));
return redirect()->back()->with('success', trans('admin/users/general.user_notified'));
}
$user->notify((new CurrentInventory($user)));
return redirect()->back()->with('success', trans('admin/users/general.user_notified'));
return redirect()->back()->with('error', trans('admin/users/message.user_not_found', ['id' => $id]));
}
/**
@@ -672,19 +676,19 @@ class UsersController extends Controller
*/
public function sendPasswordReset($id)
{
if (($user = User::find($id)) && ($user->activated == '1') && ($user->email != '') && ($user->ldap_import == '0')) {
if (($user = Company::scopeCompanyables(User::find($id))) && ($user->activated == '1') && ($user->email != '') && ($user->ldap_import == '0')) {
$credentials = ['email' => trim($user->email)];
try {
Password::sendResetLink($credentials);
return redirect()->back()->with('success', trans('admin/users/message.password_reset_sent', ['email' => $user->email]));
} catch (\Exception $e) {
return redirect()->back()->with('error', ' Error sending email. :( ');
return redirect()->back()->with('error', trans('general.error_sending_email'));
}
}
return redirect()->back()->with('error', 'User is not activated, is LDAP synced, or does not have an email address ');
return redirect()->back()->with('error', trans('general.pwd_reset_not_sent'));
}
}
@@ -5,6 +5,7 @@ namespace App\Http\Middleware;
use App\Models\Asset;
use Auth;
use Closure;
use App\Models\Setting;
class AssetCountForSidebar
{
@@ -24,6 +25,13 @@ class AssetCountForSidebar
\Log::debug($e);
}
try {
$total_assets = Asset::RTD()->count();
view()->share('total_assets', $total_assets);
} catch (\Exception $e) {
\Log::debug($e);
}
try {
$total_deployed_sidebar = Asset::Deployed()->count();
view()->share('total_deployed_sidebar', $total_deployed_sidebar);
@@ -59,6 +67,44 @@ class AssetCountForSidebar
\Log::debug($e);
}
try {
$settings = Setting::getSettings();
view()->share('settings', $settings);
} catch (\Exception $e) {
\Log::debug($e);
}
try {
$total_due_for_audit = Asset::DueForAudit($settings)->count();
view()->share('total_due_for_audit', $total_due_for_audit);
} catch (\Exception $e) {
\Log::debug($e);
}
try {
$total_overdue_for_audit = Asset::OverdueForAudit()->count();
view()->share('total_overdue_for_audit', $total_overdue_for_audit);
} catch (\Exception $e) {
\Log::debug($e);
}
try {
$total_due_for_checkin = Asset::DueForCheckin($settings)->count();
view()->share('total_due_for_checkin', $total_due_for_checkin);
} catch (\Exception $e) {
\Log::debug($e);
}
try {
$total_overdue_for_checkin = Asset::OverdueForCheckin()->count();
view()->share('total_overdue_for_checkin', $total_overdue_for_checkin);
} catch (\Exception $e) {
\Log::debug($e);
}
view()->share('total_due_and_overdue_for_checkin', ($total_due_for_checkin + $total_overdue_for_checkin));
view()->share('total_due_and_overdue_for_audit', ($total_due_for_audit + $total_overdue_for_audit));
return $next($request);
}
}
+10 -5
View File
@@ -8,6 +8,12 @@ use \App\Helpers\Helper;
class CheckLocale
{
private function warn_legacy_locale($language, $source)
{
if ($language != Helper::mapLegacyLocale($language)) {
\Log::warning("$source $language and should be updated to be ".Helper::mapLegacyLocale($language));
}
}
/**
* Handle the locale for the user, default to settings otherwise.
*
@@ -22,24 +28,23 @@ class CheckLocale
// Default app settings from config
$language = config('app.locale');
$this->warn_legacy_locale($language, "APP_LOCALE in .env is set to");
if ($settings = Setting::getSettings()) {
// User's preference
if (($request->user()) && ($request->user()->locale)) {
$language = $request->user()->locale;
$this->warn_legacy_locale($language, "username ".$request->user()->username." (".$request->user()->id.") has a language");
// App setting preference
} elseif ($settings->locale != '') {
$language = $settings->locale;
$this->warn_legacy_locale($language, "App Settings is set to");
}
}
if (config('app.locale') != Helper::mapLegacyLocale($language)) {
\Log::warning('Your current APP_LOCALE in your .env is set to "'.config('app.locale').'" and should be updated to be "'.Helper::mapLegacyLocale($language).'" in '.base_path().'/.env. Translations may display unexpectedly until this is updated.');
}
\App::setLocale(Helper::mapLegacyLocale($language));
return $next($request);
}
+7 -13
View File
@@ -34,8 +34,9 @@ class ImageUploadRequest extends Request
{
return [
'image' => 'mimes:png,gif,jpg,jpeg,svg,bmp,svg+xml,webp',
'avatar' => 'mimes:png,gif,jpg,jpeg,svg,bmp,svg+xml,webp',
'image' => 'mimes:png,gif,jpg,jpeg,svg,bmp,svg+xml,webp,avif',
'avatar' => 'mimes:png,gif,jpg,jpeg,svg,bmp,svg+xml,webp,avif',
'favicon' => 'mimes:png,gif,jpg,jpeg,svg,bmp,svg+xml,webp,image/x-icon,image/vnd.microsoft.icon,ico',
];
}
@@ -103,15 +104,13 @@ class ImageUploadRequest extends Request
\Log::info('File name will be: '.$file_name);
\Log::debug('File extension is: '.$ext);
if ($image->getMimeType() == 'image/webp') {
// If the file is a webp, we need to just move it since webp support
// needs to be compiled into gd for resizing to be available
\Log::debug('This is a webp, just move it');
if (($image->getMimeType() == 'image/vnd.microsoft.icon') || ($image->getMimeType() == 'image/x-icon') || ($image->getMimeType() == 'image/avif') || ($image->getMimeType() == 'image/webp')) {
// If the file is an icon, webp or avif, we need to just move it since gd doesn't support resizing
// icons or avif, and webp support and needs to be compiled into gd for resizing to be available
Storage::disk('public')->put($path.'/'.$file_name, file_get_contents($image));
} elseif($image->getMimeType() == 'image/svg+xml') {
// If the file is an SVG, we need to clean it and NOT encode it
\Log::debug('This is an SVG');
$sanitizer = new Sanitizer();
$dirtySVG = file_get_contents($image->getRealPath());
$cleanSVG = $sanitizer->sanitize($dirtySVG);
@@ -123,9 +122,6 @@ class ImageUploadRequest extends Request
}
} else {
\Log::debug('Not an SVG or webp - resize');
\Log::debug('Trying to upload to: '.$path.'/'.$file_name);
try {
$upload = Image::make($image->getRealPath())->setFileInfoFromPath($image->getRealPath())->resize(null, $w, function ($constraint) {
$constraint->aspectRatio();
@@ -147,10 +143,8 @@ class ImageUploadRequest extends Request
// Remove Current image if exists
if (($item->{$form_fieldname}!='') && (Storage::disk('public')->exists($path.'/'.$item->{$db_fieldname}))) {
\Log::debug('A file already exists that we are replacing - we should delete the old one.');
try {
Storage::disk('public')->delete($path.'/'.$item->{$form_fieldname});
\Log::debug('Old file '.$path.'/'.$file_name.' has been deleted.');
} catch (\Exception $e) {
\Log::debug('Could not delete old file. '.$path.'/'.$file_name.' does not exist?');
}
+49 -2
View File
@@ -4,6 +4,9 @@ namespace App\Http\Requests;
use App\Models\Asset;
use App\Models\Company;
use App\Models\Setting;
use Carbon\Carbon;
use Carbon\Exceptions\InvalidFormatException;
use Illuminate\Support\Facades\Gate;
class StoreAssetRequest extends ImageUploadRequest
@@ -27,6 +30,8 @@ class StoreAssetRequest extends ImageUploadRequest
? Company::getIdForCurrentUser($this->company_id)
: $this->company_id;
$this->parseLastAuditDate();
$this->merge([
'asset_tag' => $this->asset_tag ?? Asset::autoincrement_asset(),
'company_id' => $idForCurrentUser,
@@ -41,10 +46,52 @@ class StoreAssetRequest extends ImageUploadRequest
*/
public function rules(): array
{
$rules = array_merge(
(new Asset)->getRules(),
$modelRules = (new Asset)->getRules();
if (Setting::getSettings()->digit_separator === '1.234,56' && is_string($this->input('purchase_cost'))) {
// If purchase_cost was submitted as a string with a comma separator
// then we need to ignore the normal numeric rules.
// Since the original rules still live on the model they will be run
// right before saving (and after purchase_cost has been
// converted to a float via setPurchaseCostAttribute).
$modelRules = $this->removeNumericRulesFromPurchaseCost($modelRules);
}
return array_merge(
$modelRules,
parent::rules(),
);
}
private function parseLastAuditDate(): void
{
if ($this->input('last_audit_date')) {
try {
$lastAuditDate = Carbon::parse($this->input('last_audit_date'));
$this->merge([
'last_audit_date' => $lastAuditDate->startOfDay()->format('Y-m-d H:i:s'),
]);
} catch (InvalidFormatException $e) {
// we don't need to do anything here...
// we'll keep the provided date in an
// invalid format so validation picks it up later
}
}
}
private function removeNumericRulesFromPurchaseCost(array $rules): array
{
$purchaseCost = $rules['purchase_cost'];
// If rule is in "|" format then turn it into an array
if (is_string($purchaseCost)) {
$purchaseCost = explode('|', $purchaseCost);
}
$rules['purchase_cost'] = array_filter($purchaseCost, function ($rule) {
return $rule !== 'numeric' && $rule !== 'gte:0';
});
return $rules;
}
+1 -1
View File
@@ -27,7 +27,7 @@ class UploadFileRequest 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,xlsx,lic,xml,rtf,json,webp|max:'.$max_file_size,
'file.*' => 'required|mimes:png,gif,jpg,svg,jpeg,doc,docx,pdf,txt,zip,rar,xls,xlsx,lic,xml,rtf,json,webp,avif|max:'.$max_file_size,
];
}
@@ -88,6 +88,7 @@ class AssetsTransformer
'purchase_date' => Helper::getFormattedDateObject($asset->purchase_date, 'date'),
'age' => $asset->purchase_date ? $asset->purchase_date->diffForHumans() : '',
'last_checkout' => Helper::getFormattedDateObject($asset->last_checkout, 'datetime'),
'last_checkin' => Helper::getFormattedDateObject($asset->last_checkin, 'datetime'),
'expected_checkin' => Helper::getFormattedDateObject($asset->expected_checkin, 'date'),
'purchase_cost' => Helper::formatCurrencyOutput($asset->purchase_cost),
'checkin_counter' => (int) $asset->checkin_counter,
+69 -8
View File
@@ -74,9 +74,9 @@ class Asset extends Depreciable
'eol_explicit' => 'boolean',
'last_checkout' => 'datetime',
'last_checkin' => 'datetime',
'expected_checkin' => 'date',
'expected_checkin' => 'datetime:m-d-Y',
'last_audit_date' => 'datetime',
'next_audit_date' => 'date',
'next_audit_date' => 'datetime:m-d-Y',
'model_id' => 'integer',
'status_id' => 'integer',
'company_id' => 'integer',
@@ -96,7 +96,10 @@ class Asset extends Depreciable
'company_id' => 'nullable|integer|exists:companies,id',
'warranty_months' => 'nullable|numeric|digits_between:0,240',
'last_checkout' => 'nullable|date_format:Y-m-d H:i:s',
'last_checkin' => 'nullable|date_format:Y-m-d H:i:s',
'expected_checkin' => 'nullable|date',
'last_audit_date' => 'nullable|date_format:Y-m-d H:i:s',
'next_audit_date' => 'nullable|date|after:last_audit_date',
'location_id' => 'nullable|exists:locations,id',
'rtd_location_id' => 'nullable|exists:locations,id',
'purchase_date' => 'nullable|date|date_format:Y-m-d',
@@ -167,6 +170,8 @@ class Asset extends Depreciable
'expected_checkin',
'next_audit_date',
'last_audit_date',
'last_checkin',
'last_checkout',
'asset_eol_date',
];
@@ -1158,10 +1163,11 @@ class Asset extends Depreciable
public function scopeDueForAudit($query, $settings)
{
$interval = $settings->audit_warning_days ?? 0;
$today = Carbon::now();
$interval_date = $today->copy()->addDays($interval)->format('Y-m-d');
return $query->whereNotNull('assets.next_audit_date')
->where('assets.next_audit_date', '>=', Carbon::now())
->whereRaw("DATE_SUB(assets.next_audit_date, INTERVAL $interval DAY) <= '".Carbon::now()."'")
->whereBetween('assets.next_audit_date', [$today->format('Y-m-d'), $interval_date])
->where('assets.archived', '=', 0)
->NotArchived();
}
@@ -1183,7 +1189,7 @@ class Asset extends Depreciable
public function scopeOverdueForAudit($query)
{
return $query->whereNotNull('assets.next_audit_date')
->where('assets.next_audit_date', '<', Carbon::now())
->where('assets.next_audit_date', '<', Carbon::now()->format('Y-m-d'))
->where('assets.archived', '=', 0)
->NotArchived();
}
@@ -1204,14 +1210,69 @@ class Asset extends Depreciable
public function scopeDueOrOverdueForAudit($query, $settings)
{
$interval = $settings->audit_warning_days ?? 0;
return $query->whereNotNull('assets.next_audit_date')
->whereRaw('DATE_SUB('.DB::getTablePrefix()."assets.next_audit_date, INTERVAL $interval DAY) <= '".Carbon::now()."'")
return $query->where(function ($query) {
$query->OverdueForAudit();
})->orWhere(function ($query) use ($settings) {
$query->DueForAudit($settings);
});
}
/**
* Query builder scope for Assets that are DUE for checkin, based on the assets.expected_checkin
* and settings.audit_warning_days. It checks to see if assets.expected_checkin is now
*
* @author A. Gianotto <snipe@snipe.net>
* @since v6.4.0
* @return \Illuminate\Database\Query\Builder Modified query builder
*/
public function scopeDueForCheckin($query, $settings)
{
$interval = $settings->audit_warning_days ?? 0;
$today = Carbon::now();
$interval_date = $today->copy()->addDays($interval)->format('Y-m-d');
return $query->whereNotNull('assets.expected_checkin')
->whereBetween('assets.expected_checkin', [$today->format('Y-m-d'), $interval_date])
->where('assets.archived', '=', 0)
->whereNotNull('assets.assigned_to')
->NotArchived();
}
/**
* Query builder scope for Assets that are overdue for checkin OR overdue
*
* @author A. Gianotto <snipe@snipe.net>
* @since v6.4.0
* @return \Illuminate\Database\Query\Builder Modified query builder
*/
public function scopeOverdueForCheckin($query)
{
return $query->whereNotNull('assets.expected_checkin')
->where('assets.expected_checkin', '<', Carbon::now()->format('Y-m-d'))
->where('assets.archived', '=', 0)
->whereNotNull('assets.assigned_to')
->NotArchived();
}
/**
* Query builder scope for Assets that are due for checkin OR overdue
*
* @author A. Gianotto <snipe@snipe.net>
* @since v6.4.0
* @return \Illuminate\Database\Query\Builder Modified query builder
*/
public function scopeDueOrOverdueForCheckin($query, $settings)
{
return $query->where(function ($query) {
$query->OverdueForCheckin();
})->orWhere(function ($query) use ($settings) {
$query->DueForCheckin($settings);
});
}
/**
* Query builder scope for Archived assets counting
+134 -64
View File
@@ -81,26 +81,6 @@ final class Company extends SnipeModel
}
}
/**
* Scoping table queries, determining if a logged in user is part of a company, and only allows
* that user to see items associated with that company
*/
private static function scopeCompanyablesDirectly($query, $column = 'company_id', $table_name = null)
{
if (Auth::user()) {
$company_id = Auth::user()->company_id;
} else {
$company_id = null;
}
$table = ($table_name) ? $table_name."." : $query->getModel()->getTable().".";
if (\Schema::hasColumn($query->getModel()->getTable(), $column)) {
return $query->where($table.$column, '=', $company_id);
} else {
return $query->join('users as users_comp', 'users_comp.id', 'user_id')->where('users_comp.company_id', '=', $company_id);
}
}
public static function getIdFromInput($unescaped_input)
{
@@ -141,25 +121,49 @@ final class Company extends SnipeModel
}
}
/**
* Check to see if the current user should have access to the model.
* I hate this method and I think it should be refactored.
*
* @param $companyable
* @return bool|void
*/
public static function isCurrentUserHasAccess($companyable)
{
// When would this even happen tho??
if (is_null($companyable)) {
return false;
} elseif (! static::isFullMultipleCompanySupportEnabled()) {
return true;
} elseif (!$companyable instanceof Company && !\Schema::hasColumn($companyable->getModel()->getTable(), 'company_id')) {
// This is primary for the gate:allows-check in location->isDeletable()
// Locations don't have a company_id so without this it isn't possible to delete locations with FullMultipleCompanySupport enabled
// because this function is called by SnipePermissionsPolicy->before()
return true;
} else {
if (Auth::user()) {
$current_user_company_id = Auth::user()->company_id;
$companyable_company_id = $companyable->company_id;
}
return $current_user_company_id == null || $current_user_company_id == $companyable_company_id || Auth::user()->isSuperUser();
// If FMCS is not enabled, everyone has access, return true
if (! static::isFullMultipleCompanySupportEnabled()) {
return true;
}
// Again, where would this happen? But check that $companyable is not a string
if (!is_string($companyable)) {
$company_table = $companyable->getModel()->getTable();
try {
// This is primary for the gate:allows-check in location->isDeletable()
// Locations don't have a company_id so without this it isn't possible to delete locations with FullMultipleCompanySupport enabled
// because this function is called by SnipePermissionsPolicy->before()
if (!$companyable instanceof Company && !\Schema::hasColumn($company_table, 'company_id')) {
return true;
}
} catch (\Exception $e) {
\Log::warning($e);
}
}
if (Auth::user()) {
\Log::warning('Companyable is '.$companyable);
$current_user_company_id = Auth::user()->company_id;
$companyable_company_id = $companyable->company_id;
return $current_user_company_id == null || $current_user_company_id == $companyable_company_id || Auth::user()->isSuperUser();
}
}
public static function isCurrentUserAuthorized()
@@ -190,6 +194,10 @@ final class Company extends SnipeModel
&& ($this->users()->count() === 0);
}
/**
* @param $unescaped_input
* @return int|mixed|string|null
*/
public static function getIdForUser($unescaped_input)
{
if (! static::isFullMultipleCompanySupportEnabled() || Auth::user()->isSuperUser()) {
@@ -199,38 +207,6 @@ final class Company extends SnipeModel
}
}
public static function scopeCompanyables($query, $column = 'company_id', $table_name = null)
{
// If not logged in and hitting this, assume we are on the command line and don't scope?'
if (! static::isFullMultipleCompanySupportEnabled() || (Auth::check() && Auth::user()->isSuperUser()) || (! Auth::check())) {
return $query;
} else {
return static::scopeCompanyablesDirectly($query, $column, $table_name);
}
}
public static function scopeCompanyableChildren(array $companyable_names, $query)
{
if (count($companyable_names) == 0) {
throw new Exception('No Companyable Children to scope');
} elseif (! static::isFullMultipleCompanySupportEnabled() || (Auth::check() && Auth::user()->isSuperUser())) {
return $query;
} else {
$f = function ($q) {
static::scopeCompanyablesDirectly($q);
};
$q = $query->where(function ($q) use ($companyable_names, $f) {
$q2 = $q->whereHas($companyable_names[0], $f);
for ($i = 1; $i < count($companyable_names); $i++) {
$q2 = $q2->orWhereHas($companyable_names[$i], $f);
}
});
return $q;
}
}
public function users()
{
@@ -261,4 +237,98 @@ final class Company extends SnipeModel
{
return $this->hasMany(Component::class, 'company_id');
}
/**
* START COMPANY SCOPING FOR FMCS
*/
/**
* Scoping table queries, determining if a logged in user is part of a company, and only allows the user to access items associated with that company if FMCS is enabled.
*
* This method is the one that the CompanyableTrait uses to contrain queries automatically, however that trait CANNOT be
* applied to the user's model, since it causes an infinite loop against the authenticated user.
*
* @todo - refactor that trait to handle the user's model as well.
*
* @author [A. Gianotto] <snipe@snipe.net>
* @param $query
* @param $column
* @param $table_name
* @return mixed
*/
public static function scopeCompanyables($query, $column = 'company_id', $table_name = null)
{
// If not logged in and hitting this, assume we are on the command line and don't scope?'
if (! static::isFullMultipleCompanySupportEnabled() || (Auth::check() && Auth::user()->isSuperUser()) || (! Auth::check())) {
return $query;
} else {
\Log::debug('Fire scopeCompanyablesDirectly.');
return static::scopeCompanyablesDirectly($query, $column, $table_name);
}
}
/**
* Scoping table queries, determining if a logged in user is part of a company, and only allows
* that user to see items associated with that company
*/
private static function scopeCompanyablesDirectly($query, $column = 'company_id', $table_name = null)
{
// Get the company ID of the logged in user, or set it to null if there is no company assicoated with the user
if (Auth::user()) {
\Log::debug('Admin company is: '.Auth::user()->company_id);
$company_id = Auth::user()->company_id;
} else {
$company_id = null;
}
// Dynamically get the table name if it's not passed in, based on the model we're querying against
$table = ($table_name) ? $table_name."." : $query->getModel()->getTable().".";
\Log::debug('Model is: '.$query->getModel());
\Log::debug('Table is: '.$table);
// If the column exists in the table, use it to scope the query
if (\Schema::hasColumn($query->getModel()->getTable(), $column)) {
return $query->where($table.$column, '=', $company_id);
} else {
return $query->join('users as users_comp', 'users_comp.id', 'user_id')->where('users_comp.company_id', '=', $company_id);
}
}
/**
* I legit do not know what this method does, but we can't remove it (yet).
*
* This gets invoked by CompanyableChildScope, but I'm not sure what it does.
*
* @author [A. Gianotto] <snipe@snipe.net>
* @param array $companyable_names
* @param $query
* @return mixed
*/
public static function scopeCompanyableChildren(array $companyable_names, $query)
{
\Log::debug('Company Names in scopeCompanyableChildren: '.print_r($companyable_names, true));
if (count($companyable_names) == 0) {
throw new Exception('No Companyable Children to scope');
} elseif (! static::isFullMultipleCompanySupportEnabled() || (Auth::check() && Auth::user()->isSuperUser())) {
return $query;
} else {
$f = function ($q) {
\Log::debug('scopeCompanyablesDirectly firing ');
static::scopeCompanyablesDirectly($q);
};
$q = $query->where(function ($q) use ($companyable_names, $f) {
$q2 = $q->whereHas($companyable_names[0], $f);
for ($i = 1; $i < count($companyable_names); $i++) {
$q2 = $q2->orWhereHas($companyable_names[$i], $f);
}
});
return $q;
}
}
}
+6 -1
View File
@@ -5,8 +5,13 @@ namespace App\Models;
trait CompanyableTrait
{
/**
* Boot the companyable trait for a model.
* This trait is used to scope models to the current company. To use this scope on companyable models,
* we use the "use Companyable;" statement at the top of the mode.
*
* We CANNOT USE THIS ON USERS, as it causes an infinite loop and prevents users from logging in, since this scope will be
* applied to the currently logged in (or logging in) user in addition to the user model for viewing lists of users.
*
* @see \App\Models\Company\Company::scopeCompanyables()
* @return void
*/
public static function bootCompanyableTrait()
+15 -2
View File
@@ -5,6 +5,8 @@ namespace App\Models;
use Gate;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Log;
use Illuminate\Validation\Rule;
use Watson\Validating\ValidatingTrait;
class CustomFieldset extends Model
@@ -92,8 +94,19 @@ class CustomFieldset extends Model
array_push($rule, $field->attributes['format']);
$rules[$field->db_column_name()] = $rule;
//add not_array to rules for all fields
$rules[$field->db_column_name()][] = 'not_array';
// add not_array to rules for all fields but checkboxes
if ($field->element != 'checkbox') {
$rules[$field->db_column_name()][] = 'not_array';
}
if ($field->element == 'checkbox') {
$rules[$field->db_column_name()][] = 'checkboxes';
}
if ($field->element == 'radio') {
$rules[$field->db_column_name()][] = 'radio_buttons';
}
}
return $rules;
+6 -3
View File
@@ -160,18 +160,21 @@ class DefaultLabel extends RectangleSheet
$textY += $this->textSize + self::TEXT_MARGIN;
}
// Fields
// Render the selected fields with their labels
$fieldsDone = 0;
if ($fieldsDone < $this->getSupportFields()) {
// dd($record->get('fields'));
foreach ($record->get('fields') as $field) {
// Actually write the selected fields and their matching values
static::writeText(
$pdf, $field['label'][0]. ': ' . $field['value'],
$pdf, (($field['label']) ? $field['label'].' ' : '') . $field['value'],
$textX1, $textY,
'freesans', '', $this->textSize, 'L',
$textW, $this->textSize,
true, 0
);
$textY += $this->textSize + self::TEXT_MARGIN;
$fieldsDone++;
}
+8 -2
View File
@@ -18,8 +18,14 @@ class FieldOption {
// assignedTo directly on the asset is a special case where
// we want to avoid returning the property directly
// and instead return the entity's presented name.
if ($dataPath[0] === 'assignedTo'){
return $asset->assignedTo ? $asset->assignedTo->present()->fullName() : null;
if ($dataPath[0] === 'assignedTo') {
if ($asset->relationLoaded('assignedTo')) {
// If the "assignedTo" relationship was eager loaded then the way to get the
// relationship changes from $asset->assignedTo to $asset->assigned.
return $asset->assigned ? $asset->assigned->present()->fullName() : null;
}
return $asset->assignedTo ? $asset->assignedTo->present()->fullName() : null;
}
return $dataPath->reduce(function ($myValue, $path) {
@@ -0,0 +1,19 @@
<?php
namespace App\Models\Labels\Tapes\Brother;
use App\Helpers\Helper;
use App\Models\Labels\Label;
abstract class TZe_18mm extends Label
{
private const HEIGHT = 18.00;
private const MARGIN_SIDES = 3.20;
private const MARGIN_ENDS = 3.20;
public function getHeight() { return Helper::convertUnit(self::HEIGHT, 'mm', $this->getUnit()); }
public function getMarginTop() { return Helper::convertUnit(self::MARGIN_SIDES, 'mm', $this->getUnit()); }
public function getMarginBottom() { return Helper::convertUnit(self::MARGIN_SIDES, 'mm', $this->getUnit());}
public function getMarginLeft() { return Helper::convertUnit(self::MARGIN_ENDS, 'mm', $this->getUnit()); }
public function getMarginRight() { return Helper::convertUnit(self::MARGIN_ENDS, 'mm', $this->getUnit()); }
}
@@ -0,0 +1,56 @@
<?php
namespace App\Models\Labels\Tapes\Brother;
class TZe_18mm_A extends TZe_18mm
{
private const BARCODE_SIZE = 3.20;
private const BARCODE_MARGIN = 0.30;
private const TEXT_SIZE_MOD = 1.00;
public function getUnit() { return 'mm'; }
public function getWidth() { return 50.0; }
public function getSupportAssetTag() { return true; }
public function getSupport1DBarcode() { return true; }
public function getSupport2DBarcode() { return false; }
public function getSupportFields() { return 1; }
public function getSupportLogo() { return false; }
public function getSupportTitle() { return false; }
public function preparePDF($pdf) {}
public function write($pdf, $record) {
$pa = $this->getPrintableArea();
if ($record->has('barcode1d')) {
static::write1DBarcode(
$pdf, $record->get('barcode1d')->content, $record->get('barcode1d')->type,
$pa->x1, $pa->y1, $pa->w, self::BARCODE_SIZE
);
}
$currentY = $pa->y1 + self::BARCODE_SIZE + self::BARCODE_MARGIN;
$usableHeight = $pa->h - self::BARCODE_SIZE - self::BARCODE_MARGIN;
$fontSize = $usableHeight + self::TEXT_SIZE_MOD;
$tagWidth = $pa->w / 3;
$fieldWidth = $pa->w / 3 * 2;
static::writeText(
$pdf, $record->get('tag'),
$pa->x1, $currentY,
'freemono', 'b', $fontSize, 'L',
$tagWidth, $usableHeight, true, 0, 0
);
if ($record->get('fields')->count() >= 1) {
static::writeText(
$pdf, $record->get('fields')->values()->get(0)['value'],
$pa->x1 + ($tagWidth), $currentY,
'freemono', 'b', $fontSize, 'R',
$fieldWidth, $usableHeight, true, 0, 0
);
}
}
}
@@ -0,0 +1,89 @@
<?php
namespace App\Models\Labels\Tapes\Dymo;
class LabelWriter_1933081 extends LabelWriter
{
private const BARCODE_MARGIN = 1.80;
private const TAG_SIZE = 2.80;
private const TITLE_SIZE = 2.80;
private const TITLE_MARGIN = 0.50;
private const LABEL_SIZE = 2.80;
private const LABEL_MARGIN = - 0.35;
private const FIELD_SIZE = 2.80;
private const FIELD_MARGIN = 0.15;
public function getUnit() { return 'mm'; }
public function getWidth() { return 89; }
public function getHeight() { return 25; }
public function getSupportAssetTag() { return true; }
public function getSupport1DBarcode() { return true; }
public function getSupport2DBarcode() { return true; }
public function getSupportFields() { return 5; }
public function getSupportLogo() { return false; }
public function getSupportTitle() { return true; }
public function preparePDF($pdf) {}
public function write($pdf, $record) {
$pa = $this->getPrintableArea();
$currentX = $pa->x1;
$currentY = $pa->y1;
$usableWidth = $pa->w;
$barcodeSize = $pa->h - self::TAG_SIZE;
if ($record->has('barcode2d')) {
static::writeText(
$pdf, $record->get('tag'),
$pa->x1, $pa->y2 - self::TAG_SIZE,
'freesans', 'b', self::TAG_SIZE, 'C',
$barcodeSize, self::TAG_SIZE, true, 0
);
static::write2DBarcode(
$pdf, $record->get('barcode2d')->content, $record->get('barcode2d')->type,
$currentX, $currentY,
$barcodeSize, $barcodeSize
);
$currentX += $barcodeSize + self::BARCODE_MARGIN;
$usableWidth -= $barcodeSize + self::BARCODE_MARGIN;
} else {
static::writeText(
$pdf, $record->get('tag'),
$pa->x1, $pa->y2 - self::TAG_SIZE,
'freesans', 'b', self::TAG_SIZE, 'R',
$usableWidth, self::TAG_SIZE, true, 0
);
}
if ($record->has('title')) {
static::writeText(
$pdf, $record->get('title'),
$currentX, $currentY,
'freesans', 'b', self::TITLE_SIZE, 'L',
$usableWidth, self::TITLE_SIZE, true, 0
);
$currentY += self::TITLE_SIZE + self::TITLE_MARGIN;
}
foreach ($record->get('fields') as $field) {
static::writeText(
$pdf, (($field['label']) ? $field['label'].' ' : '') . $field['value'],
$currentX, $currentY,
'freesans', '', self::FIELD_SIZE, 'L',
$usableWidth, self::FIELD_SIZE, true, 0, 0.3
);
$currentY += self::FIELD_SIZE + self::FIELD_MARGIN;
}
if ($record->has('barcode1d')) {
static::write1DBarcode(
$pdf, $record->get('barcode1d')->content, $record->get('barcode1d')->type,
$currentX, $barcodeSize + self::BARCODE_MARGIN, $usableWidth - self::TAG_SIZE, self::TAG_SIZE
);
}
}
}
@@ -0,0 +1,89 @@
<?php
namespace App\Models\Labels\Tapes\Dymo;
class LabelWriter_2112283 extends LabelWriter
{
private const BARCODE_MARGIN = 1.80;
private const TAG_SIZE = 2.80;
private const TITLE_SIZE = 2.80;
private const TITLE_MARGIN = 0.50;
private const LABEL_SIZE = 2.80;
private const LABEL_MARGIN = - 0.35;
private const FIELD_SIZE = 2.80;
private const FIELD_MARGIN = 0.15;
public function getUnit() { return 'mm'; }
public function getWidth() { return 54; }
public function getHeight() { return 25; }
public function getSupportAssetTag() { return true; }
public function getSupport1DBarcode() { return true; }
public function getSupport2DBarcode() { return true; }
public function getSupportFields() { return 5; }
public function getSupportLogo() { return false; }
public function getSupportTitle() { return true; }
public function preparePDF($pdf) {}
public function write($pdf, $record) {
$pa = $this->getPrintableArea();
$currentX = $pa->x1;
$currentY = $pa->y1;
$usableWidth = $pa->w;
$barcodeSize = $pa->h - self::TAG_SIZE;
if ($record->has('barcode2d')) {
static::writeText(
$pdf, $record->get('tag'),
$pa->x1, $pa->y2 - self::TAG_SIZE,
'freesans', 'b', self::TAG_SIZE, 'C',
$barcodeSize, self::TAG_SIZE, true, 0
);
static::write2DBarcode(
$pdf, $record->get('barcode2d')->content, $record->get('barcode2d')->type,
$currentX, $currentY,
$barcodeSize, $barcodeSize
);
$currentX += $barcodeSize + self::BARCODE_MARGIN;
$usableWidth -= $barcodeSize + self::BARCODE_MARGIN;
} else {
static::writeText(
$pdf, $record->get('tag'),
$pa->x1, $pa->y2 - self::TAG_SIZE,
'freesans', 'b', self::TAG_SIZE, 'R',
$usableWidth, self::TAG_SIZE, true, 0
);
}
if ($record->has('title')) {
static::writeText(
$pdf, $record->get('title'),
$currentX, $currentY,
'freesans', 'b', self::TITLE_SIZE, 'L',
$usableWidth, self::TITLE_SIZE, true, 0
);
$currentY += self::TITLE_SIZE + self::TITLE_MARGIN;
}
foreach ($record->get('fields') as $field) {
static::writeText(
$pdf, (($field['label']) ? $field['label'].' ' : '') . $field['value'],
$currentX, $currentY,
'freesans', '', self::FIELD_SIZE, 'L',
$usableWidth, self::FIELD_SIZE, true, 0, 0.3
);
$currentY += self::FIELD_SIZE + self::FIELD_MARGIN;
}
if ($record->has('barcode1d')) {
static::write1DBarcode(
$pdf, $record->get('barcode1d')->content, $record->get('barcode1d')->type,
$currentX, $barcodeSize + self::BARCODE_MARGIN, $usableWidth - self::TAG_SIZE, self::TAG_SIZE
);
}
}
}
+20 -2
View File
@@ -81,6 +81,7 @@ class License extends Depreciable
'serial',
'supplier_id',
'termination_date',
'free_seat_count',
'user_id',
'min_amt',
];
@@ -114,6 +115,7 @@ class License extends Depreciable
'category' => ['name'],
'depreciation' => ['name'],
];
protected $appends = ['free_seat_count'];
/**
* Update seat counts when the license is updated
@@ -280,6 +282,16 @@ class License extends Depreciable
}
$this->attributes['termination_date'] = $value;
}
/**
* Sets free_seat_count attribute
*
* @author G. Martinez
* @since [v6.3]
* @return mixed
*/
public function getFreeSeatCountAttribute(){
return $this->attributes['free_seat_count'] = $this->remaincount();
}
/**
* Establishes the license -> company relationship
@@ -502,7 +514,13 @@ class License extends Depreciable
->whereNull('deleted_at')
->count();
}
/**
* Returns the available seats remaining
*
* @author A. Gianotto <snipe@snipe.net>
* @since [v2.0]
* @return int
*/
/**
* Returns the number of total available seats for this license
@@ -579,7 +597,7 @@ class License extends Depreciable
$taken = $this->assigned_seats_count;
$diff = ($total - $taken);
return $diff;
return (int) $diff;
}
/**
+1
View File
@@ -106,6 +106,7 @@ class Location extends SnipeModel
*/
public function isDeletable()
{
return Gate::allows('delete', $this)
&& ($this->assets_count === 0)
&& ($this->assigned_assets_count === 0)
+1 -1
View File
@@ -337,7 +337,7 @@ class User extends SnipeModel implements AuthenticatableContract, AuthorizableCo
*/
public function licenses()
{
return $this->belongsToMany(\App\Models\License::class, 'license_seats', 'assigned_to', 'license_id')->withPivot('id');
return $this->belongsToMany(\App\Models\License::class, 'license_seats', 'assigned_to', 'license_id')->withPivot('id', 'created_at', 'updated_at');
}
/**
+39 -5
View File
@@ -35,16 +35,50 @@ abstract class SnipePermissionsPolicy
public function before(User $user, $ability, $item)
{
// Lets move all company related checks here.
if ($item instanceof \App\Models\SnipeModel && ! Company::isCurrentUserHasAccess($item)) {
return false;
}
// If an admin, they can do all asset related tasks.
/**
* If an admin, they can do all item related tasks, but ARE constrained by FMCSA company access.
* That scoping happens on the model level (except for the Users model) via the Companyable trait.
*
* This does lead to some inconsistencies in the responses, since attempting to edit assets,
* accessories, etc (anything other than users) will result in a Forbidden error, whereas the users
* area will redirect with "That user doesn't exist" since the scoping is handled directly on those queries.
*
* The *superuser* global permission gets handled in the AuthServiceProvider before() method.
*
* @see https://snipe-it.readme.io/docs/permissions
*/
if ($user->hasAccess('admin')) {
return true;
}
/**
* If we got here by $this→authorize('something', $actualModel) then we can continue on Il but if we got here
* via $this→authorize('something', Model::class) then calling Company:: isCurrentUserHasAccess($item) gets weird.
* Bail out here by returning "nothing" and allow the relevant method lower in this class to be called and handle authorization.
*/
if (!$item instanceof Model){
return;
}
/**
* The Company::isCurrentUserHasAccess() method from the company model handles the check for FMCS already so we
* don't have to do that here.
*/
if (!Company::isCurrentUserHasAccess($item)) {
return false;
}
}
/**
* These methods handle the generic view/create/edit/delete permissions for the model.
*
* @param User $user
* @return bool
*/
public function index(User $user)
{
return $user->hasAccess($this->columnName().'.view');
+1
View File
@@ -41,6 +41,7 @@ class AccessoryPresenter extends Presenter
'field' => 'name',
'searchable' => true,
'sortable' => true,
'switchable' => false,
'title' => trans('general.name'),
'formatter' => 'accessoriesLinkFormatter',
], [
+6 -1
View File
@@ -38,10 +38,14 @@ class ActionlogPresenter extends Presenter
public function icon()
{
// User related icons
if ($this->itemType() == 'user') {
if ($this->actionType()=='2fa reset') {
return 'fa-solid fa-mobile-screen';
}
if ($this->actionType()=='create new') {
return 'fa-solid fa-user-plus';
}
@@ -61,6 +65,7 @@ class ActionlogPresenter extends Presenter
if ($this->actionType()=='update') {
return 'fa-solid fa-user-pen';
}
return 'fa-solid fa-user';
}
@@ -85,6 +85,7 @@ class AssetMaintenancesPresenter extends Presenter
'field' => 'title',
'searchable' => true,
'sortable' => true,
'switchable' => false,
'title' => trans('admin/asset_maintenances/form.title'),
], [
'field' => 'start_date',
+1
View File
@@ -35,6 +35,7 @@ class AssetModelPresenter extends Presenter
'field' => 'name',
'searchable' => true,
'sortable' => true,
'switchable' => false,
'visible' => true,
'title' => trans('general.name'),
'formatter' => 'modelsLinkFormatter',
+9 -1
View File
@@ -55,6 +55,7 @@ class AssetPresenter extends Presenter
'field' => 'asset_tag',
'searchable' => true,
'sortable' => true,
'switchable' => false,
'title' => trans('admin/hardware/table.asset_tag'),
'visible' => true,
'formatter' => 'hardwareLinkFormatter',
@@ -252,6 +253,13 @@ class AssetPresenter extends Presenter
'visible' => false,
'title' => trans('admin/hardware/table.checkout_date'),
'formatter' => 'dateDisplayFormatter',
], [
'field' => 'last_checkin',
'searchable' => false,
'sortable' => true,
'visible' => false,
'title' => trans('admin/hardware/table.last_checkin_date'),
'formatter' => 'dateDisplayFormatter',
], [
'field' => 'expected_checkin',
'searchable' => false,
@@ -316,7 +324,7 @@ class AssetPresenter extends Presenter
'field' => 'checkincheckout',
'searchable' => false,
'sortable' => false,
'switchable' => true,
'switchable' => false,
'title' => trans('general.checkin').'/'.trans('general.checkout'),
'visible' => true,
'formatter' => 'hardwareInOutFormatter',
+1
View File
@@ -25,6 +25,7 @@ class CategoryPresenter extends Presenter
'field' => 'name',
'searchable' => true,
'sortable' => true,
'switchable' => false,
'title' => trans('general.name'),
'visible' => true,
'formatter' => 'categoriesLinkFormatter',
+1 -1
View File
@@ -25,7 +25,7 @@ class CompanyPresenter extends Presenter
'field' => 'name',
'searchable' => true,
'sortable' => true,
'switchable' => true,
'switchable' => false,
'title' => trans('admin/companies/table.name'),
'visible' => true,
'formatter' => 'companiesLinkFormatter',
+1 -1
View File
@@ -126,7 +126,7 @@ class ComponentPresenter extends Presenter
'field' => 'checkincheckout',
'searchable' => false,
'sortable' => false,
'switchable' => true,
'switchable' => false,
'title' => trans('general.checkin').'/'.trans('general.checkout'),
'visible' => true,
'formatter' => 'componentsInOutFormatter',
+1
View File
@@ -35,6 +35,7 @@ class ConsumablePresenter extends Presenter
'field' => 'name',
'searchable' => true,
'sortable' => true,
'switchable' => false,
'title' => trans('general.name'),
'visible' => true,
'formatter' => 'consumablesLinkFormatter',
+1
View File
@@ -25,6 +25,7 @@ class DepreciationPresenter extends Presenter
'field' => 'name',
'searchable' => true,
'sortable' => true,
'switchable' => false,
'title' => trans('general.name'),
'visible' => true,
'formatter' => 'depreciationsLinkFormatter',
@@ -34,6 +34,7 @@ class DepreciationReportPresenter extends Presenter
"field" => "name",
"searchable" => true,
"sortable" => true,
'switchable' => false,
"title" => trans('admin/hardware/form.name'),
"visible" => false,
], [
+3 -2
View File
@@ -33,6 +33,7 @@ class LicensePresenter extends Presenter
'field' => 'name',
'searchable' => true,
'sortable' => true,
'switchable' => false,
'title' => trans('general.name'),
'formatter' => 'licensesLinkFormatter',
], [
@@ -186,7 +187,7 @@ class LicensePresenter extends Presenter
'field' => 'checkincheckout',
'searchable' => false,
'sortable' => false,
'switchable' => true,
'switchable' => false,
'title' => trans('general.checkin').'/'.trans('general.checkout'),
'visible' => true,
'formatter' => 'licensesInOutFormatter',
@@ -280,7 +281,7 @@ class LicensePresenter extends Presenter
'field' => 'checkincheckout',
'searchable' => false,
'sortable' => false,
'switchable' => true,
'switchable' => false,
'title' => trans('general.checkin').'/'.trans('general.checkout'),
'visible' => true,
'formatter' => 'licenseSeatInOutFormatter',
+1
View File
@@ -31,6 +31,7 @@ class LocationPresenter extends Presenter
'field' => 'name',
'searchable' => true,
'sortable' => true,
'switchable' => false,
'title' => trans('admin/locations/table.name'),
'visible' => true,
'formatter' => 'locationsLinkFormatter',
+1
View File
@@ -27,6 +27,7 @@ class ManufacturerPresenter extends Presenter
'field' => 'name',
'searchable' => true,
'sortable' => true,
'switchable' => false,
'title' => trans('admin/manufacturers/table.name'),
'visible' => true,
'formatter' => 'manufacturersLinkFormatter',
+2 -2
View File
@@ -38,7 +38,7 @@ class UserPresenter extends Presenter
'searchable' => false,
'sortable' => false,
'switchable' => true,
'title' => 'Avatar',
'title' => trans('general.importer.avatar'),
'visible' => false,
'formatter' => 'imageFormatter',
],
@@ -175,7 +175,7 @@ class UserPresenter extends Presenter
'field' => 'username',
'searchable' => true,
'sortable' => true,
'switchable' => true,
'switchable' => false,
'title' => trans('admin/users/table.username'),
'visible' => true,
'formatter' => 'usersLinkFormatter',
+16 -9
View File
@@ -93,21 +93,28 @@ class AuthServiceProvider extends ServiceProvider
Passport::personalAccessTokensExpireIn(Carbon::now()->addYears(config('passport.expiration_years')));
Passport::withCookieSerialization();
// --------------------------------
// BEFORE ANYTHING ELSE
// --------------------------------
// If this condition is true, ANYTHING else below will be assumed
// to be true. This can cause weird blade behavior.
/**
* BEFORE ANYTHING ELSE
*
* If this condition is true, ANYTHING else below will be assumed to be true.
* This is where we set the superadmin permission to allow superadmins to be able to do everything within the system.
*
*/
Gate::before(function ($user) {
if ($user->isSuperUser()) {
return true;
}
});
// --------------------------------
// GENERAL GATES
// These control general sections of the admin
// --------------------------------
/**
* GENERAL GATES
*
* These control general sections of the admin. These definitions are used in our blades via @can('blah) and also
* use in our controllers to determine if a user has access to a certain area.
*/
Gate::define('admin', function ($user) {
if ($user->hasAccess('admin')) {
return true;
+56 -2
View File
@@ -2,9 +2,12 @@
namespace App\Providers;
use App\Models\CustomField;
use App\Models\Department;
use App\Models\Setting;
use DB;
use Illuminate\Support\Facades\Crypt;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\ServiceProvider;
use Illuminate\Validation\Rule;
use Validator;
@@ -276,7 +279,24 @@ class ValidationServiceProvider extends ServiceProvider
Validator::extend('is_unique_department', function ($attribute, $value, $parameters, $validator) {
$data = $validator->getData();
if ((array_key_exists('location_id', $data) && $data['location_id'] != null) && (array_key_exists('company_id', $data) && $data['company_id'] != null)) {
if (
array_key_exists('location_id', $data) && $data['location_id'] !== null &&
array_key_exists('company_id', $data) && $data['company_id'] !== null
) {
//for updating existing departments
if(array_key_exists('id', $data) && $data['id'] !== null){
$count = Department::where('name', $data['name'])
->where('location_id', $data['location_id'])
->where('company_id', $data['company_id'])
->whereNotNull('company_id')
->whereNotNull('location_id')
->where('id', '!=', $data['id'])
->count('name');
return $count < 1;
}else // for entering in new departments
{
$count = Department::where('name', $data['name'])
->where('location_id', $data['location_id'])
->where('company_id', $data['company_id'])
@@ -286,14 +306,48 @@ class ValidationServiceProvider extends ServiceProvider
return $count < 1;
}
}
else {
return true;
}
}
});
Validator::extend('not_array', function ($attribute, $value, $parameters, $validator) {
return !is_array($value);
});
// This is only used in Models/CustomFieldset.php - it does automatic validation for checkboxes by making sure
// that the submitted values actually exist in the options.
Validator::extend('checkboxes', function ($attribute, $value, $parameters, $validator){
$field = CustomField::where('db_column', $attribute)->first();
$options = $field->formatFieldValuesAsArray();
if(is_array($value)) {
$invalid = array_diff($value, $options);
if(count($invalid) > 0) {
return false;
}
}
// for legacy, allows users to submit a comma separated string of options
elseif(!is_array($value)) {
$exploded = array_map('trim', explode(',', $value));
$invalid = array_diff($exploded, $options);
if(count($invalid) > 0) {
return false;
}
}
return true;
});
// Validates that a radio button option exists
Validator::extend('radio_buttons', function ($attribute, $value) {
$field = CustomField::where('db_column', $attribute)->first();
$options = $field->formatFieldValuesAsArray();
return in_array($value, $options);
});
}
/**
+26 -1
View File
@@ -142,7 +142,32 @@ class Label implements View
// Remove Duplicates
$toAdd = $field
->filter(fn($o) => !$myFields->contains('dataSource', $o['dataSource']))
->first();
// For fields that have multiple options, we need to combine them
// into a single field so all values are displayed.
->reduce(function ($previous, $current) {
// On the first iteration we simply return the item.
// If there is only one item to be processed for the row
// then this effectively skips everything below this if block.
if (is_null($previous)) {
return $current;
}
// At this point we are dealing with a row with multiple items being displayed.
// We need to combine the label and value of the current item with the previous item.
// The end result of this will be in this format:
// {labelOne} {valueOne} | {labelTwo} {valueTwo} | {labelThree} {valueThree}
$previous['value'] = trim(implode(' | ', [
implode(' ', [$previous['label'], $previous['value']]),
implode(' ', [$current['label'], $current['value']]),
]));
// We'll set the label to an empty string since we
// injected the label into the value field above.
$previous['label'] = '';
return $previous;
});
return $toAdd ? $myFields->push($toAdd) : $myFields;
}, new Collection());
-1
View File
@@ -58,7 +58,6 @@
"league/flysystem-aws-s3-v3": "^1.0",
"league/flysystem-cached-adapter": "^1.1",
"livewire/livewire": "^2.4",
"mediconesystems/livewire-datatables": "^0.5.0",
"neitanod/forceutf8": "^2.0",
"nesbot/carbon": "^2.32",
"nunomaduro/collision": "^5.4",
Generated
+9 -549
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": "9cca85cd0074df9154765b1ab52f83fa",
"content-hash": "0536c48de3ba12fdeb01bac07fcd7172",
"packages": [
{
"name": "alek13/slack",
@@ -2165,57 +2165,6 @@
},
"time": "2019-12-30T22:54:17+00:00"
},
{
"name": "ezyang/htmlpurifier",
"version": "v4.14.0",
"source": {
"type": "git",
"url": "https://github.com/ezyang/htmlpurifier.git",
"reference": "12ab42bd6e742c70c0a52f7b82477fcd44e64b75"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/ezyang/htmlpurifier/zipball/12ab42bd6e742c70c0a52f7b82477fcd44e64b75",
"reference": "12ab42bd6e742c70c0a52f7b82477fcd44e64b75",
"shasum": ""
},
"require": {
"php": ">=5.2"
},
"type": "library",
"autoload": {
"files": [
"library/HTMLPurifier.composer.php"
],
"psr-0": {
"HTMLPurifier": "library/"
},
"exclude-from-classmap": [
"/library/HTMLPurifier/Language/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"LGPL-2.1-or-later"
],
"authors": [
{
"name": "Edward Z. Yang",
"email": "admin@htmlpurifier.org",
"homepage": "http://ezyang.com"
}
],
"description": "Standards compliant HTML filter written in PHP",
"homepage": "http://htmlpurifier.org/",
"keywords": [
"html"
],
"support": {
"issues": "https://github.com/ezyang/htmlpurifier/issues",
"source": "https://github.com/ezyang/htmlpurifier/tree/v4.14.0"
},
"time": "2021-12-25T01:21:49+00:00"
},
{
"name": "facade/flare-client-php",
"version": "1.9.1",
@@ -5133,268 +5082,6 @@
],
"time": "2022-06-19T02:54:20+00:00"
},
{
"name": "maatwebsite/excel",
"version": "3.1.40",
"source": {
"type": "git",
"url": "https://github.com/SpartnerNL/Laravel-Excel.git",
"reference": "8a54972e3d616c74687c3cbff15765555761885c"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/SpartnerNL/Laravel-Excel/zipball/8a54972e3d616c74687c3cbff15765555761885c",
"reference": "8a54972e3d616c74687c3cbff15765555761885c",
"shasum": ""
},
"require": {
"ext-json": "*",
"illuminate/support": "5.8.*|^6.0|^7.0|^8.0|^9.0",
"php": "^7.0|^8.0",
"phpoffice/phpspreadsheet": "^1.18"
},
"require-dev": {
"orchestra/testbench": "^6.0|^7.0",
"predis/predis": "^1.1"
},
"type": "library",
"extra": {
"laravel": {
"providers": [
"Maatwebsite\\Excel\\ExcelServiceProvider"
],
"aliases": {
"Excel": "Maatwebsite\\Excel\\Facades\\Excel"
}
}
},
"autoload": {
"psr-4": {
"Maatwebsite\\Excel\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Patrick Brouwers",
"email": "patrick@spartner.nl"
}
],
"description": "Supercharged Excel exports and imports in Laravel",
"keywords": [
"PHPExcel",
"batch",
"csv",
"excel",
"export",
"import",
"laravel",
"php",
"phpspreadsheet"
],
"support": {
"issues": "https://github.com/SpartnerNL/Laravel-Excel/issues",
"source": "https://github.com/SpartnerNL/Laravel-Excel/tree/3.1.40"
},
"funding": [
{
"url": "https://laravel-excel.com/commercial-support",
"type": "custom"
},
{
"url": "https://github.com/patrickbrouwers",
"type": "github"
}
],
"time": "2022-05-02T13:50:01+00:00"
},
{
"name": "maennchen/zipstream-php",
"version": "2.2.1",
"source": {
"type": "git",
"url": "https://github.com/maennchen/ZipStream-PHP.git",
"reference": "211e9ba1530ea5260b45d90c9ea252f56ec52729"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/maennchen/ZipStream-PHP/zipball/211e9ba1530ea5260b45d90c9ea252f56ec52729",
"reference": "211e9ba1530ea5260b45d90c9ea252f56ec52729",
"shasum": ""
},
"require": {
"myclabs/php-enum": "^1.5",
"php": "^7.4 || ^8.0",
"psr/http-message": "^1.0",
"symfony/polyfill-mbstring": "^1.0"
},
"require-dev": {
"ext-zip": "*",
"guzzlehttp/guzzle": "^6.5.3 || ^7.2.0",
"mikey179/vfsstream": "^1.6",
"php-coveralls/php-coveralls": "^2.4",
"phpunit/phpunit": "^8.5.8 || ^9.4.2",
"vimeo/psalm": "^4.1"
},
"type": "library",
"autoload": {
"psr-4": {
"ZipStream\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Paul Duncan",
"email": "pabs@pablotron.org"
},
{
"name": "Jonatan Männchen",
"email": "jonatan@maennchen.ch"
},
{
"name": "Jesse Donat",
"email": "donatj@gmail.com"
},
{
"name": "András Kolesár",
"email": "kolesar@kolesar.hu"
}
],
"description": "ZipStream is a library for dynamically streaming dynamic zip files from PHP without writing to the disk at all on the server.",
"keywords": [
"stream",
"zip"
],
"support": {
"issues": "https://github.com/maennchen/ZipStream-PHP/issues",
"source": "https://github.com/maennchen/ZipStream-PHP/tree/2.2.1"
},
"funding": [
{
"url": "https://github.com/maennchen",
"type": "github"
},
{
"url": "https://opencollective.com/zipstream",
"type": "open_collective"
}
],
"time": "2022-05-18T15:52:06+00:00"
},
{
"name": "markbaker/complex",
"version": "3.0.1",
"source": {
"type": "git",
"url": "https://github.com/MarkBaker/PHPComplex.git",
"reference": "ab8bc271e404909db09ff2d5ffa1e538085c0f22"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/MarkBaker/PHPComplex/zipball/ab8bc271e404909db09ff2d5ffa1e538085c0f22",
"reference": "ab8bc271e404909db09ff2d5ffa1e538085c0f22",
"shasum": ""
},
"require": {
"php": "^7.2 || ^8.0"
},
"require-dev": {
"dealerdirect/phpcodesniffer-composer-installer": "^0.7.0",
"phpcompatibility/php-compatibility": "^9.0",
"phpunit/phpunit": "^7.0 || ^8.0 || ^9.3",
"squizlabs/php_codesniffer": "^3.4"
},
"type": "library",
"autoload": {
"psr-4": {
"Complex\\": "classes/src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Mark Baker",
"email": "mark@lange.demon.co.uk"
}
],
"description": "PHP Class for working with complex numbers",
"homepage": "https://github.com/MarkBaker/PHPComplex",
"keywords": [
"complex",
"mathematics"
],
"support": {
"issues": "https://github.com/MarkBaker/PHPComplex/issues",
"source": "https://github.com/MarkBaker/PHPComplex/tree/3.0.1"
},
"time": "2021-06-29T15:32:53+00:00"
},
{
"name": "markbaker/matrix",
"version": "3.0.0",
"source": {
"type": "git",
"url": "https://github.com/MarkBaker/PHPMatrix.git",
"reference": "c66aefcafb4f6c269510e9ac46b82619a904c576"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/MarkBaker/PHPMatrix/zipball/c66aefcafb4f6c269510e9ac46b82619a904c576",
"reference": "c66aefcafb4f6c269510e9ac46b82619a904c576",
"shasum": ""
},
"require": {
"php": "^7.1 || ^8.0"
},
"require-dev": {
"dealerdirect/phpcodesniffer-composer-installer": "^0.7.0",
"phpcompatibility/php-compatibility": "^9.0",
"phpdocumentor/phpdocumentor": "2.*",
"phploc/phploc": "^4.0",
"phpmd/phpmd": "2.*",
"phpunit/phpunit": "^7.0 || ^8.0 || ^9.3",
"sebastian/phpcpd": "^4.0",
"squizlabs/php_codesniffer": "^3.4"
},
"type": "library",
"autoload": {
"psr-4": {
"Matrix\\": "classes/src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Mark Baker",
"email": "mark@demon-angel.eu"
}
],
"description": "PHP Class for working with matrices",
"homepage": "https://github.com/MarkBaker/PHPMatrix",
"keywords": [
"mathematics",
"matrix",
"vector"
],
"support": {
"issues": "https://github.com/MarkBaker/PHPMatrix/issues",
"source": "https://github.com/MarkBaker/PHPMatrix/tree/3.0.0"
},
"time": "2021-07-01T19:01:15+00:00"
},
{
"name": "masterminds/html5",
"version": "2.8.1",
@@ -5528,69 +5215,6 @@
},
"time": "2021-12-27T18:49:48+00:00"
},
{
"name": "mediconesystems/livewire-datatables",
"version": "v0.5.4",
"source": {
"type": "git",
"url": "https://github.com/MedicOneSystems/livewire-datatables.git",
"reference": "bf6f24d529208e6bdec58276e92792719c73c827"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/MedicOneSystems/livewire-datatables/zipball/bf6f24d529208e6bdec58276e92792719c73c827",
"reference": "bf6f24d529208e6bdec58276e92792719c73c827",
"shasum": ""
},
"require": {
"illuminate/support": "^7.0|^8.0",
"livewire/livewire": "^1.2|^2.0",
"maatwebsite/excel": "^3.1",
"php": "^7.2.5|^8.0"
},
"require-dev": {
"laravel/legacy-factories": "^1.0.4",
"orchestra/testbench": "^4.0|5.0|6.0",
"phpunit/phpunit": "^8.0|9.0"
},
"type": "library",
"extra": {
"laravel": {
"providers": [
"Mediconesystems\\LivewireDatatables\\LivewireDatatablesServiceProvider"
],
"aliases": {
"LivewireDatatables": "Mediconesystems\\LivewireDatatables\\LivewireDatatablesFacade"
}
}
},
"autoload": {
"psr-4": {
"Mediconesystems\\LivewireDatatables\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Mark Salmon",
"email": "mark.salmon@mediconesystems.com",
"role": "Developer"
}
],
"homepage": "https://github.com/mediconesystems/livewire-datatables",
"keywords": [
"livewire-datatables",
"mediconesystems"
],
"support": {
"issues": "https://github.com/MedicOneSystems/livewire-datatables/issues",
"source": "https://github.com/MedicOneSystems/livewire-datatables/tree/v0.5.4"
},
"time": "2021-08-09T20:37:55+00:00"
},
{
"name": "monolog/monolog",
"version": "2.7.0",
@@ -5761,66 +5385,6 @@
},
"time": "2023-08-25T10:54:48+00:00"
},
{
"name": "myclabs/php-enum",
"version": "1.8.3",
"source": {
"type": "git",
"url": "https://github.com/myclabs/php-enum.git",
"reference": "b942d263c641ddb5190929ff840c68f78713e937"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/myclabs/php-enum/zipball/b942d263c641ddb5190929ff840c68f78713e937",
"reference": "b942d263c641ddb5190929ff840c68f78713e937",
"shasum": ""
},
"require": {
"ext-json": "*",
"php": "^7.3 || ^8.0"
},
"require-dev": {
"phpunit/phpunit": "^9.5",
"squizlabs/php_codesniffer": "1.*",
"vimeo/psalm": "^4.6.2"
},
"type": "library",
"autoload": {
"psr-4": {
"MyCLabs\\Enum\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "PHP Enum contributors",
"homepage": "https://github.com/myclabs/php-enum/graphs/contributors"
}
],
"description": "PHP Enum implementation",
"homepage": "http://github.com/myclabs/php-enum",
"keywords": [
"enum"
],
"support": {
"issues": "https://github.com/myclabs/php-enum/issues",
"source": "https://github.com/myclabs/php-enum/tree/1.8.3"
},
"funding": [
{
"url": "https://github.com/mnapoli",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/myclabs/php-enum",
"type": "tidelift"
}
],
"time": "2021-07-05T08:18:36+00:00"
},
{
"name": "neitanod/forceutf8",
"version": "v2.0.4",
@@ -6960,110 +6524,6 @@
},
"time": "2022-03-15T21:29:03+00:00"
},
{
"name": "phpoffice/phpspreadsheet",
"version": "1.24.1",
"source": {
"type": "git",
"url": "https://github.com/PHPOffice/PhpSpreadsheet.git",
"reference": "69991111e05fca3ff7398e1e7fca9ebed33efec6"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/PHPOffice/PhpSpreadsheet/zipball/69991111e05fca3ff7398e1e7fca9ebed33efec6",
"reference": "69991111e05fca3ff7398e1e7fca9ebed33efec6",
"shasum": ""
},
"require": {
"ext-ctype": "*",
"ext-dom": "*",
"ext-fileinfo": "*",
"ext-gd": "*",
"ext-iconv": "*",
"ext-libxml": "*",
"ext-mbstring": "*",
"ext-simplexml": "*",
"ext-xml": "*",
"ext-xmlreader": "*",
"ext-xmlwriter": "*",
"ext-zip": "*",
"ext-zlib": "*",
"ezyang/htmlpurifier": "^4.13",
"maennchen/zipstream-php": "^2.1",
"markbaker/complex": "^3.0",
"markbaker/matrix": "^3.0",
"php": "^7.3 || ^8.0",
"psr/http-client": "^1.0",
"psr/http-factory": "^1.0",
"psr/simple-cache": "^1.0 || ^2.0"
},
"require-dev": {
"dealerdirect/phpcodesniffer-composer-installer": "dev-master",
"dompdf/dompdf": "^1.0 || ^2.0",
"friendsofphp/php-cs-fixer": "^3.2",
"jpgraph/jpgraph": "^4.0",
"mpdf/mpdf": "8.1.1",
"phpcompatibility/php-compatibility": "^9.3",
"phpstan/phpstan": "^1.1",
"phpstan/phpstan-phpunit": "^1.0",
"phpunit/phpunit": "^8.5 || ^9.0",
"squizlabs/php_codesniffer": "^3.7",
"tecnickcom/tcpdf": "^6.4"
},
"suggest": {
"dompdf/dompdf": "Option for rendering PDF with PDF Writer (doesn't yet support PHP8)",
"jpgraph/jpgraph": "Option for rendering charts, or including charts with PDF or HTML Writers",
"mpdf/mpdf": "Option for rendering PDF with PDF Writer",
"tecnickcom/tcpdf": "Option for rendering PDF with PDF Writer (doesn't yet support PHP8)"
},
"type": "library",
"autoload": {
"psr-4": {
"PhpOffice\\PhpSpreadsheet\\": "src/PhpSpreadsheet"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Maarten Balliauw",
"homepage": "https://blog.maartenballiauw.be"
},
{
"name": "Mark Baker",
"homepage": "https://markbakeruk.net"
},
{
"name": "Franck Lefevre",
"homepage": "https://rootslabs.net"
},
{
"name": "Erik Tilt"
},
{
"name": "Adrien Crivelli"
}
],
"description": "PHPSpreadsheet - Read, Create and Write Spreadsheet documents in PHP - Spreadsheet engine",
"homepage": "https://github.com/PHPOffice/PhpSpreadsheet",
"keywords": [
"OpenXML",
"excel",
"gnumeric",
"ods",
"php",
"spreadsheet",
"xls",
"xlsx"
],
"support": {
"issues": "https://github.com/PHPOffice/PhpSpreadsheet/issues",
"source": "https://github.com/PHPOffice/PhpSpreadsheet/tree/1.24.1"
},
"time": "2022-07-18T19:50:48+00:00"
},
{
"name": "phpoption/phpoption",
"version": "1.8.1",
@@ -11523,20 +10983,20 @@
},
{
"name": "tecnickcom/tcpdf",
"version": "6.6.2",
"version": "6.7.5",
"source": {
"type": "git",
"url": "https://github.com/tecnickcom/TCPDF.git",
"reference": "e3cffc9bcbc76e89e167e9eb0bbda0cab7518459"
"reference": "951eabf0338ec2522bd0d5d9c79b08a3a3d36b36"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/tecnickcom/TCPDF/zipball/e3cffc9bcbc76e89e167e9eb0bbda0cab7518459",
"reference": "e3cffc9bcbc76e89e167e9eb0bbda0cab7518459",
"url": "https://api.github.com/repos/tecnickcom/TCPDF/zipball/951eabf0338ec2522bd0d5d9c79b08a3a3d36b36",
"reference": "951eabf0338ec2522bd0d5d9c79b08a3a3d36b36",
"shasum": ""
},
"require": {
"php": ">=5.3.0"
"php": ">=5.5.0"
},
"type": "library",
"autoload": {
@@ -11561,7 +11021,7 @@
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"LGPL-3.0-only"
"LGPL-3.0-or-later"
],
"authors": [
{
@@ -11583,7 +11043,7 @@
],
"support": {
"issues": "https://github.com/tecnickcom/TCPDF/issues",
"source": "https://github.com/tecnickcom/TCPDF/tree/6.6.2"
"source": "https://github.com/tecnickcom/TCPDF/tree/6.7.5"
},
"funding": [
{
@@ -11591,7 +11051,7 @@
"type": "custom"
}
],
"time": "2022-12-17T10:28:59+00:00"
"time": "2024-04-20T17:25:10+00:00"
},
{
"name": "tijsverkoyen/css-to-inline-styles",
+1
View File
@@ -96,6 +96,7 @@ return [
PDO::MYSQL_ATTR_SSL_CERT => env('DB_SSL_CERT_PATH'), // /path/to/cert.pem
PDO::MYSQL_ATTR_SSL_CA => env('DB_SSL_CA_PATH'), // /path/to/ca.pem
PDO::MYSQL_ATTR_SSL_CIPHER => env('DB_SSL_CIPHER'),
PDO::MYSQL_ATTR_SSL_VERIFY_SERVER_CERT => env('DB_SSL_VERIFY_SERVER'), //true/false
]) : [],
],
+13
View File
@@ -174,4 +174,17 @@ return [
'bs_table_storage' => env('BS_TABLE_STORAGE', 'cookieStorage'),
/*
|--------------------------------------------------------------------------
| Bootstrap Table Enable Deeplinking
|--------------------------------------------------------------------------
|
| Use deeplinks to directly link to search results, sorting, and pagination
|
| More info: https://github.com/generals-space/bootstrap-table-addrbar/blob/master/readme(EN).md
*/
'bs_table_addrbar' => env('BS_TABLE_DEEPLINK', true),
];
+5 -5
View File
@@ -1,10 +1,10 @@
<?php
return array (
'app_version' => 'v6.3.3',
'full_app_version' => 'v6.3.3 - build 12903-g0f63fa23e',
'build_version' => '12903',
'app_version' => 'v6.4.0',
'full_app_version' => 'v6.4.0 - build 13351-gdb2baae758',
'build_version' => '13351',
'prerelease_version' => '',
'hash_version' => 'g0f63fa23e',
'full_hash' => 'v6.3.3-67-g0f63fa23e',
'hash_version' => 'gdb2baae758',
'full_hash' => 'v6.4.0-210-gdb2baae758',
'branch' => 'master',
);
+11
View File
@@ -4,6 +4,7 @@ namespace Database\Factories;
use App\Models\Asset;
use App\Models\AssetModel;
use App\Models\CustomField;
use App\Models\Location;
use App\Models\Statuslabel;
use App\Models\Supplier;
@@ -353,6 +354,16 @@ class AssetFactory extends Factory
return $this->state(['requestable' => false]);
}
public function hasEncryptedCustomField(CustomField $field = null)
{
return $this->state(function () use ($field) {
return [
'model_id' => AssetModel::factory()->hasEncryptedCustomField($field),
];
});
}
/**
* This allows bypassing model level validation if you want to purposefully
* create an asset in an invalid state. Validation is turned back on
+10
View File
@@ -3,6 +3,7 @@
namespace Database\Factories;
use App\Models\AssetModel;
use App\Models\CustomField;
use App\Models\CustomFieldset;
use App\Models\Depreciation;
use App\Models\Manufacturer;
@@ -429,4 +430,13 @@ class AssetModelFactory extends Factory
];
});
}
public function hasEncryptedCustomField(CustomField $field = null)
{
return $this->state(function () use ($field) {
return [
'fieldset_id' => CustomFieldset::factory()->hasEncryptedCustomField($field),
];
});
}
}
@@ -3,6 +3,7 @@
namespace Database\Factories;
use App\Models\CustomFieldset;
use App\Models\CustomField;
use Illuminate\Database\Eloquent\Factories\Factory;
class CustomFieldsetFactory extends Factory
@@ -43,4 +44,13 @@ class CustomFieldsetFactory extends Factory
];
});
}
public function hasEncryptedCustomField(CustomField $field = null)
{
return $this->afterCreating(function (CustomFieldset $fieldset) use ($field) {
$field = $field ?? CustomField::factory()->testEncrypted()->create();
$fieldset->fields()->attach($field, ['order' => '1', 'required' => false]);
});
}
}
@@ -0,0 +1,47 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class UpdateLegacyLocale extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
//
Schema::table('users', function (Blueprint $table) {
//
$table->string('locale', 10)->nullable()->default('en-US')->change();
});
Schema::table('settings', function (Blueprint $table) {
//
$table->string('locale', 10)->nullable()->default('en-US')->change();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
//
Schema::table('users', function (Blueprint $table) {
//
$table->string('locale', 10)->nullable()->default(config('app.locale'))->change();
});
Schema::table('settings', function (Blueprint $table) {
//
$table->string('locale', 10)->nullable()->default(config('app.locale'))->change();
});
}
}
+492 -186
View File
@@ -1329,9 +1329,9 @@
"dev": true
},
"@fortawesome/fontawesome-free": {
"version": "6.5.1",
"resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-free/-/fontawesome-free-6.5.1.tgz",
"integrity": "sha512-CNy5vSwN3fsUStPRLX7fUYojyuzoEMSXPl7zSLJ8TgtRfjv24LOnOWKT2zYwaHZCJGkdyRnTmstR0P+Ah503Gw=="
"version": "6.5.2",
"resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-free/-/fontawesome-free-6.5.2.tgz",
"integrity": "sha512-hRILoInAx8GNT5IMkrtIt9blOdrqHOnPBH+k70aWUAqPZPgopb9G5EQJFpaBx/S8zp2fC+mPW349Bziuk1o28Q=="
},
"@jridgewell/gen-mapping": {
"version": "0.1.1",
@@ -1460,9 +1460,9 @@
},
"dependencies": {
"tslib": {
"version": "2.6.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.1.tgz",
"integrity": "sha512-t0hLfiEKfMUoqhG+U1oid7Pva4bbDPHYfJNiB7BiIjRkj1pyC++4N3huJfqY6aRH6VTB0rvtzQwjM4K6qpfOig=="
"version": "2.6.2",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz",
"integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q=="
}
}
},
@@ -1752,9 +1752,9 @@
"dev": true
},
"@types/raf": {
"version": "3.4.0",
"resolved": "https://registry.npmjs.org/@types/raf/-/raf-3.4.0.tgz",
"integrity": "sha512-taW5/WYqo36N7V39oYyHP9Ipfd5pNFvGTIQsNGj86xV88YQ7GnI30/yMfKDF7Zgin0m3e+ikX88FvImnK4RjGw==",
"version": "3.4.3",
"resolved": "https://registry.npmjs.org/@types/raf/-/raf-3.4.3.tgz",
"integrity": "sha512-c4YAvMedbPZ5tEyxzQdMoOhhJ4RD3rngZIdwC2/qDN3d7JpEhB6fiBRKVY1lg5B7Wk+uPBjn5f39j1/2MY1oOw==",
"optional": true
},
"@types/range-parser": {
@@ -2424,12 +2424,48 @@
}
},
"array-buffer-byte-length": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.0.tgz",
"integrity": "sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A==",
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.1.tgz",
"integrity": "sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==",
"requires": {
"call-bind": "^1.0.2",
"is-array-buffer": "^3.0.1"
"call-bind": "^1.0.5",
"is-array-buffer": "^3.0.4"
},
"dependencies": {
"call-bind": {
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz",
"integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==",
"requires": {
"es-define-property": "^1.0.0",
"es-errors": "^1.3.0",
"function-bind": "^1.1.2",
"get-intrinsic": "^1.2.4",
"set-function-length": "^1.2.1"
}
},
"function-bind": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
"integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA=="
},
"get-intrinsic": {
"version": "1.2.4",
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz",
"integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==",
"requires": {
"es-errors": "^1.3.0",
"function-bind": "^1.1.2",
"has-proto": "^1.0.1",
"has-symbols": "^1.0.3",
"hasown": "^2.0.0"
}
},
"has-symbols": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz",
"integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A=="
}
}
},
"array-filter": {
@@ -3377,9 +3413,9 @@
"integrity": "sha1-EQPWvADPv6jPyaJZmrUYxVZD2j8="
},
"bootstrap-table": {
"version": "1.22.2",
"resolved": "https://registry.npmjs.org/bootstrap-table/-/bootstrap-table-1.22.2.tgz",
"integrity": "sha512-ZjZGcEXm/N7N/wAykmANWKKV+U+7AxgoNuBwWLrKbvAGT8XXS2f0OCiFmuMwpkqg7pDbF+ff9bEf/lOAlxcF1w=="
"version": "1.22.3",
"resolved": "https://registry.npmjs.org/bootstrap-table/-/bootstrap-table-1.22.3.tgz",
"integrity": "sha512-YWQTXzmZBX6P4y6YW2mHOxqIAYyLKld2WecHuKSyYamimUE4KZ9YUsmAroSoS2Us1bPYXFaM+JCeTt6X0iKW+g=="
},
"brace-expansion": {
"version": "1.1.11",
@@ -3781,9 +3817,9 @@
},
"dependencies": {
"core-js": {
"version": "3.32.0",
"resolved": "https://registry.npmjs.org/core-js/-/core-js-3.32.0.tgz",
"integrity": "sha512-rd4rYZNlF3WuoYuRIDEmbR/ga9CeuWX9U05umAvgrrZoHY4Z++cp/xwPQMvUpBB4Ag6J8KfD80G0zwCyaSxDww==",
"version": "3.37.0",
"resolved": "https://registry.npmjs.org/core-js/-/core-js-3.37.0.tgz",
"integrity": "sha512-fu5vHevQ8ZG4og+LXug8ulUtVxjOcEYvifJr7L5Bfq9GOztVqsKd9/59hUk2ZSbCrS3BqUr3EpaYGIYzq7g3Ug==",
"optional": true
},
"regenerator-runtime": {
@@ -4373,9 +4409,9 @@
}
},
"crypto-js": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-4.1.1.tgz",
"integrity": "sha512-o2JlM7ydqd3Qk9CA0L4NL6mTzU2sdx96a+oOfPu8Mkl/PK51vSyoi8/rQ8NknZtk44vq15lmhAj9CIAGwgeWKw=="
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-4.2.0.tgz",
"integrity": "sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q=="
},
"css-declaration-sorter": {
"version": "6.3.0",
@@ -4607,14 +4643,14 @@
}
},
"deep-equal": {
"version": "2.2.2",
"resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-2.2.2.tgz",
"integrity": "sha512-xjVyBf0w5vH0I42jdAZzOKVldmPgSulmiyPRywoyq7HXC9qdgo17kxJE+rdnif5Tz6+pIrpJI8dCpMNLIGkUiA==",
"version": "2.2.3",
"resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-2.2.3.tgz",
"integrity": "sha512-ZIwpnevOurS8bpT4192sqAowWM76JDKSHYzMLty3BZGSswgq6pBaH3DhCSW5xVAZICZyKdOBPjwww5wfgT/6PA==",
"requires": {
"array-buffer-byte-length": "^1.0.0",
"call-bind": "^1.0.2",
"call-bind": "^1.0.5",
"es-get-iterator": "^1.1.3",
"get-intrinsic": "^1.2.1",
"get-intrinsic": "^1.2.2",
"is-arguments": "^1.1.1",
"is-array-buffer": "^3.0.2",
"is-date-object": "^1.0.5",
@@ -4624,36 +4660,58 @@
"object-is": "^1.1.5",
"object-keys": "^1.1.1",
"object.assign": "^4.1.4",
"regexp.prototype.flags": "^1.5.0",
"regexp.prototype.flags": "^1.5.1",
"side-channel": "^1.0.4",
"which-boxed-primitive": "^1.0.2",
"which-collection": "^1.0.1",
"which-typed-array": "^1.1.9"
"which-typed-array": "^1.1.13"
},
"dependencies": {
"available-typed-arrays": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz",
"integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw=="
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz",
"integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==",
"requires": {
"possible-typed-array-names": "^1.0.0"
}
},
"call-bind": {
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz",
"integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==",
"requires": {
"es-define-property": "^1.0.0",
"es-errors": "^1.3.0",
"function-bind": "^1.1.2",
"get-intrinsic": "^1.2.4",
"set-function-length": "^1.2.1"
}
},
"define-properties": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.0.tgz",
"integrity": "sha512-xvqAVKGfT1+UAvPwKTVw/njhdQ8ZhXK4lI0bCIuCMrp2up9nPnaDftrLtmpTazqd1o+UY4zgzU+avtMbDP+ldA==",
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz",
"integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==",
"requires": {
"define-data-property": "^1.0.1",
"has-property-descriptors": "^1.0.0",
"object-keys": "^1.1.1"
}
},
"function-bind": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
"integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA=="
},
"get-intrinsic": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.1.tgz",
"integrity": "sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==",
"version": "1.2.4",
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz",
"integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==",
"requires": {
"function-bind": "^1.1.1",
"has": "^1.0.3",
"es-errors": "^1.3.0",
"function-bind": "^1.1.2",
"has-proto": "^1.0.1",
"has-symbols": "^1.0.3"
"has-symbols": "^1.0.3",
"hasown": "^2.0.0"
}
},
"has-symbols": {
@@ -4693,26 +4751,26 @@
"integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw=="
},
"object.assign": {
"version": "4.1.4",
"resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.4.tgz",
"integrity": "sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==",
"version": "4.1.5",
"resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz",
"integrity": "sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==",
"requires": {
"call-bind": "^1.0.2",
"define-properties": "^1.1.4",
"call-bind": "^1.0.5",
"define-properties": "^1.2.1",
"has-symbols": "^1.0.3",
"object-keys": "^1.1.1"
}
},
"which-typed-array": {
"version": "1.1.11",
"resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.11.tgz",
"integrity": "sha512-qe9UWWpkeG5yzZ0tNYxDmd7vo58HDBc39mZ0xWWpolAGADdFOzkfamWLDxkOWcvHQKVmdTyQdLD4NOfjLWTKew==",
"version": "1.1.15",
"resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.15.tgz",
"integrity": "sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==",
"requires": {
"available-typed-arrays": "^1.0.5",
"call-bind": "^1.0.2",
"available-typed-arrays": "^1.0.7",
"call-bind": "^1.0.7",
"for-each": "^0.3.3",
"gopd": "^1.0.1",
"has-tostringtag": "^1.0.0"
"has-tostringtag": "^1.0.2"
}
}
}
@@ -4731,6 +4789,16 @@
"resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz",
"integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg=="
},
"define-data-property": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz",
"integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==",
"requires": {
"es-define-property": "^1.0.0",
"es-errors": "^1.3.0",
"gopd": "^1.0.1"
}
},
"define-lazy-prop": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz",
@@ -4902,9 +4970,9 @@
}
},
"dompurify": {
"version": "2.4.7",
"resolved": "https://registry.npmjs.org/dompurify/-/dompurify-2.4.7.tgz",
"integrity": "sha512-kxxKlPEDa6Nc5WJi+qRgPbOAbgTpSULL+vI3NUXsZMlkJxTqYI9wg5ZTay2sFrdZRWHPWNi+EdAhcJf81WtoMQ==",
"version": "2.5.2",
"resolved": "https://registry.npmjs.org/dompurify/-/dompurify-2.5.2.tgz",
"integrity": "sha512-5vSyvxRAb45EoWwAktUT3AYqAwXK4FL7si22Cgj46U6ICsj/YJczCN+Bk7WNABIQmpWRymGfslMhrRUZkQNnqA==",
"optional": true
},
"domutils": {
@@ -5071,6 +5139,43 @@
"string.prototype.trimstart": "^1.0.3"
}
},
"es-define-property": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz",
"integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==",
"requires": {
"get-intrinsic": "^1.2.4"
},
"dependencies": {
"function-bind": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
"integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA=="
},
"get-intrinsic": {
"version": "1.2.4",
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz",
"integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==",
"requires": {
"es-errors": "^1.3.0",
"function-bind": "^1.1.2",
"has-proto": "^1.0.1",
"has-symbols": "^1.0.3",
"hasown": "^2.0.0"
}
},
"has-symbols": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz",
"integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A=="
}
}
},
"es-errors": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
"integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw=="
},
"es-get-iterator": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/es-get-iterator/-/es-get-iterator-1.1.3.tgz",
@@ -5087,15 +5192,21 @@
"stop-iteration-iterator": "^1.0.0"
},
"dependencies": {
"function-bind": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
"integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA=="
},
"get-intrinsic": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.1.tgz",
"integrity": "sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==",
"version": "1.2.4",
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz",
"integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==",
"requires": {
"function-bind": "^1.1.1",
"has": "^1.0.3",
"es-errors": "^1.3.0",
"function-bind": "^1.1.2",
"has-proto": "^1.0.1",
"has-symbols": "^1.0.3"
"has-symbols": "^1.0.3",
"hasown": "^2.0.0"
}
},
"has-symbols": {
@@ -15154,15 +15265,21 @@
"get-intrinsic": "^1.1.3"
},
"dependencies": {
"function-bind": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
"integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA=="
},
"get-intrinsic": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.1.tgz",
"integrity": "sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==",
"version": "1.2.4",
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz",
"integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==",
"requires": {
"function-bind": "^1.1.1",
"has": "^1.0.3",
"es-errors": "^1.3.0",
"function-bind": "^1.1.2",
"has-proto": "^1.0.1",
"has-symbols": "^1.0.3"
"has-symbols": "^1.0.3",
"hasown": "^2.0.0"
}
},
"has-symbols": {
@@ -15236,17 +15353,17 @@
"dev": true
},
"has-property-descriptors": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz",
"integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==",
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz",
"integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==",
"requires": {
"get-intrinsic": "^1.1.1"
"es-define-property": "^1.0.0"
}
},
"has-proto": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz",
"integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg=="
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz",
"integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q=="
},
"has-symbols": {
"version": "1.0.1",
@@ -15254,11 +15371,11 @@
"integrity": "sha1-n1IUdYpEGWxAbZvXbOv4HsLdMeg="
},
"has-tostringtag": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz",
"integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==",
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz",
"integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==",
"requires": {
"has-symbols": "^1.0.2"
"has-symbols": "^1.0.3"
},
"dependencies": {
"has-symbols": {
@@ -15318,6 +15435,21 @@
"minimalistic-assert": "^1.0.1"
}
},
"hasown": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
"integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
"requires": {
"function-bind": "^1.1.2"
},
"dependencies": {
"function-bind": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
"integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA=="
}
}
},
"he": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz",
@@ -15813,31 +15945,13 @@
}
},
"internal-slot": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.5.tgz",
"integrity": "sha512-Y+R5hJrzs52QCG2laLn4udYVnxsfny9CpOhNhUvk/SSSVyF6T27FzRbF0sroPidSu3X8oEAkOn2K804mjpt6UQ==",
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.7.tgz",
"integrity": "sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==",
"requires": {
"get-intrinsic": "^1.2.0",
"has": "^1.0.3",
"es-errors": "^1.3.0",
"hasown": "^2.0.0",
"side-channel": "^1.0.4"
},
"dependencies": {
"get-intrinsic": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.1.tgz",
"integrity": "sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==",
"requires": {
"function-bind": "^1.1.1",
"has": "^1.0.3",
"has-proto": "^1.0.1",
"has-symbols": "^1.0.3"
}
},
"has-symbols": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz",
"integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A=="
}
}
},
"interpret": {
@@ -15880,55 +15994,35 @@
}
},
"is-array-buffer": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.2.tgz",
"integrity": "sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w==",
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.4.tgz",
"integrity": "sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==",
"requires": {
"call-bind": "^1.0.2",
"get-intrinsic": "^1.2.0",
"is-typed-array": "^1.1.10"
"get-intrinsic": "^1.2.1"
},
"dependencies": {
"available-typed-arrays": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz",
"integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw=="
"function-bind": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
"integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA=="
},
"get-intrinsic": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.1.tgz",
"integrity": "sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==",
"version": "1.2.4",
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz",
"integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==",
"requires": {
"function-bind": "^1.1.1",
"has": "^1.0.3",
"es-errors": "^1.3.0",
"function-bind": "^1.1.2",
"has-proto": "^1.0.1",
"has-symbols": "^1.0.3"
"has-symbols": "^1.0.3",
"hasown": "^2.0.0"
}
},
"has-symbols": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz",
"integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A=="
},
"is-typed-array": {
"version": "1.1.12",
"resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.12.tgz",
"integrity": "sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg==",
"requires": {
"which-typed-array": "^1.1.11"
}
},
"which-typed-array": {
"version": "1.1.11",
"resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.11.tgz",
"integrity": "sha512-qe9UWWpkeG5yzZ0tNYxDmd7vo58HDBc39mZ0xWWpolAGADdFOzkfamWLDxkOWcvHQKVmdTyQdLD4NOfjLWTKew==",
"requires": {
"available-typed-arrays": "^1.0.5",
"call-bind": "^1.0.2",
"for-each": "^0.3.3",
"gopd": "^1.0.1",
"has-tostringtag": "^1.0.0"
}
}
}
},
@@ -16018,9 +16112,9 @@
}
},
"is-map": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.2.tgz",
"integrity": "sha512-cOZFQQozTha1f4MxLFzlgKYPTyj26picdZTx82hbc/Xf4K/tZOOXSCkMvU4pKioRXGDLJRn0GM7Upe7kR721yg=="
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz",
"integrity": "sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw=="
},
"is-negative-zero": {
"version": "2.0.1",
@@ -16065,16 +16159,52 @@
}
},
"is-set": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.2.tgz",
"integrity": "sha512-+2cnTEZeY5z/iXGbLhPrOAaK/Mau5k5eXq9j14CpRTftq0pAJu2MwVRSZhyZWBzx3o6X795Lz6Bpb6R0GKf37g=="
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.3.tgz",
"integrity": "sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg=="
},
"is-shared-array-buffer": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz",
"integrity": "sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==",
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.3.tgz",
"integrity": "sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==",
"requires": {
"call-bind": "^1.0.2"
"call-bind": "^1.0.7"
},
"dependencies": {
"call-bind": {
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz",
"integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==",
"requires": {
"es-define-property": "^1.0.0",
"es-errors": "^1.3.0",
"function-bind": "^1.1.2",
"get-intrinsic": "^1.2.4",
"set-function-length": "^1.2.1"
}
},
"function-bind": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
"integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA=="
},
"get-intrinsic": {
"version": "1.2.4",
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz",
"integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==",
"requires": {
"es-errors": "^1.3.0",
"function-bind": "^1.1.2",
"has-proto": "^1.0.1",
"has-symbols": "^1.0.3",
"hasown": "^2.0.0"
}
},
"has-symbols": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz",
"integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A=="
}
}
},
"is-stream": {
@@ -16112,17 +16242,53 @@
}
},
"is-weakmap": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.1.tgz",
"integrity": "sha512-NSBR4kH5oVj1Uwvv970ruUkCV7O1mzgVFO4/rev2cLRda9Tm9HrL70ZPut4rOHgY0FNrUu9BCbXA2sdQ+x0chA=="
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.2.tgz",
"integrity": "sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w=="
},
"is-weakset": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.2.tgz",
"integrity": "sha512-t2yVvttHkQktwnNNmBQ98AhENLdPUTDTE21uPqAQ0ARwQfGeQKRVS0NNurH7bTf7RrvcVn1OOge45CnBeHCSmg==",
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.3.tgz",
"integrity": "sha512-LvIm3/KWzS9oRFHugab7d+M/GcBXuXX5xZkzPmN+NxihdQlZUQ4dWuSV1xR/sq6upL1TJEDrfBgRepHFdBtSNQ==",
"requires": {
"call-bind": "^1.0.2",
"get-intrinsic": "^1.1.1"
"call-bind": "^1.0.7",
"get-intrinsic": "^1.2.4"
},
"dependencies": {
"call-bind": {
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz",
"integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==",
"requires": {
"es-define-property": "^1.0.0",
"es-errors": "^1.3.0",
"function-bind": "^1.1.2",
"get-intrinsic": "^1.2.4",
"set-function-length": "^1.2.1"
}
},
"function-bind": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
"integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA=="
},
"get-intrinsic": {
"version": "1.2.4",
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz",
"integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==",
"requires": {
"es-errors": "^1.3.0",
"function-bind": "^1.1.2",
"has-proto": "^1.0.1",
"has-symbols": "^1.0.3",
"hasown": "^2.0.0"
}
},
"has-symbols": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz",
"integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A=="
}
}
},
"is-what": {
@@ -16366,9 +16532,9 @@
},
"dependencies": {
"core-js": {
"version": "3.32.0",
"resolved": "https://registry.npmjs.org/core-js/-/core-js-3.32.0.tgz",
"integrity": "sha512-rd4rYZNlF3WuoYuRIDEmbR/ga9CeuWX9U05umAvgrrZoHY4Z++cp/xwPQMvUpBB4Ag6J8KfD80G0zwCyaSxDww==",
"version": "3.37.0",
"resolved": "https://registry.npmjs.org/core-js/-/core-js-3.37.0.tgz",
"integrity": "sha512-fu5vHevQ8ZG4og+LXug8ulUtVxjOcEYvifJr7L5Bfq9GOztVqsKd9/59hUk2ZSbCrS3BqUr3EpaYGIYzq7g3Ug==",
"optional": true
}
}
@@ -17500,12 +17666,58 @@
"integrity": "sha512-i3Bp9iTqwhaLZBxGkRfo5ZbE07BQRT7MGu8+nNgwW9ItGp1TzCTw2DLEoWwjClxBjOFI/hWljTAmYGCEwmtnOw=="
},
"object-is": {
"version": "1.1.5",
"resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.5.tgz",
"integrity": "sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw==",
"version": "1.1.6",
"resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.6.tgz",
"integrity": "sha512-F8cZ+KfGlSGi09lJT7/Nd6KJZ9ygtvYC0/UYYLI9nmQKLMnydpB9yvbv9K1uSkEu7FU9vYPmVwLg328tX+ot3Q==",
"requires": {
"call-bind": "^1.0.2",
"define-properties": "^1.1.3"
"call-bind": "^1.0.7",
"define-properties": "^1.2.1"
},
"dependencies": {
"call-bind": {
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz",
"integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==",
"requires": {
"es-define-property": "^1.0.0",
"es-errors": "^1.3.0",
"function-bind": "^1.1.2",
"get-intrinsic": "^1.2.4",
"set-function-length": "^1.2.1"
}
},
"define-properties": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz",
"integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==",
"requires": {
"define-data-property": "^1.0.1",
"has-property-descriptors": "^1.0.0",
"object-keys": "^1.1.1"
}
},
"function-bind": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
"integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA=="
},
"get-intrinsic": {
"version": "1.2.4",
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz",
"integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==",
"requires": {
"es-errors": "^1.3.0",
"function-bind": "^1.1.2",
"has-proto": "^1.0.1",
"has-symbols": "^1.0.3",
"hasown": "^2.0.0"
}
},
"has-symbols": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz",
"integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A=="
}
}
},
"object-keys": {
@@ -17853,6 +18065,11 @@
"resolved": "https://registry.npmjs.org/png-js/-/png-js-1.0.0.tgz",
"integrity": "sha512-k+YsbhpA9e+EFfKjTCH3VW6aoKlyNYI6NYdTfDL4CIvFnvsuO84ttonmZE7rc+v23SLTH8XX+5w/Ak9v0xGY4g=="
},
"possible-typed-array-names": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz",
"integrity": "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q=="
},
"postcss": {
"version": "8.4.5",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.5.tgz",
@@ -18695,23 +18912,59 @@
}
},
"regexp.prototype.flags": {
"version": "1.5.0",
"resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.0.tgz",
"integrity": "sha512-0SutC3pNudRKgquxGoRGIz946MZVHqbNfPjBdxeOhBrdgDKlRoXmYLQN9xRbrR09ZXWeGAdPuif7egofn6v5LA==",
"version": "1.5.2",
"resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.2.tgz",
"integrity": "sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw==",
"requires": {
"call-bind": "^1.0.2",
"define-properties": "^1.2.0",
"functions-have-names": "^1.2.3"
"call-bind": "^1.0.6",
"define-properties": "^1.2.1",
"es-errors": "^1.3.0",
"set-function-name": "^2.0.1"
},
"dependencies": {
"define-properties": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.0.tgz",
"integrity": "sha512-xvqAVKGfT1+UAvPwKTVw/njhdQ8ZhXK4lI0bCIuCMrp2up9nPnaDftrLtmpTazqd1o+UY4zgzU+avtMbDP+ldA==",
"call-bind": {
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz",
"integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==",
"requires": {
"es-define-property": "^1.0.0",
"es-errors": "^1.3.0",
"function-bind": "^1.1.2",
"get-intrinsic": "^1.2.4",
"set-function-length": "^1.2.1"
}
},
"define-properties": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz",
"integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==",
"requires": {
"define-data-property": "^1.0.1",
"has-property-descriptors": "^1.0.0",
"object-keys": "^1.1.1"
}
},
"function-bind": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
"integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA=="
},
"get-intrinsic": {
"version": "1.2.4",
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz",
"integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==",
"requires": {
"es-errors": "^1.3.0",
"function-bind": "^1.1.2",
"has-proto": "^1.0.1",
"has-symbols": "^1.0.3",
"hasown": "^2.0.0"
}
},
"has-symbols": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz",
"integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A=="
}
}
},
@@ -19077,6 +19330,54 @@
"integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==",
"dev": true
},
"set-function-length": {
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz",
"integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==",
"requires": {
"define-data-property": "^1.1.4",
"es-errors": "^1.3.0",
"function-bind": "^1.1.2",
"get-intrinsic": "^1.2.4",
"gopd": "^1.0.1",
"has-property-descriptors": "^1.0.2"
},
"dependencies": {
"function-bind": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
"integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA=="
},
"get-intrinsic": {
"version": "1.2.4",
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz",
"integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==",
"requires": {
"es-errors": "^1.3.0",
"function-bind": "^1.1.2",
"has-proto": "^1.0.1",
"has-symbols": "^1.0.3",
"hasown": "^2.0.0"
}
},
"has-symbols": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz",
"integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A=="
}
}
},
"set-function-name": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz",
"integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==",
"requires": {
"define-data-property": "^1.1.4",
"es-errors": "^1.3.0",
"functions-have-names": "^1.2.3",
"has-property-descriptors": "^1.0.2"
}
},
"setimmediate": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz",
@@ -19162,6 +19463,11 @@
"integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==",
"dev": true
},
"signature_pad": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/signature_pad/-/signature_pad-4.2.0.tgz",
"integrity": "sha512-YLWysmaUBaC5wosAKkgbX7XI+LBv2w5L0QUcI6Jc4moHYzv9BUBJtAyNLpWzHjtjKTeWOH6bfP4a4pzf0UinfQ=="
},
"simple-concat": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz",
@@ -19328,9 +19634,9 @@
"dev": true
},
"stackblur-canvas": {
"version": "2.6.0",
"resolved": "https://registry.npmjs.org/stackblur-canvas/-/stackblur-canvas-2.6.0.tgz",
"integrity": "sha512-8S1aIA+UoF6erJYnglGPug6MaHYGo1Ot7h5fuXx4fUPvcvQfcdw2o/ppCse63+eZf8PPidSu4v1JnmEVtEDnpg==",
"version": "2.7.0",
"resolved": "https://registry.npmjs.org/stackblur-canvas/-/stackblur-canvas-2.7.0.tgz",
"integrity": "sha512-yf7OENo23AGJhBriGx0QivY5JP6Y1HbrrDI6WLt6C5auYZXlQrheoY8hD4ibekFKz1HOfE48Ww8kMWMnJD/zcQ==",
"optional": true
},
"statuses": {
@@ -19623,9 +19929,9 @@
}
},
"tableexport.jquery.plugin": {
"version": "1.28.0",
"resolved": "https://registry.npmjs.org/tableexport.jquery.plugin/-/tableexport.jquery.plugin-1.28.0.tgz",
"integrity": "sha512-ydDjOhw8A+LOu+801zPXDeMF8MoU1q2HtS2msphCuny0tdXgbXG9GJfA4ll1hBs0ABiAnOaVVZaRuxBmW/qHtw==",
"version": "1.30.0",
"resolved": "https://registry.npmjs.org/tableexport.jquery.plugin/-/tableexport.jquery.plugin-1.30.0.tgz",
"integrity": "sha512-kMztiFUsGbxsknFVCDph+5j4e9xmqBBV6Na7T9vRYCUGDxtlndrdxMs9qLJDSOXjlgkIqCUv+S/e5iTUNAFF/g==",
"requires": {
"file-saver": ">=2.0.4",
"html2canvas": ">=1.0.0",
@@ -20602,14 +20908,14 @@
}
},
"which-collection": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.1.tgz",
"integrity": "sha512-W8xeTUwaln8i3K/cY1nGXzdnVZlidBcagyNFtBdD5kxnb4TvGKR7FfSIS3mYpwWS1QUCutfKz8IY8RjftB0+1A==",
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.2.tgz",
"integrity": "sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==",
"requires": {
"is-map": "^2.0.1",
"is-set": "^2.0.1",
"is-weakmap": "^2.0.1",
"is-weakset": "^2.0.1"
"is-map": "^2.0.3",
"is-set": "^2.0.3",
"is-weakmap": "^2.0.2",
"is-weakset": "^2.0.3"
}
},
"which-module": {
+5 -4
View File
@@ -28,18 +28,18 @@
"vue-template-compiler": "2.4.4"
},
"dependencies": {
"@fortawesome/fontawesome-free": "^6.5.0",
"@fortawesome/fontawesome-free": "^6.5.2",
"acorn": "^8.11.2",
"acorn-import-assertions": "^1.9.0",
"admin-lte": "^2.4.18",
"ajv": "^6.12.6",
"alpinejs": "^3.13.5",
"alpinejs": "3.13.5",
"blueimp-file-upload": "^9.34.0",
"bootstrap": "^3.4.1",
"bootstrap-colorpicker": "^2.5.3",
"bootstrap-datepicker": "^1.10.0",
"bootstrap-less": "^3.3.8",
"bootstrap-table": "1.22.2",
"bootstrap-table": "1.22.3",
"chart.js": "^2.9.4",
"clipboard": "^2.0.11",
"css-loader": "^5.0.0",
@@ -56,7 +56,8 @@
"papaparse": "^4.3.3",
"select2": "4.0.13",
"sheetjs": "^2.0.0",
"tableexport.jquery.plugin": "1.28.0",
"signature_pad": "^4.2.0",
"tableexport.jquery.plugin": "1.30.0",
"tether": "^1.4.0",
"vue-resource": "^1.5.2",
"webpack": "^5.90.2"
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+4 -4
View File
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
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.

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