Compare commits

...

85 Commits

Author SHA1 Message Date
snipe 5a1225a8bf Merge branch 'develop' 2017-09-29 03:48:37 -07:00
snipe c6069b905b Bumped version 2017-09-29 03:47:50 -07:00
snipe 2e76620cf8 More specific required check 2017-09-29 03:44:23 -07:00
snipe a4b30279ee Fixes #4067 - Make unrequired custom fields nullable 2017-09-29 03:30:13 -07:00
snipe db59d4b2c4 Merge branch 'develop' 2017-09-29 02:08:06 -07:00
snipe faf3802971 Fixes #4011 - do not send email to user on license checkout 2017-09-29 02:00:49 -07:00
snipe 7fe2a1f802 Fixes #4051 - use delete method for deleting user files 2017-09-29 01:48:16 -07:00
snipe 3d57d1bd1d Merge branch 'develop' 2017-09-29 01:30:30 -07:00
snipe ba8bcce8eb Hopefully fixes #4020 2017-09-29 01:21:08 -07:00
snipe 8247a73182 Merge branch 'develop' 2017-09-28 22:22:37 -07:00
snipe aab409dec2 Fixes #4061 - bulk checkout error 2017-09-28 22:22:21 -07:00
snipe 70a9b7bf05 Merge branch 'develop' 2017-09-28 21:21:01 -07:00
snipe d9824a0454 Bumped version 2017-09-28 21:20:37 -07:00
snipe e759a249bd Merge branch 'develop' 2017-09-28 21:18:39 -07:00
snipe 42c2a66946 Small UI tweaks for accessories 2017-09-28 21:18:16 -07:00
snipe 4d32f2b337 Fixes #4059 - accessories view 2017-09-28 21:18:00 -07:00
snipe 0e29744ec2 Don’t try to send an email if the user doesn’t have an email address 2017-09-28 20:57:33 -07:00
snipe 51236a2ad9 Fixes #4056 - check for assets before deleting user 2017-09-28 19:57:52 -07:00
snipe 9b6726a630 Fixes #4056 - check for assets before deleting user 2017-09-28 19:57:03 -07:00
snipe cbdd05144a Merge branch 'develop' 2017-09-28 19:50:34 -07:00
snipe 507f1f196c Added integrity hashes 2017-09-28 18:46:16 -07:00
snipe b60febeea2 Removed space in XSS header because safari was getting angry 2017-09-28 18:45:54 -07:00
snipe b3e0d8f675 Disallow / in robots 2017-09-28 17:47:48 -07:00
snipe 9b84a0d516 *eyeroll* 2017-09-28 17:34:47 -07:00
snipe adac5ac544 Check for valid asset 2017-09-28 17:32:37 -07:00
snipe 1775995f26 Is this space necessary? Getting weird results from netsparker 2017-09-28 17:25:04 -07:00
snipe df4700b411 Merge branch 'develop' 2017-09-28 17:17:03 -07:00
snipe 26a7701cda Added referrer-policy header 2017-09-28 17:12:58 -07:00
snipe a34085f1d9 Added mode=block to XSSProtect header 2017-09-28 16:28:27 -07:00
snipe 8e682c715e Merge branch 'develop' 2017-09-28 16:07:04 -07:00
snipe 915c19ebda Merge branch 'develop' of github.com:snipe/snipe-it into develop 2017-09-28 16:03:41 -07:00
snipe 7fded367c4 Adds rel="noopener" to footer links 2017-09-28 16:03:36 -07:00
Daniel Meltzer 0a4743210c Pass urls to vue. Should fix subdirectory issues. (#4054) 2017-09-28 16:03:04 -07:00
Daniel Meltzer af19e5d976 Fix old route (#4053)
Looks like we missed in the v4 port.  Fixes the unrelated issue in #4052
2017-09-28 16:02:50 -07:00
snipe 3d7277398c Fixes #4057 - sig file in lightbox 2017-09-28 15:13:05 -07:00
snipe a7ad48a02a Make fields nullable for licenses 2017-09-27 22:11:20 -07:00
snipe 469a3fc608 Merge branch 'develop' 2017-09-27 17:48:32 -07:00
snipe 0fb4ff77f4 Restoring older SnipeModel attribute setters
In case needed by API - needs investigation
2017-09-27 16:39:20 -07:00
snipe ac83dba2bb Fixes #4034 - save login note 2017-09-27 16:35:54 -07:00
snipe 979ecf961d Added back button to oauth page 2017-09-27 16:33:51 -07:00
snipe 13dcdf41b8 Fixes #4045 - missing back button 2017-09-27 16:32:37 -07:00
snipe fc96fa756e Fix redirect default on password reset 2017-09-27 16:23:21 -07:00
snipe ea9a502152 Added empty regsitration controller
When using the default Laravel auth routes, it expects a registration controller, even though we don’t have a concept of registration. This blank controller just prevents route caching from throwing errors.
2017-09-27 16:23:01 -07:00
snipe d844734b6c Use named login route 2017-09-27 16:22:02 -07:00
snipe ec8a3d2e56 Fixes #4027 - proper redirect on fieldset delete 2017-09-27 16:02:29 -07:00
snipe 5410dc4255 Fixed link to contributing docs in readme 2017-09-27 15:30:20 -07:00
snipe d1112bbc99 Fix created_at date display for groups index 2017-09-27 15:28:02 -07:00
snipe ecf041fa10 Fixes #4043 - standardize groups API response 2017-09-27 15:18:29 -07:00
snipe 0ab9bc1db8 Added normalization midddleware, removed 2017-09-27 15:18:05 -07:00
snipe 73e788b94b Make min_amt fillable 2017-09-27 14:50:56 -07:00
snipe e91a537552 Use more modern Request handler 2017-09-27 14:50:48 -07:00
snipe ef8c1abf28 Fixes #3113 and #4040 2017-09-27 14:50:17 -07:00
snipe bd0498aa69 Fixes #4016 - signature file missing from history tab 2017-09-27 12:58:08 -07:00
snipe ea45033588 Merge branch 'develop' 2017-09-26 16:03:09 -07:00
snipe 5e1df7049c Make collation and charset for mysql an env variable 2017-09-26 16:02:55 -07:00
snipe e27e1a78c3 Fix for case where a fieldset is assigned to a model, but no fields are assigned 2017-09-26 16:01:23 -07:00
snipe d585a34a26 Prevent users from running this as root/admin user 2017-09-26 13:11:01 -07:00
snipe 4edaba648e Tweaks to upgrade script 2017-09-26 13:05:34 -07:00
snipe 9dca7396f3 Merge branch 'develop' 2017-09-26 11:12:55 -07:00
snipe 4324242475 Bumped version 2017-09-26 11:12:36 -07:00
snipe eca5a05335 Fix forgotten password missing route (???) 2017-09-26 11:08:47 -07:00
snipe aa4d3c3ffb Fix forgotten password missing route (???) 2017-09-26 11:07:47 -07:00
snipe d442feb687 Add @gizzmojr as a contributor 2017-09-25 22:18:25 -07:00
snipe 0a88141b18 Merge branch 'develop' of github.com:snipe/snipe-it into develop 2017-09-25 22:17:38 -07:00
snipe d5e6d82ca1 Bumped version 2017-09-25 22:17:00 -07:00
gizzmojr f2a62857cb Clear audit input field (#4010) 2017-09-25 22:15:29 -07:00
snipe b354ca817d Bumped version 2017-09-25 22:10:06 -07:00
snipe 4b9bfc178d One more try on #4001 2017-09-25 22:05:57 -07:00
snipe abc2f7e789 Bumped build number 2017-09-25 21:57:16 -07:00
snipe 29cc9a0815 Tweaks to upgrade script 2017-09-25 21:50:41 -07:00
snipe f2ee7dcabb Fixes #4001 - license checkout not working 2017-09-25 21:40:43 -07:00
snipe 26203801f6 Fixes #4009 - zip not populating on locations listing page 2017-09-25 20:45:05 -07:00
snipe fbe9539130 Proto upgrade script 2017-09-25 20:30:18 -07:00
snipe 43ec959385 Add @richardhofman6 as a contributor 2017-09-25 16:58:47 -07:00
snipe 9b6276f281 Bumped version 2017-09-25 16:04:23 -07:00
snipe 0715791229 Include oauth keys in backup 2017-09-25 15:45:33 -07:00
snipe 0a0661bf41 Additional fixes for #3995 in atypical blades 2017-09-25 15:41:02 -07:00
snipe 6ee939d29b Allegedly fixes #3995 - subdirectory issues with JS/CSS 2017-09-25 15:39:18 -07:00
snipe c3afbc0e53 Run backups before purging and importing 2017-09-25 15:00:23 -07:00
snipe 38326314ca Merge branch 'develop' 2017-09-25 11:53:33 -07:00
snipe 865950e766 Fixes #4000 - user_id blank 2017-09-25 11:53:10 -07:00
snipe d49b67d033 Fix for assigned user location
Was breaking requestable page
2017-09-25 11:26:04 -07:00
snipe 6b63808e34 Fix for asset location null on user 2017-09-25 11:25:15 -07:00
snipe 34dfcb5add Merge branch 'develop' 2017-09-22 17:23:38 -07:00
snipe 30019a144a Disable login note editing on demo 2017-09-22 17:23:22 -07:00
71 changed files with 653 additions and 373 deletions
+18
View File
@@ -737,6 +737,24 @@
"contributions": [
"code"
]
},
{
"login": "richardhofman6",
"name": "Richard Hofman",
"avatar_url": "https://avatars1.githubusercontent.com/u/6551003?v=4",
"profile": "https://github.com/richardhofman6",
"contributions": [
"code"
]
},
{
"login": "gizzmojr",
"name": "gizzmojr",
"avatar_url": "https://avatars0.githubusercontent.com/u/3697569?v=4",
"profile": "https://github.com/gizzmojr",
"contributions": [
"code"
]
}
]
}
+3
View File
@@ -19,6 +19,8 @@ DB_USERNAME=null
DB_PASSWORD=null
DB_PREFIX=null
DB_DUMP_PATH='/usr/bin'
DB_CHARSET=utf8mb4
DB_COLLATION=utf8mb4_unicode_ci
# --------------------------------------------
# OPTIONAL: SSL DATABASE SETTINGS
@@ -61,6 +63,7 @@ ENCRYPT=false
COOKIE_NAME=snipeit_session
COOKIE_DOMAIN=null
SECURE_COOKIES=false
REFERRER_POLICY=strict-origin
# --------------------------------------------
+3 -3
View File
@@ -1,5 +1,5 @@
[![Build Status](https://travis-ci.org/snipe/snipe-it.svg?branch=develop)](https://travis-ci.org/snipe/snipe-it) [![Stories in Ready](https://badge.waffle.io/snipe/snipe-it.png?label=ready+for+dev&title=Ready+for+development)](http://waffle.io/snipe/snipe-it) [![Maintenance](https://img.shields.io/maintenance/yes/2017.svg)]() [![Crowdin](https://d322cqt584bo4o.cloudfront.net/snipe-it/localized.png)](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/snipeyhead.svg?style=social)](https://twitter.com/snipeyhead) [![Zenhub](https://raw.githubusercontent.com/ZenHubIO/support/master/zenhub-badge.png)](https://zenhub.io) [![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-79-orange.svg?style=flat-square)](#contributors)
[![All Contributors](https://img.shields.io/badge/all_contributors-81-orange.svg?style=flat-square)](#contributors)
## Snipe-IT - Open Source Asset Management System
@@ -67,7 +67,7 @@ Thanks goes to all of these wonderful people ([emoji key](https://github.com/ken
| [<img src="https://avatars0.githubusercontent.com/u/8341172?v=3" width="110px;"/><br /><sub>Jay Richards</sub>](http://www.cordeos.com)<br />[💻](https://github.com/snipe/snipe-it/commits?author=technogenus "Code") | [<img src="https://avatars2.githubusercontent.com/u/7295127?v=3" width="110px;"/><br /><sub>Alexander Innes</sub>](https://necurity.co.uk)<br />[💻](https://github.com/snipe/snipe-it/commits?author=leostat "Code") | [<img src="https://avatars2.githubusercontent.com/u/334485?v=3" width="110px;"/><br /><sub>Danny Garcia</sub>](https://buzzedword.codes)<br />[💻](https://github.com/snipe/snipe-it/commits?author=buzzedword "Code") | [<img src="https://avatars2.githubusercontent.com/u/366855?v=3" width="110px;"/><br /><sub>archpoint</sub>](https://github.com/archpoint)<br />[💻](https://github.com/snipe/snipe-it/commits?author=archpoint "Code") | [<img src="https://avatars1.githubusercontent.com/u/67991?v=3" width="110px;"/><br /><sub>Jake McGraw</sub>](http://www.jakemcgraw.com)<br />[💻](https://github.com/snipe/snipe-it/commits?author=jakemcgraw "Code") | [<img src="https://avatars1.githubusercontent.com/u/1714374?v=3" width="110px;"/><br /><sub>FleischKarussel</sub>](https://github.com/FleischKarussel)<br />[📖](https://github.com/snipe/snipe-it/commits?author=FleischKarussel "Documentation") | [<img src="https://avatars3.githubusercontent.com/u/319644?v=3" width="110px;"/><br /><sub>Dylan Yi</sub>](https://github.com/feeva)<br />[💻](https://github.com/snipe/snipe-it/commits?author=feeva "Code") |
| [<img src="https://avatars2.githubusercontent.com/u/857740?v=3" width="110px;"/><br /><sub>Gil Rutkowski</sub>](http://FlashingCursor.com)<br />[💻](https://github.com/snipe/snipe-it/commits?author=flashingcursor "Code") | [<img src="https://avatars3.githubusercontent.com/u/129360?v=3" width="110px;"/><br /><sub>Desmond Morris</sub>](http://www.desmondmorris.com)<br />[💻](https://github.com/snipe/snipe-it/commits?author=desmondmorris "Code") | [<img src="https://avatars2.githubusercontent.com/u/52936?v=3" width="110px;"/><br /><sub>Nick Peelman</sub>](http://peelman.us)<br />[💻](https://github.com/snipe/snipe-it/commits?author=peelman "Code") | [<img src="https://avatars0.githubusercontent.com/u/53161?v=3" width="110px;"/><br /><sub>Abraham Vegh</sub>](https://abrahamvegh.com)<br />[💻](https://github.com/snipe/snipe-it/commits?author=abrahamvegh "Code") | [<img src="https://avatars0.githubusercontent.com/u/2818680?v=3" width="110px;"/><br /><sub>Mohamed Rashid</sub>](https://github.com/rashivkp)<br />[📖](https://github.com/snipe/snipe-it/commits?author=rashivkp "Documentation") | [<img src="https://avatars3.githubusercontent.com/u/1509456?v=3" width="110px;"/><br /><sub>Kasey</sub>](http://hinchk.github.io)<br />[💻](https://github.com/snipe/snipe-it/commits?author=HinchK "Code") | [<img src="https://avatars2.githubusercontent.com/u/10522541?v=3" width="110px;"/><br /><sub>Brett</sub>](https://github.com/BrettFagerlund)<br />[⚠️](https://github.com/snipe/snipe-it/commits?author=BrettFagerlund "Tests") |
| [<img src="https://avatars2.githubusercontent.com/u/16108587?v=3" width="110px;"/><br /><sub>Jason Spriggs</sub>](http://jasonspriggs.com)<br />[💻](https://github.com/snipe/snipe-it/commits?author=jasonspriggs "Code") | [<img src="https://avatars2.githubusercontent.com/u/1134568?v=3" width="110px;"/><br /><sub>Nate Felton</sub>](http://n8felton.wordpress.com)<br />[💻](https://github.com/snipe/snipe-it/commits?author=n8felton "Code") | [<img src="https://avatars2.githubusercontent.com/u/14036694?v=3" width="110px;"/><br /><sub>Manasses Ferreira</sub>](http://homepages.dcc.ufmg.br/~manassesferreira)<br />[💻](https://github.com/snipe/snipe-it/commits?author=manassesferreira "Code") | [<img src="https://avatars0.githubusercontent.com/u/15913949?v=3" width="110px;"/><br /><sub>Steve</sub>](https://github.com/steveelwood)<br />[⚠️](https://github.com/snipe/snipe-it/commits?author=steveelwood "Tests") | [<img src="https://avatars1.githubusercontent.com/u/3361683?v=3" width="110px;"/><br /><sub>matc</sub>](http://twitter.com/matc)<br />[⚠️](https://github.com/snipe/snipe-it/commits?author=matc "Tests") | [<img src="https://avatars3.githubusercontent.com/u/7405702?v=3" width="110px;"/><br /><sub>Cole R. Davis</sub>](http://www.davisracingteam.com)<br />[⚠️](https://github.com/snipe/snipe-it/commits?author=VanillaNinjaD "Tests") | [<img src="https://avatars2.githubusercontent.com/u/10167681?v=3" width="110px;"/><br /><sub>gibsonjoshua55</sub>](https://github.com/gibsonjoshua55)<br />[💻](https://github.com/snipe/snipe-it/commits?author=gibsonjoshua55 "Code") |
| [<img src="https://avatars2.githubusercontent.com/u/2809241?v=4" width="110px;"/><br /><sub>Robin Temme</sub>](https://github.com/zwerch)<br />[💻](https://github.com/snipe/snipe-it/commits?author=zwerch "Code") | [<img src="https://avatars0.githubusercontent.com/u/6961695?v=4" width="110px;"/><br /><sub>Iman</sub>](https://github.com/imanghafoori1)<br />[💻](https://github.com/snipe/snipe-it/commits?author=imanghafoori1 "Code") |
| [<img src="https://avatars2.githubusercontent.com/u/2809241?v=4" width="110px;"/><br /><sub>Robin Temme</sub>](https://github.com/zwerch)<br />[💻](https://github.com/snipe/snipe-it/commits?author=zwerch "Code") | [<img src="https://avatars0.githubusercontent.com/u/6961695?v=4" width="110px;"/><br /><sub>Iman</sub>](https://github.com/imanghafoori1)<br />[💻](https://github.com/snipe/snipe-it/commits?author=imanghafoori1 "Code") | [<img src="https://avatars1.githubusercontent.com/u/6551003?v=4" width="110px;"/><br /><sub>Richard Hofman</sub>](https://github.com/richardhofman6)<br />[💻](https://github.com/snipe/snipe-it/commits?author=richardhofman6 "Code") | [<img src="https://avatars0.githubusercontent.com/u/3697569?v=4" width="110px;"/><br /><sub>gizzmojr</sub>](https://github.com/gizzmojr)<br />[💻](https://github.com/snipe/snipe-it/commits?author=gizzmojr "Code") |
<!-- ALL-CONTRIBUTORS-LIST:END -->
This project follows the [all-contributors](https://github.com/kentcdodds/all-contributors) specification. Contributions of any kind welcome!
@@ -76,7 +76,7 @@ This project follows the [all-contributors](https://github.com/kentcdodds/all-co
### Contributing
Please see the documentation on [contributing and developing for Snipe-IT](https://snipe-it.readme.io/docs/contributing).
Please see the documentation on [contributing and developing for Snipe-IT](https://snipe-it.readme.io/docs/contributing-overview).
Please note that this project is released with a [Contributor Code of Conduct](CODE_OF_CONDUCT.md). By participating in this project you agree to abide by its terms.
@@ -274,7 +274,7 @@ class AccessoriesController extends Controller
$data['note'] = $logaction->note;
$data['require_acceptance'] = $accessory->requireAcceptance();
// TODO: Port this to new mail notifications
if (($accessory->requireAcceptance()=='1') || ($accessory->getEula())) {
if ((($accessory->requireAcceptance()=='1') || ($accessory->getEula())) && ($user->email!='')) {
Mail::send('emails.accept-accessory', $data, function ($m) use ($user) {
$m->to($user->email, $user->first_name . ' ' . $user->last_name);
@@ -351,7 +351,7 @@ class AccessoriesController extends Controller
$data['item_tag'] = '';
$data['note'] = e($logaction->note);
if (($accessory->checkin_email()=='1')) {
if ((($accessory->checkin_email()=='1')) && ($user->email!='')) {
Mail::send('emails.checkin-asset', $data, function ($m) use ($user) {
$m->to($user->email, $user->first_name . ' ' . $user->last_name);
@@ -129,9 +129,8 @@ class AccessoriesController extends Controller
{
$this->authorize('view', Accessory::class);
$accessory = Accessory::findOrFail($id)->with('users')->first();
$accessories_users = $accessory->users;
$total = $accessories_users->count();
return (new AccessoriesTransformer)->transformCheckedoutAccessories($accessories_users, $total);
$total = $accessory->users->count();
return (new AccessoriesTransformer)->transformCheckedoutAccessory($accessory, $total);
}
@@ -73,7 +73,7 @@ class GroupsController extends Controller
{
$this->authorize('view', Group::class);
$group = Group::findOrFail($id);
return $group;
return (new GroupsTransformer)->transformGroup($group);
}
@@ -13,6 +13,7 @@ use Illuminate\Support\Facades\Input;
use Illuminate\Support\Facades\Session;
use League\Csv\Reader;
use Symfony\Component\HttpFoundation\File\Exception\FileException;
use Artisan;
class ImportController extends Controller
{
@@ -94,6 +95,8 @@ class ImportController extends Controller
public function process(ItemImportRequest $request, $import_id)
{
$this->authorize('create', Asset::class);
// Run a backup immediately before processing
Artisan::call('backup:run');
$errors = $request->import(Import::find($import_id));
$redirectTo = "hardware.index";
switch ($request->get('import-type')) {
@@ -82,7 +82,7 @@ class AssetModelsController extends Controller
$model->manufacturer_id = $request->input('manufacturer_id');
$model->category_id = $request->input('category_id');
$model->notes = $request->input('notes');
$model->user_id = Auth::guard('api')->user();
$model->user_id = Auth::id();
$model->requestable = Input::has('requestable');
if ($request->input('custom_fieldset')!='') {
+2 -2
View File
@@ -380,7 +380,7 @@ class AssetsController extends Controller
if ($asset->save()) {
// Redirect to the new asset page
\Session::flash('success', trans('admin/hardware/message.update.success'));
return response()->json(['redirect_url' => route("view/hardware", $assetId)]);
return response()->json(['redirect_url' => route("hardware.show", $assetId)]);
}
\Input::flash();
\Session::flash('errors', $asset->getErrors());
@@ -1230,7 +1230,7 @@ class AssetsController extends Controller
foreach ($asset_ids as $asset_id) {
$asset = Asset::find($asset_id);
$this->authorize('checkout', $asset);
$error = $asset->checkOutToUser($user, $admin, $checkout_at, $expected_checkin, e(Input::get('note')), null);
$error = $asset->checkOut($user, $admin, $checkout_at, $expected_checkin, e(Input::get('note')), null);
if ($error) {
array_merge_recursive($errors, $asset->getErrors()->toArray());
@@ -0,0 +1,15 @@
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\ResetsPasswords;
class RegisterController extends Controller
{
public function __construct()
{
$this->middleware('guest');
}
}
@@ -25,7 +25,7 @@ class ResetPasswordController extends Controller
*
* @var string
*/
protected $redirectTo = '/home';
protected $redirectTo = '/';
/**
* Create a new controller instance.
+11 -11
View File
@@ -74,20 +74,20 @@ class ComponentsController extends Controller
* @since [v3.0]
* @return \Illuminate\Http\RedirectResponse
*/
public function store()
public function store(Request $request)
{
$this->authorize('create', Component::class);
$component = new Component();
$component->name = Input::get('name');
$component->category_id = Input::get('category_id');
$component->location_id = Input::get('location_id');
$component->company_id = Company::getIdForCurrentUser(Input::get('company_id'));
$component->order_number = Input::get('order_number');
$component->min_amt = Input::get('min_amt');
$component->serial = Input::get('serial');
$component->purchase_date = Input::get('purchase_date');
$component->purchase_cost = request('purchase_cost');
$component->qty = Input::get('qty');
$component->name = $request->input('name');
$component->category_id = $request->input('category_id');
$component->location_id = $request->input('location_id');
$component->company_id = Company::getIdForCurrentUser($request->input('company_id'));
$component->order_number = $request->input('order_number', null);
$component->min_amt = $request->input('min_amt', null);
$component->serial = $request->input('serial', null);
$component->purchase_date = $request->input('purchase_date', null);
$component->purchase_cost = $request->input('purchase_cost', null);
$component->qty = $request->input('qty');
$component->user_id = Auth::id();
if ($component->save()) {
@@ -37,19 +37,25 @@ class CustomFieldsetsController extends Controller
public function show($id)
{
$cfset = CustomFieldset::with('fields')->where('id', '=', $id)->orderBy('id', 'ASC')->first();
$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 ($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]);
}
}
return view("custom_fields.fieldsets.view")->with("custom_fieldset", $cfset)->with("maxid", $maxid+1)->with("custom_fields_list", $custom_fields_list);
}
return view("custom_fields.fieldsets.view")->with("custom_fieldset", $cfset)->with("maxid", $maxid+1)->with("custom_fields_list", $custom_fields_list);
return redirect()->route("fields.index")->with("error", trans('admin/custom_fields/message.fieldset.does_not_exist'));
}
@@ -133,16 +139,21 @@ class CustomFieldsetsController extends Controller
*/
public function destroy($id)
{
//
$fieldset = CustomFieldset::find($id);
$models = AssetModel::where("fieldset_id", "=", $id);
if ($models->count() == 0) {
$fieldset->delete();
return redirect()->route("fields.show")->with("success", trans('admin/custom_fields/message.fieldset.delete.success'));
} else {
return redirect()->route("fields.show")->with("error", trans('admin/custom_fields/message.fieldset.delete.in_use'));
if ($fieldset) {
$models = AssetModel::where("fieldset_id", "=", $id);
if ($models->count() == 0) {
$fieldset->delete();
return redirect()->route("fields.index")->with("success", trans('admin/custom_fields/message.fieldset.delete.success'));
} else {
return redirect()->route("fields.index")->with("error", trans('admin/custom_fields/message.fieldset.delete.in_use'));
}
}
return redirect()->route("fields.index")->with("error", trans('admin/custom_fields/message.fieldset.does_not_exist'));
}
+3 -3
View File
@@ -279,7 +279,7 @@ class LicensesController extends Controller
// Declare the rules for the form validation
$rules = [
'note' => 'string',
'note' => 'string|nullable',
'asset_id' => 'required_without:assigned_to',
];
@@ -306,8 +306,8 @@ class LicensesController extends Controller
return redirect()->route('licenses.index')->with('error', trans('admin/licenses/message.asset_does_not_exist'));
}
if (($target->assigned_to!='') && (($target->assigned_to!=$assigned_to)) && ($target!='')) {
return redirect()->route('licenses.index')->with('error', trans('admin/licenses/message.owner_doesnt_match_asset'));
if (($request->has('assigned_to')) && ($request->has('asset_id'))) {
return redirect()->back()->withInput()->with('error', trans('admin/licenses/message.select_asset_or_person'));
}
}
+6 -1
View File
@@ -338,7 +338,10 @@ class SettingsController extends Controller
$setting->email_format = $request->input('email_format');
$setting->username_format = $request->input('username_format');
$setting->require_accept_signature = $request->input('require_accept_signature');
$setting->login_note = $request->input('login_note');
if (!config('app.lock_passwords')) {
$setting->login_note = $request->input('login_note');
}
$setting->default_eula_text = $request->input('default_eula_text');
$setting->thumbnail_max_h = $request->input('thumbnail_max_h');
@@ -992,6 +995,8 @@ class SettingsController extends Controller
{
if (!config('app.lock_passwords')) {
if (Input::get('confirm_purge')=='DELETE') {
// Run a backup immediately before processing
Artisan::call('backup:run');
Artisan::call('snipeit:purge', ['--force'=>'true','--no-interaction'=>true]);
$output = Artisan::output();
return view('settings/purge')
+5
View File
@@ -376,6 +376,11 @@ class UsersController extends Controller
return redirect()->route('users.index')->with('error', 'This user still has ' . $user->assets()->count() . ' assets associated with them.');
}
if (count($user->assets) > 0) {
// Redirect to the user management page
return redirect()->route('users.index')->with('error', 'This user still has ' . count($user->assets) . ' assets associated with them.');
}
if ($user->licenses()->count() > 0) {
// Redirect to the user management page
return redirect()->route('users.index')->with('error', 'This user still has ' . $user->assets()->count() . ' assets associated with them.');
+2
View File
@@ -19,10 +19,12 @@ class Kernel extends HttpKernel
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\App\Http\Middleware\FrameGuard::class,
\App\Http\Middleware\XssProtectHeader::class,
\App\Http\Middleware\ReferrerPolicyHeader::class,
\App\Http\Middleware\NosniffGuard::class,
\App\Http\Middleware\CheckForSetup::class,
\Fideloper\Proxy\TrustProxies::class,
\App\Http\Middleware\CheckForDebug::class,
\Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
];
/**
@@ -0,0 +1,21 @@
<?php
namespace App\Http\Middleware;
use Closure;
class ReferrerPolicyHeader
{
/**
* Handle the given request and get the response.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return \Illuminate\Http\Response
*/
public function handle($request, Closure $next)
{
$response = $next($request);
$response->headers->set('Referrer-Policy', config('app.referrer_policy'));
return $response;
}
}
+2 -1
View File
@@ -14,8 +14,9 @@ class XssProtectHeader
*/
public function handle($request, Closure $next)
{
$mode = '1;mode=block';
$response = $next($request);
$response->headers->set('X-XSS-Protection', '1');
$response->headers->set('X-XSS-Protection', $mode);
return $response;
}
}
@@ -59,13 +59,30 @@ class AccessoriesTransformer
}
public function transformCheckedoutAccessories (Collection $accessories_users, $total)
public function transformCheckedoutAccessory (Accessory $accessory, $total)
{
$array = array();
foreach ($accessories_users as $user) {
$array[] = (new UsersTransformer)->transformUser($user);
foreach ($accessory->users as $user) {
$array[] = [
'assigned_pivot_id' => $user->pivot->id,
'id' => (int) $user->id,
'username' => e($user->username),
'name' => e($user->getFullNameAttribute()),
'first_name'=> e($user->first_name),
'last_name'=> e($user->last_name),
'employee_number' => e($user->employee_num),
'type' => 'user',
'available_actions' => ['checkin' => true]
];
}
return (new DatatablesTransformer)->transformDatatables($array, $total);
}
@@ -52,7 +52,8 @@ class ActionlogsTransformer
'type' => e($actionlog->targetType()),
] : null,
'note' => e($actionlog->note),
'note' => ($actionlog->note) ? e($actionlog->note): null,
'signature_file' => ($actionlog->accept_signature) ? route('log.signature.view', ['filename' => $actionlog->accept_signature ]) : null,
];
+4 -2
View File
@@ -33,7 +33,8 @@ class AssetsTransformer
'model_number' => ($asset->model) ? e($asset->model->model_number) : null,
'status_label' => ($asset->assetstatus) ? [
'id' => (int) $asset->assetstatus->id,
'name'=> e($asset->assetstatus->name)
'name'=> e($asset->assetstatus->name),
'status_type' => e($asset->assetstatus->getStatuslabelType()),
] : null,
'category' => ($asset->model->category) ? [
'id' => (int) $asset->model->category->id,
@@ -75,8 +76,9 @@ class AssetsTransformer
];
if ($asset->model->fieldset) {
if (($asset->model->fieldset) && (count($asset->model->fieldset->fields)> 0)) {
$fields_array = array();
foreach ($asset->model->fieldset->fields as $field) {
if ($field->isFieldDecryptable($asset->{$field->convertUnicodeDbSlug()})) {
+1 -1
View File
@@ -23,7 +23,7 @@ class GroupsTransformer
$array = [
'id' => (int) $group->id,
'name' => e($group->name),
'permissions' => $group->permissions,
'permissions' => json_decode($group->permissions),
'users_count' => (int) $group->users_count,
'created_at' => Helper::getFormattedDateObject($group->created_at, 'datetime'),
'updated_at' => Helper::getFormattedDateObject($group->updated_at, 'datetime'),
@@ -33,8 +33,9 @@ class LicensesTransformer
'depreciation' => ($license->depreciation) ? ['id' => (int) $license->depreciation->id,'name'=> e($license->depreciation->name)] : null,
'notes' => e($license->notes),
'expiration_date' => Helper::getFormattedDateObject($license->expiration_date, 'date'),
'total_seats' => (int) $license->total_seats,
'remaining_qty' => $license->remaincount(),
'total_seats' => (int) $license->seats,
'next_seat' => ($license->freeSeat()) ? (int) $license->freeSeat()->id : null,
'remaining_qty' => (int) $license->remaincount(),
'min_qty' => $license->remaincount(),
'license_name' => e($license->license_name),
'license_email' => e($license->license_email),
@@ -36,9 +36,11 @@ class LocationsTransformer
'address' => e($location->address),
'city' => e($location->city),
'state' => e($location->state),
'country' => e($location->country),
'zip' => e($location->zip),
'assets_checkedout' => $location->assets()->count(),
'assets_default' => $location->assignedassets()->count(),
'country' => e($location->country),
'created_at' => Helper::getFormattedDateObject($location->created_at, 'datetime'),
'updated_at' => Helper::getFormattedDateObject($location->updated_at, 'datetime'),
'parent' => ($location->parent) ? [
+27 -27
View File
@@ -262,11 +262,12 @@ class Asset extends Depreciable
return $this->assignedTo();
}
if ($this->assignedType() == self::USER) {
if (!$this->assignedTo) {
return $this->defaultLoc();
}
return $this->assignedTo->userLoc();
}
if (!$this->assignedTo) {
return $this->defaultLoc();
}
}
return $this->defaultLoc();
}
@@ -724,7 +725,8 @@ class Asset extends Depreciable
/**
* Query builder scope to search on text for complex Bootstrap Tables API
* Query builder scope to search on text for complex Bootstrap Tables API.
* This is really horrible, but I can't think of a less-awful way to do it.
*
* @param \Illuminate\Database\Query\Builder $query Query builder instance
* @param text $search Search term
@@ -735,7 +737,16 @@ class Asset extends Depreciable
{
$search = explode(' OR ', $search);
return $query->where(function ($query) use ($search) {
return $query->leftJoin('users',function ($leftJoin) {
$leftJoin->on("users.id", "=", "assets.assigned_to")
->where("assets.assigned_type", "=", User::class);
})->leftJoin('locations',function ($leftJoin) {
$leftJoin->on("locations.id","=","assets.assigned_to")
->where("assets.assigned_type","=",Location::class);
})->leftJoin('assets as assigned_assets',function ($leftJoin) {
$leftJoin->on('assigned_assets.id', '=', 'assets.assigned_to')
->where('assets.assigned_type', '=', Asset::class);
})->where(function ($query) use ($search) {
foreach ($search as $search) {
$query->whereHas('model', function ($query) use ($search) {
$query->whereHas('category', function ($query) use ($search) {
@@ -768,26 +779,15 @@ class Asset extends Depreciable
$query->whereHas('defaultLoc', function ($query) use ($search) {
$query->where('locations.name', 'LIKE', '%'.$search.'%');
});
//FIXME: This needs attention to work with checkout to not-users.
// })->orWhere(function ($query) use ($search) {
// $query->whereHas('assignedTo', function ($query) use ($search) {
// $query->where(function ($query) use ($search) {
// $query->where('assets.assigned_type', '=', User::class)
// ->join('users', 'users.id', '=', 'assets.assigned_to')
// ->where(function($query) use ($search) {
// $query->where('users.first_name', 'LIKE', '%'.$search.'%')
// ->orWhere('users.last_name', 'LIKE', '%'.$search.'%');
// });
// })->orWhere(function ($query) use ($search) {
// $query->where('assets.assigned_type', '=', Location::class)
// ->join('locations', 'locations.id', '=', 'assets.assigned_to')
// ->where('locations.name', 'LIKE', '%'.$search.'%');
// })->orWhere(function ($query) use ($search) {
// $query->where('assets.assigned_type', '=', Asset::class)
// ->join('assets as assigned_asset', 'assigned_assets.id', '=', 'assets.assigned_to')
// ->where('assigned_assets.name', 'LIKE', '%'.$search.'%');
// });
// });
})->orWhere(function ($query) use ($search) {
$query->whereHas('assignedTo', function ($query) use ($search) {
$query->where('users.first_name', 'LIKE', '%'.$search.'%')
->orWhere('users.last_name', 'LIKE', '%'.$search.'%')
->orWhere('users.username', 'LIKE', '%'.$search.'%')
->orWhere('locations.name', 'LIKE', '%'.$search.'%')
->orWhere('assigned_assets.name', 'LIKE', '%'.$search.'%');
});
})->orWhere('assets.name', 'LIKE', '%'.$search.'%')
->orWhere('assets.asset_tag', 'LIKE', '%'.$search.'%')
->orWhere('assets.serial', 'LIKE', '%'.$search.'%')
@@ -795,9 +795,9 @@ class Asset extends Depreciable
->orWhere('assets.notes', 'LIKE', '%'.$search.'%');
}
foreach (CustomField::all() as $field) {
$query->orWhere($field->db_column_name(), 'LIKE', "%$search%");
$query->orWhere('assets.'.$field->db_column_name(), 'LIKE', "%$search%");
}
});
})->withTrashed()->whereNull("assets.deleted_at"); //workaround for laravel bug
}
+1
View File
@@ -53,6 +53,7 @@ class Component extends SnipeModel
'name',
'purchase_cost',
'purchase_date',
'min_amt',
'qty',
];
+1 -3
View File
@@ -47,9 +47,7 @@ class CustomFieldset extends Model
if (($field->field_encrypted!='1') ||
(($field->field_encrypted =='1') && (Gate::allows('admin')) )) {
if ($field->pivot->required) {
$rule[]="required";
}
$rule[] = ($field->pivot->required=='1') ? "required" : "nullable";
}
array_push($rule, $field->attributes['format']);
+9 -6
View File
@@ -31,10 +31,10 @@ class License extends Depreciable
protected $rules = array(
'name' => 'required|string|min:3|max:255',
'seats' => 'required|min:1|max:1000000|integer',
'license_email' => 'email|min:0|max:120',
'license_name' => 'string|min:0|max:100',
'note' => 'string',
'notes' => 'string|min:0',
'license_email' => 'email|nullable|max:120',
'license_name' => 'string|nullable|max:100',
'note' => 'string|nullable',
'notes' => 'string|nullable',
'company_id' => 'integer|nullable',
);
@@ -332,14 +332,17 @@ class License extends Depreciable
return $this->belongsTo('\App\Models\Supplier', 'supplier_id');
}
/*
* Get the next available free seat - used by
* the API to populate next_seat
*/
public function freeSeat()
{
$seat = LicenseSeat::where('license_id', '=', $this->id)
return $this->licenseseats()
->whereNull('deleted_at')
->whereNull('assigned_to')
->whereNull('asset_id')
->first();
return $seat->id;
}
public static function getExpiringLicenses($days = 60)
+7 -4
View File
@@ -43,20 +43,23 @@ trait Loggable
$log->target_type = get_class($target);
$log->target_id = $target->id;
$class = get_class($target);
if ($class == Location::class) {
$target_class = get_class($target);
// Figure out what the target is
if ($target_class == Location::class) {
// We can checkout to a location
$log->location_id = $target->id;
} else if ($class== Asset::class) {
} elseif ($target_class== Asset::class) {
$log->location_id = $target->rtd_location_id;
} else {
$log->location_id = $target->location_id;
}
$log->note = $note;
$log->logaction('checkout');
$params = [
'item' => $this,
'item' => $log->item,
'target' => $target,
'admin' => $log->user,
'note' => $note,
+19
View File
@@ -77,6 +77,25 @@ class SnipeModel extends Model
return;
}
public function setMinAmtAttribute($value)
{
if ($value == '') {
$value = null;
}
$this->attributes['min_amt'] = $value;
return;
}
public function setParentIdAttribute($value)
{
if ($value == '') {
$value = null;
}
$this->attributes['parent_id'] = $value;
return;
}
//
public function getDisplayNameAttribute()
{
+28 -25
View File
@@ -44,7 +44,9 @@ class CheckoutNotification extends Notification
}
$item = $this->params['item'];
$notifyBy[]='mail';
if (class_basename(get_class($this->params['item']))!='License') {
$notifyBy[] = 'mail';
}
// if ((method_exists($item, 'requireAcceptance') && ($item->requireAcceptance()=='1'))
// || (method_exists($item, 'getEula') && ($item->getEula()))
// ) {
@@ -81,30 +83,31 @@ class CheckoutNotification extends Notification
*/
public function toMail($notifiable)
{
//TODO: Expand for non assets.
$item = $this->params['item'];
$admin_user = $this->params['admin'];
$target = $this->params['target'];
$data = [
'eula' => method_exists($item, 'getEula') ? $item->getEula() : '',
'first_name' => $target->present()->fullName(),
'item_name' => $item->present()->name(),
'checkout_date' => $item->last_checkout,
'expected_checkin' => $item->expected_checkin,
'item_tag' => $item->asset_tag,
'note' => $this->params['note'],
'item_serial' => $item->serial,
'require_acceptance' => $item->requireAcceptance(),
'log_id' => $this->params['log_id'],
];
return (new MailMessage)
->view('emails.accept-asset', $data)
->subject(trans('mail.Confirm_asset_delivery'));
// \Mail::send('emails.accept-asset', $data, function ($m) use ($target) {
// $m->to($target->email, $target->first_name . ' ' . $target->last_name);
// $m->replyTo(config('mail.reply_to.address'), config('mail.reply_to.name'));
// $m->subject(trans('mail.Confirm_asset_delivery'));
// });
//TODO: Expand for non assets.
$item = $this->params['item'];
$admin_user = $this->params['admin'];
$target = $this->params['target'];
$data = [
'eula' => method_exists($item, 'getEula') ? $item->getEula() : '',
'first_name' => $target->present()->fullName(),
'item_name' => $item->present()->name(),
'checkout_date' => $item->last_checkout,
'expected_checkin' => $item->expected_checkin,
'item_tag' => $item->asset_tag,
'note' => $this->params['note'],
'item_serial' => $item->serial,
'require_acceptance' => method_exists($item, 'requireAcceptance') ? $item->requireAcceptance() : '',
'log_id' => $this->params['log_id'],
];
return (new MailMessage)
->view('emails.accept-asset', $data)
->subject(trans('mail.Confirm_asset_delivery'));
}
/**
+10
View File
@@ -146,6 +146,16 @@ class LicensePresenter extends Presenter
return (string)link_to_route('licenses.show', $this->name, $this->id);
}
/**
* Link to this licenses Name
* @return string
*/
public function fullName()
{
return 'poop';
}
/**
* Link to this licenses serial
* @return string
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -1 +1 @@
{"version":3,"file":"css/AdminLTE.css","sources":[],"mappings":";;;;;;","sourceRoot":""}
{"version":3,"file":"css/AdminLTE.css","sources":[],"mappings":";;;;;;A","sourceRoot":""}
+3 -3
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -1 +1 @@
{"version":3,"file":"css/app.css","sources":[],"mappings":";;;;;;;;","sourceRoot":""}
{"version":3,"file":"css/app.css","sources":[],"mappings":";;;;;;;;A","sourceRoot":""}
File diff suppressed because one or more lines are too long
+10 -21
View File
@@ -1,23 +1,12 @@
{
"/build/vue.js": "/build/vue.js",
"/mix.js": "/mix.js",
"/build/app.css": "/build/app.535d8af1016a2377e449920c617f0197.css",
"/build/AdminLTE.css": "/build/AdminLTE.3d8a2b2e33baa060b1b324363ad5e1c2.css",
"/build/overrides.css": "/build/overrides.617623c6a96be3e0cbd11c5d4039ec10.css",
"/css/all.css": "/css/all.css",
"/js/all.js": "/js/all.js",
"/css/app.css": "/css/app.css",
"/css/dist/all.css": "/css/dist/all.css",
"/js/dist/all.js": "/js/dist/all.js",
"/css/AdminLTE.css": "/css/AdminLTE.css",
"/css/overrides.css": "/css/overrides.css",
"/css/skin-blue.css": "/css/skin-blue.css",
"/vue.js": "/vue.js",
"/vue.js.map": "/vue.js.map",
"/mix.js.map": "/mix.js.map",
"/css/AdminLTE.css.map": "/css/AdminLTE.css.map",
"/css/app.css.map": "/css/app.css.map",
"/css/overrides.css.map": "/css/overrides.css.map",
"public/css/dist/all.css": "public/css/dist/all.css",
"public/js/dist/all.js": "public/js/dist/all.js"
"/vue.js": "/vue.js",
"/css/AdminLTE.css": "/css/AdminLTE.css",
"/css/app.css": "/css/app.css",
"/css/overrides.css": "/css/overrides.css",
"/vue.js.map": "/vue.js.map",
"/css/AdminLTE.css.map": "/css/AdminLTE.css.map",
"/css/app.css.map": "/css/app.css.map",
"/css/overrides.css.map": "/css/overrides.css.map",
"/public/css/dist/all.css": "/public/css/dist/all.css",
"/public/js/dist/all.js": "/public/js/dist/all.js"
}
+1 -63
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
File diff suppressed because one or more lines are too long
+15
View File
@@ -155,6 +155,21 @@ return [
'allow_iframing' => env('ALLOW_IFRAMING', false),
/*
|--------------------------------------------------------------------------
| REFERRER-POLICY
|--------------------------------------------------------------------------
|
| This is an additional security header that browsers use to determine
| whether they should report back URL referrer information.
|
| Read more: https://www.w3.org/TR/referrer-policy/
|
*/
'referrer_policy' => env('REFERRER_POLICY', 'strict-origin'),
/*
|--------------------------------------------------------------------------
| Demo Mode Lockdown
+2 -2
View File
@@ -65,8 +65,8 @@ return [
'database' => env('DB_DATABASE', 'forge'),
'username' => env('DB_USERNAME', 'forge'),
'password' => env('DB_PASSWORD', ''),
'charset' => 'utf8mb4',
'collation' => 'utf8mb4_unicode_ci',
'charset' => env('DB_CHARSET', 'utf8mb4'),
'collation' => env('DB_COLLATION', 'utf8mb4_unicode_ci'),
'prefix' => env('DB_PREFIX', null),
'strict' => false,
'engine' => null,
+2
View File
@@ -22,6 +22,8 @@ return [
base_path('public/uploads'),
base_path('config'),
base_path('storage/private_uploads'),
base_path('storage/oauth-private.key'),
base_path('storage/oauth-public.key'),
],
/*
+4 -4
View File
@@ -1,7 +1,7 @@
<?php
return array (
'app_version' => 'v4.0',
'build_version' => '1',
'hash_version' => 'g998c4a5',
'full_hash' => 'v4.0-1-g998c4a5',
'app_version' => 'v4.0.6',
'build_version' => '47',
'hash_version' => 'g2e76620',
'full_hash' => 'v4.0.6-47-g2e76620',
);
+5 -7
View File
File diff suppressed because one or more lines are too long
+26 -26
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -1,2 +1,2 @@
User-agent: *
Disallow:
Disallow: /
@@ -67,7 +67,7 @@ tr {
<script>
export default {
props: ['file'],
props: ['file', 'customFieldUrl', 'importProcessUrl'],
data() {
return {
activeFile: this.file,
@@ -142,6 +142,12 @@ tr {
this.populateSelect2ActiveItems();
},
computed: {
processUrl() {
// Because we need to pass a parameter to the laravel route function
// We get a url 'http://localhost/api/v1/imports/process/DUMMYTEXT'
// But we want to customize that to /api/v1/imports/process/this_file
return this.importProcessUrl.replace('DUMMYTEXT', this.file.id)
},
columns() {
switch(this.options.importType) {
case 'asset':
@@ -156,7 +162,7 @@ tr {
},
methods: {
fetchCustomFields() {
this.$http.get('/api/v1/fields')
this.$http.get(this.customFieldUrl)
.then( ({data}) => {
data = data.rows;
data.forEach((item) => {
@@ -169,22 +175,22 @@ tr {
},
postSave() {
this.statusText = "Processing...";
this.$http.post('/api/v1/imports/process/'+this.file.id, {
this.$http.post(this.processUrl, {
'import-update': this.options.update,
'import-type': this.options.importType,
'column-mappings': this.columnMappings
}).then( (response) => {
}).then( ({body}) => {
// Success
this.statusText = "Success... Redirecting.";
window.location.href = response.body.messages.redirect_url;
}, (response) => {
window.location.href = body.messages.redirect_url;
}, ({body}) => {
// Failure
if(response.body.status == 'import-errors') {
window.eventHub.$emit('importErrors', response.body.messages);
if(body.status == 'import-errors') {
window.eventHub.$emit('importErrors', body.messages);
this.statusText = "Error";
} else {
this.$emit('alert', {
message: response.body.messages,
message: body.messages,
type: "danger",
visible: true,
})
@@ -11,6 +11,8 @@ th {
<script>
require('blueimp-file-upload');
export default {
props: ['importUrl'],
/*
* The component's data.
*/
@@ -72,7 +74,7 @@ th {
methods: {
fetchFiles() {
this.$http.get('/api/v1/imports')
this.$http.get(this.importUrl)
.then( ({data}) => this.files = data, // Success
//Fail
(response) => {
@@ -82,7 +84,7 @@ th {
});
},
deleteFile(file, key) {
this.$http.delete("/api/v1/imports/"+file.id)
this.$http.delete(this.importUrl+"/"+file.id)
.then((response) => this.files.splice(key, 1), // Success, remove file from array.
(response) => {// Fail
this.alert.type="danger";
@@ -7,6 +7,7 @@ return array(
'asset_does_not_exist' => 'The asset you are trying to associate with this license does not exist.',
'owner_doesnt_match_asset' => 'The asset you are trying to associate with this license is owned by somene other than the person selected in the assigned to dropdown.',
'assoc_users' => 'This license is currently checked out to a user and cannot be deleted. Please check the license in first, and then try deleting again. ',
'select_asset_or_person' => 'You must select an asset or a user, but not both.',
'create' => array(
+61 -44
View File
@@ -2,59 +2,76 @@
{{-- Page title --}}
@section('title')
{{ trans('admin/hardware/general.checkin') }}
{{ trans('admin/accessories/general.checkin') }}
@parent
@stop
@section('header_right')
<a href="{{ URL::previous() }}" class="btn btn-primary pull-right">
{{ trans('general.back') }}</a>
@stop
{{-- Page content --}}
@section('content')
<div class="row header">
<div class="col-md-12">
<a href="{{ URL::previous() }}" class="btn-flat gray pull-right"><i class="fa fa-arrow-left icon-white"></i> {{ trans('general.back') }}</a>
<h3> {{ trans('general.checkin') }}</h3>
</div>
</div>
<div class="row form-wrapper">
<!-- left column -->
<div class="col-md-10 column">
<form class="form-horizontal" method="post" action="" autocomplete="off">
<!-- CSRF Token -->
<input type="hidden" name="_token" value="{{ csrf_token() }}" />
<div class="row">
<div class="col-md-9">
<form class="form-horizontal" method="post" action="" autocomplete="off">
<!-- CSRF Token -->
<input type="hidden" name="_token" value="{{ csrf_token() }}" />
@if ($accessory->name)
<!-- accessory name -->
<div class="form-group">
<label class="col-sm-2 control-label">{{ trans('admin/hardware/form.name') }}</label>
<div class="col-md-6">
<p class="form-control-static">{{ $accessory->name }}</p>
</div>
</div>
@endif
<div class="box box-default">
@if ($accessory->id)
<div class="box-header with-border">
<h3 class="box-title">{{ $accessory->name }}</h3>
</div><!-- /.box-header -->
@endif
<!-- Note -->
<div class="form-group {{ $errors->has('note') ? 'error' : '' }}">
<label for="note" class="col-md-2 control-label">{{ trans('admin/hardware/form.notes') }}</label>
<div class="col-md-7">
<textarea class="col-md-6 form-control" id="note" name="note">
{{ Input::old('note', $accessory->note) }}
</textarea>
{!! $errors->first('note', '<span class="alert-msg"><i class="fa fa-times"></i> :message</span>') !!}
</div>
</div>
<!-- Form actions -->
<div class="form-group">
<label class="col-md-2 control-label"></label>
<div class="col-md-7">
<a class="btn btn-link" href="{{ URL::previous() }}">{{ trans('button.cancel') }}</a>
<button type="submit" class="btn btn-success"><i class="fa fa-check icon-white"></i>{{ trans('general.checkin') }}</button>
<div class="box-body">
<form class="form-horizontal" method="post" action="" autocomplete="off">
<!-- CSRF Token -->
<input type="hidden" name="_token" value="{{ csrf_token() }}" />
@if ($accessory->name)
<!-- accessory name -->
<div class="form-group">
<label class="col-sm-2 control-label">{{ trans('admin/hardware/form.name') }}</label>
<div class="col-md-6">
<p class="form-control-static">{{ $accessory->name }}</p>
</div>
</div>
@endif
<!-- Note -->
<div class="form-group {{ $errors->has('note') ? 'error' : '' }}">
<label for="note" class="col-md-2 control-label">{{ trans('admin/hardware/form.notes') }}</label>
<div class="col-md-7">
<textarea class="col-md-6 form-control" id="note" name="note">
{{ Input::old('note', $accessory->note) }}
</textarea>
{!! $errors->first('note', '<span class="alert-msg"><i class="fa fa-times"></i> :message</span>') !!}
</div>
</div>
<!-- Form actions -->
<div class="form-group">
<label class="col-md-2 control-label"></label>
<div class="col-md-7">
<a class="btn btn-link" href="{{ URL::previous() }}">{{ trans('button.cancel') }}</a>
<button type="submit" class="btn btn-success"><i class="fa fa-check icon-white"></i>{{ trans('general.checkin') }}</button>
</div>
</div>
</form>
</div>
</div>
</form>
</div> <!-- .col-md-10.column -->
</div> <!-- .row.form-wrapper -->
<div class="box-footer text-right">
<button type="submit" class="btn btn-success"><i class="fa fa-check icon-white"></i> {{ trans('general.save') }}</button>
</div>
</div> <!-- .box.box-default -->
</form>
</div> <!-- .col-md-9-->
</div> <!-- .row -->
@stop
@@ -2,7 +2,7 @@
{{-- Page title --}}
@section('title')
{{ trans('admin/hardware/general.checkout') }}
{{ trans('admin/accessories/general.checkout') }}
@parent
@stop
@section('header_right')
+3 -3
View File
@@ -57,15 +57,15 @@
name="accessory_users"
class="table table-striped snipe-table"
id="table"
data-url="{{ route('api.accessories.show', $accessory->id) }}"
data-url="{{ route('api.accessories.checkedout', $accessory->id) }}"
data-cookie="true"
data-click-to-select="true"
data-cookie-id-table="accessoryUsersTable"
>
<thead>
<tr>
<th data-switchable="false" data-searchable="false" data-formatter="userLinkObjFormatter" data-sortable="false" data-field="name">{{ trans('general.user') }}</th>
<th data-switchable="false" data-searchable="false" data-sortable="false" data-field="actions">{{ trans('table.actions') }}</th>
<th data-switchable="false" data-searchable="false" data-formatter="usersLinkFormatter" data-sortable="false" data-field="name">{{ trans('general.user') }}</th>
<th data-switchable="false" data-searchable="false" data-sortable="false" data-field="actions" data-formatter="accessoriesInOutFormatter">{{ trans('table.actions') }}</th>
</tr>
</thead>
</table>
+1 -1
View File
@@ -59,7 +59,7 @@
<button class="btn btn-lg btn-primary btn-block">{{ trans('auth/general.login') }}</button>
</div>
<div class="col-md-12 col-sm-12 col-xs-12 text-right" style="padding-top: 10px;">
<a href="{{ url('/') }}/password/reset">{{ trans('auth/general.forgot_password') }}</a>
<a href="{{ route('password.request') }}">{{ trans('auth/general.forgot_password') }}</a>
</div>
</div> <!-- end login box -->
+3 -2
View File
@@ -7,7 +7,8 @@
@stop
@section('header_right')
<a href="{{ route('groups.create') }}" class="btn btn-primary pull-right"> {{ trans('general.create') }}</a>
<a href="{{ route('groups.create') }}" class="btn btn-primary pull-right" style="margin-left: 10px;"> {{ trans('general.create') }}</a>
<a href="{{ route('settings.index') }}" class="btn btn-default pull-right">{{ trans('general.back') }}</a>
@stop
@@ -32,7 +33,7 @@
<th data-switchable="true" data-sortable="false" data-field="id" data-visible="false">{{ trans('general.id') }}</th>
<th data-switchable="true" data-sortable="true" data-field="name" data-visible="true">{{ trans('admin/groups/table.name') }}</th>
<th data-switchable="true" data-sortable="false" data-field="users_count" data-visible="true">{{ trans('admin/groups/table.users') }}</th>
<th data-switchable="true" data-sortable="true" data-field="created_at" data-visible="true" data-formatter="createdAtFormatter">{{ trans('general.created_at') }}</th>
<th data-switchable="true" data-sortable="true" data-field="created_at" data-visible="true" data-formatter="dateDisplayFormatter">{{ trans('general.created_at') }}</th>
<th data-switchable="false" data-searchable="false" data-sortable="false" data-field="actions" data-formatter="groupsActionsFormatter">{{ trans('table.actions') }}</th>
</tr>
</thead>
@@ -82,13 +82,14 @@
{!! $errors->first('selected_asset', '<span class="alert-msg"><i class="fa fa-times"></i> :message</span>') !!}
</div>
</div>
</form>
</div> <!--./box-body-->
<div class="box-footer">
<a class="btn btn-link" href="{{ URL::previous() }}"> {{ trans('button.cancel') }}</a>
<button type="submit" class="btn btn-success pull-right"><i class="fa fa-check icon-white"></i> {{ trans('general.checkout') }}</button>
</div>
</div>
</form>
</div> <!--/.col-md-7-->
<!-- right column -->
+1 -1
View File
@@ -152,7 +152,7 @@
} else {
handleAuditFail(data);
}
$('input#asset_tag').val('');
},
error: function (data) {
handleAuditFail(data);
+5 -2
View File
@@ -87,8 +87,8 @@
&nbsp; &nbsp;</span>
</span>
@endif
{{ $asset->present()->statusText() }}
({{ $asset->assetstatus->getStatuslabelType() }})
<a href="{{ route('statuslabels.show', $asset->assetstatus->id) }}">{{ $asset->present()->statusText() }}</a>
<label class="label label-default">{{ $asset->assetstatus->getStatuslabelType() }}</label>
</td>
</tr>
@endif
@@ -603,6 +603,9 @@
<th class="col-sm-2" data-field="item" data-formatter="polymorphicItemFormatter">{{ trans('general.item') }}</th>
<th class="col-sm-2" data-field="target" data-formatter="polymorphicItemFormatter">{{ trans('general.target') }}</th>
<th class="col-sm-2" data-field="note">{{ trans('general.notes') }}</th>
@if ($snipeSettings->require_accept_signature=='1')
<th class="col-md-3" data-field="signature_file" data-formatter="imageFormatter">{{ trans('general.signature') }}</th>
@endif
</tr>
</thead>
</table>
+7 -2
View File
@@ -16,7 +16,7 @@
{{-- Page content --}}
@section('content')
<div id="app">
<importer inline-template v-cloak>
<importer inline-template import-url="{{route('api.imports.index')}}" v-cloak>
<div class="row">
<alert v-show="alert.visible" :alert-type="alert.type" v-on:hide="alert.visible = false">@{{ alert.message }}</alert>
<errors :errors="importErrors"></errors>
@@ -62,7 +62,12 @@
<button class="btn btn-danger" @click="deleteFile(currentFile)"><i class="fa fa-trash icon-white"></i></button>
</td>
</tr>
<import-file :key="currentFile.id" :file="currentFile" @alert="updateAlert(alert)">
<import-file
:key="currentFile.id"
:file="currentFile"
customFieldUrl="{{route('api.customfields.index')}}"
importProcessUrl="{{route('api.imports.importFile','DUMMYTEXT')}}"
@alert="updateAlert(alert)">
</import-file>
</template>
</tbody>
+2 -2
View File
@@ -10,9 +10,9 @@
<!-- Select2 -->
<link rel="stylesheet" href="{{ asset('js/plugins/select2/select2.min.css') }}">
<link rel="stylesheet" href="{{ url(asset('js/plugins/select2/select2.min.css')) }}">
<link rel="stylesheet" href="{{ mix('css/dist/all.css') }}">
<link rel="stylesheet" href="{{ url(mix('css/dist/all.css')) }}">
<link rel="shortcut icon" type="image/ico" href="{{ asset('favicon.ico') }}">
+14 -15
View File
@@ -13,17 +13,17 @@
<meta content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" name="viewport">
<!-- Select2 -->
<link rel="stylesheet" href="{{ asset('js/plugins/select2/select2.min.css') }}">
<link rel="stylesheet" href="{{ url(asset('js/plugins/select2/select2.min.css')) }}">
<!-- iCheck for checkboxes and radio inputs -->
<link rel="stylesheet" href="{{ asset('js/plugins/iCheck/all.css') }}">
<link rel="stylesheet" href="{{ url(asset('js/plugins/iCheck/all.css')) }}">
<!-- bootstrap tables CSS -->
<link rel="stylesheet" href="{{ asset('css/bootstrap-table.css') }}">
<link rel="stylesheet" href="{{ url(asset('css/bootstrap-table.css')) }}">
<link rel="stylesheet" href="{{ mix('css/dist/all.css') }}">
<link rel="stylesheet" href="{{ url(mix('css/dist/all.css')) }}">
<link rel="shortcut icon" type="image/ico" href="{{ asset('favicon.ico') }}">
<link rel="shortcut icon" type="image/ico" href="{{ url(asset('favicon.ico')) }}">
<meta name="csrf-token" content="{{ csrf_token() }}">
@@ -83,13 +83,12 @@
<!--[if lt IE 9]>
@if ($snipeSettings->load_remote=='1')
<script src="https://oss.maxcdn.com/html5shiv/3.7.3/html5shiv.min.js"></script>
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
<script src="https://oss.maxcdn.com/html5shiv/3.7.3/html5shiv.min.js" integrity="sha384-qFIkRsVO/J5orlMvxK1sgAt2FXT67og+NyFTITYzvbIP1IJavVEKZM7YWczXkwpB" crossorigin="anonymous"></script>
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js" integrity="sha384-ZoaMbDF+4LeFxg6WdScQ9nnR1QC2MIRxA1O9KWEXQwns1G8UNyIEZIQidzb0T1fo" crossorigin="anonymous"></script>
@else
<script src="{{ asset('js/html5shiv.js') }}"></script>
<script src="{{ asset('js/respond.js') }}"></script>
<script src="{{ url(asset('js/html5shiv.js')) }}"></script>
<script src="{{ url(asset('js/respond.js')) }}"></script>
@endif
<![endif]-->
</head>
@@ -625,11 +624,11 @@
<footer class="main-footer hidden-print">
<div class="pull-right hidden-xs">
<b>Version</b> {{ config('version.app_version') }} build {{ config('version.build_version') }} ({{ config('version.hash_version') }})
<a target="_blank" class="btn btn-default btn-xs" href="https://snipe-it.readme.io/docs/overview">User's Manual</a>
<a target="_blank" class="btn btn-default btn-xs" href="https://snipeitapp.com/support/">Report a Bug</a>
<a target="_blank" class="btn btn-default btn-xs" href="https://snipe-it.readme.io/docs/overview" rel="noopener">User's Manual</a>
<a target="_blank" class="btn btn-default btn-xs" href="https://snipeitapp.com/support/" rel="noopener">Report a Bug</a>
</div>
<a target="_blank" href="https://snipeitapp.com">Snipe-IT</a> is an open source
project, made with <i class="fa fa-heart" style="color: #a94442; font-size: 10px"></i> by <a href="https://twitter.com/snipeyhead">@snipeyhead</a> under the <a href="https://www.gnu.org/licenses/agpl-3.0.en.html">AGPL3 license</a>.
<a target="_blank" href="https://snipeitapp.com" rel="noopener">Snipe-IT</a> is an open source
project, made with <i class="fa fa-heart" style="color: #a94442; font-size: 10px"></i> by <a href="https://twitter.com/snipeyhead" rel="noopener">@snipeyhead</a> under the <a href="https://www.gnu.org/licenses/agpl-3.0.en.html" rel="noopener">AGPL3 license</a>.
</footer>
@@ -662,7 +661,7 @@
<script src="{{ mix('js/dist/all.js') }}"></script>
<script src="{{ url(mix('js/dist/all.js')) }}"></script>
<script>
$(function () {
var datepicker = $.fn.datepicker.noConflict(); // return $.fn.datepicker to previously assigned value
+2 -2
View File
@@ -7,7 +7,7 @@
@show
</title>
<link rel="stylesheet" href="{{ mix('css/dist/all.css') }}">
<link rel="stylesheet" href="{{ url(mix('css/dist/all.css')) }}">
@@ -118,7 +118,7 @@
</div>
</div>
</div>
<script src="{{ asset(mix('js/dist/all.js')) }}"></script>
<script src="{{ url(mix('js/dist/all.js')) }}"></script>
<script>
$(function () {
@@ -139,7 +139,9 @@ $('.snipe-table').bootstrapTable({
// Use this when we're introspecting into a column object and need to link
function genericColumnObjLinkFormatter(destination) {
return function (value,row) {
if ((value) && (value.name)) {
if ((value) && (value.status_type)) {
return '<a href="{{ url('/') }}/' + destination + '/' + value.id + '"> ' + value.name + '</a> ' + '<label class="label label-default">'+ value.status_type + '</label>';
} else if ((value) && (value.name)) {
return '<a href="{{ url('/') }}/' + destination + '/' + value.id + '"> ' + value.name + '</a>';
}
};
@@ -215,15 +217,27 @@ $('.snipe-table').bootstrapTable({
// The user is allowed to check items out, AND the item is deployable
if ((row.available_actions.checkout == true) && (row.user_can_checkout == true) && (!row.assigned_to)) {
return '<a href="{{ url('/') }}/' + destination + '/' + row.id + '/checkout" class="btn btn-sm btn-primary" data-tooltip="true" title="Check this item out to a user">{{ trans('general.checkout') }}</a>';
// case for licenses
if (row.next_seat) {
return '<a href="{{ url('/') }}/' + destination + '/' + row.next_seat + '/checkout" class="btn btn-sm btn-primary" data-tooltip="true" title="Check this item out to a user">{{ trans('general.checkout') }}</a>';
} else {
return '<a href="{{ url('/') }}/' + destination + '/' + row.id + '/checkout" class="btn btn-sm btn-primary" data-tooltip="true" title="Check this item out to a user">{{ trans('general.checkout') }}</a>';
}
// The user is allowed to check items out, but the item is not deployable
} else if (((row.user_can_checkout == false)) && (row.available_actions.checkout == true) && (!row.assigned_to)) {
return '<div data-tooltip="true" title="This item has a status label that is undeployable and cannot be checked out at this time."><a class="btn btn-sm btn-primary disabled">{{ trans('general.checkout') }}</a></div>';
// The user is allowed to check items in
} else if ((row.available_actions.checkin == true) && (row.assigned_to)) {
return '<nobr><a href="{{ url('/') }}/' + destination + '/' + row.id + '/checkin" class="btn btn-sm btn-primary" data-tooltip="true" title="Check this item in so it is available for re-imaging, re-issue, etc.">{{ trans('general.checkin') }}</a>';
} else if (row.available_actions.checkin == true) {
if (row.assigned_to) {
return '<nobr><a href="{{ url('/') }}/' + destination + '/' + row.id + '/checkin" class="btn btn-sm btn-primary" data-tooltip="true" title="Check this item in so it is available for re-imaging, re-issue, etc.">{{ trans('general.checkin') }}</a>';
} else if (row.assigned_pivot_id) {
return '<nobr><a href="{{ url('/') }}/' + destination + '/' + row.assigned_pivot_id + '/checkin" class="btn btn-sm btn-primary" data-tooltip="true" title="Check this item in so it is available for re-imaging, re-issue, etc.">{{ trans('general.checkin') }}</a>';
}
} else {
}
@@ -352,7 +366,7 @@ $('.snipe-table').bootstrapTable({
function imageFormatter(value, row) {
if (value) {
return '<img src="' + value + '" style="max-height: {{ $snipeSettings->thumbnail_max_h }}px; width: auto;">';
return '<a href="' + value + '" data-toggle="lightbox" data-type="image"><img src="' + value + '" style="max-height: {{ $snipeSettings->thumbnail_max_h }}px; width: auto;" class="img-responsive"></a>';
}
}
@@ -41,30 +41,32 @@
$totalCost = 0;
?>
@foreach ($assetMaintenances as $assetMaintenance)
<tr>
<td>{{ is_null($assetMaintenance->asset->company) ? '' : $assetMaintenance->asset->company->name }}</td>
<td>{{ $assetMaintenance->asset->asset_tag }}</td>
<td>{{ $assetMaintenance->asset->name }}</td>
<td>{{ $assetMaintenance->supplier->name }}</td>
<td>{{ $assetMaintenance->asset_maintenance_type }}</td>
<td>{{ $assetMaintenance->title }}</td>
<td>{{ $assetMaintenance->start_date }}</td>
<td>{{ is_null($assetMaintenance->completion_date) ? trans('admin/asset_maintenances/message.asset_maintenance_incomplete') : $assetMaintenance->completion_date }}</td>
@if (is_null($assetMaintenance->asset_maintenance_time))
<?php
$assetMaintenanceTime = intval(Carbon::now()->diffInDays(Carbon::parse($assetMaintenance->start_date)));
?>
@else
<?php
$assetMaintenanceTime = intval($assetMaintenance->asset_maintenance_time);
?>
@endif
<td>{{ $assetMaintenanceTime }}</td>
<td>
{{ $snipeSettings->default_currency }}
{{ number_format($assetMaintenance->cost,2) }}
</td>
</tr>
@if ($assetMaintenance->asset)
<tr>
<td>{{ ($assetMaintenance->asset->company) ? $assetMaintenance->asset->company->name : '' }}</td>
<td>{{ $assetMaintenance->asset->asset_tag }}</td>
<td>{{ $assetMaintenance->asset->name }}</td>
<td>{{ $assetMaintenance->supplier->name }}</td>
<td>{{ $assetMaintenance->asset_maintenance_type }}</td>
<td>{{ $assetMaintenance->title }}</td>
<td>{{ $assetMaintenance->start_date }}</td>
<td>{{ is_null($assetMaintenance->completion_date) ? trans('admin/asset_maintenances/message.asset_maintenance_incomplete') : $assetMaintenance->completion_date }}</td>
@if (is_null($assetMaintenance->asset_maintenance_time))
<?php
$assetMaintenanceTime = intval(Carbon::now()->diffInDays(Carbon::parse($assetMaintenance->start_date)));
?>
@else
<?php
$assetMaintenanceTime = intval($assetMaintenance->asset_maintenance_time);
?>
@endif
<td>{{ $assetMaintenanceTime }}</td>
<td>
{{ $snipeSettings->default_currency }}
{{ number_format($assetMaintenance->cost,2) }}
</td>
</tr>
@endif
<?php
$totalDays += $assetMaintenanceTime;
$totalCost += floatval($assetMaintenance->cost);
+4
View File
@@ -6,6 +6,10 @@
@parent
@stop
@section('header_right')
<a href="{{ route('settings.index') }}" class="btn btn-default pull-right">{{ trans('general.back') }}</a>
@stop
{{-- Page content --}}
@section('content')
@if (!config('app.lock_passwords'))
+2 -2
View File
@@ -165,9 +165,9 @@
{{ Form::label('login_note', trans('admin/settings/general.login_note')) }}
</div>
<div class="col-md-9">
@if (config('app.lock_passwords')===true)
@if (config('app.lock_passwords'))
<textarea class="form-control" name="login_note" placeholder="If you do not have a login or have found a device belonging to this company, please call technical support at 888-555-1212. Thank you." rows="2">{{ Input::old('login_note', $setting->login_note) }}</textarea>
<textarea class="form-control disabled" name="login_note" placeholder="If you do not have a login or have found a device belonging to this company, please call technical support at 888-555-1212. Thank you." rows="2" readonly>{{ Input::old('login_note', $setting->login_note) }}</textarea>
{!! $errors->first('login_note', '<span class="alert-msg">:message</span>') !!}
<p class="help-block">{{ trans('general.lock_passwords') }}</p>
@else
+1 -1
View File
@@ -426,7 +426,7 @@
</td>
<td>
@can('update', $user)
<a class="btn delete-asset btn-danger btn-sm hidden-print" href="{{ route('delete/userfile', [$user->id, $file->id]) }}" data-content="Are you sure you wish to delete this file?" data-title="Delete {{ $file->filename }}?"><i class="fa fa-trash icon-white"></i></a>
<a class="btn delete-asset btn-danger btn-sm hidden-print" href="{{ route('userfile.destroy', [$user->id, $file->id]) }}" data-content="Are you sure you wish to delete this file?" data-title="Delete {{ $file->filename }}?"><i class="fa fa-trash icon-white"></i></a>
@endcan
</td>
</tr>
+1
View File
@@ -459,6 +459,7 @@ Route::group(['middleware' => 'web'], function () {
});
Auth::routes();
+2 -2
View File
@@ -13,9 +13,9 @@ Route::group([ 'prefix' => 'users', 'middleware' => ['auth']], function () {
Route::get('{userId}/restore', [ 'as' => 'restore/user', 'uses' => 'UsersController@getRestore' ]);
Route::get('{userId}/unsuspend', [ 'as' => 'unsuspend/user', 'uses' => 'UsersController@getUnsuspend' ]);
Route::post('{userId}/upload', [ 'as' => 'upload/user', 'uses' => 'UsersController@postUpload' ]);
Route::get(
Route::delete(
'{userId}/deletefile/{fileId}',
[ 'as' => 'delete/userfile', 'uses' => 'UsersController@getDeleteFile' ]
[ 'as' => 'userfile.destroy', 'uses' => 'UsersController@getDeleteFile' ]
);
Route::get(
'{userId}/showfile/{fileId}',
+139
View File
@@ -0,0 +1,139 @@
<?php
(PHP_SAPI !== 'cli' || isset($_SERVER['HTTP_USER_AGENT'])) && die('Access denied.');
$pwu_data = posix_getpwuid(posix_geteuid());
$username = $pwu_data['name'];
if (($username=='root') || ($username=='admin')) {
die("\nERROR: This script should not be run as root/admin. Exiting.\n\n");
}
echo "Welcome to the Snipe-IT upgrader.\n\n";
echo "Please note that this script will not download the latest Snipe-IT \n";
echo "files for you, it simply runs the standard composer and artisan \n";
echo "commands needed to finalize the upgrade after \n\n";
echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! WARNING !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n";
echo "!! If you have any encrypted custom fields, BE SURE TO run the recrypter. \n";
echo "!! See the Snipe-IT documentation for help: \n";
echo "!! https://snipe-it.readme.io/docs/upgrading-to-v4\n";
echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! WARNING !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n";
echo "--------------------------------------------------------\n";
echo "STEP 1: Backing up database: \n";
echo "--------------------------------------------------------\n\n";
$backup = shell_exec('php artisan snipeit:backup');
echo '-- '.$backup."\n\n";
echo "--------------------------------------------------------\n";
echo "STEP 2: Putting application into maintenance mode: \n";
echo "--------------------------------------------------------\n\n";
$down = shell_exec('php artisan down');
echo '-- '.$down."\n\n";
echo "--------------------------------------------------------\n";
echo "Step 3: Cleaning up old cached files:\n";
echo "--------------------------------------------------------\n\n";
if (file_exists('bootstrap/cache/compiled.php')) {
echo "-- Deleting bootstrap/cache/compiled.php. It it no longer used.\n";
@unlink('bootstrap/cache/compiled.php');
} else {
echo "-- No bootstrap/cache/compiled.php, so nothing to delete.\n";
}
if (file_exists('bootstrap/cache/services.php')) {
echo "-- Deleting bootstrap/cache/services.php. It it no longer used.\n";
@unlink('bootstrap/cache/services.php');
} else {
echo "-- No bootstrap/cache/services.php, so nothing to delete.\n";
}
if (file_exists('bootstrap/cache/config.php')) {
echo "-- Deleting bootstrap/cache/config.php. It it no longer used.\n";
@unlink('bootstrap/cache/config.php');
} else {
echo "-- No bootstrap/cache/config.php, so nothing to delete.\n";
}
$config_clear = shell_exec('php artisan config:clear');
$cache_clear = shell_exec('php artisan cache:clear');
$route_clear = shell_exec('php artisan route:clear');
$view_clear = shell_exec('php artisan view:clear');
echo '-- '.$config_clear;
echo '-- '.$cache_clear;
echo '-- '.$route_clear;
echo '-- '.$view_clear;
echo "\n";
echo "--------------------------------------------------------\n";
echo "Step 4: Updating composer dependencies:\n";
echo "(This may take an moment.)\n";
echo "--------------------------------------------------------\n\n";
// Composer install
if (file_exists('composer.phar')) {
echo "-- Local composer.phar detected, so we'll use that.\n\n";
$composer_dump = shell_exec('php composer.phar dump');
$composer = shell_exec('php composer.phar install --prefer-source');
} else {
echo "-- We couldn't find a local composer.phar - trying globally.\n\n";
$composer_dump = shell_exec('composer dump');
$composer = shell_exec('composer install --prefer-source');
}
echo $composer_dump."\n\n";
echo $composer."\n\n";
echo "--------------------------------------------------------\n";
echo "Step 5: Migrating database:\n";
echo "--------------------------------------------------------\n\n";
$migrations = shell_exec('php artisan migrate --force');
echo '-- '.$migrations."\n\n";
echo "--------------------------------------------------------\n";
echo "Step 6: Checking for OAuth keys:\n";
echo "--------------------------------------------------------\n\n";
if ((!file_exists('storage/oauth-public.key')) || (!file_exists('storage/oauth-private.key'))) {
echo "- No OAuth keys detected. Running passport install now.\n\n";
$passport = shell_exec('php artisan passport:install');
echo $passport;
} else {
echo "- OAuth keys detected. Skipping passport install.\n\n";
}
echo "--------------------------------------------------------\n";
echo "Step 7: Caching routes and config:\n";
echo "--------------------------------------------------------\n\n";
$config_cache = shell_exec('php artisan config:cache');
$route_cache = shell_exec('php artisan route:cache');
echo '-- '.$config_cache;
echo '-- '.$route_cache;
echo "\n";
echo "--------------------------------------------------------\n";
echo "Step 8: Taking application out of maintenance mode:\n";
echo "--------------------------------------------------------\n\n";
$up = shell_exec('php artisan up');
echo '-- '.$up."\n\n";
echo "--------------------------------------------------------\n";
echo "FINISHED! Clear your browser cookies and re-login to use :\n";
echo "your upgraded Snipe-IT.\n";
echo "--------------------------------------------------------\n\n";