Compare commits
70 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a7a10455ae | ||
|
|
bd02b9ed62 | ||
|
|
16f57e16cb | ||
|
|
af6f208c43 | ||
|
|
52270fa4db | ||
|
|
bf3731d65c | ||
|
|
233ebf06ee | ||
|
|
e27f6a483d | ||
|
|
19670f9dd8 | ||
|
|
1448229cd2 | ||
|
|
4721cab928 | ||
|
|
08f3e78d26 | ||
|
|
62227ec27d | ||
|
|
10711245ba | ||
|
|
29a7c8577d | ||
|
|
dfb1ff81e6 | ||
|
|
021e723acf | ||
|
|
14c0c314aa | ||
|
|
d23ea70b08 | ||
|
|
1b047c768b | ||
|
|
e6323e0a1b | ||
|
|
73ce5f98bb | ||
|
|
a37cb616eb | ||
|
|
659d953f3f | ||
|
|
c1dcc22217 | ||
|
|
6a67426140 | ||
|
|
4ba474cf73 | ||
|
|
fb6caa35ff | ||
|
|
a5870c888e | ||
|
|
f35f8477d3 | ||
|
|
d0637d38f3 | ||
|
|
7141968d64 | ||
|
|
0f7b7d8e6a | ||
|
|
ca78b3ed7c | ||
|
|
2d2cae10b9 | ||
|
|
5e9331f5ae | ||
|
|
6e30fa6922 | ||
|
|
58b3f0519d | ||
|
|
f119c69698 | ||
|
|
57f4c986af | ||
|
|
2958630923 | ||
|
|
72dacda4f9 | ||
|
|
9c2b986bb0 | ||
|
|
06c5bce3c7 | ||
|
|
a0cbca85bf | ||
|
|
9bda62d295 | ||
|
|
1d7e243d0a | ||
|
|
63bc2ec09f | ||
|
|
d5cadeab1a | ||
|
|
31516abef9 | ||
|
|
d2535582f3 | ||
|
|
eaaea303f4 | ||
|
|
8c5312b931 | ||
|
|
4ef6e292d1 | ||
|
|
6310670835 | ||
|
|
15bb30acd6 | ||
|
|
148d41d8dc | ||
|
|
71c1c74164 | ||
|
|
9c02526a37 | ||
|
|
25dc26aac3 | ||
|
|
afc763ebac | ||
|
|
6a73ec6537 | ||
|
|
481143b891 | ||
|
|
cef67695cd | ||
|
|
4576cb6f56 | ||
|
|
56f88d2c22 | ||
|
|
c1d1cb8122 | ||
|
|
54279f22a3 | ||
|
|
dfea47a272 | ||
|
|
f0d78091d2 |
@@ -719,6 +719,15 @@
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "zwerch",
|
||||
"name": "Robin Temme",
|
||||
"avatar_url": "https://avatars2.githubusercontent.com/u/2809241?v=4",
|
||||
"profile": "https://github.com/zwerch",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ FILESYSTEM_DISK=local
|
||||
DB_CONNECTION=mysql
|
||||
DB_HOST=localhost
|
||||
DB_DATABASE=snipeit_unit
|
||||
DB_USERNAME=travis
|
||||
DB_USERNAME=root
|
||||
DB_PASSWORD=null
|
||||
|
||||
# --------------------------------------------
|
||||
|
||||
@@ -6,6 +6,9 @@ sudo: false
|
||||
# see http://about.travis-ci.org/docs/user/languages/php/ for more hints
|
||||
language: php
|
||||
|
||||
services:
|
||||
- mysql
|
||||
|
||||
# list any PHP version you want to test against
|
||||
php:
|
||||
- 5.6
|
||||
@@ -15,7 +18,10 @@ php:
|
||||
before_script:
|
||||
- phantomjs --webdriver=4444 &
|
||||
- sleep 4
|
||||
- mysql -e "create database IF NOT EXISTS snipeit_unit;" -utravis
|
||||
- mysql -e 'CREATE DATABASE snipeit_unit;'
|
||||
- mysql -e 'CREATE USER "travis'@'localhost";'
|
||||
- mysql -e 'GRANT ALL PRIVILEGES ON * . * TO "travis'@'localhost";'
|
||||
- mysql -e 'FLUSH PRIVILEGES;'
|
||||
- composer self-update
|
||||
- composer install -n --prefer-source
|
||||
- chmod -R 777 storage
|
||||
|
||||
@@ -13,6 +13,7 @@ php7.0-gd \
|
||||
php7.0-xml \
|
||||
php7.0-mbstring \
|
||||
php7.0-zip \
|
||||
php7.0-bcmath \
|
||||
patch \
|
||||
curl \
|
||||
vim \
|
||||
@@ -23,6 +24,7 @@ mysql-client \
|
||||
|
||||
RUN phpenmod mcrypt
|
||||
RUN phpenmod gd
|
||||
RUN phpenmod bcmath
|
||||
|
||||
RUN sed -i 's/variables_order = .*/variables_order = "EGPCS"/' /etc/php/7.0/apache2/php.ini
|
||||
RUN sed -i 's/variables_order = .*/variables_order = "EGPCS"/' /etc/php/7.0/cli/php.ini
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
[](https://travis-ci.org/snipe/snipe-it) [](http://waffle.io/snipe/snipe-it) []() [](https://crowdin.com/project/snipe-it) [](https://gitter.im/snipe/snipe-it?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [](https://hub.docker.com/r/snipe/snipe-it/) [](https://twitter.com/snipeyhead) [](https://zenhub.io) [](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://travis-ci.org/snipe/snipe-it) [](http://waffle.io/snipe/snipe-it) []() [](https://crowdin.com/project/snipe-it) [](https://gitter.im/snipe/snipe-it?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [](https://hub.docker.com/r/snipe/snipe-it/) [](https://twitter.com/snipeyhead) [](https://zenhub.io) [](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)
|
||||
|
||||
|
||||
## Snipe-IT - Open Source Asset Management System
|
||||
@@ -67,6 +67,7 @@ Thanks goes to all of these wonderful people ([emoji key](https://github.com/ken
|
||||
| [<img src="https://avatars0.githubusercontent.com/u/8341172?v=3" width="110px;"/><br /><sub>Jay Richards</sub>](http://www.cordeos.com)<br />[💻](https://github.com/snipe/snipe-it/commits?author=technogenus "Code") | [<img src="https://avatars2.githubusercontent.com/u/7295127?v=3" width="110px;"/><br /><sub>Alexander Innes</sub>](https://necurity.co.uk)<br />[💻](https://github.com/snipe/snipe-it/commits?author=leostat "Code") | [<img src="https://avatars2.githubusercontent.com/u/334485?v=3" width="110px;"/><br /><sub>Danny Garcia</sub>](https://buzzedword.codes)<br />[💻](https://github.com/snipe/snipe-it/commits?author=buzzedword "Code") | [<img src="https://avatars2.githubusercontent.com/u/366855?v=3" width="110px;"/><br /><sub>archpoint</sub>](https://github.com/archpoint)<br />[💻](https://github.com/snipe/snipe-it/commits?author=archpoint "Code") | [<img src="https://avatars1.githubusercontent.com/u/67991?v=3" width="110px;"/><br /><sub>Jake McGraw</sub>](http://www.jakemcgraw.com)<br />[💻](https://github.com/snipe/snipe-it/commits?author=jakemcgraw "Code") | [<img src="https://avatars1.githubusercontent.com/u/1714374?v=3" width="110px;"/><br /><sub>FleischKarussel</sub>](https://github.com/FleischKarussel)<br />[📖](https://github.com/snipe/snipe-it/commits?author=FleischKarussel "Documentation") | [<img src="https://avatars3.githubusercontent.com/u/319644?v=3" width="110px;"/><br /><sub>Dylan Yi</sub>](https://github.com/feeva)<br />[💻](https://github.com/snipe/snipe-it/commits?author=feeva "Code") |
|
||||
| [<img src="https://avatars2.githubusercontent.com/u/857740?v=3" width="110px;"/><br /><sub>Gil Rutkowski</sub>](http://FlashingCursor.com)<br />[💻](https://github.com/snipe/snipe-it/commits?author=flashingcursor "Code") | [<img src="https://avatars3.githubusercontent.com/u/129360?v=3" width="110px;"/><br /><sub>Desmond Morris</sub>](http://www.desmondmorris.com)<br />[💻](https://github.com/snipe/snipe-it/commits?author=desmondmorris "Code") | [<img src="https://avatars2.githubusercontent.com/u/52936?v=3" width="110px;"/><br /><sub>Nick Peelman</sub>](http://peelman.us)<br />[💻](https://github.com/snipe/snipe-it/commits?author=peelman "Code") | [<img src="https://avatars0.githubusercontent.com/u/53161?v=3" width="110px;"/><br /><sub>Abraham Vegh</sub>](https://abrahamvegh.com)<br />[💻](https://github.com/snipe/snipe-it/commits?author=abrahamvegh "Code") | [<img src="https://avatars0.githubusercontent.com/u/2818680?v=3" width="110px;"/><br /><sub>Mohamed Rashid</sub>](https://github.com/rashivkp)<br />[📖](https://github.com/snipe/snipe-it/commits?author=rashivkp "Documentation") | [<img src="https://avatars3.githubusercontent.com/u/1509456?v=3" width="110px;"/><br /><sub>Kasey</sub>](http://hinchk.github.io)<br />[💻](https://github.com/snipe/snipe-it/commits?author=HinchK "Code") | [<img src="https://avatars2.githubusercontent.com/u/10522541?v=3" width="110px;"/><br /><sub>Brett</sub>](https://github.com/BrettFagerlund)<br />[⚠️](https://github.com/snipe/snipe-it/commits?author=BrettFagerlund "Tests") |
|
||||
| [<img src="https://avatars2.githubusercontent.com/u/16108587?v=3" width="110px;"/><br /><sub>Jason Spriggs</sub>](http://jasonspriggs.com)<br />[💻](https://github.com/snipe/snipe-it/commits?author=jasonspriggs "Code") | [<img src="https://avatars2.githubusercontent.com/u/1134568?v=3" width="110px;"/><br /><sub>Nate Felton</sub>](http://n8felton.wordpress.com)<br />[💻](https://github.com/snipe/snipe-it/commits?author=n8felton "Code") | [<img src="https://avatars2.githubusercontent.com/u/14036694?v=3" width="110px;"/><br /><sub>Manasses Ferreira</sub>](http://homepages.dcc.ufmg.br/~manassesferreira)<br />[💻](https://github.com/snipe/snipe-it/commits?author=manassesferreira "Code") | [<img src="https://avatars0.githubusercontent.com/u/15913949?v=3" width="110px;"/><br /><sub>Steve</sub>](https://github.com/steveelwood)<br />[⚠️](https://github.com/snipe/snipe-it/commits?author=steveelwood "Tests") | [<img src="https://avatars1.githubusercontent.com/u/3361683?v=3" width="110px;"/><br /><sub>matc</sub>](http://twitter.com/matc)<br />[⚠️](https://github.com/snipe/snipe-it/commits?author=matc "Tests") | [<img src="https://avatars3.githubusercontent.com/u/7405702?v=3" width="110px;"/><br /><sub>Cole R. Davis</sub>](http://www.davisracingteam.com)<br />[⚠️](https://github.com/snipe/snipe-it/commits?author=VanillaNinjaD "Tests") | [<img src="https://avatars2.githubusercontent.com/u/10167681?v=3" width="110px;"/><br /><sub>gibsonjoshua55</sub>](https://github.com/gibsonjoshua55)<br />[💻](https://github.com/snipe/snipe-it/commits?author=gibsonjoshua55 "Code") |
|
||||
| [<img src="https://avatars2.githubusercontent.com/u/2809241?v=4" width="110px;"/><br /><sub>Robin Temme</sub>](https://github.com/zwerch)<br />[💻](https://github.com/snipe/snipe-it/commits?author=zwerch "Code") |
|
||||
<!-- ALL-CONTRIBUTORS-LIST:END -->
|
||||
|
||||
This project follows the [all-contributors](https://github.com/kentcdodds/all-contributors) specification. Contributions of any kind welcome!
|
||||
|
||||
151
app/Console/Commands/RecryptFromMcrypt.php
Normal file
151
app/Console/Commands/RecryptFromMcrypt.php
Normal file
@@ -0,0 +1,151 @@
|
||||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use App\Models\CustomField;
|
||||
use Illuminate\Console\Command;
|
||||
use App\LegacyEncrypter\McryptEncrypter;
|
||||
use App\Models\Setting;
|
||||
use App\Models\Asset;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
|
||||
class RecryptFromMcrypt extends Command
|
||||
{
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'snipeit:legacy-recrypt';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'This command allows upgrading users to de-encrypt their deprecated mcrypt encrypted fields and re-encrypt them using the current OpenSSL encryption.';
|
||||
|
||||
/**
|
||||
* Create a new command instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
|
||||
|
||||
// Check and see if they have a legacy app key listed in their .env
|
||||
// If not, we can try to use the current APP_KEY if looks like it's old
|
||||
$legacy_key = env('LEGACY_APP_KEY');
|
||||
$errors = array();
|
||||
|
||||
if (!$legacy_key) {
|
||||
$this->error('ERROR: You do not have a LEGACY_APP_KEY set in your .env file. Please locate your old APP_KEY and ADD a line to your .env file like: LEGACY_APP_KEY=YOUR_OLD_APP_KEY');
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check that the app key is 32 characters
|
||||
if (strlen($legacy_key) == 32) {
|
||||
$this->comment('INFO: Your LEGACY_APP_KEY is 32 characters. Okay to continue.');
|
||||
} else {
|
||||
$this->error('ERROR: Your LEGACY_APP_KEY is not the correct length (32 characters). Please locate your old APP_KEY and use that as your LEGACY_APP_KEY in your .env file to continue.');
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->error('================================!!!! WARNING !!!!================================');
|
||||
$this->error('================================!!!! WARNING !!!!================================');
|
||||
$this->comment("This tool will attempt to decrypt your old Snipe-IT (mcrypt, now deprecated) encrypted data and re-encrypt it using OpenSSL. \n\nYou should only continue if you have backed up any and all old APP_KEYs and have backed up your data.");
|
||||
|
||||
if ($this->confirm("Are you SURE you wish to continue?")) {
|
||||
|
||||
$backup_file = 'backups/env-backups/'.'app_key-'.date('Y-m-d-gis');
|
||||
|
||||
try {
|
||||
Storage::disk('local')->put($backup_file, 'APP_KEY: '.config('app.key'));
|
||||
Storage::disk('local')->append($backup_file, 'LEGACY_APP_KEY: '.$legacy_key);
|
||||
} catch (\Exception $e) {
|
||||
$this->info('WARNING: Could not backup app keys');
|
||||
}
|
||||
|
||||
|
||||
$mcrypter = new McryptEncrypter($legacy_key);
|
||||
$settings = Setting::getSettings();
|
||||
|
||||
if ($settings->ldap_password=='') {
|
||||
$this->comment('INFO: No LDAP password found. Skipping... ');
|
||||
}
|
||||
|
||||
$custom_fields = CustomField::where('field_encrypted','=', 1)->get();
|
||||
$this->comment('INFO: Retrieving encrypted custom fields...');
|
||||
|
||||
$query = Asset::withTrashed();
|
||||
|
||||
foreach ($custom_fields as $custom_field) {
|
||||
$this->comment('FIELD TO RECRYPT: '.$custom_field->name .' ('.$custom_field->db_column.')');
|
||||
$query->orWhereNotNull($custom_field->db_column);
|
||||
}
|
||||
|
||||
|
||||
// Get all assets with a value in any of the fields that were encrypted
|
||||
$assets = $query->get();
|
||||
|
||||
$bar = $this->output->createProgressBar(count($assets));
|
||||
|
||||
foreach ($custom_fields as $encrypted_field) {
|
||||
|
||||
// Try to decrypt the payload using the legacy app key
|
||||
try {
|
||||
$decrypted_field = $mcrypter->decrypt($encrypted_field);
|
||||
$this->comment($decrypted_field);
|
||||
} catch (\Exception $e) {
|
||||
$errors[] = ' - ERROR: Could not decrypt field ['.$encrypted_field->name.']: '.$e->getMessage();
|
||||
}
|
||||
$bar->advance();
|
||||
}
|
||||
|
||||
|
||||
foreach ($assets as $asset) {
|
||||
foreach ($custom_fields as $encrypted_field) {
|
||||
|
||||
// Make sure the value isn't null
|
||||
if ($asset->{$encrypted_field}!='') {
|
||||
// Try to decrypt the payload using the legacy app key
|
||||
try {
|
||||
$decrypted_field = $mcrypter->decrypt($asset->{$encrypted_field});
|
||||
$asset->{$encrypted_field} = \Crypt::encrypt($decrypted_field);
|
||||
$this->comment($decrypted_field);
|
||||
} catch (\Exception $e) {
|
||||
$errors[] = ' - ERROR: Could not decrypt field ['.$encrypted_field->name.']: '.$e->getMessage();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
$asset->save();
|
||||
$bar->advance();
|
||||
}
|
||||
|
||||
|
||||
|
||||
$bar->finish();
|
||||
|
||||
if (count($errors) > 0) {
|
||||
$this->comment("\n\n");
|
||||
$this->error("The decrypter encountered some errors: \n");
|
||||
foreach ($errors as $error) {
|
||||
$this->error($error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -23,7 +23,8 @@ class Kernel extends ConsoleKernel
|
||||
Commands\DisableLDAP::class,
|
||||
Commands\Purge::class,
|
||||
Commands\LdapSync::class,
|
||||
Commands\FixDoubleEscape::class
|
||||
Commands\FixDoubleEscape::class,
|
||||
Commands\RecryptFromMcrypt::class
|
||||
];
|
||||
|
||||
/**
|
||||
|
||||
@@ -80,7 +80,7 @@ class Handler extends ExceptionHandler
|
||||
|
||||
}
|
||||
}
|
||||
// Try to parse 500 Errors ina bit nicer way when debug is enabled.
|
||||
// Try to parse 500 Errors in a bit nicer way when debug is enabled.
|
||||
if (config('app.debug')) {
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, "An Error has occured! " . $e->getMessage()), 500);
|
||||
}
|
||||
|
||||
@@ -683,12 +683,11 @@ class Helper
|
||||
public static function formatStandardApiResponse($status, $payload = null, $messages = null) {
|
||||
|
||||
$array['status'] = $status;
|
||||
($payload) ? $array['payload'] = $payload : '';
|
||||
|
||||
$array['messages'] = $messages;
|
||||
if (($messages) && (count($messages) > 0)) {
|
||||
$array['messages'] = $messages;
|
||||
}
|
||||
|
||||
($payload) ? $array['payload'] = $payload : $array['payload'] = null;
|
||||
return $array;
|
||||
}
|
||||
|
||||
|
||||
226
app/Http/Controllers/Api/AssetMaintenancesController.php
Normal file
226
app/Http/Controllers/Api/AssetMaintenancesController.php
Normal file
@@ -0,0 +1,226 @@
|
||||
<?php
|
||||
namespace App\Http\Controllers\Api;
|
||||
|
||||
use App\Models\AssetMaintenance;
|
||||
use Carbon\Carbon;
|
||||
use App\Models\Company;
|
||||
use App\Models\Asset;
|
||||
use App\Helpers\Helper;
|
||||
use Auth;
|
||||
use Gate;
|
||||
use Illuminate\Http\Request;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Transformers\AssetMaintenancesTransformer;
|
||||
|
||||
/**
|
||||
* This controller handles all actions related to Asset Maintenance for
|
||||
* the Snipe-IT Asset Management application.
|
||||
*
|
||||
* @version v2.0
|
||||
*/
|
||||
class AssetMaintenancesController extends Controller
|
||||
{
|
||||
|
||||
|
||||
/**
|
||||
* Generates the JSON response for asset maintenances listing view.
|
||||
*
|
||||
* @see AssetMaintenancesController::getIndex() method that generates view
|
||||
* @author Vincent Sposato <vincent.sposato@gmail.com>
|
||||
* @version v1.0
|
||||
* @since [v1.8]
|
||||
* @return String JSON
|
||||
*/
|
||||
public function index(Request $request)
|
||||
{
|
||||
$maintenances = AssetMaintenance::with('asset', 'supplier', 'asset.company', 'admin');
|
||||
|
||||
if (Input::has('search')) {
|
||||
$maintenances = $maintenances->TextSearch(e($request->input('search')));
|
||||
}
|
||||
|
||||
$offset = request('offset', 0);
|
||||
$limit = request('limit', 50);
|
||||
|
||||
$allowed_columns = ['id','title','asset_maintenance_time','asset_maintenance_type','cost','start_date','completion_date','notes','user_id'];
|
||||
$order = Input::get('order') === 'asc' ? 'asc' : 'desc';
|
||||
$sort = in_array(Input::get('sort'), $allowed_columns) ? e($request->input('sort')) : 'created_at';
|
||||
|
||||
switch ($sort) {
|
||||
case 'user_id':
|
||||
$maintenances = $maintenances->OrderAdmin($order);
|
||||
break;
|
||||
default:
|
||||
$maintenances = $maintenances->orderBy($sort, $order);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
$maintenances = $maintenances->skip($offset)->take($limit)->get();
|
||||
|
||||
|
||||
return (new AssetMaintenancesTransformer())->transformAssetMaintenances($maintenances, $maintenances->count());
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Validates and stores the new asset maintenance
|
||||
*
|
||||
* @see AssetMaintenancesController::getCreate() method for the form
|
||||
* @author Vincent Sposato <vincent.sposato@gmail.com>
|
||||
* @version v1.0
|
||||
* @since [v1.8]
|
||||
* @return String JSON
|
||||
*/
|
||||
public function store(Request $request)
|
||||
{
|
||||
// create a new model instance
|
||||
$assetMaintenance = new AssetMaintenance();
|
||||
$assetMaintenance->supplier_id = $request->input('supplier_id');
|
||||
$assetMaintenance->is_warranty = $request->input('is_warranty');
|
||||
$assetMaintenance->cost = e($request->input('cost'));
|
||||
$assetMaintenance->notes = e($request->input('notes'));
|
||||
$asset = Asset::find(e($request->input('asset_id')));
|
||||
|
||||
if (!Company::isCurrentUserHasAccess($asset)) {
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, 'You cannot add a maintenance for that asset'));
|
||||
}
|
||||
|
||||
// Save the asset maintenance data
|
||||
$assetMaintenance->asset_id = $request->input('asset_id');
|
||||
$assetMaintenance->asset_maintenance_type = $request->input('asset_maintenance_type');
|
||||
$assetMaintenance->title = $request->input('title');
|
||||
$assetMaintenance->start_date = $request->input('start_date');
|
||||
$assetMaintenance->completion_date = $request->input('completion_date');
|
||||
$assetMaintenance->user_id = Auth::id();
|
||||
|
||||
if (( $assetMaintenance->completion_date !== null )
|
||||
&& ( $assetMaintenance->start_date !== "" )
|
||||
&& ( $assetMaintenance->start_date !== "0000-00-00" )
|
||||
) {
|
||||
$startDate = Carbon::parse($assetMaintenance->start_date);
|
||||
$completionDate = Carbon::parse($assetMaintenance->completion_date);
|
||||
$assetMaintenance->asset_maintenance_time = $completionDate->diffInDays($startDate);
|
||||
}
|
||||
|
||||
// Was the asset maintenance created?
|
||||
if ($assetMaintenance->save()) {
|
||||
return response()->json(Helper::formatStandardApiResponse('success', $assetMaintenance, trans('admin/asset_maintenances/message.create.success')));
|
||||
|
||||
}
|
||||
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, $assetMaintenance->getErrors()));
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Validates and stores an update to an asset maintenance
|
||||
*
|
||||
* @author A. Gianotto <snipe@snipe.net>
|
||||
* @param int $assetMaintenanceId
|
||||
* @param int $request
|
||||
* @version v1.0
|
||||
* @since [v4.0]
|
||||
* @return String JSON
|
||||
*/
|
||||
public function update(Request $request, $assetMaintenanceId = null)
|
||||
{
|
||||
// Check if the asset maintenance exists
|
||||
$assetMaintenance = AssetMaintenance::findOrFail($assetMaintenanceId);
|
||||
|
||||
if (!Company::isCurrentUserHasAccess($assetMaintenance->asset)) {
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, 'You cannot edit a maintenance for that asset'));
|
||||
}
|
||||
|
||||
$assetMaintenance->supplier_id = e($request->input('supplier_id'));
|
||||
$assetMaintenance->is_warranty = e($request->input('is_warranty'));
|
||||
$assetMaintenance->cost = Helper::ParseFloat(e($request->input('cost')));
|
||||
$assetMaintenance->notes = e($request->input('notes'));
|
||||
|
||||
$asset = Asset::find(request('asset_id'));
|
||||
|
||||
if (!Company::isCurrentUserHasAccess($asset)) {
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, 'You cannot edit a maintenance for that asset'));
|
||||
}
|
||||
|
||||
// Save the asset maintenance data
|
||||
$assetMaintenance->asset_id = $request->input('asset_id');
|
||||
$assetMaintenance->asset_maintenance_type = $request->input('asset_maintenance_type');
|
||||
$assetMaintenance->title = $request->input('title');
|
||||
$assetMaintenance->start_date = $request->input('start_date');
|
||||
$assetMaintenance->completion_date = $request->input('completion_date');
|
||||
|
||||
if (( $assetMaintenance->completion_date == null )
|
||||
) {
|
||||
if (( $assetMaintenance->asset_maintenance_time !== 0 )
|
||||
|| ( !is_null($assetMaintenance->asset_maintenance_time) )
|
||||
) {
|
||||
$assetMaintenance->asset_maintenance_time = null;
|
||||
}
|
||||
}
|
||||
|
||||
if (( $assetMaintenance->completion_date !== null )
|
||||
&& ( $assetMaintenance->start_date !== "" )
|
||||
&& ( $assetMaintenance->start_date !== "0000-00-00" )
|
||||
) {
|
||||
$startDate = Carbon::parse($assetMaintenance->start_date);
|
||||
$completionDate = Carbon::parse($assetMaintenance->completion_date);
|
||||
$assetMaintenance->asset_maintenance_time = $completionDate->diffInDays($startDate);
|
||||
}
|
||||
|
||||
// Was the asset maintenance created?
|
||||
if ($assetMaintenance->save()) {
|
||||
|
||||
return response()->json(Helper::formatStandardApiResponse('success', $assetMaintenance, trans('admin/asset_maintenances/message.edit.success')));
|
||||
|
||||
}
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, $assetMaintenance->getErrors()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete an asset maintenance
|
||||
*
|
||||
* @author A. Gianotto <snipe@snipe.net>
|
||||
* @param int $assetMaintenanceId
|
||||
* @version v1.0
|
||||
* @since [v4.0]
|
||||
* @return String JSON
|
||||
*/
|
||||
public function destroy($assetMaintenanceId)
|
||||
{
|
||||
// Check if the asset maintenance exists
|
||||
$assetMaintenance = AssetMaintenance::findOrFail($assetMaintenanceId);
|
||||
|
||||
if (!Company::isCurrentUserHasAccess($assetMaintenance->asset)) {
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, 'You cannot delete a maintenance for that asset'));
|
||||
}
|
||||
|
||||
$assetMaintenance->delete();
|
||||
|
||||
return response()->json(Helper::formatStandardApiResponse('success', $assetMaintenance, trans('admin/asset_maintenances/message.delete.success')));
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* View an asset maintenance
|
||||
*
|
||||
* @author A. Gianotto <snipe@snipe.net>
|
||||
* @param int $assetMaintenanceId
|
||||
* @version v1.0
|
||||
* @since [v4.0]
|
||||
* @return String JSON
|
||||
*/
|
||||
public function show($assetMaintenanceId)
|
||||
{
|
||||
$assetMaintenance = AssetMaintenance::findOrFail($assetMaintenanceId);
|
||||
if (!Company::isCurrentUserHasAccess($assetMaintenance->asset)) {
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, 'You cannot view a maintenance for that asset'));
|
||||
}
|
||||
return (new AssetMaintenancesTransformer())->transformAssetMaintenance($assetMaintenance);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -76,7 +76,7 @@ class AssetModelsController extends Controller
|
||||
$assetmodel->fill($request->all());
|
||||
|
||||
if ($assetmodel->save()) {
|
||||
return response()->json(Helper::formatStandardApiResponse('success', $assetmodel, trans('admin/assetmodels/message.create.success')));
|
||||
return response()->json(Helper::formatStandardApiResponse('success', $assetmodel, trans('admin/models/message.create.success')));
|
||||
}
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, $assetmodel->getErrors()));
|
||||
|
||||
|
||||
@@ -31,6 +31,7 @@ use TCPDF;
|
||||
use Validator;
|
||||
use View;
|
||||
|
||||
|
||||
/**
|
||||
* This class controls all actions related to assets for
|
||||
* the Snipe-IT Asset Management application.
|
||||
@@ -231,7 +232,8 @@ class AssetsController extends Controller
|
||||
*/
|
||||
public function store(AssetRequest $request)
|
||||
{
|
||||
// $this->authorize('create', Asset::class);
|
||||
|
||||
$this->authorize('create', Asset::class);
|
||||
|
||||
$asset = new Asset();
|
||||
$asset->model()->associate(AssetModel::find((int) $request->get('model_id')));
|
||||
@@ -279,6 +281,7 @@ class AssetsController extends Controller
|
||||
}
|
||||
return response()->json(Helper::formatStandardApiResponse('success', $asset, trans('admin/hardware/message.create.success')));
|
||||
}
|
||||
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, $asset->getErrors()), 200);
|
||||
}
|
||||
|
||||
@@ -494,4 +497,33 @@ class AssetsController extends Controller
|
||||
|
||||
return response()->json(Helper::formatStandardApiResponse('success', ['asset'=> e($asset->asset_tag)], trans('admin/hardware/message.checkin.error')));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Mark an asset as audited
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @param int $id
|
||||
* @since [v4.0]
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function audit(Request $request, $id) {
|
||||
|
||||
$this->authorize('audit', Asset::class);
|
||||
|
||||
$rules = array(
|
||||
'id' => 'required'
|
||||
);
|
||||
|
||||
$validator = \Validator::make($request->all(), $rules);
|
||||
|
||||
$asset = Asset::findOrFail($id);
|
||||
$asset->next_audit_date = $request->input('next_audit_date');
|
||||
|
||||
if ($asset->save()) {
|
||||
$asset->logAudit(request('note'));
|
||||
return response()->json(Helper::formatStandardApiResponse('success', ['asset'=> e($asset->asset_tag)], trans('admin/hardware/message.audit.success')));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ class CategoriesController extends Controller
|
||||
$this->authorize('view', Category::class);
|
||||
$allowed_columns = ['id', 'name','category_type','use_default_eula','require_acceptance','checkin_email'];
|
||||
|
||||
$categories = Category::select(['id', 'name','category_type','use_default_eula','require_acceptance','checkin_email'])
|
||||
$categories = Category::select(['id', 'created_at', 'updated_at', 'name','category_type','use_default_eula','require_acceptance','checkin_email'])
|
||||
->withCount('assets', 'accessories', 'consumables', 'components');
|
||||
|
||||
if ($request->has('search')) {
|
||||
@@ -75,7 +75,8 @@ class CategoriesController extends Controller
|
||||
{
|
||||
$this->authorize('view', Category::class);
|
||||
$category = Category::findOrFail($id);
|
||||
return $category;
|
||||
return (new CategoriesTransformer)->transformCategory($category);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -99,16 +99,14 @@ class DepartmentsController extends Controller
|
||||
*/
|
||||
public function destroy($id)
|
||||
{
|
||||
if (is_null($department = Department::find($id))) {
|
||||
return redirect()->to(route('departments.index'))->with('error', trans('admin/departments/message.not_found'));
|
||||
}
|
||||
$department = Department::findOrFail($id);
|
||||
|
||||
if ($department->users->count() > 0) {
|
||||
return redirect()->to(route('departments.index'))->with('error', trans('admin/departments/message.assoc_users'));
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, trans('admin/departments/message.assoc_users')));
|
||||
}
|
||||
|
||||
$department->delete();
|
||||
return redirect()->to(route('departments.index'))->with('success', trans('admin/departments/message.delete.success'));
|
||||
return response()->json(Helper::formatStandardApiResponse('success', null, trans('admin/departments/message.delete.success')));
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -59,6 +59,10 @@ class LicensesController extends Controller
|
||||
$licenses->where('manufacturer_id','=',$request->input('manufacturer_id'));
|
||||
}
|
||||
|
||||
if ($request->has('supplier_id')) {
|
||||
$licenses->where('supplier_id','=',$request->input('supplier_id'));
|
||||
}
|
||||
|
||||
if ($request->has('depreciation_id')) {
|
||||
$licenses->where('depreciation_id','=',$request->input('depreciation_id'));
|
||||
}
|
||||
@@ -69,22 +73,26 @@ class LicensesController extends Controller
|
||||
|
||||
$offset = request('offset', 0);
|
||||
$limit = request('limit', 50);
|
||||
|
||||
$allowed_columns = ['id','name','purchase_cost','expiration_date','purchase_order','order_number','notes','purchase_date','serial','manufacturer','company','license_name','license_email'];
|
||||
$order = $request->input('order') === 'asc' ? 'asc' : 'desc';
|
||||
$sort = in_array($request->input('sort'), $allowed_columns) ? e($request->input('sort')) : 'created_at';
|
||||
|
||||
switch ($sort) {
|
||||
|
||||
switch ($request->input('sort')) {
|
||||
case 'manufacturer':
|
||||
$licenses = $licenses->OrderManufacturer($order);
|
||||
break;
|
||||
case 'supplier':
|
||||
$licenses = $licenses->OrderSupplier($order);
|
||||
break;
|
||||
case 'company':
|
||||
$licenses = $licenses->OrderCompany($order);
|
||||
break;
|
||||
default:
|
||||
$allowed_columns = ['id','name','purchase_cost','expiration_date','purchase_order','order_number','notes','purchase_date','serial','company','license_name','license_email'];
|
||||
$sort = in_array($request->input('sort'), $allowed_columns) ? e($request->input('sort')) : 'created_at';
|
||||
$licenses = $licenses->orderBy($sort, $order);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
$total = $licenses->count();
|
||||
$licenses = $licenses->skip($offset)->take($limit)->get();
|
||||
|
||||
@@ -21,7 +21,7 @@ class LocationsController extends Controller
|
||||
{
|
||||
$this->authorize('view', Location::class);
|
||||
$allowed_columns = ['id','name','address','address2','city','state','country','zip','created_at',
|
||||
'updated_at','parent_id'];
|
||||
'updated_at','parent_id', 'manager_id'];
|
||||
|
||||
$locations = Location::select([
|
||||
'locations.id',
|
||||
@@ -33,6 +33,7 @@ class LocationsController extends Controller
|
||||
'locations.zip',
|
||||
'locations.country',
|
||||
'locations.parent_id',
|
||||
'locations.manager_id',
|
||||
'locations.created_at',
|
||||
'locations.updated_at',
|
||||
'locations.currency'
|
||||
|
||||
@@ -36,6 +36,10 @@ class ReportsController extends Controller
|
||||
->where('item_type','=',"App\\Models\\".ucwords($request->input('item_type')));
|
||||
}
|
||||
|
||||
if ($request->has('action_type')) {
|
||||
$actionlogs = $actionlogs->where('action_type','=',$request->input('action_type'))->orderBy('created_at', 'desc');
|
||||
}
|
||||
|
||||
$allowed_columns = [
|
||||
'id',
|
||||
'created_at'
|
||||
|
||||
@@ -53,9 +53,20 @@ class StatuslabelsController extends Controller
|
||||
public function store(Request $request)
|
||||
{
|
||||
$this->authorize('create', Statuslabel::class);
|
||||
$request->except('deployable', 'pending','archived');
|
||||
|
||||
if (!$request->has('type')) {
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, ["type" => ["Status label type is required."]]));
|
||||
}
|
||||
|
||||
$statuslabel = new Statuslabel;
|
||||
$statuslabel->fill($request->all());
|
||||
|
||||
$statusType = Statuslabel::getStatuslabelTypesForDB($request->input('type'));
|
||||
$statuslabel->deployable = $statusType['deployable'];
|
||||
$statuslabel->pending = $statusType['pending'];
|
||||
$statuslabel->archived = $statusType['archived'];
|
||||
|
||||
if ($statuslabel->save()) {
|
||||
return response()->json(Helper::formatStandardApiResponse('success', $statuslabel, trans('admin/statuslabels/message.create.success')));
|
||||
}
|
||||
@@ -75,7 +86,7 @@ class StatuslabelsController extends Controller
|
||||
{
|
||||
$this->authorize('view', Statuslabel::class);
|
||||
$statuslabel = Statuslabel::findOrFail($id);
|
||||
return $statuslabel;
|
||||
return (new StatuslabelsTransformer)->transformStatuslabel($statuslabel);
|
||||
}
|
||||
|
||||
|
||||
@@ -92,8 +103,20 @@ class StatuslabelsController extends Controller
|
||||
{
|
||||
$this->authorize('edit', Statuslabel::class);
|
||||
$statuslabel = Statuslabel::findOrFail($id);
|
||||
|
||||
$request->except('deployable', 'pending','archived');
|
||||
|
||||
if (!$request->has('type')) {
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, 'Status label type is required.'));
|
||||
}
|
||||
|
||||
$statuslabel->fill($request->all());
|
||||
|
||||
$statusType = Statuslabel::getStatuslabelTypesForDB($request->input('type'));
|
||||
$statuslabel->deployable = $statusType['deployable'];
|
||||
$statuslabel->pending = $statusType['pending'];
|
||||
$statuslabel->archived = $statusType['archived'];
|
||||
|
||||
if ($statuslabel->save()) {
|
||||
return response()->json(Helper::formatStandardApiResponse('success', $statuslabel, trans('admin/statuslabels/message.update.success')));
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ use App\Http\Transformers\UsersTransformer;
|
||||
use App\Models\Company;
|
||||
use App\Models\User;
|
||||
use App\Helpers\Helper;
|
||||
use App\Http\Requests\SaveUserRequest;
|
||||
|
||||
class UsersController extends Controller
|
||||
{
|
||||
@@ -102,7 +103,7 @@ class UsersController extends Controller
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function store(Request $request)
|
||||
public function store(SaveUserRequest $request)
|
||||
{
|
||||
$this->authorize('view', User::class);
|
||||
$user = new User;
|
||||
@@ -139,7 +140,7 @@ class UsersController extends Controller
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function update(Request $request, $id)
|
||||
public function update(SaveUserRequest $request, $id)
|
||||
{
|
||||
$this->authorize('edit', User::class);
|
||||
$user = User::findOrFail($id);
|
||||
|
||||
@@ -414,7 +414,7 @@ class AssetModelsController extends Controller
|
||||
$manufacturer_list = $nochange + Helper::manufacturerList();
|
||||
|
||||
|
||||
return view('models/bulk-edit', compact('models'))
|
||||
return view('models/bulk-edit', compact('models'))
|
||||
->with('manufacturer_list', $manufacturer_list)
|
||||
->with('category_list', $category_list)
|
||||
->with('fieldset_list', $fieldset_list)
|
||||
|
||||
@@ -116,9 +116,9 @@ class AssetsController extends Controller
|
||||
->with('statuslabel_list', Helper::statusLabelList())
|
||||
->with('location_list', Helper::locationsList())
|
||||
->with('item', new Asset)
|
||||
->with('manufacturer', Helper::manufacturerList())
|
||||
->with('category', Helper::categoryList('asset'))
|
||||
->with('statuslabel_types', Helper::statusTypeList())
|
||||
->with('manufacturer', Helper::manufacturerList()) //handled in modal now?
|
||||
->with('category', Helper::categoryList('asset')) //handled in modal now?
|
||||
->with('statuslabel_types', Helper::statusTypeList()) //handled in modal now?
|
||||
->with('users_list', Helper::usersList())
|
||||
->with('assets_list', Helper::assetsList())
|
||||
->with('locations_list', Helper::locationsList());
|
||||
@@ -595,9 +595,12 @@ class AssetsController extends Controller
|
||||
*/
|
||||
public function show($assetId = null)
|
||||
{
|
||||
|
||||
$asset = Asset::withTrashed()->find($assetId);
|
||||
$settings = Setting::getSettings();
|
||||
$this->authorize('view', $asset);
|
||||
$settings = Setting::getSettings();
|
||||
$audit_log = Actionlog::where('action_type','=','audit')->where('item_id','=',$assetId)->where('item_type','=',Asset::class)->orderBy('created_at','DESC')->first();
|
||||
|
||||
|
||||
if (isset($asset)) {
|
||||
|
||||
@@ -617,7 +620,8 @@ class AssetsController extends Controller
|
||||
'url' => route('qr_code/hardware', $asset->id)
|
||||
);
|
||||
|
||||
return view('hardware/view', compact('asset', 'qr_code', 'settings'))->with('use_currency', $use_currency);
|
||||
return view('hardware/view', compact('asset', 'qr_code', 'settings'))
|
||||
->with('use_currency', $use_currency)->with('audit_log',$audit_log);
|
||||
}
|
||||
|
||||
return redirect()->route('hardware.index')->with('error', trans('admin/hardware/message.does_not_exist', compact('id')));
|
||||
@@ -1233,4 +1237,29 @@ class AssetsController extends Controller
|
||||
// Redirect to the asset management page with error
|
||||
return redirect()->to("hardware/bulk-checkout")->with('error', trans('admin/hardware/message.checkout.error'))->withErrors($errors);
|
||||
}
|
||||
|
||||
public function audit(Request $request, $id)
|
||||
{
|
||||
$this->authorize('audit', Asset::class);
|
||||
|
||||
$dt = Carbon::now()->addMonths(12)->toDateString();
|
||||
|
||||
$asset = Asset::findOrFail($id);
|
||||
return view('hardware/audit')->with('asset', $asset)->with('next_audit_date', $dt);
|
||||
}
|
||||
|
||||
public function auditStore(Request $request, $id)
|
||||
{
|
||||
$this->authorize('audit', Asset::class);
|
||||
|
||||
$asset = Asset::findOrFail($id);
|
||||
$asset->next_audit_date = $request->input('next_audit_date');
|
||||
|
||||
if ($asset->save()) {
|
||||
$asset->logAudit(request('note'));
|
||||
return redirect()->to("hardware")->with('success', trans('admin/hardware/message.audit.success'));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -63,7 +63,8 @@ class LocationsController extends Controller
|
||||
|
||||
return view('locations/edit')
|
||||
->with('location_options', $location_options)
|
||||
->with('item', new Location);
|
||||
->with('item', new Location)
|
||||
->with('manager_list', Helper::managerList());
|
||||
}
|
||||
|
||||
|
||||
@@ -88,6 +89,7 @@ class LocationsController extends Controller
|
||||
$location->state = Input::get('state');
|
||||
$location->country = Input::get('country');
|
||||
$location->zip = Input::get('zip');
|
||||
$location->manager_id = Input::get('manager_id');
|
||||
$location->user_id = Auth::id();
|
||||
|
||||
if ($location->save()) {
|
||||
@@ -154,7 +156,10 @@ class LocationsController extends Controller
|
||||
$location_options = Location::flattenLocationsArray($location_options_array);
|
||||
$location_options = array('' => 'Top Level') + $location_options;
|
||||
|
||||
return view('locations/edit', compact('item'))->with('location_options', $location_options);
|
||||
|
||||
return view('locations/edit', compact('item'))
|
||||
->with('location_options', $location_options)
|
||||
->with('manager_list', Helper::managerList());
|
||||
}
|
||||
|
||||
|
||||
@@ -185,6 +190,7 @@ class LocationsController extends Controller
|
||||
$location->country = Input::get('country');
|
||||
$location->zip = Input::get('zip');
|
||||
$location->ldap_ou = Input::get('ldap_ou');
|
||||
$location->manager_id = Input::get('manager_id');
|
||||
|
||||
// Was the location updated?
|
||||
if ($location->save()) {
|
||||
@@ -232,8 +238,6 @@ class LocationsController extends Controller
|
||||
* the content for the locations detail page.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @see LocationsController::getDataViewUsers() method that returns JSON for location users
|
||||
* @see LocationsController::getDataViewAssets() method that returns JSON for location assets
|
||||
* @param int $locationId
|
||||
* @since [v1.0]
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
@@ -252,78 +256,4 @@ class LocationsController extends Controller
|
||||
return redirect()->route('locations.index')->with('error', $error);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a JSON response that contains the users association with the
|
||||
* selected location, to be used by the location detail view.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @see LocationsController::getView() method that creates the display view
|
||||
* @param $locationID
|
||||
* @return array
|
||||
* @internal param int $locationId
|
||||
* @since [v1.8]
|
||||
*/
|
||||
public function getDataViewUsers($locationID)
|
||||
{
|
||||
$location = Location::find($locationID);
|
||||
$users = User::where('location_id', '=', $location->id);
|
||||
|
||||
if (Input::has('search')) {
|
||||
$users = $users->TextSearch(e(Input::get('search')));
|
||||
}
|
||||
|
||||
$users = $users->get();
|
||||
$rows = array();
|
||||
|
||||
foreach ($users as $user) {
|
||||
$rows[] = array(
|
||||
'name' => (string)link_to_route('users.show', e($user->present()->fullName()), ['user'=>$user->id])
|
||||
);
|
||||
}
|
||||
|
||||
$data = array('total' => $users->count(), 'rows' => $rows);
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a JSON response that contains the assets association with the
|
||||
* selected location, to be used by the location detail view.
|
||||
*
|
||||
* @todo This is broken for accessories and consumables.
|
||||
* @todo This is a very naive implementation. Should clean this up with query scopes.
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @see LocationsController::getView() method that creates the display view
|
||||
* @param int $locationID
|
||||
* @since [v1.8]
|
||||
* @return array
|
||||
*/
|
||||
public function getDataViewAssets($locationID)
|
||||
{
|
||||
$location = Location::find($locationID)->load('assignedassets.model');
|
||||
$assets = Asset::AssetsByLocation($location);
|
||||
|
||||
if (Input::has('search')) {
|
||||
$assets = $assets->TextSearch(e(Input::get('search')));
|
||||
}
|
||||
|
||||
$assets = $assets->get();
|
||||
|
||||
$rows = array();
|
||||
|
||||
foreach ($assets as $asset) {
|
||||
$rows[] = [
|
||||
'name' => (string)link_to_route('hardware.show', e($asset->present()->name()), ['hardware' => $asset->id]),
|
||||
'asset_tag' => e($asset->asset_tag),
|
||||
'serial' => e($asset->serial),
|
||||
'model' => e($asset->model->name),
|
||||
];
|
||||
}
|
||||
|
||||
$data = array('total' => $assets->count(), 'rows' => $rows);
|
||||
return $data;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
32
app/Http/Controllers/ModalController.php
Normal file
32
app/Http/Controllers/ModalController.php
Normal file
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
use App\Helpers\Helper;
|
||||
|
||||
class ModalController extends Controller
|
||||
{
|
||||
function location() {
|
||||
return view('modals.location');
|
||||
}
|
||||
|
||||
function model() {
|
||||
return view('modals.model')
|
||||
->with('manufacturer', Helper::manufacturerList())
|
||||
->with('category', Helper::categoryList('asset'));
|
||||
}
|
||||
|
||||
function statuslabel() {
|
||||
return view('modals.statuslabel')->with('statuslabel_types', Helper::statusTypeList());
|
||||
}
|
||||
|
||||
function supplier() {
|
||||
return view('modals.supplier');
|
||||
}
|
||||
|
||||
function user() {
|
||||
return view('modals.user');
|
||||
}
|
||||
}
|
||||
@@ -4,12 +4,13 @@ namespace App\Http\Controllers;
|
||||
use Image;
|
||||
use Input;
|
||||
use Redirect;
|
||||
use App\Models\Location;
|
||||
use View;
|
||||
use Auth;
|
||||
use App\Helpers\Helper;
|
||||
use App\Models\Setting;
|
||||
use Gate;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
|
||||
/**
|
||||
* This controller handles all actions related to User Profiles for
|
||||
@@ -87,4 +88,60 @@ class ProfileController extends Controller
|
||||
public function api() {
|
||||
return view('account/api');
|
||||
}
|
||||
|
||||
/**
|
||||
* User change email page.
|
||||
*
|
||||
* @return View
|
||||
*/
|
||||
public function password()
|
||||
{
|
||||
$user = Auth::user();
|
||||
return view('account/change-password', compact('user'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Users change password form processing page.
|
||||
*
|
||||
* @return Redirect
|
||||
*/
|
||||
public function passwordSave(Request $request)
|
||||
{
|
||||
|
||||
if (config('app.lock_passwords')) {
|
||||
return redirect()->route('account.password.index')->with('error', Lang::get('admin/users/table.lock_passwords'));
|
||||
}
|
||||
|
||||
$user = Auth::user();
|
||||
if ($user->ldap_import=='1') {
|
||||
return redirect()->route('account.password.index')->with('error', Lang::get('admin/users/message.error.password_ldap'));
|
||||
}
|
||||
|
||||
$rules = array(
|
||||
'current_password' => 'required',
|
||||
'password' => Setting::passwordComplexityRulesSaving('store'),
|
||||
'password_confirm' => 'required|same:password',
|
||||
);
|
||||
|
||||
$validator = \Validator::make($request->all(), $rules);
|
||||
$validator->after(function($validator) use ($request, $user) {
|
||||
|
||||
if (!Hash::check($request->input('current_password'), $user->password)) {
|
||||
$validator->errors()->add('current_password', trans('validation.hashed_pass'));
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
if (!$validator->fails()) {
|
||||
$user->password = Hash::make($request->input('password'));
|
||||
$user->save();
|
||||
return redirect()->route('account.password.index')->with('success', 'Password updated!');
|
||||
|
||||
}
|
||||
return redirect()->back()->withInput()->withErrors($validator);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -271,6 +271,20 @@ class ReportsController extends Controller
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Displays audit report.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v4.0]
|
||||
* @return View
|
||||
*/
|
||||
public function audit()
|
||||
{
|
||||
return view('reports/audit');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Displays activity report.
|
||||
*
|
||||
|
||||
@@ -184,6 +184,7 @@ class SettingsController extends Controller
|
||||
$settings->site_name = e(Input::get('site_name'));
|
||||
$settings->alert_email = e(Input::get('email'));
|
||||
$settings->alerts_enabled = 1;
|
||||
$settings->pwd_secure_min = 10;
|
||||
$settings->brand = 1;
|
||||
$settings->locale = 'en';
|
||||
$settings->default_currency = 'USD';
|
||||
@@ -259,6 +260,13 @@ class SettingsController extends Controller
|
||||
Artisan::call('migrate', ['--force' => true]);
|
||||
|
||||
$output = Artisan::output();
|
||||
|
||||
if ((!file_exists(storage_path().'/oauth-private.key')) || (!file_exists(storage_path().'/oauth-public.key'))) {
|
||||
Artisan::call('passport:install');
|
||||
Artisan::call('migrate', ['--force' => true]);
|
||||
}
|
||||
|
||||
|
||||
return view('setup/migrate')
|
||||
->with('output', $output)
|
||||
->with('step', 2)
|
||||
@@ -462,6 +470,15 @@ class SettingsController extends Controller
|
||||
|
||||
}
|
||||
|
||||
$setting->pwd_secure_uncommon = (int) $request->input('pwd_secure_uncommon');
|
||||
$setting->pwd_secure_min = (int) $request->input('pwd_secure_min');
|
||||
$setting->pwd_secure_complexity = '';
|
||||
|
||||
if ($request->has('pwd_secure_complexity')) {
|
||||
$setting->pwd_secure_complexity = implode('|', $request->input('pwd_secure_complexity'));
|
||||
}
|
||||
|
||||
|
||||
|
||||
if ($setting->save()) {
|
||||
return redirect()->route('settings.index')
|
||||
|
||||
@@ -12,9 +12,7 @@ use App\Models\Company;
|
||||
use App\Models\Location;
|
||||
use App\Models\License;
|
||||
use App\Models\Setting;
|
||||
use App\Models\Statuslabel;
|
||||
use App\Http\Requests\SaveUserRequest;
|
||||
use App\Http\Requests\UpdateUserRequest;
|
||||
use Symfony\Component\HttpFoundation\StreamedResponse;
|
||||
use App\Models\User;
|
||||
use App\Models\Ldap;
|
||||
@@ -23,7 +21,6 @@ use Config;
|
||||
use Crypt;
|
||||
use DB;
|
||||
use HTML;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Input;
|
||||
use Lang;
|
||||
use League\Csv\Reader;
|
||||
@@ -169,7 +166,7 @@ class UsersController extends Controller
|
||||
* @since [v1.8]
|
||||
* @return string JSON
|
||||
*/
|
||||
public function apiStore(Request $request)
|
||||
public function apiStore(SaveUserRequest $request)
|
||||
{
|
||||
$this->authorize('create', User::class);
|
||||
|
||||
@@ -270,7 +267,7 @@ class UsersController extends Controller
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function update(UpdateUserRequest $request, $id = null)
|
||||
public function update(SaveUserRequest $request, $id = null)
|
||||
{
|
||||
// We need to reverse the UI specific logic for our
|
||||
// permissions here before we update the user.
|
||||
@@ -309,14 +306,11 @@ class UsersController extends Controller
|
||||
}
|
||||
}
|
||||
|
||||
// Do we want to update the user password?
|
||||
if ($request->has('password')) {
|
||||
$user->password = bcrypt($request->input('password'));
|
||||
}
|
||||
|
||||
if ($request->has('username')) {
|
||||
$user->username = e($request->input('username'));
|
||||
$user->username = $request->input('username');
|
||||
}
|
||||
$user->email = e($request->input('email'));
|
||||
$user->email = $request->input('email');
|
||||
|
||||
|
||||
// Update the user
|
||||
@@ -334,6 +328,12 @@ class UsersController extends Controller
|
||||
$user->notes = $request->input('notes');
|
||||
$user->department_id = $request->input('department_id', null);
|
||||
|
||||
|
||||
// Do we want to update the user password?
|
||||
if ($request->has('password')) {
|
||||
$user->password = bcrypt($request->input('password'));
|
||||
}
|
||||
|
||||
// Strip out the superuser permission if the user isn't a superadmin
|
||||
$permissions_array = $request->input('permission');
|
||||
|
||||
@@ -376,7 +376,6 @@ class UsersController extends Controller
|
||||
}
|
||||
|
||||
if ($user->licenses()->count() > 0) {
|
||||
|
||||
// Redirect to the user management page
|
||||
return redirect()->route('users.index')->with('error', 'This user still has ' . $user->licenses()->count() . ' licenses associated with them.');
|
||||
}
|
||||
@@ -386,6 +385,11 @@ class UsersController extends Controller
|
||||
return redirect()->route('users.index')->with('error', 'This user still has ' . $user->accessories()->count() . ' accessories associated with them.');
|
||||
}
|
||||
|
||||
if ($user->managedLocations()->count() > 0) {
|
||||
// Redirect to the user management page
|
||||
return redirect()->route('users.index')->with('error', 'This user still has ' . $user->managedLocations()->count() . ' locations that they manage.');
|
||||
}
|
||||
|
||||
// Delete the user
|
||||
$user->delete();
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
namespace App\Http\Requests;
|
||||
|
||||
use App\Http\Requests\Request;
|
||||
use App\Models\Setting;
|
||||
|
||||
class SaveUserRequest extends Request
|
||||
{
|
||||
@@ -23,12 +24,38 @@ class SaveUserRequest extends Request
|
||||
*/
|
||||
public function rules()
|
||||
{
|
||||
return [
|
||||
'first_name' => 'required|string|min:1',
|
||||
'email' => 'email',
|
||||
'password' => 'required|min:6',
|
||||
'password_confirm' => 'sometimes|required_with:password',
|
||||
'username' => 'required|string|min:2|unique:users,username,NULL,deleted_at',
|
||||
];
|
||||
|
||||
$rules = [];
|
||||
|
||||
switch($this->method())
|
||||
{
|
||||
|
||||
// Brand new asset
|
||||
case 'POST':
|
||||
{
|
||||
$rules['first_name'] = 'required|string|min:1';
|
||||
$rules['username'] = 'required|string|min:1';
|
||||
$rules['password'] = Setting::passwordComplexityRulesSaving('store');
|
||||
}
|
||||
|
||||
// Save all fields
|
||||
case 'PUT':
|
||||
$rules['first_name'] = 'required|string|min:1';
|
||||
$rules['username'] = 'required|string|min:1';
|
||||
$rules['password'] = Setting::passwordComplexityRulesSaving('update');
|
||||
|
||||
// Save only what's passed
|
||||
case 'PATCH':
|
||||
{
|
||||
$rules['password'] = Setting::passwordComplexityRulesSaving('update');
|
||||
}
|
||||
|
||||
default:break;
|
||||
}
|
||||
|
||||
$rules['password_confirm'] = 'sometimes|required_with:password';
|
||||
|
||||
return $rules;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,32 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Requests;
|
||||
|
||||
use App\Http\Requests\Request;
|
||||
|
||||
class UpdateUserRequest extends Request
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules()
|
||||
{
|
||||
return [
|
||||
'first_name' => 'required|string|min:1',
|
||||
'email' => 'email',
|
||||
'password_confirm' => 'sometimes|required_with:password',
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -29,6 +29,7 @@ class ActionlogsTransformer
|
||||
] : null,
|
||||
'created_at' => Helper::getFormattedDateObject($actionlog->created_at, 'datetime'),
|
||||
'updated_at' => Helper::getFormattedDateObject($actionlog->updated_at, 'datetime'),
|
||||
'next_audit_date' => ($actionlog->itemType()=='asset') ? Helper::getFormattedDateObject($actionlog->item->next_audit_date, 'datetime'): null,
|
||||
'action_type' => $actionlog->present()->actionType(),
|
||||
'admin' => ($actionlog->user) ? [
|
||||
'id' => (int) $actionlog->user->id,
|
||||
|
||||
53
app/Http/Transformers/AssetMaintenancesTransformer.php
Normal file
53
app/Http/Transformers/AssetMaintenancesTransformer.php
Normal file
@@ -0,0 +1,53 @@
|
||||
<?php
|
||||
namespace App\Http\Transformers;
|
||||
|
||||
use App\Models\AssetMaintenance;
|
||||
use Gate;
|
||||
use Illuminate\Database\Eloquent\Collection;
|
||||
use App\Helpers\Helper;
|
||||
|
||||
class AssetMaintenancesTransformer
|
||||
{
|
||||
|
||||
public function transformAssetMaintenances (Collection $assetmaintenances, $total)
|
||||
{
|
||||
$array = array();
|
||||
foreach ($assetmaintenances as $assetmaintenance) {
|
||||
$array[] = self::transformAssetMaintenance($assetmaintenance);
|
||||
}
|
||||
return (new DatatablesTransformer)->transformDatatables($array, $total);
|
||||
}
|
||||
|
||||
public function transformAssetMaintenance (AssetMaintenance $assetmaintenance)
|
||||
{
|
||||
$array = [
|
||||
'id' => (int) $assetmaintenance->id,
|
||||
'asset_name' => ($assetmaintenance->asset) ? ['id' => $assetmaintenance->asset->id,'name'=> e($assetmaintenance->asset->name)] : null,
|
||||
'title' => ($assetmaintenance->title) ? e($assetmaintenance->title) : null,
|
||||
'notes' => ($assetmaintenance->notes) ? e($assetmaintenance->notes) : null,
|
||||
'supplier' => ($assetmaintenance->supplier) ? ['id' => $assetmaintenance->supplier->id,'name'=> e($assetmaintenance->supplier->name)] : null,
|
||||
'cost' => Helper::formatCurrencyOutput($assetmaintenance->cost),
|
||||
'asset_maintenance_type' => e($assetmaintenance->asset_maintenance_type),
|
||||
'start_date' => Helper::getFormattedDateObject($assetmaintenance->start_date, 'datetime'),
|
||||
'asset_maintenance_time' => $assetmaintenance->asset_maintenance_time,
|
||||
'completion_date' => Helper::getFormattedDateObject($assetmaintenance->completion_date, 'datetime'),
|
||||
'user_id' => ($assetmaintenance->admin) ? ['id' => $assetmaintenance->admin->id,'name'=> e($assetmaintenance->admin->getFullNameAttribute())] : null,
|
||||
'created_at' => Helper::getFormattedDateObject($assetmaintenance->created_at, 'datetime'),
|
||||
'updated_at' => Helper::getFormattedDateObject($assetmaintenance->updated_at, 'datetime'),
|
||||
|
||||
];
|
||||
|
||||
$permissions_array['available_actions'] = [
|
||||
'delete' => (bool) Gate::allows('delete', Asset::class),
|
||||
];
|
||||
|
||||
$array += $permissions_array;
|
||||
|
||||
return $array;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -110,6 +110,8 @@ class AssetsTransformer
|
||||
//array += $fields_array;
|
||||
$array['custom_fields'] = $fields_array;
|
||||
}
|
||||
} else {
|
||||
$array['custom_fields'] = array();
|
||||
}
|
||||
|
||||
$permissions_array['available_actions'] = [
|
||||
|
||||
@@ -4,6 +4,7 @@ namespace App\Http\Transformers;
|
||||
use App\Models\Category;
|
||||
use Illuminate\Database\Eloquent\Collection;
|
||||
use Gate;
|
||||
use App\Helpers\Helper;
|
||||
|
||||
class CategoriesTransformer
|
||||
{
|
||||
@@ -22,15 +23,18 @@ class CategoriesTransformer
|
||||
if ($category) {
|
||||
|
||||
$array = [
|
||||
'id' => e($category->id),
|
||||
'id' => (int) $category->id,
|
||||
'name' => e($category->name),
|
||||
'type' => e($category->category_type),
|
||||
'use_default_eula' => ($category->use_default_eula =='1') ? true : false,
|
||||
'checkin_email' => ($category->checkin_email =='1') ? true : false,
|
||||
'require_acceptance' => ($category->require_acceptance =='1') ? true : false,
|
||||
'assets_count' => $category->assets_count,
|
||||
'accessories_count' => $category->accessories_count,
|
||||
'consumables_count' => $category->consumables_count,
|
||||
'components_count' => $category->components_count,
|
||||
'created_at' => Helper::getFormattedDateObject($category->created_at, 'datetime'),
|
||||
'updated_at' => Helper::getFormattedDateObject($category->updated_at, 'datetime'),
|
||||
];
|
||||
|
||||
$permissions_array['available_actions'] = [
|
||||
|
||||
@@ -23,7 +23,7 @@ class CompaniesTransformer
|
||||
if ($company) {
|
||||
|
||||
$array = [
|
||||
'id' => e($company->id),
|
||||
'id' => (int) $company->id,
|
||||
'name' => e($company->name),
|
||||
"created_at" => Helper::getFormattedDateObject($company->created_at, 'datetime'),
|
||||
"updated_at" => Helper::getFormattedDateObject($company->updated_at, 'datetime'),
|
||||
|
||||
@@ -9,7 +9,7 @@ use App\Helpers\Helper;
|
||||
class LocationsTransformer
|
||||
{
|
||||
|
||||
public function transformLocations (Collection $locations, $total)
|
||||
public function transformLocations(Collection $locations, $total)
|
||||
{
|
||||
$array = array();
|
||||
foreach ($locations as $location) {
|
||||
@@ -18,18 +18,16 @@ class LocationsTransformer
|
||||
return (new DatatablesTransformer)->transformDatatables($array, $total);
|
||||
}
|
||||
|
||||
public function transformLocation (Location $location = null)
|
||||
public function transformLocation(Location $location = null)
|
||||
{
|
||||
if ($location) {
|
||||
|
||||
$assets_arr = [];
|
||||
foreach($location->assets() as $asset) {
|
||||
$assets_arr = ['id' => $asset->id];
|
||||
}
|
||||
|
||||
$children_arr = [];
|
||||
foreach($location->childLocations() as $child) {
|
||||
$children_arr = ['id' => $child->id];
|
||||
foreach($location->childLocations as $child) {
|
||||
$children_arr[] = [
|
||||
'id' => (int) $child->id,
|
||||
'name' => $child->name
|
||||
];
|
||||
}
|
||||
|
||||
$array = [
|
||||
@@ -41,10 +39,15 @@ class LocationsTransformer
|
||||
'assets_checkedout' => $location->assets()->count(),
|
||||
'assets_default' => $location->assignedassets()->count(),
|
||||
'country' => e($location->country),
|
||||
'assets' => $assets_arr,
|
||||
'created_at' => Helper::getFormattedDateObject($location->created_at, 'datetime'),
|
||||
'updated_at' => Helper::getFormattedDateObject($location->updated_at, 'datetime'),
|
||||
'parent_id' => ($location->parent_id) ? (int) $location->parent_id : null,
|
||||
'parent' => ($location->parent) ? [
|
||||
'id' => (int) $location->parent->id,
|
||||
'name'=> e($location->parent->name)
|
||||
] : null,
|
||||
'manager' => ($location->manager) ? (new UsersTransformer)->transformUser($location->manager) : null,
|
||||
|
||||
|
||||
'children' => $children_arr,
|
||||
];
|
||||
|
||||
|
||||
@@ -30,6 +30,7 @@ class SuppliersTransformer
|
||||
'city' => ($supplier->city) ? e($supplier->city) : null,
|
||||
'state' => ($supplier->state) ? e($supplier->state) : null,
|
||||
'country' => ($supplier->country) ? e($supplier->country) : null,
|
||||
'zip' => ($supplier->zip) ? e($supplier->zip) : null,
|
||||
'fax' => ($supplier->fax) ? e($supplier->fax) : null,
|
||||
'phone' => ($supplier->phone) ? e($supplier->phone) : null,
|
||||
'email' => ($supplier->email) ? e($supplier->email) : null,
|
||||
@@ -37,6 +38,7 @@ class SuppliersTransformer
|
||||
'assets_count' => (int) $supplier->assets_count,
|
||||
'licenses_count' => (int) $supplier->licenses_count,
|
||||
'image' => ($supplier->image) ? e($supplier->image) : null,
|
||||
'notes' => ($supplier->notes) ? e($supplier->notes) : null,
|
||||
'created_at' => Helper::getFormattedDateObject($supplier->created_at, 'datetime'),
|
||||
'updated_at' => Helper::getFormattedDateObject($supplier->updated_at, 'datetime'),
|
||||
|
||||
|
||||
@@ -32,11 +32,6 @@ class UsersTransformer
|
||||
'id' => (int) $user->manager->id,
|
||||
'name'=> e($user->manager->username)
|
||||
] : null,
|
||||
|
||||
'groups' => ($user->groups) ? [
|
||||
'id' => (int) $user->userloc->id,
|
||||
'name'=> e($user->userloc->name)
|
||||
] : null,
|
||||
'jobtitle' => ($user->jobtitle) ? e($user->jobtitle) : null,
|
||||
'email' => e($user->email),
|
||||
'department' => ($user->department) ? [
|
||||
@@ -68,6 +63,24 @@ class UsersTransformer
|
||||
|
||||
$array += $permissions_array;
|
||||
|
||||
|
||||
$numGroups = count($user->groups);
|
||||
if($numGroups > 0)
|
||||
{
|
||||
$groups["total"] = $numGroups;
|
||||
foreach($user->groups as $group)
|
||||
{
|
||||
$groups["rows"][] = [
|
||||
'id' => (int) $group->id,
|
||||
'name' => e($group->name)
|
||||
];
|
||||
}
|
||||
$array["groups"] = $groups;
|
||||
}
|
||||
else {
|
||||
$array["groups"] = null;
|
||||
}
|
||||
|
||||
return $array;
|
||||
}
|
||||
|
||||
|
||||
81
app/LegacyEncrypter/BaseEncrypter.php
Normal file
81
app/LegacyEncrypter/BaseEncrypter.php
Normal file
@@ -0,0 +1,81 @@
|
||||
<?php
|
||||
|
||||
namespace App\LegacyEncrypter;
|
||||
|
||||
use Illuminate\Contracts\Encryption\DecryptException;
|
||||
|
||||
abstract class BaseEncrypter
|
||||
{
|
||||
/**
|
||||
* The encryption key.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $key;
|
||||
|
||||
/**
|
||||
* Create a MAC for the given value.
|
||||
*
|
||||
* @param string $iv
|
||||
* @param string $value
|
||||
* @return string
|
||||
*/
|
||||
protected function hash($iv, $value)
|
||||
{
|
||||
return hash_hmac('sha256', $iv.$value, $this->key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the JSON array from the given payload.
|
||||
*
|
||||
* @param string $payload
|
||||
* @return array
|
||||
*
|
||||
* @throws \Illuminate\Contracts\Encryption\DecryptException
|
||||
*/
|
||||
protected function getJsonPayload($payload)
|
||||
{
|
||||
$payload = json_decode(base64_decode($payload), true);
|
||||
|
||||
// If the payload is not valid JSON or does not have the proper keys set we will
|
||||
// assume it is invalid and bail out of the routine since we will not be able
|
||||
// to decrypt the given value. We'll also check the MAC for this encryption.
|
||||
if (! $payload || $this->invalidPayload($payload)) {
|
||||
throw new DecryptException('The payload is invalid.');
|
||||
}
|
||||
|
||||
if (! $this->validMac($payload)) {
|
||||
throw new DecryptException('The MAC is invalid.');
|
||||
}
|
||||
|
||||
return $payload;
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify that the encryption payload is valid.
|
||||
*
|
||||
* @param array|mixed $data
|
||||
* @return bool
|
||||
*/
|
||||
protected function invalidPayload($data)
|
||||
{
|
||||
return ! is_array($data) || ! isset($data['iv']) || ! isset($data['value']) || ! isset($data['mac']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the MAC for the given payload is valid.
|
||||
*
|
||||
* @param array $payload
|
||||
* @return bool
|
||||
*
|
||||
* @throws \RuntimeException
|
||||
*/
|
||||
protected function validMac(array $payload)
|
||||
{
|
||||
$bytes = random_bytes(16);
|
||||
|
||||
$calcMac = hash_hmac('sha256', $this->hash($payload['iv'], $payload['value']), $bytes, true);
|
||||
|
||||
return hash_equals(hash_hmac('sha256', $payload['mac'], $bytes, true), $calcMac);
|
||||
}
|
||||
}
|
||||
214
app/LegacyEncrypter/McryptEncrypter.php
Normal file
214
app/LegacyEncrypter/McryptEncrypter.php
Normal file
@@ -0,0 +1,214 @@
|
||||
<?php
|
||||
|
||||
namespace App\LegacyEncrypter;
|
||||
|
||||
use Exception;
|
||||
use RuntimeException;
|
||||
use Illuminate\Contracts\Encryption\DecryptException;
|
||||
use Illuminate\Contracts\Encryption\EncryptException;
|
||||
use Illuminate\Contracts\Encryption\Encrypter as EncrypterContract;
|
||||
|
||||
/**
|
||||
* @deprecated since version 5.1. Use Illuminate\Encryption\Encrypter.
|
||||
*/
|
||||
class McryptEncrypter extends BaseEncrypter implements EncrypterContract
|
||||
{
|
||||
/**
|
||||
* The algorithm used for encryption.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $cipher;
|
||||
|
||||
/**
|
||||
* The block size of the cipher.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $block;
|
||||
|
||||
/**
|
||||
* Create a new encrypter instance.
|
||||
*
|
||||
* @param string $key
|
||||
* @param string $cipher
|
||||
* @return void
|
||||
*
|
||||
* @throws \RuntimeException
|
||||
*/
|
||||
public function __construct($key, $cipher = MCRYPT_RIJNDAEL_128)
|
||||
{
|
||||
$key = (string) $key;
|
||||
|
||||
if (static::supported($key, $cipher)) {
|
||||
$this->key = $key;
|
||||
$this->cipher = $cipher;
|
||||
$this->block = mcrypt_get_iv_size($this->cipher, MCRYPT_MODE_CBC);
|
||||
} else {
|
||||
throw new RuntimeException('The only supported ciphers are MCRYPT_RIJNDAEL_128 and MCRYPT_RIJNDAEL_256.');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the given key and cipher combination is valid.
|
||||
*
|
||||
* @param string $key
|
||||
* @param string $cipher
|
||||
* @return bool
|
||||
*/
|
||||
public static function supported($key, $cipher)
|
||||
{
|
||||
return defined('MCRYPT_RIJNDAEL_128') &&
|
||||
($cipher === MCRYPT_RIJNDAEL_128 || $cipher === MCRYPT_RIJNDAEL_256);
|
||||
}
|
||||
|
||||
/**
|
||||
* Encrypt the given value.
|
||||
*
|
||||
* @param string $value
|
||||
* @return string
|
||||
*
|
||||
* @throws \Illuminate\Contracts\Encryption\EncryptException
|
||||
*/
|
||||
public function encrypt($value, $serialize = true)
|
||||
{
|
||||
$iv = mcrypt_create_iv($this->getIvSize(), $this->getRandomizer());
|
||||
|
||||
$value = base64_encode($this->padAndMcrypt($value, $iv));
|
||||
|
||||
// Once we have the encrypted value we will go ahead base64_encode the input
|
||||
// vector and create the MAC for the encrypted value so we can verify its
|
||||
// authenticity. Then, we'll JSON encode the data in a "payload" array.
|
||||
$mac = $this->hash($iv = base64_encode($iv), $value);
|
||||
|
||||
$json = json_encode(compact('iv', 'value', 'mac'));
|
||||
|
||||
if (! is_string($json)) {
|
||||
throw new EncryptException('Could not encrypt the data.');
|
||||
}
|
||||
|
||||
return base64_encode($json);
|
||||
}
|
||||
|
||||
/**
|
||||
* Pad and use mcrypt on the given value and input vector.
|
||||
*
|
||||
* @param string $value
|
||||
* @param string $iv
|
||||
* @return string
|
||||
*/
|
||||
protected function padAndMcrypt($value, $iv)
|
||||
{
|
||||
$value = $this->addPadding(serialize($value));
|
||||
|
||||
return mcrypt_encrypt($this->cipher, $this->key, $value, MCRYPT_MODE_CBC, $iv);
|
||||
}
|
||||
|
||||
/**
|
||||
* Decrypt the given value.
|
||||
*
|
||||
* @param string $payload
|
||||
* @return string
|
||||
*/
|
||||
public function decrypt($payload, $unserialize = true)
|
||||
{
|
||||
$payload = $this->getJsonPayload($payload);
|
||||
|
||||
// We'll go ahead and remove the PKCS7 padding from the encrypted value before
|
||||
// we decrypt it. Once we have the de-padded value, we will grab the vector
|
||||
// and decrypt the data, passing back the unserialized from of the value.
|
||||
$value = base64_decode($payload['value']);
|
||||
|
||||
$iv = base64_decode($payload['iv']);
|
||||
|
||||
return unserialize($this->stripPadding($this->mcryptDecrypt($value, $iv)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Run the mcrypt decryption routine for the value.
|
||||
*
|
||||
* @param string $value
|
||||
* @param string $iv
|
||||
* @return string
|
||||
*
|
||||
* @throws \Illuminate\Contracts\Encryption\DecryptException
|
||||
*/
|
||||
protected function mcryptDecrypt($value, $iv)
|
||||
{
|
||||
try {
|
||||
return mcrypt_decrypt($this->cipher, $this->key, $value, MCRYPT_MODE_CBC, $iv);
|
||||
} catch (Exception $e) {
|
||||
throw new DecryptException($e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add PKCS7 padding to a given value.
|
||||
*
|
||||
* @param string $value
|
||||
* @return string
|
||||
*/
|
||||
protected function addPadding($value)
|
||||
{
|
||||
$pad = $this->block - (strlen($value) % $this->block);
|
||||
|
||||
return $value.str_repeat(chr($pad), $pad);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the padding from the given value.
|
||||
*
|
||||
* @param string $value
|
||||
* @return string
|
||||
*/
|
||||
protected function stripPadding($value)
|
||||
{
|
||||
$pad = ord($value[($len = strlen($value)) - 1]);
|
||||
|
||||
return $this->paddingIsValid($pad, $value) ? substr($value, 0, $len - $pad) : $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the given padding for a value is valid.
|
||||
*
|
||||
* @param string $pad
|
||||
* @param string $value
|
||||
* @return bool
|
||||
*/
|
||||
protected function paddingIsValid($pad, $value)
|
||||
{
|
||||
$beforePad = strlen($value) - $pad;
|
||||
|
||||
return substr($value, $beforePad) == str_repeat(substr($value, -1), $pad);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the IV size for the cipher.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
protected function getIvSize()
|
||||
{
|
||||
return mcrypt_get_iv_size($this->cipher, MCRYPT_MODE_CBC);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the random data source available for the OS.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
protected function getRandomizer()
|
||||
{
|
||||
if (defined('MCRYPT_DEV_URANDOM')) {
|
||||
return MCRYPT_DEV_URANDOM;
|
||||
}
|
||||
|
||||
if (defined('MCRYPT_DEV_RANDOM')) {
|
||||
return MCRYPT_DEV_RANDOM;
|
||||
}
|
||||
|
||||
mt_srand();
|
||||
|
||||
return MCRYPT_RAND;
|
||||
}
|
||||
}
|
||||
@@ -60,6 +60,8 @@ class Accessory extends SnipeModel
|
||||
'purchase_cost',
|
||||
'purchase_date',
|
||||
'model_number',
|
||||
'manufacturer_id',
|
||||
'notes',
|
||||
'qty',
|
||||
'requestable'
|
||||
];
|
||||
|
||||
@@ -276,13 +276,17 @@ class Asset extends Depreciable
|
||||
if (!empty($this->assignedType())) {
|
||||
if ($this->assignedType() == self::ASSET) {
|
||||
return $this->assignedTo->assetloc(); // Recurse until we have a final location
|
||||
} elseif ($this->assignedType() == self::LOCATION) {
|
||||
}
|
||||
if ($this->assignedType() == self::LOCATION) {
|
||||
return $this->assignedTo();
|
||||
} elseif (!$this->assignedTo) {
|
||||
return $this->defaultLoc();
|
||||
} elseif ($this->assignedType() == self::USER) {
|
||||
return $this->assignedTo->userLoc();
|
||||
}
|
||||
if ($this->assignedType() == self::USER) {
|
||||
return $this->assignedTo->userLoc();
|
||||
}
|
||||
}
|
||||
return $this->defaultLoc();
|
||||
}
|
||||
@@ -1088,7 +1092,7 @@ class Asset extends Depreciable
|
||||
return $query->where(function ($query) use ($search) {
|
||||
$query->whereHas('defaultLoc', function ($query) use ($search) {
|
||||
$query->where('locations.id', '=', $search);
|
||||
})->whereNull('assigned_to');
|
||||
});
|
||||
})->orWhere(function ($query) use ($search) {
|
||||
$query->whereHas('assigneduser', function ($query) use ($search) {
|
||||
$query->whereHas('userloc', function ($query) use ($search) {
|
||||
|
||||
@@ -55,7 +55,7 @@ class AssetModel extends SnipeModel
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $fillable = ['name','manufacturer_id','category_id','eol', 'user_id', 'fieldset_id'];
|
||||
protected $fillable = ['name','manufacturer_id','category_id','eol', 'user_id', 'fieldset_id', 'model_number', 'notes'];
|
||||
|
||||
public function assets()
|
||||
{
|
||||
|
||||
@@ -38,12 +38,10 @@ class CustomField extends Model
|
||||
public static function boot()
|
||||
{
|
||||
self::created(function ($custom_field) {
|
||||
\Log::debug("\n\nCreating Original Name: ".$custom_field->name);
|
||||
\Log::debug('Creating Column Name: '.$custom_field->convertUnicodeDbSlug());
|
||||
|
||||
|
||||
// column exists - nothing to do here
|
||||
if (Schema::hasColumn(CustomField::$table_name, $custom_field->convertUnicodeDbSlug())) {
|
||||
\Log::debug('Column exists. Nothing to do here.');
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -57,18 +55,13 @@ class CustomField extends Model
|
||||
|
||||
|
||||
self::updating(function ($custom_field) {
|
||||
\Log::debug('Updating column name');
|
||||
\Log::debug('Updating Original Name: '.$custom_field->getOriginal("name"));
|
||||
\Log::debug('Updating New Column Name: '.$custom_field->convertUnicodeDbSlug());
|
||||
|
||||
// Column already exists. Nothing to update.
|
||||
if ($custom_field->isDirty("name")) {
|
||||
if (Schema::hasColumn(CustomField::$table_name, $custom_field->convertUnicodeDbSlug())) {
|
||||
\Log::debug('Column already exists. Nothing to update.');
|
||||
return true;
|
||||
}
|
||||
|
||||
\Log::debug('Updating column name to.'.$custom_field->convertUnicodeDbSlug());
|
||||
|
||||
return Schema::table(CustomField::$table_name, function ($table) use ($custom_field) {
|
||||
$table->renameColumn($custom_field->convertUnicodeDbSlug($custom_field->getOriginal("name")), $custom_field->convertUnicodeDbSlug());
|
||||
});
|
||||
@@ -85,7 +78,7 @@ class CustomField extends Model
|
||||
|
||||
public function fieldset()
|
||||
{
|
||||
return $this->belongsToMany('\App\Models\CustomFieldset'); //?!?!?!?!?!?
|
||||
return $this->belongsToMany('\App\Models\CustomFieldset');
|
||||
}
|
||||
|
||||
public function user()
|
||||
@@ -102,10 +95,9 @@ class CustomField extends Model
|
||||
public function db_column_name()
|
||||
{
|
||||
return $this->db_column;
|
||||
// return self::convertUnicodeDbSlug();
|
||||
}
|
||||
|
||||
//mutators for 'format' attribute
|
||||
// mutators for 'format' attribute
|
||||
public function getFormatAttribute($value)
|
||||
{
|
||||
foreach (self::$PredefinedFormats as $name => $pattern) {
|
||||
@@ -116,6 +108,13 @@ class CustomField extends Model
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Format a value string as an array for select boxes and checkboxes.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v3.4]
|
||||
* @return Array
|
||||
*/
|
||||
public function setFormatAttribute($value)
|
||||
{
|
||||
if (isset(self::$PredefinedFormats[$value])) {
|
||||
|
||||
@@ -401,6 +401,20 @@ class License extends Depreciable
|
||||
->orderBy('manufacturers.name', $order);
|
||||
}
|
||||
|
||||
/**
|
||||
* Query builder scope to order on supplier
|
||||
*
|
||||
* @param \Illuminate\Database\Query\Builder $query Query builder instance
|
||||
* @param text $order Order
|
||||
*
|
||||
* @return \Illuminate\Database\Query\Builder Modified query builder
|
||||
*/
|
||||
public function scopeOrderSupplier($query, $order)
|
||||
{
|
||||
return $query->leftJoin('suppliers', 'licenses.supplier_id', '=', 'suppliers.id')->select('licenses.*')
|
||||
->orderBy('suppliers.name', $order);
|
||||
}
|
||||
|
||||
/**
|
||||
* Query builder scope to order on company
|
||||
*
|
||||
|
||||
@@ -24,6 +24,7 @@ class Location extends SnipeModel
|
||||
'address' => 'max:80|nullable',
|
||||
'address2' => 'max:80|nullable',
|
||||
'zip' => 'min:3|max:10|nullable',
|
||||
// 'manager_id' => 'exists:users'
|
||||
);
|
||||
|
||||
/**
|
||||
@@ -63,7 +64,12 @@ class Location extends SnipeModel
|
||||
|
||||
public function parent()
|
||||
{
|
||||
return $this->belongsTo('\App\Models\Location', 'parent_id');
|
||||
return $this->belongsTo('\App\Models\Location', 'parent_id','id');
|
||||
}
|
||||
|
||||
public function manager()
|
||||
{
|
||||
return $this->belongsTo('\App\Models\User', 'manager_id');
|
||||
}
|
||||
|
||||
public function childLocations()
|
||||
|
||||
@@ -7,6 +7,7 @@ use App\Models\Asset;
|
||||
use App\Models\CheckoutRequest;
|
||||
use App\Models\User;
|
||||
use App\Notifications\CheckinNotification;
|
||||
use App\Notifications\AuditNotification;
|
||||
use App\Notifications\CheckoutNotification;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
@@ -80,8 +81,11 @@ trait Loggable
|
||||
'admin' => $log->user,
|
||||
'note' => $note
|
||||
];
|
||||
Setting::getSettings()->notify(new CheckoutNotification($params));
|
||||
|
||||
if ($settings = Setting::getSettings()) {
|
||||
$settings->notify(new CheckoutNotification($params));
|
||||
}
|
||||
|
||||
return $log;
|
||||
}
|
||||
|
||||
@@ -117,6 +121,38 @@ trait Loggable
|
||||
return $log;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @author A. Gianotto <snipe@snipe.net>
|
||||
* @since [v4.0]
|
||||
* @return \App\Models\Actionlog
|
||||
*/
|
||||
public function logAudit($note)
|
||||
{
|
||||
$log = new Actionlog;
|
||||
if (static::class == LicenseSeat::class) {
|
||||
$log->item_type = License::class;
|
||||
$log->item_id = $this->license_id;
|
||||
} else {
|
||||
$log->item_type = static::class;
|
||||
$log->item_id = $this->id;
|
||||
}
|
||||
$log->location_id = null;
|
||||
$log->note = $note;
|
||||
$log->user_id = Auth::user()->id;
|
||||
$log->logaction('audit');
|
||||
|
||||
$params = [
|
||||
'item' => $log->item,
|
||||
'admin' => $log->user,
|
||||
'note' => $note
|
||||
];
|
||||
Setting::getSettings()->notify(new AuditNotification($params));
|
||||
|
||||
return $log;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @author Daniel Meltzer <parallelgrapefruit@gmail.com
|
||||
* @since [v3.5]
|
||||
|
||||
@@ -14,36 +14,37 @@ class Setting extends Model
|
||||
|
||||
protected $rules = [
|
||||
"brand" => 'required|min:1|numeric',
|
||||
"qr_text" => 'max:31',
|
||||
"qr_text" => 'max:31|nullable',
|
||||
"logo_img" => 'mimes:jpeg,bmp,png,gif',
|
||||
"alert_email" => 'email_array',
|
||||
"alert_email" => 'email_array|nullable',
|
||||
"default_currency" => 'required',
|
||||
"locale" => 'required',
|
||||
"slack_endpoint" => 'url|required_with:slack_channel',
|
||||
"slack_channel" => 'regex:/(?<!\w)#\w+/|required_with:slack_endpoint',
|
||||
"slack_endpoint" => 'url|required_with:slack_channel|nullable',
|
||||
"slack_channel" => 'regex:/(?<!\w)#\w+/|required_with:slack_endpoint|nullable',
|
||||
"slack_botname" => 'string|nullable',
|
||||
'labels_per_page' => 'numeric',
|
||||
'labels_width' => 'numeric',
|
||||
'labels_height' => 'numeric',
|
||||
'labels_pmargin_left' => 'numeric',
|
||||
'labels_pmargin_right' => 'numeric',
|
||||
'labels_pmargin_top' => 'numeric',
|
||||
'labels_pmargin_bottom' => 'numeric',
|
||||
'labels_display_bgutter' => 'numeric',
|
||||
'labels_display_sgutter' => 'numeric',
|
||||
'labels_pmargin_left' => 'numeric|nullable',
|
||||
'labels_pmargin_right' => 'numeric|nullable',
|
||||
'labels_pmargin_top' => 'numeric|nullable',
|
||||
'labels_pmargin_bottom' => 'numeric|nullable',
|
||||
'labels_display_bgutter' => 'numeric|nullable',
|
||||
'labels_display_sgutter' => 'numeric|nullable',
|
||||
'labels_fontsize' => 'numeric|min:5',
|
||||
'labels_pagewidth' => 'numeric',
|
||||
'labels_pageheight' => 'numeric',
|
||||
"ldap_server" => 'sometimes|required_if:ldap_enabled,1|url',
|
||||
"ldap_uname" => 'sometimes|required_if:ldap_enabled,1',
|
||||
"ldap_basedn" => 'sometimes|required_if:ldap_enabled,1',
|
||||
"ldap_filter" => 'sometimes|required_if:ldap_enabled,1',
|
||||
"ldap_username_field" => 'sometimes|required_if:ldap_enabled,1',
|
||||
"ldap_fname_field" => 'sometimes|required_if:ldap_enabled,1',
|
||||
"ldap_lname_field" => 'sometimes|required_if:ldap_enabled,1',
|
||||
"ldap_auth_filter_query" => 'sometimes|required_if:ldap_enabled,1',
|
||||
"ldap_version" => 'sometimes|required_if:ldap_enabled,1',
|
||||
'labels_pagewidth' => 'numeric|nullable',
|
||||
'labels_pageheight' => 'numeric|nullable',
|
||||
"ldap_server" => 'sometimes|required_if:ldap_enabled,1|url|nullable',
|
||||
"ldap_uname" => 'sometimes|required_if:ldap_enabled,1|nullable',
|
||||
"ldap_basedn" => 'sometimes|required_if:ldap_enabled,1|nullable',
|
||||
"ldap_filter" => 'sometimes|required_if:ldap_enabled,1|nullable',
|
||||
"ldap_username_field" => 'sometimes|required_if:ldap_enabled,1|nullable',
|
||||
"ldap_fname_field" => 'sometimes|required_if:ldap_enabled,1|nullable',
|
||||
"ldap_lname_field" => 'sometimes|required_if:ldap_enabled,1|nullable',
|
||||
"ldap_auth_filter_query" => 'sometimes|required_if:ldap_enabled,1|nullable',
|
||||
"ldap_version" => 'sometimes|required_if:ldap_enabled,1|nullable',
|
||||
"thumbnail_max_h" => 'numeric|max:500|min:25',
|
||||
"pwd_secure_min" => "numeric|required|min:5",
|
||||
];
|
||||
|
||||
protected $fillable = ['site_name','email_domain','email_format','username_format'];
|
||||
@@ -158,4 +159,30 @@ class Setting extends Model
|
||||
// In the future this may want to be adapted for individual notifications.
|
||||
return $this->slack_endpoint;
|
||||
}
|
||||
|
||||
public static function passwordComplexityRulesSaving($action = 'update')
|
||||
{
|
||||
$security_rules = '';
|
||||
$settings = Setting::getSettings();
|
||||
|
||||
// Check if they have uncommon password enforcement selected in settings
|
||||
if ($settings->pwd_secure_uncommon == 1) {
|
||||
$security_rules .= '|dumbpwd';
|
||||
}
|
||||
|
||||
// Check for any secure password complexity rules that may have been selected
|
||||
if ($settings->pwd_secure_complexity!='') {
|
||||
$security_rules .= '|'.$settings->pwd_secure_complexity;
|
||||
}
|
||||
|
||||
if ($action == 'update') {
|
||||
return 'nullable|min:'.$settings->pwd_secure_min.$security_rules;
|
||||
}
|
||||
|
||||
return 'required|min:'.$settings->pwd_secure_min.$security_rules;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -45,7 +45,7 @@ class Supplier extends SnipeModel
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $fillable = ['name'];
|
||||
protected $fillable = ['name','address','address2','city','state','country','zip','phone','fax','email','contact','url','notes'];
|
||||
|
||||
|
||||
// Eager load counts.
|
||||
|
||||
@@ -51,9 +51,9 @@ class User extends SnipeModel implements AuthenticatableContract, CanResetPasswo
|
||||
protected $rules = [
|
||||
'first_name' => 'required|string|min:1',
|
||||
'username' => 'required|string|min:1|unique_undeleted',
|
||||
'email' => 'email',
|
||||
'email' => 'email|nullable',
|
||||
'password' => 'required|min:6',
|
||||
'locale' => 'max:10'
|
||||
'locale' => 'max:10|nullable'
|
||||
];
|
||||
|
||||
|
||||
@@ -205,6 +205,14 @@ class User extends SnipeModel implements AuthenticatableContract, CanResetPasswo
|
||||
return $this->belongsTo('\App\Models\User', 'manager_id')->withTrashed();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get any locations the user manages.
|
||||
**/
|
||||
public function managedLocations()
|
||||
{
|
||||
return $this->hasMany('\App\Models\Location', 'manager_id')->withTrashed();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get user groups
|
||||
*/
|
||||
|
||||
90
app/Notifications/AuditNotification.php
Normal file
90
app/Notifications/AuditNotification.php
Normal file
@@ -0,0 +1,90 @@
|
||||
<?php
|
||||
|
||||
namespace App\Notifications;
|
||||
|
||||
use App\Models\Setting;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Notifications\Messages\SlackMessage;
|
||||
use Illuminate\Notifications\Notification;
|
||||
use Illuminate\Notifications\Messages\MailMessage;
|
||||
|
||||
class AuditNotification extends Notification
|
||||
{
|
||||
use Queueable;
|
||||
/**
|
||||
* @var
|
||||
*/
|
||||
private $params;
|
||||
|
||||
/**
|
||||
* Create a new notification instance.
|
||||
*
|
||||
* @param $params
|
||||
*/
|
||||
public function __construct($params)
|
||||
{
|
||||
//
|
||||
$this->params = $params;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the notification's delivery channels.
|
||||
*
|
||||
* @param mixed $notifiable
|
||||
* @return array
|
||||
*/
|
||||
public function via($notifiable)
|
||||
{
|
||||
$notifyBy = [];
|
||||
if (Setting::getSettings()->slack_endpoint) {
|
||||
$notifyBy[] = 'slack';
|
||||
}
|
||||
|
||||
return $notifyBy;
|
||||
}
|
||||
|
||||
public function toSlack($notifiable)
|
||||
{
|
||||
|
||||
return (new SlackMessage)
|
||||
->success()
|
||||
->content(class_basename(get_class($this->params['item'])) . " Audited")
|
||||
->attachment(function ($attachment) use ($notifiable) {
|
||||
$item = $this->params['item'];
|
||||
$admin_user = $this->params['admin'];
|
||||
$fields = [
|
||||
'By' => '<'.$admin_user->present()->viewUrl().'|'.$admin_user->present()->fullName().'>'
|
||||
];
|
||||
array_key_exists('note', $this->params) && $fields['Notes'] = $this->params['note'];
|
||||
|
||||
$attachment->title($item->name, $item->present()->viewUrl())
|
||||
->fields($fields);
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Get the mail representation of the notification.
|
||||
*
|
||||
* @param mixed $notifiable
|
||||
* @return \Illuminate\Notifications\Messages\MailMessage
|
||||
*/
|
||||
public function toMail($notifiable)
|
||||
{
|
||||
return (new MailMessage)
|
||||
->line('The introduction to the notification.')
|
||||
->action('Notification Action', 'https://laravel.com')
|
||||
->line('Thank you for using our application!');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the array representation of the notification.
|
||||
*
|
||||
* @param mixed $notifiable
|
||||
* @return array
|
||||
*/
|
||||
public function toArray($notifiable)
|
||||
{
|
||||
return [
|
||||
//
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -28,8 +28,7 @@ class AccessoryObserver
|
||||
|
||||
|
||||
/**
|
||||
* Listen to the Accessory created event, and increment
|
||||
* the next_auto_tag_base value in the settings table when i
|
||||
* Listen to the Accessory created event when
|
||||
* a new accessory is created.
|
||||
*
|
||||
* @param Accessory $accessory
|
||||
@@ -37,9 +36,6 @@ class AccessoryObserver
|
||||
*/
|
||||
public function created(Accessory $accessory)
|
||||
{
|
||||
$settings = Setting::first();
|
||||
$settings->increment('next_auto_tag_base');
|
||||
|
||||
$logAction = new Actionlog();
|
||||
$logAction->item_type = Accessory::class;
|
||||
$logAction->item_id = $accessory->id;
|
||||
|
||||
@@ -18,7 +18,9 @@ class AssetObserver
|
||||
public function updating(Asset $asset)
|
||||
{
|
||||
|
||||
if (($asset->getAttributes()['assigned_to'] == $asset->getOriginal()['assigned_to'])
|
||||
|
||||
if ((isset($asset->getOriginal()['assigned_to'])) && ($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'])
|
||||
&& ($asset->getAttributes()['status_id'] == $asset->getOriginal()['status_id']))
|
||||
{
|
||||
@@ -43,8 +45,9 @@ class AssetObserver
|
||||
*/
|
||||
public function created(Asset $asset)
|
||||
{
|
||||
$settings = Setting::first();
|
||||
$settings->increment('next_auto_tag_base');
|
||||
if ($settings = Setting::first()) {
|
||||
$settings->increment('next_auto_tag_base');
|
||||
}
|
||||
|
||||
$logAction = new Actionlog();
|
||||
$logAction->item_type = Asset::class;
|
||||
|
||||
@@ -28,8 +28,7 @@ class ComponentObserver
|
||||
|
||||
|
||||
/**
|
||||
* Listen to the Component created event, and increment
|
||||
* the next_auto_tag_base value in the settings table when i
|
||||
* Listen to the Component created event when
|
||||
* a new component is created.
|
||||
*
|
||||
* @param Component $component
|
||||
@@ -37,9 +36,6 @@ class ComponentObserver
|
||||
*/
|
||||
public function created(Component $component)
|
||||
{
|
||||
$settings = Setting::first();
|
||||
$settings->increment('next_auto_tag_base');
|
||||
|
||||
$logAction = new Actionlog();
|
||||
$logAction->item_type = Component::class;
|
||||
$logAction->item_id = $component->id;
|
||||
|
||||
@@ -28,8 +28,7 @@ class ConsumableObserver
|
||||
|
||||
|
||||
/**
|
||||
* Listen to the Consumable created event, and increment
|
||||
* the next_auto_tag_base value in the settings table when i
|
||||
* Listen to the Consumable created event when
|
||||
* a new consumable is created.
|
||||
*
|
||||
* @param Consumable $consumable
|
||||
@@ -37,8 +36,6 @@ class ConsumableObserver
|
||||
*/
|
||||
public function created(Consumable $consumable)
|
||||
{
|
||||
$settings = Setting::first();
|
||||
$settings->increment('next_auto_tag_base');
|
||||
|
||||
$logAction = new Actionlog();
|
||||
$logAction->item_type = Consumable::class;
|
||||
|
||||
@@ -28,8 +28,7 @@ class LicenseObserver
|
||||
|
||||
|
||||
/**
|
||||
* Listen to the License created event, and increment
|
||||
* the next_auto_tag_base value in the settings table when i
|
||||
* Listen to the License created event when
|
||||
* a new license is created.
|
||||
*
|
||||
* @param License $license
|
||||
@@ -37,8 +36,6 @@ class LicenseObserver
|
||||
*/
|
||||
public function created(License $license)
|
||||
{
|
||||
$settings = Setting::first();
|
||||
$settings->increment('next_auto_tag_base');
|
||||
|
||||
$logAction = new Actionlog();
|
||||
$logAction->item_type = License::class;
|
||||
|
||||
@@ -100,13 +100,12 @@ class AssetPresenter extends Presenter
|
||||
"visible" => true,
|
||||
"formatter" => "usersLinkObjFormatter"
|
||||
], [
|
||||
"field" => "assigned_to",
|
||||
"field" => "employee_number",
|
||||
"searchable" => false,
|
||||
"sortable" => false,
|
||||
"title" => trans('admin/users/table.employee_num'),
|
||||
"visible" => false,
|
||||
"formatter" => "employeeNumFormatter"
|
||||
|
||||
],[
|
||||
"field" => "location",
|
||||
"searchable" => true,
|
||||
|
||||
@@ -61,6 +61,14 @@ class LicensePresenter extends Presenter
|
||||
"searchable" => true,
|
||||
"sortable" => true,
|
||||
"title" => trans('admin/licenses/form.to_name'),
|
||||
], [
|
||||
"field" => "supplier",
|
||||
"searchable" => true,
|
||||
"sortable" => true,
|
||||
"switchable" => true,
|
||||
"title" => trans('general.supplier'),
|
||||
"visible" => false,
|
||||
"formatter" => "suppliersLinkObjFormatter"
|
||||
], [
|
||||
"field" => "manufacturer",
|
||||
"searchable" => true,
|
||||
|
||||
@@ -42,4 +42,8 @@ class LocationPresenter extends Presenter
|
||||
{
|
||||
return '<i class="fa fa-globe"></i>';
|
||||
}
|
||||
|
||||
public function fullName() {
|
||||
return $this->name;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -67,11 +67,15 @@ class AppServiceProvider extends ServiceProvider
|
||||
// This works around the use case where multiple deleted items have the same unique attribute.
|
||||
// (I think this is a bug in Laravel's validator?)
|
||||
Validator::extend('unique_undeleted', function ($attribute, $value, $parameters, $validator) {
|
||||
$count = DB::table($parameters[0])->select('id')->where($attribute, '=', $value)->whereNull('deleted_at')->where('id', '!=', $parameters[1])->count();
|
||||
return $count < 1;
|
||||
|
||||
if (count($parameters)) {
|
||||
$count = DB::table($parameters[0])->select('id')->where($attribute, '=', $value)->whereNull('deleted_at')->where('id', '!=', $parameters[1])->count();
|
||||
return $count < 1;
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
// Share common variables with all views.
|
||||
// Share common setting variables with all views.
|
||||
view()->composer('*', function ($view) {
|
||||
$view->with('snipeSettings', \App\Models\Setting::getSettings());
|
||||
});
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
"fideloper/proxy": "^3.1",
|
||||
"intervention/image": "^2.3",
|
||||
"javiereguiluz/easyslugger": "^1.0",
|
||||
"laravel/framework": "5.4.27",
|
||||
"laravel/framework": "5.4.20",
|
||||
"laravel/passport": "^1.0",
|
||||
"laravel/tinker": "^1.0",
|
||||
"laravelcollective/html": "^5.3",
|
||||
@@ -24,9 +24,13 @@
|
||||
"neitanod/forceutf8": "^2.0",
|
||||
"patchwork/utf8": "~1.2",
|
||||
"pragmarx/google2fa": "^1.0",
|
||||
"schuppo/password-strength": "~1.5",
|
||||
"spatie/laravel-backup": "^3.0.0",
|
||||
"tecnickcom/tc-lib-barcode": "^1.15",
|
||||
"watson/validating": "^3.0"
|
||||
"unicodeveloper/laravel-password": "^1.0",
|
||||
"watson/validating": "^3.0",
|
||||
"doctrine/instantiator": "1.0.5",
|
||||
"doctrine/inflector": "1.0.*"
|
||||
},
|
||||
"require-dev": {
|
||||
"fzaninotto/faker": "~1.4",
|
||||
@@ -34,7 +38,8 @@
|
||||
"symfony/css-selector": "3.1.*",
|
||||
"symfony/dom-crawler": "3.1.*",
|
||||
"codeception/codeception": "2.2.9",
|
||||
"squizlabs/php_codesniffer": "*"
|
||||
"squizlabs/php_codesniffer": "*",
|
||||
"phpunit/php-token-stream": "1.4.11"
|
||||
|
||||
},
|
||||
"autoload": {
|
||||
|
||||
731
composer.lock
generated
731
composer.lock
generated
File diff suppressed because it is too large
Load Diff
@@ -220,6 +220,8 @@ return [
|
||||
PragmaRX\Google2FA\Vendor\Laravel\ServiceProvider::class,
|
||||
Laravel\Passport\PassportServiceProvider::class,
|
||||
Laravel\Tinker\TinkerServiceProvider::class,
|
||||
Unicodeveloper\DumbPassword\DumbPasswordServiceProvider::class,
|
||||
Schuppo\PasswordStrength\PasswordStrengthServiceProvider::class,
|
||||
|
||||
|
||||
/*
|
||||
|
||||
@@ -85,8 +85,8 @@ return array(
|
||||
array(
|
||||
'permission' => 'assets.audit',
|
||||
'label' => 'Audit ',
|
||||
'note' => '',
|
||||
'display' => false,
|
||||
'note' => 'Allows the user to mark an asset as physically inventoried.',
|
||||
'display' => true,
|
||||
),
|
||||
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?php
|
||||
return array (
|
||||
'app_version' => 'v4.0-beta',
|
||||
'build_version' => '1',
|
||||
'hash_version' => 'gcb1e3b7',
|
||||
'full_hash' => 'v4.0-beta-244-gcb1e3b7',
|
||||
'app_version' => 'v4.0',
|
||||
'build_version' => 'beta3',
|
||||
'hash_version' => '22',
|
||||
'full_hash' => 'v4.0-beta3-22-gbd02b9e',
|
||||
);
|
||||
|
||||
@@ -210,5 +210,6 @@ $factory->define(App\Models\Setting::class, function ($faker) {
|
||||
'brand' => 1,
|
||||
'default_currency' => $faker->currencyCode,
|
||||
'locale' => $faker->locale,
|
||||
'pwd_secure_min' => 5,
|
||||
];
|
||||
});
|
||||
|
||||
@@ -21,7 +21,7 @@ use Illuminate\Database\Schema\Blueprint;
|
||||
function updateLegacyColumnName($customfield) {
|
||||
|
||||
$name_to_db_name = CustomField::name_to_db_name($customfield->name);
|
||||
\Log::debug('Trying to rename '.$name_to_db_name." to ".$customfield->convertUnicodeDbSlug()."...\n");
|
||||
//\Log::debug('Trying to rename '.$name_to_db_name." to ".$customfield->convertUnicodeDbSlug()."...\n");
|
||||
|
||||
if (Schema::hasColumn(CustomField::$table_name, $name_to_db_name)) {
|
||||
|
||||
@@ -32,7 +32,7 @@ function updateLegacyColumnName($customfield) {
|
||||
);
|
||||
|
||||
} else {
|
||||
\Log::debug('Legacy DB column '.$name_to_db_name.' was not found on the assets table.');
|
||||
//\Log::debug('Legacy DB column '.$name_to_db_name.' was not found on the assets table.');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
class AddManagerToLocationsTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::table('locations', function (Blueprint $table) {
|
||||
//
|
||||
$table->integer('manager_id')->nullable()->default(null);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::table('locations', function (Blueprint $table) {
|
||||
//
|
||||
$table->dropColumn('manager_id');
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -25,7 +25,7 @@ class AddNextAutoincrementToSettings extends Migration
|
||||
$table->bigInteger('next_auto_tag_base')->default('1');
|
||||
});
|
||||
|
||||
\Log::debug('Setting '.$next.' as default auto-increment');
|
||||
//\Log::debug('Setting '.$next.' as default auto-increment');
|
||||
|
||||
if ($settings = App\Models\Setting::first()) {
|
||||
$settings->next_auto_tag_base = $next;
|
||||
|
||||
@@ -13,6 +13,9 @@ class SetAssetArchivedToZeroDefault extends Migration
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
$platform = Schema::getConnection()->getDoctrineSchemaManager()->getDatabasePlatform();
|
||||
$platform->registerDoctrineTypeMapping('enum', 'string');
|
||||
|
||||
Schema::table('assets', function (Blueprint $table) {
|
||||
$table->boolean('archived')->default(0)->change();
|
||||
});
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
class AddSecurePasswordOptions extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::table('settings', function (Blueprint $table) {
|
||||
$table->boolean('pwd_secure_uncommon')->default('0');
|
||||
$table->string('pwd_secure_complexity')->nullable()->default(NULL);
|
||||
$table->integer('pwd_secure_min')->default('8');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::table('settings', function (Blueprint $table) {
|
||||
$table->dropColumn('pwd_secure_uncommon');
|
||||
$table->dropColumn('pwd_secure_complexity');
|
||||
$table->dropColumn('pwd_secure_min');
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
class AddAuditingTables extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::table('assets', function (Blueprint $table) {
|
||||
$table->date('next_audit_date')->nullable()->default(NULL);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::table('assets', function (Blueprint $table) {
|
||||
$table->dropColumn('next_audit_date');
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -12,8 +12,8 @@
|
||||
'success' => 'Asset Maintenance created successfully.'
|
||||
],
|
||||
'edit' => [
|
||||
'error' => 'Asset Maintenance was not edited, please try again.',
|
||||
'success' => 'Asset Maintenance edited successfully.'
|
||||
'error' => 'Asset Maintenance was not created, please try again.',
|
||||
'success' => 'Asset Maintenance created successfully.'
|
||||
],
|
||||
'asset_maintenance_incomplete' => 'Not Completed Yet',
|
||||
'warranty' => 'Warranty',
|
||||
|
||||
@@ -28,7 +28,7 @@ return array(
|
||||
|
||||
'fieldset' => array(
|
||||
|
||||
|
||||
'does_not_exist' => 'Fieldset does not exist',
|
||||
|
||||
'create' => array(
|
||||
'error' => 'Fieldset was not created, please try again.',
|
||||
|
||||
@@ -63,6 +63,8 @@ return array(
|
||||
'ldap_email' => 'LDAP Email',
|
||||
'load_remote_text' => 'Remote Scripts',
|
||||
'load_remote_help_text' => 'This Snipe-IT install can load scripts from the outside world.',
|
||||
'login_note' => 'Login Note',
|
||||
'login_note_help' => 'Optionally include a few sentences on your login screen, for example to assist people who have found a lost or stolen device. This field accepts <a href="https://help.github.com/articles/github-flavored-markdown/">Github flavored markdown</a>',
|
||||
'logo' => 'Logo',
|
||||
'full_multiple_companies_support_help_text' => 'Restricting users (including admins) assigned to companies to their company\'s assets.',
|
||||
'full_multiple_companies_support_text' => 'Full Multiple Companies Support',
|
||||
@@ -71,6 +73,12 @@ return array(
|
||||
'php' => 'PHP Version',
|
||||
'php_gd_info' => 'You must install php-gd to display QR codes, see install instructions.',
|
||||
'php_gd_warning' => 'PHP Image Processing and GD plugin is NOT installed.',
|
||||
'pwd_secure_complexity' => 'Password Complexity',
|
||||
'pwd_secure_complexity_help' => 'Select whichever password complexity rules you wish to enforce.',
|
||||
'pwd_secure_min' => 'Password minimum characters',
|
||||
'pwd_secure_min_help' => 'Minimum permitted value is 5',
|
||||
'pwd_secure_uncommon' => 'Prevent common passwords',
|
||||
'pwd_secure_uncommon_help' => 'This will disallow users from using common passwords from the top 10,000 passwords reported in breaches.',
|
||||
'qr_help' => 'Enable QR Codes first to set this',
|
||||
'qr_text' => 'QR Code Text',
|
||||
'setting' => 'Setting',
|
||||
@@ -105,6 +113,8 @@ return array(
|
||||
'width_w' => 'w',
|
||||
'height_h' => 'h',
|
||||
'text_pt' => 'pt',
|
||||
'thumbnail_max_h' => 'Max thumbnail height',
|
||||
'thumbnail_max_h_help' => 'Maximum height in pixels that thumbnails may display in the listing view. Min 25, max 500.',
|
||||
'two_factor' => 'Two Factor Authentication',
|
||||
'two_factor_secret' => 'Two-Factor Code',
|
||||
'two_factor_enrollment' => 'Two-Factor Enrollment',
|
||||
|
||||
@@ -31,6 +31,7 @@ return array(
|
||||
'create' => 'There was an issue creating the user. Please try again.',
|
||||
'update' => 'There was an issue updating the user. Please try again.',
|
||||
'delete' => 'There was an issue deleting the user. Please try again.',
|
||||
'delete_has_assets' => 'This user has items assigned and could not be deleted.',
|
||||
'unsuspend' => 'There was an issue unsuspending the user. Please try again.',
|
||||
'import' => 'There was an issue importing users. Please try again.',
|
||||
'asset_already_accepted' => 'This asset has already been accepted.',
|
||||
@@ -40,6 +41,7 @@ return array(
|
||||
'ldap_could_not_bind' => 'Could not bind to the LDAP server. Please check your LDAP server configuration in the LDAP config file. <br>Error from LDAP Server: ',
|
||||
'ldap_could_not_search' => 'Could not search the LDAP server. Please check your LDAP server configuration in the LDAP config file. <br>Error from LDAP Server:',
|
||||
'ldap_could_not_get_entries' => 'Could not get entries from the LDAP server. Please check your LDAP server configuration in the LDAP config file. <br>Error from LDAP Server:',
|
||||
'password_ldap' => 'The password for this account is managed by LDAP/Active Directory. Please contact your IT department to change your password. ',
|
||||
),
|
||||
|
||||
'deletefile' => array(
|
||||
|
||||
@@ -19,6 +19,7 @@ return array(
|
||||
'location' => 'Location',
|
||||
'lock_passwords' => 'Login details cannot be changed on this installation.',
|
||||
'manager' => 'Manager',
|
||||
'managed_locations' => 'Managed Locations',
|
||||
'name' => 'Name',
|
||||
'notes' => 'Notes',
|
||||
'password_confirm' => 'Confirm Password',
|
||||
|
||||
@@ -35,6 +35,8 @@ return array(
|
||||
"email" => "The :attribute format is invalid.",
|
||||
"exists" => "The selected :attribute is invalid.",
|
||||
"email_array" => "One or more email addresses is invalid.",
|
||||
"hashed_pass" => "Your current password is incorrect",
|
||||
'dumbpwd' => 'That password is too common.',
|
||||
"image" => "The :attribute must be an image.",
|
||||
"in" => "The selected :attribute is invalid.",
|
||||
"integer" => "The :attribute must be an integer.",
|
||||
|
||||
@@ -12,8 +12,8 @@
|
||||
'success' => 'تم إنشاء سند صيانة الأصل بنجاح.'
|
||||
],
|
||||
'edit' => [
|
||||
'error' => 'Asset Maintenance was not edited, please try again.',
|
||||
'success' => 'Asset Maintenance edited successfully.'
|
||||
'error' => 'Asset Maintenance was not created, please try again.',
|
||||
'success' => 'Asset Maintenance created successfully.'
|
||||
],
|
||||
'asset_maintenance_incomplete' => 'لم يكتمل بعد',
|
||||
'warranty' => 'الضمان',
|
||||
|
||||
@@ -28,7 +28,7 @@ return array(
|
||||
|
||||
'fieldset' => array(
|
||||
|
||||
|
||||
'does_not_exist' => 'Fieldset does not exist',
|
||||
|
||||
'create' => array(
|
||||
'error' => 'لم يتم إنشاء مجموعة-الحقول، الرجاء المحاولة مرة اخرى.',
|
||||
|
||||
@@ -63,6 +63,8 @@ return array(
|
||||
'ldap_email' => 'LDAP Email',
|
||||
'load_remote_text' => 'Remote Scripts',
|
||||
'load_remote_help_text' => 'This Snipe-IT install can load scripts from the outside world.',
|
||||
'login_note' => 'Login Note',
|
||||
'login_note_help' => 'Optionally include a few sentences on your login screen, for example to assist people who have found a lost or stolen device. This field accepts <a href="https://help.github.com/articles/github-flavored-markdown/">Github flavored markdown</a>',
|
||||
'logo' => 'Logo',
|
||||
'full_multiple_companies_support_help_text' => 'Restricting users (including admins) assigned to companies to their company\'s assets.',
|
||||
'full_multiple_companies_support_text' => 'Full Multiple Companies Support',
|
||||
@@ -71,6 +73,12 @@ return array(
|
||||
'php' => 'PHP Version',
|
||||
'php_gd_info' => 'You must install php-gd to display QR codes, see install instructions.',
|
||||
'php_gd_warning' => 'PHP Image Processing and GD plugin is NOT installed.',
|
||||
'pwd_secure_complexity' => 'Password Complexity',
|
||||
'pwd_secure_complexity_help' => 'Select whichever password complexity rules you wish to enforce.',
|
||||
'pwd_secure_min' => 'Password minimum characters',
|
||||
'pwd_secure_min_help' => 'Minimum permitted value is 5',
|
||||
'pwd_secure_uncommon' => 'Prevent common passwords',
|
||||
'pwd_secure_uncommon_help' => 'This will disallow users from using common passwords from the top 10,000 passwords reported in breaches.',
|
||||
'qr_help' => 'Enable QR Codes first to set this',
|
||||
'qr_text' => 'QR Code Text',
|
||||
'setting' => 'Setting',
|
||||
@@ -105,6 +113,8 @@ return array(
|
||||
'width_w' => 'w',
|
||||
'height_h' => 'h',
|
||||
'text_pt' => 'pt',
|
||||
'thumbnail_max_h' => 'Max thumbnail height',
|
||||
'thumbnail_max_h_help' => 'Maximum height in pixels that thumbnails may display in the listing view. Min 25, max 500.',
|
||||
'two_factor' => 'Two Factor Authentication',
|
||||
'two_factor_secret' => 'Two-Factor Code',
|
||||
'two_factor_enrollment' => 'Two-Factor Enrollment',
|
||||
|
||||
@@ -31,6 +31,7 @@ return array(
|
||||
'create' => 'حدث خطأ ما أثناء إنشاء هذا المستخدم. حاول مرة أخرى.',
|
||||
'update' => 'حدث خطأ أثناء تحديث هذا المستخدم. حاول مرة أخرى.',
|
||||
'delete' => 'حدث خطأ ما أثناء حذف هذا المستخدم. حاول مرة أخرى.',
|
||||
'delete_has_assets' => 'This user has items assigned and could not be deleted.',
|
||||
'unsuspend' => 'حدث خطأ ما أثناء إلغاء التعليق عن المستخدم. حاول مرة أخرى.',
|
||||
'import' => 'حدث خطأ أثناء استيراد المستخدمين. حاول مرة أخرى.',
|
||||
'asset_already_accepted' => 'هذا الجهاز تم قبوله مسبقاً.',
|
||||
@@ -40,6 +41,7 @@ return array(
|
||||
'ldap_could_not_bind' => 'Could not bind to the LDAP server. Please check your LDAP server configuration in the LDAP config file. <br>Error from LDAP Server: ',
|
||||
'ldap_could_not_search' => 'Could not search the LDAP server. Please check your LDAP server configuration in the LDAP config file. <br>Error from LDAP Server:',
|
||||
'ldap_could_not_get_entries' => 'Could not get entries from the LDAP server. Please check your LDAP server configuration in the LDAP config file. <br>Error from LDAP Server:',
|
||||
'password_ldap' => 'The password for this account is managed by LDAP/Active Directory. Please contact your IT department to change your password. ',
|
||||
),
|
||||
|
||||
'deletefile' => array(
|
||||
|
||||
@@ -19,6 +19,7 @@ return array(
|
||||
'location' => 'الموقع',
|
||||
'lock_passwords' => 'لا يمكن تغيير تفاصيل الدخول بالنسبة لهذا التنصيب.',
|
||||
'manager' => 'المدير',
|
||||
'managed_locations' => 'Managed Locations',
|
||||
'name' => 'الاسم',
|
||||
'notes' => 'مُلاحظات',
|
||||
'password_confirm' => 'تأكيد كلمة المرور',
|
||||
|
||||
@@ -35,6 +35,8 @@ return array(
|
||||
"email" => "The :attribute format is invalid.",
|
||||
"exists" => "The selected :attribute is invalid.",
|
||||
"email_array" => "One or more email addresses is invalid.",
|
||||
"hashed_pass" => "Your current password is incorrect",
|
||||
'dumbpwd' => 'That password is too common.',
|
||||
"image" => "The :attribute must be an image.",
|
||||
"in" => "The selected :attribute is invalid.",
|
||||
"integer" => "The :attribute must be an integer.",
|
||||
|
||||
@@ -12,8 +12,8 @@
|
||||
'success' => 'Поддръжката на актив създадена успешно.'
|
||||
],
|
||||
'edit' => [
|
||||
'error' => 'Поддръжката на активи не беше редактирана, моля опитайте отново.',
|
||||
'success' => 'Поддръжката на активи редактирана успешно.'
|
||||
'error' => 'Asset Maintenance was not created, please try again.',
|
||||
'success' => 'Asset Maintenance created successfully.'
|
||||
],
|
||||
'asset_maintenance_incomplete' => 'Все още неприключила',
|
||||
'warranty' => 'Гаранция',
|
||||
|
||||
@@ -28,7 +28,7 @@ return array(
|
||||
|
||||
'fieldset' => array(
|
||||
|
||||
|
||||
'does_not_exist' => 'Fieldset does not exist',
|
||||
|
||||
'create' => array(
|
||||
'error' => 'Fieldset не беше създаден, моля опитайте отново.',
|
||||
|
||||
@@ -63,6 +63,8 @@ return array(
|
||||
'ldap_email' => 'LDAP електронна поща',
|
||||
'load_remote_text' => 'Отдалечени скриптове',
|
||||
'load_remote_help_text' => 'Тази Snipe-IT инсталация може да зарежда и изпълнява външни скриптове.',
|
||||
'login_note' => 'Login Note',
|
||||
'login_note_help' => 'Optionally include a few sentences on your login screen, for example to assist people who have found a lost or stolen device. This field accepts <a href="https://help.github.com/articles/github-flavored-markdown/">Github flavored markdown</a>',
|
||||
'logo' => 'Лого',
|
||||
'full_multiple_companies_support_help_text' => 'Ограничаване на потребителите (включително административните) до активите на собствената им компания.',
|
||||
'full_multiple_companies_support_text' => 'Поддръжка на множество компании',
|
||||
@@ -71,6 +73,12 @@ return array(
|
||||
'php' => 'PHP версия',
|
||||
'php_gd_info' => 'Необходимо е да инсталирате php-gd, за да визуализирате QR кодове. Моля прегледайте инструкцията за инсталация.',
|
||||
'php_gd_warning' => 'php-gd НЕ е инсталиран.',
|
||||
'pwd_secure_complexity' => 'Password Complexity',
|
||||
'pwd_secure_complexity_help' => 'Select whichever password complexity rules you wish to enforce.',
|
||||
'pwd_secure_min' => 'Password minimum characters',
|
||||
'pwd_secure_min_help' => 'Minimum permitted value is 5',
|
||||
'pwd_secure_uncommon' => 'Prevent common passwords',
|
||||
'pwd_secure_uncommon_help' => 'This will disallow users from using common passwords from the top 10,000 passwords reported in breaches.',
|
||||
'qr_help' => 'Първо включете QR кодовете, за да извършите тези настройки.',
|
||||
'qr_text' => 'Съдържание на QR код',
|
||||
'setting' => 'Настройка',
|
||||
@@ -105,6 +113,8 @@ return array(
|
||||
'width_w' => 'w',
|
||||
'height_h' => 'h',
|
||||
'text_pt' => 'pt',
|
||||
'thumbnail_max_h' => 'Max thumbnail height',
|
||||
'thumbnail_max_h_help' => 'Maximum height in pixels that thumbnails may display in the listing view. Min 25, max 500.',
|
||||
'two_factor' => 'Двуфакторно удостоверяване',
|
||||
'two_factor_secret' => 'Двуфакторен код',
|
||||
'two_factor_enrollment' => 'Двуфакторово записване',
|
||||
|
||||
@@ -31,6 +31,7 @@ return array(
|
||||
'create' => 'Възникна проблем при създаването на този потребител. Моля, опитайте отново.',
|
||||
'update' => 'Възникна проблем при обновяването на този потребител. Моля, опитайте отново.',
|
||||
'delete' => 'Възникна проблем при изтриването на този потребител. Моля, опитайте отново.',
|
||||
'delete_has_assets' => 'This user has items assigned and could not be deleted.',
|
||||
'unsuspend' => 'Проблем при активирането на потребителя. Моля опитайте отново.',
|
||||
'import' => 'Проблем при зареждането на потребителите. Моля опитайте отново.',
|
||||
'asset_already_accepted' => 'Този актив е вече приет.',
|
||||
@@ -40,6 +41,7 @@ return array(
|
||||
'ldap_could_not_bind' => 'Проблем при връзката с LDAP сървъра. Моля прегледайте конфигурацията на LDAP.<br/>Грешка от LDAP сървъра: ',
|
||||
'ldap_could_not_search' => 'Проблем при търсенето в LDAP сървъра. Моля прегледайте конфигурацията на LDAP.<br/>Грешка от LDAP сървъра: ',
|
||||
'ldap_could_not_get_entries' => 'Проблем при извличането на резултат от LDAP сървъра. Моля прегледайте конфигурацията на LDAP.<br/>Грешка от LDAP сървъра:',
|
||||
'password_ldap' => 'The password for this account is managed by LDAP/Active Directory. Please contact your IT department to change your password. ',
|
||||
),
|
||||
|
||||
'deletefile' => array(
|
||||
|
||||
@@ -19,6 +19,7 @@ return array(
|
||||
'location' => 'Местоположение',
|
||||
'lock_passwords' => 'Настройките за вход не могат да бъдат променяни в текущата инсталация.',
|
||||
'manager' => 'Ръководител',
|
||||
'managed_locations' => 'Managed Locations',
|
||||
'name' => 'Име',
|
||||
'notes' => 'Бележки',
|
||||
'password_confirm' => 'Потвърждение на паролата',
|
||||
|
||||
@@ -35,6 +35,8 @@ return array(
|
||||
"email" => ":attribute е с невалиден формат.",
|
||||
"exists" => "Избраният :attribute е невалиден.",
|
||||
"email_array" => "Един или повече email адреси е невалиден.",
|
||||
"hashed_pass" => "Your current password is incorrect",
|
||||
'dumbpwd' => 'That password is too common.',
|
||||
"image" => ":attribute трябва да бъде изображение.",
|
||||
"in" => "Избраният :attribute е невалиден.",
|
||||
"integer" => ":attribute трябва да бъде целочислен.",
|
||||
|
||||
@@ -12,8 +12,8 @@
|
||||
'success' => 'Údržba zařízení byla v pořádku vytvořena.'
|
||||
],
|
||||
'edit' => [
|
||||
'error' => 'Údržbu zařízení se nepodařilo vytvořit, zkuste to prosím znovu.',
|
||||
'success' => 'Údržba zařízení byla upravena.'
|
||||
'error' => 'Asset Maintenance was not created, please try again.',
|
||||
'success' => 'Asset Maintenance created successfully.'
|
||||
],
|
||||
'asset_maintenance_incomplete' => 'Prozatím nedokončeno',
|
||||
'warranty' => 'Záruka',
|
||||
|
||||
@@ -28,7 +28,7 @@ return array(
|
||||
|
||||
'fieldset' => array(
|
||||
|
||||
|
||||
'does_not_exist' => 'Fieldset does not exist',
|
||||
|
||||
'create' => array(
|
||||
'error' => 'Sadu se nám nepodařilo vytvořit, pokuste se o to znovu.',
|
||||
|
||||
@@ -2,20 +2,20 @@
|
||||
|
||||
return array(
|
||||
|
||||
'does_not_exist' => 'Department does not exist.',
|
||||
'assoc_users' => 'This department is currently associated with at least one user and cannot be deleted. Please update your users to no longer reference this department and try again. ',
|
||||
'does_not_exist' => 'Oddělení neexistuje.',
|
||||
'assoc_users' => 'Toto oddělení je momentálně přiřazeno alespoň jednomu uživateli a nelze jej smazat. Aktualizujte své uživatele tak, aby již neodkázali na toto oddělení a zkuste to znovu.',
|
||||
'create' => array(
|
||||
'error' => 'Department was not created, please try again.',
|
||||
'success' => 'Department created successfully.'
|
||||
'error' => 'Oddělení nebylo vytvořeno, zkuste to prosím znovu.',
|
||||
'success' => 'Oddělení bylo úspěšně vytvořeno.'
|
||||
),
|
||||
'update' => array(
|
||||
'error' => 'Department was not updated, please try again',
|
||||
'success' => 'Department updated successfully.'
|
||||
'error' => 'Oddělení nebylo aktualizováno, zkuste to prosím znovu',
|
||||
'success' => 'Oddělení se úspěšně aktualizovalo.'
|
||||
),
|
||||
'delete' => array(
|
||||
'confirm' => 'Are you sure you wish to delete this department?',
|
||||
'error' => 'There was an issue deleting the department. Please try again.',
|
||||
'success' => 'The department was deleted successfully.'
|
||||
'confirm' => 'Opravdu chcete smazat toto oddělení?',
|
||||
'error' => 'Byl problém odstranit oddělení. Prosím zkuste to znovu.',
|
||||
'success' => 'Oddělení bylo úspěšně smazáno.'
|
||||
)
|
||||
|
||||
);
|
||||
|
||||
@@ -3,9 +3,9 @@
|
||||
return array(
|
||||
|
||||
'id' => 'ID',
|
||||
'name' => 'Department Name',
|
||||
'manager' => 'Manager',
|
||||
'location' => 'Location',
|
||||
'create' => 'Create Department',
|
||||
'update' => 'Update Department',
|
||||
'name' => 'Název Oddělení',
|
||||
'manager' => 'Manažer',
|
||||
'location' => 'Umístění',
|
||||
'create' => 'Vytvořit Oddělení',
|
||||
'update' => 'Aktualizovat Oddělení',
|
||||
);
|
||||
|
||||
@@ -48,7 +48,7 @@ return array(
|
||||
'delete' => array(
|
||||
'confirm' => 'Opravdu si přejete tento majetek odstranit?',
|
||||
'error' => 'Nepodařilo se nám tento majetek odstranit. Zkuste to prosím znovu.',
|
||||
'nothing_updated' => 'No assets were selected, so nothing was deleted.',
|
||||
'nothing_updated' => 'Žádný majetek nebyl vybrán, takže nic nebylo odstraněno.',
|
||||
'success' => 'Majetek byl úspěšně smazán.'
|
||||
),
|
||||
|
||||
|
||||
@@ -29,8 +29,8 @@ return array(
|
||||
),
|
||||
|
||||
'bulkedit' => array(
|
||||
'error' => 'No fields were changed, so nothing was updated.',
|
||||
'success' => 'Models updated.'
|
||||
'error' => 'Žádné pole nebyly změněny, takže nic nebylo aktualizováno.',
|
||||
'success' => 'Modely byly aktualizovány.'
|
||||
),
|
||||
|
||||
);
|
||||
|
||||
@@ -63,6 +63,8 @@ return array(
|
||||
'ldap_email' => 'LDAP email',
|
||||
'load_remote_text' => 'Vzdálené skripty',
|
||||
'load_remote_help_text' => 'Tato instalace Snipe-IT může nahrávat skripty z vnějšího světa.',
|
||||
'login_note' => 'Login Note',
|
||||
'login_note_help' => 'Optionally include a few sentences on your login screen, for example to assist people who have found a lost or stolen device. This field accepts <a href="https://help.github.com/articles/github-flavored-markdown/">Github flavored markdown</a>',
|
||||
'logo' => 'Logo',
|
||||
'full_multiple_companies_support_help_text' => 'Omezení uživatelů (včetně správců) jsou přiřazená ke společnostem s majetkem společnosti.',
|
||||
'full_multiple_companies_support_text' => 'Plná podpora více společností',
|
||||
@@ -71,6 +73,12 @@ return array(
|
||||
'php' => 'Verze PHP',
|
||||
'php_gd_info' => 'Je nutné nainstalovat php-gd pro zobrazení QR kódů. Více v instalační příručce.',
|
||||
'php_gd_warning' => 'PHP pluginy pro zpracování obrazu a GD nejsou nainstalovány.',
|
||||
'pwd_secure_complexity' => 'Password Complexity',
|
||||
'pwd_secure_complexity_help' => 'Select whichever password complexity rules you wish to enforce.',
|
||||
'pwd_secure_min' => 'Password minimum characters',
|
||||
'pwd_secure_min_help' => 'Minimum permitted value is 5',
|
||||
'pwd_secure_uncommon' => 'Prevent common passwords',
|
||||
'pwd_secure_uncommon_help' => 'This will disallow users from using common passwords from the top 10,000 passwords reported in breaches.',
|
||||
'qr_help' => 'Nejprve povolte QR kódy',
|
||||
'qr_text' => 'Text QR kódu',
|
||||
'setting' => 'Nastavení',
|
||||
@@ -90,7 +98,7 @@ return array(
|
||||
'about_settings_text' => 'Tato nastavení umožňují zvolit určité prvky instalace.',
|
||||
'labels_per_page' => 'Štítků na stránku',
|
||||
'label_dimensions' => 'Rozměry štítku (palce)',
|
||||
'next_auto_tag_base' => 'Next auto-increment',
|
||||
'next_auto_tag_base' => 'Další auto přírůstek',
|
||||
'page_padding' => 'Okraje stránky (palce)',
|
||||
'purge' => 'Vyčištění odstraněných záznamů',
|
||||
'labels_display_bgutter' => 'Spodní okraj štítku',
|
||||
@@ -105,6 +113,8 @@ return array(
|
||||
'width_w' => 'š',
|
||||
'height_h' => 'v',
|
||||
'text_pt' => 'pt',
|
||||
'thumbnail_max_h' => 'Max thumbnail height',
|
||||
'thumbnail_max_h_help' => 'Maximum height in pixels that thumbnails may display in the listing view. Min 25, max 500.',
|
||||
'two_factor' => 'Dvoufaktorové ověření',
|
||||
'two_factor_secret' => 'Dvojfaktorový kód',
|
||||
'two_factor_enrollment' => 'Dvojfaktorový zápis',
|
||||
|
||||
@@ -31,6 +31,7 @@ return array(
|
||||
'create' => 'Vyskytl se problém při vytvářením uživatele. Zkuste to znovu.',
|
||||
'update' => 'Vyskytl se problém při aktualizování uživatele. Zkuste to znovu.',
|
||||
'delete' => 'Vyskytl se problém při mazání uživatele. Zkuste to znovu.',
|
||||
'delete_has_assets' => 'This user has items assigned and could not be deleted.',
|
||||
'unsuspend' => 'Vyskytl se problém při rušení uživatele. Zkuste to znovu.',
|
||||
'import' => 'Vyskytl se problém při importu uživatelů. Zkuste to znovu.',
|
||||
'asset_already_accepted' => 'Tento majetek již byl odsouhlasen.',
|
||||
@@ -40,6 +41,7 @@ return array(
|
||||
'ldap_could_not_bind' => 'Nelze svázat server LDAP. Zkontrolujte prosím konfiguraci serveru LDAP v konfiguračním souboru LDAP. <br>Chyba serveru LDAP: ',
|
||||
'ldap_could_not_search' => 'Nelze vyhledat server LDAP. Zkontrolujte prosím konfiguraci serveru LDAP v konfiguračním souboru LDAP. <br>Chyba serveru LDAP:',
|
||||
'ldap_could_not_get_entries' => 'Nelze získat záznamy ze serveru LDAP. Zkontrolujte prosím konfiguraci serveru LDAP v konfiguračním souboru LDAP. <br>Chyba serveru LDAP:',
|
||||
'password_ldap' => 'The password for this account is managed by LDAP/Active Directory. Please contact your IT department to change your password. ',
|
||||
),
|
||||
|
||||
'deletefile' => array(
|
||||
|
||||
@@ -19,6 +19,7 @@ return array(
|
||||
'location' => 'Umístění',
|
||||
'lock_passwords' => 'Přihlašovací údaje nelze v této instalaci měnit.',
|
||||
'manager' => 'Nadřízený',
|
||||
'managed_locations' => 'Managed Locations',
|
||||
'name' => 'Položka',
|
||||
'notes' => 'Poznámky',
|
||||
'password_confirm' => 'Potvrzení hesla',
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
'cancel' => 'Storno',
|
||||
'categories' => 'Kategorie',
|
||||
'category' => 'Kategorie',
|
||||
'change' => 'In/Out',
|
||||
'change' => 'Příjem/Výdej',
|
||||
'changeemail' => 'Změnit e-mailovou adresu',
|
||||
'changepassword' => 'Změnit heslo',
|
||||
'checkin' => 'Příjem',
|
||||
@@ -58,8 +58,8 @@
|
||||
'delete' => 'Odstranit',
|
||||
'deleted' => 'Odstraněno',
|
||||
'delete_seats' => 'Vymazaná licenční místa',
|
||||
'departments' => 'Departments',
|
||||
'department' => 'Department',
|
||||
'departments' => 'Oddělení',
|
||||
'department' => 'Oddělení',
|
||||
'deployed' => 'Vydané',
|
||||
'depreciation_report' => 'Report zastarání',
|
||||
'download' => 'Stáhnout',
|
||||
@@ -145,14 +145,14 @@
|
||||
'select' => 'Zvolit',
|
||||
'search' => 'Hledat',
|
||||
'select_category' => 'Vyberte kategorii',
|
||||
'select_department' => 'Select a Department',
|
||||
'select_department' => 'Vyberte Oddělení',
|
||||
'select_depreciation' => 'Zvolit typ amortizace',
|
||||
'select_location' => 'Zvolit místo',
|
||||
'select_manufacturer' => 'Zvolit výrobce',
|
||||
'select_model' => 'Zvolit model',
|
||||
'select_supplier' => 'Zvolit dodavatele',
|
||||
'select_user' => 'Zvolit uživatele',
|
||||
'select_date' => 'Select Date (YYYY-MM-DD)',
|
||||
'select_date' => 'Vyberte Datum (RRRR-MM-DD)',
|
||||
'select_statuslabel' => 'Vybrat stav',
|
||||
'select_company' => 'Zvolte společnost',
|
||||
'select_asset' => 'Zvolte majetek',
|
||||
|
||||
@@ -35,6 +35,8 @@ return array(
|
||||
"email" => "Formát :attribute je neplatný.",
|
||||
"exists" => "Zvolený :attribute je neplatný.",
|
||||
"email_array" => "Jedna nebo více e-mailových adres je neplatná.",
|
||||
"hashed_pass" => "Your current password is incorrect",
|
||||
'dumbpwd' => 'That password is too common.',
|
||||
"image" => ":attribute musí být obrázek.",
|
||||
"in" => "Zvolený :attribute je neplatný.",
|
||||
"integer" => ":attribute musí být celočíselný.",
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user