Merge remote-tracking branch 'origin/master' into develop

Signed-off-by: snipe <snipe@snipe.net>

# Conflicts:
#	.env.example
#	app/Http/Controllers/Auth/LoginController.php
#	app/Http/Kernel.php
#	app/Http/Transformers/ActionlogsTransformer.php
#	app/Importer/AssetImporter.php
#	app/Models/Accessory.php
#	app/Models/Consumable.php
#	app/Presenters/AccessoryPresenter.php
#	app/Presenters/ComponentPresenter.php
#	app/Presenters/ConsumablePresenter.php
#	app/Providers/AuthServiceProvider.php
#	composer.json
#	composer.lock
#	config/app.php
#	config/cors.php
#	config/version.php
#	package-lock.json
#	public/js/build/app.js
#	public/js/build/app.js.LICENSE.txt
#	public/js/dist/all.js
#	public/mix-manifest.json
#	resources/views/accessories/view.blade.php
#	resources/views/consumables/view.blade.php
#	resources/views/settings/saml.blade.php
#	routes/api.php
This commit is contained in:
snipe 2022-03-03 21:59:38 -08:00
commit b876d0abb0
42 changed files with 1141 additions and 878 deletions

View file

@ -157,4 +157,4 @@ IMPORT_TIME_LIMIT=600
IMPORT_MEMORY_LIMIT=500M
REPORT_TIME_LIMIT=12000
REQUIRE_SAML=false
API_THROTTLE_PER_MINUTE=120

View file

@ -84,10 +84,12 @@ class Handler extends ExceptionHandler
switch ($e->getStatusCode()) {
case '404':
return response()->json(Helper::formatStandardApiResponse('error', null, $statusCode . ' endpoint not found'), 404);
case '405':
case '429':
return response()->json(Helper::formatStandardApiResponse('error', null, 'Too many requests'), 429);
case '405':
return response()->json(Helper::formatStandardApiResponse('error', null, 'Method not allowed'), 405);
default:
return response()->json(Helper::formatStandardApiResponse('error', null, $statusCode), 405);
return response()->json(Helper::formatStandardApiResponse('error', null, $statusCode), $statusCode);
}
}

View file

@ -79,6 +79,8 @@ class AccessoriesController extends Controller
$accessory->qty = request('qty');
$accessory->user_id = Auth::user()->id;
$accessory->supplier_id = request('supplier_id');
$accessory->notes = request('notes');
$accessory = $request->handleImages($accessory);
@ -143,6 +145,7 @@ class AccessoriesController extends Controller
$accessory->purchase_cost = Helper::ParseCurrency(request('purchase_cost'));
$accessory->qty = request('qty');
$accessory->supplier_id = request('supplier_id');
$accessory->notes = request('notes');
$accessory = $request->handleImages($accessory);

View file

@ -40,7 +40,8 @@ class AccessoriesController extends Controller
'notes',
'created_at',
'min_amt',
'company_id'
'company_id',
'notes',
];
@ -70,6 +71,10 @@ class AccessoriesController extends Controller
$accessories->where('location_id','=',$request->input('location_id'));
}
if ($request->filled('notes')) {
$accessories->where('notes','=',$request->input('notes'));
}
// Set the offset to the API call's offset, unless the offset is higher than the actual count of items in which
// case we override with the actual count, so we should return 0 items.
$offset = (($accessories) && ($request->get('offset') > $accessories->count())) ? $accessories->count() : $request->get('offset', 0);

View file

@ -102,7 +102,7 @@ class AssetMaintenancesController extends Controller
*/
public function store(Request $request)
{
$this->authorize('edit', Asset::class);
$this->authorize('update', Asset::class);
// create a new model instance
$assetMaintenance = new AssetMaintenance();
$assetMaintenance->supplier_id = $request->input('supplier_id');
@ -154,7 +154,7 @@ class AssetMaintenancesController extends Controller
*/
public function update(Request $request, $assetMaintenanceId = null)
{
$this->authorize('edit', Asset::class);
$this->authorize('update', Asset::class);
// Check if the asset maintenance exists
$assetMaintenance = AssetMaintenance::findOrFail($assetMaintenanceId);
@ -218,7 +218,7 @@ class AssetMaintenancesController extends Controller
*/
public function destroy($assetMaintenanceId)
{
$this->authorize('edit', Asset::class);
$this->authorize('update', Asset::class);
// Check if the asset maintenance exists
$assetMaintenance = AssetMaintenance::findOrFail($assetMaintenanceId);

View file

@ -40,6 +40,7 @@ class ComponentsController extends Controller
'purchase_cost',
'qty',
'image',
'notes',
];
@ -62,6 +63,10 @@ class ComponentsController extends Controller
$components->where('location_id', '=', $request->input('location_id'));
}
if ($request->filled('notes')) {
$components->where('notes','=',$request->input('notes'));
}
// Set the offset to the API call's offset, unless the offset is higher than the actual count of items in which
// case we override with the actual count, so we should return 0 items.
$offset = (($components) && ($request->get('offset') > $components->count())) ? $components->count() : $request->get('offset', 0);

View file

@ -42,6 +42,7 @@ class ConsumablesController extends Controller
'item_no',
'qty',
'image',
'notes',
];
@ -74,6 +75,10 @@ class ConsumablesController extends Controller
$consumables->where('location_id','=',$request->input('location_id'));
}
if ($request->filled('notes')) {
$consumables->where('notes','=',$request->input('notes'));
}
// Set the offset to the API call's offset, unless the offset is higher than the actual count of items in which
// case we override with the actual count, so we should return 0 items.

View file

@ -7,6 +7,7 @@ use App\Http\Controllers\Controller;
use App\Http\Requests\SaveUserRequest;
use App\Http\Transformers\AccessoriesTransformer;
use App\Http\Transformers\AssetsTransformer;
use App\Http\Transformers\ConsumablesTransformer;
use App\Http\Transformers\LicensesTransformer;
use App\Http\Transformers\SelectlistTransformer;
use App\Http\Transformers\UsersTransformer;
@ -131,6 +132,26 @@ class UsersController extends Controller
$users = $users->where('users.manager_id','=',$request->input('manager_id'));
}
if ($request->filled('ldap_import')) {
$users = $users->where('ldap_import', '=', $request->input('ldap_import'));
}
if ($request->filled('assets_count')) {
$users->has('assets', '=', $request->input('assets_count'));
}
if ($request->filled('consumables_count')) {
$users->has('consumables', '=', $request->input('consumables_count'));
}
if ($request->filled('licenses_count')) {
$users->has('licenses', '=', $request->input('licenses_count'));
}
if ($request->filled('accessories_count')) {
$users->has('accessories', '=', $request->input('accessories_count'));
}
if ($request->filled('search')) {
$users = $users->TextSearch($request->input('search'));
}
@ -445,6 +466,24 @@ class UsersController extends Controller
return (new AssetsTransformer)->transformAssets($assets, $assets->count(), $request);
}
/**
* Return JSON containing a list of consumables assigned to a user.
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v3.0]
* @param $userId
* @return string JSON
*/
public function consumables(Request $request, $id)
{
$this->authorize('view', User::class);
$this->authorize('view', Consumable::class);
$user = User::findOrFail($id);
$consumables = $user->consumables;
return (new ConsumablesTransformer)->transformConsumables($consumables, $consumables->count(), $request);
}
/**
* Return JSON containing a list of accessories assigned to a user.
*

View file

@ -65,7 +65,7 @@ class AssetMaintenancesController extends Controller
*/
public function create()
{
$this->authorize('edit', Asset::class);
$this->authorize('update', Asset::class);
$asset = null;
if ($asset = Asset::find(request('asset_id'))) {
@ -96,7 +96,7 @@ class AssetMaintenancesController extends Controller
*/
public function store(Request $request)
{
$this->authorize('edit', Asset::class);
$this->authorize('update', Asset::class);
// create a new model instance
$assetMaintenance = new AssetMaintenance();
$assetMaintenance->supplier_id = $request->input('supplier_id');
@ -148,7 +148,7 @@ class AssetMaintenancesController extends Controller
*/
public function edit($assetMaintenanceId = null)
{
$this->authorize('edit', Asset::class);
$this->authorize('update', Asset::class);
// Check if the asset maintenance exists
if (is_null($assetMaintenance = AssetMaintenance::find($assetMaintenanceId))) {
// Redirect to the improvement management page
@ -199,7 +199,7 @@ class AssetMaintenancesController extends Controller
*/
public function update(Request $request, $assetMaintenanceId = null)
{
$this->authorize('edit', Asset::class);
$this->authorize('update', Asset::class);
// Check if the asset maintenance exists
if (is_null($assetMaintenance = AssetMaintenance::find($assetMaintenanceId))) {
// Redirect to the asset maintenance management page
@ -267,7 +267,7 @@ class AssetMaintenancesController extends Controller
*/
public function destroy($assetMaintenanceId)
{
$this->authorize('edit', Asset::class);
$this->authorize('update', Asset::class);
// Check if the asset maintenance exists
if (is_null($assetMaintenance = AssetMaintenance::find($assetMaintenanceId))) {
// Redirect to the asset maintenance management page

View file

@ -68,12 +68,13 @@ class LoginController extends Controller
return redirect()->intended('/');
}
//If the environment is set to ALWAYS require SAML, go straight to the SAML route.
//We don't need to check other settings, as this should override those.
if(config('app.require_saml')) {
// If the environment is set to ALWAYS require SAML, go straight to the SAML route.
// We don't need to check other settings, as this should override those.
if (config('app.require_saml')) {
return redirect()->route('saml.login');
}
if ($this->saml->isEnabled() && Setting::getSettings()->saml_forcelogin == '1' && ! ($request->has('nosaml') || $request->session()->has('error'))) {
return redirect()->route('saml.login');
}
@ -235,8 +236,9 @@ class LoginController extends Controller
*/
public function login(Request $request)
{
//If the environment is set to ALWAYS require SAML, return access denied
if(config('app.require_saml')) {
if (config('app.require_saml')) {
return view('errors.403');
}

View file

@ -80,6 +80,7 @@ class ComponentsController extends Controller
$component->purchase_cost = Helper::ParseCurrency($request->input('purchase_cost', null));
$component->qty = $request->input('qty');
$component->user_id = Auth::id();
$component->notes = $request->input('notes');
$component = $request->handleImages($component);
@ -152,6 +153,7 @@ class ComponentsController extends Controller
$component->purchase_date = $request->input('purchase_date');
$component->purchase_cost = Helper::ParseCurrency(request('purchase_cost'));
$component->qty = $request->input('qty');
$component->notes = $request->input('notes');
$component = $request->handleImages($component);

View file

@ -78,6 +78,8 @@ class ConsumablesController extends Controller
$consumable->purchase_cost = Helper::ParseCurrency($request->input('purchase_cost'));
$consumable->qty = $request->input('qty');
$consumable->user_id = Auth::id();
$consumable->notes = $request->input('notes');
$consumable = $request->handleImages($consumable);
@ -140,6 +142,7 @@ class ConsumablesController extends Controller
$consumable->purchase_date = $request->input('purchase_date');
$consumable->purchase_cost = Helper::ParseCurrency($request->input('purchase_cost'));
$consumable->qty = Helper::ParseFloat($request->input('qty'));
$consumable->notes = $request->input('notes');
$consumable = $request->handleImages($consumable);

View file

@ -45,7 +45,6 @@ class Kernel extends HttpKernel
],
'api' => [
'throttle:120,1',
'auth:api',
],
];

View file

@ -1,5 +1,4 @@
<?php
namespace App\Http\Transformers;
use App\Helpers\Helper;
@ -9,73 +8,58 @@ use Illuminate\Database\Eloquent\Collection;
class ActionlogsTransformer
{
public function transformActionlogs(Collection $actionlogs, $total)
public function transformActionlogs (Collection $actionlogs, $total)
{
$array = [];
$array = array();
$settings = Setting::getSettings();
foreach ($actionlogs as $actionlog) {
$array[] = self::transformActionlog($actionlog, $settings);
}
return (new DatatablesTransformer)->transformDatatables($array, $total);
}
public function transformActionlog(Actionlog $actionlog, $settings = null)
private function clean_field($value)
{
// This object stuff is weird, and is used to make up for the fact that
// older data can get strangely formatted if an asset existed,
// then a new custom field is added, and the asset is saved again.
// It can result in funnily-formatted strings like:
//
// {"_snipeit_right_sized_fault_tolerant_localareanetwo_1":
// {"old":null,"new":{"value":"1579490695972","_snipeit_new_field_2":2,"_snipeit_new_field_3":"Monday, 20 January 2020 2:24:55 PM"}}
// so we have to walk down that next level
if(is_object($value) && isset($value->value)) {
return $this->clean_field($value->value);
}
return is_scalar($value) || is_null($value) ? e($value) : e(json_encode($value));
}
public function transformActionlog (Actionlog $actionlog, $settings = null)
{
$icon = $actionlog->present()->icon();
if ($actionlog->filename != '') {
$icon = e(Helper::filetype_icon($actionlog->filename));
if ($actionlog->filename!='') {
$icon = e(\App\Helpers\Helper::filetype_icon($actionlog->filename));
}
// This is necessary since we can't escape special characters within a JSON object
if (($actionlog->log_meta) && ($actionlog->log_meta != '')) {
if (($actionlog->log_meta) && ($actionlog->log_meta!='')) {
$meta_array = json_decode($actionlog->log_meta);
if ($meta_array) {
foreach ($meta_array as $key => $value) {
foreach ($value as $meta_key => $meta_value) {
if (is_array($meta_value)) {
foreach ($meta_value as $meta_value_key => $meta_value_value) {
if (is_scalar($meta_value_value)) {
$clean_meta[$key][$meta_value_key] = e($meta_value_value);
} else {
$clean_meta[$key][$meta_value_key] = 'invalid scalar: '.print_r($meta_value_value, true);
}
}
} else {
// This object stuff is weird, and is used to make up for the fact that
// older data can get strangely formatted if an asset existed,
// then a new custom field is added, and the asset is saved again.
// It can result in funnily-formatted strings like:
//
// {"_snipeit_right_sized_fault_tolerant_localareanetwo_1":
// {"old":null,"new":{"value":"1579490695972","_snipeit_new_field_2":2,"_snipeit_new_field_3":"Monday, 20 January 2020 2:24:55 PM"}}
// so we have to walk down that next level
if (is_object($meta_value)) {
foreach ($meta_value as $meta_value_key => $meta_value_value) {
if ($meta_value_key == 'value') {
$clean_meta[$key]['old'] = null;
$clean_meta[$key]['new'] = e($meta_value->value);
} else {
$clean_meta[$meta_value_key]['old'] = null;
$clean_meta[$meta_value_key]['new'] = e($meta_value_value);
}
}
} else {
$clean_meta[$key][$meta_key] = e($meta_value);
}
}
}
foreach ($meta_array as $fieldname => $fieldata) {
$clean_meta[$fieldname]['old'] = $this->clean_field($fieldata->old);
$clean_meta[$fieldname]['new'] = $this->clean_field($fieldata->new);
}
}
}
$array = [
'id' => (int) $actionlog->id,
'icon' => $icon,
'file' => ($actionlog->filename != '') ?
'file' => ($actionlog->filename!='') ?
[
'url' => route('show/assetfile', ['assetId' => $actionlog->item->id, 'fileId' => $actionlog->id]),
'filename' => $actionlog->filename,
@ -84,7 +68,7 @@ class ActionlogsTransformer
'item' => ($actionlog->item) ? [
'id' => (int) $actionlog->item->id,
'name' => ($actionlog->itemType() == 'user') ? $actionlog->filename : e($actionlog->item->getDisplayNameAttribute()),
'name' => ($actionlog->itemType()=='user') ? $actionlog->filename : e($actionlog->item->getDisplayNameAttribute()),
'type' => e($actionlog->itemType()),
] : null,
'location' => ($actionlog->location) ? [
@ -93,18 +77,18 @@ 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->calcNextAuditDate(null, $actionlog->item), 'date') : null,
'next_audit_date' => ($actionlog->itemType()=='asset') ? Helper::getFormattedDateObject($actionlog->calcNextAuditDate(null, $actionlog->item), 'date'): null,
'days_to_next_audit' => $actionlog->daysUntilNextAudit($settings->audit_interval, $actionlog->item),
'action_type' => $actionlog->present()->actionType(),
'admin' => ($actionlog->user) ? [
'id' => (int) $actionlog->user->id,
'name' => e($actionlog->user->getFullNameAttribute()),
'first_name'=> e($actionlog->user->first_name),
'last_name'=> e($actionlog->user->last_name),
'last_name'=> e($actionlog->user->last_name)
] : null,
'target' => ($actionlog->target) ? [
'id' => (int) $actionlog->target->id,
'name' => ($actionlog->targetType() == 'user') ? e($actionlog->target->getFullNameAttribute()) : e($actionlog->target->getDisplayNameAttribute()),
'name' => ($actionlog->targetType()=='user') ? e($actionlog->target->getFullNameAttribute()) : e($actionlog->target->getDisplayNameAttribute()),
'type' => e($actionlog->targetType()),
] : null,
@ -114,17 +98,23 @@ class ActionlogsTransformer
'action_date' => ($actionlog->action_date) ? Helper::getFormattedDateObject($actionlog->action_date, 'datetime'): Helper::getFormattedDateObject($actionlog->created_at, 'datetime'),
];
//\Log::info("Clean Meta is: ".print_r($clean_meta,true));
return $array;
}
public function transformCheckedoutActionlog(Collection $accessories_users, $total)
public function transformCheckedoutActionlog (Collection $accessories_users, $total)
{
$array = [];
$array = array();
foreach ($accessories_users as $user) {
$array[] = (new UsersTransformer)->transformUser($user);
}
return (new DatatablesTransformer)->transformDatatables($array, $total);
}
}
}

View file

@ -45,6 +45,7 @@ class ComponentsTransformer
'id' => (int) $component->company->id,
'name' => e($component->company->name),
] : null,
'notes' => ($component->notes) ? e($component->notes) : null,
'created_at' => Helper::getFormattedDateObject($component->created_at, 'datetime'),
'updated_at' => Helper::getFormattedDateObject($component->updated_at, 'datetime'),
'user_can_checkout' => ($component->numRemaining() > 0) ? 1 : 0,

View file

@ -38,6 +38,7 @@ class ConsumablesTransformer
'purchase_cost' => Helper::formatCurrencyOutput($consumable->purchase_cost),
'purchase_date' => Helper::getFormattedDateObject($consumable->purchase_date, 'date'),
'qty' => (int) $consumable->qty,
'notes' => ($consumable->notes) ? e($consumable->notes) : null,
'created_at' => Helper::getFormattedDateObject($consumable->created_at, 'datetime'),
'updated_at' => Helper::getFormattedDateObject($consumable->updated_at, 'datetime'),
];

View file

@ -39,6 +39,7 @@ class AssetImporter extends ItemImporter
}
}
$this->createAssetIfNotExists($row);
}

View file

@ -37,7 +37,7 @@ class Accessory extends SnipeModel
*
* @var array
*/
protected $searchableAttributes = ['name', 'model_number', 'order_number', 'purchase_date'];
protected $searchableAttributes = ['name', 'model_number', 'order_number', 'purchase_date', 'notes'];
/**
* The relations and their attributes that should be included when searching the model.
@ -64,6 +64,7 @@ class Accessory extends SnipeModel
'purchase_cost' => 'numeric|nullable',
];
/**
* Whether the model should inject it's identifier to the unique
* validation rules before attempting validation. If this property
@ -94,6 +95,7 @@ class Accessory extends SnipeModel
'qty',
'min_amt',
'requestable',
'notes',
];
@ -110,6 +112,7 @@ class Accessory extends SnipeModel
return $this->belongsTo(\App\Models\Supplier::class, 'supplier_id');
}
/**
* Sets the requestable attribute on the accessory
*
@ -220,8 +223,8 @@ class Accessory extends SnipeModel
if ($this->image) {
return Storage::disk('public')->url(app('accessories_upload_path').$this->image);
}
return false;
}
/**

View file

@ -65,6 +65,7 @@ class Component extends SnipeModel
'order_number',
'qty',
'serial',
'notes',
];
use Searchable;
@ -74,7 +75,7 @@ class Component extends SnipeModel
*
* @var array
*/
protected $searchableAttributes = ['name', 'order_number', 'serial', 'purchase_cost', 'purchase_date'];
protected $searchableAttributes = ['name', 'order_number', 'serial', 'purchase_cost', 'purchase_date', 'notes'];
/**
* The relations and their attributes that should be included when searching the model.

View file

@ -27,7 +27,8 @@ class Consumable extends SnipeModel
'category_id' => 'integer',
'company_id' => 'integer',
'qty' => 'integer',
'min_amt' => 'integer', ];
'min_amt' => 'integer',
];
/**
* Category validation rules
@ -70,6 +71,7 @@ class Consumable extends SnipeModel
'qty',
'min_amt',
'requestable',
'notes',
];
use Searchable;
@ -79,7 +81,7 @@ class Consumable extends SnipeModel
*
* @var array
*/
protected $searchableAttributes = ['name', 'order_number', 'purchase_cost', 'purchase_date', 'item_no', 'model_number'];
protected $searchableAttributes = ['name', 'order_number', 'purchase_cost', 'purchase_date', 'item_no', 'model_number', 'notes'];
/**
* The relations and their attributes that should be included when searching the model.

View file

@ -59,7 +59,9 @@ class AccessoryPresenter extends Presenter
'field' => 'manufacturer',
'searchable' => true,
'sortable' => true,
'switchable' => true,
'title' => trans('general.manufacturer'),
'visible' => false,
'formatter' => 'manufacturersLinkObjFormatter',
], [
'field' => 'supplier',
@ -89,6 +91,7 @@ class AccessoryPresenter extends Presenter
'field' => 'remaining_qty',
'searchable' => false,
'sortable' => false,
'visible' => false,
'title' => trans('admin/accessories/general.remaining'),
], [
'field' => 'purchase_date',
@ -110,6 +113,13 @@ class AccessoryPresenter extends Presenter
'sortable' => true,
'visible' => false,
'title' => trans('general.order_number'),
],[
'field' => 'notes',
'searchable' => true,
'sortable' => true,
'visible' => false,
'title' => trans('general.notes'),
'formatter' => 'notesFormatter'
], [
'field' => 'change',
'searchable' => false,

View file

@ -103,6 +103,13 @@ class ComponentPresenter extends Presenter
'visible' => true,
'footerFormatter' => 'sumFormatterQuantity',
'class' => 'text-right',
], [
'field' => 'notes',
'searchable' => true,
'sortable' => true,
'visible' => false,
'title' => trans('general.notes'),
'formatter' => 'notesFormatter',
],
];

View file

@ -115,6 +115,13 @@ class ConsumablePresenter extends Presenter
'visible' => true,
'footerFormatter' => 'sumFormatterQuantity',
'class' => 'text-right',
], [
'field' => 'notes',
'searchable' => true,
'sortable' => true,
'visible' => false,
'title' => trans('general.notes'),
'formatter' => 'notesFormatter',
], [
'field' => 'change',
'searchable' => false,

View file

@ -121,6 +121,7 @@ class AuthServiceProvider extends ServiceProvider
}
});
// -----------------------------------------
// Reports
// -----------------------------------------

View file

@ -30,7 +30,7 @@
"erusev/parsedown": "^1.7",
"facade/ignition": "^2.10",
"fideloper/proxy": "^4.3",
"fruitcake/laravel-cors": "^2.0",
"fruitcake/laravel-cors": "^2.2",
"guzzlehttp/guzzle": "^7.0.1",
"intervention/image": "^2.5",
"javiereguiluz/easyslugger": "^1.0",

1541
composer.lock generated

File diff suppressed because it is too large Load diff

View file

@ -250,6 +250,7 @@ return [
'enable_csp' => env('ENABLE_CSP', false),
/*
|--------------------------------------------------------------------------
| Require SAML Login
@ -265,7 +266,6 @@ return [
'require_saml' => env('REQUIRE_SAML', false),
/*
|--------------------------------------------------------------------------
| Demo Mode Lockdown
@ -418,4 +418,15 @@ return [
],
/*
|--------------------------------------------------------------------------
| API Throttling
|--------------------------------------------------------------------------
|
| This value determines the number of API requests permitted per minute
|
*/
'api_throttle_per_minute' => env('API_THROTTLE_PER_MINUTE', 120),
];

View file

@ -1,48 +1,49 @@
<?php
/**
* ---------------------------------------------------------------------
* THIS IS $allowed_origins code IS NOT PART OF THE ORIGINAL CORS PACKAGE.
* IT IS A MODIFICATION BY SNIPE-IT TO ALLOW ADDING ALLOWED ORIGINS VIA THE ENV.
* ---------------------------------------------------------------------
*
* Since we don't really want people editing config files (lest they get
* overwritten later), this enables the person managing the Snipe-IT
* installation to modify these values without modifying the code.
*
* If APP_CORS_ALLOWED_ORIGINS is not set in the .env (for example if no one added it
* after an upgrade from a previous version that didn't include it in the .env.example) or is null,
* set it to * to allow all. If there is a value, either a single url or a comma-delimited
* list of urls, explode that out into an array to whitelist just those urls.
*/
$allowed_origins = env('CORS_ALLOWED_ORIGINS') !== null ?
explode(',', env('CORS_ALLOWED_ORIGINS')) : [];
/**
* Original Laravel CORS package config file modifications end here
*
*/
return [
'supportsCredentials' => false,
'allowedOrigins' => $allowed_origins,
'allowedHeaders' => ['*'],
'allowedMethods' => ['GET', 'POST', 'PUT', 'PATCH', 'DELETE'],
'maxAge' => 0,
/*
|--------------------------------------------------------------------------
| Cross-Origin Resource Sharing (CORS) Configuration
| Laravel CORS
|--------------------------------------------------------------------------
|
| Here you may configure your settings for cross-origin resource sharing
| or "CORS". This determines what cross-origin operations may execute
| in web browsers. You are free to adjust these settings as needed.
|
| To learn more: https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS
| allowedOrigins, allowedHeaders and allowedMethods can be set to array('*')
| to accept any value.
|
*/
'supports_credentials' => false,
'allowed_origins' => $allowed_origins,
'allowed_origins_patterns' => [],
'allowed_headers' => ['*'],
'allowed_methods' => ['GET', 'POST', 'PUT', 'PATCH', 'DELETE'],
'exposed_headers' => [],
'max_age' => 0,
'paths' => ['api/*', 'sanctum/csrf-cookie'],
'allowed_methods' => ['*'],
'allowed_origins' => ['*'],
'allowed_origins_patterns' => [],
'allowed_headers' => ['*'],
'exposed_headers' => [],
'max_age' => 0,
'supports_credentials' => false,
];

View file

@ -0,0 +1,34 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class AddNotesToAccessories extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('accessories', function (Blueprint $table) {
$table->text("notes")->nullable()->default(null);
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('accessories', function (Blueprint $table) {
if (Schema::hasColumn('accessories', 'notes')) {
$table->dropColumn('notes');
}
});
}
}

View file

@ -0,0 +1,34 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class AddNotesToComponents extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('components', function (Blueprint $table) {
$table->text("notes")->nullable()->default(null);
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('components', function (Blueprint $table) {
if (Schema::hasColumn('components', 'notes')) {
$table->dropColumn('notes');
}
});
}
}

View file

@ -0,0 +1,34 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class AddNotesToConsumables extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('consumables', function (Blueprint $table) {
$table->text("notes")->nullable()->default(null);
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('consumables', function (Blueprint $table) {
if (Schema::hasColumn('consumables', 'notes')) {
$table->dropColumn('notes');
}
});
}
}

Binary file not shown.

BIN
public/js/dist/all.js vendored

Binary file not shown.

View file

@ -1,5 +1,5 @@
{
"/js/build/app.js": "/js/build/app.js?id=53bb9a89289532242ef7",
"/js/build/app.js": "/js/build/app.js?id=869aec997ba93ec756a2",
"/css/dist/skins/skin-blue.css": "/css/dist/skins/skin-blue.css?id=83e39e254b7f9035eddc",
"/css/build/overrides.css": "/css/build/overrides.css?id=4fc3a0e0a16964643e70",
"/css/build/app.css": "/css/build/app.css?id=a7cd7ad6e0e053ccf443",
@ -26,7 +26,7 @@
"/css/dist/bootstrap-table.css": "/css/dist/bootstrap-table.css?id=810d7e520c3057ee500e",
"/js/build/vendor.js": "/js/build/vendor.js?id=651427cc4b45d8e68d0c",
"/js/dist/bootstrap-table.js": "/js/dist/bootstrap-table.js?id=675a086b82536dd212f0",
"/js/dist/all.js": "/js/dist/all.js?id=7fe089bb7f3e8a1fd4a4",
"/js/dist/all.js": "/js/dist/all.js?id=d850187bf56be758be7c",
"/css/dist/skins/skin-green.min.css": "/css/dist/skins/skin-green.min.css?id=efda2335fa5243175850",
"/css/dist/skins/skin-green-dark.min.css": "/css/dist/skins/skin-green-dark.min.css?id=6e35fb4cb2f1063b3047",
"/css/dist/skins/skin-black.min.css": "/css/dist/skins/skin-black.min.css?id=ec96c42439cdeb022133",

View file

@ -147,6 +147,8 @@
assets: [
{id: 'asset_tag', text: 'Asset Tag' },
{id: 'asset_model', text: 'Model Name' },
{id: 'asset_notes', text: 'Asset Notes' },
{id: 'model_notes', text: 'Model Notes' },
{id: 'checkout_class', text: 'Checkout Type' },
{id: 'checkout_location', text: 'Checkout Location' },
{id: 'image', text: 'Image Filename' },
@ -172,6 +174,7 @@
{id: 'notes', text: 'Notes' },
{id: 'license_email', text: 'Licensed To Email' },
{id: 'license_name', text: 'Licensed To Name' },
{id: 'notes', text: 'Notes' },
{id: 'purchase_order', text: 'Purchase Order' },
{id: 'reassignable', text: 'Reassignable' },
{id: 'seats', text: 'Seats' },
@ -185,6 +188,7 @@
{id: 'manager_first_name', text: 'Manager First Name' },
{id: 'notes', text: 'Notes' },
{id: 'manager_last_name', text: 'Manager Last Name' },
{id: 'notes', text: 'Notes' },
{id: 'activated', text: 'Activated' },
{id: 'address', text: 'Address' },
{id: 'city', text: 'City' },

View file

@ -174,7 +174,7 @@ return [
'saml_idp_metadata_help' => 'You can specify the IdP metadata using a URL or XML file.',
'saml_attr_mapping_username' => 'Attribute Mapping - Username',
'saml_attr_mapping_username_help' => 'NameID will be used if attribute mapping is unspecified or invalid.',
'saml_forcelogin_label' => 'SAML Force Login',
'saml_forcelogin_label' => 'SAML Default Login',
'saml_forcelogin' => 'Make SAML the primary login',
'saml_forcelogin_help' => 'You can use \'/login?nosaml\' to get to the normal login page.',
'saml_slo_label' => 'SAML Single Log Out',

View file

@ -35,6 +35,8 @@
</div>
@endif
@include ('partials.forms.edit.notes')
@include ('partials.forms.edit.image-upload')
@stop

View file

@ -112,7 +112,7 @@
@endif
@if ($accessory->category)
@if ($accessory->category)
<div class="row">
<div class="col-md-4" style="padding-bottom: 15px;">
{{ trans('general.category')}}
@ -122,6 +122,20 @@
</div>
</div>
@endif
@if ($accessory->notes)
<div class="col-md-12">
<strong>
{{ trans('general.notes') }}
</strong>
</div>
<div class="col-md-12">
{!! nl2br(e($accessory->notes)) !!}
</div>
</div>
@endif
<div class="row">

View file

@ -33,6 +33,8 @@
</div>
@endif
@include ('partials.forms.edit.notes')
@include ('partials.forms.edit.image-upload')
@stop

View file

@ -136,6 +136,20 @@
<div class="col-md-12" style="padding-bottom: 5px;"><strong>{{ trans('general.order_number') }}:</strong>
{{ $component->order_number }} </div>
@endif
@if ($component->notes)
<div class="col-md-12">
<strong>
{{ trans('general.notes') }}
</strong>
</div>
<div class="col-md-12">
{!! nl2br(e($component->notes)) !!}
</div>
</div>
@endif
</div>
</div> <!-- .row-->

View file

@ -33,5 +33,7 @@
</div>
@endif
@include ('partials.forms.edit.notes')
@include ('partials.forms.edit.image-upload')
@stop

View file

@ -125,17 +125,24 @@
</div>
@endif
@can('checkout', \App\Models\Accessory::class)
<div class="col-md-12 text-center">
@can('checkout', \App\Models\Consumable::class)
<div class="col-md-12">
<a href="{{ route('checkout/consumable', $consumable->id) }}" style="padding-bottom:5px;" class="btn btn-primary btn-sm" {{ (($consumable->numRemaining() > 0 ) ? '' : ' disabled') }}>{{ trans('general.checkout') }}</a>
</div>
@endcan
@if ($consumable->notes)
<div class="col-md-12">
<strong>
{{ trans('general.notes') }}
</strong>
</div>
<div class="col-md-12">
{!! nl2br(e($consumable->notes)) !!}
</div>
</div>
</div>
@endif
</div>