Compare commits

...

175 Commits

Author SHA1 Message Date
snipe 961268172b Merge remote-tracking branch 'origin/develop' 2021-04-26 18:12:10 -07:00
snipe b01baec7a8 Updated languages
Signed-off-by: snipe <snipe@snipe.net>
2021-04-26 18:11:48 -07:00
snipe a1bc984d17 Generate production assets, bumped version
Signed-off-by: snipe <snipe@snipe.net>
2021-04-26 17:34:02 -07:00
snipe 31944cd4d4 Bumped version
Signed-off-by: snipe <snipe@snipe.net>
2021-04-26 17:28:38 -07:00
snipe d5894a4d64 Generated dev assets
Signed-off-by: snipe <snipe@snipe.net>
2021-04-26 17:27:28 -07:00
snipe 32f043c5df Set the body skin style if one was overridden by the user profile
Signed-off-by: snipe <snipe@snipe.net>
2021-04-26 17:25:39 -07:00
snipe 23376c317e Use correct URL for css for subdirs
Signed-off-by: snipe <snipe@snipe.net>
2021-04-26 17:22:02 -07:00
snipe b3b02933a5 Removed duplicate code
Signed-off-by: snipe <snipe@snipe.net>
2021-04-26 17:21:48 -07:00
snipe 882732b2de WTF kind of gendered language was this mess?
Signed-off-by: snipe <snipe@snipe.net>
2021-04-26 17:18:17 -07:00
snipe b8c3564434 Removed min from personal CSS
Signed-off-by: snipe <snipe@snipe.net>
2021-04-26 14:05:18 -07:00
snipe 138ddfec1c Merge remote-tracking branch 'origin/develop' 2021-04-23 14:27:12 -07:00
snipe 315bcb6b38 Added use statement
Signed-off-by: snipe <snipe@snipe.net>
2021-04-23 14:26:57 -07:00
snipe 8016807268 Add @Nevets82 as a contributor 2021-04-23 12:09:34 -07:00
Steven 82f73eb9e2 Added user locale to REST API GET /api/users response; (#9486)
* Clearer reporting on import

Signed-off-by: snipe <snipe@snipe.net>

* Try adding  text/x-Algol68 to import

Signed-off-by: snipe <snipe@snipe.net>

* Added user locale to REST API GET /api/users response;

Co-authored-by: snipe <snipe@snipe.net>
2021-04-23 12:09:00 -07:00
snipe b865a8aeea Merge remote-tracking branch 'origin/develop' 2021-04-21 20:19:17 -07:00
snipe 1d43eda21f Features: improved UI for importer (#9467)
* Small UI improvements for importer

Signed-off-by: snipe <snipe@snipe.net>

* And UI backup improvements

Signed-off-by: snipe <snipe@snipe.net>
2021-04-21 20:16:17 -07:00
snipe ea0d0df1af Try adding text/x-Algol68 to import
Signed-off-by: snipe <snipe@snipe.net>
2021-04-21 13:48:51 -07:00
snipe 54ef469d98 Clearer reporting on import
Signed-off-by: snipe <snipe@snipe.net>
2021-04-21 13:27:23 -07:00
snipe cef689a679 Merge branch 'develop' of https://github.com/snipe/snipe-it into develop 2021-04-21 12:29:06 -07:00
snipe 36c2edb278 Add @nepella as a contributor 2021-04-21 11:40:38 -07:00
Renee Margaret McConahy e6c3d7fe57 Restore LOG_CHANNEL environment variable. (#9464)
This allows selecting the Monolog channel with the LOG_CHANNEL variable.
2021-04-21 11:40:23 -07:00
snipe 3855b74161 Merge remote-tracking branch 'origin/develop' 2021-04-21 10:24:04 -07:00
snipe 90f79eaf83 Merge branch 'develop' of https://github.com/snipe/snipe-it into develop 2021-04-21 10:23:46 -07:00
Brady Wetherington 72a813f23d This fixes the controller signature error people are getting with LDAP logins (#9466) 2021-04-21 10:23:32 -07:00
snipe d90abdf86f Snipe codeacy workflow (#9460)
* Removed printerClass="NunoMaduro\Collision\Adapters\Phpunit\Printer"

Signed-off-by: snipe <snipe@snipe.net>

* fix ldap ad authentication filter query mechanism (#7441)

* Create SECURITY.md

* Create codacy-analysis.yml

Co-authored-by: Istvan Basa <basipottom@gmail.com>
2021-04-20 22:17:37 -07:00
snipe 1886841ec5 Create SECURITY.md 2021-04-20 22:15:41 -07:00
Istvan Basa b037d0efdd fix ldap ad authentication filter query mechanism (#7441) 2021-04-20 21:25:45 -07:00
aranar-pro 5127727730 Fixed #9424: import history adds asset model to assigned user and respects checkin date (#9350)
* Fixed #9294: Assets import history. Behaviour based on Checkin Date added, including assigning checked out items to users.

* Fixed #9294: Fixed asset import history to respect checkin and update user with checked out items.

* Fixed #9294: whitespace and comment cleanup for merge

* Fixed #9294: Fixed asset import history to respect checkin and update user with checked out items.
2021-04-20 21:25:17 -07:00
Ross Crawford-d'Heureuse 2a058c3ce1 Added a docker-compose with helper services (#9105)
* Updates

* BAse

* pdated instructions round app_key

Co-authored-by: Ross Crawford-d'Heureuse <ross.crawford@mindcurv.com>
2021-04-20 21:17:34 -07:00
Mateus Villar fdcb63f251 Added #9313: Add new fpm-alpine docker image and docker secrets support (#9331)
* Add docker secret support

* Add docker secret support to selected environment variables below:

- APP_KEY_FILE        -> APP_KEY;

- DB_HOST_FILE        -> DB_HOST;
- DB_PORT_FILE        -> DB_PORT;
- DB_DATABASE_FILE    -> DB_DATABASE;
- DB_USERNAME_FILE    -> DB_USERNAME;
- DB_PASSWORD_FILE    -> DB_PASSWORD;

- REDIS_HOST_FILE     -> REDIS_HOST;
- REDIS_PASSWORD_FILE -> REDIS_PASSWORD;
- REDIS_PORT_FILE     -> REDIS_PORT;

- MAIL_HOST_FILE      -> MAIL_HOST;
- MAIL_PORT_FILE      -> MAIL_PORT;
- MAIL_USERNAME_FILE  -> MAIL_USERNAME;
- MAIL_PASSWORD_FILE  -> MAIL_PASSWORD;

* Add env file for docker secrets

* Added #9313: add new fpm-image using docker secrets

* Fix broken symlinks

* Add docker secrets support using shell script

* Remove old docker config php files
2021-04-20 21:14:47 -07:00
dependabot[bot] da79a16284 Bump ssri from 6.0.1 to 6.0.2 (#9459)
* Removed printerClass="NunoMaduro\Collision\Adapters\Phpunit\Printer"

Signed-off-by: snipe <snipe@snipe.net>

* Bump ssri from 6.0.1 to 6.0.2

Bumps [ssri](https://github.com/npm/ssri) from 6.0.1 to 6.0.2.
- [Release notes](https://github.com/npm/ssri/releases)
- [Changelog](https://github.com/npm/ssri/blob/v6.0.2/CHANGELOG.md)
- [Commits](https://github.com/npm/ssri/compare/v6.0.1...v6.0.2)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: snipe <snipe@snipe.net>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-04-20 21:13:34 -07:00
snipe d10d090d33 Moved status label help text to headline
Signed-off-by: snipe <snipe@snipe.net>
2021-04-20 15:31:07 -07:00
snipe aa6b1456b2 Added help text to custom fields headline
Signed-off-by: snipe <snipe@snipe.net>
2021-04-20 15:29:43 -07:00
snipe b2de0d4ade Changed “Asset Categories” to “Categories” since there are more than asset categories now
Signed-off-by: snipe <snipe@snipe.net>
2021-04-20 15:29:22 -07:00
snipe c17eaaad69 Check that the field is valid before checking to see count()
This mostly affects the demo, since the seeder updates info often

Signed-off-by: snipe <snipe@snipe.net>
2021-04-20 15:10:28 -07:00
snipe e286ff0be3 Added show() redirect for CustomFields::show()
Signed-off-by: snipe <snipe@snipe.net>
2021-04-20 15:09:23 -07:00
snipe 83200d3cbd Merge remote-tracking branch 'origin/develop' 2021-04-20 14:55:48 -07:00
snipe d40fe1b683 Merge branch 'develop' of https://github.com/snipe/snipe-it into develop 2021-04-20 14:54:29 -07:00
Brady Wetherington 2a28f5e66c (Maybe?) Fixes the problem where we always need LDAP enabled (#9321)
* I *think* this fixes the problem where we need LDAP even if we aren't using it?

* Pull the LdapAd dependency out of the AuthController constructor
2021-04-20 14:53:47 -07:00
snipe dd1a5681da Add @psarossy as a contributor 2021-04-20 14:53:10 -07:00
Peter Sarossy cacb707a7f Added #9355: include Accessories and Consumables on the location reports (#9356) 2021-04-20 14:53:04 -07:00
snipe e92f69dcda Add @zybersup as a contributor 2021-04-20 14:52:29 -07:00
Supapong Areeprasertkul b28b245acc Update labels.blade.php (#8441)
- Make the qr_size bigger when no barcode printed.
- BUG: Missing unit of font size for .qr-text class.
- Reduce padding-right to remove the additional space above text when print from Google Chrome. (I do not know the cause. I tried "box-sizing: border-box" without success.)
2021-04-20 14:52:17 -07:00
Michael Pietsch 15e729f4b8 fix css when not runnin in webroot directory (#9445)
Co-authored-by: Michael Pietsch <skywalker-11@mi-pietsch.de>
2021-04-20 14:49:57 -07:00
snipe 3138f45e8c Merge branch 'develop' of https://github.com/snipe/snipe-it into develop 2021-04-20 14:49:38 -07:00
snipe 3e471a6587 Add @sh1hab as a contributor 2021-04-20 14:49:31 -07:00
Masudul Haque Shihab f3831fe010 Fixed #9447 change route parameter name in locations view (#9456) 2021-04-20 14:49:05 -07:00
Ivan Nieto Vivanco 36bc47c61c Handle regex format when assigned from API (#9443) 2021-04-20 14:44:47 -07:00
snipe e4acf8d795 Merge remote-tracking branch 'origin/master' into develop 2021-04-20 14:44:01 -07:00
snipe b562f38729 Removed printerClass="NunoMaduro\Collision\Adapters\Phpunit\Printer"
Signed-off-by: snipe <snipe@snipe.net>
2021-04-19 10:51:29 -07:00
snipe e8adf8d44c One more category fix
Signed-off-by: snipe <snipe@snipe.net>
2021-04-14 16:57:55 -07:00
snipe b693e5202b Check for category name
Signed-off-by: snipe <snipe@snipe.net>
2021-04-14 16:54:36 -07:00
snipe 415ae5854f Add @Skywalker-11 as a contributor 2021-04-14 15:15:57 -07:00
snipe e1c6d4ced7 Merge branch 'develop' of https://github.com/Skywalker-11/snipe-it into Skywalker-11-develop
Signed-off-by: snipe <snipe@snipe.net>

# Conflicts:
#	app/Http/Requests/SettingsSamlRequest.php
2021-04-14 15:15:07 -07:00
snipe 252b2ee1b4 Add @Jelle-S as a contributor 2021-04-14 15:07:40 -07:00
snipe 39b0f464d2 Adds ID columns to tables that don’t have them - reproduces #9363
This reproduces #9363 without the PK in custom fields

Signed-off-by: snipe <snipe@snipe.net>
2021-04-14 15:07:11 -07:00
snipe 2c0438bdcb Add @andreaci as a contributor 2021-04-14 11:18:13 -07:00
snipe 2986765a68 Implements #9373
Signed-off-by: snipe <snipe@snipe.net>
2021-04-14 11:17:59 -07:00
snipe f19595f525 Add @deivishome as a contributor 2021-04-14 10:27:08 -07:00
snipe 465ec054d3 Add @limeless as a contributor 2021-04-14 10:22:58 -07:00
theburger 785b1ad5a6 Update snipeit.sh php version from 7.1 to 7.4 (#9407)
Snipe-it 5.2.x is required PHP 7.4 or above,
update script to install PHP 7.4 instead of 7.1

## Changed
- PHP to install in script is changed to 7.4 from 7.1
- Add `''`at DB_PASSWORD when configuring `.env` file
2021-04-14 10:22:31 -07:00
snipe ab8f7e7b84 Add @Joly0 as a contributor 2021-04-14 10:21:18 -07:00
Joly0 31b2287a57 Update print.blade.php (#9426)
Fixes #9418
2021-04-14 10:20:36 -07:00
Godfrey Martinez 5fab1d6f0d FIxes Sum of purchase cost of components not taking quantity into account in Asset View > Components tab (#9424)
* git commit -m

* added text
2021-04-14 10:19:40 -07:00
Godfrey Martinez 246cc0eaa8 Feature/ch16172/adding other fields to ldap sync settings (#9416)
* new branch, added manager as an additional field. Currently having DB issues

* WIP DB Issue with eloquent

* added department to LDAP sync

* removed unused variables
2021-04-14 10:17:57 -07:00
snipe ce1d3284b0 Buld assets
Signed-off-by: snipe <snipe@snipe.net>
2021-04-14 10:12:14 -07:00
Brady Wetherington bf344fd707 Merge branch 'develop'
mix-manifest I just picked one.
version.php will get bumped by hand
bootstrap table seems to just be another copy? Added it back.
2021-04-14 09:58:21 -07:00
Ivan Nieto Vivanco 9cf5fbd675 Logic added to handle when a cloned user is imported via LDAP. (#9429) 2021-04-14 09:19:25 -07:00
Ivan Nieto Vivanco 3824a50e8b Fixes an issue with CSS when the 'skin' value in settings table is empty. (#9423) 2021-04-12 20:37:02 -07:00
snipe b6006769c3 Bumped version
Signed-off-by: snipe <snipe@snipe.net>
2021-04-06 21:02:05 -07:00
snipe bf2479c5d9 Fixed url to user-ridden style
Signed-off-by: snipe <snipe@snipe.net>
2021-04-06 20:36:13 -07:00
snipe 7ddcc97e79 Generated dev assets
Signed-off-by: snipe <snipe@snipe.net>
2021-04-06 20:35:58 -07:00
snipe ba92d751a3 Removed depreciated Input:: facade
Signed-off-by: snipe <snipe@snipe.net>
2021-04-06 20:28:05 -07:00
Brady Wetherington 6b86e2a58f Rebuilt all assets after all commits had landed 2021-04-06 20:16:59 -07:00
Brady Wetherington 792a31cc7f Merge branch 'develop' 2021-04-06 20:10:22 -07:00
snipe e47e2e3754 Fixed #9404 - include note in accessory API
Signed-off-by: snipe <snipe@snipe.net>
2021-04-06 10:57:30 -07:00
snipe 105f57e059 Possible fix for Docker failing on master
Signed-off-by: snipe <snipe@snipe.net>
2021-04-06 06:09:04 -07:00
snipe 390403ddb7 Fixed #9370 - listbox custom fields not decryoted on edit
Signed-off-by: snipe <snipe@snipe.net>
2021-04-06 05:59:31 -07:00
snipe 7da32443ff Move develop fixes to master
Signed-off-by: snipe <snipe@snipe.net>
2021-04-06 05:05:16 -07:00
Brady Wetherington 72806cf8db Fix up docker build on develop branch (#9401) 2021-04-05 22:13:31 -07:00
Serkan 0e34e43abb The return early pattern applied to improve readability. (#8894) 2021-04-05 22:03:15 -07:00
snipe 981b503653 Merge branch 'develop' of https://github.com/snipe/snipe-it into develop 2021-04-05 22:01:35 -07:00
Joel Pittet af8509c4d0 Allow NPM packages to build for production (#9171)
* add back changes before compiling assets

* new css location and mix manifest

* update papaparse, most vunerabilities attached to it

* update axios and papaparse for security releases

* removing security fixes that still allow npm run production to work

* Update lodash
2021-04-05 22:01:11 -07:00
snipe abddda2ab8 Add @kajes as a contributor 2021-04-05 21:56:45 -07:00
Lars Kajes 49532e1cd6 Add option to force TLS connection (#9327)
Co-authored-by: Lars Kajes <lars.kajes@iusinnovation.se>
2021-04-05 21:56:25 -07:00
snipe 09887bdabd Removed stray opening tag
Signed-off-by: snipe <snipe@snipe.net>
2021-04-05 21:54:31 -07:00
snipe ff0e526021 Merge branch 'develop' of https://github.com/snipe/snipe-it into develop 2021-04-05 21:53:47 -07:00
Godfrey Martinez f9f8ce6df6 Auditing feature improvement Better mobile [ch14328] (#9181) 2021-04-05 21:53:19 -07:00
snipe 55692bfe98 Add @Tetrachloromethane250 as a contributor 2021-04-05 21:52:14 -07:00
snipe 5c5fe2bd87 Merge branch 'develop' of https://github.com/snipe/snipe-it into develop 2021-04-05 21:52:01 -07:00
Tetrachloromethane250 157d9e4ebb Added #5977: Add permission to view files attached to licenses (#9264)
* Add permission to view and modify files for licenses

* Actually use the permission
2021-04-05 21:51:47 -07:00
snipe 20a3028386 Merge branch 'develop' of https://github.com/snipe/snipe-it into develop 2021-04-05 21:48:01 -07:00
snipe 3ffa3534a0 Use environmental variables in memory limits
Signed-off-by: snipe <snipe@snipe.net>
2021-04-05 21:47:57 -07:00
Jan Kiesewetter d61d189328 Change owner while copy (#7552)
* Change owner while copy

Copy all files and chown them in a 2nd layer leads to a larger image.
See layer 22 and 26 of https://hub.docker.com/layers/snipe/snipe-it/v4.7.8/images/sha256-67c865d91df1b90cef1112f12bbc9c64402dfeafde0bdb160c4f07e785ee0bcc

* Copy docker.env as user docker
2021-04-05 21:15:54 -07:00
Earl Ramirez 6a8d5282ef Add support for Debian 10 (#7414) 2021-04-05 21:06:53 -07:00
snipe f147c43dd4 Add @t3easy as a contributor 2021-04-05 21:04:39 -07:00
snipe c9ec15101c Add @ajsy as a contributor 2021-04-05 20:56:39 -07:00
snipe b9bab05ac3 Merge branch 'master' of https://github.com/ajsy/snipe-it into ajsy-master
Signed-off-by: snipe <snipe@snipe.net>

# Conflicts:
#	resources/views/users/print.blade.php
2021-04-05 20:55:49 -07:00
snipe 298bfa73c8 Add @ocelotsloth as a contributor 2021-04-05 20:35:28 -07:00
Mark Stenglein dd1b9ab926 VAGRANT: Fix Ubuntu Development VMs (#6909)
* GITIGNORE: Add vagrant log and ansible retry files

This patch adds the following to the project's .gitignore file:
  - Vagrant's log file
  - Ansible's retry files

Signed-off-by: Mark Stenglein <mark@stengle.in>

* ANSIBLE: Add Ubuntu Ansible playbook for dev env

This patch adds an Ansible playbook to provision an Ubuntu based
development environment. This playbook is fully idempotent and
can be run multiple times without negative consequences.

Signed-off-by: Mark Stenglein <mark@stengle.in>

* VAGRANTFILE: Clean Vagrantfile

There was a lot of extra VMs being provisioned by the existing
Vagrantfile. Some of this may need to come back but I am removing
it with this commit to demonstrate that this is all that is
needed.

Signed-off-by: Mark Stenglein <mark@stengle.in>

* ANSIBLE: UBUNTU: PLAYBOOK: Add .env configuration

I missed the configuration of the .env file in the initial commit.
This patch adds these configuration steps as well as the needed
Cron job for the Artisan scheduler.

Signed-off-by: Mark Stenglein <mark@stengle.in>

* Revert "VAGRANTFILE: Clean Vagrantfile"

This reverts commit a608a30d6b.

* VAGRANTFILE: Fix Ubuntu Vagrant Development Boxes

This patch addresses problems with the existing Vagrant deployment
configurations for the Ubuntu VMs.
  - The vagrant file is configuring the VMs for an incorrect bridge
    interface. Fixed by changing the config to use the default
    networking as well as a port-forward.
  - Moves provisioning over to the Ansible-Local playbook I wrote.

Signed-off-by: Mark Stenglein <mark@stengle.in>
2021-04-05 20:35:04 -07:00
Sxderp f01c93e162 Extend #6229 to include superuser permission check (#6772) 2021-04-05 20:26:06 -07:00
snipe 26b97d2b0b Add @JuustoMestari as a contributor 2021-04-05 20:16:35 -07:00
snipe df72f92bc0 Brings PR #6744 up to parity with previous changes - Set custom field's default value when creating a new asset using the API
Signed-off-by: snipe <snipe@snipe.net>
2021-04-05 20:16:06 -07:00
AlexanderWPapyrus a1f9642a18 Increases DPI of barcode for small lables (#9344)
solves issue #9293
2021-04-05 19:33:10 -07:00
Ivan Nieto Vivanco 90a24539b0 Fixes/cli importer issue (#9199)
* Added logic to handle the CLI importer.

* Fix bug introduced with the commit previous to the regression.

* Adds a validation for  variable when is null, add comments to clarify where the  class variable came from.

* Add support for when  variable is an instance of User class.
2021-04-05 19:28:31 -07:00
Godfrey Martinez 5ea759f615 Fixed #7211, #9197, #7864, [ch15504] - Added additional LDAP fields to sync (#9318)
* LDAP and Active Directory has plenty of other [ch15504]

* removed department id from ldap sync

* removed department id from ldap sync

* Update 2021_03_18_184102_adds_several_ldap_fields.php
2021-04-05 19:26:04 -07:00
Ivan Nieto Vivanco eb0ae74ef8 Fixes typo that doesn't accepts 'textarea' as custom field type element. (#9387) 2021-04-01 18:23:05 -07:00
snipe 6f4215cfac Fixed label name for field_values
Signed-off-by: snipe <snipe@snipe.net>
2021-03-31 14:07:30 -07:00
snipe a199c75f5c Added textarea and checkbox to validation rules
Signed-off-by: snipe <snipe@snipe.net>
2021-03-31 14:04:01 -07:00
snipe b5f7cb534e Fixed element name
Signed-off-by: snipe <snipe@snipe.net>
2021-03-31 14:02:25 -07:00
snipe 618e4439e2 Fixed validation to include textarea
Signed-off-by: snipe <snipe@snipe.net>
2021-03-31 14:02:10 -07:00
snipe 6a8e761c5e Added created_at and updated_at to presenter
Signed-off-by: snipe <snipe@snipe.net>
2021-03-30 08:57:20 -07:00
snipe 70a7a8f20b WTF. This shit is haunted.
Signed-off-by: snipe <snipe@snipe.net>
2021-03-30 08:00:27 -07:00
snipe a5b67965f2 Fixed CSS path
(Fixes RB #14746)

Signed-off-by: snipe <snipe@snipe.net>
2021-03-30 07:49:30 -07:00
snipe 2354e37504 Merge branch 'develop' of https://github.com/snipe/snipe-it into develop 2021-03-30 07:40:14 -07:00
Nikolay Didenko 06e641b782 Do not override per table data-id-cookie-table attribute by current route name globally (#7835) 2021-03-29 20:05:24 -07:00
Shaun McPeck c88813bbb8 set docker user as owner of key symbolic links (#7924)
Co-authored-by: Shaun McPeck <shaun@shaunmcpeck.com>
2021-03-29 19:44:42 -07:00
Marc Leuser 90b7d34c69 Added #6695: add API endpoint for license seats (#8058)
* remove miselading comment line

* added dedicated API endpoint for license seats

* don't display a seat name via API
it makes no sense and we don't have any particular sorting order
so the numbering would be inconsistent anyway

* reduce amount of IFs

* add sanity checks to show()

* fix goofed logging logic

* add tests for action log entries
2021-03-29 19:41:26 -07:00
R. Christian McDonald cb1a95a530 Apache site configurations shouldn't be written to sites-enabled (#6982)
It is better (best) practice to write configurations to sites-available and then let Apache copy the configuration to sites-enabled via 'a2ensite' command
2021-03-29 19:21:30 -07:00
NMC 3e934a1b96 Add a way for a user to override the site skin setting + fix mislabeled comment. (#6891)
* Add a way for a user to override the skin setting.

* Add site setting to allow user to change the skin.

* Fix skin list.

Co-authored-by: NMC <info@nmc-lab.com>
2021-03-29 19:09:23 -07:00
Nuno Maduro 8b6b95a05b Makes nunomaduro/collision versioning consistent with other dependencies (#9316) 2021-03-29 18:15:20 -07:00
snipe 53651ba3df Add @misilot as a contributor 2021-03-24 14:09:02 -07:00
snipe d527f23ec8 Add @raelldottin as a contributor 2021-03-24 14:08:56 -07:00
Raell Dottin 78cc47a859 Added sanity check to determine if a bind user account is set. (#9340) 2021-03-24 14:08:37 -07:00
snipe b00413e8aa Added missing .env vars to example from #8389
Signed-off-by: snipe <snipe@snipe.net>
2021-03-24 11:46:07 -07:00
Tom Misilo 7557879d4a Add support for overriding the Time and Memory Limits (#8389)
This is similar to what exists for the LDAP Import, and adds support for
setting th  Import and Report max execution time and memory limits

Co-authored-by: snipe <snipe@snipe.net>
2021-03-24 11:40:43 -07:00
snipe 0b41f9182a Merge remote-tracking branch 'origin/develop' 2021-03-24 11:35:39 -07:00
Jo Drexl 0114373468 Fixing #9224 (#9328) 2021-03-22 12:57:26 -07:00
snipe 86fef3f40a Set SAML errors to warning instead of error
Signed-off-by: snipe <snipe@snipe.net>
2021-03-17 22:30:26 -07:00
snipe c90604b5ae Merge remote-tracking branch 'origin/develop' 2021-03-17 22:19:24 -07:00
snipe 069e9e52fe Try/catch barcodes so they don’t shit up the logs
Signed-off-by: snipe <snipe@snipe.net>
2021-03-17 22:19:10 -07:00
Peter Dave Hello ca8b152549 Remove unnecessary apt-get clean in Dockerfile (#9201)
This image is built from the official Debian image as upstream, so there
is no need to do apt-get clean manually.

Ref:
- docs.docker.com/develop/develop-images/dockerfile_best-practices/#apt-get

> Official Debian and Ubuntu images automatically run apt-get clean, so
> explicit invocation is not required.
2021-03-17 20:33:54 -07:00
snipe b2a3a80f96 Bumped hash
Signed-off-by: snipe <snipe@snipe.net>

# Conflicts:
#	composer.lock
#	config/version.php
2021-03-17 20:04:43 -07:00
snipe c8e172ec6b Downgrade packages
Signed-off-by: snipe <snipe@snipe.net>
2021-03-17 20:03:09 -07:00
snipe afb7fcfa3e Bumped hash
Signed-off-by: snipe <snipe@snipe.net>
2021-03-17 20:02:54 -07:00
snipe 9f3a8a43cc Merge remote-tracking branch 'origin/develop'
Signed-off-by: snipe <snipe@snipe.net>

# Conflicts:
#	composer.lock
2021-03-17 19:41:02 -07:00
snipe 8fd8e716ac Changed debug level on bad LDAP connection (#9314)
* Changed debug level on bad LDAP connection

TODO:

Unfuck all of this. It’s a mess and it really doesn’t work the way we think it does. AdLdap library strikes again. :(

Signed-off-by: snipe <snipe@snipe.net>

* Improved phrasing

Signed-off-by: snipe <snipe@snipe.net>
2021-03-17 19:24:28 -07:00
snipe 72f7baf5ee Removed unused class references 2021-03-17 16:56:32 -07:00
snipe 1b890ffcc5 Added collision 2021-03-17 15:45:00 -07:00
snipe ca882e2b3d Add @elyscape as a contributor 2021-03-15 16:42:52 -07:00
Eli Young 97fa9663b1 Fixed #9299: Use correct SVG MIME type for uploads (#9300)
The correct MIME type of SVG is image/svg+xml. Out of an abundance of
caution, I am leaving in image/svg to avoid potentially causing issues
on very old browsers, but this can likely be removed without issue.
2021-03-15 16:42:11 -07:00
snipe ab092fd209 Merge remote-tracking branch 'origin/develop'
# Conflicts:
#	app/Providers/AppServiceProvider.php
#	config/logging.php
#	config/services.php
2021-03-15 12:29:29 -07:00
Brady Wetherington c7626f8387 Add new StorageHelper and use it where it makes sense (#9276) 2021-03-15 12:26:39 -07:00
snipe 3fc24b4e61 Set spatie encryption to null 2021-03-09 21:07:41 -08:00
snipe f164f0ea60 Fixed #9266 - set a colors_array variable even if other conditions are not met 2021-03-09 21:04:32 -08:00
snipe 0dd38c4a9b One more try for logo copying
Again, this might not work, but I cannot find snipe-logo-lg.png anywhere in the repo
2021-03-09 20:41:47 -08:00
snipe 6e8aaddb40 One more changes for settings seeder (this may not work) 2021-03-09 17:40:22 -08:00
snipe 104912cdf3 Added default logos to setting seeder 2021-03-09 17:39:10 -08:00
snipe b103f724b5 Added discard changes in composer (for those weird cases where it says something changed in a vendor directory) 2021-03-09 17:38:06 -08:00
snipe cf4e97f103 Log namespacing 2021-03-09 13:39:53 -08:00
snipe f05a8d782c Added spatie encryption line 2021-03-09 13:38:53 -08:00
snipe 89ab4bb86f Revert "Added PHP8 compatibility [experimental]"
This reverts commit 3873f14971.

# Conflicts:
#	composer.lock
2021-03-09 13:38:38 -08:00
snipe 707a68fc54 Rollback :( 2021-03-09 13:15:00 -08:00
snipe 4bd9706693 Merge branch 'develop' of https://github.com/snipe/snipe-it into develop 2021-03-09 12:56:17 -08:00
snipe 0d91ebfed8 One more try at Spatie 2021-03-09 12:56:13 -08:00
snipe 2d6dcb6b3b Applying fix for Undefined class constant 'EM_AES_256' in spatie
https://github.com/spatie/laravel-backup/discussions/1247
2021-03-09 12:52:26 -08:00
snipe e9ee9ea2e9 Fixed rollbar integration 2021-03-09 12:40:00 -08:00
snipe 3873f14971 Added PHP8 compatibility [experimental] 2021-03-09 12:39:49 -08:00
Michael Pietsch 4f5374b2e8 enable use custom file based saml certificate/private key 2020-08-14 12:25:00 +02:00
ajsy a714cd357f Update web.php 2019-05-03 15:22:05 +03:00
ajsy 0cdc7af611 Update print.blade.php 2019-05-03 15:22:01 +03:00
ajsy 9b3a8c046c Update LocationsController.php 2019-05-03 15:21:57 +03:00
ajsy 878cfee5a2 Revert "Delete print.blade.php"
This reverts commit a0721412fa.
2019-04-20 09:28:48 +03:00
ajsy a0721412fa Delete print.blade.php 2019-04-19 15:50:05 +03:00
ajsy 52add03e56 Update print.blade.php
replace string in serial number with x except last five character
2019-04-19 15:43:40 +03:00
ajsy c974968821 Update view.blade.php 2019-04-19 14:03:09 +03:00
ajsy 5dcf9fbb50 Update web.php 2019-04-19 13:20:44 +03:00
ajsy f2242fa32e Update view.blade.php 2019-04-19 13:20:41 +03:00
ajsy 38e8028300 Update LocationsController.php 2019-04-19 13:20:37 +03:00
ajsy 7a68187466 Update table.php 2019-04-19 13:20:31 +03:00
ajsy 57c0f69286 Update LocationsController.php 2019-03-09 13:45:19 +03:00
ajsy 03c5b8e4ab Create print.blade.php 2019-03-09 11:36:42 +03:00
ajsy 311dd18443 Update LocationsController.php 2019-03-09 11:34:47 +03:00
ajsy a958d56590 Update view.blade.php 2019-03-09 11:29:06 +03:00
ajsy c11e93b72f Update web.php 2019-03-09 11:14:24 +03:00
476 changed files with 11498 additions and 7502 deletions
+178
View File
@@ -2137,6 +2137,184 @@
"contributions": [
"code"
]
},
{
"login": "elyscape",
"name": "Eli Young",
"avatar_url": "https://avatars.githubusercontent.com/u/792695?v=4",
"profile": "https://elyscape.com",
"contributions": [
"code"
]
},
{
"login": "raelldottin",
"name": "Raell Dottin",
"avatar_url": "https://avatars.githubusercontent.com/u/317015?v=4",
"profile": "https://github.com/raelldottin",
"contributions": [
"code"
]
},
{
"login": "misilot",
"name": "Tom Misilo",
"avatar_url": "https://avatars.githubusercontent.com/u/1446856?v=4",
"profile": "https://github.com/misilot",
"contributions": [
"code"
]
},
{
"login": "JuustoMestari",
"name": "David Davenne",
"avatar_url": "https://avatars.githubusercontent.com/u/4496300?v=4",
"profile": "http://david.davenne.be",
"contributions": [
"code"
]
},
{
"login": "ocelotsloth",
"name": "Mark Stenglein",
"avatar_url": "https://avatars.githubusercontent.com/u/9255772?v=4",
"profile": "https://markstenglein.com",
"contributions": [
"code"
]
},
{
"login": "ajsy",
"name": "ajsy",
"avatar_url": "https://avatars.githubusercontent.com/u/35658596?v=4",
"profile": "https://github.com/ajsy",
"contributions": [
"code"
]
},
{
"login": "t3easy",
"name": "Jan Kiesewetter",
"avatar_url": "https://avatars.githubusercontent.com/u/3628035?v=4",
"profile": "https://github.com/t3easy",
"contributions": [
"code"
]
},
{
"login": "Tetrachloromethane250",
"name": "Tetrachloromethane250",
"avatar_url": "https://avatars.githubusercontent.com/u/79449630?v=4",
"profile": "https://github.com/Tetrachloromethane250",
"contributions": [
"code"
]
},
{
"login": "kajes",
"name": "Lars Kajes",
"avatar_url": "https://avatars.githubusercontent.com/u/22004482?v=4",
"profile": "https://www.kajes.se/",
"contributions": [
"code"
]
},
{
"login": "Joly0",
"name": "Joly0",
"avatar_url": "https://avatars.githubusercontent.com/u/13993216?v=4",
"profile": "https://github.com/Joly0",
"contributions": [
"code"
]
},
{
"login": "limeless",
"name": "theburger",
"avatar_url": "https://avatars.githubusercontent.com/u/1501022?v=4",
"profile": "https://github.com/limeless",
"contributions": [
"code"
]
},
{
"login": "deivishome",
"name": "David Valin Alonso",
"avatar_url": "https://avatars.githubusercontent.com/u/36065681?v=4",
"profile": "https://github.com/deivishome",
"contributions": [
"code"
]
},
{
"login": "andreaci",
"name": "andreaci",
"avatar_url": "https://avatars.githubusercontent.com/u/8290389?v=4",
"profile": "https://github.com/andreaci",
"contributions": [
"code"
]
},
{
"login": "Jelle-S",
"name": "Jelle Sebreghts",
"avatar_url": "https://avatars.githubusercontent.com/u/1828542?v=4",
"profile": "http://www.jellesebreghts.be",
"contributions": [
"code"
]
},
{
"login": "Skywalker-11",
"name": "Michael Pietsch",
"avatar_url": "https://avatars.githubusercontent.com/u/11180862?v=4",
"profile": "https://github.com/Skywalker-11",
"contributions": []
},
{
"login": "sh1hab",
"name": "Masudul Haque Shihab",
"avatar_url": "https://avatars.githubusercontent.com/u/22068886?v=4",
"profile": "https://github.com/sh1hab",
"contributions": [
"code"
]
},
{
"login": "zybersup",
"name": "Supapong Areeprasertkul",
"avatar_url": "https://avatars.githubusercontent.com/u/16099942?v=4",
"profile": "http://www.freedomdive.com/",
"contributions": [
"code"
]
},
{
"login": "psarossy",
"name": "Peter Sarossy",
"avatar_url": "https://avatars.githubusercontent.com/u/207358?v=4",
"profile": "https://github.com/psarossy",
"contributions": [
"code"
]
},
{
"login": "nepella",
"name": "Renee Margaret McConahy",
"avatar_url": "https://avatars.githubusercontent.com/u/11823649?v=4",
"profile": "https://github.com/nepella",
"contributions": [
"code"
]
},
{
"login": "Nevets82",
"name": "Steven",
"avatar_url": "https://avatars.githubusercontent.com/u/4462739?v=4",
"profile": "http://nevets82.github.io",
"contributions": [
"code"
]
}
]
}
+157
View File
@@ -0,0 +1,157 @@
# --------------------------------------------
# REQUIRED: DB SETUP
# --------------------------------------------
MYSQL_DATABASE=snipeit
MYSQL_USER=snipeit
MYSQL_PASSWORD=changeme1234
MYSQL_ROOT_PASSWORD=changeme1234
# --------------------------------------------
# REQUIRED: BASIC APP SETTINGS
# --------------------------------------------
APP_ENV=develop
APP_DEBUG=false
# please regenerate the APP_KEY value by calling `docker-compose run --rm snipeit bash` and then `php artisan key:generate --show` and then copy paste the value here
APP_KEY=base64:3ilviXqB9u6DX1NRcyWGJ+sjySF+H18CPDGb3+IVwMQ=
APP_URL=http://localhost:8000
APP_TIMEZONE='UTC'
APP_LOCALE=en
MAX_RESULTS=500
# --------------------------------------------
# REQUIRED: UPLOADED FILE STORAGE SETTINGS
# --------------------------------------------
PRIVATE_FILESYSTEM_DISK=local
PUBLIC_FILESYSTEM_DISK=local_public
# --------------------------------------------
# REQUIRED: DATABASE SETTINGS
# --------------------------------------------
DB_CONNECTION=mysql
DB_HOST=mariadb
DB_DATABASE=snipeit
DB_USERNAME=snipeit
DB_PASSWORD=changeme1234
DB_PREFIX=null
DB_DUMP_PATH='/usr/bin'
DB_CHARSET=utf8mb4
DB_COLLATION=utf8mb4_unicode_ci
# --------------------------------------------
# OPTIONAL: SSL DATABASE SETTINGS
# --------------------------------------------
DB_SSL=false
DB_SSL_IS_PAAS=false
DB_SSL_KEY_PATH=null
DB_SSL_CERT_PATH=null
DB_SSL_CA_PATH=null
DB_SSL_CIPHER=null
# --------------------------------------------
# REQUIRED: OUTGOING MAIL SERVER SETTINGS
# --------------------------------------------
MAIL_DRIVER=smtp
MAIL_HOST=mailhog
MAIL_PORT=1025
MAIL_USERNAME=null
MAIL_PASSWORD=null
MAIL_ENCRYPTION=null
MAIL_FROM_ADDR=you@example.com
MAIL_FROM_NAME='Snipe-IT'
MAIL_REPLYTO_ADDR=you@example.com
MAIL_REPLYTO_NAME='Snipe-IT'
MAIL_AUTO_EMBED_METHOD='attachment'
# --------------------------------------------
# REQUIRED: IMAGE LIBRARY
# This should be gd or imagick
# --------------------------------------------
IMAGE_LIB=gd
# --------------------------------------------
# OPTIONAL: BACKUP SETTINGS
# --------------------------------------------
MAIL_BACKUP_NOTIFICATION_DRIVER=null
MAIL_BACKUP_NOTIFICATION_ADDRESS=null
BACKUP_ENV=true
# --------------------------------------------
# OPTIONAL: SESSION SETTINGS
# --------------------------------------------
SESSION_LIFETIME=12000
EXPIRE_ON_CLOSE=false
ENCRYPT=false
COOKIE_NAME=snipeit_session
COOKIE_DOMAIN=null
SECURE_COOKIES=false
API_TOKEN_EXPIRATION_YEARS=40
# --------------------------------------------
# OPTIONAL: SECURITY HEADER SETTINGS
# --------------------------------------------
APP_TRUSTED_PROXIES=192.168.1.1,10.0.0.1
ALLOW_IFRAMING=false
REFERRER_POLICY=same-origin
ENABLE_CSP=false
CORS_ALLOWED_ORIGINS=null
ENABLE_HSTS=false
# --------------------------------------------
# OPTIONAL: CACHE SETTINGS
# --------------------------------------------
CACHE_DRIVER=file
SESSION_DRIVER=file
QUEUE_DRIVER=sync
CACHE_PREFIX=snipeit
# --------------------------------------------
# OPTIONAL: REDIS SETTINGS
# --------------------------------------------
REDIS_HOST=redis
REDIS_PASSWORD=null
REDIS_PORT=6379
# --------------------------------------------
# OPTIONAL: MEMCACHED SETTINGS
# --------------------------------------------
MEMCACHED_HOST=null
MEMCACHED_PORT=null
# --------------------------------------------
# OPTIONAL: PUBLIC S3 Settings
# --------------------------------------------
PUBLIC_AWS_SECRET_ACCESS_KEY=null
PUBLIC_AWS_ACCESS_KEY_ID=null
PUBLIC_AWS_DEFAULT_REGION=null
PUBLIC_AWS_BUCKET=null
PUBLIC_AWS_URL=null
PUBLIC_AWS_BUCKET_ROOT=null
# --------------------------------------------
# OPTIONAL: PRIVATE S3 Settings
# --------------------------------------------
PRIVATE_AWS_ACCESS_KEY_ID=null
PRIVATE_AWS_SECRET_ACCESS_KEY=null
PRIVATE_AWS_DEFAULT_REGION=null
PRIVATE_AWS_BUCKET=null
PRIVATE_AWS_URL=null
PRIVATE_AWS_BUCKET_ROOT=null
# --------------------------------------------
# OPTIONAL: LOGIN THROTTLING
# --------------------------------------------
LOGIN_MAX_ATTEMPTS=5
LOGIN_LOCKOUT_DURATION=60
RESET_PASSWORD_LINK_EXPIRES=900
# --------------------------------------------
# OPTIONAL: MISC
# --------------------------------------------
APP_LOG=stderr
APP_LOG_MAX_FILES=10
APP_LOCKED=false
APP_CIPHER=AES-256-CBC
GOOGLE_MAPS_API=
LDAP_MEM_LIM=500M
LDAP_TIME_LIM=600
+5
View File
@@ -144,6 +144,11 @@ APP_LOG=single
APP_LOG_MAX_FILES=10
APP_LOCKED=false
APP_CIPHER=AES-256-CBC
APP_FORCE_TLS=false
GOOGLE_MAPS_API=
LDAP_MEM_LIM=500M
LDAP_TIME_LIM=600
IMPORT_TIME_LIMIT=600
IMPORT_MEMORY_LIMIT=500M
REPORT_TIME_LIMIT=12000
+49
View File
@@ -0,0 +1,49 @@
# This workflow checks out code, performs a Codacy security scan
# and integrates the results with the
# GitHub Advanced Security code scanning feature. For more information on
# the Codacy security scan action usage and parameters, see
# https://github.com/codacy/codacy-analysis-cli-action.
# For more information on Codacy Analysis CLI in general, see
# https://github.com/codacy/codacy-analysis-cli.
name: Codacy Security Scan
on:
push:
branches: [ master ]
pull_request:
# The branches below must be a subset of the branches above
branches: [ master ]
schedule:
- cron: '36 23 * * 3'
jobs:
codacy-security-scan:
name: Codacy Security Scan
runs-on: ubuntu-latest
steps:
# Checkout the repository to the GitHub Actions runner
- name: Checkout code
uses: actions/checkout@v2
# Execute Codacy Analysis CLI and generate a SARIF output with the security issues identified during the analysis
- name: Run Codacy Analysis CLI
uses: codacy/codacy-analysis-cli-action@1.1.0
with:
# Check https://github.com/codacy/codacy-analysis-cli#project-token to get your project token from your Codacy repository
# You can also omit the token and run the tools that support default configurations
project-token: ${{ secrets.CODACY_PROJECT_TOKEN }}
verbose: true
output: results.sarif
format: sarif
# Adjust severity of non-security issues
gh-code-scanning-compat: true
# Force 0 exit code to allow SARIF file generation
# This will handover control about PR rejection to the GitHub side
max-allowed-issues: 2147483647
# Upload the SARIF file generated in the previous step
- name: Upload SARIF results file
uses: github/codeql-action/upload-sarif@v1
with:
sarif_file: results.sarif
+3 -1
View File
@@ -48,10 +48,12 @@ tests/_support/_generated/*
/npm-debug.log
/storage/oauth-private.key
/storage/oauth-public.key
logs/*
*.cache
.vagrant
*.log
*.retry
\.php_cs\.dist
+5 -1
View File
@@ -1,6 +1,10 @@
FROM ubuntu:bionic
LABEL maintainer Brady Wetherington <uberbrady@gmail.com>
# No need to add `apt-get clean` here, reference:
# - https://github.com/snipe/snipe-it/pull/9201
# - https://docs.docker.com/develop/develop-images/dockerfile_best-practices/#apt-get
RUN export DEBIAN_FRONTEND=noninteractive; \
export DEBCONF_NONINTERACTIVE_SEEN=true; \
echo 'tzdata tzdata/Areas select Etc' | debconf-set-selections; \
@@ -37,7 +41,6 @@ libmcrypt-dev \
php7.2-dev \
ca-certificates \
unzip \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
@@ -94,6 +97,7 @@ RUN \
&& mkdir -p "/var/lib/snipeit/keys" && ln -fs "/var/lib/snipeit/keys/oauth-private.key" "/var/www/html/storage/oauth-private.key" \
&& ln -fs "/var/lib/snipeit/keys/oauth-public.key" "/var/www/html/storage/oauth-public.key" \
&& chown docker "/var/lib/snipeit/keys/" \
&& chown -h docker "/var/www/html/storage/" \
&& chmod +x /var/www/html/artisan \
&& echo "Finished setting up application in /var/www/html"
+1
View File
@@ -57,6 +57,7 @@ RUN \
&& mkdir -p "/var/lib/snipeit/dumps" && rm -r "/var/www/html/storage/app/backups" && ln -fs "/var/lib/snipeit/dumps" "/var/www/html/storage/app/backups" \
&& mkdir -p "/var/lib/snipeit/keys" && ln -fs "/var/lib/snipeit/keys/oauth-private.key" "/var/www/html/storage/oauth-private.key" \
&& ln -fs "/var/lib/snipeit/keys/oauth-public.key" "/var/www/html/storage/oauth-public.key" \
&& chown -h "/var/www/html/storage/*.key"
&& chown -R apache "/var/lib/snipeit"
# Install composer
+102
View File
@@ -0,0 +1,102 @@
ARG ENVIRONMENT=production
ARG SNIPEIT_RELEASE=5.1.3
ARG PHP_VERSION=7.4.16
ARG PHP_ALPINE_VERSION=3.13
ARG COMPOSER_VERSION=2.0.11
# Cannot use arguments with 'COPY --from' workaround
# https://github.com/moby/moby/issues/34482#issuecomment-454716952
FROM composer:${COMPOSER_VERSION} AS composer
# Final stage
FROM php:${PHP_VERSION}-fpm-alpine${PHP_ALPINE_VERSION} AS source
LABEL maintainer="Mateus Villar <mromeravillar@gmail.com>"
ARG PACKAGES="\
mysql-client \
"
ARG DEV_PACKAGES="\
git \
"
ARG ENVIRONMENT
ENV ENVIRONMENT ${ENVIRONMENT}
ARG SNIPEIT_RELEASE
ENV SNIPEIT_RELEASE ${SNIPEIT_RELEASE}
# Cribbed from wordpress-fpm-alpine image
# set recommended PHP.ini settings
# see https://secure.php.net/manual/en/opcache.installation.php
RUN set -eux; \
docker-php-ext-enable opcache; \
{ \
echo 'opcache.memory_consumption=128'; \
echo 'opcache.interned_strings_buffer=8'; \
echo 'opcache.max_accelerated_files=4000'; \
echo 'opcache.revalidate_freq=2'; \
echo 'opcache.fast_shutdown=1'; \
} > /usr/local/etc/php/conf.d/opcache-recommended.ini
# https://wordpress.org/support/article/editing-wp-config-php/#configure-error-logging
RUN { \
# https://www.php.net/manual/en/errorfunc.constants.php
# https://github.com/docker-library/wordpress/issues/420#issuecomment-517839670
echo 'error_reporting = E_ERROR | E_WARNING | E_PARSE | E_CORE_ERROR | E_CORE_WARNING | E_COMPILE_ERROR | E_COMPILE_WARNING | E_RECOVERABLE_ERROR'; \
echo 'display_errors = Off'; \
echo 'display_startup_errors = Off'; \
echo 'log_errors = On'; \
echo 'error_log = /dev/stderr'; \
echo 'log_errors_max_len = 1024'; \
echo 'ignore_repeated_errors = On'; \
echo 'ignore_repeated_source = Off'; \
echo 'html_errors = Off'; \
} > /usr/local/etc/php/conf.d/error-logging.ini
# Install php extensions inside docker containers easily
# https://github.com/mlocati/docker-php-extension-installer
COPY --from=mlocati/php-extension-installer:1.2.19 /usr/bin/install-php-extensions /usr/local/bin/
RUN set -eux; \
install-php-extensions \
bcmath \
gd \
ldap \
mysqli \
pdo_mysql \
zip; \
rm -f /usr/local/bin/install-php-extensions; \
# Install prerequisites packages
apk add --no-cache \
${PACKAGES};
COPY --from=composer /usr/bin/composer /usr/local/bin
ARG COMPOSER_ALLOW_SUPERUSER=1
RUN set -eux; \
# Download and extract snipeit tarball
curl -o snipeit.tar.gz -fL "https://github.com/snipe/snipe-it/archive/v$SNIPEIT_RELEASE.tar.gz"; \
tar -xzf snipeit.tar.gz --strip-components=1 -C /var/www/html/; \
rm snipeit.tar.gz; \
# Install composer php dependencies
if [ "$ENVIRONMENT" = "production" ]; then \
echo "production enviroment detected!"; \
composer update \
--no-cache \
--no-dev \
--optimize-autoloader \
--working-dir=/var/www/html; \
else \
echo "development enviroment detected!"; \
apk add --no-cache \
${DEV_PACKAGES}; \
composer update \
--no-cache \
--prefer-source \
--optimize-autoloader \
--working-dir=/var/www/html; \
fi; \
rm -f /usr/local/bin/composer; \
chown -R www-data:www-data /var/www/html;
VOLUME [ "/var/lib/snipeit" ]
COPY --chown=www-data:www-data docker/docker-secrets.env /var/www/html/.env
COPY --chmod=655 docker/docker-entrypoint.sh /usr/local/bin/docker-snipeit-entrypoint
ENTRYPOINT [ "/usr/local/bin/docker-snipeit-entrypoint" ]
CMD [ "/usr/local/bin/docker-php-entrypoint", "php-fpm" ]
+5 -2
View File
@@ -1,5 +1,5 @@
![Build Status](https://app.chipperci.com/projects/0e5f8979-31eb-4ee6-9abf-050b76ab0383/status/master) [![Crowdin](https://d322cqt584bo4o.cloudfront.net/snipe-it/localized.svg)](https://crowdin.com/project/snipe-it) [![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/snipe/snipe-it?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Docker Pulls](https://img.shields.io/docker/pulls/snipe/snipe-it.svg)](https://hub.docker.com/r/snipe/snipe-it/) [![Twitter Follow](https://img.shields.io/twitter/follow/snipeitapp.svg?style=social)](https://twitter.com/snipeitapp) [![Codacy Badge](https://api.codacy.com/project/badge/Grade/553ce52037fc43ea99149785afcfe641)](https://www.codacy.com/app/snipe/snipe-it?utm_source=github.com&amp;utm_medium=referral&amp;utm_content=snipe/snipe-it&amp;utm_campaign=Badge_Grade)
[![All Contributors](https://img.shields.io/badge/all_contributors-234-orange.svg?style=flat-square)](#contributors)
[![All Contributors](https://img.shields.io/badge/all_contributors-254-orange.svg?style=flat-square)](#contributors)
## Snipe-IT - Open Source Asset Management System
@@ -122,7 +122,10 @@ Thanks goes to all of these wonderful people ([emoji key](https://github.com/ken
| [<img src="https://avatars0.githubusercontent.com/u/1255375?v=4" width="110px;"/><br /><sub>Peter Upfold</sub>](https://peter.upfold.org.uk/)<br />[💻](https://github.com/snipe/snipe-it/commits?author=PeterUpfold "Code") | [<img src="https://avatars2.githubusercontent.com/u/961717?v=4" width="110px;"/><br /><sub>Jared Biel</sub>](https://github.com/jbiel)<br />[💻](https://github.com/snipe/snipe-it/commits?author=jbiel "Code") | [<img src="https://avatars1.githubusercontent.com/u/1733625?v=4" width="110px;"/><br /><sub>Dampfklon</sub>](https://github.com/dampfklon)<br />[💻](https://github.com/snipe/snipe-it/commits?author=dampfklon "Code") | [<img src="https://avatars2.githubusercontent.com/u/52973156?v=4" width="110px;"/><br /><sub>Charles Hamilton</sub>](https://communityclosing.com)<br />[💻](https://github.com/snipe/snipe-it/commits?author=chamilton-ccn "Code") | [<img src="https://avatars.githubusercontent.com/u/551789?v=4" width="110px;"/><br /><sub>Giuseppe Iannello</sub>](https://github.com/giannello)<br />[💻](https://github.com/snipe/snipe-it/commits?author=giannello "Code") | [<img src="https://avatars.githubusercontent.com/u/3691490?v=4" width="110px;"/><br /><sub>Peter Dave Hello</sub>](https://www.peterdavehello.org/)<br />[💻](https://github.com/snipe/snipe-it/commits?author=PeterDaveHello "Code") | [<img src="https://avatars.githubusercontent.com/u/6106332?v=4" width="110px;"/><br /><sub>sigmoidal</sub>](https://github.com/sigmoidal)<br />[💻](https://github.com/snipe/snipe-it/commits?author=sigmoidal "Code") |
| [<img src="https://avatars.githubusercontent.com/u/2082554?v=4" width="110px;"/><br /><sub>Vincent Lainé</sub>](https://github.com/phenixdotnet)<br />[💻](https://github.com/snipe/snipe-it/commits?author=phenixdotnet "Code") | [<img src="https://avatars.githubusercontent.com/u/1943040?v=4" width="110px;"/><br /><sub>Lucas Pleß</sub>](http://www.lucas-pless.com)<br />[💻](https://github.com/snipe/snipe-it/commits?author=derlucas "Code") | [<img src="https://avatars.githubusercontent.com/u/472804?v=4" width="110px;"/><br /><sub>Ian Littman</sub>](http://twitter.com/iansltx)<br />[💻](https://github.com/snipe/snipe-it/commits?author=iansltx "Code") | [<img src="https://avatars.githubusercontent.com/u/3519029?v=4" width="110px;"/><br /><sub>João Paulo</sub>](https://github.com/PauloLuna)<br />[💻](https://github.com/snipe/snipe-it/commits?author=PauloLuna "Code") | [<img src="https://avatars.githubusercontent.com/u/70443365?v=4" width="110px;"/><br /><sub>ThoBur</sub>](https://github.com/ThoBur)<br />[💻](https://github.com/snipe/snipe-it/commits?author=ThoBur "Code") | [<img src="https://avatars.githubusercontent.com/u/1972329?v=4" width="110px;"/><br /><sub>Alexander Chibrikin</sub>](http://phpprofi.ru/)<br />[💻](https://github.com/snipe/snipe-it/commits?author=alek13 "Code") | [<img src="https://avatars.githubusercontent.com/u/438332?v=4" width="110px;"/><br /><sub>Anthony Winstanley</sub>](https://github.com/winstan)<br />[💻](https://github.com/snipe/snipe-it/commits?author=winstan "Code") |
| [<img src="https://avatars.githubusercontent.com/u/3075214?v=4" width="110px;"/><br /><sub>Folke</sub>](https://github.com/fashberg)<br />[💻](https://github.com/snipe/snipe-it/commits?author=fashberg "Code") | [<img src="https://avatars.githubusercontent.com/u/1351571?v=4" width="110px;"/><br /><sub>Bennett Blodinger</sub>](https://github.com/benwa)<br />[💻](https://github.com/snipe/snipe-it/commits?author=benwa "Code") | [<img src="https://avatars.githubusercontent.com/u/2974631?v=4" width="110px;"/><br /><sub>NMC</sub>](https://nmc.dev)<br />[💻](https://github.com/snipe/snipe-it/commits?author=ncareau "Code") | [<img src="https://avatars.githubusercontent.com/u/52182449?v=4" width="110px;"/><br /><sub>andres-baller</sub>](https://github.com/andres-baller)<br />[💻](https://github.com/snipe/snipe-it/commits?author=andres-baller "Code") | [<img src="https://avatars.githubusercontent.com/u/67109348?v=4" width="110px;"/><br /><sub>sean-borg</sub>](https://github.com/sean-borg)<br />[💻](https://github.com/snipe/snipe-it/commits?author=sean-borg "Code") | [<img src="https://avatars.githubusercontent.com/u/32170051?v=4" width="110px;"/><br /><sub>EDVLeer</sub>](https://github.com/EDVLeer)<br />[💻](https://github.com/snipe/snipe-it/commits?author=EDVLeer "Code") | [<img src="https://avatars.githubusercontent.com/u/23075196?v=4" width="110px;"/><br /><sub>Kurokat</sub>](https://github.com/Kurokat)<br />[💻](https://github.com/snipe/snipe-it/commits?author=Kurokat "Code") |
| [<img src="https://avatars.githubusercontent.com/u/915514?v=4" width="110px;"/><br /><sub>Kevin Köllmann</sub>](https://www.kevinkoellmann.de)<br />[💻](https://github.com/snipe/snipe-it/commits?author=koelle25 "Code") | [<img src="https://avatars.githubusercontent.com/u/49025941?v=4" width="110px;"/><br /><sub>sw-mreyes</sub>](https://github.com/sw-mreyes)<br />[💻](https://github.com/snipe/snipe-it/commits?author=sw-mreyes "Code") | [<img src="https://avatars.githubusercontent.com/u/70129?v=4" width="110px;"/><br /><sub>Joel Pittet</sub>](https://pittet.ca)<br />[💻](https://github.com/snipe/snipe-it/commits?author=joelpittet "Code") |
| [<img src="https://avatars.githubusercontent.com/u/915514?v=4" width="110px;"/><br /><sub>Kevin Köllmann</sub>](https://www.kevinkoellmann.de)<br />[💻](https://github.com/snipe/snipe-it/commits?author=koelle25 "Code") | [<img src="https://avatars.githubusercontent.com/u/49025941?v=4" width="110px;"/><br /><sub>sw-mreyes</sub>](https://github.com/sw-mreyes)<br />[💻](https://github.com/snipe/snipe-it/commits?author=sw-mreyes "Code") | [<img src="https://avatars.githubusercontent.com/u/70129?v=4" width="110px;"/><br /><sub>Joel Pittet</sub>](https://pittet.ca)<br />[💻](https://github.com/snipe/snipe-it/commits?author=joelpittet "Code") | [<img src="https://avatars.githubusercontent.com/u/792695?v=4" width="110px;"/><br /><sub>Eli Young</sub>](https://elyscape.com)<br />[💻](https://github.com/snipe/snipe-it/commits?author=elyscape "Code") | [<img src="https://avatars.githubusercontent.com/u/317015?v=4" width="110px;"/><br /><sub>Raell Dottin</sub>](https://github.com/raelldottin)<br />[💻](https://github.com/snipe/snipe-it/commits?author=raelldottin "Code") | [<img src="https://avatars.githubusercontent.com/u/1446856?v=4" width="110px;"/><br /><sub>Tom Misilo</sub>](https://github.com/misilot)<br />[💻](https://github.com/snipe/snipe-it/commits?author=misilot "Code") | [<img src="https://avatars.githubusercontent.com/u/4496300?v=4" width="110px;"/><br /><sub>David Davenne</sub>](http://david.davenne.be)<br />[💻](https://github.com/snipe/snipe-it/commits?author=JuustoMestari "Code") |
| [<img src="https://avatars.githubusercontent.com/u/9255772?v=4" width="110px;"/><br /><sub>Mark Stenglein</sub>](https://markstenglein.com)<br />[💻](https://github.com/snipe/snipe-it/commits?author=ocelotsloth "Code") | [<img src="https://avatars.githubusercontent.com/u/35658596?v=4" width="110px;"/><br /><sub>ajsy</sub>](https://github.com/ajsy)<br />[💻](https://github.com/snipe/snipe-it/commits?author=ajsy "Code") | [<img src="https://avatars.githubusercontent.com/u/3628035?v=4" width="110px;"/><br /><sub>Jan Kiesewetter</sub>](https://github.com/t3easy)<br />[💻](https://github.com/snipe/snipe-it/commits?author=t3easy "Code") | [<img src="https://avatars.githubusercontent.com/u/79449630?v=4" width="110px;"/><br /><sub>Tetrachloromethane250</sub>](https://github.com/Tetrachloromethane250)<br />[💻](https://github.com/snipe/snipe-it/commits?author=Tetrachloromethane250 "Code") | [<img src="https://avatars.githubusercontent.com/u/22004482?v=4" width="110px;"/><br /><sub>Lars Kajes</sub>](https://www.kajes.se/)<br />[💻](https://github.com/snipe/snipe-it/commits?author=kajes "Code") | [<img src="https://avatars.githubusercontent.com/u/13993216?v=4" width="110px;"/><br /><sub>Joly0</sub>](https://github.com/Joly0)<br />[💻](https://github.com/snipe/snipe-it/commits?author=Joly0 "Code") | [<img src="https://avatars.githubusercontent.com/u/1501022?v=4" width="110px;"/><br /><sub>theburger</sub>](https://github.com/limeless)<br />[💻](https://github.com/snipe/snipe-it/commits?author=limeless "Code") |
| [<img src="https://avatars.githubusercontent.com/u/36065681?v=4" width="110px;"/><br /><sub>David Valin Alonso</sub>](https://github.com/deivishome)<br />[💻](https://github.com/snipe/snipe-it/commits?author=deivishome "Code") | [<img src="https://avatars.githubusercontent.com/u/8290389?v=4" width="110px;"/><br /><sub>andreaci</sub>](https://github.com/andreaci)<br />[💻](https://github.com/snipe/snipe-it/commits?author=andreaci "Code") | [<img src="https://avatars.githubusercontent.com/u/1828542?v=4" width="110px;"/><br /><sub>Jelle Sebreghts</sub>](http://www.jellesebreghts.be)<br />[💻](https://github.com/snipe/snipe-it/commits?author=Jelle-S "Code") | [<img src="https://avatars.githubusercontent.com/u/11180862?v=4" width="110px;"/><br /><sub>Michael Pietsch</sub>](https://github.com/Skywalker-11)<br /> | [<img src="https://avatars.githubusercontent.com/u/22068886?v=4" width="110px;"/><br /><sub>Masudul Haque Shihab</sub>](https://github.com/sh1hab)<br />[💻](https://github.com/snipe/snipe-it/commits?author=sh1hab "Code") | [<img src="https://avatars.githubusercontent.com/u/16099942?v=4" width="110px;"/><br /><sub>Supapong Areeprasertkul</sub>](http://www.freedomdive.com/)<br />[💻](https://github.com/snipe/snipe-it/commits?author=zybersup "Code") | [<img src="https://avatars.githubusercontent.com/u/207358?v=4" width="110px;"/><br /><sub>Peter Sarossy</sub>](https://github.com/psarossy)<br />[💻](https://github.com/snipe/snipe-it/commits?author=psarossy "Code") |
| [<img src="https://avatars.githubusercontent.com/u/11823649?v=4" width="110px;"/><br /><sub>Renee Margaret McConahy</sub>](https://github.com/nepella)<br />[💻](https://github.com/snipe/snipe-it/commits?author=nepella "Code") | [<img src="https://avatars.githubusercontent.com/u/4462739?v=4" width="110px;"/><br /><sub>Steven</sub>](http://nevets82.github.io)<br />[💻](https://github.com/snipe/snipe-it/commits?author=Nevets82 "Code") |
<!-- ALL-CONTRIBUTORS-LIST:END -->
This project follows the [all-contributors](https://github.com/kentcdodds/all-contributors) specification. Contributions of any kind welcome!
+27
View File
@@ -0,0 +1,27 @@
# Security Policy
We take security issues very seriously, and will always attempt to address any
vulnerabilities as quickly as possible.
## Supported Versions
We try to make a reasonable effort to support older versions of Snipe-IT,
however there are times when library dependencies and/or PHP/MySQL dependencies
make it impossible to backport security fixes on older versions.
| Version | Supported |
| ------- | ------------------ |
| 5.1.x | :white_check_mark: |
| 5.0.x | :x: |
| 4.0.x | :white_check_mark: |
| < 4.0 | :x: |
## Reporting a Vulnerability
Security vulnerabilities should be sent to security@snipeitapp.com. You can typically expect a
response within two business days, and we typically have fixes out in under a week from the initial disclosure.
This obviously varies based on the severity of the security issue and the difficulty in remediation,
but those have historically been the timelines we worm around.
For a full breakdown of our security policies, please see https://snipeitapp.com/security.
Vendored
+18 -9
View File
@@ -8,25 +8,34 @@ Vagrant.configure("2") do |config|
config.vm.define "bionic" do |bionic|
bionic.vm.box = "ubuntu/bionic64"
bionic.vm.hostname = 'bionic'
bionic.vm.network "public_network", bridge: NETWORK_BRIDGE
bionic.vm.provision :shell, :inline => "wget #{SNIPEIT_SH_URL}"
bionic.vm.provision :shell, :inline => "chmod 755 snipeit.sh"
bionic.vm.network "forwarded_port", guest: 80, host: 8080
bionic.vm.synced_folder ".", "/vagrant", :owner => 'www-data',
:group => 'vagrant', :mount_options => ['dmode=775', 'fmode=775']
bionic.vm.provision "ansible_local" do |ansible|
ansible.playbook = "ansible/ubuntu/vagrant_playbook.yml"
end
end
config.vm.define "xenial" do |xenial|
xenial.vm.box = "ubuntu/xenial64"
xenial.vm.hostname = 'xenial'
xenial.vm.network "public_network", bridge: NETWORK_BRIDGE
xenial.vm.provision :shell, :inline => "wget #{SNIPEIT_SH_URL}"
xenial.vm.provision :shell, :inline => "chmod 755 snipeit.sh"
xenial.vm.network "forwarded_port", guest: 80, host: 8080
xenial.vm.synced_folder ".", "/vagrant", :owner => 'www-data',
:group => 'vagrant', :mount_options => ['dmode=775', 'fmode=775']
xenial.vm.provision "ansible_local" do |ansible|
ansible.playbook = "ansible/ubuntu/vagrant_playbook.yml"
end
end
config.vm.define "trusty" do |trusty|
trusty.vm.box = "ubuntu/trusty32"
trusty.vm.hostname = 'trusty'
trusty.vm.network "public_network", bridge: NETWORK_BRIDGE
trusty.vm.provision :shell, :inline => "wget #{SNIPEIT_SH_URL}"
trusty.vm.provision :shell, :inline => "chmod 755 snipeit.sh"
trusty.vm.network "forwarded_port", guest: 80, host: 8080
trusty.vm.synced_folder ".", "/vagrant", :owner => 'www-data',
:group => 'vagrant', :mount_options => ['dmode=775', 'fmode=775']
trusty.vm.provision "ansible_local" do |ansible|
ansible.playbook = "ansible/ubuntu/vagrant_playbook.yml"
end
end
config.vm.define "centos7" do |centos7|
+10
View File
@@ -0,0 +1,10 @@
<VirtualHost *:80>
<Directory {{ app_path }}/public>
Allow From All
AllowOverride All
Options -Indexes
</Directory>
DocumentRoot {{ app_path }}/public
ServerName {{ fqdn }}
</VirtualHost>
+226
View File
@@ -0,0 +1,226 @@
---
- name: Set up local server
hosts: all
remote_user: vagrant
become_user: root
become_method: sudo
vars:
app_path: "/var/www/snipeit"
fqdn: "localhost"
tasks:
- name: Update and upgrade existing apt packages
become: true
apt:
upgrade: yes
update_cache: yes
- name: Install Utilities
become: true
apt:
name: "{{ packages }}"
state: present
vars:
packages:
- nano
- vim
- name: Installing Apache httpd, PHP, MariaDB and other requirements.
become: true
apt:
name: "{{ packages }}"
state: present
vars:
packages:
- mariadb-client
- php
- php-curl
- php-mysql
- php-gd
- php-ldap
- php-zip
- php-mbstring
- php-xml
- php-bcmath
- curl
- git
- unzip
- python-pymysql
#
# Install the lastest version of composer
#
- name: Composer check
stat:
path: /usr/local/bin/composer
register: composer_exits
- name: Install Composer
shell: |
EXPECTED_SIGNATURE=$(wget -q -O - https://composer.github.io/installer.sig)
php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
ACTUAL_SIGNATURE=$(php -r "echo hash_file('SHA384', 'composer-setup.php');")
if [ "$EXPECTED_SIGNATURE" != "$ACTUAL_SIGNATURE" ]
then
>&2 echo 'ERROR: Invalid installer signature'
rm composer-setup.php
exit 1
fi
php composer-setup.php --quiet
RESULT=$?
rm composer-setup.php
mv composer.phar /usr/local/bin/composer
exit $RESULT
when: not composer_exits.stat.exists
args:
creates: /usr/local/bin/composer
become: true
#
# Install and Configure MariaDB
#
- name: Install MariaDB
become: true
apt:
name: mariadb-server
state: present
register: sql_server
- name: Start and Enable MySQL server
become: true
systemd:
state: started
enabled: yes
name: mariadb
- name: Create Vagrant mysql password
become: true
mysql_user:
name: vagrant
password: vagrant
login_unix_socket: /var/run/mysqld/mysqld.sock
priv: "*.*:ALL"
state: present
- name: Enable remote mysql
replace:
path: /etc/mysql/mariadb.conf.d/50-server.cnf
regexp: "127.0.0.1"
replace: "0.0.0.0"
become: true
notify:
- restart mysql
- name: Create snipeit database
become: true
mysql_db:
name: snipeit
state: present
login_unix_socket: /var/run/mysqld/mysqld.sock
#
# Install Apache Web Server
#
- name: Install Apache 2.4
apt:
name: "{{ packages }}"
state: present
vars:
packages:
- apache2
- libapache2-mod-php
become: true
register: apache2_server
- name: Start and Enable Apache2 Server
become: true
systemd:
name: apache2
state: started
enabled: yes
#- name: Disable Apache modules
# become: true
# apache2_module:
# state: absent
# name: "{{ item }}"
# with_items:
# #- mpm_prefork
# notify:
# - restart apache2
- name: Enable Apache modules
become: true
apache2_module:
state: present
name: "{{ item }}"
with_items:
- rewrite
- vhost_alias
- deflate
- expires
- proxy_fcgi
- proxy
notify:
- restart apache2
- name: Install Apache VirtualHost File
become: true
template:
src: apachevirtualhost.conf.j2
dest: "/etc/apache2/sites-available/snipeit.conf"
- name: Enable VirtualHost
become: true
command: a2ensite snipeit
args:
creates: /etc/apache2/sites-enabled/snipeit.conf
notify:
- restart apache2
- name: Map apache dir to local folder
become: true
file:
src: /vagrant
dest: "{{ app_path }}"
state: link
notify:
- restart apache2
#
# Install dependencies from composer
#
- name: Install dependencies from composer
composer:
command: install
working_dir: "{{ app_path }}"
notify:
- restart apache2
#
# Configure .env file
#
- name: Copy .env file
copy:
src: "{{ app_path }}/.env.example"
dest: "{{ app_path }}/.env"
- name: Configure .env file
lineinfile:
path: "{{ app_path }}/.env"
regexp: "{{ item.regexp }}"
line: "{{ item.line }}"
with_items:
- { regexp: '^DB_HOST=', line: 'DB_HOST=127.0.0.1'}
- { regexp: '^DB_DATABASE=', line: 'DB_DATABASE=snipeit' }
- { regexp: '^DB_USERNAME=', line: 'DB_USERNAME=vagrant' }
- { regexp: '^DB_PASSWORD=', line: 'DB_PASSWORD=vagrant' }
- { regexp: '^APP_URL=', line: "APP_URL=http://{{ fqdn }}" }
- { regexp: '^APP_ENV=', line: "APP_ENV=development" }
- { regexp: '^APP_DEBUG=', line: "APP_ENV=true" }
- name: Generate application key
shell: "php {{ app_path }}/artisan key:generate --force"
- name: Artisan Migrate
shell: "php {{ app_path }}/artisan migrate --force"
#
# Create Cron Job
#
- name: Create scheduler cron job
become: true
cron:
name: "Snipe-IT Artisan Scheduler"
job: "/usr/bin/php {{ app_path }}/artisan schedule:run"
handlers:
- name: restart apache2
become: true
systemd:
name: apache2
state: restarted
- name: restart mysql
become: true
systemd:
name: mysql
state: restarted
+19
View File
@@ -2,6 +2,7 @@
namespace App\Console\Commands;
use App\Models\Department;
use Illuminate\Console\Command;
use App\Models\Setting;
use App\Models\Ldap;
@@ -51,6 +52,10 @@ class LdapSync extends Command
$ldap_result_active_flag = Setting::getSettings()->ldap_active_flag_field;
$ldap_result_emp_num = Setting::getSettings()->ldap_emp_num;
$ldap_result_email = Setting::getSettings()->ldap_email;
$ldap_result_phone = Setting::getSettings()->ldap_phone_field;
$ldap_result_jobtitle = Setting::getSettings()->ldap_jobtitle;
$ldap_result_country = Setting::getSettings()->ldap_country;
$ldap_result_dept = Setting::getSettings()->ldap_dept;
try {
$ldapconn = Ldap::connectToLdap();
@@ -175,6 +180,16 @@ class LdapSync extends Command
$item["email"] = isset($results[$i][$ldap_result_email][0]) ? $results[$i][$ldap_result_email][0] : "" ;
$item["ldap_location_override"] = isset($results[$i]["ldap_location_override"]) ? $results[$i]["ldap_location_override"]:"";
$item["location_id"] = isset($results[$i]["location_id"]) ? $results[$i]["location_id"]:"";
$item["telephone"] = isset($results[$i][$ldap_result_phone][0]) ? $results[$i][$ldap_result_phone][0] : "";
$item["jobtitle"] = isset($results[$i][$ldap_result_jobtitle][0]) ? $results[$i][$ldap_result_jobtitle][0] : "";
$item["country"] = isset($results[$i][$ldap_result_country][0]) ? $results[$i][$ldap_result_country][0] : "";
$item["department"] = isset($results[$i][$ldap_result_dept][0]) ? $results[$i][$ldap_result_dept][0] : "";
$department = Department::firstOrCreate([
'name' => $item["department"],
]);
$user = User::where('username', $item["username"])->first();
if ($user) {
@@ -193,6 +208,10 @@ class LdapSync extends Command
$user->username = $item["username"];
$user->email = $item["email"];
$user->employee_num = e($item["employee_number"]);
$user->phone = $item["telephone"];
$user->jobtitle = $item["jobtitle"];
$user->country = $item["country"];
$user->department_id = $department->id;
// Sync activated state for Active Directory.
if ( array_key_exists('useraccountcontrol', $results[$i]) ) {
+2 -2
View File
@@ -5,8 +5,8 @@ use Illuminate\Console\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputOption;
ini_set('max_execution_time', 600); //600 seconds = 10 minutes
ini_set('memory_limit', '500M');
ini_set('max_execution_time', env('IMPORT_TIME_LIMIT', 600)); //600 seconds = 10 minutes
ini_set('memory_limit', env('IMPORT_MEMORY_LIMIT', '500M'));
/**
* Class ObjectImportCommand
+1 -1
View File
@@ -39,7 +39,7 @@ class Handler extends ExceptionHandler
public function report(Exception $exception)
{
if ($this->shouldReport($exception)) {
Log::error($exception);
\Log::error($exception);
return parent::report($exception);
}
}
+32 -33
View File
@@ -774,10 +774,9 @@ class Helper
/**
* Gracefully handle decrypting the legacy data (encrypted via mcrypt) and use the new
* decryption method instead.
* Gracefully handle decrypting encrypted fields (custom fields, etc).
*
* This is not currently used, but will be.
* @todo allow this to handle more than just strings (arrays, etc)
*
* @author A. Gianotto
* @since 3.6
@@ -1003,38 +1002,38 @@ class Helper
* @return string path to uploaded image or false if something went wrong
*/
public static function processUploadedImage(String $image_data, String $save_path) {
if ($image_data != null && $save_path != null) {
// After modification, the image is prefixed by mime info like the following:
// data:image/jpeg;base64,; This causes the image library to be unhappy, so we need to remove it.
$header = explode(';', $image_data, 2)[0];
// Grab the image type from the header while we're at it.
$extension = substr($header, strpos($header, '/')+1);
// Start reading the image after the first comma, postceding the base64.
$image = substr($image_data, strpos($image_data, ',')+1);
$file_name = str_random(25).".".$extension;
$directory= public_path($save_path);
// Check if the uploads directory exists. If not, try to create it.
if (!file_exists($directory)) {
mkdir($directory, 0755, true);
}
$path = public_path($save_path.$file_name);
try {
Image::make($image)->resize(500, 500, function ($constraint) {
$constraint->aspectRatio();
$constraint->upsize();
})->save($path);
} catch (\Exception $e) {
return false;
}
return $file_name;
if ($image_data == null || $save_path == null) {
return false;
}
return false;
// After modification, the image is prefixed by mime info like the following:
// data:image/jpeg;base64,; This causes the image library to be unhappy, so we need to remove it.
$header = explode(';', $image_data, 2)[0];
// Grab the image type from the header while we're at it.
$extension = substr($header, strpos($header, '/')+1);
// Start reading the image after the first comma, postceding the base64.
$image = substr($image_data, strpos($image_data, ',')+1);
$file_name = str_random(25).".".$extension;
$directory= public_path($save_path);
// Check if the uploads directory exists. If not, try to create it.
if (!file_exists($directory)) {
mkdir($directory, 0755, true);
}
$path = public_path($save_path.$file_name);
try {
Image::make($image)->resize(500, 500, function ($constraint) {
$constraint->aspectRatio();
$constraint->upsize();
})->save($path);
} catch (\Exception $e) {
return false;
}
return $file_name;
}
}
+23
View File
@@ -0,0 +1,23 @@
<?php
namespace App\Helpers;
use Illuminate\Support\Facades\Storage;
class StorageHelper
{
static function downloader($filename, $disk = 'default') {
if($disk == 'default') {
$disk = config('filesystems.default');
}
switch(config("filesystems.disks.$disk.driver")) {
case 'local':
return response()->download(Storage::disk($disk)->path($filename)); //works for PRIVATE or public?!
case 's3':
return redirect()->away(Storage::disk($disk)->temporaryUrl($filename, now()->addMinutes(5))); //works for private or public, I guess?
default:
return Storage::disk($disk)->download($filename);
}
}
}
@@ -254,7 +254,8 @@ class AccessoriesController extends Controller
'accessory_id' => $accessory->id,
'created_at' => Carbon::now(),
'user_id' => Auth::id(),
'assigned_to' => $request->get('assigned_to')
'assigned_to' => $request->get('assigned_to'),
'note' => $request->get('note')
]);
$accessory->logCheckout($request->input('note'), $user);
+29 -6
View File
@@ -478,13 +478,36 @@ class AssetsController extends Controller
$model = AssetModel::find($request->get('model_id'));
if (($model) && ($model->fieldset)) {
foreach ($model->fieldset->fields as $field) {
if ($field->field_encrypted=='1') {
if (Gate::allows('admin')) {
$asset->{$field->convertUnicodeDbSlug()} = \Crypt::encrypt($request->input($field->convertUnicodeDbSlug()));
}
} else {
$asset->{$field->convertUnicodeDbSlug()} = $request->input($field->convertUnicodeDbSlug());
// Set the field value based on what was sent in the request
$field_val = $request->input($field->convertUnicodeDbSlug(), null);
// If input value is null, use custom field's default value
if ($field_val == null) {
\Log::debug('Field value for '.$field->convertUnicodeDbSlug().' is null');
$field_val = $field->defaultValue($request->get('model_id'));
\Log::debug('Use the default fieldset value of '.$field->defaultValue($request->get('model_id')));
}
// if the field is set to encrypted, make sure we encrypt the value
if ($field->field_encrypted == '1') {
\Log::debug('This model field is encrypted in this fieldset.');
if (Gate::allows('admin')) {
// If input value is null, use custom field's default value
if (($field_val == null) && ($request->has('model_id')!='')){
$field_val = \Crypt::encrypt($field->defaultValue($request->get('model_id')));
} else {
$field_val = \Crypt::encrypt($request->input($field->convertUnicodeDbSlug()));
}
}
}
$asset->{$field->convertUnicodeDbSlug()} = $field_val;
}
}
@@ -95,7 +95,14 @@ class CustomFieldsController extends Controller
$field = new CustomField;
$data = $request->all();
$validator = Validator::make($data, $field->validationRules());
$regex_format = null;
if (str_contains($data["format"], "regex:")){
$regex_format = $data["format"];
}
$validator = Validator::make($data, $field->validationRules($regex_format));
if ($validator->fails()) {
return response()->json(Helper::formatStandardApiResponse('error', null, $validator->errors()));
}
@@ -49,10 +49,12 @@ class ImportController extends Controller
if (!in_array($file->getMimeType(), array(
'application/vnd.ms-excel',
'text/csv',
'application/csv',
'text/x-Algol68', // because wtf CSV files?
'text/plain',
'text/comma-separated-values',
'text/tsv'))) {
$results['error']='File type must be CSV';
$results['error']='File type must be CSV. Uploaded file is '.$file->getMimeType();
return response()->json(Helper::formatStandardApiResponse('error', null, $results['error']), 500);
}
@@ -0,0 +1,138 @@
<?php
namespace App\Http\Controllers\Api;
use App\Helpers\Helper;
use App\Http\Controllers\Controller;
use App\Http\Transformers\LicenseSeatsTransformer;
use App\Models\Asset;
use App\Models\License;
use App\Models\LicenseSeat;
use App\Models\User;
use Auth;
use Illuminate\Http\Request;
class LicenseSeatsController extends Controller
{
/**
* Display a listing of the resource.
*
* @return \Illuminate\Http\Response
*/
public function index(Request $request, $licenseId)
{
//
if ($license = License::find($licenseId)) {
$this->authorize('view', $license);
$seats = LicenseSeat::with('license', 'user', 'asset', 'user.department')
->where('license_seats.license_id', $licenseId);
$order = $request->input('order') === 'asc' ? 'asc' : 'desc';
if ($request->input('sort')=='department') {
$seats->OrderDepartments($order);
} else {
$seats->orderBy('id', $order);
}
$total = $seats->count();
$offset = (($seats) && (request('offset') > $total)) ? 0 : request('offset', 0);
$limit = request('limit', 50);
$seats = $seats->skip($offset)->take($limit)->get();
if ($seats) {
return (new LicenseSeatsTransformer)->transformLicenseSeats($seats, $total);
}
}
return response()->json(Helper::formatStandardApiResponse('error', null, trans('admin/licenses/message.does_not_exist')), 200);
}
/**
* Display the specified resource.
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public function show($licenseId, $seatId)
{
//
$this->authorize('view', License::class);
// sanity checks:
// 1. does the license seat exist?
if (!$licenseSeat = LicenseSeat::find($seatId)) {
return response()->json(Helper::formatStandardApiResponse('error', null, 'Seat not found'));
}
// 2. does the seat belong to the specified license?
if (!$license = $licenseSeat->license()->first() || $license->id != intval($licenseId)) {
return response()->json(Helper::formatStandardApiResponse('error', null, 'Seat does not belong to the specified license'));
}
return (new LicenseSeatsTransformer)->transformLicenseSeat($licenseSeat);
}
/**
* Update the specified resource in storage.
*
* @param \Illuminate\Http\Request $request
* @param int $licenseId
* @param int $seatId
* @return \Illuminate\Http\Response
*/
public function update(Request $request, $licenseId, $seatId)
{
$this->authorize('checkout', License::class);
// sanity checks:
// 1. does the license seat exist?
if (!$licenseSeat = LicenseSeat::find($seatId)) {
return response()->json(Helper::formatStandardApiResponse('error', null, 'Seat not found'));
}
// 2. does the seat belong to the specified license?
if (!$license = $licenseSeat->license()->first() || $license->id != intval($licenseId)) {
return response()->json(Helper::formatStandardApiResponse('error', null, 'Seat does not belong to the specified license'));
}
$oldUser = $licenseSeat->user()->first();
$oldAsset = $licenseSeat->asset()->first();
// attempt to update the license seat
$licenseSeat->fill($request->all());
$licenseSeat->user_id = Auth::user()->id;
// check if this update is a checkin operation
// 1. are relevant fields touched at all?
$touched = $licenseSeat->isDirty('assigned_to') || $licenseSeat->isDirty('asset_id');
// 2. are they cleared? if yes then this is a checkin operation
$is_checkin = ($touched && $licenseSeat->assigned_to === null && $licenseSeat->asset_id === null);
if (!$touched) {
// nothing to update
return response()->json(Helper::formatStandardApiResponse('success', $licenseSeat, trans('admin/licenses/message.update.success')));
}
if ($licenseSeat->save()) {
// the logging functions expect only one "target". if both asset and user are present in the request,
// we simply let assets take precedence over users...
$changes = $licenseSeat->getChanges();
if (array_key_exists('assigned_to', $changes)) {
$target = $is_checkin ? $oldUser : User::find($changes['assigned_to']);
}
if (array_key_exists('asset_id', $changes)) {
$target = $is_checkin ? $oldAsset : Asset::find($changes['asset_id']);
}
if ($is_checkin) {
$licenseSeat->logCheckin($target, $request->input('note'));
return response()->json(Helper::formatStandardApiResponse('success', $licenseSeat, trans('admin/licenses/message.update.success')));
}
// in this case, relevant fields are touched but it's not a checkin operation. so it must be a checkout operation.
$licenseSeat->logCheckout($request->input('note'), $target);
return response()->json(Helper::formatStandardApiResponse('success', $licenseSeat, trans('admin/licenses/message.update.success')));
}
return Helper::formatStandardApiResponse('error', null, $licenseSeat->getErrors());
}
}
@@ -237,50 +237,6 @@ class LicensesController extends Controller
}
return response()->json(Helper::formatStandardApiResponse('error', null, trans('admin/licenses/message.assoc_users')));
}
/**
* Get license seat listing
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v1.0]
* @param int $licenseId
* @return \Illuminate\Contracts\View\View
*/
public function seats(Request $request, $licenseId)
{
if ($license = License::find($licenseId)) {
$this->authorize('view', $license);
$seats = LicenseSeat::with('license', 'user', 'asset', 'user.department')
->where('license_seats.license_id', $licenseId);
$order = $request->input('order') === 'asc' ? 'asc' : 'desc';
if ($request->input('sort')=='department') {
$seats->OrderDepartments($order);
} else {
$seats->orderBy('id', $order);
}
$offset = (($seats) && (request('offset') > $seats->count())) ? 0 : request('offset', 0);
$limit = request('limit', 50);
$total = $seats->count();
$seats = $seats->skip($offset)->take($limit)->get();
if ($seats) {
return (new LicenseSeatsTransformer)->transformLicenseSeats($seats, $total);
}
}
return response()->json(Helper::formatStandardApiResponse('error', null, trans('admin/licenses/message.does_not_exist')), 200);
}
/**
* Gets a paginated collection for the select2 menus
+22 -13
View File
@@ -36,13 +36,17 @@ class SettingsController extends Controller
public function ldapAdSettingsTest(LdapAd $ldap): JsonResponse
{
if(!$ldap->init()) {
Log::info('LDAP is not enabled cannot test.');
Log::info('LDAP is not enabled so we cannot test.');
return response()->json(['message' => 'LDAP is not enabled, cannot test.'], 400);
}
// The connect, bind and resulting users message
$message = [];
// This is all kinda fucked right now. The connection test doesn't actually do what you think,
// // and the way we parse the errors
// on the JS side is horrible.
Log::info('Preparing to test LDAP user login');
// Test user can connect to the LDAP server
try {
@@ -51,13 +55,11 @@ class SettingsController extends Controller
'message' => 'Successfully connected to LDAP server.'
];
} catch (\Exception $ex) {
\Log::debug('LDAP connected but Bind failed. Please check your LDAP settings and try again.');
return response()->json([
'message' => 'Error logging into LDAP server, error: ' . $ex->getMessage() . ' - Verify your that your username and password are correct']);
\Log::debug('Connection to LDAP server '.Setting::getSettings()->ldap_server.' failed. Please check your LDAP settings and try again. Server Responded with error: ' . $ex->getMessage());
return response()->json(
['message' => 'Connection to LDAP server '.Setting::getSettings()->ldap_server." failed. Verify that the LDAP hostname is entered correctly and that it can be reached from this web server. \n\nServer Responded with error: " . $ex->getMessage()
} catch (\Exception $e) {
\Log::info('LDAP connection failed but we cannot debug it any further on our end.');
return response()->json(['message' => 'The LDAP connection failed but we cannot debug it any further on our end. The error from the server is: '.$e->getMessage()], 500);
], 400);
}
Log::info('Preparing to test LDAP bind connection');
@@ -66,12 +68,11 @@ class SettingsController extends Controller
Log::info('Testing Bind');
$ldap->testLdapAdBindConnection();
$message['bind'] = [
'message' => 'Successfully binded to LDAP server.'
'message' => 'Successfully bound to LDAP server.'
];
} catch (\Exception $ex) {
Log::info('LDAP Bind failed');
return response()->json([
'message' => 'Error binding to LDAP server, error: ' . $ex->getMessage()
return response()->json(['message' => 'Connection to LDAP successful, but we were unable to Bind the LDAP user '.Setting::getSettings()->ldap_uname.". Verify your that your LDAP Bind username and password are correct. \n\nServer Responded with error: " . $ex->getMessage()
], 400);
}
@@ -94,9 +95,17 @@ class SettingsController extends Controller
'email' => $item[$settings['ldap_email']][0] ?? null,
];
});
$message['user_sync'] = [
'users' => $users
];
if ($users->count() > 0) {
$message['user_sync'] = [
'users' => $users
];
} else {
$message['user_sync'] = [
'message' => 'Connection to LDAP was successful, however there were no users returned from your query. You should confirm the Base Bind DN above.'
];
return response()->json($message, 400);
}
} catch (\Exception $ex) {
Log::info('LDAP sync failed');
$message['user_sync'] = [
@@ -175,6 +175,7 @@ class StatuslabelsController extends Controller
$labels=[];
$points=[];
$default_color_count = 0;
$colors_array = array();
foreach ($statuslabels as $statuslabel) {
if ($statuslabel->assets_count > 0) {
@@ -49,6 +49,7 @@ class UsersController extends Controller
'users.jobtitle',
'users.last_login',
'users.last_name',
'users.locale',
'users.location_id',
'users.manager_id',
'users.notes',
@@ -9,6 +9,7 @@ use App\Models\Actionlog;
use App\Models\Asset;
use Illuminate\Support\Facades\Response;
use Illuminate\Support\Facades\Storage;
use App\Helpers\StorageHelper;
class AssetFilesController extends Controller
{
@@ -86,7 +87,7 @@ class AssetFilesController extends Controller
}
return JsonResponse::create(["error" => "Failed validation: "], 500);
}
return Storage::download($file);
return StorageHelper::downloader($file);
}
// Prepare the error message
$error = trans('admin/hardware/message.does_not_exist', ['id' => $fileId]);
@@ -14,6 +14,7 @@ use App\Models\Setting;
use App\Models\User;
use Auth;
use Carbon\Carbon;
use Intervention\Image\Facades\Image;
use DB;
use Gate;
use Illuminate\Http\Request;
@@ -483,13 +484,19 @@ class AssetsController extends Controller
return response()->file($barcode_file, $header);
} else {
// Calculate barcode width in pixel based on label width (inch)
$barcode_width = ($settings->labels_width - $settings->labels_display_sgutter) * 96.000000000001;
$barcode_width = ($settings->labels_width - $settings->labels_display_sgutter) * 200.000000000001;
$barcode = new \Com\Tecnick\Barcode\Barcode();
$barcode_obj = $barcode->getBarcodeObj($settings->alt_barcode,$asset->asset_tag,($barcode_width < 300 ? $barcode_width : 300),50);
try {
$barcode_obj = $barcode->getBarcodeObj($settings->alt_barcode,$asset->asset_tag,($barcode_width < 300 ? $barcode_width : 300),50);
file_put_contents($barcode_file, $barcode_obj->getPngData());
return response($barcode_obj->getPngData())->header('Content-type', 'image/png');
} catch(\Exception $e) {
\Log::debug('The barcode format is invalid.');
return response(file_get_contents(public_path('uploads/barcodes/invalid_barcode.gif')))->header('Content-type', 'image/gif');
}
file_put_contents($barcode_file, $barcode_obj->getPngData());
return response($barcode_obj->getPngData())->header('Content-type', 'image/png');
}
}
}
@@ -565,7 +572,12 @@ class AssetsController extends Controller
*
* This needs a LOT of love. It's done very inelegantly right now, and there are
* a ton of optimizations that could (and should) be done.
*
*
* Updated to respect checkin dates:
* No checkin column, assume all items are checked in (todays date)
* Checkin date in the past, update history.
* Checkin date in future or empty, check the item out to the user.
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v3.3]
* @return View
@@ -582,6 +594,8 @@ class AssetsController extends Controller
}
$csv = Reader::createFromPath($request->file('user_import_csv'));
$csv->setHeaderOffset(0);
$header = $csv->getHeader();
$isCheckinHeaderExplicit = in_array("checkin date", (array_map('strtolower', $header)));
$results = $csv->getRecords();
$item = array();
$status = array();
@@ -596,8 +610,19 @@ class AssetsController extends Controller
}
$batch_counter = count($item[$asset_tag]);
$item[$asset_tag][$batch_counter]['checkout_date'] = Carbon::parse(Helper::array_smart_fetch($row, "checkout date"))->format('Y-m-d H:i:s');
$item[$asset_tag][$batch_counter]['checkin_date'] = Carbon::parse(Helper::array_smart_fetch($row, "checkin date"))->format('Y-m-d H:i:s');
\Log::debug($item[$asset_tag][$batch_counter]['checkin_date']);
if ($isCheckinHeaderExplicit){
//checkin date not empty, assume past transaction or future checkin date (expected)
if (!empty(Helper::array_smart_fetch($row, "checkin date"))) {
$item[$asset_tag][$batch_counter]['checkin_date'] = Carbon::parse(Helper::array_smart_fetch($row, "checkin date"))->format('Y-m-d H:i:s');
} else {
$item[$asset_tag][$batch_counter]['checkin_date'] = '';
}
} else {
//checkin header missing, assume data is unavailable and make checkin date explicit (now) so we don't encounter invalid state.
$item[$asset_tag][$batch_counter]['checkin_date'] = Carbon::parse(now())->format('Y-m-d H:i:s');
}
$item[$asset_tag][$batch_counter]['asset_tag'] = Helper::array_smart_fetch($row, "asset tag");
$item[$asset_tag][$batch_counter]['name'] = Helper::array_smart_fetch($row, "name");
$item[$asset_tag][$batch_counter]['email'] = Helper::array_smart_fetch($row, "email");
@@ -625,16 +650,24 @@ class AssetsController extends Controller
$user_query .= ', or on username '.$firstname['username'];
}
if ($request->input('match_email')=='1') {
if ($item[$asset_tag][$batch_counter]['email']=='') {
if ($item[$asset_tag][$batch_counter]['name']=='') {
$item[$asset_tag][$batch_counter]['username'][] = $user_email = User::generateEmailFromFullName($item[$asset_tag][$batch_counter]['name']);
$user->orWhere('username', '=', $user_email);
$user_query .= ', or on username '.$user_email;
}
}
if ($request->input('match_username') == '1'){
// Added #8825: add explicit username lookup
$raw_username = $item[$asset_tag][$batch_counter]['name'];
$user->orWhere('username', '=', $raw_username);
$user_query .= ', or on username ' . $raw_username;
}
// A matching user was found
if ($user = $user->first()) {
$item[$asset_tag][$batch_counter]['checkedout_to'] = $user->id;
//$user is now matched user from db
$item[$asset_tag][$batch_counter]['user_id'] = $user->id;
Actionlog::firstOrCreate(array(
'item_id' => $asset->id,
'item_type' => Asset::class,
@@ -645,14 +678,44 @@ class AssetsController extends Controller
'created_at' => $item[$asset_tag][$batch_counter]['checkout_date'],
'action_type' => 'checkout',
));
$asset->assigned_to = $user->id;
$checkin_date = $item[$asset_tag][$batch_counter]['checkin_date'];
if ($isCheckinHeaderExplicit) {
//if checkin date header exists, assume that empty or future date is still checked out
//if checkin is before todays date, assume it's checked in and do not assign user ID, if checkin date is in the future or blank, this is the expected checkin date, items is checked out
if ((strtotime($checkin_date) > strtotime(Carbon::now())) || (empty($checkin_date))
) {
//only do this if item is checked out
$asset->assigned_to = $user->id;
$asset->assigned_type = User::class;
}
}
if (!empty($checkin_date)) {
//only make a checkin there is a valid checkin date or we created one on import.
Actionlog::firstOrCreate(array(
'item_id' =>
$item[$asset_tag][$batch_counter]['asset_id'],
'item_type' => Asset::class,
'user_id' => Auth::user()->id,
'note' => 'Checkin imported by ' . Auth::user()->present()->fullName() . ' from history importer',
'target_id' => null,
'created_at' => $checkin_date,
'action_type' => 'checkin'
));
}
if ($asset->save()) {
$status['success'][]['asset'][$asset_tag]['msg'] = 'Asset successfully matched for '.Helper::array_smart_fetch($row, "name").$user_query.' on '.$item[$asset_tag][$batch_counter]['checkout_date'];
} else {
$status['error'][]['asset'][$asset_tag]['msg'] = 'Asset and user was matched but could not be saved.';
}
} else {
$item[$asset_tag][$batch_counter]['checkedout_to'] = null;
$item[$asset_tag][$batch_counter]['user_id'] = null;
$status['error'][]['user'][Helper::array_smart_fetch($row, "name")]['msg'] = 'User does not exist so no checkin log was created.';
}
} else {
@@ -661,31 +724,6 @@ class AssetsController extends Controller
}
}
}
// Loop through and backfill the checkins
foreach ($item as $key => $asset_batch) {
$total_in_batch = count($asset_batch);
for ($x = 0; $x < $total_in_batch; $x++) {
$next = $x + 1;
// Only do this if a matching user was found
if ((array_key_exists('checkedout_to', $asset_batch[$x])) && ($asset_batch[$x]['checkedout_to']!='')) {
if (($total_in_batch > 1) && ($x < $total_in_batch) && (array_key_exists($next, $asset_batch))) {
$checkin_date = Carbon::parse($asset_batch[$next]['checkin_date'])->format('Y-m-d H:i:s');
$asset_batch[$x]['real_checkin'] = $checkin_date;
\Log::debug($asset_batch[$next]['checkin_date']);
\Log::debug($checkin_date);
Actionlog::firstOrCreate(array(
'item_id' => $asset_batch[$x]['asset_id'],
'item_type' => Asset::class,
'user_id' => Auth::user()->id,
'note' => 'Checkin imported by ' . Auth::user()->present()->fullName() . ' from history importer',
'target_id' => null,
'created_at' => $checkin_date,
'action_type' => 'checkin'
));
}
}
}
}
return view('hardware/history')->with('status', $status);
}
@@ -58,12 +58,12 @@ class LoginController extends Controller
*
* @return void
*/
public function __construct(LdapAd $ldap, Saml $saml)
public function __construct(/*LdapAd $ldap, */ Saml $saml)
{
parent::__construct();
$this->middleware('guest', ['except' => ['logout','postTwoFactorAuth','getTwoFactorAuth','getTwoFactorEnroll']]);
Session::put('backUrl', \URL::previous());
$this->ldap = $ldap;
// $this->ldap = $ldap;
$this->saml = $saml;
}
@@ -111,7 +111,7 @@ class LoginController extends Controller
Auth::login($user, true);
} else {
$username = $saml->getUsername();
Log::error("SAML user '$username' could not be found in database.");
\Log::warning("SAML user '$username' could not be found in database.");
$request->session()->flash('error', trans('auth/message.signin.error'));
$saml->clearData();
}
@@ -121,7 +121,7 @@ class LoginController extends Controller
$user->save();
}
} catch (\Exception $e) {
Log::error("There was an error authenticating the SAML user: " . $e->getMessage());
\Log::warning("There was an error authenticating the SAML user: " . $e->getMessage());
throw new \Exception($e->getMessage());
}
}
@@ -142,8 +142,9 @@ class LoginController extends Controller
*/
private function loginViaLdap(Request $request): User
{
$ldap = \App::make( LdapAd::class);
try {
return $this->ldap->ldapLogin($request->input('username'), $request->input('password'));
return $ldap->ldapLogin($request->input('username'), $request->input('password'));
} catch (\Exception $ex) {
LOG::debug("LDAP user login: " . $ex->getMessage());
throw new \Exception($ex->getMessage());
@@ -217,7 +218,7 @@ class LoginController extends Controller
$user = null;
// Should we even check for LDAP users?
if ($this->ldap->init()) {
if (Setting::getSettings()->ldap_enabled) { // avoid hitting the $this->ldap
LOG::debug("LDAP is enabled.");
try {
LOG::debug("Attempting to log user in by LDAP authentication.");
@@ -40,6 +40,24 @@ class CustomFieldsController extends Controller
}
/**
* Just redirect the user back if they try to view the details of a field.
* We already show those details on the listing page.
*
* @see CustomFieldsController::storeField()
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v5.1.5]
* @return Redirect
* @throws \Illuminate\Auth\Access\AuthorizationException
*/
public function show()
{
return redirect()->route("fields.index");
}
/**
* Returns a view with a form to create a new custom field.
*
@@ -133,16 +151,19 @@ class CustomFieldsController extends Controller
*/
public function destroy($field_id)
{
$field = CustomField::find($field_id);
if ($field = CustomField::find($field_id)) {
$this->authorize('delete', $field);
$this->authorize('delete', $field);
if ($field->fieldset->count()>0) {
return redirect()->back()->withErrors(['message' => "Field is in-use"]);
if (($field->fieldset) && ($field->fieldset->count() > 0)) {
return redirect()->back()->withErrors(['message' => "Field is in-use"]);
}
$field->delete();
return redirect()->route("fields.index")
->with("success", trans('admin/custom_fields/message.field.delete.success'));
}
$field->delete();
return redirect()->route("fields.index")
->with("success", trans('admin/custom_fields/message.field.delete.success'));
return redirect()->back()->withErrors(['message' => "Field does not exist"]);
}
@@ -10,6 +10,7 @@ use Illuminate\Support\Facades\Input;
use Illuminate\Support\Facades\Response;
use Illuminate\Support\Facades\Storage;
use Symfony\Component\HttpFoundation\JsonResponse;
use App\Helpers\StorageHelper;
class LicenseFilesController extends Controller
{
@@ -143,18 +144,18 @@ class LicenseFilesController extends Controller
// We have to override the URL stuff here, since local defaults in Laravel's Flysystem
// won't work, as they're not accessible via the web
if (config('filesystems.default') == 'local') {
return Storage::download($file);
if (config('filesystems.default') == 'local') { // TODO - is there any way to fix this at the StorageHelper layer?
return StorageHelper::downloader($file);
} else {
if ($download != 'true') {
\Log::debug('display the file');
if ($contents = file_get_contents(Storage::url($file))) {
if ($contents = file_get_contents(Storage::url($file))) { // TODO - this will fail on private S3 files or large public ones
return Response::make(Storage::url($file)->header('Content-Type', mime_content_type($file)));
}
return JsonResponse::create(["error" => "Failed validation: "], 500);
}
return Storage::download($file);
return StorageHelper::downloader($file);
}
}
+26 -1
View File
@@ -4,6 +4,7 @@ namespace App\Http\Controllers;
use App\Http\Requests\ImageUploadRequest;
use App\Models\Location;
use App\Models\User;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Storage;
@@ -210,5 +211,29 @@ class LocationsController extends Controller
return redirect()->route('locations.index')->with('error', trans('admin/locations/message.does_not_exist'));
}
public function print_assigned($id)
{
}
$location = Location::where('id',$id)->first();
$parent = Location::where('id',$location->parent_id)->first();
$manager = User::where('id',$location->manager_id)->first();
$users = User::where('location_id', $id)->with('company', 'department', 'location')->get();
$assets = Asset::where('assigned_to', $id)->where('assigned_type', Location::class)->with('model', 'model.category')->get();
return view('locations/print')->with('assets', $assets)->with('users',$users)->with('location', $location)->with('parent', $parent)->with('manager', $manager);
}
public function print_all_assigned($id)
{
$location = Location::where('id',$id)->first();
$parent = Location::where('id',$location->parent_id)->first();
$manager = User::where('id',$location->manager_id)->first();
$users = User::where('location_id', $id)->with('company', 'department', 'location')->get();
$assets = Asset::where('location_id', $id)->with('model', 'model.category')->get();
return view('locations/print')->with('assets', $assets)->with('users',$users)->with('location', $location)->with('parent', $parent)->with('manager', $manager);
}
}
+1 -2
View File
@@ -48,10 +48,9 @@ class ProfileController extends Controller
$user->last_name = $request->input('last_name');
$user->website = $request->input('website');
$user->gravatar = $request->input('gravatar');
$user->skin = $request->input('skin');
$user->phone = $request->input('phone');
if (!config('app.lock_passwords')) {
$user->locale = $request->input('locale', 'en');
}
+1 -1
View File
@@ -403,7 +403,7 @@ class ReportsController extends Controller
*/
public function postCustom(Request $request)
{
ini_set('max_execution_time', 12000);
ini_set('max_execution_time', env('REPORT_TIME_LIMIT', 12000)); //12000 seconds = 200 minutes
$this->authorize('reports.view');
+13 -2
View File
@@ -21,6 +21,7 @@ use Image;
use Input;
use Redirect;
use Response;
use App\Helpers\StorageHelper;
/**
* This controller handles all actions related to Settings for
@@ -399,6 +400,7 @@ class SettingsController extends Controller
$setting->version_footer = $request->input('version_footer');
$setting->footer_text = $request->input('footer_text');
$setting->skin = $request->input('skin');
$setting->allow_user_skin = $request->input('allow_user_skin');
$setting->show_url_in_emails = $request->input('show_url_in_emails', '0');
$setting->logo_print_assets = $request->input('logo_print_assets', '0');
@@ -941,6 +943,10 @@ class SettingsController extends Controller
$setting->ldap_tls = $request->input('ldap_tls', '0');
$setting->ldap_pw_sync = $request->input('ldap_pw_sync', '0');
$setting->custom_forgot_pass_url = $request->input('custom_forgot_pass_url');
$setting->ldap_phone_field = $request->input('ldap_phone');
$setting->ldap_jobtitle = $request->input('ldap_jobtitle');
$setting->ldap_country = $request->input('ldap_country');
$setting->ldap_dept = $request->input('ldap_dept');
}
@@ -992,6 +998,11 @@ class SettingsController extends Controller
$setting->saml_sp_x509cert = $request->input('saml_sp_x509cert');
$setting->saml_sp_privatekey = $request->input('saml_sp_privatekey');
}
if (!empty($request->input('saml_sp_x509certNew'))) {
$setting->saml_sp_x509certNew = $request->input('saml_sp_x509certNew');
} else {
$setting->saml_sp_x509certNew = "";
}
$setting->saml_custom_settings = $request->input('saml_custom_settings');
if ($setting->save()) {
@@ -1091,7 +1102,7 @@ class SettingsController extends Controller
if (! config('app.lock_passwords')) {
if (Storage::exists($path . '/' . $filename)) {
return Storage::download($path . '/' . $filename);
return StorageHelper::downloader($path . '/' . $filename);
} else {
// Redirect to the backup page
return redirect()->route('settings.backups.index')->with('error', trans('admin/settings/message.backup.file_not_found'));
@@ -1220,4 +1231,4 @@ class SettingsController extends Controller
{
return view('settings.logins');
}
}
}
@@ -117,7 +117,7 @@ class UserFilesController extends Controller
$log = Actionlog::find($fileId);
$file = $log->get_src('users');
return Response::download($file);
return Response::download($file); //FIXME this doesn't use the new StorageHelper yet, but it's complicated...
}
// Prepare the error message
$error = trans('admin/users/message.user_not_found', ['id' => $userId]);
+3 -2
View File
@@ -32,8 +32,9 @@ class ItemImportRequest extends FormRequest
public function import(Import $import)
{
ini_set('max_execution_time', 600); //600 seconds = 10 minutes
ini_set('memory_limit', '500M');
ini_set('max_execution_time', env('IMPORT_TIME_LIMIT', 600)); //600 seconds = 10 minutes
ini_set('memory_limit', env('IMPORT_MEMORY_LIMIT', '500M'));
$filename = config('app.private_uploads') . '/imports/' . $import->file_path;
$import->import_type = $this->input('import-type');
$class = title_case($import->import_type);
+61 -18
View File
@@ -5,11 +5,13 @@ namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
use OneLogin\Saml2\IdPMetadataParser as OneLogin_Saml2_IdPMetadataParser;
use OneLogin\Saml2\Utils as OneLogin_Saml2_Utils;
use App\Models\Setting;
/**
* This handles validating and cleaning SAML settings provided by the user.
*
* @author Johnson Yi <jyi.dev@outlook.com>
* @author Michael Pietsch <skywalker-11@mi-pietsch.de>
*
* @since 5.0.0
*/
@@ -55,7 +57,49 @@ class SettingsSamlRequest extends FormRequest
}
}
if ($this->input('saml_sp_regenerate_keypair') == '1' || !$this->has('saml_sp_x509cert')) {
$was_custom_x509cert = strpos(Setting::getSettings()->saml_custom_settings, 'sp_x509cert') !== false;
$custom_x509cert='';
$custom_privateKey='';
$custom_x509certNew='';
if (!empty($this->input('saml_custom_settings'))) {
$req_custom_settings = preg_split('/\r\n|\r|\n/', $this->input('saml_custom_settings'));
$custom_settings = [];
foreach ($req_custom_settings as $custom_setting) {
$split = explode('=', $custom_setting, 2);
if (count($split) == 2) {
$split[0] = trim($split[0]);
$split[1] = trim($split[1]);
if (!empty($split[0])) {
$custom_settings[] = implode('=', $split);
}
if ($split[0] == 'sp_x509cert') {
$custom_x509cert = $split[1];
} elseif ($split[0] == 'sp_privateKey') {
$custom_privateKey = $split[1];
} elseif ($split[0] == 'sp_x509certNew') {
//to prepare for Key rollover
$custom_x509certNew = $split[1];
}
}
}
$this->merge(['saml_custom_settings' => implode(PHP_EOL, $custom_settings) . PHP_EOL]);
}
$cert_updated=false;
if (!empty($custom_x509cert) && !empty($custom_privateKey)) {
// custom certificate and private key are defined
$cert_updated=true;
$x509 = openssl_x509_read($custom_x509cert);
$pkey = openssl_pkey_get_private($custom_privateKey);
} elseif ($this->input('saml_sp_regenerate_keypair') == '1' || !$this->has('saml_sp_x509cert') || $was_custom_x509cert) {
// key regeneration requested, no certificate defined yet or previous custom certicate was removed
error_log("regen");
$cert_updated=true;
$dn = [
"countryName" => "US",
"stateOrProvinceName" => "N/A",
@@ -94,24 +138,23 @@ class SettingsSamlRequest extends FormRequest
}
}
if (!empty($this->input('saml_custom_settings'))) {
$req_custom_settings = preg_split('/\r\n|\r|\n/', $this->input('saml_custom_settings'));
$custom_settings = [];
foreach ($req_custom_settings as $custom_setting) {
$split = explode('=', $custom_setting, 2);
if (count($split) == 2) {
$split[0] = trim($split[0]);
$split[1] = trim($split[1]);
if (!empty($split[0])) {
$custom_settings[] = implode('=', $split);
}
}
if ($custom_x509certNew) {
$x509New = openssl_x509_read($custom_x509certNew);
openssl_x509_export($x509New, $x509certNew);
while (($error = openssl_error_string() !== false)) {
$errors[] = $error;
}
$this->merge(['saml_custom_settings' => implode(PHP_EOL, $custom_settings) . PHP_EOL]);
if (!empty($x509certNew)) {
$this->merge([
'saml_sp_x509certNew' => $x509certNew
]);
}
} else {
$this->merge([
'saml_sp_x509certNew' => ""
]);
}
});
}
@@ -20,12 +20,11 @@ class LicenseSeatsTransformer
return (new DatatablesTransformer)->transformDatatables($array, $total);
}
public function transformLicenseSeat (LicenseSeat $seat, $seat_count)
public function transformLicenseSeat (LicenseSeat $seat, $seat_count=0)
{
$array = [
'id' => (int) $seat->id,
'license_id' => (int) $seat->license->id,
'name' => 'Seat '.$seat_count,
'assigned_user' => ($seat->user) ? [
'id' => (int) $seat->user->id,
'name'=> e($seat->user->present()->fullName),
@@ -49,6 +48,10 @@ class LicenseSeatsTransformer
'user_can_checkout' => (($seat->assigned_to=='') && ($seat->asset_id=='')),
];
if($seat_count != 0) {
$array['name'] = 'Seat '.$seat_count;
}
$permissions_array['available_actions'] = [
'checkout' => Gate::allows('checkout', License::class),
'checkin' => Gate::allows('checkin', License::class),
@@ -27,6 +27,7 @@ class UsersTransformer
'first_name' => e($user->first_name),
'last_name' => e($user->last_name),
'username' => e($user->username),
'locale' => ($user->locale) ? e($user->locale) : null,
'employee_num' => e($user->employee_num),
'manager' => ($user->manager) ? [
'id' => (int) $user->manager->id,
+3 -1
View File
@@ -120,8 +120,10 @@ class AssetImporter extends ItemImporter
$this->log('Asset ' . $this->item["name"] . ' with serial number ' . $this->item['serial'] . ' was created');
// If we have a target to checkout to, lets do so.
//-- user_id is a property of the abstract class Importer, which this class inherits from and it's setted by
//-- the class that needs to use it (command importer or GUI importer inside the project).
if(isset($target)) {
$asset->fresh()->checkOut($target);
$asset->fresh()->checkOut($target, $this->user_id);
}
return;
}
+8 -2
View File
@@ -313,8 +313,14 @@ class Asset extends Depreciable
}
if ($this->save()) {
event(new CheckoutableCheckedOut($this, $target, Auth::user(), $note));
if (is_integer($admin)){
$checkedOutBy = User::findOrFail($admin);
} elseif (get_class($admin) === 'App\Models\User') {
$checkedOutBy = $admin;
} else {
$checkedOutBy = Auth::user();
}
event(new CheckoutableCheckedOut($this, $target, $checkedOutBy, $note));
$this->increment('checkout_counter', 1);
return true;
+1 -1
View File
@@ -78,7 +78,7 @@ final class Company extends SnipeModel
$company_id = null;
}
$table = ($table_name) ? DB::getTablePrefix().$table_name."." : '';
$table = ($table_name) ? $table_name."." : '';
if(\Schema::hasColumn($query->getModel()->getTable(), $column)){
return $query->where($table.$column, '=', $company_id);
+3 -3
View File
@@ -353,16 +353,16 @@ class CustomField extends Model
* @since [v4.1.10]
* @return array
*/
public function validationRules()
public function validationRules($regex_format = null)
{
return [
"name" => "required|unique:custom_fields",
"element" => [
"required",
Rule::in(['text', 'listbox'])
Rule::in(['text', 'listbox', 'textarea', 'checkbox', 'radio'])
],
'format' => [
Rule::in(array_merge(array_keys(CustomField::PREDEFINED_FORMATS), CustomField::PREDEFINED_FORMATS))
Rule::in(array_merge(array_keys(CustomField::PREDEFINED_FORMATS), CustomField::PREDEFINED_FORMATS, [$regex_format]))
],
'field_encrypted' => "nullable|boolean"
];
+23 -9
View File
@@ -93,8 +93,12 @@ class Ldap extends Model
\Log::debug('Attempting to login using distinguished name:'.$userDn);
$filterQuery = $settings->ldap_auth_filter_query . $username;
$filter = Setting::getSettings()->ldap_filter;
$filterQuery = "({$filter}({$filterQuery}))";
\Log::debug('Filter query: '.$filterQuery);
if (!$ldapbind = @ldap_bind($connection, $userDn, $password)) {
@@ -161,7 +165,7 @@ class Ldap extends Model
* @param $ldapatttibutes
* @return array|bool
*/
static function parseAndMapLdapAttributes($ldapatttibutes)
static function parseAndMapLdapAttributes($ldapattributes)
{
//Get LDAP attribute config
$ldap_result_username = Setting::getSettings()->ldap_username_field;
@@ -169,15 +173,21 @@ class Ldap extends Model
$ldap_result_last_name = Setting::getSettings()->ldap_lname_field;
$ldap_result_first_name = Setting::getSettings()->ldap_fname_field;
$ldap_result_email = Setting::getSettings()->ldap_email;
$ldap_result_phone = Setting::getSettings()->ldap_phone;
$ldap_result_jobtitle = Setting::getSettings()->ldap_jobtitle;
$ldap_result_country = Setting::getSettings()->ldap_country;
$ldap_result_dept = Setting::getSettings()->ldap_dept;
// Get LDAP user data
$item = array();
$item["username"] = isset($ldapatttibutes[$ldap_result_username][0]) ? $ldapatttibutes[$ldap_result_username][0] : "";
$item["employee_number"] = isset($ldapatttibutes[$ldap_result_emp_num][0]) ? $ldapatttibutes[$ldap_result_emp_num][0] : "";
$item["lastname"] = isset($ldapatttibutes[$ldap_result_last_name][0]) ? $ldapatttibutes[$ldap_result_last_name][0] : "";
$item["firstname"] = isset($ldapatttibutes[$ldap_result_first_name][0]) ? $ldapatttibutes[$ldap_result_first_name][0] : "";
$item["email"] = isset($ldapatttibutes[$ldap_result_email][0]) ? $ldapatttibutes[$ldap_result_email][0] : "" ;
$item["username"] = isset($ldapattributes[$ldap_result_username][0]) ? $ldapattributes[$ldap_result_username][0] : "";
$item["employee_number"] = isset($ldapattributes[$ldap_result_emp_num][0]) ? $ldapattributes[$ldap_result_emp_num][0] : "";
$item["lastname"] = isset($ldapattributes[$ldap_result_last_name][0]) ? $ldapattributes[$ldap_result_last_name][0] : "";
$item["firstname"] = isset($ldapattributes[$ldap_result_first_name][0]) ? $ldapattributes[$ldap_result_first_name][0] : "";
$item["email"] = isset($ldapattributes[$ldap_result_email][0]) ? $ldapattributes[$ldap_result_email][0] : "" ;
$item["telephone"] = isset($ldapattributes[$ldap_result_phone][0]) ?$ldapattributes[$ldap_result_phone][0] : "";
$item["jobtitle"] = isset($ldapattributes[$ldap_result_jobtitle][0]) ? $ldapattributes[$ldap_result_jobtitle][0] : "";
$item["country"] = isset($ldapattributes[$ldap_result_country][0]) ? $ldapattributes[$ldap_result_country][0] : "";
$item["department"] = isset($ldapattributes[$ldap_result_dept][0]) ? $ldapattributes[$ldap_result_dept][0] : "";
return $item;
@@ -263,7 +273,11 @@ class Ldap extends Model
if ($filter != '' && substr($filter, 0, 1) != '(') { // wrap parens around NON-EMPTY filters that DON'T have them, for back-compatibility with AdLdap2-based filters
$filter = "($filter)";
} elseif ($filter == '') {
$filter = "(cn=*)";
}
$search_results = ldap_search($ldapconn, $base_dn, $filter);
if (!$search_results) {
+10
View File
@@ -20,6 +20,16 @@ class LicenseSeat extends SnipeModel implements ICompanyableChild
protected $guarded = 'id';
protected $table = 'license_seats';
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = [
'assigned_to',
'asset_id'
];
use Acceptable;
public function getCompanyableParents()
+21 -27
View File
@@ -114,20 +114,12 @@ class User extends SnipeModel implements AuthenticatableContract, AuthorizableCo
/**
* Check user permissions
* Internally check the user permission for the given section
*
* Parses the user and group permission masks to see if the user
* is authorized to do the thing
*
* @author A. Gianotto <snipe@snipe.net>
* @since [v1.0]
* @return boolean
*/
public function hasAccess($section)
protected function checkPermissionSection($section)
{
if ($this->isSuperUser()) {
return true;
}
$user_groups = $this->groups;
@@ -158,6 +150,24 @@ class User extends SnipeModel implements AuthenticatableContract, AuthorizableCo
return false;
}
/**
* Check user permissions
*
* Parses the user and group permission masks to see if the user
* is authorized to do the thing
*
* @author A. Gianotto <snipe@snipe.net>
* @since [v1.0]
* @return boolean
*/
public function hasAccess($section)
{
if ($this->isSuperUser()) {
return true;
}
return $this->checkPermissionSection($section);
}
/**
* Checks if the user is a SuperUser
*
@@ -167,23 +177,7 @@ class User extends SnipeModel implements AuthenticatableContract, AuthorizableCo
*/
public function isSuperUser()
{
if (!$user_permissions = json_decode($this->permissions, true)) {
return false;
}
foreach ($this->groups as $user_group) {
$group_permissions = json_decode($user_group->permissions, true);
$group_array = (array)$group_permissions;
if ((array_key_exists('superuser', $group_array)) && ($group_permissions['superuser']=='1')) {
return true;
}
}
if ((array_key_exists('superuser', $user_permissions)) && ($user_permissions['superuser']=='1')) {
return true;
}
return false;
return $this->checkPermissionSection('superuser');
}
+10
View File
@@ -35,4 +35,14 @@ class LicensePolicy extends CheckoutablePermissionsPolicy
return false;
}
/**
* Determine whether the user can access files associated with licenses.
*
* @param \App\Models\User $user
* @return mixed
*/
public function files(User $user)
{
return $user->hasAccess($this->columnName().'.files');
}
}
+17
View File
@@ -115,6 +115,23 @@ class AssetModelPresenter extends Presenter
"title" => trans('general.notes'),
"visible" => false,
],
[
"field" => "created_at",
"searchable" => true,
"sortable" => true,
"visible" => false,
"title" => trans('general.created_at'),
"formatter" => "dateDisplayFormatter"
],
[
"field" => "updated_at",
"searchable" => true,
"sortable" => true,
"visible" => false,
"title" => trans('general.updated_at'),
"formatter" => "dateDisplayFormatter"
],
];
+17 -1
View File
@@ -79,7 +79,23 @@ class CategoryPresenter extends Presenter
"title" => trans('table.actions'),
"visible" => true,
"formatter" => "categoriesActionsFormatter",
]
],
[
"field" => "created_at",
"searchable" => true,
"sortable" => true,
"visible" => false,
"title" => trans('general.created_at'),
"formatter" => "dateDisplayFormatter"
],
[
"field" => "updated_at",
"searchable" => true,
"sortable" => true,
"visible" => false,
"title" => trans('general.updated_at'),
"formatter" => "dateDisplayFormatter"
],
];
return json_encode($layout);
+9 -1
View File
@@ -16,6 +16,7 @@ use App\Observers\LicenseObserver;
use App\Observers\SettingObserver;
use Illuminate\Support\Facades\Schema;
use Illuminate\Support\ServiceProvider;
use Illuminate\Routing\UrlGenerator;
/**
* This service provider handles setting the observers on models
@@ -33,8 +34,15 @@ class AppServiceProvider extends ServiceProvider
* @since [v3.0]
* @return void
*/
public function boot()
public function boot(UrlGenerator $url)
{
if (env('APP_FORCE_TLS')) {
if (strpos(env('APP_URL'), 'https') === 0) {
$url->forceScheme('https');
} else {
\Log::warning("'APP_FORCE_TLS' is set to true, but 'APP_URL' does not start with 'https://'. Will not force TLS on connections.");
}
}
Schema::defaultStringLength(191);
Asset::observe(AssetObserver::class);
Accessory::observe(AccessoryObserver::class);
+12 -1
View File
@@ -2,8 +2,9 @@
use App\Services\LdapAd;
use Illuminate\Support\ServiceProvider;
use Illuminate\Contracts\Support\DeferrableProvider;
class LdapServiceProvider extends ServiceProvider
class LdapServiceProvider extends ServiceProvider implements DeferrableProvider
{
/**
@@ -26,4 +27,14 @@ class LdapServiceProvider extends ServiceProvider
{
$this->app->singleton(LdapAd::class, LdapAd::class);
}
/**
* Get the services provided by the provider.
*
* @return array
*/
public function provides()
{
return [LdapAd::class];
}
}
+10 -4
View File
@@ -129,7 +129,13 @@ class LdapAd extends LdapAdConfiguration
$login_username = $username;
}
if ($this->ldap->auth()->attempt($login_username, $password, true) === false) {
if ($this->ldapConfig['username'] && $this->ldapConfig['password']) {
$bind_as_user = false;
} else {
$bind_as_user = true;
}
if ($this->ldap->auth()->attempt($login_username, $password, $bind_as_user) === false) {
throw new Exception('Unable to validate user credentials!');
}
@@ -504,9 +510,9 @@ class LdapAd extends LdapAdConfiguration
{
try {
$this->ldap->connect();
} catch (\Adldap\Auth\BindException $e) {
Log::error($e);
throw new Exception('Unable to connect to LDAP directory!');
} catch (\Exception $e) {
Log::debug('LDAP ERROR: '.$e->getMessage());
throw new Exception($e->getMessage());
}
}
+7 -2
View File
@@ -141,6 +141,7 @@ class Saml
* Builds settings from Snipe-IT for OneLogin_Saml2_Auth.
*
* @author Johnson Yi <jyi.dev@outlook.com>
* @author Michael Pietsch <skywalker-11@mi-pietsch.de>
*
* @since 5.0.0
*
@@ -162,6 +163,11 @@ class Saml
data_set($settings, 'sp.singleLogoutService.url', route('saml.sls'));
data_set($settings, 'sp.x509cert', $setting->saml_sp_x509cert);
data_set($settings, 'sp.privateKey', $setting->saml_sp_privatekey);
if(!empty($setting->saml_sp_x509certNew)) {
data_set($settings, 'sp.x509certNew', $setting->saml_sp_x509certNew);
} else {
data_set($settings, 'sp.x509certNew', "");
}
if (!empty(data_get($settings, 'sp.privateKey'))) {
data_set($settings, 'security.logoutRequestSigned', true);
@@ -214,7 +220,6 @@ class Saml
}
}
}
$this->_settings = $settings;
}
}
@@ -502,4 +507,4 @@ class Saml
return $username;
}
}
}
+4 -5
View File
@@ -45,6 +45,7 @@
"league/flysystem-cached-adapter": "^1.0",
"neitanod/forceutf8": "^2.0",
"nesbot/carbon": "^2.32",
"nunomaduro/collision": "^3.2",
"onelogin/php-saml": "^3.4",
"paragonie/constant_time_encoding": "^2.3",
"patchwork/utf8": "^1.3",
@@ -108,9 +109,7 @@
"preferred-install": "dist",
"sort-packages": true,
"optimize-autoloader": true,
"process-timeout": 3000,
"platform": {
"php": "7.2.5"
}
"discard-changes": true,
"process-timeout": 3000
}
}
}
Generated
+603 -537
View File
File diff suppressed because it is too large Load Diff
-3
View File
@@ -333,7 +333,6 @@ return [
Laravel\Passport\PassportServiceProvider::class,
Laravel\Tinker\TinkerServiceProvider::class,
Unicodeveloper\DumbPassword\DumbPasswordServiceProvider::class,
//Schuppo\PasswordStrength\PasswordStrengthServiceProvider::class,
Tightenco\Ziggy\ZiggyServiceProvider::class, // Laravel routes in vue
Eduardokum\LaravelMailAutoEmbed\ServiceProvider::class,
@@ -403,11 +402,9 @@ return [
'URL' => Illuminate\Support\Facades\URL::class,
'Validator' => Illuminate\Support\Facades\Validator::class,
'View' => Illuminate\Support\Facades\View::class,
//'Input' => Illuminate\Support\Facades\Input::class,
'Form' => Collective\Html\FormFacade::class,
'Html' => Collective\Html\HtmlFacade::class,
'Google2FA' => PragmaRX\Google2FALaravel\Facade::class,
// 'Debugbar' => Barryvdh\Debugbar\Facade::class, //autodiscover should handle this
'Image' => Intervention\Image\ImageServiceProvider::class,
'Carbon' => Carbon\Carbon::class,
+3
View File
@@ -100,6 +100,9 @@ return [
* The directory where the temporary files will be stored.
*/
'temporary_directory' => storage_path('app/backup-temp'),
//'encryption' => \ZipArchive::EM_AES_256,
'encryption' => null,
],
/*
+2 -2
View File
@@ -14,7 +14,6 @@ $config = [
| one of the channels defined in the "channels" configuration array.
|
*/
'default' => env('LOG_CHANNEL', 'stack'),
/*
@@ -59,6 +58,7 @@ $config = [
'level' => env('APP_LOG_LEVEL', 'debug'),
],
'slack' => [
'driver' => 'slack',
'url' => env('LOG_SLACK_WEBHOOK_URL'),
@@ -99,4 +99,4 @@ if ((env('APP_ENV')=='production') && env('ROLLBAR_TOKEN')) {
}
return $config;
return $config;
+6
View File
@@ -218,6 +218,12 @@ return array(
'note' => '',
'display' => true,
),
array(
'permission' => 'licenses.files',
'label' => 'View and Modify License Files',
'note' => '',
'display' => true,
),
),
+5 -5
View File
@@ -1,10 +1,10 @@
<?php
return array (
'app_version' => 'v5.1.3',
'full_app_version' => 'v5.1.3 - build 5862-gc3871c98d',
'build_version' => '5862',
'app_version' => 'v5.1.5',
'full_app_version' => 'v5.1.5 - build 6029-gb8c356443',
'build_version' => '6029',
'prerelease_version' => '',
'hash_version' => 'gc3871c98d',
'full_hash' => 'v5.1.3-12-gc3871c98d',
'hash_version' => 'gb8c356443',
'full_hash' => 'v5.1.5-125-gb8c356443',
'branch' => 'master',
);
@@ -0,0 +1,34 @@
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class AddUserSkinSetting extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
// Update the users table
Schema::table('users', function ($table) {
$table->string('skin')->nullable();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
// Update the users table
Schema::table('users', function ($table) {
$table->dropColumn('skin');
});
}
}
@@ -0,0 +1,34 @@
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class AddSettingAllowUserSkin extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
// Update the users table
Schema::table('settings', function ($table) {
$table->boolean('allow_user_skin')->default(0);
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
// Update the users table
Schema::table('settings', function ($table) {
$table->dropColumn('allow_user_skin');
});
}
}
@@ -0,0 +1,32 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class AddSamlKeyRollover extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('settings', function(Blueprint $table) {
$table->text('saml_sp_x509certNew')->nullable()->default(NULL);
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('settings', function(Blueprint $table) {
$table->dropColumn('saml_sp_x509certNew');
});
}
}
@@ -0,0 +1,36 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class AddsSeveralLdapFields extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('settings', function (Blueprint $table) {
$table->string('ldap_phone_field')->after('ldap_email')->nullable();
$table->string('ldap_jobtitle')->after('ldap_phone_field')->nullable();
$table->string('ldap_country')->after('ldap_jobtitle')->nullable();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('settings', function (Blueprint $table) {
$table->dropColumn('ldap_phone_field');
$table->dropColumn('ldap_jobtitle');
$table->dropColumn('ldap_country');
});
}
}
@@ -0,0 +1,33 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class AddLdapDept extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('settings', function (Blueprint $table) {
$table->string('ldap_dept')->after('ldap_active_flag')->nullable();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('settings', function (Blueprint $table) {
$table->dropColumn('ldap_dept');
});
}
}
@@ -0,0 +1,54 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class AddIdsToTables extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('migrations', function (Blueprint $table) {
// Add the id column to the migrations table if it doesn't yet have one
if (!Schema::hasColumn('migrations', 'id')) {
$table->increments('id');
}
});
Schema::table('password_resets', function (Blueprint $table) {
// Add the id column to the password_resets table if it doesn't yet have one
if (!Schema::hasColumn('password_resets', 'id')) {
$table->increments('id');
}
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('migrations', function (Blueprint $table) {
if (Schema::hasColumn('migrations', 'id')) {
$table->dropColumn('id');
}
});
Schema::table('password_resets', function (Blueprint $table) {
if (Schema::hasColumn('password_resets', 'id')) {
$table->dropColumn('id');
}
});
}
}
+6
View File
@@ -39,5 +39,11 @@ class SettingsSeeder extends Seeder
$user->locale = 'en';
$user->save();
}
// Copy the logos from the img/demo directory
Storage::disk('public')->put(public_path('uploads/snipe-logo.png'), file_get_contents(public_path('img/demo/snipe-logo.png')));
Storage::disk('public')->put(public_path('uploads/snipe-logo-lg.png'), file_get_contents(public_path('img/demo/snipe-logo-lg.png')));
}
}
+48
View File
@@ -0,0 +1,48 @@
version: '3'
services:
snipeit:
build:
context: .
dockerfile: Dockerfile.alpine
container_name: snipeit
ports:
- 8000:80
volumes:
- ./logs:/var/www/html/storage/logs
depends_on:
- mariadb
- redis
env_file:
- .env.docker
networks:
- snipeit-backend
mariadb:
image: mariadb:latest
volumes:
- db:/var/lib/mysql
env_file:
- .env.docker
networks:
- snipeit-backend
redis:
image: redis:latest
networks:
- snipeit-backend
mailhog:
image: mailhog/mailhog:latest
ports:
# - 1025:1025
- 8025:8025
networks:
- snipeit-backend
volumes:
db: {}
networks:
snipeit-backend: {}
+119
View File
@@ -0,0 +1,119 @@
#!/bin/sh
set -eo pipefail;
# Cribbed from nextcloud docker official repo
# https://github.com/nextcloud/docker/blob/master/docker-entrypoint.sh
# usage: file_env VAR [DEFAULT]
# ie: file_env 'XYZ_DB_PASSWORD' 'example'
# (will allow for "$XYZ_DB_PASSWORD_FILE" to fill in the value of
# "$XYZ_DB_PASSWORD" from a file, especially for Docker's secrets feature)
file_env() {
local var="$1"
local fileVar="${var}_FILE"
local def="${2:-}"
local varValue=$(env | grep -E "^${var}=" | sed -E -e "s/^${var}=//")
local fileVarValue=$(env | grep -E "^${fileVar}=" | sed -E -e "s/^${fileVar}=//")
if [ -n "${varValue}" ] && [ -n "${fileVarValue}" ]; then
echo >&2 "error: both $var and $fileVar are set (but are exclusive)"
exit 1
fi
if [ -n "${varValue}" ]; then
export "$var"="${varValue}"
elif [ -n "${fileVarValue}" ]; then
export "$var"="$(cat "${fileVarValue}")"
elif [ -n "${def}" ]; then
export "$var"="$def"
fi
unset "$fileVar"
}
# Add docker secrets support for the variables below:
file_env APP_KEY
file_env DB_HOST
file_env DB_PORT
file_env DB_DATABASE
file_env DB_USERNAME
file_env DB_PASSWORD
file_env REDIS_HOST
file_env REDIS_PASSWORD
file_env REDIS_PORT
file_env MAIL_HOST
file_env MAIL_PORT
file_env MAIL_USERNAME
file_env MAIL_PASSWORD
echo [INFO docker entrypoint] Start script execution
# Generate new app key if none is provided
if [ -z "$APP_KEY" -a -z "$APP_KEY_FILE" ]
then
echo "Please re-run this container with an environment variable \$APP_KEY"
echo "An example APP_KEY you could use is: "
php artisan key:generate --show
exit
fi
# Directory configuration
rm -rf \
"/var/www/html/storage/private_uploads" \
"/var/www/html/public/uploads" \
"/var/www/html/storage/app/backups"
# Create data directories
for dir in \
'data/private_uploads' \
'data/uploads/accessories' \
'data/uploads/avatars' \
'data/uploads/barcodes' \
'data/uploads/categories' \
'data/uploads/companies' \
'data/uploads/components' \
'data/uploads/consumables' \
'data/uploads/departments' \
'data/uploads/locations' \
'data/uploads/manufacturers' \
'data/uploads/models' \
'data/uploads/suppliers' \
'dumps' \
'keys'
do
[ ! -d "/var/lib/snipeit/$dir" ] && mkdir -p "/var/lib/snipeit/$dir"
done
# Sync /var/lib/snipeit (docker volume) with /var/www/html directory
ln -fs \
"/var/lib/snipeit/data/private_uploads" "/var/www/html/storage/private_uploads"
ln -fs \
"/var/lib/snipeit/data/uploads" "/var/www/html/public/uploads"
ln -fs \
"/var/lib/snipeit/dumps" "/var/www/html/storage/app/backups"
ln -fs \
"/var/lib/snipeit/keys/oauth-public.key" "/var/www/html/storage/oauth-public.key"
ln -fs \
"/var/lib/snipeit/keys/oauth-private.key" "/var/www/html/storage/oauth-private.key"
# If the Oauth DB files are not present copy the vendor files over to the db migrations
if [ ! -f "/var/www/html/database/migrations/*create_oauth*" ]
then
cp -a /var/www/html/vendor/laravel/passport/database/migrations/* /var/www/html/database/migrations/
fi
# Create laravel log file
touch /var/www/html/storage/logs/laravel.log
# Add correct permissions for files and directories
chown www-data:www-data /var/www/html/storage/logs/laravel.log
chown -R www-data:www-data \
/var/lib/snipeit/data \
/var/lib/snipeit/dumps \
/var/lib/snipeit/keys
# Migrate/create database
php artisan migrate --force
# Clear cache files
php artisan config:clear
php artisan config:cache
echo [INFO docker entrypoint] End script execution
exec "$@"
+54
View File
@@ -0,0 +1,54 @@
# --------------------------------------------
# REQUIRED: BASIC APP SETTINGS
# --------------------------------------------
#APP_ENV=develop
#APP_DEBUG=false
#APP_KEY=Change_this_key_or_snipe_will_get_ya
#APP_URL=http://127.0.0.1:32782
#APP_TIMEZONE=US/Pacific
#APP_LOCALE=en
# --------------------------------------------
# REQUIRED: DATABASE SETTINGS
# --------------------------------------------
DB_CONNECTION=mysql
DB_PREFIX=null
DB_DUMP_PATH='/usr/bin'
# --------------------------------------------
# REQUIRED: OUTGOING MAIL SERVER SETTINGS
# --------------------------------------------
MAIL_DRIVER=smtp
MAIL_ENCRYPTION=${MAIL_ENV_ENCRYPTION}
MAIL_FROM_ADDR=${MAIL_ENV_FROM_ADDR}
MAIL_FROM_NAME=${MAIL_ENV_FROM_NAME}
MAIL_REPLYTO_ADDR=${MAIL_ENV_FROM_ADDR}
MAIL_REPLYTO_NAME=${MAIL_ENV_FROM_NAME}
# --------------------------------------------
# REQUIRED: IMAGE LIBRARY
# This should be gd or imagick
# --------------------------------------------
IMAGE_LIB=gd
# --------------------------------------------
# OPTIONAL: SESSION SETTINGS
# --------------------------------------------
SESSION_LIFETIME=12000
EXPIRE_ON_CLOSE=false
ENCRYPT=false
COOKIE_NAME=snipeit_session
COOKIE_DOMAIN=null
SECURE_COOKIES=false
# --------------------------------------------
# OPTIONAL: CACHE SETTINGS
# --------------------------------------------
CACHE_DRIVER=file
SESSION_DRIVER=file
QUEUE_DRIVER=sync
+6119 -5348
View File
File diff suppressed because it is too large Load Diff
+10 -8
View File
@@ -2,12 +2,12 @@
"private": true,
"scripts": {
"dev": "npm run development",
"development": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js",
"watch": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --watch --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js",
"development": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --progress --config=node_modules/laravel-mix/setup/webpack.config.js",
"watch": "npm run development -- --watch",
"watch-poll": "npm run watch -- --watch-poll",
"hot": "cross-env NODE_ENV=development node_modules/webpack-dev-server/bin/webpack-dev-server.js --inline --hot --config=node_modules/laravel-mix/setup/webpack.config.js",
"hot": "cross-env NODE_ENV=development node_modules/webpack-dev-server/bin/webpack-dev-server.js --inline --hot --disable-host-check --config=node_modules/laravel-mix/setup/webpack.config.js",
"prod": "npm run production",
"production": "cross-env NODE_ENV=production node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js"
"production": "cross-env NODE_ENV=production node_modules/webpack/bin/webpack.js --no-progress --config=node_modules/laravel-mix/setup/webpack.config.js"
},
"engines": {
"node": ">=0.12"
@@ -15,12 +15,12 @@
"devDependencies": {
"axios": "^0.20.0",
"babel-preset-latest": "^6.24.1",
"cross-env": "^5.0.5",
"cross-env": "^7.0",
"jquery": "^3.5.1",
"laravel-mix": "2.1",
"laravel-mix": "^5.0.1",
"lodash": "^4.17.20",
"vue": "2.4.4",
"vue-loader": "^13.6.1",
"vue-loader": "^15.9.6",
"vue-template-compiler": "2.4.4"
},
"dependencies": {
@@ -34,6 +34,7 @@
"bootstrap-less": "^3.3.8",
"bootstrap-table": "^1.18.0",
"chart.js": "^2.9.4",
"css-loader": "^3.6.0",
"ekko-lightbox": "^5.1.1",
"font-awesome": "^4.7.0",
"icheck": "^1.0.2",
@@ -43,12 +44,13 @@
"jquery-ui": "^1.12.1",
"jquery-ui-bundle": "^1.12.1",
"jquery.iframe-transport": "^1.0.0",
"less": "github:less/less.js#efa6eb5306f28a7ef7e235d79ce854b780345591",
"less": "^3.13.1",
"less-loader": "^4.1.0",
"list.js": "^1.5.0",
"papaparse": "^4.3.3",
"phantomjs": "^2.1.7",
"select2": "4.0.13",
"sheetjs": "^2.0.0",
"tableexport.jquery.plugin": "^1.10.20",
"tether": "^1.4.0",
"vue-resource": "^1.3.3"
-1
View File
@@ -1 +0,0 @@
+1
View File
@@ -0,0 +1 @@
#signature-pad{padding-top:250px;margin:auto}.m-signature-pad{position:relative;font-size:10px;width:100%;height:300px;border:1px solid #e8e8e8;background-color:#fff;box-shadow:0 1px 4px rgba(0,0,0,.27),0 0 40px rgba(0,0,0,.08) inset;border-radius:4px}.m-signature-pad:after,.m-signature-pad:before{position:absolute;z-index:-1;content:"";width:40%;height:10px;left:20px;bottom:10px;background:0 0;-webkit-transform:skew(-3deg) rotate(-3deg);-moz-transform:skew(-3deg) rotate(-3deg);-ms-transform:skew(-3deg) rotate(-3deg);-o-transform:skew(-3deg) rotate(-3deg);transform:skew(-3deg) rotate(-3deg);box-shadow:0 8px 12px rgba(0,0,0,.4)}.m-signature-pad:after{left:auto;right:20px;-webkit-transform:skew(3deg) rotate(3deg);-moz-transform:skew(3deg) rotate(3deg);-ms-transform:skew(3deg) rotate(3deg);-o-transform:skew(3deg) rotate(3deg);transform:skew(3deg) rotate(3deg)}.m-signature-pad--body{position:absolute;top:20px;bottom:60px;border:1px solid #f4f4f4;background-color:#fff}.m-signature-pad--body canvas{position:absolute;left:0;top:0;width:100%;height:100%;border-radius:4px;box-shadow:0 0 5px rgba(0,0,0,.02) inset}.m-signature-pad--footer{position:absolute;left:20px;right:20px;bottom:20px;height:40px}.m-signature-pad--footer .description{color:#c3c3c3;text-align:center;font-size:1.2em;margin-top:1.8em}.m-signature-pad--footer .button{position:absolute;bottom:0}.m-signature-pad--footer .button.clear{left:0}.m-signature-pad--footer .button.save{right:0}@media screen and (max-width:1024px){.m-signature-pad{top:0;left:0;right:0;bottom:0;width:auto;height:auto;min-width:250px;min-height:140px;margin:5%}}@media screen and (min-device-width:768px) and (max-device-width:1024px){.m-signature-pad{margin:10%}}@media screen and (max-height:320px){.m-signature-pad--body{left:0;right:0;top:0;bottom:32px}.m-signature-pad--footer{left:20px;right:20px;bottom:4px;height:28px}.m-signature-pad--footer .description{font-size:1em;margin-top:1em}}
+1
View File
@@ -0,0 +1 @@
.skin-black .main-header .navbar{background-color:#111}.skin-black .main-header .navbar .nav>li>a{color:#fff}.skin-black .main-header .navbar .nav .open>a,.skin-black .main-header .navbar .nav .open>a:focus,.skin-black .main-header .navbar .nav .open>a:hover,.skin-black .main-header .navbar .nav>.active>a,.skin-black .main-header .navbar .nav>li>a:active,.skin-black .main-header .navbar .nav>li>a:focus,.skin-black .main-header .navbar .nav>li>a:hover,.skin-black .main-header .navbar .sidebar-toggle:hover{background:rgba(0,0,0,.1);color:#f6f6f6}.skin-black .main-header .navbar .sidebar-toggle{color:#fff}.skin-black .main-header .navbar .sidebar-toggle:hover{background-color:#040404}@media (max-width:767px){.skin-black .main-header .navbar .dropdown-menu li.divider{background-color:hsla(0,0%,100%,.1)}.skin-black .main-header .navbar .dropdown-menu li a{color:#fff}.skin-black .main-header .navbar .dropdown-menu li a:hover{background:#040404}}.skin-black .main-header li.user-header{background-color:#111}.skin-black .content-header{background:0 0}.skin-black .left-side,.skin-black .main-sidebar,.skin-black .wrapper{background-color:#222d32}.skin-black .user-panel>.info,.skin-black .user-panel>.info>a{color:#fff}.skin-black .sidebar-menu>li.header{color:#4b646f;background:#1a2226}.skin-black .sidebar-menu>li>a{border-left:3px solid transparent}.skin-black .sidebar-menu>li.active>a,.skin-black .sidebar-menu>li:hover>a{color:#fff;background:#1e282c;border-left-color:#111}.skin-black .sidebar-menu>li>.treeview-menu{margin:0 1px;background:#2c3b41}.skin-black .sidebar a{color:#b8c7ce}.skin-black .sidebar a:hover{text-decoration:none}.skin-black .treeview-menu>li>a{color:#8aa4af}.skin-black .treeview-menu>li.active>a,.skin-black .treeview-menu>li>a:hover{color:#fff}.skin-black .sidebar-form{border-radius:3px;border:1px solid #374850;margin:10px}.skin-black .sidebar-form .btn,.skin-black .sidebar-form input[type=text]{-webkit-box-shadow:none;box-shadow:none;background-color:#374850;border:1px solid transparent;height:35px;-webkit-transition:all .3s ease-in-out;transition:all .3s ease-in-out}.skin-black .sidebar-form input[type=text]{color:#666;border-top-left-radius:2px;border-top-right-radius:0;border-bottom-right-radius:0;border-bottom-left-radius:2px}.skin-black .sidebar-form input[type=text]:focus,.skin-black .sidebar-form input[type=text]:focus+.input-group-btn .btn{background-color:#fff;color:#666}.skin-black .sidebar-form input[type=text]:focus+.input-group-btn .btn{border-left-color:#fff}.skin-black .sidebar-form .btn{color:#999;border-top-left-radius:0;border-top-right-radius:2px;border-bottom-right-radius:2px;border-bottom-left-radius:0}.skin-black.layout-top-nav .main-header>.logo .logo-variant{background-color:none}.btn,.btn:hover{text-decoration:none}.btn .btn-primary:link,.btn.btn-primary,.btn:hover .btn-primary:link,.btn:hover.btn-primary{background-color:#505156;border-color:#b5bbc8;color:#fff}.btn:hovera.btn-primary:hover,.btna.btn-primary:hover{background-color:#111;border-color:#1f1f21;color:#fff}.btn.btn-white:hover,.btn.btn-white:link,.btn.btn-white:visited,.btn:hover.btn-white:hover,.btn:hover.btn-white:link,.btn:hover.btn-white:visited{color:#fff}a{color:#111;text-decoration:underline}a:hover{color:#000}a:visited{color:#111}.text-primary{color:#000}.skin-black .main-header .navbar .nav>li>a{text-decoration:none}.select2-container--default .select2-selection--multiple .select2-selection__choice{background-color:#111}
+1
View File
@@ -0,0 +1 @@
.skin-blue .main-header .navbar{background-color:#3c8dbc}.skin-blue .main-header .navbar .nav>li>a{color:#fff}.skin-blue .main-header .navbar .nav .open>a,.skin-blue .main-header .navbar .nav .open>a:focus,.skin-blue .main-header .navbar .nav .open>a:hover,.skin-blue .main-header .navbar .nav>.active>a,.skin-blue .main-header .navbar .nav>li>a:active,.skin-blue .main-header .navbar .nav>li>a:focus,.skin-blue .main-header .navbar .nav>li>a:hover,.skin-blue .main-header .navbar .sidebar-toggle:hover{background:rgba(0,0,0,.1);color:#f6f6f6}.skin-blue .main-header .navbar .sidebar-toggle{color:#fff}.skin-blue .main-header .navbar .sidebar-toggle:hover{background-color:#367fa9}@media (max-width:767px){.skin-blue .main-header .navbar .dropdown-menu li.divider{background-color:hsla(0,0%,100%,.1)}.skin-blue .main-header .navbar .dropdown-menu li a{color:#fff}.skin-blue .main-header .navbar .dropdown-menu li a:hover{background:#367fa9}}.skin-blue .main-header li.user-header{background-color:#3c8dbc}.skin-blue .content-header{background:0 0}.skin-blue .left-side,.skin-blue .main-sidebar,.skin-blue .wrapper{background-color:#222d32}.skin-blue .user-panel>.info,.skin-blue .user-panel>.info>a{color:#fff}.skin-blue .sidebar-menu>li.header{color:#4b646f;background:#1a2226}.skin-blue .sidebar-menu>li>a{border-left:3px solid transparent}.skin-blue .sidebar-menu>li.active>a,.skin-blue .sidebar-menu>li:hover>a{color:#fff;background:#1e282c;border-left-color:#3c8dbc}.skin-blue .sidebar-menu>li>.treeview-menu{margin:0 1px;background:#2c3b41}.skin-blue .sidebar a{color:#b8c7ce}.skin-blue .sidebar a:hover{text-decoration:none}.skin-blue .treeview-menu>li>a{color:#8aa4af}.skin-blue .treeview-menu>li.active>a,.skin-blue .treeview-menu>li>a:hover{color:#fff}.skin-blue .sidebar-form{border-radius:3px;border:1px solid #374850;margin:10px}.skin-blue .sidebar-form .btn,.skin-blue .sidebar-form input[type=text]{-webkit-box-shadow:none;box-shadow:none;background-color:#374850;border:1px solid transparent;height:35px;-webkit-transition:all .3s ease-in-out;transition:all .3s ease-in-out}.skin-blue .sidebar-form input[type=text]{color:#666;border-top-left-radius:2px;border-top-right-radius:0;border-bottom-right-radius:0;border-bottom-left-radius:2px}.skin-blue .sidebar-form input[type=text]:focus,.skin-blue .sidebar-form input[type=text]:focus+.input-group-btn .btn{background-color:#fff;color:#666}.skin-blue .sidebar-form input[type=text]:focus+.input-group-btn .btn{border-left-color:#fff}.skin-blue .sidebar-form .btn{color:#999;border-top-left-radius:0;border-top-right-radius:2px;border-bottom-right-radius:2px;border-bottom-left-radius:0}.skin-blue.layout-top-nav .main-header>.logo .logo-variant{background-color:none}.btn .btn-primary:link,.btn.btn-primary,.btn:hover .btn-primary:link,.btn:hover.btn-primary,btn-sm .btn-primary:link,btn-sm.btn-primary{background-color:#307095;border-color:#23536f;color:#fff}.btn:hovera.btn-primary:hover,.btna.btn-primary:hover,btn-sma.btn-primary:hover{background-color:#23536f;border-color:#23536f;color:#fff}.btn.btn-white:link,.btn:hover.btn-white:link,btn-sm.btn-white:link{background-color:#307095;color:#fff}.btn.btn-white:hover,.btn.btn-white:visited,.btn:hover.btn-white:hover,.btn:hover.btn-white:visited,btn-sm.btn-white:hover,btn-sm.btn-white:visited{background-color:#173648;color:#fff}.btn-danger,.btn-danger:link,.btn-danger:visited,.btn-warning,.btn-warning:link,.btn-warning:visited,a.btn-danger:hover,a.btn-warning:hover{color:#fff}a{color:#3c8dbc}a:hover{color:#23536f}a:visited{color:#3c8dbc}.text-primary{color:#23536f}.fixed-table-container tbody .selected td{background-color:#fff8af}.select2-container--default .select2-selection--multiple .select2-selection__choice{background-color:#3c8dbc}
+1
View File
@@ -0,0 +1 @@
.skin-green .main-header .navbar{background-color:#00a65a}.skin-green .main-header .navbar .nav>li>a{color:#fff}.skin-green .main-header .navbar .nav .open>a,.skin-green .main-header .navbar .nav .open>a:focus,.skin-green .main-header .navbar .nav .open>a:hover,.skin-green .main-header .navbar .nav>.active>a,.skin-green .main-header .navbar .nav>li>a:active,.skin-green .main-header .navbar .nav>li>a:focus,.skin-green .main-header .navbar .nav>li>a:hover,.skin-green .main-header .navbar .sidebar-toggle:hover{background:rgba(0,0,0,.1);color:#f6f6f6}.skin-green .main-header .navbar .sidebar-toggle{color:#fff}.skin-green .main-header .navbar .sidebar-toggle:hover{background-color:#008d4c}@media (max-width:767px){.skin-green .main-header .navbar .dropdown-menu li.divider{background-color:hsla(0,0%,100%,.1)}.skin-green .main-header .navbar .dropdown-menu li a{color:#fff}.skin-green .main-header .navbar .dropdown-menu li a:hover{background:#008d4c}}.skin-green .main-header li.user-header{background-color:#00a65a}.skin-green .content-header{background:0 0}.skin-green .left-side,.skin-green .main-sidebar,.skin-green .wrapper{background-color:#222d32}.skin-green .user-panel>.info,.skin-green .user-panel>.info>a{color:#fff}.skin-green .sidebar-menu>li.header{color:#4b646f;background:#1a2226}.skin-green .sidebar-menu>li>a{border-left:3px solid transparent}.skin-green .sidebar-menu>li.active>a,.skin-green .sidebar-menu>li:hover>a{color:#fff;background:#1e282c;border-left-color:#00a65a}.skin-green .sidebar-menu>li>.treeview-menu{margin:0 1px;background:#2c3b41}.skin-green .sidebar a{color:#b8c7ce}.skin-green .sidebar a:hover{text-decoration:none}.skin-green .treeview-menu>li>a{color:#8aa4af}.skin-green .treeview-menu>li.active>a,.skin-green .treeview-menu>li>a:hover{color:#fff}.skin-green .sidebar-form{border-radius:3px;border:1px solid #374850;margin:10px}.skin-green .sidebar-form .btn,.skin-green .sidebar-form input[type=text]{-webkit-box-shadow:none;box-shadow:none;background-color:#374850;border:1px solid transparent;height:35px;-webkit-transition:all .3s ease-in-out;transition:all .3s ease-in-out}.skin-green .sidebar-form input[type=text]{color:#666;border-top-left-radius:2px;border-top-right-radius:0;border-bottom-right-radius:0;border-bottom-left-radius:2px}.skin-green .sidebar-form input[type=text]:focus,.skin-green .sidebar-form input[type=text]:focus+.input-group-btn .btn{background-color:#fff;color:#666}.skin-green .sidebar-form input[type=text]:focus+.input-group-btn .btn{border-left-color:#fff}.skin-green .sidebar-form .btn{color:#999;border-top-left-radius:0;border-top-right-radius:2px;border-bottom-right-radius:2px;border-bottom-left-radius:0}.skin-green.layout-top-nav .main-header>.logo .logo-variant{background-color:none}.btn .btn-primary:link,.btn.btn-primary,.btn:hover .btn-primary:link,.btn:hover.btn-primary{background-color:#00733e;border-color:#004023;color:#fff}.btn:hovera.btn-primary:hover,.btna.btn-primary:hover{background-color:#004023;border-color:#004023;color:#fff}.btn.btn-white:link,.btn:hover.btn-white:link{background-color:#00733e;color:#fff}.btn.btn-white:hover,.btn:hover.btn-white:hover{background-color:#000d07;color:#fff}a{color:#00a65a}a:hover{color:#004023}a:visited{color:#00a65a}.text-primary{color:#004023}.fixed-table-container tbody .selected td{background-color:#fff8af}.select2-container--default .select2-selection--multiple .select2-selection__choice{background-color:#00a65a}
+1
View File
@@ -0,0 +1 @@
.skin-orange .main-header .navbar{background-color:#ff8c00}.skin-orange .main-header .navbar .nav>li>a{color:#fff}.skin-orange .main-header .navbar .nav .open>a,.skin-orange .main-header .navbar .nav .open>a:focus,.skin-orange .main-header .navbar .nav .open>a:hover,.skin-orange .main-header .navbar .nav>.active>a,.skin-orange .main-header .navbar .nav>li>a:active,.skin-orange .main-header .navbar .nav>li>a:focus,.skin-orange .main-header .navbar .nav>li>a:hover,.skin-orange .main-header .navbar .sidebar-toggle:hover{background:rgba(0,0,0,.1);color:#f6f6f6}.skin-orange .main-header .navbar .sidebar-toggle{color:#fff}.skin-orange .main-header .navbar .sidebar-toggle:hover{background-color:#e67e00}@media (max-width:767px){.skin-orange .main-header .navbar .dropdown-menu li.divider{background-color:hsla(0,0%,100%,.1)}.skin-orange .main-header .navbar .dropdown-menu li a{color:#fff}.skin-orange .main-header .navbar .dropdown-menu li a:hover{background:#e67e00}}.skin-orange .main-header li.user-header{background-color:#ff8c00}.skin-orange .content-header{background:0 0}.skin-orange .left-side,.skin-orange .main-sidebar,.skin-orange .wrapper{background-color:#222d32}.skin-orange .user-panel>.info,.skin-orange .user-panel>.info>a{color:#fff}.skin-orange .sidebar-menu>li.header{color:#4b646f;background:#1a2226}.skin-orange .sidebar-menu>li>a{border-left:3px solid transparent}.skin-orange .sidebar-menu>li.active>a,.skin-orange .sidebar-menu>li:hover>a{color:#fff;background:#1e282c;border-left-color:#ff8c00}.skin-orange .sidebar-menu>li>.treeview-menu{margin:0 1px;background:#2c3b41}.skin-orange .sidebar a{color:#b8c7ce}.skin-orange .sidebar a:hover{text-decoration:none}.skin-orange .treeview-menu>li>a{color:#8aa4af}.skin-orange .treeview-menu>li.active>a,.skin-orange .treeview-menu>li>a:hover{color:#fff}.skin-orange .sidebar-form{border-radius:3px;border:1px solid #374850;margin:10px}.skin-orange .sidebar-form .btn,.skin-orange .sidebar-form input[type=text]{-webkit-box-shadow:none;box-shadow:none;background-color:#374850;border:1px solid transparent;height:35px;-webkit-transition:all .3s ease-in-out;transition:all .3s ease-in-out}.skin-orange .sidebar-form input[type=text]{color:#666;border-top-left-radius:2px;border-top-right-radius:0;border-bottom-right-radius:0;border-bottom-left-radius:2px}.skin-orange .sidebar-form input[type=text]:focus,.skin-orange .sidebar-form input[type=text]:focus+.input-group-btn .btn{background-color:#fff;color:#666}.skin-orange .sidebar-form input[type=text]:focus+.input-group-btn .btn{border-left-color:#fff}.skin-orange .sidebar-form .btn{color:#999;border-top-left-radius:0;border-top-right-radius:2px;border-bottom-right-radius:2px;border-bottom-left-radius:0}.skin-orange.layout-top-nav .main-header>.logo .logo-variant{background-color:none}.btn .btn-primary:link,.btn.btn-primary,.btn:hover .btn-primary:link,.btn:hover.btn-primary{background-color:#cc7000;border-color:#995400;color:#fff}.btn:hovera.btn-primary:hover,.btna.btn-primary:hover{background-color:#995400;border-color:#995400;color:#fff}.btn.btn-white:link,.btn:hover.btn-white:link{background-color:#cc7000;color:#fff}.btn.btn-white:hover,.btn:hover.btn-white:hover{background-color:#663800;color:#fff}a{color:#ff8c00}a:hover{color:#995400}a:visited{color:#ff8c00}.text-primary{color:#995400}.fixed-table-container tbody .selected td{background-color:#fff8af}.select2-container--default .select2-selection--multiple .select2-selection__choice{background-color:#ff8c00}
+1
View File
@@ -0,0 +1 @@
.skin-purple .main-header .navbar{background-color:#605ca8}.skin-purple .main-header .navbar .nav>li>a{color:#fff}.skin-purple .main-header .navbar .nav .open>a,.skin-purple .main-header .navbar .nav .open>a:focus,.skin-purple .main-header .navbar .nav .open>a:hover,.skin-purple .main-header .navbar .nav>.active>a,.skin-purple .main-header .navbar .nav>li>a:active,.skin-purple .main-header .navbar .nav>li>a:focus,.skin-purple .main-header .navbar .nav>li>a:hover,.skin-purple .main-header .navbar .sidebar-toggle:hover{background:rgba(0,0,0,.1);color:#f6f6f6}.skin-purple .main-header .navbar .sidebar-toggle{color:#fff}.skin-purple .main-header .navbar .sidebar-toggle:hover{background-color:#555299}@media (max-width:767px){.skin-purple .main-header .navbar .dropdown-menu li.divider{background-color:hsla(0,0%,100%,.1)}.skin-purple .main-header .navbar .dropdown-menu li a{color:#fff}.skin-purple .main-header .navbar .dropdown-menu li a:hover{background:#555299}}.skin-purple .main-header li.user-header{background-color:#605ca8}.skin-purple .content-header{background:0 0}.skin-purple .left-side,.skin-purple .main-sidebar,.skin-purple .wrapper{background-color:#222d32}.skin-purple .user-panel>.info,.skin-purple .user-panel>.info>a{color:#fff}.skin-purple .sidebar-menu>li.header{color:#4b646f;background:#1a2226}.skin-purple .sidebar-menu>li>a{border-left:3px solid transparent}.skin-purple .sidebar-menu>li.active>a,.skin-purple .sidebar-menu>li:hover>a{color:#fff;background:#1e282c;border-left-color:#605ca8}.skin-purple .sidebar-menu>li>.treeview-menu{margin:0 1px;background:#2c3b41}.skin-purple .sidebar a{color:#b8c7ce}.skin-purple .sidebar a:hover{text-decoration:none}.skin-purple .treeview-menu>li>a{color:#8aa4af}.skin-purple .treeview-menu>li.active>a,.skin-purple .treeview-menu>li>a:hover{color:#fff}.skin-purple .sidebar-form{border-radius:3px;border:1px solid #374850;margin:10px}.skin-purple .sidebar-form .btn,.skin-purple .sidebar-form input[type=text]{-webkit-box-shadow:none;box-shadow:none;background-color:#374850;border:1px solid transparent;height:35px;-webkit-transition:all .3s ease-in-out;transition:all .3s ease-in-out}.skin-purple .sidebar-form input[type=text]{color:#666;border-top-left-radius:2px;border-top-right-radius:0;border-bottom-right-radius:0;border-bottom-left-radius:2px}.skin-purple .sidebar-form input[type=text]:focus,.skin-purple .sidebar-form input[type=text]:focus+.input-group-btn .btn{background-color:#fff;color:#666}.skin-purple .sidebar-form input[type=text]:focus+.input-group-btn .btn{border-left-color:#fff}.skin-purple .sidebar-form .btn{color:#999;border-top-left-radius:0;border-top-right-radius:2px;border-bottom-right-radius:2px;border-bottom-left-radius:0}.skin-purple.layout-top-nav .main-header>.logo .logo-variant{background-color:none}.btn .btn-primary:link,.btn.btn-primary,.btn:hover .btn-primary:link,.btn:hover.btn-primary{background-color:#4c4988;border-color:#3a3767;color:#fff}.btn:hovera.btn-primary:hover,.btna.btn-primary:hover{background-color:#3a3767;border-color:#3a3767;color:#fff}.btn.btn-white:link,.btn:hover.btn-white:link{background-color:#4c4988;color:#fff}.btn.btn-white:hover,.btn:hover.btn-white:hover{background-color:#272546;color:#fff}a{color:#605ca8}a:hover{color:#3a3767}a:visited{color:#605ca8}.text-primary{color:#3a3767}.fixed-table-container tbody .selected td{background-color:#fff8af}.select2-container--default .select2-selection--multiple .select2-selection__choice{background-color:#605ca8}
+1
View File
@@ -0,0 +1 @@
.skin-red .main-header .navbar{background-color:#dd4b39}.skin-red .main-header .navbar .nav>li>a{color:#fff}.skin-red .main-header .navbar .nav .open>a,.skin-red .main-header .navbar .nav .open>a:focus,.skin-red .main-header .navbar .nav .open>a:hover,.skin-red .main-header .navbar .nav>.active>a,.skin-red .main-header .navbar .nav>li>a:active,.skin-red .main-header .navbar .nav>li>a:focus,.skin-red .main-header .navbar .nav>li>a:hover,.skin-red .main-header .navbar .sidebar-toggle:hover{background:rgba(0,0,0,.1);color:#f6f6f6}.skin-red .main-header .navbar .sidebar-toggle{color:#fff}.skin-red .main-header .navbar .sidebar-toggle:hover{background-color:#d73925}@media (max-width:767px){.skin-red .main-header .navbar .dropdown-menu li.divider{background-color:hsla(0,0%,100%,.1)}.skin-red .main-header .navbar .dropdown-menu li a{color:#fff}.skin-red .main-header .navbar .dropdown-menu li a:hover{background:#d73925}}.skin-red .main-header li.user-header{background-color:#dd4b39}.skin-red .content-header{background:0 0}.skin-red .left-side,.skin-red .main-sidebar,.skin-red .wrapper{background-color:#222d32}.skin-red .user-panel>.info,.skin-red .user-panel>.info>a{color:#fff}.skin-red .sidebar-menu>li.header{color:#4b646f;background:#1a2226}.skin-red .sidebar-menu>li>a{border-left:3px solid transparent}.skin-red .sidebar-menu>li.active>a,.skin-red .sidebar-menu>li:hover>a{color:#fff;background:#1e282c;border-left-color:#dd4b39}.skin-red .sidebar-menu>li>.treeview-menu{margin:0 1px;background:#2c3b41}.skin-red .sidebar a{color:#b8c7ce}.skin-red .sidebar a:hover{text-decoration:none}.skin-red .treeview-menu>li>a{color:#8aa4af}.skin-red .treeview-menu>li.active>a,.skin-red .treeview-menu>li>a:hover{color:#fff}.skin-red .sidebar-form{border-radius:3px;border:1px solid #374850;margin:10px}.skin-red .sidebar-form .btn,.skin-red .sidebar-form input[type=text]{-webkit-box-shadow:none;box-shadow:none;background-color:#374850;border:1px solid transparent;height:35px;-webkit-transition:all .3s ease-in-out;transition:all .3s ease-in-out}.skin-red .sidebar-form input[type=text]{color:#666;border-top-left-radius:2px;border-top-right-radius:0;border-bottom-right-radius:0;border-bottom-left-radius:2px}.skin-red .sidebar-form input[type=text]:focus,.skin-red .sidebar-form input[type=text]:focus+.input-group-btn .btn{background-color:#fff;color:#666}.skin-red .sidebar-form input[type=text]:focus+.input-group-btn .btn{border-left-color:#fff}.skin-red .sidebar-form .btn{color:#999;border-top-left-radius:0;border-top-right-radius:2px;border-bottom-right-radius:2px;border-bottom-left-radius:0}.skin-red.layout-top-nav .main-header>.logo .logo-variant{background-color:none}.btn .btn-primary:link,.btn.btn-primary,.btn:hover .btn-primary:link,.btn:hover.btn-primary{background-color:#c23321;border-color:#96271a;color:#fff}.btn:hovera.btn-primary:hover,.btna.btn-primary:hover{background-color:#96271a;border-color:#96271a;color:#fff}.btn.btn-white:link,.btn:hover.btn-white:link{background-color:#c23321;color:#fff}.btn.btn-white:hover,.btn:hover.btn-white:hover{background-color:#6b1c12;color:#fff}a{color:#dd4b39}a:hover{color:#96271a}a:visited{color:#dd4b39}.text-primary{color:#96271a}.fixed-table-container tbody .selected td{background-color:#fff8af}.select2-container--default .select2-selection--multiple .select2-selection__choice{background-color:#dd4b39}
+1
View File
@@ -0,0 +1 @@
.skin-yellow .main-header .navbar{background-color:#f39c12}.skin-yellow .main-header .navbar .nav>li>a{color:#fff}.skin-yellow .main-header .navbar .nav .open>a,.skin-yellow .main-header .navbar .nav .open>a:focus,.skin-yellow .main-header .navbar .nav .open>a:hover,.skin-yellow .main-header .navbar .nav>.active>a,.skin-yellow .main-header .navbar .nav>li>a:active,.skin-yellow .main-header .navbar .nav>li>a:focus,.skin-yellow .main-header .navbar .nav>li>a:hover,.skin-yellow .main-header .navbar .sidebar-toggle:hover{background:rgba(0,0,0,.1);color:#f6f6f6}.skin-yellow .main-header .navbar .sidebar-toggle{color:#fff}.skin-yellow .main-header .navbar .sidebar-toggle:hover{background-color:#e08e0b}@media (max-width:767px){.skin-yellow .main-header .navbar .dropdown-menu li.divider{background-color:hsla(0,0%,100%,.1)}.skin-yellow .main-header .navbar .dropdown-menu li a{color:#fff}.skin-yellow .main-header .navbar .dropdown-menu li a:hover{background:#e08e0b}}.skin-yellow .main-header li.user-header{background-color:#f39c12}.skin-yellow .content-header{background:0 0}.skin-yellow .left-side,.skin-yellow .main-sidebar,.skin-yellow .wrapper{background-color:#222d32}.skin-yellow .user-panel>.info,.skin-yellow .user-panel>.info>a{color:#fff}.skin-yellow .sidebar-menu>li.header{color:#4b646f;background:#1a2226}.skin-yellow .sidebar-menu>li>a{border-left:3px solid transparent}.skin-yellow .sidebar-menu>li.active>a,.skin-yellow .sidebar-menu>li:hover>a{color:#fff;background:#1e282c;border-left-color:#f39c12}.skin-yellow .sidebar-menu>li>.treeview-menu{margin:0 1px;background:#2c3b41}.skin-yellow .sidebar a{color:#b8c7ce}.skin-yellow .sidebar a:hover{text-decoration:none}.skin-yellow .treeview-menu>li>a{color:#8aa4af}.skin-yellow .treeview-menu>li.active>a,.skin-yellow .treeview-menu>li>a:hover{color:#fff}.skin-yellow .sidebar-form{border-radius:3px;border:1px solid #374850;margin:10px}.skin-yellow .sidebar-form .btn,.skin-yellow .sidebar-form input[type=text]{-webkit-box-shadow:none;box-shadow:none;background-color:#374850;border:1px solid transparent;height:35px;-webkit-transition:all .3s ease-in-out;transition:all .3s ease-in-out}.skin-yellow .sidebar-form input[type=text]{color:#666;border-top-left-radius:2px;border-top-right-radius:0;border-bottom-right-radius:0;border-bottom-left-radius:2px}.skin-yellow .sidebar-form input[type=text]:focus,.skin-yellow .sidebar-form input[type=text]:focus+.input-group-btn .btn{background-color:#fff;color:#666}.skin-yellow .sidebar-form input[type=text]:focus+.input-group-btn .btn{border-left-color:#fff}.skin-yellow .sidebar-form .btn{color:#999;border-top-left-radius:0;border-top-right-radius:2px;border-bottom-right-radius:2px;border-bottom-left-radius:0}.skin-yellow.layout-top-nav .main-header>.logo .logo-variant{background-color:none}.btn .btn-primary:link,.btn.btn-primary,.btn:hover .btn-primary:link,.btn:hover.btn-primary{background-color:#c87f0a;border-color:#976008;color:#fff}.btn:hovera.btn-primary:hover,.btna.btn-primary:hover{background-color:#976008;border-color:#976008;color:#fff}.btn.btn-white:link,.btn:hover.btn-white:link{background-color:#c87f0a;color:#fff}.btn.btn-white:hover,.btn:hover.btn-white:hover{background-color:#674105;color:#fff}a{color:#f39c12}a:hover{color:#976008}a:visited{color:#f39c12}.text-primary{color:#976008}.fixed-table-container tbody .selected td{background-color:#fff8af}.select2-container--default .select2-selection--multiple .select2-selection__choice{background-color:#f39c12}
File diff suppressed because one or more lines are too long
+59
View File
@@ -0,0 +1,59 @@
/*!
* Bootstrap v3.3.4 (http://getbootstrap.com)
* Copyright 2011-2015 Twitter, Inc.
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
*/
/*!
* Sizzle CSS Selector Engine v2.3.5
* https://sizzlejs.com/
*
* Copyright JS Foundation and other contributors
* Released under the MIT license
* https://js.foundation/
*
* Date: 2020-03-14
*/
/*!
* Vue.js v2.4.4
* (c) 2014-2017 Evan You
* Released under the MIT License.
*/
/*!
* jQuery JavaScript Library v3.5.1
* https://jquery.com/
*
* Includes Sizzle.js
* https://sizzlejs.com/
*
* Copyright JS Foundation and other contributors
* Released under the MIT license
* https://jquery.org/license
*
* Date: 2020-05-04T22:49Z
*/
/*!
* jQuery UI Widget 1.12.1
* http://jqueryui.com
*
* Copyright jQuery Foundation and other contributors
* Released under the MIT license.
* http://jquery.org/license
*/
/**
* @license
* Lodash <https://lodash.com/>
* Copyright OpenJS Foundation and other contributors <https://openjsf.org/>
* Released under MIT license <https://lodash.com/license>
* Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
* Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
*/
/**
* @license almond 0.3.3 Copyright jQuery Foundation and other contributors.
* Released under MIT license, http://github.com/requirejs/almond/LICENSE
*/
+14 -14
View File
File diff suppressed because one or more lines are too long
+34 -19
View File
File diff suppressed because one or more lines are too long
+19 -12
View File
@@ -1,5 +1,5 @@
{
"/js/build/app.js": "/js/build/app.js?id=dbeda4a18809e6247c2a",
"/js/build/app.js": "/js/build/app.js?id=b23ec8d1be42f9d3d810",
"/css/build/AdminLTE.css": "/css/build/AdminLTE.css?id=59413334823616b81341",
"/css/build/app.css": "/css/build/app.css?id=032fd8c3fce99c7fd862",
"/css/build/overrides.css": "/css/build/overrides.css?id=0b4aefd7ef0c117ef23a",
@@ -21,18 +21,25 @@
"/css/dist/all.css": "/css/dist/all.css?id=199fdf677ce0dce6cef8",
"/css/blue.png": "/css/blue.png?id=4c85d6a97173123bd14a",
"/css/blue@2x.png": "/css/blue@2x.png?id=62c67c6a822439e8a4ac",
"/css/dist/skins/skin-green-dark.min.css": "/css/dist/skins/skin-green-dark.min.css?id=0d9935d834b39386a82e",
"/css/dist/skins/skin-black-dark.min.css": "/css/dist/skins/skin-black-dark.min.css?id=97ec6f217441ac2f79ed",
"/css/dist/skins/skin-blue-dark.min.css": "/css/dist/skins/skin-blue-dark.min.css?id=8f7aed152883df9c6f5e",
"/css/dist/skins/skin-yellow-dark.min.css": "/css/dist/skins/skin-yellow-dark.min.css?id=23a14ac3cfe978b19c89",
"/css/dist/skins/skin-red-dark.min.css": "/css/dist/skins/skin-red-dark.min.css?id=bb408a66967c2c81f420",
"/css/dist/skins/skin-purple-dark.min.css": "/css/dist/skins/skin-purple-dark.min.css?id=39058e01caf0aeb39624",
"/css/dist/skins/skin-orange-dark.min.css": "/css/dist/skins/skin-orange-dark.min.css?id=b3d2ebfcb2541fa8e9ec",
"/css/dist/skins/skin-contrast.min.css": "/css/dist/skins/skin-contrast.min.css?id=d7996d850e8bcdc4e167",
"/css/dist/signature-pad.css": "/css/dist/signature-pad.css?id=6a89d3cd901305e66ced",
"/css/build/signature-pad.min.css": "/css/build/signature-pad.min.css?id=d41d8cd98f00b204e980",
"/css/dist/signature-pad.min.css": "/css/dist/signature-pad.min.css?id=6a89d3cd901305e66ced",
"/css/dist/bootstrap-table.css": "/css/dist/bootstrap-table.css?id=1e77fde04b3f42432581",
"/js/build/vendor.js": "/js/build/vendor.js?id=b93877b4a88a76e1b18b",
"/js/dist/bootstrap-table.js": "/js/dist/bootstrap-table.js?id=58d95c93430f2ae33392",
"/js/dist/all.js": "/js/dist/all.js?id=0efed60df4636f215a73"
"/js/dist/bootstrap-table.js": "/js/dist/bootstrap-table.js?id=fd6e727609678bf04984",
"/js/dist/all.js": "/js/dist/all.js?id=dde965016a515da2f8d2",
"/css/dist/skins/skin-green.min.css": "/css/dist/skins/skin-green.min.css?id=eee1d10b6d7db576428e",
"/css/dist/skins/skin-green-dark.min.css": "/css/dist/skins/skin-green-dark.min.css?id=0d9935d834b39386a82e",
"/css/dist/skins/skin-black.min.css": "/css/dist/skins/skin-black.min.css?id=39250963ef83dac17f77",
"/css/dist/skins/skin-black-dark.min.css": "/css/dist/skins/skin-black-dark.min.css?id=97ec6f217441ac2f79ed",
"/css/dist/skins/skin-blue.min.css": "/css/dist/skins/skin-blue.min.css?id=2a741dd5409582c0af89",
"/css/dist/skins/skin-blue-dark.min.css": "/css/dist/skins/skin-blue-dark.min.css?id=8f7aed152883df9c6f5e",
"/css/dist/skins/skin-yellow.min.css": "/css/dist/skins/skin-yellow.min.css?id=67a30cff63473dade0e3",
"/css/dist/skins/skin-yellow-dark.min.css": "/css/dist/skins/skin-yellow-dark.min.css?id=23a14ac3cfe978b19c89",
"/css/dist/skins/skin-red.min.css": "/css/dist/skins/skin-red.min.css?id=817384969ed226028416",
"/css/dist/skins/skin-red-dark.min.css": "/css/dist/skins/skin-red-dark.min.css?id=bb408a66967c2c81f420",
"/css/dist/skins/skin-purple.min.css": "/css/dist/skins/skin-purple.min.css?id=b8be296ada5cbc4563fa",
"/css/dist/skins/skin-purple-dark.min.css": "/css/dist/skins/skin-purple-dark.min.css?id=39058e01caf0aeb39624",
"/css/dist/skins/skin-orange.min.css": "/css/dist/skins/skin-orange.min.css?id=39eb843599c275696aed",
"/css/dist/skins/skin-orange-dark.min.css": "/css/dist/skins/skin-orange-dark.min.css?id=b3d2ebfcb2541fa8e9ec",
"/css/dist/skins/skin-contrast.min.css": "/css/dist/skins/skin-contrast.min.css?id=d7996d850e8bcdc4e167"
}
@@ -1,6 +1,7 @@
<template>
<div v-show="processDetail" class="col-md-12">
<tr v-show="processDetail">
<td colspan="5">
<div class="col-md-12">
<div class="row">
<div class="dynamic-form-row">
@@ -20,7 +21,7 @@
<label for="import-update">Update Existing Values?:</label>
</div>
<div class="col-md-7 col-xs-12">
<input type="checkbox" class="minimal" name="import-update" v-model="options.update">
<input type="checkbox" class="iCheck minimal" name="import-update" v-model="options.update">
</div>
</div><!-- /dynamic-form-row -->
@@ -94,6 +95,8 @@
</div><!-- /div v-show -->
</td>
</tr>
</template>
<script>
@@ -11,6 +11,8 @@ return array(
'country' => 'land',
'create' => 'Skep Ligging',
'update' => 'Opdateer Plek',
'print_assigned' => 'Print Assigned',
'print_all_assigned' => 'Print All Assigned',
'name' => 'Pleknaam',
'address' => 'adres',
'zip' => 'Poskode',
@@ -14,6 +14,8 @@ return array(
'alerts_enabled' => 'Alerts aangeskakel',
'alert_interval' => 'Uitgaande Alert Drempel (in dae)',
'alert_inv_threshold' => 'Voorraadwaarskuwingsdrempel',
'allow_user_skin' => 'Allow user skin',
'allow_user_skin_help_text' => 'Checking this box will allow a user to override the UI skin with a different one.' ,
'asset_ids' => 'Bate ID\'s',
'audit_interval' => 'Ouditinterval',
'audit_interval_help' => 'As u gereeld u bates fisies moet kontroleer, vul die interval in maande in.',
@@ -72,6 +74,10 @@ return array(
'ldap_tls' => 'Gebruik TLS',
'ldap_tls_help' => 'Dit moet slegs nagegaan word as u STARTTLS op u LDAP-bediener uitvoer.',
'ldap_uname' => 'LDAP Bind Gebruikersnaam',
'ldap_dept' => 'LDAP Department',
'ldap_phone' => 'LDAP Telephone Number',
'ldap_jobtitle' => 'LDAP Job Title',
'ldap_country' => 'LDAP Country',
'ldap_pword' => 'LDAP-koppel wagwoord',
'ldap_basedn' => 'Base Bind DN',
'ldap_filter' => 'LDAP Filter',
@@ -125,6 +131,7 @@ return array(
'saml_sp_acs_url' => 'Assertion Consumer Service (ACS) URL',
'saml_sp_sls_url' => 'Single Logout Service (SLS) URL',
'saml_sp_x509cert' => 'Public Certificate',
'saml_sp_metadata_url' => 'Metadata URL',
'saml_idp_metadata' => 'SAML IdP Metadata',
'saml_idp_metadata_help' => 'You can specify the IdP metadata using a URL or XML file.',
'saml_attr_mapping_username' => 'Attribute Mapping - Username',
+2
View File
@@ -9,5 +9,7 @@ return [
'login_prompt' => 'Asseblief Login',
'forgot_password' => 'ek het my wagwoord vergeet',
'remember_me' => 'Onthou my',
'username_help_top' => 'Enter your <strong>username</strong> to be emailed a password reset link.',
'username_help_bottom' => 'Your username and email address <em>may</em> be the same, but may not be, depending on your configuration. If you cannot remember your username, contact your administrator. <br><br><strong>Usernames without an associated email address will not be emailed a password reset link.</strong> ',
];
+4 -2
View File
@@ -112,7 +112,7 @@
'image' => 'Image',
'image_delete' => 'Vee prent uit',
'image_upload' => 'Laai prent op',
'image_filetypes_help' => 'Accepted filetypes are jpg, png, gif, and svg. Max upload size allowed is :size.',
'image_filetypes_help' => 'Accepted filetypes are jpg, webp, png, gif, and svg. Max upload size allowed is :size.',
'import' => 'invoer',
'importing' => 'Importing',
'importing_help' => 'You can import assets, accessories, licenses, components, consumables, and users via CSV file. <br><br>The CSV should be comma-delimited and formatted with headers that match the ones in the <a href="https://snipe-it.readme.io/docs/importing" target="_new">sample CSVs in the documentation</a>.',
@@ -243,5 +243,7 @@
'i_accept' => 'I accept',
'i_decline' => 'I decline',
'sign_tos' => 'Sign below to indicate that you agree to the terms of service:',
'clear_signature' => 'Clear Signature'
'clear_signature' => 'Clear Signature',
'show_help' => 'Show help',
'hide_help' => 'Hide help',
];
@@ -11,6 +11,8 @@ return array(
'country' => 'الدولة',
'create' => 'إنشاء موقع',
'update' => 'تحديث الموقع',
'print_assigned' => 'Print Assigned',
'print_all_assigned' => 'Print All Assigned',
'name' => 'إسم الموقع',
'address' => 'العنوان',
'zip' => 'الرمز البريدي',
@@ -14,6 +14,8 @@ return array(
'alerts_enabled' => 'التنبيهان ممكنه',
'alert_interval' => 'انتهاء فترة التنبيهات (بالأيام)',
'alert_inv_threshold' => 'عتبة تنبيه المخزون',
'allow_user_skin' => 'Allow user skin',
'allow_user_skin_help_text' => 'Checking this box will allow a user to override the UI skin with a different one.' ,
'asset_ids' => 'ارقام تعريف الاصول',
'audit_interval' => 'مدة التدقيق',
'audit_interval_help' => 'إذا كان مطلوبا منك مراجعة أصولك الفعلية بشكل دوري، قم بإدخال المدة بالأشهر.',
@@ -72,6 +74,10 @@ return array(
'ldap_tls' => 'استخدام تلس',
'ldap_tls_help' => 'يجب التحقق من ذلك فقط في حالة تشغيل ستارتلز على خادم لداب.',
'ldap_uname' => 'لداب ربط اسم المستخدم',
'ldap_dept' => 'LDAP Department',
'ldap_phone' => 'LDAP Telephone Number',
'ldap_jobtitle' => 'LDAP Job Title',
'ldap_country' => 'LDAP Country',
'ldap_pword' => 'لداب ربط كلمة المرور',
'ldap_basedn' => 'قاعدة ربط دن',
'ldap_filter' => 'فلتر لداب',
@@ -125,6 +131,7 @@ return array(
'saml_sp_acs_url' => 'رابط خدمة مستهلك الضمان (ACS)',
'saml_sp_sls_url' => 'رابط خدمة تسجيل الخروج الفردي (SLS)',
'saml_sp_x509cert' => 'شهادة عامة',
'saml_sp_metadata_url' => 'Metadata URL',
'saml_idp_metadata' => 'بيانات تعريف هوية SAML',
'saml_idp_metadata_help' => 'يمكنك تحديد بيانات التعريف الشخصية الشخصية باستخدام عنوان URL أو ملف XML.',
'saml_attr_mapping_username' => 'تعيين السمة - اسم المستخدم',
+2
View File
@@ -9,5 +9,7 @@ return [
'login_prompt' => 'الرجاء تسجيل الدخول',
'forgot_password' => 'نسيت كلمة المرور',
'remember_me' => 'تذكرني',
'username_help_top' => 'Enter your <strong>username</strong> to be emailed a password reset link.',
'username_help_bottom' => 'Your username and email address <em>may</em> be the same, but may not be, depending on your configuration. If you cannot remember your username, contact your administrator. <br><br><strong>Usernames without an associated email address will not be emailed a password reset link.</strong> ',
];
+4 -2
View File
@@ -112,7 +112,7 @@
'image' => 'صورة',
'image_delete' => 'حذف الصورة',
'image_upload' => 'رفع صورة',
'image_filetypes_help' => 'أنواع الملفات المقبولة هي jpg و png و gif و svg. الحد الأقصى لحجم التحميل المسموح به هو: الحجم.',
'image_filetypes_help' => 'Accepted filetypes are jpg, webp, png, gif, and svg. Max upload size allowed is :size.',
'import' => 'استيراد',
'importing' => 'الاستيراد',
'importing_help' => 'يمكنك استيراد الأصول، الملحقات، التراخيص، المكونات، المواد الاستهلاكية، والمستخدمين عبر ملف CSV. <br><br>يجب أن تكون CSV محددة بفواصل وأن يتم تنسيقها مع رؤوس تطابق تلك الموجودة في <a href="https://snipe-it.readme.io/docs/importing" target="_new">عينة CSVs في الوثائق</a>.',
@@ -243,5 +243,7 @@
'i_accept' => 'قبول',
'i_decline' => 'أنا أرفض',
'sign_tos' => 'قم بتسجيل الدخول أدناه للإشارة إلى أنك توافق على شروط الخدمة:',
'clear_signature' => 'مسح التوقيع'
'clear_signature' => 'مسح التوقيع',
'show_help' => 'Show help',
'hide_help' => 'Hide help',
];
@@ -2,7 +2,7 @@
return array(
'does_not_exist' => 'The accessory [:id] does not exist.',
'does_not_exist' => 'Аксесоарът [:id] не съществува.',
'assoc_users' => 'От този аксесоар са предадени :count броя на потребителите. Моля впишете обратно нови или върнати и опитайте отново.',
'create' => array(
@@ -8,7 +8,7 @@
'repair' => 'Ремонт',
'maintenance' => 'Поддръжка',
'upgrade' => 'Upgrade',
'calibration' => 'Calibration',
'software_support' => 'Software Support',
'hardware_support' => 'Hardware Support',
'calibration' => 'Калибриране',
'software_support' => 'Софтуерна Поддръжка',
'hardware_support' => 'Хардуерна Поддръжка',
];
+1 -1
View File
@@ -20,6 +20,6 @@ return array(
'title' => 'Актив ',
'image' => 'Изображение на устройството',
'days_without_acceptance' => 'Дни без да е предаден',
'monthly_depreciation' => 'Monthly Depreciation'
'monthly_depreciation' => 'Месечна Амортизация'
);

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