Compare commits

..

28 Commits

Author SHA1 Message Date
snipe
141b0b410b Change variable name to be clearer 2019-07-23 18:23:51 -07:00
snipe
d40f06373e DIsable CORS allowed origins by default to replicate existing behavior 2019-07-23 18:23:39 -07:00
snipe
56753fa4cd More clarification 2019-07-23 18:07:45 -07:00
snipe
8a7bafb575 Clarified header comments 2019-07-23 18:05:07 -07:00
snipe
82f91cb944 Fixed typo 2019-07-23 18:03:53 -07:00
snipe
41b226e5fc Added APP_CORS_ALLOWED_ORIGINS env option 2019-07-23 18:02:51 -07:00
snipe
ae6048a6ea Changed order so CORS will still work if throttle hit 2019-07-23 18:02:27 -07:00
snipe
ef41e0060a Added CORS support to API 2019-07-23 17:17:01 -07:00
snipe
a0f3fc6d76 Bumped hash 2019-07-18 14:37:54 -07:00
snipe
74e647fea7 Apply fix from PR #7273 to master 2019-07-18 14:37:48 -07:00
snipe
55ee90b25d Fixes #7252 form request changes (#7272)
* Fixes for #7252 - custom fields not validating / no validaton messages in API w/form requests

* Removed debug info

* More fixes for #7252

This is mostly working as intended, if not yet the way Laravel wants us to do it.

Right now, the API returns correctly, and the form UI will return highlighted errors, with the input filled in ~sometimes~. I’m not sure why it’s only sometimes yet, but this is potentially progress.

* Removed experimental method

* Check for digits_between:0,240 for warranty

* Removed debug code
2019-07-18 14:32:23 -07:00
snipe
eec445fcf5 Command to fix custom field unicode conversion differences between PHP versions (#7263) 2019-07-18 14:30:18 -07:00
snipe
cef22c3158 Caps asset warranty to 20 years 2019-07-18 09:49:58 -07:00
snipe
61fb38087e Bumped hash 2019-07-17 17:55:53 -07:00
snipe
0e93495ca2 Check that the user has assets and that the aset model is valid 2019-07-17 17:51:35 -07:00
snipe
444e250609 Fixed countable() strings on user destroy 2019-07-17 17:51:13 -07:00
snipe
77a6f6f400 Cap warranty months to 3 on the frontend blade 2019-07-17 12:15:15 -07:00
snipe
15bfd07f30 Cap warranty months to three characters
Filles rollbar 209
2019-07-17 12:13:15 -07:00
snipe
fecf8015a1 Added space between footer and custom message 2019-07-17 12:09:32 -07:00
snipe
79ab0d8dc2 Check for valid seat on hardware view 2019-07-17 12:09:18 -07:00
snipe
b4b6d6b571 Comment clarification on #7186 2019-07-15 15:31:09 -07:00
snipe
8c73a47afb Fixed #7186 - has vs filled in User’s API blanking out groups if no group_ids are passed 2019-07-15 15:27:02 -07:00
snipe
f82ffe378c Merge branch 'master' of https://github.com/snipe/snipe-it 2019-07-15 14:11:18 -07:00
snipe
984c2a8fd4 Better log message for bad LDAP connection 2019-07-15 14:10:57 -07:00
snipe
6736b1c4e7 Addresses #7238 - add PWA code to layout
Needs additional UX testing
2019-07-15 13:49:56 -07:00
Ivan Nieto
d409be6d43 Fix #6910: Add logic to manipulate the eloquent query. (#7006)
* Added company_id to consumables_users table

* Added logic to manage when a pivot table doesn't have the column company_id trough a join with users

* Remove a migration that tries to fix this problem, but is not longer necessary
2019-07-15 13:02:44 -07:00
Thomas Misilo
e1b33f3087 Spelling Correction (#7206)
Fixed Spelling for the word reqrite, to be rewrite.
2019-06-27 18:33:13 -07:00
snipe
740d5a6846 Downgrading rollbar for Laravel 5.5 2019-06-25 18:07:21 -07:00
22 changed files with 400 additions and 77 deletions

View File

@@ -66,6 +66,7 @@ SECURE_COOKIES=false
# --------------------------------------------
REFERRER_POLICY=same-origin
ENABLE_CSP=false
CORS_ALLOWED_ORIGINS=null
# --------------------------------------------
# OPTIONAL: CACHE SETTINGS

View File

@@ -33,7 +33,7 @@ class Purge extends Command
*
* @var string
*/
protected $description = 'Purge all soft-deleted deleted records in the database. This will rewrite history for items that have been edited, or checked in or out. It will also reqrite history for users associated with deleted items.';
protected $description = 'Purge all soft-deleted deleted records in the database. This will rewrite history for items that have been edited, or checked in or out. It will also rewrite history for users associated with deleted items.';
/**
* Create a new command instance.

View File

@@ -0,0 +1,126 @@
<?php
namespace App\Console\Commands;
use App\Models\CustomField;
use Illuminate\Console\Command;
class ReEncodeCustomFieldNames extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'snipeit:regenerate-fieldnames';
/**
* The console command description.
*
* @var string
*/
protected $description = 'This utility will regenerate the column names for custom fields. It should typically only be needed when a PHP upgrade changed the behavior of the unicode conversion between versions.';
/**
* Create a new command instance.
*
* @return void
*/
public function __construct()
{
parent::__construct();
}
/**
* All three of these things must match for the custom fields system to work as expected:
*
* - what the system thinks the output of $field->convertUnicodeDbSlug() is
* - the actual db_column name in the customfields table
* - the physical column name that was created on the assets table
*
* For some people who upgraded their version of PHP, the unicode converter now behaves
* differently in than it did when their custom fields were first created, specifically as it
* relates to handling slashes, ampersands, etc. This can result in the field names no longer
* matching up, as an older version of the PHP extension simply dropped slashes, etc, while the
* newer version of the PHP extension will convert them to underscores.
*
* @return mixed
*/
public function handle()
{
if ($this->confirm('This will regenerate all of the custom field database fieldnames in your database. THIS WILL CHANGE YOUR SCHEMA AND SHOULD NOT BE DONE WITHOUT MAKING A BACKUP FIRST. Do you wish to continue?'))
{
/** Get all of the custom fields */
$fields = CustomField::get();
$asset_columns = \DB::getSchemaBuilder()->getColumnListing('assets');
$custom_field_columns = array();
/** Loop through the columns on the assets table */
foreach ($asset_columns as $asset_column) {
/** Add ones that start with _snipeit_ to an array for handling */
if (strpos($asset_column, '_snipeit_') === 0) {
/**
* Get the ID of the custom field based on the fieldname.
* For example, in _snipeit_mac_address_1, we grab the 1 because we know
* that's the ID of the custom field that created the column.
* Then use that ID as the array key for use comparing the actual assets field name
* and the db_column value from the custom fields table.
*/
$last_part = substr(strrchr($asset_column, "_snipeit_"), 1);
$custom_field_columns[$last_part] = $asset_column;
}
}
foreach ($fields as $field) {
$this->info($field->name .' ('.$field->id.') column should be '. $field->convertUnicodeDbSlug().'');
/** The assets table has the column it should have, all is well */
if (\Schema::hasColumn('assets', $field->convertUnicodeDbSlug()))
{
$this->info('-- ✓ This field exists - all good');
/**
* There is a mismatch between the fieldname on the assets table and
* what $field->convertUnicodeDbSlug() is *now* expecting.
*/
} else {
$this->warn('-- X Field mismatch: updating... ');
/** Make sure the custom_field_columns array has the ID */
if (array_key_exists($field->id, $custom_field_columns)) {
/**
* Update the asset schema to the corrected fieldname that will be recognized by the
* system elsewhere that we use $field->convertUnicodeDbSlug()
*/
\Schema::table('assets', function($table) use ($custom_field_columns, $field) {
$table->renameColumn($custom_field_columns[$field->id], $field->convertUnicodeDbSlug());
});
$this->warn('-- ✓ Field updated from '.$custom_field_columns[$field->id].' to '.$field->convertUnicodeDbSlug());
} else {
$this->warn('-- X WARNING: There is no field on the assets table ending in '.$field->id.'. This may require more in-depth investigation and may mean the schema was altered manually.');
}
}
/** Update the db_column property in the custom fields table, just in case it doesn't match the other
* things.
*/
$field->db_column = $field->convertUnicodeDbSlug();
$field->save();
}
}
}
}

View File

@@ -2,6 +2,7 @@
namespace App\Console;
use App\Console\Commands\ImportLocations;
use App\Console\Commands\RestoreDeletedUsers;
use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
@@ -34,6 +35,7 @@ class Kernel extends ConsoleKernel
Commands\RestoreDeletedUsers::class,
Commands\SendUpcomingAuditReport::class,
Commands\ImportLocations::class,
Commands\ReEncodeCustomFieldNames::class,
];
/**

View File

@@ -67,10 +67,6 @@ class Handler extends ExceptionHandler
return response()->json(Helper::formatStandardApiResponse('error', null, $className . ' not found'), 200);
}
if ($e instanceof \Illuminate\Validation\ValidationException) {
return response()->json(Helper::formatStandardApiResponse('error', null, $e->response['messages'], 400));
}
if ($this->isHttpException($e)) {
$statusCode = $e->getStatusCode();
@@ -85,11 +81,6 @@ class Handler extends ExceptionHandler
}
}
// 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);
}
}
@@ -128,6 +119,6 @@ class Handler extends ExceptionHandler
*/
protected function invalidJson($request, ValidationException $exception)
{
return response()->json($exception->errors(), $exception->status);
return response()->json(Helper::formatStandardApiResponse('error', null, $exception->errors(), 400));
}
}

View File

@@ -165,7 +165,7 @@ class ConsumablesController extends Controller
{
$consumable = Consumable::with(array('consumableAssignments'=>
function ($query) {
$query->orderBy('created_at', 'DESC');
$query->orderBy($query->getModel()->getTable().'.created_at', 'DESC');
},
'consumableAssignments.admin'=> function ($query) {
},

View File

@@ -38,7 +38,7 @@ class SettingsController extends Controller
//return response()->json(['message' => $e->getMessage()], 500);
}
} catch (\Exception $e) {
\Log::debug('Connection failed');
\Log::debug('Connection failed but we cannot debug it any further on our end.');
return response()->json(['message' => $e->getMessage()], 600);
}

View File

@@ -260,12 +260,21 @@ class UsersController extends Controller
if ($user->save()) {
// Sync group memberships:
// This was changed in Snipe-IT v4.6.x to 4.7, since we upgraded to Laravel 5.5
// which changes the behavior of has vs filled.
// The $request->has method will now return true even if the input value is an empty string or null.
// A new $request->filled method has was added that provides the previous behavior of the has method.
// Check if the request has groups passed and has a value
if ($request->filled('groups')) {
$user->groups()->sync($request->input('groups'));
} else {
// The groups field has been passed but it is null, so we should blank it out
} elseif ($request->has('groups')) {
$user->groups()->sync(array());
}
return response()->json(Helper::formatStandardApiResponse('success', (new UsersTransformer)->transformUser($user), trans('admin/users/message.success.update')));
}
@@ -287,10 +296,23 @@ class UsersController extends Controller
$this->authorize('delete', $user);
if ($user->assets()->count() > 0) {
if (($user->assets) && ($user->assets->count() > 0)) {
return response()->json(Helper::formatStandardApiResponse('error', null, trans('admin/users/message.error.delete_has_assets')));
}
if (($user->licenses) && ($user->licenses->count() > 0)) {
return response()->json(Helper::formatStandardApiResponse('error', null, 'This user still has ' . $user->licenses->count() . ' license(s) associated with them and cannot be deleted.'));
}
if (($user->accessories) && ($user->accessories->count() > 0)) {
return response()->json(Helper::formatStandardApiResponse('error', null, 'This user still has ' . $user->accessories->count() . ' accessories associated with them.'));
}
if (($user->managedLocations()) && ($user->managedLocations()->count() > 0)) {
return response()->json(Helper::formatStandardApiResponse('error', null, 'This user still has ' . $user->managedLocations()->count() . ' locations that they manage.'));
}
if ($user->delete()) {
return response()->json(Helper::formatStandardApiResponse('success', null, trans('admin/users/message.success.delete')));
}

View File

@@ -340,25 +340,25 @@ class UsersController extends Controller
// Check if we are not trying to delete ourselves
if ($user->id === Auth::user()->id) {
// Redirect to the user management page
return redirect()->route('users.index')->with('error', 'This user still has ' . $user->assets()->count() . ' assets associated with them.');
return redirect()->route('users.index')->with('error', 'You cannot delete yourself.');
}
if ($user->assets->count() > 0) {
if (($user->assets) && ($user->assets->count() > 0)) {
// Redirect to the user management page
return redirect()->route('users.index')->with('error', 'This user still has ' . count($user->assets->count()) . ' assets associated with them.');
return redirect()->route('users.index')->with('error', 'This user still has ' . $user->assets->count() . ' assets associated with them. Use the Checkin and Delete button on the user profile to check these items back in and delete this user.');
}
if ($user->licenses()->count() > 0) {
if (($user->licenses) && ($user->licenses->count() > 0)) {
// Redirect to the user management page
return redirect()->route('users.index')->with('error', 'This user still has ' . $user->assets()->count() . ' assets associated with them.');
return redirect()->route('users.index')->with('error', 'This user still has ' . $user->licenses->count() . ' license(s associated with them. Use the Checkin and Delete button on the user profile to check these items back in and delete this user.');
}
if ($user->accessories()->count() > 0) {
if (($user->accessories) && ($user->accessories->count() > 0)) {
// Redirect to the user management page
return redirect()->route('users.index')->with('error', 'This user still has ' . $user->accessories()->count() . ' accessories associated with them.');
return redirect()->route('users.index')->with('error', 'This user still has ' . $user->accessories->count() . ' accessories associated with them. Use the Checkin and Delete button on the user profile to check these items back in and delete this user.');
}
if ($user->managedLocations()->count() > 0) {
if (($user->managedLocations()) && ($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.');
}

View File

@@ -44,6 +44,7 @@ class Kernel extends HttpKernel
],
'api' => [
\Barryvdh\Cors\HandleCors::class,
'throttle:120,1',
'auth:api',
],

View File

@@ -4,7 +4,7 @@ namespace App\Http\Requests;
use App\Models\AssetModel;
use Session;
use Illuminate\Http\Exceptions\HttpResponseException;
use Illuminate\Contracts\Validation\Validator;
@@ -32,7 +32,7 @@ class AssetRequest extends Request
'model_id' => 'required|integer|exists:models,id',
'status_id' => 'required|integer|exists:status_labels,id',
'company_id' => 'integer|nullable',
'warranty_months' => 'numeric|nullable',
'warranty_months' => 'numeric|nullable|digits_between:0,240',
'physical' => 'integer|nullable',
'checkout_date' => 'date',
'checkin_date' => 'date',
@@ -48,7 +48,7 @@ class AssetRequest extends Request
$rules['asset_tag'] = ($settings->auto_increment_assets == '1') ? 'max:255' : 'required';
if($this->request->get('model_id') != '') {
if ($this->request->get('model_id') != '') {
$model = AssetModel::find($this->request->get('model_id'));
if (($model) && ($model->fieldset)) {
@@ -60,13 +60,6 @@ class AssetRequest extends Request
}
public function response(array $errors)
{
$this->session()->flash('errors', Session::get('errors', new \Illuminate\Support\ViewErrorBag)
->put('default', new \Illuminate\Support\MessageBag($errors)));
\Input::flash();
return parent::response($errors);
}
/**
* Handle a failed validation attempt.
@@ -76,13 +69,17 @@ class AssetRequest extends Request
* @param \Illuminate\Contracts\Validation\Validator $validator
* @return void
*
* @throws \Illuminate\Validation\ValidationException
* @throws \Illuminate\Http\Exceptions\HttpResponseException
*/
protected function failedValidation(Validator $validator)
{
return response()->json([
'message' => 'The given data is invalid',
'errors' => $validator->errors()
], 422);
$this->session()->flash('errors', Session::get('errors', new \Illuminate\Support\ViewErrorBag)
->put('default', new \Illuminate\Support\MessageBag($validator->errors()->toArray())));
\Input::flash();
throw new HttpResponseException(response()->json([
'status' => 'error',
'messages' => $validator->errors(),
'payload' => null
], 422));
}
}

View File

@@ -2,10 +2,12 @@
namespace App\Http\Requests;
use App\Http\Requests\Request;
use App\Models\Setting;
use Illuminate\Http\Exceptions\HttpResponseException;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Contracts\Validation\Validator;
class SaveUserRequest extends Request
class SaveUserRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
@@ -62,4 +64,5 @@ class SaveUserRequest extends Request
return $rules;
}
}

View File

@@ -75,7 +75,7 @@ class Asset extends Depreciable
'model_id' => 'required|integer|exists:models,id',
'status_id' => 'required|integer|exists:status_labels,id',
'company_id' => 'integer|nullable',
'warranty_months' => 'numeric|nullable',
'warranty_months' => 'numeric|nullable|digits_between:0,240',
'physical' => 'numeric|max:1|nullable',
'checkout_date' => 'date|max:10|min:10|nullable',
'checkin_date' => 'date|max:10|min:10|nullable',
@@ -866,8 +866,10 @@ class Asset extends Depreciable
public function scopeDueOrOverdueForAudit($query, $settings)
{
$interval = $settings->audit_warning_days ?? 0;
return $query->whereNotNull('assets.next_audit_date')
->whereRaw("DATE_SUB(assets.next_audit_date, INTERVAL $settings->audit_warning_days DAY) <= '".Carbon::now()."'")
->whereRaw("DATE_SUB(assets.next_audit_date, INTERVAL $interval DAY) <= '".Carbon::now()."'")
->where('assets.archived', '=', 0)
->NotArchived();
}

View File

@@ -80,7 +80,13 @@ final class Company extends SnipeModel
}
$table = ($table_name) ? DB::getTablePrefix().$table_name."." : '';
return $query->where($table.$column, '=', $company_id);
if(\Schema::hasColumn($query->getModel()->getTable(), $column)){
return $query->where($table.$column, '=', $company_id);
} else {
return $query->join('users as users_comp', 'users_comp.id', 'user_id')->where('users_comp.company_id', '=', $company_id);
}
}
public static function getIdFromInput($unescaped_input)

View File

@@ -6,6 +6,7 @@
"type": "project",
"require": {
"php": ">=7.1.2",
"barryvdh/laravel-cors": "^0.11.3",
"barryvdh/laravel-debugbar": "^3.2",
"doctrine/cache": "^1.8",
"doctrine/common": "^2.10",
@@ -31,7 +32,7 @@
"pragmarx/google2fa": "^5.0",
"pragmarx/google2fa-laravel": "^1.0",
"predis/predis": "^1.1",
"rollbar/rollbar-laravel": "^4.0",
"rollbar/rollbar-laravel": "2.*",
"schuppo/password-strength": "~1.5",
"spatie/laravel-backup": "^5.12",
"tecnickcom/tc-lib-barcode": "^1.15",

138
composer.lock generated
View File

@@ -4,8 +4,60 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
"This file is @generated automatically"
],
"content-hash": "3a44e6e940451424e4b9fa7068e604c5",
"content-hash": "83584cbcfed9d4b063847283c0472606",
"packages": [
{
"name": "asm89/stack-cors",
"version": "1.2.0",
"source": {
"type": "git",
"url": "https://github.com/asm89/stack-cors.git",
"reference": "c163e2b614550aedcf71165db2473d936abbced6"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/asm89/stack-cors/zipball/c163e2b614550aedcf71165db2473d936abbced6",
"reference": "c163e2b614550aedcf71165db2473d936abbced6",
"shasum": ""
},
"require": {
"php": ">=5.5.9",
"symfony/http-foundation": "~2.7|~3.0|~4.0",
"symfony/http-kernel": "~2.7|~3.0|~4.0"
},
"require-dev": {
"phpunit/phpunit": "^5.0 || ^4.8.10",
"squizlabs/php_codesniffer": "^2.3"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.2-dev"
}
},
"autoload": {
"psr-4": {
"Asm89\\Stack\\": "src/Asm89/Stack/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Alexander",
"email": "iam.asm89@gmail.com"
}
],
"description": "Cross-origin resource sharing library and stack middleware",
"homepage": "https://github.com/asm89/stack-cors",
"keywords": [
"cors",
"stack"
],
"time": "2017-12-20T14:37:45+00:00"
},
{
"name": "bacon/bacon-qr-code",
"version": "2.0.0",
@@ -55,6 +107,68 @@
"homepage": "https://github.com/Bacon/BaconQrCode",
"time": "2018-04-25T17:53:56+00:00"
},
{
"name": "barryvdh/laravel-cors",
"version": "v0.11.3",
"source": {
"type": "git",
"url": "https://github.com/barryvdh/laravel-cors.git",
"reference": "c95ac944f2f20a17949aae6645692dfd3b402bca"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/barryvdh/laravel-cors/zipball/c95ac944f2f20a17949aae6645692dfd3b402bca",
"reference": "c95ac944f2f20a17949aae6645692dfd3b402bca",
"shasum": ""
},
"require": {
"asm89/stack-cors": "^1.2",
"illuminate/support": "5.5.x|5.6.x|5.7.x|5.8.x",
"php": ">=7",
"symfony/http-foundation": "^3.1|^4",
"symfony/http-kernel": "^3.1|^4"
},
"require-dev": {
"laravel/framework": "^5.5",
"orchestra/testbench": "3.3.x|3.4.x|3.5.x|3.6.x|3.7.x",
"phpunit/phpunit": "^4.8|^5.2|^7.0",
"squizlabs/php_codesniffer": "^2.3"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "0.11-dev"
},
"laravel": {
"providers": [
"Barryvdh\\Cors\\ServiceProvider"
]
}
},
"autoload": {
"psr-4": {
"Barryvdh\\Cors\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Barry vd. Heuvel",
"email": "barryvdh@gmail.com"
}
],
"description": "Adds CORS (Cross-Origin Resource Sharing) headers support in your Laravel application",
"keywords": [
"api",
"cors",
"crossdomain",
"laravel"
],
"time": "2019-02-26T18:08:30+00:00"
},
{
"name": "barryvdh/laravel-debugbar",
"version": "v3.2.3",
@@ -3864,29 +3978,29 @@
},
{
"name": "rollbar/rollbar-laravel",
"version": "v4.0.3",
"version": "v2.4.3",
"source": {
"type": "git",
"url": "https://github.com/rollbar/rollbar-php-laravel.git",
"reference": "e4ea0343e32748123ee7d7da8c6bf98593c5f74c"
"reference": "e581cd9a175d0b3fa0568893026e38c1d94329b2"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/rollbar/rollbar-php-laravel/zipball/e4ea0343e32748123ee7d7da8c6bf98593c5f74c",
"reference": "e4ea0343e32748123ee7d7da8c6bf98593c5f74c",
"url": "https://api.github.com/repos/rollbar/rollbar-php-laravel/zipball/e581cd9a175d0b3fa0568893026e38c1d94329b2",
"reference": "e581cd9a175d0b3fa0568893026e38c1d94329b2",
"shasum": ""
},
"require": {
"illuminate/support": "^5.0",
"php": ">=7.0",
"illuminate/support": "^4.0|^5.0",
"php": ">=5.4",
"rollbar/rollbar": "^1"
},
"require-dev": {
"mockery/mockery": "^1",
"orchestra/testbench": "~3.6",
"phpunit/phpunit": "~7.0",
"mockery/mockery": "^0.9",
"orchestra/testbench": "~3.0",
"phpunit/phpunit": "~4.0|~5.0",
"satooshi/php-coveralls": "^1.0",
"squizlabs/php_codesniffer": "3.*"
"squizlabs/php_codesniffer": "2.*"
},
"type": "library",
"extra": {
@@ -3928,7 +4042,7 @@
"monitoring",
"rollbar"
],
"time": "2019-01-01T18:39:35+00:00"
"time": "2019-01-01T22:20:05+00:00"
},
{
"name": "schuppo/password-strength",

48
config/cors.php Normal file
View File

@@ -0,0 +1,48 @@
<?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 [
/*
|--------------------------------------------------------------------------
| Laravel CORS
|--------------------------------------------------------------------------
|
| allowedOrigins, allowedHeaders and allowedMethods can be set to array('*')
| to accept any value.
|
*/
'supportsCredentials' => false,
'allowedOrigins' => $allowed_origins,
'allowedOriginsPatterns' => [],
'allowedHeaders' => ['*'],
'allowedMethods' => ['GET', 'POST', 'PUT', 'PATCH', 'DELETE'],
'exposedHeaders' => [],
'maxAge' => 0,
];

View File

@@ -1,10 +1,10 @@
<?php
return array (
'app_version' => 'v4.7.5',
'full_app_version' => 'v4.7.5 - build 4118-g03a451240',
'build_version' => '4118',
'full_app_version' => 'v4.7.5 - build 4137-g55ee90b25',
'build_version' => '4137',
'prerelease_version' => '',
'hash_version' => 'g03a451240',
'full_hash' => 'v4.7.5-10-g03a451240',
'hash_version' => 'g55ee90b25',
'full_hash' => 'v4.7.5-18-g55ee90b25',
'branch' => 'master',
);

View File

@@ -569,19 +569,21 @@
</thead>
<tbody>
@foreach ($asset->licenseseats as $seat)
<tr>
<td><a href="{{ route('licenses.show', $seat->license->id) }}">{{ $seat->license->name }}</a></td>
<td>
@can('viewKeys', $seat->license)
{!! nl2br(e($seat->license->serial)) !!}
@else
------------
@endcan
</td>
<td>
<a href="{{ route('licenses.checkin', $seat->id) }}" class="btn btn-sm bg-purple" data-tooltip="true">{{ trans('general.checkin') }}</a>
</td>
</tr>
@if ($seat->license)
<tr>
<td><a href="{{ route('licenses.show', $seat->license->id) }}">{{ $seat->license->name }}</a></td>
<td>
@can('viewKeys', $seat->license)
{!! nl2br(e($seat->license->serial)) !!}
@else
------------
@endcan
</td>
<td>
<a href="{{ route('licenses.checkin', $seat->id) }}" class="btn btn-sm bg-purple" data-tooltip="true">{{ trans('general.checkin') }}</a>
</td>
</tr>
@endif
@endforeach
</tbody>
</table>

View File

@@ -11,6 +11,11 @@
<!-- Tell the browser to be responsive to screen width -->
<meta content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" name="viewport">
<meta name="apple-mobile-web-app-capable" content="yes">
<link rel="apple-touch-icon" href="{{ url('/') }}/uploads/{{ $snipeSettings->logo }}">
<link rel="apple-touch-startup-image" href="{{ url('/') }}/uploads/{{ $snipeSettings->logo }}">
<!-- Select2 -->
<link rel="stylesheet" href="{{ url(asset('js/plugins/select2/select2.min.css')) }}">
@@ -761,7 +766,7 @@
<div class="pull-right hidden-xs">
@if ($snipeSettings->version_footer!='off')
@if (($snipeSettings->version_footer=='on') || (($snipeSettings->version_footer=='admin') && (Auth::user()->isSuperUser()=='1')))
<b>Version</b> {{ config('version.app_version') }} - build {{ config('version.build_version') }} ({{ config('version.branch') }})
&nbsp; <b>Version</b> {{ config('version.app_version') }} - build {{ config('version.build_version') }} ({{ config('version.branch') }})
@endif
@endif

View File

@@ -3,11 +3,11 @@
<label for="warranty_months" class="col-md-3 control-label">{{ trans('admin/hardware/form.warranty') }}</label>
<div class="col-md-9">
<div class="input-group col-md-3" style="padding-left: 0px;">
<input class="form-control" type="text" name="warranty_months" id="warranty_months" value="{{ Input::old('warranty_months', $item->warranty_months) }}" />
<input class="form-control" type="text" name="warranty_months" id="warranty_months" value="{{ Input::old('warranty_months', $item->warranty_months) }}" maxlength="3" />
<span class="input-group-addon">{{ trans('admin/hardware/form.months') }}</span>
</div>
<div class="col-md-9" style="padding-left: 0px;">
{!! $errors->first('warranty_months', '<span class="alert-msg"><i class="fa fa-times"></i> :message</span>') !!}
</div>
</div>
</div>
</div>

View File

@@ -340,10 +340,11 @@
</tr>
</thead>
<tbody>
@if ($user->assets)
@foreach ($user->assets as $asset)
<tr>
<td>
@if ($asset->physical=='1')
@if (($asset->model) && ($asset->physical=='1'))
<a href="{{ route('models.show', $asset->model->id) }}">{{ $asset->model->name }}</a>
@endif
</td>
@@ -360,6 +361,7 @@
</td>
</tr>
@endforeach
@endif
</tbody>
</table>
</div>