Merge branch 'develop' of https://github.com/snipe/snipe-it into develop

This commit is contained in:
Minaev Dmitriy 2018-09-14 19:36:01 +03:00
commit 2604d3c1fd
203 changed files with 4151 additions and 8623 deletions

View file

@ -1650,6 +1650,60 @@
"contributions": [
"code"
]
},
{
"login": "jwhulette",
"name": "Wes Hulette",
"avatar_url": "https://avatars1.githubusercontent.com/u/4930051?v=4",
"profile": "http://macfoo.wordpress.com/",
"contributions": [
"code"
]
},
{
"login": "patrict",
"name": "patrict",
"avatar_url": "https://avatars0.githubusercontent.com/u/8134591?v=4",
"profile": "https://github.com/patrict",
"contributions": [
"code"
]
},
{
"login": "VELIKII-DIVAN",
"name": "Dmitriy Minaev",
"avatar_url": "https://avatars3.githubusercontent.com/u/2611616?v=4",
"profile": "https://github.com/VELIKII-DIVAN",
"contributions": [
"code"
]
},
{
"login": "liquidhorse",
"name": "liquidhorse",
"avatar_url": "https://avatars0.githubusercontent.com/u/5132245?v=4",
"profile": "https://github.com/liquidhorse",
"contributions": [
"code"
]
},
{
"login": "Seldaek",
"name": "Jordi Boggiano",
"avatar_url": "https://avatars1.githubusercontent.com/u/183678?v=4",
"profile": "https://seld.be/",
"contributions": [
"code"
]
},
{
"login": "inietov",
"name": "Ivan Nieto",
"avatar_url": "https://avatars0.githubusercontent.com/u/653557?v=4",
"profile": "https://github.com/inietov",
"contributions": [
"code"
]
}
]
}

View file

@ -43,6 +43,8 @@ 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=true
MAIL_AUTO_EMBED_METHOD=base64
# --------------------------------------------
# REQUIRED: IMAGE LIBRARY

2
.gitignore vendored
View file

@ -50,3 +50,5 @@ tests/_support/_generated/*
/storage/oauth-public.key
*.cache
.vagrant

View file

@ -1,5 +1,5 @@
[![Build Status](https://travis-ci.org/snipe/snipe-it.svg?branch=master)](https://travis-ci.org/snipe/snipe-it) [![Crowdin](https://d322cqt584bo4o.cloudfront.net/snipe-it/localized.svg)](https://crowdin.com/project/snipe-it) [![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/snipe/snipe-it?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Docker Pulls](https://img.shields.io/docker/pulls/snipe/snipe-it.svg)](https://hub.docker.com/r/snipe/snipe-it/) [![Twitter Follow](https://img.shields.io/twitter/follow/snipeitapp.svg?style=social)](https://twitter.com/snipeitapp) [![Codacy Badge](https://api.codacy.com/project/badge/Grade/553ce52037fc43ea99149785afcfe641)](https://www.codacy.com/app/snipe/snipe-it?utm_source=github.com&utm_medium=referral&utm_content=snipe/snipe-it&utm_campaign=Badge_Grade)
[![All Contributors](https://img.shields.io/badge/all_contributors-180-orange.svg?style=flat-square)](#contributors) [![Open Source Helpers](https://www.codetriage.com/snipe/snipe-it/badges/users.svg)](https://www.codetriage.com/snipe/snipe-it)
[![All Contributors](https://img.shields.io/badge/all_contributors-186-orange.svg?style=flat-square)](#contributors) [![Open Source Helpers](https://www.codetriage.com/snipe/snipe-it/badges/users.svg)](https://www.codetriage.com/snipe/snipe-it)
## Snipe-IT - Open Source Asset Management System
@ -95,7 +95,8 @@ Thanks goes to all of these wonderful people ([emoji key](https://github.com/ken
| [<img src="https://avatars2.githubusercontent.com/u/982885?v=4" width="110px;"/><br /><sub>Martin Stub</sub>](http://martinstub.dk)<br />[🌍](#translation-stubben "Translation") | [<img src="https://avatars2.githubusercontent.com/u/28959963?v=4" width="110px;"/><br /><sub>Meyer Flavio</sub>](https://github.com/meyerf99)<br />[🌍](#translation-meyerf99 "Translation") | [<img src="https://avatars3.githubusercontent.com/u/796443?v=4" width="110px;"/><br /><sub>Micael Rodrigues</sub>](https://github.com/MicaelRodrigues)<br />[🌍](#translation-MicaelRodrigues "Translation") | [<img src="https://avatars0.githubusercontent.com/u/10481331?v=4" width="110px;"/><br /><sub>Mikael Rasmussen</sub>](http://rubixy.com/)<br />[🌍](#translation-mikaelssen "Translation") | [<img src="https://avatars1.githubusercontent.com/u/1544552?v=4" width="110px;"/><br /><sub>IxFail</sub>](https://github.com/IxFail)<br />[🌍](#translation-IxFail "Translation") | [<img src="https://avatars3.githubusercontent.com/u/18483118?v=4" width="110px;"/><br /><sub>Mohammed Fota</sub>](http://www.mohammedfota.com)<br />[🌍](#translation-MohammedFota "Translation") | [<img src="https://avatars0.githubusercontent.com/u/227080?v=4" width="110px;"/><br /><sub>Moayad Alserihi</sub>](https://github.com/omego)<br />[🌍](#translation-omego "Translation") |
| [<img src="https://avatars0.githubusercontent.com/u/1680266?v=4" width="110px;"/><br /><sub>saymd</sub>](https://github.com/saymd)<br />[🌍](#translation-saymd "Translation") | [<img src="https://avatars0.githubusercontent.com/u/1826808?v=4" width="110px;"/><br /><sub>Patrik Larsson</sub>](https://nordsken.se)<br />[🌍](#translation-pooot "Translation") | [<img src="https://avatars1.githubusercontent.com/u/20584746?v=4" width="110px;"/><br /><sub>drcryo</sub>](https://github.com/drcryo)<br />[🌍](#translation-drcryo "Translation") | [<img src="https://avatars1.githubusercontent.com/u/19408004?v=4" width="110px;"/><br /><sub>pawel1615</sub>](https://github.com/pawel1615)<br />[🌍](#translation-pawel1615 "Translation") | [<img src="https://avatars2.githubusercontent.com/u/23340468?v=4" width="110px;"/><br /><sub>bodrovics</sub>](https://github.com/bodrovics)<br />[🌍](#translation-bodrovics "Translation") | [<img src="https://avatars0.githubusercontent.com/u/3257654?v=4" width="110px;"/><br /><sub>priatna</sub>](https://github.com/priatna)<br />[🌍](#translation-priatna "Translation") | [<img src="https://avatars1.githubusercontent.com/u/5358374?v=4" width="110px;"/><br /><sub>Fan Jiang</sub>](https://amayume.net)<br />[🌍](#translation-ProfFan "Translation") |
| [<img src="https://avatars1.githubusercontent.com/u/22555451?v=4" width="110px;"/><br /><sub>ragnarcx</sub>](https://github.com/ragnarcx)<br />[🌍](#translation-ragnarcx "Translation") | [<img src="https://avatars2.githubusercontent.com/u/18654582?v=4" width="110px;"/><br /><sub>Rein van Haaren</sub>](http://www.reinvanhaaren.nl/)<br />[🌍](#translation-reinvanhaaren "Translation") | [<img src="https://avatars1.githubusercontent.com/u/386672?v=4" width="110px;"/><br /><sub>Teguh Dwicaksana</sub>](http://dheche.songolimo.net)<br />[🌍](#translation-dheche "Translation") | [<img src="https://avatars2.githubusercontent.com/u/2572552?v=4" width="110px;"/><br /><sub>fraccie</sub>](https://github.com/FRaccie)<br />[🌍](#translation-FRaccie "Translation") | [<img src="https://avatars0.githubusercontent.com/u/35182720?v=4" width="110px;"/><br /><sub>vinzruzell</sub>](https://github.com/vinzruzell)<br />[🌍](#translation-vinzruzell "Translation") | [<img src="https://avatars1.githubusercontent.com/u/7883603?v=4" width="110px;"/><br /><sub>Kevin Austin</sub>](http://kevinaustin.com)<br />[🌍](#translation-vipsystem "Translation") | [<img src="https://avatars3.githubusercontent.com/u/3861828?v=4" width="110px;"/><br /><sub>Wira Sandy</sub>](http://azuraweb.xyz)<br />[🌍](#translation-wira-sandy "Translation") |
| [<img src="https://avatars2.githubusercontent.com/u/8663789?v=4" width="110px;"/><br /><sub>Илья</sub>](https://github.com/GrayHoax)<br />[🌍](#translation-GrayHoax "Translation") | [<img src="https://avatars3.githubusercontent.com/u/30119111?v=4" width="110px;"/><br /><sub>GodUseVPN</sub>](https://github.com/godusevpn)<br />[🌍](#translation-godusevpn "Translation") | [<img src="https://avatars1.githubusercontent.com/u/745576?v=4" width="110px;"/><br /><sub>周周</sub>](https://github.com/EngrZhou)<br />[🌍](#translation-EngrZhou "Translation") | [<img src="https://avatars3.githubusercontent.com/u/1631095?v=4" width="110px;"/><br /><sub>Sam</sub>](https://github.com/takuy)<br />[💻](https://github.com/snipe/snipe-it/commits?author=takuy "Code") | [<img src="https://avatars1.githubusercontent.com/u/264022?v=4" width="110px;"/><br /><sub>Azerothian</sub>](https://www.illisian.com.au)<br />[💻](https://github.com/snipe/snipe-it/commits?author=Azerothian "Code") |
| [<img src="https://avatars2.githubusercontent.com/u/8663789?v=4" width="110px;"/><br /><sub>Илья</sub>](https://github.com/GrayHoax)<br />[🌍](#translation-GrayHoax "Translation") | [<img src="https://avatars3.githubusercontent.com/u/30119111?v=4" width="110px;"/><br /><sub>GodUseVPN</sub>](https://github.com/godusevpn)<br />[🌍](#translation-godusevpn "Translation") | [<img src="https://avatars1.githubusercontent.com/u/745576?v=4" width="110px;"/><br /><sub>周周</sub>](https://github.com/EngrZhou)<br />[🌍](#translation-EngrZhou "Translation") | [<img src="https://avatars3.githubusercontent.com/u/1631095?v=4" width="110px;"/><br /><sub>Sam</sub>](https://github.com/takuy)<br />[💻](https://github.com/snipe/snipe-it/commits?author=takuy "Code") | [<img src="https://avatars1.githubusercontent.com/u/264022?v=4" width="110px;"/><br /><sub>Azerothian</sub>](https://www.illisian.com.au)<br />[💻](https://github.com/snipe/snipe-it/commits?author=Azerothian "Code") | [<img src="https://avatars1.githubusercontent.com/u/4930051?v=4" width="110px;"/><br /><sub>Wes Hulette</sub>](http://macfoo.wordpress.com/)<br />[💻](https://github.com/snipe/snipe-it/commits?author=jwhulette "Code") | [<img src="https://avatars0.githubusercontent.com/u/8134591?v=4" width="110px;"/><br /><sub>patrict</sub>](https://github.com/patrict)<br />[💻](https://github.com/snipe/snipe-it/commits?author=patrict "Code") |
| [<img src="https://avatars3.githubusercontent.com/u/2611616?v=4" width="110px;"/><br /><sub>Dmitriy Minaev</sub>](https://github.com/VELIKII-DIVAN)<br />[💻](https://github.com/snipe/snipe-it/commits?author=VELIKII-DIVAN "Code") | [<img src="https://avatars0.githubusercontent.com/u/5132245?v=4" width="110px;"/><br /><sub>liquidhorse</sub>](https://github.com/liquidhorse)<br />[💻](https://github.com/snipe/snipe-it/commits?author=liquidhorse "Code") | [<img src="https://avatars1.githubusercontent.com/u/183678?v=4" width="110px;"/><br /><sub>Jordi Boggiano</sub>](https://seld.be/)<br />[💻](https://github.com/snipe/snipe-it/commits?author=Seldaek "Code") | [<img src="https://avatars0.githubusercontent.com/u/653557?v=4" width="110px;"/><br /><sub>Ivan Nieto</sub>](https://github.com/inietov)<br />[💻](https://github.com/snipe/snipe-it/commits?author=inietov "Code") |
<!-- ALL-CONTRIBUTORS-LIST:END -->
This project follows the [all-contributors](https://github.com/kentcdodds/all-contributors) specification. Contributions of any kind welcome!

18
Vagrantfile vendored
View file

@ -81,4 +81,22 @@ Vagrant.configure("2") do |config|
fedora26.vm.provision :shell, :inline => "wget #{SNIPEIT_SH_URL}"
fedora26.vm.provision :shell, :inline => "chmod 755 snipeit.sh"
end
config.vm.define "freebsd" do |freebsd|
freebsd.vm.box = "freebsd/FreeBSD-11.2-RELEASE"
freebsd.vm.hostname = 'freebsd12'
freebsd.vm.network "forwarded_port", guest: 80, host: 8080
freebsd.vm.network "forwarded_port", guest:3306, host:3306 # mysql
freebsd.vm.network "private_network", type: "dhcp"
freebsd.ssh.shell = "sh"
freebsd.vm.base_mac = "080027D14C66"
freebsd.vm.synced_folder ".", "/vagrant", :nfs => true, id: "vagrant-root",
:mount_options => ['rw', 'vers=3', 'tcp', 'actimeo=2']
freebsd.vm.provision "shell", inline: <<-SHELL
pkg install -y python27;
SHELL
freebsd.vm.provision "ansible" do |ansible|
ansible.playbook = "ansible/freebsd/vagrant_playbook.yml"
end
end
end

View file

@ -0,0 +1,260 @@
---
- name: Set up local server
hosts: all
remote_user: vagrant
become_user: root
become_method: sudo
vars:
- ansible_python_interpreter: /usr/local/bin/python2.7
gather_facts: no
# Tasks
tasks:
#
# Update the PKG database
#
- name: Upgrade PKG database
raw: sudo pkg upgrade -y
#
# Mount the shared folders
#
- name: Update Vagrant Shared Folders
command: "{{ item }}"
with_items:
- sysrc rpc_lockd_enable=YES
- sysrc rpc_statd_enable=YES
become: true
#
# Install required utilities
#
- name: Install Utilities
pkgng:
name: "{{ item }}"
state: present
with_items:
- openssl
- node
- npm
- git
- nano
- wget
- bash
become: true
#
# Install php and php dependancies
#
- name: Install PHP dependancies
pkgng:
name: "{{ item }}"
state: present
with_items:
- php72
- php72-zip
- php72-zlib
- php72-extensions
- php72-mbstring
- php72-openssl
# - php72-mysqli
- php72-curl
- php72-soap
- php72-pdo_mysql
# - php72-pdo_pgsql
- php72-ldap
- php72-curl
- php72-fileinfo
- php72-bcmath
- php72-gd
become: true
#
# Create a php.ini file
#
- name: PHP INI check
stat:
path: /usr/local/etc/php.ini
register: php_ini_exits
- name: Create PHP ini
command: cp /usr/local/etc/php.ini-development /usr/local/etc/php.ini
become: true
when: not php_ini_exits.stat.exists
- name: Enable PHP-FPM auto-start
command: sysrc php_fpm_enable=YES
become: true
- name: Start PHP-FPM service
service:
name: php-fpm
state: started
become: true
#
# 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
become: true
#
# Install MySQL Server
- name: Install MySQL 5.7
pkgng:
name: mysql57-server
state: present
become: true
register: sql_server
- name: Start MySQL server
service:
name: mysql-server
state: started
become: true
- name: MySQL 5.7 auto-start
command: sysrc mysql_enable=YES
become: true
when: sql_server.changed == true
- name: Get MySQL root password
command: tail -1 /root/.mysql_secret
register: myql_root_pwd
become: true
when: sql_server.changed == true
- name: Change MySQL root password
command: mysqladmin -u root -p'{{myql_root_pwd.stdout}}' password vagrant
when: sql_server.changed == true
- name: Enable remote mysql
replace:
path: /usr/local/etc/mysql/my.cnf
regexp: "127.0.0.1"
replace: "0.0.0.0"
become: true
when: sql_server.changed == true
- name: Grant user vagrant privelages
shell: mysql -u root -pvagrant -e "GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY 'vagrant' WITH GRANT OPTION; FLUSH PRIVILEGES;"
become: true
when: sql_server.changed == true
ignore_errors: true
- name: Restart MySQL server
service:
name: mysql-server
state: restarted
become: true
#
# Install Apache Web Server
#
- name: Install Apache 2.4
pkgng:
name: apache24
state: present
become: true
register: apache24_server
- name: Apache 2.4 auto-start
command: sysrc apache24_enable=YES
become: true
when: apache24_server.changed == true
- name: Enable Apache modules
replace:
path: /usr/local/etc/apache24/httpd.conf
regexp: "#{{ item }}"
replace: "{{ item }}"
become: true
with_items:
- LoadModule rewrite_module libexec/apache24/mod_rewrite.so
- LoadModule vhost_alias_module libexec/apache24/mod_vhost_alias.so
- LoadModule deflate_module libexec/apache24/mod_deflate.so
- LoadModule expires_module libexec/apache24/mod_expires.so
- LoadModule mpm_worker_module libexec/apache24/mod_mpm_worker.so
- LoadModule proxy_fcgi_module libexec/apache24/mod_proxy_fcgi.so
- LoadModule proxy_module libexec/apache24/mod_proxy.so
- Include etc/apache24/extra/httpd-vhosts.conf
when: apache24_server.changed == true
- name: Disable Apache modules
replace:
path: /usr/local/etc/apache24/httpd.conf
regexp: "{{ item }}"
replace: "#{{ item }}"
become: true
with_items:
- LoadModule mpm_prefork_module libexec/apache24/mod_mpm_prefork.so
when: apache24_server.changed == true
- name: Backup vhosts
command: cp /usr/local/etc/apache24/extra/httpd-vhosts.conf /usr/local/etc/apache24/extra/httpd-vhosts.conf.bak
become: true
when: apache24_server.changed == true
- name: Truncate vhosts
command: truncate -s 0 /usr/local/etc/apache24/extra/httpd-vhosts.conf
become: true
when: apache24_server.changed == true
- name: Set up vhost
blockinfile:
path: "/usr/local/etc/apache24/extra/httpd-vhosts.conf"
block: |
<VirtualHost *>
DocumentRoot /usr/local/www/apache24/data/public
ServerName vagrant.app
ProxyPassMatch ^/(.*\.php(/.*)?)$ fcgi://127.0.0.1:9000/usr/local/www/apache24/data/public/$1
DirectoryIndex /index.php index.php
<Directory /usr/local/www/apache24/data/public>
Options -Indexes +FollowSymLinks
AllowOverride All
Require all granted
</Directory>
</VirtualHost>
become: true
when: apache24_server.changed == true
- name: Map apache dir to local folder
shell: |
if ! [ -L /var/www ]; then
rm -rf /usr/local/www/apache24/data;
ln -fs /vagrant /usr/local/www/apache24/data;
fi
become: true
when: apache24_server.changed == true
- name: Start Apache 2.4 server
service:
name: apache24
state: started
become: true

View file

@ -169,6 +169,11 @@ class LdapSync extends Command
$item['activated'] = ( in_array($results[$i]['useraccountcontrol'][0], $enabled_accounts) ) ? 1 : 0;
} else {
$item['activated'] = 0;
// If there is no activated flag, assume this is handled via the OU and activate the users
if (empty($ldap_result_active_flag)) {
$item['activated'] = 1;
}
}
// User exists

View file

@ -0,0 +1,61 @@
<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
use App\Models\Asset;
use App\Models\User;
use App\Notifications\CurrentInventory;
class SendCurrentInventoryToUsers extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'snipeit:user-inventory';
/**
* The console command description.
*
* @var string
*/
protected $description = 'This will send users a report of all of the items currently checked out to them.';
/**
* Create a new command instance.
*
* @return void
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
*
* @return mixed
*/
public function handle()
{
$users = User::whereNull('deleted_at')->whereNotNull('email')->with('assets', 'accessories', 'licenses')->get();
$count = 0;
foreach ($users as $user) {
if (($user->assets->count() > 0) || ($user->accessories->count() > 0) || ($user->licenses->count() > 0))
{
$count++;
$user->notify((new CurrentInventory($user)));
}
}
$this->info($count.' users notified.');
}
}

View file

@ -57,17 +57,12 @@ class SendExpectedCheckinAlerts extends Command
}
}
// Send a rollup to the admin, if settings dictate
$recipient = new \App\Models\Recipients\AlertRecipient();
if (($assets) && ($assets->count() > 0) && ($settings->alert_email!='')) {
if (($assets) && ($assets->count() > 0) && ($settings->alerts_enabled && $settings->alert_email != '')) {
$recipient->notify(new ExpectedCheckinAdminNotification($assets));
}
}
}

View file

@ -31,6 +31,7 @@ class Kernel extends ConsoleKernel
Commands\RegenerateAssetTags::class,
Commands\SyncAssetCounters::class,
Commands\RestoreDeletedUsers::class,
Commands\SendCurrentInventoryToUsers::class,
];
/**

View file

@ -132,7 +132,7 @@ class AccessoriesController extends Controller
* @param int $id
* @return \Illuminate\Http\Response
*/
public function checkedout($id)
public function checkedout($id, Request $request)
{
$this->authorize('view', Accessory::class);
@ -143,8 +143,16 @@ class AccessoriesController extends Controller
$accessory->lastCheckoutArray = $accessory->lastCheckout->toArray();
$accessory_users = $accessory->users;
$total = $accessory_users->count();
if ($request->filled('search')) {
$accessory_users = $accessory->users()
->where('first_name', 'like', '%'.$request->input('search').'%')
->orWhere('last_name', 'like', '%'.$request->input('search').'%')
->get();
}
$total = $accessory_users->count();
return (new AccessoriesTransformer)->transformCheckedoutAccessory($accessory, $accessory_users, $total);
}

View file

@ -733,6 +733,12 @@ class AssetsController extends Controller
$asset->next_audit_date = $request->input('next_audit_date');
}
// Check to see if they checked the box to update the physical location,
// not just note it in the audit notes
if ($request->input('update_location')=='1') {
$asset->location_id = $request->input('location_id');
}
$asset->last_audit_date = date('Y-m-d h:i:s');
if ($asset->save()) {

View file

@ -763,6 +763,14 @@ class AssetsController extends Controller
$asset->next_audit_date = $request->input('next_audit_date');
$asset->last_audit_date = date('Y-m-d h:i:s');
// Check to see if they checked the box to update the physical location,
// not just note it in the audit notes
if ($request->input('update_location')=='1') {
\Log::debug('update location in audit');
$asset->location_id = $request->input('location_id');
}
if ($asset->save()) {

View file

@ -55,7 +55,10 @@ class ForgotPasswordController extends Controller
// to send the link, we will examine the response then see the message we
// need to show to the user. Finally, we'll send out a proper response.
$response = $this->broker()->sendResetLink(
$request->only('email')
array_merge(
$request->only('email'),
['activated' => '1']
)
);
if ($response === \Password::RESET_LINK_SENT) {

View file

@ -4,6 +4,9 @@ namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\ResetsPasswords;
use App\Models\User;
use Illuminate\Http\Request;
class ResetPasswordController extends Controller
{
@ -36,4 +39,18 @@ class ResetPasswordController extends Controller
{
$this->middleware('guest');
}
public function showSnipeResetForm(Request $request, $token = null)
{
// Check that the user is active
if ($user = User::where('email', '=',$request->input('email'))->where('activated','=','1')->count() > 0) {
return view('auth.passwords.reset')->with(
['token' => $token, 'email' => $request->email]
);
}
return redirect()->route('password.request')->withErrors(['email' => 'No matching users']);
}
}

View file

@ -42,14 +42,19 @@ class CustomFieldsetsController extends Controller
if ($cfset) {
$custom_fields_list = ["" => "Add New Field to Fieldset"] + CustomField::pluck("name", "id")->toArray();
$maxid = 0;
foreach ($cfset->fields() as $field) {
if ($field->pivot->order > $maxid) {
$maxid=$field->pivot->order;
}
if (isset($custom_fields_list[$field->id])) {
unset($custom_fields_list[$field->id]);
if ($field) {
if ($field->pivot->order > $maxid) {
$maxid=$field->pivot->order;
}
if (isset($custom_fields_list[$field->id])) {
unset($custom_fields_list[$field->id]);
}
}
}
return view("custom_fields.fieldsets.view")

View file

@ -90,8 +90,11 @@ class UsersController extends Controller
$userPermissions = Helper::selectedPermissionsArray($permissions, Input::old('permissions', array()));
$permissions = $this->filterDisplayable($permissions);
$user = new User;
$user->activated = 1;
return view('users/edit', compact('groups', 'userGroups', 'permissions', 'userPermissions'))
->with('user', new User);
->with('user', $user);
}
/**
@ -140,7 +143,6 @@ class UsersController extends Controller
$user->permissions = json_encode($permissions_array);
if ($user->save()) {
if ($request->filled('groups')) {
$user->groups()->sync($request->input('groups'));
} else {
@ -148,7 +150,7 @@ class UsersController extends Controller
}
if (($request->input('email_user') == 1) && ($request->filled('email'))) {
// Send the credentials through email
// Send the credentials through email
$data = array();
$data['email'] = e($request->input('email'));
$data['username'] = e($request->input('username'));
@ -169,9 +171,9 @@ class UsersController extends Controller
{
$output = null;
foreach ($permissions as $key => $permission) {
$output[$key] = array_filter($permission, function ($p) {
return $p['display'] === true;
});
$output[$key] = array_filter($permission, function ($p) {
return $p['display'] === true;
});
}
return $output;
}
@ -188,9 +190,7 @@ class UsersController extends Controller
*/
public function edit($id)
{
if ($user = User::find($id)) {
$this->authorize('update', $user);
$permissions = config('permissions');
@ -206,8 +206,6 @@ class UsersController extends Controller
$error = trans('admin/users/message.user_not_found', compact('id'));
return redirect()->route('users.index')->with('error', $error);
}
/**
@ -232,7 +230,6 @@ class UsersController extends Controller
}
try {
$user = User::findOrFail($id);
if ($user->id == $request->input('manager_id')) {
@ -247,9 +244,6 @@ class UsersController extends Controller
$orig_superuser = $orig_permissions_array['superuser'];
}
}
} catch (ModelNotFoundException $e) {
return redirect()->route('users.index')
->with('error', trans('admin/users/message.user_not_found', compact('id')));
@ -270,7 +264,7 @@ class UsersController extends Controller
$user->email = $request->input('email');
// Update the user
// Update the user
$user->first_name = $request->input('first_name');
$user->last_name = $request->input('last_name');
$user->two_factor_optin = $request->input('two_factor_optin') ?: 0;
@ -395,7 +389,7 @@ class UsersController extends Controller
public function getRestore($id = null)
{
$this->authorize('edit', User::class);
// Get user information
// Get user information
if (!$user = User::onlyTrashed()->find($id)) {
return redirect()->route('users.index')->with('error', trans('admin/users/messages.user_not_found'));
}
@ -419,7 +413,7 @@ class UsersController extends Controller
*/
public function show($userId = null)
{
if(!$user = User::with('assets', 'assets.model', 'consumables', 'accessories', 'licenses', 'userloc')->withTrashed()->find($userId)) {
if (!$user = User::with('assets', 'assets.model', 'consumables', 'accessories', 'licenses', 'userloc')->withTrashed()->find($userId)) {
// Redirect to the user management page
return redirect()->route('users.index')
->with('error', trans('admin/users/message.user_not_found', ['id' => $userId]));
@ -533,7 +527,6 @@ class UsersController extends Controller
*/
public function getExportUserCsv()
{
$this->authorize('view', User::class);
\Debugbar::disable();
@ -541,76 +534,74 @@ class UsersController extends Controller
// Open output stream
$handle = fopen('php://output', 'w');
User::with('assets', 'accessories', 'consumables', 'department', 'licenses', 'manager', 'groups', 'userloc', 'company','throttle')
User::with('assets', 'accessories', 'consumables', 'department', 'licenses', 'manager', 'groups', 'userloc', 'company')
->orderBy('created_at', 'DESC')
->chunk(500, function($users) use($handle) {
$headers=[
// strtolower to prevent Excel from trying to open it as a SYLK file
strtolower(trans('general.id')),
trans('admin/companies/table.title'),
trans('admin/users/table.title'),
trans('admin/users/table.employee_num'),
trans('admin/users/table.name'),
trans('admin/users/table.username'),
trans('admin/users/table.email'),
trans('admin/users/table.manager'),
trans('admin/users/table.location'),
trans('general.department'),
trans('general.assets'),
trans('general.licenses'),
trans('general.accessories'),
trans('general.consumables'),
trans('admin/users/table.groups'),
trans('general.notes'),
trans('admin/users/table.activated'),
trans('general.created_at')
];
fputcsv($handle, $headers);
foreach ($users as $user) {
$user_groups = '';
foreach ($user->groups as $user_group) {
$user_groups .= $user_group->name.', ';
}
// Add a new row with data
$values = [
$user->id,
($user->company) ? $user->company->name : '',
$user->jobtitle,
$user->employee_num,
$user->present()->fullName(),
$user->username,
$user->email,
($user->manager) ? $user->manager->present()->fullName() : '',
($user->userloc) ? $user->userloc->name : '',
($user->department) ? $user->department->name : '',
$user->assets->count(),
$user->licenses->count(),
$user->accessories->count(),
$user->consumables->count(),
$user_groups,
$user->notes,
($user->activated=='1') ? trans('general.yes') : trans('general.no'),
$user->created_at,
->chunk(500, function ($users) use ($handle) {
$headers=[
// strtolower to prevent Excel from trying to open it as a SYLK file
strtolower(trans('general.id')),
trans('admin/companies/table.title'),
trans('admin/users/table.title'),
trans('admin/users/table.employee_num'),
trans('admin/users/table.name'),
trans('admin/users/table.username'),
trans('admin/users/table.email'),
trans('admin/users/table.manager'),
trans('admin/users/table.location'),
trans('general.department'),
trans('general.assets'),
trans('general.licenses'),
trans('general.accessories'),
trans('general.consumables'),
trans('admin/users/table.groups'),
trans('general.notes'),
trans('admin/users/table.activated'),
trans('general.created_at')
];
fputcsv($handle, $values);
}
});
fputcsv($handle, $headers);
foreach ($users as $user) {
$user_groups = '';
foreach ($user->groups as $user_group) {
$user_groups .= $user_group->name.', ';
}
// Add a new row with data
$values = [
$user->id,
($user->company) ? $user->company->name : '',
$user->jobtitle,
$user->employee_num,
$user->present()->fullName(),
$user->username,
$user->email,
($user->manager) ? $user->manager->present()->fullName() : '',
($user->userloc) ? $user->userloc->name : '',
($user->department) ? $user->department->name : '',
$user->assets->count(),
$user->licenses->count(),
$user->accessories->count(),
$user->consumables->count(),
$user_groups,
$user->notes,
($user->activated=='1') ? trans('general.yes') : trans('general.no'),
$user->created_at,
];
fputcsv($handle, $values);
}
});
// Close the output stream
fclose($handle);
}, 200, [
'Content-Type' => 'text/csv',
'Content-Type' => 'text/csv; charset=UTF-8',
'Content-Disposition' => 'attachment; filename="users-'.date('Y-m-d-his').'.csv"',
]);
return $response;
}
/**
@ -622,8 +613,7 @@ class UsersController extends Controller
*/
public function printInventory($id)
{
$show_user = User::where('id',$id)->withTrashed()->first();
$show_user = User::where('id', $id)->withTrashed()->first();
$assets = Asset::where('assigned_to', $id)->where('assigned_type', User::class)->with('model', 'model.category')->get();
$accessories = $show_user->accessories()->get();
$consumables = $show_user->consumables()->get();
@ -632,7 +622,5 @@ class UsersController extends Controller
->with('accessories', $accessories)
->with('consumables', $consumables)
->with('show_user', $show_user);
}
}

View file

@ -6,6 +6,10 @@ use Illuminate\Cookie\Middleware\EncryptCookies as BaseEncrypter;
class EncryptCookies extends BaseEncrypter
{
protected static $serialize = true;
/**
* The names of the cookies that should not be encrypted.
*

View file

@ -1360,8 +1360,8 @@ class Asset extends Depreciable
*/
public function scopeInCategory($query, $category_id)
{
return $query->join('models', 'assets.model_id', '=', 'models.id')
->join('categories', 'models.category_id', '=', 'categories.id')->where('models.category_id', '=', $category_id);
return $query->join('models as category_models', 'assets.model_id', '=', 'category_models.id')
->join('categories', 'category_models.category_id', '=', 'categories.id')->where('category_models.category_id', '=', $category_id);
}
/**

View file

@ -12,9 +12,14 @@ use Illuminate\Validation\Rule;
class CustomField extends Model
{
use ValidatingTrait, UniqueUndeletedTrait;
public $guarded=["id"];
public static $PredefinedFormats=[
use ValidatingTrait,
UniqueUndeletedTrait;
public $guarded = [
"id"
];
public static $PredefinedFormats = [
"ANY" => "",
"CUSTOM REGEX" => "",
"ALPHA" => "alpha",
@ -31,6 +36,14 @@ class CustomField extends Model
"BOOLEAN" => "boolean",
];
/**
* Validation rules.
* At least empty array must be provided if using ValidatingTrait.
*
* @var array
*/
protected $rules = [];
/**
* The attributes that are mass assignable.
*
@ -57,7 +70,6 @@ class CustomField extends Model
*/
public static $table_name = "assets";
/**
* Convert the custom field's name property to a db-safe string.
*
@ -87,6 +99,7 @@ class CustomField extends Model
*/
public static function boot()
{
parent::boot();
self::created(function ($custom_field) {
// Column already exists on the assets table - nothing to do here.

View file

@ -7,10 +7,16 @@ use Watson\Validating\ValidatingTrait;
class CustomFieldset extends Model
{
use ValidatingTrait;
protected $guarded=["id"];
public $rules=[
"name" => "required|unique:custom_fieldsets"
/**
* Validation rules
* @var array
*/
protected $rules = [
"name" => "required|unique:custom_fieldsets"
];
/**
@ -21,7 +27,6 @@ class CustomFieldset extends Model
* @var boolean
*/
protected $injectUniqueIdentifier = true;
use ValidatingTrait;
/**

View file

@ -20,13 +20,13 @@ class Location extends SnipeModel
protected $dates = ['deleted_at'];
protected $table = 'locations';
protected $rules = array(
'name' => 'required|min:2|max:255|unique_undeleted',
'city' => 'min:2|max:255|nullable',
'country' => 'min:2|max:2|nullable',
'name' => 'required|min:2|max:255|unique_undeleted',
'city' => 'min:2|max:255|nullable',
'country' => 'min:2|max:2|nullable',
'address' => 'max:80|nullable',
'address2' => 'max:80|nullable',
'zip' => 'min:3|max:10|nullable',
// 'manager_id' => 'exists:users'
'zip' => 'min:3|max:10|nullable',
'manager_id' => 'exists:users,id|nullable'
);
/**
@ -56,6 +56,7 @@ class Location extends SnipeModel
'country',
'zip',
'ldap_ou',
'manager_id',
'currency',
'image',
];

View file

@ -0,0 +1,66 @@
<?php
namespace App\Notifications;
use Illuminate\Bus\Queueable;
use Illuminate\Notifications\Notification;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage;
class CurrentInventory extends Notification
{
use Queueable;
/**
* Create a new notification instance.
*
* @return void
*/
public function __construct($user)
{
$this->user = $user;
}
/**
* Get the notification's delivery channels.
*
* @param mixed $notifiable
* @return array
*/
public function via($notifiable)
{
return ['mail'];
}
/**
* Get the mail representation of the notification.
*
* @param mixed $notifiable
* @return \Illuminate\Notifications\Messages\MailMessage
*/
public function toMail($notifiable)
{
$message = (new MailMessage)->markdown('notifications.markdown.user-inventory',
[
'assets' => $this->user->assets,
'accessories' => $this->user->accessories,
'licenses' => $this->user->licenses,
])
->subject('Inventory Report');
return $message;
}
/**
* Get the array representation of the notification.
*
* @param mixed $notifiable
* @return array
*/
public function toArray($notifiable)
{
return [
//
];
}
}

View file

@ -139,6 +139,10 @@ class AuthServiceProvider extends ServiceProvider
return $user->hasAccess('self.edit_location');
});
Gate::define('self.checkout_assets', function($user) {
return $user->hasAccess('self.checkout_assets');
});
Gate::define('backend.interact', function ($user) {
return $user->can('view', Statuslabel::class)
|| $user->can('view', AssetModel::class)

View file

@ -2,7 +2,7 @@
"name": "snipe/snipe-it",
"description": "Open source asset management system built on Laravel.",
"keywords": ["assets", "asset-management", "laravel"],
"license": "AGPL-3",
"license": "AGPL-3.0-or-later",
"type": "project",
"require": {
"php": ">=7.1.3",
@ -13,11 +13,12 @@
"doctrine/dbal": "^2.8.0",
"doctrine/inflector": "1.3.*",
"doctrine/instantiator": "1.1.*",
"eduardokum/laravel-mail-auto-embed": "^1.0",
"erusev/parsedown": "^1.6",
"fideloper/proxy": "~4.0",
"intervention/image": "^2.3",
"javiereguiluz/easyslugger": "^1.0",
"laravel/framework": "5.6.16",
"laravel/framework": "5.7.*",
"laravel/passport": "~6.0",
"laravel/tinker": "^1.0",
"laravelcollective/html": "^5.3",
@ -39,7 +40,7 @@
"tecnickcom/tc-lib-barcode": "^1.15",
"tightenco/ziggy": "^0.6.3",
"unicodeveloper/laravel-password": "^1.0",
"watson/validating": "^3.0"
"watson/validating": "3.1.7"
},
"require-dev": {
"codeception/codeception": "^2.4",

705
composer.lock generated

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,28 @@
<?php
return [
/*
|--------------------------------------------------------------------------
| Mail auto embed
|--------------------------------------------------------------------------
|
| If true, images will be automatically embedded.
| If false, only images with the 'data-auto-embed' attribute will be embedded
|
*/
'enabled' => env('MAIL_AUTO_EMBED', true),
/*
|--------------------------------------------------------------------------
| Mail embed method
|--------------------------------------------------------------------------
|
| Supported: "attachment", "base64"
|
*/
'method' => env('MAIL_AUTO_EMBED_METHOD', 'base64'),
];

View file

@ -578,6 +578,13 @@ return array(
'display' => true,
),
array(
'permission' => 'self.checkout_assets',
'label' => 'Self-Checkout',
'note' => 'This user may check out assets that are marked for self-checkout.',
'display' => true,
),
),

8257
npm-shrinkwrap.json generated

File diff suppressed because it is too large Load diff

View file

@ -14,7 +14,7 @@
"babel-preset-latest": "^6.24.1",
"cross-env": "^5.0.5",
"jquery": "^3.1.1",
"laravel-mix": "2.1",
"laravel-mix": "^2.1.14",
"lodash": "^4.17.4",
"vue": "2.4.4",
"vue-loader": "^13.6.1",
@ -22,14 +22,17 @@
},
"dependencies": {
"@fortawesome/fontawesome-free": "^5.2.0",
"ajv": "^6.5.3",
"blueimp-file-upload": "^9.18.0",
"bootstrap": "^3.3.7",
"bootstrap-colorpicker": "^2.5.1",
"bootstrap-datepicker": "^1.6.4",
"bootstrap-less": "^3.3.8",
"bootstrap-table": "^1.12.1",
"ekko-lightbox": "^5.1.1",
"font-awesome": "^4.7.0",
"icheck": "^1.0.2",
"imagemin": "^5.3.1",
"jquery-slimscroll": "^1.3.8",
"jquery-ui": "^1.12.1",
"jquery-ui-bundle": "^1.12.1",
@ -38,6 +41,7 @@
"less-loader": "^4.1.0",
"papaparse": "^4.3.3",
"select2": "^4.0.3",
"tableexport.jquery.plugin": "^1.9.15",
"tether": "^1.4.0",
"vue-resource": "^1.3.3"
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
public/css/dist/bootstrap-table.css vendored Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
public/js/dist/all.js vendored

Binary file not shown.

Binary file not shown.

BIN
public/js/dist/bootstrap-table.js vendored Normal file

Binary file not shown.

Binary file not shown.

BIN
public/js/jspdf.min.js vendored

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

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