diff --git a/Dockerfile b/Dockerfile index 09e511ba80..ed942e2587 100644 --- a/Dockerfile +++ b/Dockerfile @@ -96,6 +96,8 @@ RUN \ && rm -r "/var/www/html/storage/app/backups" && ln -fs "/var/lib/snipeit/dumps" "/var/www/html/storage/app/backups" \ && mkdir -p "/var/lib/snipeit/keys" && ln -fs "/var/lib/snipeit/keys/oauth-private.key" "/var/www/html/storage/oauth-private.key" \ && ln -fs "/var/lib/snipeit/keys/oauth-public.key" "/var/www/html/storage/oauth-public.key" \ + && ln -fs "/var/lib/snipeit/keys/ldap_client_tls.cert" "/var/www/html/storage/ldap_client_tls.cert" \ + && ln -fs "/var/lib/snipeit/keys/ldap_client_tls.key" "/var/www/html/storage/ldap_client_tls.key" \ && chown docker "/var/lib/snipeit/keys/" \ && chown -h docker "/var/www/html/storage/" \ && chmod +x /var/www/html/artisan \ diff --git a/app/Http/Controllers/Api/AssetsController.php b/app/Http/Controllers/Api/AssetsController.php index b1337c45b2..cdf37a903c 100644 --- a/app/Http/Controllers/Api/AssetsController.php +++ b/app/Http/Controllers/Api/AssetsController.php @@ -171,6 +171,7 @@ class AssetsController extends Controller // case we override with the actual count, so we should return 0 items. $offset = (($assets) && ($request->get('offset') > $assets->count())) ? $assets->count() : $request->get('offset', 0); + // Check to make sure the limit is not higher than the max allowed ((config('app.max_results') >= $request->input('limit')) && ($request->filled('limit'))) ? $limit = $request->input('limit') : $limit = config('app.max_results'); @@ -336,6 +337,7 @@ class AssetsController extends Controller return (new $transformer)->transformAssets($assets, $total, $request); } + /** * Returns JSON with information about an asset (by tag) for detail view. * @@ -373,9 +375,19 @@ class AssetsController extends Controller } return response()->json(Helper::formatStandardApiResponse('error', null, 'Asset not found'), 200); + $assets = Asset::with('assetstatus')->with('assignedTo'); + if ($request->input('deleted', 'false') === 'true') { + $assets = $assets->withTrashed(); } + $assets = $assets->where('serial', $serial)->get(); + if ($assets) { + return (new AssetsTransformer)->transformAssets($assets, $assets->count()); + } else { + return response()->json(Helper::formatStandardApiResponse('error', null, 'Asset not found'), 200); + } + } /** * Returns JSON with information about an asset for detail view. @@ -677,6 +689,8 @@ class AssetsController extends Controller return response()->json(Helper::formatStandardApiResponse('error', null, trans('admin/hardware/message.does_not_exist')), 200); } + + /** * Restore a soft-deleted asset. * diff --git a/app/Http/Transformers/AssetsTransformer.php b/app/Http/Transformers/AssetsTransformer.php index 8af6f62c64..c8a187a354 100644 --- a/app/Http/Transformers/AssetsTransformer.php +++ b/app/Http/Transformers/AssetsTransformer.php @@ -114,24 +114,13 @@ class AssetsTransformer } $permissions_array['available_actions'] = [ - 'checkout' => Gate::allows('checkout', Asset::class), - 'checkin' => Gate::allows('checkin', Asset::class), - 'clone' => false, - 'restore' => false, - 'update' => (bool) Gate::allows('update', Asset::class), - 'delete' => ($asset->assigned_to == '' && Gate::allows('delete', Asset::class)), - ]; - - if ($asset->deleted_at != '') { - $permissions_array['available_actions'] = [ - 'checkout' => true, - 'checkin' => false, - 'clone' => Gate::allows('create', Asset::class), - 'restore' => Gate::allows('create', Asset::class), - 'update' => false, - 'delete' => false, - ]; - } + 'checkout' => ($asset->deleted_at=='' && Gate::allows('checkout', Asset::class)) ? true : false, + 'checkin' => ($asset->deleted_at=='' && Gate::allows('checkin', Asset::class)) ? true : false, + 'clone' => Gate::allows('create', Asset::class) ? true : false, + 'restore' => ($asset->deleted_at!='' && Gate::allows('create', Asset::class)) ? true : false, + 'update' => ($asset->deleted_at=='' && Gate::allows('update', Asset::class)) ? true : false, + 'delete' => ($asset->deleted_at=='' && $asset->assigned_to =='' && Gate::allows('delete', Asset::class)) ? true : false, + ]; if (request('components')=='true') { diff --git a/app/Importer/Importer.php b/app/Importer/Importer.php index f80b869d54..f5b0ae44da 100644 --- a/app/Importer/Importer.php +++ b/app/Importer/Importer.php @@ -76,6 +76,7 @@ abstract class Importer 'department' => 'department', 'manager_first_name' => 'manager first name', 'manager_last_name' => 'manager last name', + 'min_amt' => 'minimum quantity', ]; /** * Map of item fields->csv names @@ -196,11 +197,11 @@ abstract class Importer $val = $default; $key = $this->lookupCustomKey($key); - // $this->log("Custom Key: ${key}"); + $this->log("Custom Key: ${key}"); if (array_key_exists($key, $array)) { $val = Encoding::toUTF8(trim($array[$key])); } - // $this->log("${key}: ${val}"); + $this->log("${key}: ${val}"); return $val; } diff --git a/app/Importer/import_mappings.md b/app/Importer/import_mappings.md index 7899cf679a..211a68bc9c 100644 --- a/app/Importer/import_mappings.md +++ b/app/Importer/import_mappings.md @@ -29,6 +29,7 @@ | serial number | serial | Asset, license | | status | status | Asset ? All | | supplier | supplier | Asset ? All | +| minimum quantity | min_amt | Consumable | | termination date | termination_date | License | | warranty months | warranty_months | Asset | | User Related Fields | assigned_to | Asset | diff --git a/app/Models/Consumable.php b/app/Models/Consumable.php index 2d456e12c4..13591123d7 100644 --- a/app/Models/Consumable.php +++ b/app/Models/Consumable.php @@ -68,6 +68,7 @@ class Consumable extends SnipeModel 'purchase_cost', 'purchase_date', 'qty', + 'min_amt', 'requestable', ]; @@ -185,6 +186,7 @@ class Consumable extends SnipeModel return $this->belongsTo(\App\Models\Category::class, 'category_id'); } + /** * Establishes the component -> action logs relationship * @@ -209,8 +211,8 @@ class Consumable extends SnipeModel if ($this->image) { return Storage::disk('public')->url(app('consumables_upload_path').$this->image); } - return false; + } /** @@ -225,6 +227,7 @@ class Consumable extends SnipeModel return $this->belongsToMany(\App\Models\User::class, 'consumables_users', 'consumable_id', 'assigned_to')->withPivot('user_id')->withTrashed()->withTimestamps(); } + /** * Determine whether to send a checkin/checkout email based on * asset model category diff --git a/config/version.php b/config/version.php index 008ac13252..3922390ee8 100644 --- a/config/version.php +++ b/config/version.php @@ -7,4 +7,4 @@ return array ( 'hash_version' => 'gace7abc1a', 'full_hash' => 'v6-pre-alpha-71-gace7abc1a', 'branch' => 'develop-v6-integration', -); \ No newline at end of file +); diff --git a/docker/supervisor-exit-event-listener b/docker/supervisor-exit-event-listener index 84201634e1..409ca0565e 100644 --- a/docker/supervisor-exit-event-listener +++ b/docker/supervisor-exit-event-listener @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 # A supervisor event listener which terminates supervisord if any of its child # processes enter the FATAL state. # https://stackoverflow.com/a/37527488/119527 diff --git a/package.json b/package.json index 08a18509fb..0437ad44ef 100644 --- a/package.json +++ b/package.json @@ -32,7 +32,7 @@ "bootstrap-colorpicker": "^2.5.3", "bootstrap-datepicker": "^1.9.0", "bootstrap-less": "^3.3.8", - "bootstrap-table": "^1.18.3", + "bootstrap-table": "^1.19.1", "chart.js": "^2.9.4", "css-loader": "^3.6.0", "ekko-lightbox": "^5.1.1", @@ -41,7 +41,7 @@ "imagemin": "^5.3.1", "jquery-form-validator": "^2.3.79", "jquery-slimscroll": "^1.3.8", - "jquery-ui": "^1.12.1", + "jquery-ui": "^1.13.0", "jquery-ui-bundle": "^1.12.1", "jquery.iframe-transport": "^1.0.0", "less": "^4.1.1", diff --git a/public/js/build/app.js.LICENSE.txt b/public/js/build/app.js.LICENSE.txt index c50b3aa8d6..eff7f713bb 100644 --- a/public/js/build/app.js.LICENSE.txt +++ b/public/js/build/app.js.LICENSE.txt @@ -36,7 +36,7 @@ */ /*! - * jQuery UI Widget 1.12.1 + * jQuery UI Widget 1.13.0 * http://jqueryui.com * * Copyright jQuery Foundation and other contributors diff --git a/resources/assets/js/components/importer/importer-file.vue b/resources/assets/js/components/importer/importer-file.vue index 83970614e5..86a83ace22 100644 --- a/resources/assets/js/components/importer/importer-file.vue +++ b/resources/assets/js/components/importer/importer-file.vue @@ -158,6 +158,7 @@ consumables: [ {id: 'item_no', text: "Item Number"}, {id: 'model_number', text: "Model Number"}, + {id: 'min_amt', text: "Minimum Quantity"}, ], licenses: [ {id: 'asset_tag', text: 'Assigned To Asset'}, @@ -216,6 +217,7 @@ .concat(this.columnOptions.accessories) .sort(sorter); case 'consumable': + console.log('Returned consumable'); return this.columnOptions.general .concat(this.columnOptions.consumables) .sort(sorter); @@ -309,4 +311,4 @@ select2: require('../select2.vue').default } } - \ No newline at end of file + diff --git a/resources/views/custom_fields/fieldsets/view.blade.php b/resources/views/custom_fields/fieldsets/view.blade.php index da08f7ab61..685eb95baf 100644 --- a/resources/views/custom_fields/fieldsets/view.blade.php +++ b/resources/views/custom_fields/fieldsets/view.blade.php @@ -57,21 +57,28 @@ {{$field->element}} {{ $field->field_encrypted=='1' ? trans('general.yes') : trans('general.no') }} + @if ($field->pivot->required) - - - Required - click to make optional - +
+ @csrf + +
+ @else - - - Optional - click to make required - + +
+ @csrf + +
@endif + @can('update', $custom_fieldset) - Remove +
+ @csrf + +
@endcan diff --git a/resources/views/layouts/default.blade.php b/resources/views/layouts/default.blade.php index 0138a61923..ac0f297e74 100644 --- a/resources/views/layouts/default.blade.php +++ b/resources/views/layouts/default.blade.php @@ -109,14 +109,14 @@ @if ($snipeSettings->brand == '3') @elseif ($snipeSettings->brand == '2') @@ -355,10 +355,17 @@ @endcan
  • - - - {{ trans('general.logout') }} + + + {{ trans('general.logout') }} + {{ csrf_field() }} + + + +
  • @@ -947,6 +954,7 @@ @endif + @livewireScripts diff --git a/routes/web/fields.php b/routes/web/fields.php index 50fd46efe6..aedaa46bd7 100644 --- a/routes/web/fields.php +++ b/routes/web/fields.php @@ -1,58 +1,40 @@ 'fields', 'middleware' => ['auth']], function () { - Route::get( - 'required/{fieldset_id}/{field_id}', - [ - CustomFieldsetsController::class, - 'makeFieldRequired' - ] - )->name('fields.required'); - Route::get( - 'optional/{fieldset_id}/{field_id}', - [ - CustomFieldsetsController::class, - 'makeFieldOptional' - ] - )->name('fields.optional'); +Route::group([ 'prefix' => 'fields','middleware' => ['auth'] ], function () { - Route::get( - '{field_id}/fieldset/{fieldset_id}/disassociate', - [ - CustomFieldsetsController::class, - 'deleteFieldFromFieldset' - ] - )->name('fields.disassociate'); + Route::post('required/{fieldset_id}/{field_id}', + ['uses' => 'CustomFieldsetsController@makeFieldRequired', + 'as' => 'fields.required'] + ); - Route::post( - 'fieldsets/{id}/associate', - [ - CustomFieldsetsController::class, - 'associate' - ] - )->name('fieldsets.associate'); + Route::post('optional/{fieldset_id}/{field_id}', + ['uses' => 'CustomFieldsetsController@makeFieldOptional', + 'as' => 'fields.optional'] + ); - Route::resource('fieldsets', CustomFieldsetsController::class, [ - 'parameters' => ['fieldset' => 'field_id', 'field' => 'field_id'], - ]); + Route::post('{field_id}/fieldset/{fieldset_id}/disassociate', + ['uses' => 'CustomFieldsController@deleteFieldFromFieldset', + 'as' => 'fields.disassociate'] + ); + + Route::post('fieldsets/{id}/associate', + ['uses' => 'CustomFieldsetsController@associate', + 'as' => 'fieldsets.associate'] + ); + + Route::resource('fieldsets', 'CustomFieldsetsController', [ + 'parameters' => ['fieldset' => 'field_id', 'field' => 'field_id'] + ]); }); - -Route::resource('fields', CustomFieldsController::class, [ - 'parameters' => ['field' => 'field_id'], +Route::resource('fields', 'CustomFieldsController', [ + 'middleware' => ['auth'], + 'parameters' => ['field' => 'field_id', 'fieldset' => 'fieldset_id'] ]); - - -