Compare commits
148 Commits
v5.3.10
...
possible_f
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5fbafb8a6a | ||
|
|
cab29745e7 | ||
|
|
41fa42f7d8 | ||
|
|
eb49c33e1b | ||
|
|
c838354b74 | ||
|
|
46c4d1a3d6 | ||
|
|
57ed3afcc4 | ||
|
|
fd71b48489 | ||
|
|
1cbbf8f976 | ||
|
|
5a8c3444e2 | ||
|
|
edab4e1371 | ||
|
|
173ec44b9e | ||
|
|
2e9cf8fa87 | ||
|
|
126bb486b5 | ||
|
|
0abc108686 | ||
|
|
f623d05d0c | ||
|
|
ef7f21e3ba | ||
|
|
91694064fb | ||
|
|
9a0219eff7 | ||
|
|
b2087a9947 | ||
|
|
6b1329133b | ||
|
|
e4ef970934 | ||
|
|
f211c11034 | ||
|
|
698c7f4904 | ||
|
|
7479f5f12d | ||
|
|
161c6b7d31 | ||
|
|
1441cf9f4f | ||
|
|
270143bb46 | ||
|
|
6b0a1ab3fb | ||
|
|
5fba8202d6 | ||
|
|
61f5825c69 | ||
|
|
5314ef97e5 | ||
|
|
b7fbc5d018 | ||
|
|
211a0820e5 | ||
|
|
7b891f0952 | ||
|
|
6c1bb89776 | ||
|
|
3eb7a87a66 | ||
|
|
0cb4caa4cf | ||
|
|
4db7cb0e21 | ||
|
|
6529a75683 | ||
|
|
4b255ada70 | ||
|
|
01342ca266 | ||
|
|
87fc856361 | ||
|
|
3dd7c00a0b | ||
|
|
0c31e840c4 | ||
|
|
c12ef19fcc | ||
|
|
2d213a9c77 | ||
|
|
0882cfede2 | ||
|
|
96cd90f842 | ||
|
|
d56552a8af | ||
|
|
bdabbbd4e9 | ||
|
|
ab18ceb2f9 | ||
|
|
e046db6d1e | ||
|
|
863ea62551 | ||
|
|
70059f6f80 | ||
|
|
e50ad8a442 | ||
|
|
639409fb3f | ||
|
|
20e65804ef | ||
|
|
729b23c0cf | ||
|
|
af9f3d5e1e | ||
|
|
00ca30a205 | ||
|
|
8c92198636 | ||
|
|
169973e697 | ||
|
|
7571c0b850 | ||
|
|
7cbcd2d95c | ||
|
|
1ac293a12a | ||
|
|
3e3c277a3f | ||
|
|
93d6ce1a6a | ||
|
|
dadc80d558 | ||
|
|
9caf27ce60 | ||
|
|
968de7e469 | ||
|
|
2410b1a146 | ||
|
|
ed39df349f | ||
|
|
86a2312a31 | ||
|
|
e30d814ece | ||
|
|
e9d297e97d | ||
|
|
9269d5945e | ||
|
|
33ee63f985 | ||
|
|
def570db4b | ||
|
|
fcb81b9505 | ||
|
|
3e2fe10480 | ||
|
|
f840652395 | ||
|
|
afd83311aa | ||
|
|
29a2e80984 | ||
|
|
fa576bc78f | ||
|
|
3e22dce117 | ||
|
|
9adcf58ae5 | ||
|
|
5266b2c71f | ||
|
|
94dded3785 | ||
|
|
ac8a7d0bc9 | ||
|
|
6fca8350f9 | ||
|
|
9acb5413f6 | ||
|
|
08a2fe4edb | ||
|
|
6abe8f296b | ||
|
|
a53a67be4a | ||
|
|
b72cac3511 | ||
|
|
698b7301b6 | ||
|
|
c940d36fff | ||
|
|
cd12028845 | ||
|
|
3225605ef3 | ||
|
|
31dde20a2b | ||
|
|
aa36ebc947 | ||
|
|
92434fa943 | ||
|
|
0164354463 | ||
|
|
bdc737ce0c | ||
|
|
733b3a7550 | ||
|
|
3339a691e1 | ||
|
|
2eef43e8bf | ||
|
|
336d8e6574 | ||
|
|
dfbff27483 | ||
|
|
24ce34c8d7 | ||
|
|
7abb1f960c | ||
|
|
ec7df11d73 | ||
|
|
64fa7e23fc | ||
|
|
93ad59466b | ||
|
|
4b7f45a15e | ||
|
|
83f21d0ddf | ||
|
|
2906a89442 | ||
|
|
50f55b4308 | ||
|
|
a8028e7dd0 | ||
|
|
15abc84ab0 | ||
|
|
8a09211310 | ||
|
|
42fcd29200 | ||
|
|
dc2e6c2b06 | ||
|
|
0cfc0a4bee | ||
|
|
64f83f9a5f | ||
|
|
dc2b58f865 | ||
|
|
34ebc629c2 | ||
|
|
d1b45a83b8 | ||
|
|
01a8701a8c | ||
|
|
67fe53e32a | ||
|
|
7f6b8cc43d | ||
|
|
5fe999eb02 | ||
|
|
ea429d650e | ||
|
|
7fe7d56999 | ||
|
|
4f89dfee49 | ||
|
|
017534bc07 | ||
|
|
5540069cce | ||
|
|
e9a4ff8e74 | ||
|
|
1ad56760ce | ||
|
|
5582949008 | ||
|
|
290baf1c8d | ||
|
|
f878e0ad66 | ||
|
|
178e440951 | ||
|
|
321be4733d | ||
|
|
cab4fa1687 | ||
|
|
4804e5b3ab | ||
|
|
15b96f304b |
@@ -2549,6 +2549,24 @@
|
||||
"contributions": [
|
||||
"test"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "QveenSi",
|
||||
"name": "Yevhenii Huzii",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/19945501?v=4",
|
||||
"profile": "https://github.com/QveenSi",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "chrisweirich",
|
||||
"name": "Christian Weirich",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/97299851?v=4",
|
||||
"profile": "https://github.com/chrisweirich",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -152,4 +152,5 @@ LDAP_TIME_LIM=600
|
||||
IMPORT_TIME_LIMIT=600
|
||||
IMPORT_MEMORY_LIMIT=500M
|
||||
REPORT_TIME_LIMIT=12000
|
||||
|
||||
REQUIRE_SAML=false
|
||||
API_THROTTLE_PER_MINUTE=120
|
||||
41
.github/ISSUE_TEMPLATE/feature_request.yml
vendored
41
.github/ISSUE_TEMPLATE/feature_request.yml
vendored
@@ -1,42 +1,27 @@
|
||||
name: Feature Request
|
||||
description: Suggest an idea for this project
|
||||
title: "[Feature Request]: "
|
||||
labels: ["feature request"]
|
||||
assignees:
|
||||
- snipe
|
||||
body:
|
||||
- type: input
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Snipe-IT Version
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
id: server_operatingSystem
|
||||
attributes:
|
||||
label: Operating System
|
||||
description: 'e.g. Ubuntu, Windows'
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
attributes:
|
||||
label: Web Server
|
||||
description: 'e.g. Apache, IIS'
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
attributes:
|
||||
label: PHP Version
|
||||
label: Is your feature request related to a problem? Please describe.
|
||||
description: A clear and concise description of what the problem is. The more information you can provide about your use-case, the more liklely we are to consider your feature.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Is your feature request related to a problem? Please describe. A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
||||
label: Describe the solution you'd like
|
||||
description: A clear and concise description of what you want to happen.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Describe the solution you'd like A clear and concise description of what you want to happen.
|
||||
validations:
|
||||
required: true
|
||||
label: Describe alternatives you've considered
|
||||
description: A clear and concise description of any alternative solutions or features you've considered.
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Describe alternatives you've considered A clear and concise description of any alternative solutions or features you've considered.
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Additional context Add any other context or screenshots about the feature request here.
|
||||
label: Additional context
|
||||
description: Add any other context or screenshots about the feature request here.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
 [](https://crowdin.com/project/snipe-it) [](https://hub.docker.com/r/snipe/snipe-it/) [](https://twitter.com/snipeitapp) [](https://www.codacy.com/app/snipe/snipe-it?utm_source=github.com&utm_medium=referral&utm_content=snipe/snipe-it&utm_campaign=Badge_Grade)
|
||||
[](#contributors) [](https://discord.gg/yZFtShAcKk) [](https://huntr.dev)
|
||||
[](#contributors) [](https://discord.gg/yZFtShAcKk) [](https://huntr.dev)
|
||||
|
||||
## Snipe-IT - Open Source Asset Management System
|
||||
|
||||
@@ -131,6 +131,7 @@ Thanks goes to all of these wonderful people ([emoji key](https://github.com/ken
|
||||
| [<img src="https://avatars.githubusercontent.com/u/8735148?v=4" width="110px;"/><br /><sub>Petri Asikainen</sub>](https://github.com/PetriAsi)<br />[💻](https://github.com/snipe/snipe-it/commits?author=PetriAsi "Code") | [<img src="https://avatars.githubusercontent.com/u/11424540?v=4" width="110px;"/><br /><sub>derdeagle</sub>](https://github.com/derdeagle)<br />[💻](https://github.com/snipe/snipe-it/commits?author=derdeagle "Code") | [<img src="https://avatars.githubusercontent.com/u/176950?v=4" width="110px;"/><br /><sub>Mike Frysinger</sub>](https://wh0rd.org/)<br />[💻](https://github.com/snipe/snipe-it/commits?author=vapier "Code") | [<img src="https://avatars.githubusercontent.com/u/22044358?v=4" width="110px;"/><br /><sub>ALPHA</sub>](https://github.com/AL4AL)<br />[💻](https://github.com/snipe/snipe-it/commits?author=AL4AL "Code") | [<img src="https://avatars.githubusercontent.com/u/1042587?v=4" width="110px;"/><br /><sub>FliegenKLATSCH</sub>](https://www.ifern.de)<br />[💻](https://github.com/snipe/snipe-it/commits?author=FliegenKLATSCH "Code") | [<img src="https://avatars.githubusercontent.com/u/442138?v=4" width="110px;"/><br /><sub>Jeremy Price</sub>](https://github.com/jerm)<br />[💻](https://github.com/snipe/snipe-it/commits?author=jerm "Code") | [<img src="https://avatars.githubusercontent.com/u/84392209?v=4" width="110px;"/><br /><sub>Toreg87</sub>](https://github.com/Toreg87)<br />[💻](https://github.com/snipe/snipe-it/commits?author=Toreg87 "Code") |
|
||||
| [<img src="https://avatars.githubusercontent.com/u/67638596?v=4" width="110px;"/><br /><sub>Matthew Nickson</sub>](https://github.com/Computroniks)<br />[💻](https://github.com/snipe/snipe-it/commits?author=Computroniks "Code") | [<img src="https://avatars.githubusercontent.com/u/1646397?v=4" width="110px;"/><br /><sub>Jethro Nederhof</sub>](https://jethron.id.au)<br />[💻](https://github.com/snipe/snipe-it/commits?author=jethron "Code") | [<img src="https://avatars.githubusercontent.com/u/23289826?v=4" width="110px;"/><br /><sub>Oskar Stenberg</sub>](https://github.com/01ste02)<br />[💻](https://github.com/snipe/snipe-it/commits?author=01ste02 "Code") | [<img src="https://avatars.githubusercontent.com/u/82208283?v=4" width="110px;"/><br /><sub>Robert-Azelis</sub>](https://github.com/Robert-Azelis)<br />[💻](https://github.com/snipe/snipe-it/commits?author=Robert-Azelis "Code") | [<img src="https://avatars.githubusercontent.com/u/60648387?v=4" width="110px;"/><br /><sub>Alexander William Smith</sub>](https://github.com/alwism)<br />[💻](https://github.com/snipe/snipe-it/commits?author=alwism "Code") | [<img src="https://avatars.githubusercontent.com/u/24418301?v=4" width="110px;"/><br /><sub>LEITWERK AG</sub>](https://www.leitwerk.de/)<br />[💻](https://github.com/snipe/snipe-it/commits?author=leitwerk-ag "Code") | [<img src="https://avatars.githubusercontent.com/u/1911435?v=4" width="110px;"/><br /><sub>Adam</sub>](http://www.aboutcher.co.uk)<br />[💻](https://github.com/snipe/snipe-it/commits?author=adamboutcher "Code") |
|
||||
| [<img src="https://avatars.githubusercontent.com/u/16104273?v=4" width="110px;"/><br /><sub>Ian</sub>](https://snksrv.com)<br />[💻](https://github.com/snipe/snipe-it/commits?author=sneak-it "Code") | [<img src="https://avatars.githubusercontent.com/u/4023909?v=4" width="110px;"/><br /><sub>Shao Yu-Lung (Allen)</sub>](http://blog.bestlong.idv.tw/)<br />[💻](https://github.com/snipe/snipe-it/commits?author=bestlong "Code") | [<img src="https://avatars.githubusercontent.com/u/76475453?v=4" width="110px;"/><br /><sub>Haxatron</sub>](https://github.com/Haxatron)<br />[💻](https://github.com/snipe/snipe-it/commits?author=Haxatron "Code") | [<img src="https://avatars.githubusercontent.com/u/3842948?v=4" width="110px;"/><br /><sub>Bradley Coudriet</sub>](http://bjcpgd.cias.rit.edu)<br />[💻](https://github.com/snipe/snipe-it/commits?author=exula "Code") | [<img src="https://avatars.githubusercontent.com/u/21966173?v=4" width="110px;"/><br /><sub>Dalton Durst</sub>](https://daltondur.st)<br />[💻](https://github.com/snipe/snipe-it/commits?author=UniversalSuperBox "Code") | [<img src="https://avatars.githubusercontent.com/u/48162670?v=4" width="110px;"/><br /><sub>TenOfTens</sub>](https://github.com/TenOfTens)<br />[💻](https://github.com/snipe/snipe-it/commits?author=TenOfTens "Code") | [<img src="https://avatars.githubusercontent.com/u/917232?v=4" width="110px;"/><br /><sub>Simona Avornicesei</sub>](http://www.avornicesei.com)<br />[⚠️](https://github.com/snipe/snipe-it/commits?author=savornicesei "Tests") |
|
||||
| [<img src="https://avatars.githubusercontent.com/u/19945501?v=4" width="110px;"/><br /><sub>Yevhenii Huzii</sub>](https://github.com/QveenSi)<br />[💻](https://github.com/snipe/snipe-it/commits?author=QveenSi "Code") | [<img src="https://avatars.githubusercontent.com/u/97299851?v=4" width="110px;"/><br /><sub>Christian Weirich</sub>](https://github.com/chrisweirich)<br />[💻](https://github.com/snipe/snipe-it/commits?author=chrisweirich "Code") |
|
||||
<!-- ALL-CONTRIBUTORS-LIST:END -->
|
||||
|
||||
This project follows the [all-contributors](https://github.com/kentcdodds/all-contributors) specification. Contributions of any kind welcome!
|
||||
|
||||
59
app/Console/Commands/KillAllSessions.php
Normal file
59
app/Console/Commands/KillAllSessions.php
Normal file
@@ -0,0 +1,59 @@
|
||||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use Illuminate\Console\Command;
|
||||
|
||||
class KillAllSessions extends Command
|
||||
{
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'snipeit:global-logout {--force : Skip the danger prompt; assuming you enter "y"} ';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'This command will destroy all web sessions on disk and will force a re-login for all users.';
|
||||
|
||||
/**
|
||||
* Create a new command instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
|
||||
if (!$this->option('force') && !$this->confirm("****************************************************\nTHIS WILL FORCE A LOGIN FOR ALL LOGGED IN USERS.\n\nAre you SURE you wish to continue? ")) {
|
||||
return $this->error("Session loss not confirmed");
|
||||
}
|
||||
|
||||
$session_files = glob(storage_path("framework/sessions/*"));
|
||||
|
||||
$count = 0;
|
||||
foreach ($session_files as $file) {
|
||||
|
||||
if (is_file($file))
|
||||
unlink($file);
|
||||
$count++;
|
||||
}
|
||||
\DB::table('users')->update(['remember_token' => null]);
|
||||
|
||||
$this->info($count. ' sessions cleared!');
|
||||
|
||||
}
|
||||
}
|
||||
@@ -47,18 +47,18 @@ class MoveUploadsToNewDisk extends Command
|
||||
}
|
||||
$delete_local = $this->argument('delete_local');
|
||||
|
||||
$public_uploads['accessories'] = glob('public/accessories'."/*.*");
|
||||
$public_uploads['assets'] = glob('public/assets'."/*.*");
|
||||
$public_uploads['avatars'] = glob('public/avatars'."/*.*");
|
||||
$public_uploads['categories'] = glob('public/categories'."/*.*");
|
||||
$public_uploads['companies'] = glob('public/companies'."/*.*");
|
||||
$public_uploads['components'] = glob('public/components'."/*.*");
|
||||
$public_uploads['consumables'] = glob('public/consumables'."/*.*");
|
||||
$public_uploads['departments'] = glob('public/departments'."/*.*");
|
||||
$public_uploads['locations'] = glob('public/locations'."/*.*");
|
||||
$public_uploads['manufacturers'] = glob('public/manufacturers'."/*.*");
|
||||
$public_uploads['suppliers'] = glob('public/suppliers'."/*.*");
|
||||
$public_uploads['assetmodels'] = glob('public/models'."/*.*");
|
||||
$public_uploads['accessories'] = glob('public/uploads/accessories'."/*.*");
|
||||
$public_uploads['assets'] = glob('public/uploads/assets'."/*.*");
|
||||
$public_uploads['avatars'] = glob('public/uploads/avatars'."/*.*");
|
||||
$public_uploads['categories'] = glob('public/uploads/categories'."/*.*");
|
||||
$public_uploads['companies'] = glob('public/uploads/companies'."/*.*");
|
||||
$public_uploads['components'] = glob('public/uploads/components'."/*.*");
|
||||
$public_uploads['consumables'] = glob('public/uploads/consumables'."/*.*");
|
||||
$public_uploads['departments'] = glob('public/uploads/departments'."/*.*");
|
||||
$public_uploads['locations'] = glob('public/uploads/locations'."/*.*");
|
||||
$public_uploads['manufacturers'] = glob('public/uploads/manufacturers'."/*.*");
|
||||
$public_uploads['suppliers'] = glob('public/uploads/suppliers'."/*.*");
|
||||
$public_uploads['assetmodels'] = glob('public/uploads/models'."/*.*");
|
||||
|
||||
|
||||
// iterate files
|
||||
@@ -72,7 +72,7 @@ class MoveUploadsToNewDisk extends Command
|
||||
$filename = basename($public_upload[$i]);
|
||||
|
||||
try {
|
||||
Storage::disk('public')->put('uploads/'.public_type.'/'.$filename, file_get_contents($public_upload[$i]));
|
||||
Storage::disk('public')->put('uploads/'.$public_type.'/'.$filename, file_get_contents($public_upload[$i]));
|
||||
$new_url = Storage::disk('public')->url('uploads/'.$public_type.'/'.$filename, $filename);
|
||||
$this->info($type_count.'. PUBLIC: '.$filename.' was copied to '.$new_url);
|
||||
} catch (\Exception $e) {
|
||||
@@ -103,7 +103,7 @@ class MoveUploadsToNewDisk extends Command
|
||||
$private_uploads['imports'] = glob('storage/private_uploads/imports'."/*.*");
|
||||
$private_uploads['licenses'] = glob('storage/private_uploads/licenses'."/*.*");
|
||||
$private_uploads['users'] = glob('storage/private_uploads/users'."/*.*");
|
||||
$private_uploads['backups'] = glob('storage/private_uploads/users'."/*.*");
|
||||
$private_uploads['backups'] = glob('storage/private_uploads/backups'."/*.*");
|
||||
|
||||
|
||||
foreach($private_uploads as $private_type => $private_upload)
|
||||
|
||||
@@ -14,7 +14,7 @@ class RestoreFromBackup extends Command
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'snipeit:restore
|
||||
{--force : Skip the danger prompt; assuming you hit "y"}
|
||||
{--force : Skip the danger prompt; assuming you enter "y"}
|
||||
{filename : The zip file to be migrated}
|
||||
{--no-progress : Don\'t show a progress bar}';
|
||||
|
||||
|
||||
@@ -84,10 +84,12 @@ class Handler extends ExceptionHandler
|
||||
switch ($e->getStatusCode()) {
|
||||
case '404':
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, $statusCode . ' endpoint not found'), 404);
|
||||
case '405':
|
||||
case '429':
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, 'Too many requests'), 429);
|
||||
case '405':
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, 'Method not allowed'), 405);
|
||||
default:
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, $statusCode), 405);
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, $statusCode), $statusCode);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -78,6 +78,8 @@ class AccessoriesController extends Controller
|
||||
$accessory->qty = request('qty');
|
||||
$accessory->user_id = Auth::user()->id;
|
||||
$accessory->supplier_id = request('supplier_id');
|
||||
$accessory->notes = request('notes');
|
||||
|
||||
|
||||
$accessory = $request->handleImages($accessory);
|
||||
|
||||
@@ -140,6 +142,7 @@ class AccessoriesController extends Controller
|
||||
$accessory->purchase_cost = Helper::ParseCurrency(request('purchase_cost'));
|
||||
$accessory->qty = request('qty');
|
||||
$accessory->supplier_id = request('supplier_id');
|
||||
$accessory->notes = request('notes');
|
||||
|
||||
$accessory = $request->handleImages($accessory);
|
||||
|
||||
|
||||
@@ -9,10 +9,21 @@ class ActionlogController extends Controller
|
||||
{
|
||||
public function displaySig($filename)
|
||||
{
|
||||
// PHP doesn't let you handle file not found errors well with
|
||||
// file_get_contents, so we set the error reporting for just this class
|
||||
error_reporting(0);
|
||||
|
||||
$this->authorize('view', \App\Models\Asset::class);
|
||||
$file = config('app.private_uploads') . '/signatures/' . $filename;
|
||||
$file = config('app.private_uploads').'/signatures/'.$filename;
|
||||
$filetype = Helper::checkUploadIsImage($file);
|
||||
$contents = file_get_contents($file);
|
||||
return Response::make($contents)->header('Content-Type', $filetype);
|
||||
|
||||
$contents = file_get_contents($file, false, stream_context_create(['http' => ['ignore_errors' => true]]));
|
||||
if ($contents === false) {
|
||||
\Log::warn('File '.$file.' not found');
|
||||
return false;
|
||||
} else {
|
||||
return Response::make($contents)->header('Content-Type', $filetype);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,7 +39,8 @@ class AccessoriesController extends Controller
|
||||
'notes',
|
||||
'created_at',
|
||||
'min_amt',
|
||||
'company_id'
|
||||
'company_id',
|
||||
'notes',
|
||||
];
|
||||
|
||||
|
||||
@@ -69,6 +70,10 @@ class AccessoriesController extends Controller
|
||||
$accessories->where('location_id','=',$request->input('location_id'));
|
||||
}
|
||||
|
||||
if ($request->filled('notes')) {
|
||||
$accessories->where('notes','=',$request->input('notes'));
|
||||
}
|
||||
|
||||
// Set the offset to the API call's offset, unless the offset is higher than the actual count of items in which
|
||||
// case we override with the actual count, so we should return 0 items.
|
||||
$offset = (($accessories) && ($request->get('offset') > $accessories->count())) ? $accessories->count() : $request->get('offset', 0);
|
||||
|
||||
@@ -33,6 +33,7 @@ class AssetMaintenancesController extends Controller
|
||||
*/
|
||||
public function index(Request $request)
|
||||
{
|
||||
$this->authorize('view', Asset::class);
|
||||
$maintenances = AssetMaintenance::with('asset', 'asset.model','asset.location', 'supplier', 'asset.company', 'admin');
|
||||
|
||||
if ($request->filled('search')) {
|
||||
@@ -101,6 +102,7 @@ class AssetMaintenancesController extends Controller
|
||||
*/
|
||||
public function store(Request $request)
|
||||
{
|
||||
$this->authorize('update', Asset::class);
|
||||
// create a new model instance
|
||||
$assetMaintenance = new AssetMaintenance();
|
||||
$assetMaintenance->supplier_id = $request->input('supplier_id');
|
||||
@@ -153,6 +155,7 @@ class AssetMaintenancesController extends Controller
|
||||
*/
|
||||
public function update(Request $request, $assetMaintenanceId = null)
|
||||
{
|
||||
$this->authorize('update', Asset::class);
|
||||
// Check if the asset maintenance exists
|
||||
$assetMaintenance = AssetMaintenance::findOrFail($assetMaintenanceId);
|
||||
|
||||
@@ -216,6 +219,7 @@ class AssetMaintenancesController extends Controller
|
||||
*/
|
||||
public function destroy($assetMaintenanceId)
|
||||
{
|
||||
$this->authorize('update', Asset::class);
|
||||
// Check if the asset maintenance exists
|
||||
$assetMaintenance = AssetMaintenance::findOrFail($assetMaintenanceId);
|
||||
|
||||
@@ -241,6 +245,7 @@ class AssetMaintenancesController extends Controller
|
||||
*/
|
||||
public function show($assetMaintenanceId)
|
||||
{
|
||||
$this->authorize('view', Asset::class);
|
||||
$assetMaintenance = AssetMaintenance::findOrFail($assetMaintenanceId);
|
||||
if (!Company::isCurrentUserHasAccess($assetMaintenance->asset)) {
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, 'You cannot view a maintenance for that asset'));
|
||||
|
||||
@@ -788,6 +788,9 @@ class AssetsController extends Controller
|
||||
$error_payload['target_type'] = 'user';
|
||||
}
|
||||
|
||||
if ($request->filled('status_id')) {
|
||||
$asset->status_id = $request->get('status_id');
|
||||
}
|
||||
|
||||
|
||||
if (!isset($target)) {
|
||||
|
||||
@@ -40,6 +40,7 @@ class ComponentsController extends Controller
|
||||
'purchase_cost',
|
||||
'qty',
|
||||
'image',
|
||||
'notes',
|
||||
];
|
||||
|
||||
|
||||
@@ -62,6 +63,10 @@ class ComponentsController extends Controller
|
||||
$components->where('location_id','=',$request->input('location_id'));
|
||||
}
|
||||
|
||||
if ($request->filled('notes')) {
|
||||
$components->where('notes','=',$request->input('notes'));
|
||||
}
|
||||
|
||||
// Set the offset to the API call's offset, unless the offset is higher than the actual count of items in which
|
||||
// case we override with the actual count, so we should return 0 items.
|
||||
$offset = (($components) && ($request->get('offset') > $components->count())) ? $components->count() : $request->get('offset', 0);
|
||||
|
||||
@@ -42,6 +42,7 @@ class ConsumablesController extends Controller
|
||||
'item_no',
|
||||
'qty',
|
||||
'image',
|
||||
'notes',
|
||||
];
|
||||
|
||||
|
||||
@@ -74,6 +75,10 @@ class ConsumablesController extends Controller
|
||||
$consumables->where('location_id','=',$request->input('location_id'));
|
||||
}
|
||||
|
||||
if ($request->filled('notes')) {
|
||||
$consumables->where('notes','=',$request->input('notes'));
|
||||
}
|
||||
|
||||
|
||||
// Set the offset to the API call's offset, unless the offset is higher than the actual count of items in which
|
||||
// case we override with the actual count, so we should return 0 items.
|
||||
|
||||
@@ -26,7 +26,7 @@ class LicensesController extends Controller
|
||||
public function index(Request $request)
|
||||
{
|
||||
$this->authorize('view', License::class);
|
||||
$licenses = Company::scopeCompanyables(License::with('company', 'manufacturer', 'freeSeats', 'supplier','category')->withCount('freeSeats as free_seats_count'));
|
||||
$licenses = Company::scopeCompanyables(License::with('company', 'manufacturer', 'supplier','category')->withCount('freeSeats as free_seats_count'));
|
||||
|
||||
|
||||
if ($request->filled('company_id')) {
|
||||
@@ -82,6 +82,10 @@ class LicensesController extends Controller
|
||||
$licenses = $licenses->TextSearch($request->input('search'));
|
||||
}
|
||||
|
||||
if ($request->input('deleted')=='true') {
|
||||
$licenses->onlyTrashed();
|
||||
}
|
||||
|
||||
|
||||
// Set the offset to the API call's offset, unless the offset is higher than the actual count of items in which
|
||||
// case we override with the actual count, so we should return 0 items.
|
||||
|
||||
@@ -30,11 +30,11 @@ class ProfileController extends Controller
|
||||
// Make sure the asset and request still exist
|
||||
if ($checkoutRequest && $checkoutRequest->itemRequested()) {
|
||||
$results['rows'][] = [
|
||||
'image' => $checkoutRequest->itemRequested()->present()->getImageUrl(),
|
||||
'name' => $checkoutRequest->itemRequested()->present()->name(),
|
||||
'type' => $checkoutRequest->itemType(),
|
||||
'qty' => $checkoutRequest->quantity,
|
||||
'location' => ($checkoutRequest->location()) ? $checkoutRequest->location()->name : null,
|
||||
'image' => e($checkoutRequest->itemRequested()->present()->getImageUrl()),
|
||||
'name' => e($checkoutRequest->itemRequested()->present()->name()),
|
||||
'type' => e($checkoutRequest->itemType()),
|
||||
'qty' => (int) $checkoutRequest->quantity,
|
||||
'location' => ($checkoutRequest->location()) ? e($checkoutRequest->location()->name) : null,
|
||||
'expected_checkin' => Helper::getFormattedDateObject($checkoutRequest->itemRequested()->expected_checkin, 'datetime'),
|
||||
'request_date' => Helper::getFormattedDateObject($checkoutRequest->created_at, 'datetime'),
|
||||
];
|
||||
|
||||
@@ -30,6 +30,19 @@ class StatuslabelsController extends Controller
|
||||
$statuslabels = $statuslabels->TextSearch($request->input('search'));
|
||||
}
|
||||
|
||||
// if a status_type is passed, filter by that
|
||||
if ($request->filled('status_type')) {
|
||||
if (strtolower($request->input('status_type')) == 'pending') {
|
||||
$statuslabels = $statuslabels->Pending();
|
||||
} elseif (strtolower($request->input('status_type')) == 'archived') {
|
||||
$statuslabels = $statuslabels->Archived();
|
||||
} elseif (strtolower($request->input('status_type')) == 'deployable') {
|
||||
$statuslabels = $statuslabels->Deployable();
|
||||
} elseif (strtolower($request->input('status_type')) == 'undeployable') {
|
||||
$statuslabels = $statuslabels->Undeployable();
|
||||
}
|
||||
}
|
||||
|
||||
// Set the offset to the API call's offset, unless the offset is higher than the actual count of items in which
|
||||
// case we override with the actual count, so we should return 0 items.
|
||||
$offset = (($statuslabels) && ($request->get('offset') > $statuslabels->count())) ? $statuslabels->count() : $request->get('offset', 0);
|
||||
|
||||
@@ -7,6 +7,7 @@ use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\SaveUserRequest;
|
||||
use App\Http\Transformers\AccessoriesTransformer;
|
||||
use App\Http\Transformers\AssetsTransformer;
|
||||
use App\Http\Transformers\ConsumablesTransformer;
|
||||
use App\Http\Transformers\LicensesTransformer;
|
||||
use App\Http\Transformers\SelectlistTransformer;
|
||||
use App\Http\Transformers\UsersTransformer;
|
||||
@@ -131,6 +132,26 @@ class UsersController extends Controller
|
||||
$users = $users->where('users.manager_id','=',$request->input('manager_id'));
|
||||
}
|
||||
|
||||
if ($request->filled('ldap_import')) {
|
||||
$users = $users->where('ldap_import', '=', $request->input('ldap_import'));
|
||||
}
|
||||
|
||||
if ($request->filled('assets_count')) {
|
||||
$users->has('assets', '=', $request->input('assets_count'));
|
||||
}
|
||||
|
||||
if ($request->filled('consumables_count')) {
|
||||
$users->has('consumables', '=', $request->input('consumables_count'));
|
||||
}
|
||||
|
||||
if ($request->filled('licenses_count')) {
|
||||
$users->has('licenses', '=', $request->input('licenses_count'));
|
||||
}
|
||||
|
||||
if ($request->filled('accessories_count')) {
|
||||
$users->has('accessories', '=', $request->input('accessories_count'));
|
||||
}
|
||||
|
||||
if ($request->filled('search')) {
|
||||
$users = $users->TextSearch($request->input('search'));
|
||||
}
|
||||
@@ -448,6 +469,24 @@ class UsersController extends Controller
|
||||
return (new AssetsTransformer)->transformAssets($assets, $assets->count(), $request);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return JSON containing a list of consumables assigned to a user.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v3.0]
|
||||
* @param $userId
|
||||
* @return string JSON
|
||||
*/
|
||||
public function consumables(Request $request, $id)
|
||||
{
|
||||
$this->authorize('view', User::class);
|
||||
$this->authorize('view', Consumable::class);
|
||||
$user = User::findOrFail($id);
|
||||
$consumables = $user->consumables;
|
||||
return (new ConsumablesTransformer)->transformConsumables($consumables, $consumables->count(), $request);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return JSON containing a list of accessories assigned to a user.
|
||||
*
|
||||
|
||||
@@ -50,6 +50,7 @@ class AssetMaintenancesController extends Controller
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
$this->authorize('view', Asset::class);
|
||||
return view('asset_maintenances/index');
|
||||
}
|
||||
|
||||
@@ -66,6 +67,7 @@ class AssetMaintenancesController extends Controller
|
||||
*/
|
||||
public function create()
|
||||
{
|
||||
$this->authorize('update', Asset::class);
|
||||
$asset = null;
|
||||
|
||||
if ($asset = Asset::find(request('asset_id'))) {
|
||||
@@ -96,6 +98,7 @@ class AssetMaintenancesController extends Controller
|
||||
*/
|
||||
public function store(Request $request)
|
||||
{
|
||||
$this->authorize('update', Asset::class);
|
||||
// create a new model instance
|
||||
$assetMaintenance = new AssetMaintenance();
|
||||
$assetMaintenance->supplier_id = $request->input('supplier_id');
|
||||
@@ -148,6 +151,7 @@ class AssetMaintenancesController extends Controller
|
||||
*/
|
||||
public function edit($assetMaintenanceId = null)
|
||||
{
|
||||
$this->authorize('update', Asset::class);
|
||||
// Check if the asset maintenance exists
|
||||
if (is_null($assetMaintenance = AssetMaintenance::find($assetMaintenanceId))) {
|
||||
// Redirect to the improvement management page
|
||||
@@ -200,6 +204,7 @@ class AssetMaintenancesController extends Controller
|
||||
*/
|
||||
public function update(Request $request, $assetMaintenanceId = null)
|
||||
{
|
||||
$this->authorize('update', Asset::class);
|
||||
// Check if the asset maintenance exists
|
||||
if (is_null($assetMaintenance = AssetMaintenance::find($assetMaintenanceId))) {
|
||||
// Redirect to the asset maintenance management page
|
||||
@@ -266,6 +271,7 @@ class AssetMaintenancesController extends Controller
|
||||
*/
|
||||
public function destroy($assetMaintenanceId)
|
||||
{
|
||||
$this->authorize('update', Asset::class);
|
||||
// Check if the asset maintenance exists
|
||||
if (is_null($assetMaintenance = AssetMaintenance::find($assetMaintenanceId))) {
|
||||
// Redirect to the asset maintenance management page
|
||||
@@ -294,6 +300,8 @@ class AssetMaintenancesController extends Controller
|
||||
*/
|
||||
public function show($assetMaintenanceId)
|
||||
{
|
||||
$this->authorize('view', Asset::class);
|
||||
|
||||
// Check if the asset maintenance exists
|
||||
if (is_null($assetMaintenance = AssetMaintenance::find($assetMaintenanceId))) {
|
||||
// Redirect to the asset maintenance management page
|
||||
|
||||
@@ -105,9 +105,9 @@ class AssetCheckinController extends Controller
|
||||
$asset->location_id = e($request->get('location_id'));
|
||||
}
|
||||
|
||||
$checkin_at = date('Y-m-d');
|
||||
if($request->filled('checkin_at')){
|
||||
$checkin_at = $request->input('checkin_at');
|
||||
$checkin_at = date('Y-m-d H:i:s');
|
||||
if (($request->filled('checkin_at')) && ($request->get('checkin_at') != date('Y-m-d'))) {
|
||||
$checkin_at = $request->get('checkin_at');
|
||||
}
|
||||
|
||||
// Was the asset updated?
|
||||
|
||||
@@ -410,7 +410,23 @@ class AssetsController extends Controller
|
||||
return redirect()->route('hardware.index')->with('success', trans('admin/hardware/message.delete.success'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Searches the assets table by serial, and redirects if it finds one
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v3.0]
|
||||
* @return Redirect
|
||||
*/
|
||||
public function getAssetBySerial(Request $request)
|
||||
{
|
||||
$topsearch = ($request->get('topsearch')=="true");
|
||||
|
||||
if (!$asset = Asset::where('serial', '=', $request->get('serial'))->first()) {
|
||||
return redirect()->route('hardware.index')->with('error', trans('admin/hardware/message.does_not_exist'));
|
||||
}
|
||||
$this->authorize('view', $asset);
|
||||
return redirect()->route('hardware.show', $asset->id)->with('topsearch', $topsearch);
|
||||
}
|
||||
|
||||
/**
|
||||
* Searches the assets table by asset tag, and redirects if it finds one
|
||||
@@ -429,6 +445,8 @@ class AssetsController extends Controller
|
||||
$this->authorize('view', $asset);
|
||||
return redirect()->route('hardware.show', $asset->id)->with('topsearch', $topsearch);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return a QR code for the asset
|
||||
*
|
||||
@@ -843,6 +861,7 @@ class AssetsController extends Controller
|
||||
|
||||
public function getRequestedIndex($user_id = null)
|
||||
{
|
||||
$this->authorize('index', Asset::class);
|
||||
$requestedItems = CheckoutRequest::with('user', 'requestedItem')->whereNull('canceled_at')->with('user', 'requestedItem');
|
||||
|
||||
if ($user_id) {
|
||||
|
||||
@@ -87,6 +87,8 @@ class ForgotPasswordController extends Controller
|
||||
\Log::info('Password reset attempt: User '.$request->input('username').'failed with exception: '.$e );
|
||||
}
|
||||
|
||||
// Prevent timing attack to enumerate users.
|
||||
usleep(500000 + random_int(0, 1500000));
|
||||
|
||||
if ($response === \Password::RESET_LINK_SENT) {
|
||||
\Log::info('Password reset attempt: User '.$request->input('username').' WAS found, password reset sent');
|
||||
|
||||
@@ -75,6 +75,13 @@ class LoginController extends Controller
|
||||
return redirect()->intended('/');
|
||||
}
|
||||
|
||||
// If the environment is set to ALWAYS require SAML, go straight to the SAML route.
|
||||
// We don't need to check other settings, as this should override those.
|
||||
if (config('app.require_saml')) {
|
||||
return redirect()->route('saml.login');
|
||||
}
|
||||
|
||||
|
||||
if ($this->saml->isEnabled() && Setting::getSettings()->saml_forcelogin == "1" && !($request->has('nosaml') || $request->session()->has('error'))) {
|
||||
return redirect()->route('saml.login');
|
||||
}
|
||||
@@ -197,6 +204,12 @@ class LoginController extends Controller
|
||||
*/
|
||||
public function login(Request $request)
|
||||
{
|
||||
|
||||
//If the environment is set to ALWAYS require SAML, return access denied
|
||||
if (config('app.require_saml')) {
|
||||
return view('errors.403');
|
||||
}
|
||||
|
||||
if (Setting::getSettings()->login_common_disabled == "1") {
|
||||
return view('errors.403');
|
||||
}
|
||||
@@ -363,7 +376,7 @@ class LoginController extends Controller
|
||||
if (Google2FA::verifyKey($user->two_factor_secret, $secret)) {
|
||||
$user->two_factor_enrolled = 1;
|
||||
$user->save();
|
||||
$request->session()->put('2fa_authed', 'true');
|
||||
$request->session()->put('2fa_authed', $user->id);
|
||||
return redirect()->route('home')->with('success', 'You are logged in!');
|
||||
}
|
||||
|
||||
@@ -402,10 +415,8 @@ class LoginController extends Controller
|
||||
return redirect()->away($sloRequestUrl);
|
||||
}
|
||||
|
||||
$request->session()->regenerate(true);
|
||||
|
||||
$request->session()->regenerate(true);
|
||||
Auth::logout();
|
||||
$request->session()->flush();
|
||||
|
||||
if (!empty($sloRedirectUrl)) {
|
||||
return redirect()->away($sloRedirectUrl);
|
||||
|
||||
@@ -78,6 +78,7 @@ class ComponentsController extends Controller
|
||||
$component->purchase_cost = Helper::ParseCurrency($request->input('purchase_cost', null));
|
||||
$component->qty = $request->input('qty');
|
||||
$component->user_id = Auth::id();
|
||||
$component->notes = $request->input('notes');
|
||||
|
||||
$component = $request->handleImages($component);
|
||||
|
||||
@@ -147,6 +148,7 @@ class ComponentsController extends Controller
|
||||
$component->purchase_date = $request->input('purchase_date');
|
||||
$component->purchase_cost = Helper::ParseCurrency(request('purchase_cost'));
|
||||
$component->qty = $request->input('qty');
|
||||
$component->notes = $request->input('notes');
|
||||
|
||||
$component = $request->handleImages($component);
|
||||
|
||||
|
||||
@@ -78,6 +78,8 @@ class ConsumablesController extends Controller
|
||||
$consumable->purchase_cost = Helper::ParseCurrency($request->input('purchase_cost'));
|
||||
$consumable->qty = $request->input('qty');
|
||||
$consumable->user_id = Auth::id();
|
||||
$consumable->notes = $request->input('notes');
|
||||
|
||||
|
||||
|
||||
$consumable = $request->handleImages($consumable);
|
||||
@@ -143,6 +145,7 @@ class ConsumablesController extends Controller
|
||||
$consumable->purchase_date = $request->input('purchase_date');
|
||||
$consumable->purchase_cost = Helper::ParseCurrency($request->input('purchase_cost'));
|
||||
$consumable->qty = Helper::ParseFloat($request->input('qty'));
|
||||
$consumable->notes = $request->input('notes');
|
||||
|
||||
$consumable = $request->handleImages($consumable);
|
||||
|
||||
|
||||
@@ -235,7 +235,7 @@ class LicensesController extends Controller
|
||||
public function show($licenseId = null)
|
||||
{
|
||||
|
||||
$license = License::with('assignedusers', 'licenseSeats.user', 'licenseSeats.asset')->find($licenseId);
|
||||
$license = License::with('assignedusers')->find($licenseId);
|
||||
|
||||
if ($license) {
|
||||
$this->authorize('view', $license);
|
||||
|
||||
@@ -272,13 +272,18 @@ class ReportsController extends Controller
|
||||
}
|
||||
}
|
||||
|
||||
if($actionlog->item){
|
||||
$item_name = e($actionlog->item->getDisplayNameAttribute());
|
||||
} else {
|
||||
$item_name ='';
|
||||
}
|
||||
|
||||
$row = [
|
||||
$actionlog->created_at,
|
||||
($actionlog->user) ? e($actionlog->user->getFullNameAttribute()) : '',
|
||||
$actionlog->present()->actionType(),
|
||||
e($actionlog->itemType()),
|
||||
($actionlog->itemType()=='user') ? $actionlog->filename : e($actionlog->item->getDisplayNameAttribute()),
|
||||
($actionlog->itemType()=='user') ? $actionlog->filename : $item_name,
|
||||
$target_name,
|
||||
($actionlog->note) ? e($actionlog->note): '',
|
||||
$actionlog->log_meta,
|
||||
|
||||
@@ -8,6 +8,7 @@ use App\Http\Requests\ImageUploadRequest;
|
||||
use App\Http\Requests\SettingsSamlRequest;
|
||||
use App\Http\Requests\SetupUserRequest;
|
||||
use App\Models\Setting;
|
||||
use App\Models\Asset;
|
||||
use App\Models\User;
|
||||
use App\Notifications\FirstAdminNotification;
|
||||
use App\Notifications\MailTest;
|
||||
@@ -621,6 +622,26 @@ class SettingsController extends Controller
|
||||
return redirect()->to('admin')->with('error', trans('admin/settings/message.update.error'));
|
||||
}
|
||||
|
||||
// Check if the audit interval has changed - if it has, we want to update ALL of the assets audit dates
|
||||
if ($request->input('audit_interval') != $setting->audit_interval) {
|
||||
|
||||
// Be careful - this could be a negative number
|
||||
$audit_diff_months = ((int)$request->input('audit_interval') - (int)($setting->audit_interval));
|
||||
|
||||
// Grab all of the assets that have an existing next_audit_date
|
||||
$assets = Asset::whereNotNull('next_audit_date')->get();
|
||||
|
||||
// Update all of the assets' next_audit_date values
|
||||
foreach ($assets as $asset) {
|
||||
|
||||
if ($asset->next_audit_date != '') {
|
||||
$old_next_audit = new \DateTime($asset->next_audit_date);
|
||||
$asset->next_audit_date = $old_next_audit->modify($audit_diff_months.' month')->format('Y-m-d');
|
||||
$asset->forceSave();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$alert_email = rtrim($request->input('alert_email'), ',');
|
||||
$alert_email = trim($alert_email);
|
||||
$admin_cc_email = rtrim($request->input('admin_cc_email'), ',');
|
||||
|
||||
@@ -109,12 +109,15 @@ class BulkUsersController extends Controller
|
||||
if (!$manager_conflict) {
|
||||
$this->conditionallyAddItem('manager_id');
|
||||
}
|
||||
|
||||
|
||||
// Save the updated info
|
||||
User::whereIn('id', $user_raw_array)
|
||||
->where('id', '!=', Auth::id())->update($this->update_array);
|
||||
|
||||
if(array_key_exists('location_id', $this->update_array)){
|
||||
Asset::where('assigned_type', User::class)
|
||||
->whereIn('assigned_to', $user_raw_array)
|
||||
->update(['location_id' => $this->update_array['location_id']]);
|
||||
}
|
||||
// Only sync groups if groups were selected
|
||||
if ($request->filled('groups')) {
|
||||
foreach ($users as $user) {
|
||||
|
||||
@@ -24,6 +24,7 @@ class Kernel extends HttpKernel
|
||||
\Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
|
||||
\App\Http\Middleware\SecurityHeaders::class,
|
||||
\App\Http\Middleware\PreventBackHistory::class,
|
||||
\Fruitcake\Cors\HandleCors::class,
|
||||
|
||||
];
|
||||
|
||||
@@ -38,14 +39,13 @@ class Kernel extends HttpKernel
|
||||
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
|
||||
\App\Http\Middleware\VerifyCsrfToken::class,
|
||||
\App\Http\Middleware\CheckLocale::class,
|
||||
\App\Http\Middleware\CheckUserIsActivated::class,
|
||||
\App\Http\Middleware\CheckForTwoFactor::class,
|
||||
\Laravel\Passport\Http\Middleware\CreateFreshApiToken::class,
|
||||
\App\Http\Middleware\AssetCountForSidebar::class,
|
||||
],
|
||||
|
||||
'api' => [
|
||||
\Barryvdh\Cors\HandleCors::class,
|
||||
'throttle:120,1',
|
||||
'auth:api',
|
||||
],
|
||||
];
|
||||
|
||||
@@ -32,7 +32,7 @@ class CheckForTwoFactor
|
||||
if ($settings = Setting::getSettings()) {
|
||||
if (Auth::check() && ($settings->two_factor_enabled != '')) {
|
||||
// This user is already 2fa-authed
|
||||
if ($request->session()->get('2fa_authed')) {
|
||||
if ($request->session()->get('2fa_authed')==Auth::user()->id) {
|
||||
return $next($request);
|
||||
}
|
||||
|
||||
|
||||
@@ -4,8 +4,9 @@ namespace App\Http\Middleware;
|
||||
|
||||
use Closure;
|
||||
use Illuminate\Contracts\Auth\Guard;
|
||||
use Auth;
|
||||
|
||||
class Authenticate
|
||||
class CheckUserIsActivated
|
||||
{
|
||||
/**
|
||||
* The Guard implementation.
|
||||
@@ -34,14 +35,16 @@ class Authenticate
|
||||
*/
|
||||
public function handle($request, Closure $next)
|
||||
{
|
||||
if ($this->auth->guest()) {
|
||||
if ($request->ajax()) {
|
||||
return response('Unauthorized.', 401);
|
||||
} else {
|
||||
return redirect()->guest('login');
|
||||
}
|
||||
|
||||
// If there is a user AND the user is NOT activated, send them to the login page
|
||||
// This prevents people who still have active sessions logged in and their status gets toggled
|
||||
// to inactive (aka unable to login)
|
||||
if (($request->user()) && (!$request->user()->isActivated())) {
|
||||
Auth::logout();
|
||||
return redirect()->guest('login');
|
||||
}
|
||||
|
||||
return $next($request);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -25,6 +25,7 @@ class AssetCheckoutRequest extends Request
|
||||
"assigned_user" => 'required_without_all:assigned_asset,assigned_location',
|
||||
"assigned_asset" => 'required_without_all:assigned_user,assigned_location',
|
||||
"assigned_location" => 'required_without_all:assigned_user,assigned_asset',
|
||||
'status_id' => 'exists:status_labels,id,deployable,1',
|
||||
"checkout_to_type" => 'required|in:asset,location,user'
|
||||
];
|
||||
|
||||
|
||||
@@ -19,6 +19,22 @@ class ActionlogsTransformer
|
||||
return (new DatatablesTransformer)->transformDatatables($array, $total);
|
||||
}
|
||||
|
||||
private function clean_field($value)
|
||||
{
|
||||
// This object stuff is weird, and is used to make up for the fact that
|
||||
// older data can get strangely formatted if an asset existed,
|
||||
// then a new custom field is added, and the asset is saved again.
|
||||
// It can result in funnily-formatted strings like:
|
||||
//
|
||||
// {"_snipeit_right_sized_fault_tolerant_localareanetwo_1":
|
||||
// {"old":null,"new":{"value":"1579490695972","_snipeit_new_field_2":2,"_snipeit_new_field_3":"Monday, 20 January 2020 2:24:55 PM"}}
|
||||
// so we have to walk down that next level
|
||||
if(is_object($value) && isset($value->value)) {
|
||||
return $this->clean_field($value->value);
|
||||
}
|
||||
return is_scalar($value) || is_null($value) ? e($value) : e(json_encode($value));
|
||||
}
|
||||
|
||||
public function transformActionlog (Actionlog $actionlog, $settings = null)
|
||||
{
|
||||
$icon = $actionlog->present()->icon();
|
||||
@@ -31,49 +47,9 @@ class ActionlogsTransformer
|
||||
$meta_array = json_decode($actionlog->log_meta);
|
||||
|
||||
if ($meta_array) {
|
||||
foreach ($meta_array as $key => $value) {
|
||||
foreach ($value as $meta_key => $meta_value) {
|
||||
|
||||
if (is_array($meta_value)) {
|
||||
foreach ($meta_value as $meta_value_key => $meta_value_value) {
|
||||
if (is_scalar($meta_value_value)) {
|
||||
$clean_meta[$key][$meta_value_key] = e($meta_value_value);
|
||||
} else {
|
||||
$clean_meta[$key][$meta_value_key] = 'invalid scalar: '.print_r($meta_value_value, true);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
||||
// This object stuff is weird, and is used to make up for the fact that
|
||||
// older data can get strangely formatted if an asset existed,
|
||||
// then a new custom field is added, and the asset is saved again.
|
||||
// It can result in funnily-formatted strings like:
|
||||
//
|
||||
// {"_snipeit_right_sized_fault_tolerant_localareanetwo_1":
|
||||
// {"old":null,"new":{"value":"1579490695972","_snipeit_new_field_2":2,"_snipeit_new_field_3":"Monday, 20 January 2020 2:24:55 PM"}}
|
||||
// so we have to walk down that next level
|
||||
|
||||
if (is_object($meta_value)) {
|
||||
|
||||
foreach ($meta_value as $meta_value_key => $meta_value_value) {
|
||||
|
||||
if ($meta_value_key == 'value') {
|
||||
$clean_meta[$key]['old'] = null;
|
||||
$clean_meta[$key]['new'] = e($meta_value->value);
|
||||
} else {
|
||||
$clean_meta[$meta_value_key]['old'] = null;
|
||||
$clean_meta[$meta_value_key]['new'] = e($meta_value_value);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
} else {
|
||||
$clean_meta[$key][$meta_key] = e($meta_value);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
foreach ($meta_array as $fieldname => $fieldata) {
|
||||
$clean_meta[$fieldname]['old'] = $this->clean_field($fieldata->old);
|
||||
$clean_meta[$fieldname]['new'] = $this->clean_field($fieldata->new);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -122,6 +98,7 @@ class ActionlogsTransformer
|
||||
'action_date' => ($actionlog->action_date) ? Helper::getFormattedDateObject($actionlog->action_date, 'datetime'): Helper::getFormattedDateObject($actionlog->created_at, 'datetime'),
|
||||
|
||||
];
|
||||
//\Log::info("Clean Meta is: ".print_r($clean_meta,true));
|
||||
|
||||
return $array;
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ namespace App\Http\Transformers;
|
||||
|
||||
use App\Helpers\Helper;
|
||||
use App\Models\Asset;
|
||||
use App\Models\Setting;
|
||||
use Gate;
|
||||
use Illuminate\Database\Eloquent\Collection;
|
||||
|
||||
@@ -20,6 +21,9 @@ class AssetsTransformer
|
||||
|
||||
public function transformAsset(Asset $asset)
|
||||
{
|
||||
// This uses the getSettings() method so we're pulling from the cache versus querying the settings on single asset
|
||||
$setting = Setting::getSettings();
|
||||
|
||||
$array = [
|
||||
'id' => (int) $asset->id,
|
||||
'name' => e($asset->name),
|
||||
@@ -64,6 +68,8 @@ class AssetsTransformer
|
||||
'name'=> e($asset->defaultLoc->name)
|
||||
] : null,
|
||||
'image' => ($asset->getImageUrl()) ? $asset->getImageUrl() : null,
|
||||
'qr' => ($setting->qr_code=='1') ? config('app.url').'/uploads/barcodes/qr-'.str_slug($asset->asset_tag).'-'.str_slug($asset->id).'.png' : null,
|
||||
'alt_barcode' => ($setting->alt_barcode_enabled=='1') ? config('app.url').'/uploads/barcodes/'.str_slug($setting->alt_barcode).'-'.str_slug($asset->asset_tag).'.png' : null,
|
||||
'assigned_to' => $this->transformAssignedTo($asset),
|
||||
'warranty_months' => ($asset->warranty_months > 0) ? e($asset->warranty_months . ' ' . trans('admin/hardware/form.months')) : null,
|
||||
'warranty_expires' => ($asset->warranty_months > 0) ? Helper::getFormattedDateObject($asset->warranty_expires, 'date') : null,
|
||||
|
||||
@@ -43,6 +43,7 @@ class ComponentsTransformer
|
||||
'id' => (int) $component->company->id,
|
||||
'name' => e($component->company->name)
|
||||
] : null,
|
||||
'notes' => ($component->notes) ? e($component->notes) : null,
|
||||
'created_at' => Helper::getFormattedDateObject($component->created_at, 'datetime'),
|
||||
'updated_at' => Helper::getFormattedDateObject($component->updated_at, 'datetime'),
|
||||
'user_can_checkout' => ($component->numRemaining() > 0) ? 1 : 0,
|
||||
|
||||
@@ -37,6 +37,7 @@ class ConsumablesTransformer
|
||||
'purchase_cost' => Helper::formatCurrencyOutput($consumable->purchase_cost),
|
||||
'purchase_date' => Helper::getFormattedDateObject($consumable->purchase_date, 'date'),
|
||||
'qty' => (int) $consumable->qty,
|
||||
'notes' => ($consumable->notes) ? e($consumable->notes) : null,
|
||||
'created_at' => Helper::getFormattedDateObject($consumable->created_at, 'datetime'),
|
||||
'updated_at' => Helper::getFormattedDateObject($consumable->updated_at, 'datetime'),
|
||||
];
|
||||
|
||||
@@ -98,7 +98,7 @@ class DepreciationReportTransformer
|
||||
'purchase_cost' => Helper::formatCurrencyOutput($asset->purchase_cost),
|
||||
'book_value' => Helper::formatCurrencyOutput($depreciated_value),
|
||||
'monthly_depreciation' => $monthly_depreciation,
|
||||
'checked_out_to' => $checkout_target,
|
||||
'checked_out_to' => ($checkout_target) ? e($checkout_target) : null,
|
||||
'diff' => Helper::formatCurrencyOutput($diff),
|
||||
'number_of_months' => ($asset->model && $asset->model->depreciation) ? e($asset->model->depreciation->months) : null,
|
||||
'depreciation' => (($asset->model) && ($asset->model->depreciation)) ? e($asset->model->depreciation->name) : null,
|
||||
|
||||
@@ -45,7 +45,9 @@ class LicensesTransformer
|
||||
'category' => ($license->category) ? ['id' => (int) $license->category->id,'name'=> e($license->category->name)] : null,
|
||||
'created_at' => Helper::getFormattedDateObject($license->created_at, 'datetime'),
|
||||
'updated_at' => Helper::getFormattedDateObject($license->updated_at, 'datetime'),
|
||||
'deleted_at' => Helper::getFormattedDateObject($license->deleted_at, 'datetime'),
|
||||
'user_can_checkout' => (bool) ($license->free_seats_count > 0),
|
||||
|
||||
];
|
||||
|
||||
$permissions_array['available_actions'] = [
|
||||
|
||||
@@ -71,7 +71,7 @@ class AssetImporter extends ItemImporter
|
||||
$this->log("No Matching Asset, Creating a new one");
|
||||
$asset = new Asset;
|
||||
}
|
||||
|
||||
$this->item['notes'] = $this->findCsvMatch($row, 'asset_notes');
|
||||
$this->item['image'] = $this->findCsvMatch($row, "image");
|
||||
$this->item['requestable'] = $this->fetchHumanBoolean($this->findCsvMatch($row, "requestable"));;
|
||||
$asset->requestable = $this->fetchHumanBoolean($this->findCsvMatch($row, "requestable"));
|
||||
|
||||
@@ -208,6 +208,7 @@ class ItemImporter extends Importer
|
||||
$this->log("Matching Model found, updating it.");
|
||||
$item = $this->sanitizeItemForStoring($asset_model, $editingModel);
|
||||
$item['name'] = $asset_model_name;
|
||||
$item['notes'] = $this->findCsvMatch($row, 'model_notes');
|
||||
|
||||
if(!empty($asset_modelNumber)){
|
||||
$item['model_number'] = $asset_modelNumber;
|
||||
@@ -224,6 +225,7 @@ class ItemImporter extends Importer
|
||||
$item = $this->sanitizeItemForStoring($asset_model, $editingModel);
|
||||
$item['name'] = $asset_model_name;
|
||||
$item['model_number'] = $asset_modelNumber;
|
||||
$item['notes'] = $this->findCsvMatch($row, 'model_notes');
|
||||
|
||||
$asset_model->fill($item);
|
||||
$item = null;
|
||||
|
||||
@@ -46,14 +46,22 @@ class LicenseImporter extends ItemImporter
|
||||
$license = new License;
|
||||
}
|
||||
$asset_tag = $this->item['asset_tag'] = $this->findCsvMatch($row, 'asset_tag'); // used for checkout out to an asset.
|
||||
$this->item['expiration_date'] = $this->findCsvMatch($row, 'expiration_date');
|
||||
|
||||
$this->item["expiration_date"] = null;
|
||||
if ($this->findCsvMatch($row, "expiration_date")!='') {
|
||||
$this->item["expiration_date"] = date("Y-m-d 00:00:01", strtotime($this->findCsvMatch($row, "expiration_date")));
|
||||
}
|
||||
$this->item['license_email'] = $this->findCsvMatch($row, "license_email");
|
||||
$this->item['license_name'] = $this->findCsvMatch($row, "license_name");
|
||||
$this->item['maintained'] = $this->findCsvMatch($row, 'maintained');
|
||||
$this->item['purchase_order'] = $this->findCsvMatch($row, 'purchase_order');
|
||||
$this->item['reassignable'] = $this->findCsvMatch($row, 'reassignable');
|
||||
$this->item['seats'] = $this->findCsvMatch($row, 'seats');
|
||||
$this->item['termination_date'] = $this->findCsvMatch($row, 'termination_date');
|
||||
|
||||
$this->item["termination_date"] = null;
|
||||
if ($this->findCsvMatch($row, "termination_date")!='') {
|
||||
$this->item["termination_date"] = date("Y-m-d 00:00:01", strtotime($this->findCsvMatch($row, "termination_date")));
|
||||
}
|
||||
|
||||
if ($editingLicense) {
|
||||
$license->update($this->sanitizeItemForUpdating($license));
|
||||
|
||||
@@ -35,7 +35,7 @@ class Accessory extends SnipeModel
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $searchableAttributes = ['name', 'model_number', 'order_number', 'purchase_date'];
|
||||
protected $searchableAttributes = ['name', 'model_number', 'order_number', 'purchase_date', 'notes'];
|
||||
|
||||
/**
|
||||
* The relations and their attributes that should be included when searching the model.
|
||||
@@ -92,7 +92,8 @@ class Accessory extends SnipeModel
|
||||
'image',
|
||||
'qty',
|
||||
'min_amt',
|
||||
'requestable'
|
||||
'requestable',
|
||||
'notes',
|
||||
];
|
||||
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@ class Actionlog extends SnipeModel
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $searchableAttributes = ['action_type', 'note', 'log_meta'];
|
||||
protected $searchableAttributes = ['action_type', 'note', 'log_meta','user_id'];
|
||||
|
||||
/**
|
||||
* The relations and their attributes that should be included when searching the model.
|
||||
@@ -38,7 +38,8 @@ class Actionlog extends SnipeModel
|
||||
* @var array
|
||||
*/
|
||||
protected $searchableRelations = [
|
||||
'company' => ['name']
|
||||
'company' => ['name'],
|
||||
'user' => ['first_name','last_name','username'],
|
||||
];
|
||||
|
||||
/**
|
||||
|
||||
@@ -185,10 +185,19 @@ class Asset extends Depreciable
|
||||
$model = AssetModel::find($this->model_id);
|
||||
|
||||
if (($model) && ($model->fieldset)) {
|
||||
|
||||
foreach ($model->fieldset->fields as $field){
|
||||
if($field->format == 'BOOLEAN'){
|
||||
$this->{$field->db_column} = filter_var($this->{$field->db_column}, FILTER_VALIDATE_BOOLEAN);
|
||||
}
|
||||
}
|
||||
|
||||
$this->rules += $model->fieldset->validation_rules();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
return parent::save($params);
|
||||
}
|
||||
|
||||
|
||||
@@ -60,6 +60,7 @@ class Component extends SnipeModel
|
||||
'order_number',
|
||||
'qty',
|
||||
'serial',
|
||||
'notes',
|
||||
];
|
||||
|
||||
use Searchable;
|
||||
@@ -69,7 +70,7 @@ class Component extends SnipeModel
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $searchableAttributes = ['name', 'order_number', 'serial', 'purchase_cost', 'purchase_date'];
|
||||
protected $searchableAttributes = ['name', 'order_number', 'serial', 'purchase_cost', 'purchase_date', 'notes'];
|
||||
|
||||
/**
|
||||
* The relations and their attributes that should be included when searching the model.
|
||||
|
||||
@@ -69,7 +69,8 @@ class Consumable extends SnipeModel
|
||||
'purchase_date',
|
||||
'qty',
|
||||
'min_amt',
|
||||
'requestable'
|
||||
'requestable',
|
||||
'notes',
|
||||
];
|
||||
|
||||
use Searchable;
|
||||
@@ -79,7 +80,7 @@ class Consumable extends SnipeModel
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $searchableAttributes = ['name', 'order_number', 'purchase_cost', 'purchase_date', 'item_no', 'model_number'];
|
||||
protected $searchableAttributes = ['name', 'order_number', 'purchase_cost', 'purchase_date', 'item_no', 'model_number', 'notes'];
|
||||
|
||||
/**
|
||||
* The relations and their attributes that should be included when searching the model.
|
||||
|
||||
@@ -45,7 +45,7 @@ class License extends Depreciable
|
||||
|
||||
protected $rules = array(
|
||||
'name' => 'required|string|min:3|max:255',
|
||||
'seats' => 'required|min:1|max:999|integer',
|
||||
'seats' => 'required|min:1|max:9999|integer',
|
||||
'license_email' => 'email|nullable|max:120',
|
||||
'license_name' => 'string|nullable|max:100',
|
||||
'notes' => 'string|nullable',
|
||||
@@ -173,13 +173,25 @@ class License extends Depreciable
|
||||
$logAction->logaction('delete seats');
|
||||
return true;
|
||||
}
|
||||
// Else we're adding seats.
|
||||
DB::transaction(function () use ($license, $oldSeats, $newSeats) {
|
||||
for ($i = $oldSeats; $i < $newSeats; $i++) {
|
||||
$license->licenseSeatsRelation()->save(new LicenseSeat, ['user_id' => Auth::id()]);
|
||||
}
|
||||
//Create enough seats for the change.
|
||||
$licenseInsert = [];
|
||||
for ($i = $oldSeats; $i < $newSeats; $i++) {
|
||||
$licenseInsert[] = [
|
||||
'user_id' => Auth::id(),
|
||||
'license_id' => $license->id,
|
||||
'created_at' => now(),
|
||||
'updated_at' => now()
|
||||
];
|
||||
}
|
||||
//Chunk and use DB transactions to prevent timeouts.
|
||||
|
||||
collect($licenseInsert)->chunk(1000)->each(function ($chunk) {
|
||||
DB::transaction(function () use ($chunk) {
|
||||
LicenseSeat::insert($chunk->toArray());
|
||||
});
|
||||
});
|
||||
// On initail create, we shouldn't log the addition of seats.
|
||||
|
||||
// On initial create, we shouldn't log the addition of seats.
|
||||
if ($license->id) {
|
||||
//Log the addition of license to the log.
|
||||
$logAction = new Actionlog();
|
||||
|
||||
@@ -116,6 +116,9 @@ trait Loggable
|
||||
$log->location_id = null;
|
||||
$log->note = $note;
|
||||
$log->action_date = $action_date;
|
||||
if (! $log->action_date) {
|
||||
$log->action_date = date('Y-m-d H:i:s');
|
||||
}
|
||||
|
||||
if (Auth::user()) {
|
||||
$log->user_id = Auth::user()->id;
|
||||
|
||||
@@ -121,6 +121,18 @@ class Statuslabel extends SnipeModel
|
||||
->where('deployable', '=', 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Query builder scope for undeployable status types
|
||||
*
|
||||
* @return \Illuminate\Database\Query\Builder Modified query builder
|
||||
*/
|
||||
public function scopeUndeployable()
|
||||
{
|
||||
return $this->where('pending', '=', 0)
|
||||
->where('archived', '=', 0)
|
||||
->where('deployable', '=', 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to determine type attributes
|
||||
*
|
||||
|
||||
@@ -70,7 +70,6 @@ class User extends SnipeModel implements AuthenticatableContract, AuthorizableCo
|
||||
* @var array
|
||||
*/
|
||||
|
||||
// 'username' => 'required|string|min:1|unique:users,username,NULL,id,deleted_at,NULL',
|
||||
protected $rules = [
|
||||
'first_name' => 'required|string|min:1',
|
||||
'username' => 'required|string|min:1|unique_undeleted',
|
||||
@@ -306,7 +305,7 @@ class User extends SnipeModel implements AuthenticatableContract, AuthorizableCo
|
||||
*/
|
||||
public function consumables()
|
||||
{
|
||||
return $this->belongsToMany('\App\Models\Consumable', 'consumables_users', 'assigned_to', 'consumable_id')->withPivot('id')->withTrashed();
|
||||
return $this->belongsToMany('\App\Models\Consumable', 'consumables_users', 'assigned_to', 'consumable_id')->withPivot('id', 'created_at')->withTrashed();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -318,7 +317,7 @@ class User extends SnipeModel implements AuthenticatableContract, AuthorizableCo
|
||||
*/
|
||||
public function licenses()
|
||||
{
|
||||
return $this->belongsToMany('\App\Models\License', 'license_seats', 'assigned_to', 'license_id')->withPivot('id');
|
||||
return $this->belongsToMany('\App\Models\License', 'license_seats', 'assigned_to', 'license_id')->withPivot('id', 'created_at');
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -17,12 +17,13 @@ class AssetObserver
|
||||
*/
|
||||
public function updating(Asset $asset)
|
||||
{
|
||||
|
||||
// If the asset isn't being checked out or audited, log the update.
|
||||
// (Those other actions already create log entries.)
|
||||
if (($asset->getAttributes()['assigned_to'] == $asset->getOriginal()['assigned_to'])
|
||||
&& ($asset->getAttributes()['next_audit_date'] == $asset->getOriginal()['next_audit_date'])
|
||||
&& ($asset->getAttributes()['last_checkout'] == $asset->getOriginal()['last_checkout']))
|
||||
$attributes = $asset->getAttributes();
|
||||
$attributesOriginal = $asset->getOriginal();
|
||||
// If the asset isn't being checked out or audited, log the update.
|
||||
// (Those other actions already create log entries.)
|
||||
if (($attributes['assigned_to'] == $attributesOriginal['assigned_to'])
|
||||
&& ((isset( $attributes['next_audit_date']) ? $attributes['next_audit_date'] : null) == (isset($attributesOriginal['next_audit_date']) ? $attributesOriginal['next_audit_date']: null))
|
||||
&& ($attributes['last_checkout'] == $attributesOriginal['last_checkout']))
|
||||
{
|
||||
$changed = [];
|
||||
|
||||
|
||||
@@ -109,7 +109,14 @@ class AccessoryPresenter extends Presenter
|
||||
"sortable" => true,
|
||||
"visible" => false,
|
||||
"title" => trans('general.order_number'),
|
||||
],[
|
||||
], [
|
||||
"field" => "notes",
|
||||
"searchable" => true,
|
||||
"sortable" => true,
|
||||
"visible" => false,
|
||||
"title" => trans('general.notes'),
|
||||
"formatter" => "notesFormatter"
|
||||
], [
|
||||
"field" => "change",
|
||||
"searchable" => false,
|
||||
"sortable" => false,
|
||||
|
||||
@@ -104,7 +104,14 @@ class ComponentPresenter extends Presenter
|
||||
"title" => trans('general.purchase_cost'),
|
||||
"visible" => true,
|
||||
"footerFormatter" => 'sumFormatter',
|
||||
],
|
||||
], [
|
||||
"field" => "notes",
|
||||
"searchable" => true,
|
||||
"sortable" => true,
|
||||
"visible" => false,
|
||||
"title" => trans('general.notes'),
|
||||
"formatter" => "notesFormatter"
|
||||
]
|
||||
];
|
||||
|
||||
$layout[] = [
|
||||
|
||||
@@ -118,13 +118,20 @@ class ConsumablePresenter extends Presenter
|
||||
"visible" => true,
|
||||
"footerFormatter" => 'sumFormatter',
|
||||
],[
|
||||
"field" => "notes",
|
||||
"searchable" => true,
|
||||
"sortable" => true,
|
||||
"visible" => false,
|
||||
"title" => trans('general.notes'),
|
||||
"formatter" => "notesFormatter"
|
||||
], [
|
||||
"field" => "change",
|
||||
"searchable" => false,
|
||||
"sortable" => false,
|
||||
"visible" => true,
|
||||
"title" => trans('general.change'),
|
||||
"formatter" => "consumablesInOutFormatter",
|
||||
], [
|
||||
], [
|
||||
"field" => "actions",
|
||||
"searchable" => false,
|
||||
"sortable" => false,
|
||||
|
||||
@@ -179,12 +179,21 @@ class AuthServiceProvider extends ServiceProvider
|
||||
// to the logged in API user, but creating assets, licenses, etc won't work
|
||||
// if the user can't view and interact with the select lists.
|
||||
Gate::define('view.selectlists', function ($user) {
|
||||
return $user->can(['create','update'], Asset::class)
|
||||
|| $user->can(['create','update'], License::class)
|
||||
|| $user->can(['create','update'], Component::class)
|
||||
|| $user->can(['create','update'], Consumable::class)
|
||||
|| $user->can(['create','update'], Accessory::class)
|
||||
|| $user->can(['create','update'], User::class);
|
||||
return $user->can('update', Asset::class)
|
||||
|| $user->can('create', Asset::class)
|
||||
|| $user->can('checkout', Asset::class)
|
||||
|| $user->can('checkin', Asset::class)
|
||||
|| $user->can('audit', Asset::class)
|
||||
|| $user->can('update', License::class)
|
||||
|| $user->can('create', License::class)
|
||||
|| $user->can('update', Component::class)
|
||||
|| $user->can('create', Component::class)
|
||||
|| $user->can('update', Consumable::class)
|
||||
|| $user->can('create', Consumable::class)
|
||||
|| $user->can('update', Accessory::class)
|
||||
|| $user->can('create', Accessory::class)
|
||||
|| $user->can('update', User::class)
|
||||
|| $user->can('create', User::class);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
"adldap2/adldap2": "^10.2",
|
||||
"alek13/slack": "^1.12",
|
||||
"bacon/bacon-qr-code": "^1.0",
|
||||
"barryvdh/laravel-cors": "^0.11.3",
|
||||
"barryvdh/laravel-debugbar": "^3.2",
|
||||
"doctrine/cache": "^1.10",
|
||||
"doctrine/common": "^2.12",
|
||||
@@ -28,9 +27,10 @@
|
||||
"doctrine/inflector": "^1.3",
|
||||
"doctrine/instantiator": "^1.3",
|
||||
"eduardokum/laravel-mail-auto-embed": "^1.0",
|
||||
"enshrined/svg-sanitize": "^0.13.3",
|
||||
"enshrined/svg-sanitize": "^0.15.0",
|
||||
"erusev/parsedown": "^1.7",
|
||||
"fideloper/proxy": "^4.3",
|
||||
"fruitcake/laravel-cors": "^2.2",
|
||||
"guzzlehttp/guzzle": "^6.5",
|
||||
"intervention/image": "^2.5",
|
||||
"javiereguiluz/easyslugger": "^1.0",
|
||||
|
||||
1575
composer.lock
generated
1575
composer.lock
generated
File diff suppressed because it is too large
Load Diff
@@ -255,7 +255,20 @@ return [
|
||||
'enable_csp' => env('ENABLE_CSP', false),
|
||||
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Require SAML Login
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Disable the ability to login via form login, and disables the 'nosaml'
|
||||
| workaround. It requires all logins to process via SAML login.
|
||||
| (This is for high security setups. If your SAML configuration is not
|
||||
| working, this option should be set to false. This option is not needed
|
||||
| to successfully configure SAML authentication.)
|
||||
|
|
||||
*/
|
||||
|
||||
'require_saml' => env('REQUIRE_SAML', false),
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
@@ -412,4 +425,15 @@ return [
|
||||
|
||||
],
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| API Throttling
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| This value determines the number of API requests permitted per minute
|
||||
|
|
||||
*/
|
||||
|
||||
'api_throttle_per_minute' => env('API_THROTTLE_PER_MINUTE', 120),
|
||||
|
||||
];
|
||||
|
||||
@@ -37,12 +37,13 @@ return [
|
||||
|
|
||||
*/
|
||||
|
||||
'supportsCredentials' => false,
|
||||
'allowedOrigins' => $allowed_origins,
|
||||
'allowedOriginsPatterns' => [],
|
||||
'allowedHeaders' => ['*'],
|
||||
'allowedMethods' => ['GET', 'POST', 'PUT', 'PATCH', 'DELETE'],
|
||||
'exposedHeaders' => [],
|
||||
'maxAge' => 0,
|
||||
'supports_credentials' => false,
|
||||
'allowed_origins' => $allowed_origins,
|
||||
'allowed_origins_patterns' => [],
|
||||
'allowed_headers' => ['*'],
|
||||
'allowed_methods' => ['GET', 'POST', 'PUT', 'PATCH', 'DELETE'],
|
||||
'exposed_headers' => [],
|
||||
'max_age' => 0,
|
||||
'paths' => ['api/*', 'sanctum/csrf-cookie'],
|
||||
|
||||
];
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
<?php
|
||||
return array (
|
||||
'app_version' => 'v5.3.10',
|
||||
'full_app_version' => 'v5.3.10 - build 6684-g05c081977',
|
||||
'build_version' => '6684',
|
||||
'app_version' => 'v5.4.4',
|
||||
'full_app_version' => 'v5.4.4 - build 6829-gfd71b4848',
|
||||
'build_version' => '6829',
|
||||
'prerelease_version' => '',
|
||||
'hash_version' => 'g05c081977',
|
||||
'full_hash' => 'v5.3.10-1-g05c081977',
|
||||
'hash_version' => 'gfd71b4848',
|
||||
'full_hash' => 'v5.4.4-14-gfd71b4848',
|
||||
'branch' => 'master',
|
||||
);
|
||||
@@ -1,4 +1,8 @@
|
||||
<?php
|
||||
namespace Database\Factories;
|
||||
|
||||
use App\Models\Category;
|
||||
use Illuminate\Database\Eloquent\Factories\Factory;
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
@@ -13,16 +17,18 @@ $factory->define(App\Models\License::class, function (Faker\Generator $faker) {
|
||||
|
||||
return [
|
||||
'user_id' => 1,
|
||||
'license_name' => $faker->name,
|
||||
'name' => $this->faker->name,
|
||||
'license_email' => $faker->safeEmail,
|
||||
'serial' => $faker->uuid,
|
||||
'notes' => 'Created by DB seeder',
|
||||
'seats' => $this->faker->numberBetween(1, 10),
|
||||
'purchase_date' => $faker->dateTimeBetween('-1 years','now', date_default_timezone_get()),
|
||||
'order_number' => $faker->numberBetween(1000000, 50000000),
|
||||
'expiration_date' => $faker->dateTimeBetween('now', '+3 years', date_default_timezone_get())->format('Y-m-d H:i:s'),
|
||||
'reassignable' => $faker->boolean(),
|
||||
'termination_date' => $faker->dateTimeBetween('-1 years','now', date_default_timezone_get())->format('Y-m-d H:i:s'),
|
||||
'supplier_id' => $faker->numberBetween(1,5),
|
||||
'category_id' => Category::where('category_type', '=', 'license')->inRandomOrder()->first()->id,
|
||||
];
|
||||
});
|
||||
|
||||
|
||||
@@ -14,13 +14,14 @@ class CreateCustomFieldCustomFieldset extends Migration {
|
||||
{
|
||||
Schema::create('custom_field_custom_fieldset', function(Blueprint $table)
|
||||
{
|
||||
$table->bigIncrements('id');
|
||||
$table->integer('custom_field_id');
|
||||
$table->integer('custom_fieldset_id');
|
||||
|
||||
$table->integer('order');
|
||||
$table->boolean('required');
|
||||
$table->engine = 'InnoDB';
|
||||
$table->engine = 'InnoDB';
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -13,20 +13,22 @@ class CreateCheckoutAcceptancesTable extends Migration
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::create('checkout_acceptances', function (Blueprint $table) {
|
||||
$table->increments('id');
|
||||
if (!Schema::hasTable('checkout_acceptances')) {
|
||||
Schema::create('checkout_acceptances', function (Blueprint $table) {
|
||||
$table->increments('id');
|
||||
|
||||
$table->morphs('checkoutable');
|
||||
$table->integer('assigned_to_id')->nullable();
|
||||
$table->morphs('checkoutable');
|
||||
$table->integer('assigned_to_id')->nullable();
|
||||
|
||||
$table->string('signature_filename')->nullable();
|
||||
$table->string('signature_filename')->nullable();
|
||||
|
||||
$table->timestamp('accepted_at')->nullable();
|
||||
$table->timestamp('declined_at')->nullable();
|
||||
$table->timestamp('accepted_at')->nullable();
|
||||
$table->timestamp('declined_at')->nullable();
|
||||
|
||||
$table->timestamps();
|
||||
$table->softDeletes();
|
||||
});
|
||||
$table->timestamps();
|
||||
$table->softDeletes();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -36,6 +38,8 @@ class CreateCheckoutAcceptancesTable extends Migration
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::dropIfExists('checkout_acceptances');
|
||||
if (Schema::hasTable('checkout_acceptances')) {
|
||||
Schema::dropIfExists('checkout_acceptances');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,14 +12,15 @@ class AddKitsLicensesTable extends Migration {
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
//
|
||||
Schema::create('kits_licenses', function ($table) {
|
||||
$table->increments('id');
|
||||
$table->integer('kit_id')->nullable()->default(NULL);
|
||||
$table->integer('license_id')->nullable()->default(NULL);
|
||||
$table->integer('quantity')->default(1);
|
||||
$table->timestamps();
|
||||
});
|
||||
if (!Schema::hasTable('kits_licenses')) {
|
||||
Schema::create('kits_licenses', function ($table) {
|
||||
$table->increments('id');
|
||||
$table->integer('kit_id')->nullable()->default(NULL);
|
||||
$table->integer('license_id')->nullable()->default(NULL);
|
||||
$table->integer('quantity')->default(1);
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -29,8 +30,9 @@ class AddKitsLicensesTable extends Migration {
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
//
|
||||
Schema::drop('kits_licenses');
|
||||
if (Schema::hasTable('kits_licenses')) {
|
||||
Schema::drop('kits_licenses');
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -12,13 +12,14 @@ class AddKitsTable extends Migration {
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
//
|
||||
Schema::create('kits', function ($table) {
|
||||
$table->increments('id');
|
||||
$table->string('name')->nullable()->default(NULL);
|
||||
$table->timestamps();
|
||||
$table->engine = 'InnoDB';
|
||||
});
|
||||
if (!Schema::hasTable('kits')) {
|
||||
Schema::create('kits', function ($table) {
|
||||
$table->increments('id');
|
||||
$table->string('name')->nullable()->default(NULL);
|
||||
$table->timestamps();
|
||||
$table->engine = 'InnoDB';
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -29,8 +30,9 @@ class AddKitsTable extends Migration {
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
//
|
||||
Schema::drop('kits');
|
||||
if (Schema::hasTable('kits')) {
|
||||
Schema::drop('kits');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -12,14 +12,15 @@ class AddKitsModelsTable extends Migration {
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
//
|
||||
Schema::create('kits_models', function ($table) {
|
||||
$table->increments('id');
|
||||
$table->integer('kit_id')->nullable()->default(NULL);
|
||||
$table->integer('model_id')->nullable()->default(NULL);
|
||||
$table->integer('quantity')->default(1);
|
||||
$table->timestamps();
|
||||
});
|
||||
if (!Schema::hasTable('kits_models')) {
|
||||
Schema::create('kits_models', function ($table) {
|
||||
$table->increments('id');
|
||||
$table->integer('kit_id')->nullable()->default(NULL);
|
||||
$table->integer('model_id')->nullable()->default(NULL);
|
||||
$table->integer('quantity')->default(1);
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -29,8 +30,9 @@ class AddKitsModelsTable extends Migration {
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
//
|
||||
Schema::drop('kits_models');
|
||||
if (Schema::hasTable('kits_models')) {
|
||||
Schema::drop('kits_models');
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -13,14 +13,15 @@ class AddKitsConsumablesTable extends Migration
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
//
|
||||
Schema::create('kits_consumables', function ($table) {
|
||||
$table->increments('id');
|
||||
$table->integer('kit_id')->nullable()->default(NULL);
|
||||
$table->integer('consumable_id')->nullable()->default(NULL);
|
||||
$table->integer('quantity')->default(1);
|
||||
$table->timestamps();
|
||||
});
|
||||
if (!Schema::hasTable('kits_consumables')) {
|
||||
Schema::create('kits_consumables', function ($table) {
|
||||
$table->increments('id');
|
||||
$table->integer('kit_id')->nullable()->default(NULL);
|
||||
$table->integer('consumable_id')->nullable()->default(NULL);
|
||||
$table->integer('quantity')->default(1);
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -30,7 +31,8 @@ class AddKitsConsumablesTable extends Migration
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
//
|
||||
Schema::drop('kits_consumables');
|
||||
if (Schema::hasTable('kits_consumables')) {
|
||||
Schema::drop('kits_consumables');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,14 +13,15 @@ class AddKitsAccessoriesTable extends Migration
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
//
|
||||
Schema::create('kits_accessories', function ($table) {
|
||||
$table->increments('id');
|
||||
$table->integer('kit_id')->nullable()->default(NULL);
|
||||
$table->integer('accessory_id')->nullable()->default(NULL);
|
||||
$table->integer('quantity')->default(1);
|
||||
$table->timestamps();
|
||||
});
|
||||
if (!Schema::hasTable('kits_accessories')) {
|
||||
Schema::create('kits_accessories', function ($table) {
|
||||
$table->increments('id');
|
||||
$table->integer('kit_id')->nullable()->default(NULL);
|
||||
$table->integer('accessory_id')->nullable()->default(NULL);
|
||||
$table->integer('quantity')->default(1);
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -30,7 +31,8 @@ class AddKitsAccessoriesTable extends Migration
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
//
|
||||
Schema::drop('kits_accessories');
|
||||
if (Schema::hasTable('kits_accessories')) {
|
||||
Schema::drop('kits_accessories');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class AddLicenseIdIndexToLicenseSeats extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::table('license_seats', function (Blueprint $table) {
|
||||
$table->index(['license_id']);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::table('license_seats', function (Blueprint $table) {
|
||||
$table->dropIndex(['license_id']);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class AddNotesToAccessories extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::table('accessories', function (Blueprint $table) {
|
||||
$table->text("notes")->nullable()->default(null);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::table('accessories', function (Blueprint $table) {
|
||||
if (Schema::hasColumn('accessories', 'notes')) {
|
||||
$table->dropColumn('notes');
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class AddNotesToComponents extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::table('components', function (Blueprint $table) {
|
||||
$table->text("notes")->nullable()->default(null);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::table('components', function (Blueprint $table) {
|
||||
if (Schema::hasColumn('components', 'notes')) {
|
||||
$table->dropColumn('notes');
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class AddNotesToConsumables extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::table('consumables', function (Blueprint $table) {
|
||||
$table->text("notes")->nullable()->default(null);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::table('consumables', function (Blueprint $table) {
|
||||
if (Schema::hasColumn('consumables', 'notes')) {
|
||||
$table->dropColumn('notes');
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class AddPrimaryKeyToCustomFieldsPivot extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
|
||||
// Check if the ID primary key already exists, if not, add it
|
||||
Schema::table('custom_field_custom_fieldset', function (Blueprint $table) {
|
||||
if (!Schema::hasColumn('custom_field_custom_fieldset', 'id')) {
|
||||
$table->bigIncrements('id')->first();
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::table('custom_field_custom_fieldset', function (Blueprint $table) {
|
||||
if (Schema::hasColumn('custom_field_custom_fieldset', 'id')) {
|
||||
$table->dropColumn('id');
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
12
package-lock.json
generated
12
package-lock.json
generated
@@ -2693,9 +2693,9 @@
|
||||
"integrity": "sha1-EQPWvADPv6jPyaJZmrUYxVZD2j8="
|
||||
},
|
||||
"bootstrap-table": {
|
||||
"version": "1.19.1",
|
||||
"resolved": "https://registry.npmjs.org/bootstrap-table/-/bootstrap-table-1.19.1.tgz",
|
||||
"integrity": "sha512-WvV+l1AI/C+zThaKmfHmi/IuayVNB0qdFyEhFx1jyZhO0oLtNJNANkCR3rvJf6Dkh72dsLElxpE/bzK9seEQLA=="
|
||||
"version": "1.18.3",
|
||||
"resolved": "https://registry.npmjs.org/bootstrap-table/-/bootstrap-table-1.18.3.tgz",
|
||||
"integrity": "sha512-/eFLkldDlNFi37qC/d9THfRVxMUGD34E8fQBFtXJLDHLBOVKWDTq7BV+udoP7k3FfCEyhM1jWQnQ0rMQdBv//w=="
|
||||
},
|
||||
"brace-expansion": {
|
||||
"version": "1.1.11",
|
||||
@@ -16238,9 +16238,9 @@
|
||||
"integrity": "sha1-G+i3twTdOFcVJwiu+x1KSzpp+zM="
|
||||
},
|
||||
"jquery-ui": {
|
||||
"version": "1.13.0",
|
||||
"resolved": "https://registry.npmjs.org/jquery-ui/-/jquery-ui-1.13.0.tgz",
|
||||
"integrity": "sha512-Osf7ECXNTYHtKBkn9xzbIf9kifNrBhfywFEKxOeB/OVctVmLlouV9mfc2qXCp6uyO4Pn72PXKOnj09qXetopCw==",
|
||||
"version": "1.13.1",
|
||||
"resolved": "https://registry.npmjs.org/jquery-ui/-/jquery-ui-1.13.1.tgz",
|
||||
"integrity": "sha512-2VlU59N5P4HaumDK1Z3XEVjSvegFbEOQRgpHUBaB2Ak98Axl3hFhJ6RFcNQNuk9SfL6WxIbuLst8dW/U56NSiA==",
|
||||
"requires": {
|
||||
"jquery": ">=1.8.0 <4.0.0"
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
"bootstrap-colorpicker": "^2.5.3",
|
||||
"bootstrap-datepicker": "^1.9.0",
|
||||
"bootstrap-less": "^3.3.8",
|
||||
"bootstrap-table": "^1.19.1",
|
||||
"bootstrap-table": "1.18.x",
|
||||
"chart.js": "^2.9.4",
|
||||
"css-loader": "^3.6.0",
|
||||
"ekko-lightbox": "^5.1.1",
|
||||
@@ -41,7 +41,7 @@
|
||||
"imagemin": "^5.3.1",
|
||||
"jquery-form-validator": "^2.3.79",
|
||||
"jquery-slimscroll": "^1.3.8",
|
||||
"jquery-ui": "^1.13.0",
|
||||
"jquery-ui": "^1.13.1",
|
||||
"jquery-ui-bundle": "^1.12.1",
|
||||
"jquery.iframe-transport": "^1.0.0",
|
||||
"less": "^3.13.1",
|
||||
|
||||
2
public/css/dist/all.css
vendored
2
public/css/dist/all.css
vendored
File diff suppressed because one or more lines are too long
2
public/css/dist/bootstrap-table.css
vendored
2
public/css/dist/bootstrap-table.css
vendored
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -36,7 +36,7 @@
|
||||
*/
|
||||
|
||||
/*!
|
||||
* jQuery UI Widget 1.13.0
|
||||
* jQuery UI Widget 1.13.1
|
||||
* http://jqueryui.com
|
||||
*
|
||||
* Copyright jQuery Foundation and other contributors
|
||||
|
||||
2
public/js/dist/all.js
vendored
2
public/js/dist/all.js
vendored
File diff suppressed because one or more lines are too long
2
public/js/dist/bootstrap-table.js
vendored
2
public/js/dist/bootstrap-table.js
vendored
File diff suppressed because one or more lines are too long
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"/js/build/app.js": "/js/build/app.js?id=45f6fb8b6b6121469cd6",
|
||||
"/js/build/app.js": "/js/build/app.js?id=7f0aa35a0e80a6a64427",
|
||||
"/css/build/AdminLTE.css": "/css/build/AdminLTE.css?id=89f2b7816c4e00784b59",
|
||||
"/css/build/app.css": "/css/build/app.css?id=423186da9bf73779ce2a",
|
||||
"/css/build/overrides.css": "/css/build/overrides.css?id=e0c3caf0357a7ab0a2e9",
|
||||
@@ -18,15 +18,15 @@
|
||||
"/css/dist/skins/skin-blue-dark.css": "/css/dist/skins/skin-blue-dark.css?id=0409748eb4bb77fe171a",
|
||||
"/css/dist/skins/skin-orange-dark.css": "/css/dist/skins/skin-orange-dark.css?id=7abb3dcd41ad0d4700b7",
|
||||
"/css/dist/skins/skin-orange.css": "/css/dist/skins/skin-orange.css?id=96477616f4a4b4ff1db8",
|
||||
"/css/dist/all.css": "/css/dist/all.css?id=23d12dde43fa52cbc84d",
|
||||
"/css/dist/all.css": "/css/dist/all.css?id=19b5eace0db8c1559925",
|
||||
"/css/blue.png": "/css/blue.png?id=e83a6c29e04fe851f212",
|
||||
"/css/blue@2x.png": "/css/blue@2x.png?id=51135dd4d24f88f5de0b",
|
||||
"/css/dist/signature-pad.css": "/css/dist/signature-pad.css?id=6a89d3cd901305e66ced",
|
||||
"/css/dist/signature-pad.min.css": "/css/dist/signature-pad.min.css?id=6a89d3cd901305e66ced",
|
||||
"/css/dist/bootstrap-table.css": "/css/dist/bootstrap-table.css?id=810d7e520c3057ee500e",
|
||||
"/css/dist/bootstrap-table.css": "/css/dist/bootstrap-table.css?id=93c24b4c89490bbfd73e",
|
||||
"/js/build/vendor.js": "/js/build/vendor.js?id=b93877b4a88a76e1b18b",
|
||||
"/js/dist/bootstrap-table.js": "/js/dist/bootstrap-table.js?id=473d249fc27f1b907d07",
|
||||
"/js/dist/all.js": "/js/dist/all.js?id=7fbd7aad35364c6060e6",
|
||||
"/js/dist/bootstrap-table.js": "/js/dist/bootstrap-table.js?id=75760107ce879b26f156",
|
||||
"/js/dist/all.js": "/js/dist/all.js?id=1b9488168279292af5c4",
|
||||
"/css/dist/skins/skin-green.min.css": "/css/dist/skins/skin-green.min.css?id=1f137fd2dcbac676d291",
|
||||
"/css/dist/skins/skin-green-dark.min.css": "/css/dist/skins/skin-green-dark.min.css?id=af88a4cc8e58dc298963",
|
||||
"/css/dist/skins/skin-black.min.css": "/css/dist/skins/skin-black.min.css?id=5ef650950378aeb72dfa",
|
||||
|
||||
@@ -130,7 +130,6 @@
|
||||
{id: 'location', text: 'Location' },
|
||||
{id: 'maintained', text: 'Maintained' },
|
||||
{id: 'manufacturer', text: 'Manufacturer' },
|
||||
{id: 'notes', text: 'Notes' },
|
||||
{id: 'order_number', text: 'Order Number' },
|
||||
{id: 'purchase_cost', text: 'Purchase Cost' },
|
||||
{id: 'purchase_date', text: 'Purchase Date' },
|
||||
@@ -143,10 +142,13 @@
|
||||
],
|
||||
accessories:[
|
||||
{id: 'model_number', text: 'Model Number'},
|
||||
{id: 'notes', text: 'Notes' },
|
||||
],
|
||||
assets: [
|
||||
{id: 'asset_tag', text: 'Asset Tag' },
|
||||
{id: 'asset_model', text: 'Model Name' },
|
||||
{id: 'asset_notes', text: 'Asset Notes' },
|
||||
{id: 'model_notes', text: 'Model Notes' },
|
||||
{id: 'checkout_class', text: 'Checkout Type' },
|
||||
{id: 'checkout_location', text: 'Checkout Location' },
|
||||
{id: 'image', text: 'Image Filename' },
|
||||
@@ -159,6 +161,7 @@
|
||||
{id: 'item_no', text: "Item Number"},
|
||||
{id: 'model_number', text: "Model Number"},
|
||||
{id: 'min_amt', text: "Minimum Quantity"},
|
||||
{id: 'notes', text: 'Notes' },
|
||||
],
|
||||
licenses: [
|
||||
{id: 'asset_tag', text: 'Assigned To Asset'},
|
||||
@@ -166,6 +169,7 @@
|
||||
{id: 'full_name', text: 'Full Name' },
|
||||
{id: 'license_email', text: 'Licensed To Email' },
|
||||
{id: 'license_name', text: 'Licensed To Name' },
|
||||
{id: 'notes', text: 'Notes' },
|
||||
{id: 'purchase_order', text: 'Purchase Order' },
|
||||
{id: 'reassignable', text: 'Reassignable' },
|
||||
{id: 'seats', text: 'Seats' },
|
||||
@@ -178,6 +182,7 @@
|
||||
{id: 'phone_number', text: 'Phone Number' },
|
||||
{id: 'manager_first_name', text: 'Manager First Name' },
|
||||
{id: 'manager_last_name', text: 'Manager Last Name' },
|
||||
{id: 'notes', text: 'Notes' },
|
||||
{id: 'activated', text: 'Activated' },
|
||||
{id: 'address', text: 'Address' },
|
||||
{id: 'city', text: 'City' },
|
||||
|
||||
@@ -41,5 +41,7 @@ return [
|
||||
'make_required' => 'Optional - click to make required',
|
||||
'reorder' => 'Reorder',
|
||||
'db_field' => 'DB Field',
|
||||
'db_convert_warning' => 'WARNING. This field is in the custom fields table as <code> :db_column </code> but should be :expected </code>.'
|
||||
'db_convert_warning' => 'WARNING. This field is in the custom fields table as <code> :db_column </code> but should be :expected </code>.',
|
||||
'is_unique' => 'This value must be unique across all assets',
|
||||
'unique' => 'Unique',
|
||||
];
|
||||
|
||||
@@ -6,6 +6,7 @@ return [
|
||||
'archived' => 'argief',
|
||||
'asset' => 'bate',
|
||||
'bulk_checkout' => 'Checkout Assets',
|
||||
'bulk_checkin' => 'Checkin Assets',
|
||||
'checkin' => 'Kontrole bate',
|
||||
'checkout' => 'Checkout Asset',
|
||||
'clone' => 'Klone Bate',
|
||||
|
||||
@@ -17,11 +17,11 @@ return [
|
||||
'alerts_enabled' => 'Alerts aangeskakel',
|
||||
'alert_interval' => 'Uitgaande Alert Drempel (in dae)',
|
||||
'alert_inv_threshold' => 'Voorraadwaarskuwingsdrempel',
|
||||
'allow_user_skin' => 'Allow user skin',
|
||||
'allow_user_skin' => 'Allow User Skin',
|
||||
'allow_user_skin_help_text' => 'Checking this box will allow a user to override the UI skin with a different one.',
|
||||
'asset_ids' => 'Bate ID\'s',
|
||||
'audit_interval' => 'Ouditinterval',
|
||||
'audit_interval_help' => 'As u gereeld u bates fisies moet kontroleer, vul die interval in maande in.',
|
||||
'audit_interval_help' => 'If you are required to regularly physically audit your assets, enter the interval in months that you use. If you update this value, all of the "next audit dates" for assets with an upcoming audit date.',
|
||||
'audit_warning_days' => 'Oudit Waarskuwing Drempel',
|
||||
'audit_warning_days_help' => 'Hoeveel dae vooruit moet ons u waarsku wanneer bates verskuldig is vir ouditering?',
|
||||
'auto_increment_assets' => 'Generate auto-incrementing asset tags',
|
||||
@@ -32,7 +32,7 @@ return [
|
||||
'backups_upload' => 'Upload Backup',
|
||||
'backups_path' => 'Backups on the server are stored in <code>:path</code>',
|
||||
'backups_restore_warning' => 'Use the restore button <small><span class="btn btn-xs btn-warning"><i class="text-white fas fa-retweet" aria-hidden="true"></i></span></small> to restore from a previous backup. (This does not currently work with S3 file storage or Docker.<br><br>Your <strong>entire :app_name database and any uploaded files will be completely replaced</strong> by what\'s in the backup file. ',
|
||||
'backups_logged_out' => 'You will be logged out once your restore is complete.',
|
||||
'backups_logged_out' => 'All existing users, including you, will be logged out once your restore is complete.',
|
||||
'backups_large' => 'Very large backups may time out on the restore attempt and may still need to be run via command line. ',
|
||||
'barcode_settings' => 'Barcode-instellings',
|
||||
'confirm_purge' => 'Bevestig skoonmaak',
|
||||
|
||||
@@ -96,6 +96,7 @@
|
||||
'eol' => 'EOL',
|
||||
'email_domain' => 'E-pos Domein',
|
||||
'email_format' => 'E-pos formaat',
|
||||
'employee_number' => 'Employee Number',
|
||||
'email_domain_help' => 'Dit word gebruik om e-posadresse te genereer wanneer u dit invoer',
|
||||
'error' => 'Error',
|
||||
'filastname_format' => 'Eerste Voorletter (jsmith@voorbeeld.com)',
|
||||
@@ -192,6 +193,8 @@
|
||||
'qty' => 'HOEV',
|
||||
'quantity' => 'hoeveelheid',
|
||||
'quantity_minimum' => 'You have :count items below or almost below minimum quantity levels',
|
||||
'quickscan_checkin' => 'Quick Scan Checkin',
|
||||
'quickscan_checkin_status' => 'Checkin Status',
|
||||
'ready_to_deploy' => 'Klaar om te implementeer',
|
||||
'recent_activity' => 'Onlangse aktiwiteite',
|
||||
'remaining' => 'Remaining',
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
'sent' => 'Jou wagwoord skakel is gestuur!',
|
||||
'sent' => 'Success: If that email address exists in our system, a password recovery email has been sent.',
|
||||
'user' => 'No matching active user found with that email.',
|
||||
];
|
||||
|
||||
@@ -41,5 +41,7 @@ return [
|
||||
'make_required' => 'Optional - click to make required',
|
||||
'reorder' => 'Reorder',
|
||||
'db_field' => 'DB Field',
|
||||
'db_convert_warning' => 'WARNING. This field is in the custom fields table as <code> :db_column </code> but should be :expected </code>.'
|
||||
'db_convert_warning' => 'WARNING. This field is in the custom fields table as <code> :db_column </code> but should be :expected </code>.',
|
||||
'is_unique' => 'This value must be unique across all assets',
|
||||
'unique' => 'Unique',
|
||||
];
|
||||
|
||||
@@ -6,6 +6,7 @@ return [
|
||||
'archived' => 'Archived',
|
||||
'asset' => 'Asset',
|
||||
'bulk_checkout' => 'Checkout Assets',
|
||||
'bulk_checkin' => 'Checkin Assets',
|
||||
'checkin' => 'Checkin Asset',
|
||||
'checkout' => 'Checkout Asset',
|
||||
'clone' => 'Clone Asset',
|
||||
|
||||
@@ -17,11 +17,11 @@ return [
|
||||
'alerts_enabled' => 'Email Alerts Enabled',
|
||||
'alert_interval' => 'Expiring Alerts Threshold (in days)',
|
||||
'alert_inv_threshold' => 'Inventory Alert Threshold',
|
||||
'allow_user_skin' => 'Allow user skin',
|
||||
'allow_user_skin' => 'Allow User Skin',
|
||||
'allow_user_skin_help_text' => 'Checking this box will allow a user to override the UI skin with a different one.',
|
||||
'asset_ids' => 'Asset IDs',
|
||||
'audit_interval' => 'Audit Interval',
|
||||
'audit_interval_help' => 'If you are required to regularly physically audit your assets, enter the interval in months.',
|
||||
'audit_interval_help' => 'If you are required to regularly physically audit your assets, enter the interval in months that you use. If you update this value, all of the "next audit dates" for assets with an upcoming audit date.',
|
||||
'audit_warning_days' => 'Audit Warning Threshold',
|
||||
'audit_warning_days_help' => 'How many days in advance should we warn you when assets are due for auditing?',
|
||||
'auto_increment_assets' => 'Generate auto-incrementing asset tags',
|
||||
@@ -32,7 +32,7 @@ return [
|
||||
'backups_upload' => 'Upload Backup',
|
||||
'backups_path' => 'Backups on the server are stored in <code>:path</code>',
|
||||
'backups_restore_warning' => 'Use the restore button <small><span class="btn btn-xs btn-warning"><i class="text-white fas fa-retweet" aria-hidden="true"></i></span></small> to restore from a previous backup. (This does not currently work with S3 file storage or Docker.<br><br>Your <strong>entire :app_name database and any uploaded files will be completely replaced</strong> by what\'s in the backup file. ',
|
||||
'backups_logged_out' => 'You will be logged out once your restore is complete.',
|
||||
'backups_logged_out' => 'All existing users, including you, will be logged out once your restore is complete.',
|
||||
'backups_large' => 'Very large backups may time out on the restore attempt and may still need to be run via command line. ',
|
||||
'barcode_settings' => 'Barcode Settings',
|
||||
'confirm_purge' => 'Confirm Purge',
|
||||
|
||||
@@ -96,6 +96,7 @@
|
||||
'eol' => 'EOL',
|
||||
'email_domain' => 'Email Domain',
|
||||
'email_format' => 'Email Format',
|
||||
'employee_number' => 'Employee Number',
|
||||
'email_domain_help' => 'This is used to generate email addresses when importing',
|
||||
'error' => 'Error',
|
||||
'filastname_format' => 'First Initial Last Name (jsmith@example.com)',
|
||||
@@ -192,6 +193,8 @@
|
||||
'qty' => 'QTY',
|
||||
'quantity' => 'Quantity',
|
||||
'quantity_minimum' => 'You have :count items below or almost below minimum quantity levels',
|
||||
'quickscan_checkin' => 'Quick Scan Checkin',
|
||||
'quickscan_checkin_status' => 'Checkin Status',
|
||||
'ready_to_deploy' => 'Ready to Deploy',
|
||||
'recent_activity' => 'Recent Activity',
|
||||
'remaining' => 'Remaining',
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
'sent' => 'Your password link has been sent!',
|
||||
'sent' => 'Success: If that email address exists in our system, a password recovery email has been sent.',
|
||||
'user' => 'No matching active user found with that email.',
|
||||
];
|
||||
|
||||
@@ -41,5 +41,7 @@ return [
|
||||
'make_required' => 'Optional - click to make required',
|
||||
'reorder' => 'Reorder',
|
||||
'db_field' => 'DB Field',
|
||||
'db_convert_warning' => 'WARNING. This field is in the custom fields table as <code> :db_column </code> but should be :expected </code>.'
|
||||
'db_convert_warning' => 'WARNING. This field is in the custom fields table as <code> :db_column </code> but should be :expected </code>.',
|
||||
'is_unique' => 'يجب أن تكون هذه القيمة فريدة من نوعها عبر جميع الأصول',
|
||||
'unique' => 'غير مكرر',
|
||||
];
|
||||
|
||||
@@ -6,6 +6,7 @@ return [
|
||||
'archived' => 'مؤرشفة',
|
||||
'asset' => 'أصل',
|
||||
'bulk_checkout' => 'إخراج الأصول',
|
||||
'bulk_checkin' => 'ادخال الأصل',
|
||||
'checkin' => 'ادخال الأصل',
|
||||
'checkout' => 'اخراج الأصل',
|
||||
'clone' => 'استنساخ الأصل',
|
||||
|
||||
@@ -21,7 +21,7 @@ return [
|
||||
'allow_user_skin_help_text' => 'التحقق من هذا المربع سيسمح للمستخدم باستخدام مظهر واجهة المستخدم بمظهر آخر.',
|
||||
'asset_ids' => 'ارقام تعريف الاصول',
|
||||
'audit_interval' => 'مدة التدقيق',
|
||||
'audit_interval_help' => 'إذا كان مطلوبا منك مراجعة أصولك الفعلية بشكل دوري، قم بإدخال المدة بالأشهر.',
|
||||
'audit_interval_help' => 'إذا كان مطلوبا منك التدقيق المادي بانتظام في الأصول الخاصة بك، قم بإدخال الفاصل الزمني بالأشهر التي تستخدمها. إذا قمت بتحديث هذه القيمة، كل "تواريخ المراجعة التالية" للأصول مع تاريخ مراجعة الحسابات المقبل.',
|
||||
'audit_warning_days' => 'عتبة تحذير التدقيق',
|
||||
'audit_warning_days_help' => 'كم يوما مقدما يجب أن نحذركم عندما تكون الأصول مستحقة للتدقيق؟',
|
||||
'auto_increment_assets' => 'Generate auto-incrementing asset tags',
|
||||
@@ -32,7 +32,7 @@ return [
|
||||
'backups_upload' => 'Upload Backup',
|
||||
'backups_path' => 'Backups on the server are stored in <code>:path</code>',
|
||||
'backups_restore_warning' => 'Use the restore button <small><span class="btn btn-xs btn-warning"><i class="text-white fas fa-retweet" aria-hidden="true"></i></span></small> to restore from a previous backup. (This does not currently work with S3 file storage or Docker.<br><br>Your <strong>entire :app_name database and any uploaded files will be completely replaced</strong> by what\'s in the backup file. ',
|
||||
'backups_logged_out' => 'You will be logged out once your restore is complete.',
|
||||
'backups_logged_out' => 'سيتم تسجيل الخروج من جميع المستخدمين الحاليين، بما في ذلك انت، بمجرد اكتمال الاستعادة.',
|
||||
'backups_large' => 'Very large backups may time out on the restore attempt and may still need to be run via command line. ',
|
||||
'barcode_settings' => 'إعدادات الباركود',
|
||||
'confirm_purge' => 'تأكيد التطهير',
|
||||
|
||||
@@ -30,7 +30,7 @@ return [
|
||||
'superadmin_permission_warning' => 'Only superadmins may grant a user superadmin access.',
|
||||
'admin_permission_warning' => 'Only users with admins rights or greater may grant a user admin access.',
|
||||
'remove_group_memberships' => 'Remove Group Memberships',
|
||||
'warning_deletion' => 'WARNING:',
|
||||
'warning_deletion' => 'تحذير:',
|
||||
'warning_deletion_information' => 'You are about to delete the :count user(s) listed below. Super admin names are highlighted in red.',
|
||||
'update_user_asssets_status' => 'Update all assets for these users to this status',
|
||||
'checkin_user_properties' => 'Check in all properties associated with these users',
|
||||
|
||||
@@ -8,7 +8,7 @@ return [
|
||||
'delete' => 'حذف',
|
||||
'edit' => 'تعديل',
|
||||
'restore' => 'إستعادة',
|
||||
'remove' => 'إزالة',
|
||||
'remove' => 'حذف',
|
||||
'request' => 'طلب',
|
||||
'submit' => 'إرسال',
|
||||
'upload' => 'رفع',
|
||||
@@ -17,8 +17,8 @@ return [
|
||||
'generate_labels' => '{1} انشاء تسميات [2,*] توليد تسميات',
|
||||
'send_password_link' => 'إرسال رابط إعادة تعيين كلمة السر',
|
||||
'go' => 'انطلق',
|
||||
'bulk_actions' => 'Bulk Actions',
|
||||
'add_maintenance' => 'Add Maintenance',
|
||||
'append' => 'Append',
|
||||
'bulk_actions' => 'مجموعة إجراءات',
|
||||
'add_maintenance' => 'إضافة صيانة',
|
||||
'append' => 'إلحاق',
|
||||
'new' => 'جديد',
|
||||
];
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user