mirror of
https://github.com/snipe/snipe-it.git
synced 2025-03-05 20:52:15 -08:00
Merge remote-tracking branch 'origin/develop'
Signed-off-by: snipe <snipe@snipe.net> # Conflicts: # config/version.php # public/css/dist/skins/skin-black-dark.css # public/css/dist/skins/skin-black-dark.min.css # public/css/dist/skins/skin-blue-dark.css # public/css/dist/skins/skin-blue-dark.min.css # public/css/dist/skins/skin-green-dark.css # public/css/dist/skins/skin-green-dark.min.css # public/css/dist/skins/skin-orange-dark.css # public/css/dist/skins/skin-orange-dark.min.css # public/css/dist/skins/skin-purple-dark.css # public/css/dist/skins/skin-purple-dark.min.css # public/css/dist/skins/skin-red-dark.css # public/css/dist/skins/skin-red-dark.min.css # public/css/dist/skins/skin-yellow-dark.css # public/css/dist/skins/skin-yellow-dark.min.css # public/mix-manifest.json
This commit is contained in:
commit
56cb9a0f4e
|
@ -665,27 +665,28 @@ class AssetsController extends Controller
|
||||||
$model = AssetModel::find($asset->model_id);
|
$model = AssetModel::find($asset->model_id);
|
||||||
|
|
||||||
// Update custom fields
|
// Update custom fields
|
||||||
|
$problems_updating_encrypted_custom_fields = false;
|
||||||
if (($model) && (isset($model->fieldset))) {
|
if (($model) && (isset($model->fieldset))) {
|
||||||
foreach ($model->fieldset->fields as $field) {
|
foreach ($model->fieldset->fields as $field) {
|
||||||
$field_val = $request->input($field->db_column, null);
|
$field_val = $request->input($field->db_column, null);
|
||||||
|
|
||||||
if ($request->has($field->db_column)) {
|
if ($request->has($field->db_column)) {
|
||||||
if ($field->field_encrypted == '1') {
|
|
||||||
if (Gate::allows('admin')) {
|
|
||||||
$asset->{$field->db_column} = Crypt::encrypt($field_val);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ($field->element == 'checkbox') {
|
if ($field->element == 'checkbox') {
|
||||||
if(is_array($field_val)) {
|
if(is_array($field_val)) {
|
||||||
$field_val = implode(',', $field_val);
|
$field_val = implode(',', $field_val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ($field->field_encrypted == '1') {
|
||||||
|
if (Gate::allows('admin')) {
|
||||||
|
$field_val = Crypt::encrypt($field_val);
|
||||||
|
} else {
|
||||||
|
$problems_updating_encrypted_custom_fields = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
$asset->{$field->db_column} = $field_val;
|
$asset->{$field->db_column} = $field_val;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
$asset->{$field->db_column} = $field_val;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -709,8 +710,11 @@ class AssetsController extends Controller
|
||||||
$asset->image = $asset->getImageUrl();
|
$asset->image = $asset->getImageUrl();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($problems_updating_encrypted_custom_fields) {
|
||||||
|
return response()->json(Helper::formatStandardApiResponse('success', $asset, trans('admin/hardware/message.update.encrypted_warning')));
|
||||||
|
} else {
|
||||||
return response()->json(Helper::formatStandardApiResponse('success', $asset, trans('admin/hardware/message.update.success')));
|
return response()->json(Helper::formatStandardApiResponse('success', $asset, trans('admin/hardware/message.update.success')));
|
||||||
return response()->json(Helper::formatStandardApiResponse('success', (new AssetsTransformer)->transformAsset($asset), trans('admin/hardware/message.update.success')));
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return response()->json(Helper::formatStandardApiResponse('error', null, $asset->getErrors()), 200);
|
return response()->json(Helper::formatStandardApiResponse('error', null, $asset->getErrors()), 200);
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
<?php
|
<?php
|
||||||
return array (
|
return array (
|
||||||
'app_version' => 'v6.3.4',
|
'app_version' => 'v6.3.4',
|
||||||
'full_app_version' => 'v6.3.4 - build 13139-g6f9ba6ede',
|
'full_app_version' => 'v6.3.4 - build 13226-g5229dd65c',
|
||||||
'build_version' => '13139',
|
'build_version' => '13226',
|
||||||
'prerelease_version' => '',
|
'prerelease_version' => '',
|
||||||
'hash_version' => 'g6f9ba6ede',
|
'hash_version' => 'g5229dd65c',
|
||||||
'full_hash' => 'v6.3.4-234-g6f9ba6ede',
|
'full_hash' => 'v6.3.4-85-g5229dd65c',
|
||||||
'branch' => 'master',
|
'branch' => 'master',
|
||||||
);
|
);
|
|
@ -4,6 +4,7 @@ namespace Database\Factories;
|
||||||
|
|
||||||
use App\Models\Asset;
|
use App\Models\Asset;
|
||||||
use App\Models\AssetModel;
|
use App\Models\AssetModel;
|
||||||
|
use App\Models\CustomField;
|
||||||
use App\Models\Location;
|
use App\Models\Location;
|
||||||
use App\Models\Statuslabel;
|
use App\Models\Statuslabel;
|
||||||
use App\Models\Supplier;
|
use App\Models\Supplier;
|
||||||
|
@ -353,6 +354,16 @@ class AssetFactory extends Factory
|
||||||
return $this->state(['requestable' => false]);
|
return $this->state(['requestable' => false]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function hasEncryptedCustomField(CustomField $field = null)
|
||||||
|
{
|
||||||
|
return $this->state(function () use ($field) {
|
||||||
|
return [
|
||||||
|
'model_id' => AssetModel::factory()->hasEncryptedCustomField($field),
|
||||||
|
];
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This allows bypassing model level validation if you want to purposefully
|
* This allows bypassing model level validation if you want to purposefully
|
||||||
* create an asset in an invalid state. Validation is turned back on
|
* create an asset in an invalid state. Validation is turned back on
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
namespace Database\Factories;
|
namespace Database\Factories;
|
||||||
|
|
||||||
use App\Models\AssetModel;
|
use App\Models\AssetModel;
|
||||||
|
use App\Models\CustomField;
|
||||||
use App\Models\CustomFieldset;
|
use App\Models\CustomFieldset;
|
||||||
use App\Models\Depreciation;
|
use App\Models\Depreciation;
|
||||||
use App\Models\Manufacturer;
|
use App\Models\Manufacturer;
|
||||||
|
@ -429,4 +430,13 @@ class AssetModelFactory extends Factory
|
||||||
];
|
];
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function hasEncryptedCustomField(CustomField $field = null)
|
||||||
|
{
|
||||||
|
return $this->state(function () use ($field) {
|
||||||
|
return [
|
||||||
|
'fieldset_id' => CustomFieldset::factory()->hasEncryptedCustomField($field),
|
||||||
|
];
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
namespace Database\Factories;
|
namespace Database\Factories;
|
||||||
|
|
||||||
use App\Models\CustomFieldset;
|
use App\Models\CustomFieldset;
|
||||||
|
use App\Models\CustomField;
|
||||||
use Illuminate\Database\Eloquent\Factories\Factory;
|
use Illuminate\Database\Eloquent\Factories\Factory;
|
||||||
|
|
||||||
class CustomFieldsetFactory extends Factory
|
class CustomFieldsetFactory extends Factory
|
||||||
|
@ -43,4 +44,13 @@ class CustomFieldsetFactory extends Factory
|
||||||
];
|
];
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function hasEncryptedCustomField(CustomField $field = null)
|
||||||
|
{
|
||||||
|
return $this->afterCreating(function (CustomFieldset $fieldset) use ($field) {
|
||||||
|
$field = $field ?? CustomField::factory()->testEncrypted()->create();
|
||||||
|
|
||||||
|
$fieldset->fields()->attach($field, ['order' => '1', 'required' => false]);
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
BIN
public/css/dist/skins/skin-black-dark.css
vendored
BIN
public/css/dist/skins/skin-black-dark.css
vendored
Binary file not shown.
BIN
public/css/dist/skins/skin-black-dark.min.css
vendored
BIN
public/css/dist/skins/skin-black-dark.min.css
vendored
Binary file not shown.
BIN
public/css/dist/skins/skin-blue-dark.css
vendored
BIN
public/css/dist/skins/skin-blue-dark.css
vendored
Binary file not shown.
BIN
public/css/dist/skins/skin-blue-dark.min.css
vendored
BIN
public/css/dist/skins/skin-blue-dark.min.css
vendored
Binary file not shown.
BIN
public/css/dist/skins/skin-green-dark.css
vendored
BIN
public/css/dist/skins/skin-green-dark.css
vendored
Binary file not shown.
BIN
public/css/dist/skins/skin-green-dark.min.css
vendored
BIN
public/css/dist/skins/skin-green-dark.min.css
vendored
Binary file not shown.
BIN
public/css/dist/skins/skin-orange-dark.css
vendored
BIN
public/css/dist/skins/skin-orange-dark.css
vendored
Binary file not shown.
BIN
public/css/dist/skins/skin-orange-dark.min.css
vendored
BIN
public/css/dist/skins/skin-orange-dark.min.css
vendored
Binary file not shown.
BIN
public/css/dist/skins/skin-purple-dark.css
vendored
BIN
public/css/dist/skins/skin-purple-dark.css
vendored
Binary file not shown.
BIN
public/css/dist/skins/skin-purple-dark.min.css
vendored
BIN
public/css/dist/skins/skin-purple-dark.min.css
vendored
Binary file not shown.
BIN
public/css/dist/skins/skin-red-dark.css
vendored
BIN
public/css/dist/skins/skin-red-dark.css
vendored
Binary file not shown.
BIN
public/css/dist/skins/skin-red-dark.min.css
vendored
BIN
public/css/dist/skins/skin-red-dark.min.css
vendored
Binary file not shown.
BIN
public/css/dist/skins/skin-yellow-dark.css
vendored
BIN
public/css/dist/skins/skin-yellow-dark.css
vendored
Binary file not shown.
BIN
public/css/dist/skins/skin-yellow-dark.min.css
vendored
BIN
public/css/dist/skins/skin-yellow-dark.min.css
vendored
Binary file not shown.
|
@ -5,16 +5,16 @@
|
||||||
"/css/build/app.css": "/css/build/app.css?id=4c2cb86bf76bcd58e9e362a356bc9182",
|
"/css/build/app.css": "/css/build/app.css?id=4c2cb86bf76bcd58e9e362a356bc9182",
|
||||||
"/css/build/AdminLTE.css": "/css/build/AdminLTE.css?id=f25c77ed07053646a42e9c19923d24fa",
|
"/css/build/AdminLTE.css": "/css/build/AdminLTE.css?id=f25c77ed07053646a42e9c19923d24fa",
|
||||||
"/css/dist/skins/skin-orange.css": "/css/dist/skins/skin-orange.css?id=268041e902b019730c23ee3875838005",
|
"/css/dist/skins/skin-orange.css": "/css/dist/skins/skin-orange.css?id=268041e902b019730c23ee3875838005",
|
||||||
"/css/dist/skins/skin-orange-dark.css": "/css/dist/skins/skin-orange-dark.css?id=9a474f38641582dc07bc004b44e2849e",
|
"/css/dist/skins/skin-orange-dark.css": "/css/dist/skins/skin-orange-dark.css?id=03075904b967308132b810bc0205ab1c",
|
||||||
"/css/dist/skins/skin-blue-dark.css": "/css/dist/skins/skin-blue-dark.css?id=9f4a71e8812af08857dad5879b4855c8",
|
"/css/dist/skins/skin-blue-dark.css": "/css/dist/skins/skin-blue-dark.css?id=47ab28abd019c2b1f9aae60a3d44824a",
|
||||||
"/css/dist/skins/skin-yellow-dark.css": "/css/dist/skins/skin-yellow-dark.css?id=c98bdc8f8d3560d732c4985f76cee8d5",
|
"/css/dist/skins/skin-yellow-dark.css": "/css/dist/skins/skin-yellow-dark.css?id=af8c7daf7e9a2c784eafb76f65c418f7",
|
||||||
"/css/dist/skins/skin-yellow.css": "/css/dist/skins/skin-yellow.css?id=fc7adb943668ac69fe4b646625a7571f",
|
"/css/dist/skins/skin-yellow.css": "/css/dist/skins/skin-yellow.css?id=fc7adb943668ac69fe4b646625a7571f",
|
||||||
"/css/dist/skins/skin-purple-dark.css": "/css/dist/skins/skin-purple-dark.css?id=ac9929237d506367832e8fee426ff396",
|
"/css/dist/skins/skin-purple-dark.css": "/css/dist/skins/skin-purple-dark.css?id=7fb8cf2421ad272b41393fdf5844559f",
|
||||||
"/css/dist/skins/skin-purple.css": "/css/dist/skins/skin-purple.css?id=cf6c8c340420724b02d6e787ef9bded5",
|
"/css/dist/skins/skin-purple.css": "/css/dist/skins/skin-purple.css?id=cf6c8c340420724b02d6e787ef9bded5",
|
||||||
"/css/dist/skins/skin-red-dark.css": "/css/dist/skins/skin-red-dark.css?id=6559832aaaa3a4c8ef7540daa24127f5",
|
"/css/dist/skins/skin-red-dark.css": "/css/dist/skins/skin-red-dark.css?id=122d3df19d2c0552d7ef388e69f7d71f",
|
||||||
"/css/dist/skins/skin-black-dark.css": "/css/dist/skins/skin-black-dark.css?id=5852d0e007f9907d196f7b04f945edb2",
|
"/css/dist/skins/skin-black-dark.css": "/css/dist/skins/skin-black-dark.css?id=5414c37b1403f41e051ad7b3aac112b4",
|
||||||
"/css/dist/skins/skin-black.css": "/css/dist/skins/skin-black.css?id=1f33ca3d860461c1127ec465ab3ebb6b",
|
"/css/dist/skins/skin-black.css": "/css/dist/skins/skin-black.css?id=1f33ca3d860461c1127ec465ab3ebb6b",
|
||||||
"/css/dist/skins/skin-green-dark.css": "/css/dist/skins/skin-green-dark.css?id=293aac2b6a8b56419c4ca3bfeffcbf0d",
|
"/css/dist/skins/skin-green-dark.css": "/css/dist/skins/skin-green-dark.css?id=bd61fefb56b30ed6d8c946f02bc956fb",
|
||||||
"/css/dist/skins/skin-green.css": "/css/dist/skins/skin-green.css?id=b48f4d8af0e1ca5621c161e93951109f",
|
"/css/dist/skins/skin-green.css": "/css/dist/skins/skin-green.css?id=b48f4d8af0e1ca5621c161e93951109f",
|
||||||
"/css/dist/skins/skin-contrast.css": "/css/dist/skins/skin-contrast.css?id=f0fbbb0ac729ea092578fb05ca615460",
|
"/css/dist/skins/skin-contrast.css": "/css/dist/skins/skin-contrast.css?id=f0fbbb0ac729ea092578fb05ca615460",
|
||||||
"/css/dist/skins/skin-red.css": "/css/dist/skins/skin-red.css?id=b9a74ec0cd68f83e7480d5ae39919beb",
|
"/css/dist/skins/skin-red.css": "/css/dist/skins/skin-red.css?id=b9a74ec0cd68f83e7480d5ae39919beb",
|
||||||
|
@ -35,18 +35,18 @@
|
||||||
"/js/dist/all.js": "/js/dist/all.js?id=fca6ea9956fd827d9790c08e0e982b22",
|
"/js/dist/all.js": "/js/dist/all.js?id=fca6ea9956fd827d9790c08e0e982b22",
|
||||||
"/js/dist/all-defer.js": "/js/dist/all-defer.js?id=19ccc62a8f1ea103dede4808837384d4",
|
"/js/dist/all-defer.js": "/js/dist/all-defer.js?id=19ccc62a8f1ea103dede4808837384d4",
|
||||||
"/css/dist/skins/skin-green.min.css": "/css/dist/skins/skin-green.min.css?id=b48f4d8af0e1ca5621c161e93951109f",
|
"/css/dist/skins/skin-green.min.css": "/css/dist/skins/skin-green.min.css?id=b48f4d8af0e1ca5621c161e93951109f",
|
||||||
"/css/dist/skins/skin-green-dark.min.css": "/css/dist/skins/skin-green-dark.min.css?id=293aac2b6a8b56419c4ca3bfeffcbf0d",
|
"/css/dist/skins/skin-green-dark.min.css": "/css/dist/skins/skin-green-dark.min.css?id=bd61fefb56b30ed6d8c946f02bc956fb",
|
||||||
"/css/dist/skins/skin-black.min.css": "/css/dist/skins/skin-black.min.css?id=1f33ca3d860461c1127ec465ab3ebb6b",
|
"/css/dist/skins/skin-black.min.css": "/css/dist/skins/skin-black.min.css?id=1f33ca3d860461c1127ec465ab3ebb6b",
|
||||||
"/css/dist/skins/skin-black-dark.min.css": "/css/dist/skins/skin-black-dark.min.css?id=5852d0e007f9907d196f7b04f945edb2",
|
"/css/dist/skins/skin-black-dark.min.css": "/css/dist/skins/skin-black-dark.min.css?id=5414c37b1403f41e051ad7b3aac112b4",
|
||||||
"/css/dist/skins/skin-blue.min.css": "/css/dist/skins/skin-blue.min.css?id=392cc93cfc0be0349bab9697669dd091",
|
"/css/dist/skins/skin-blue.min.css": "/css/dist/skins/skin-blue.min.css?id=392cc93cfc0be0349bab9697669dd091",
|
||||||
"/css/dist/skins/skin-blue-dark.min.css": "/css/dist/skins/skin-blue-dark.min.css?id=9f4a71e8812af08857dad5879b4855c8",
|
"/css/dist/skins/skin-blue-dark.min.css": "/css/dist/skins/skin-blue-dark.min.css?id=47ab28abd019c2b1f9aae60a3d44824a",
|
||||||
"/css/dist/skins/skin-yellow.min.css": "/css/dist/skins/skin-yellow.min.css?id=fc7adb943668ac69fe4b646625a7571f",
|
"/css/dist/skins/skin-yellow.min.css": "/css/dist/skins/skin-yellow.min.css?id=fc7adb943668ac69fe4b646625a7571f",
|
||||||
"/css/dist/skins/skin-yellow-dark.min.css": "/css/dist/skins/skin-yellow-dark.min.css?id=c98bdc8f8d3560d732c4985f76cee8d5",
|
"/css/dist/skins/skin-yellow-dark.min.css": "/css/dist/skins/skin-yellow-dark.min.css?id=af8c7daf7e9a2c784eafb76f65c418f7",
|
||||||
"/css/dist/skins/skin-red.min.css": "/css/dist/skins/skin-red.min.css?id=b9a74ec0cd68f83e7480d5ae39919beb",
|
"/css/dist/skins/skin-red.min.css": "/css/dist/skins/skin-red.min.css?id=b9a74ec0cd68f83e7480d5ae39919beb",
|
||||||
"/css/dist/skins/skin-red-dark.min.css": "/css/dist/skins/skin-red-dark.min.css?id=6559832aaaa3a4c8ef7540daa24127f5",
|
"/css/dist/skins/skin-red-dark.min.css": "/css/dist/skins/skin-red-dark.min.css?id=122d3df19d2c0552d7ef388e69f7d71f",
|
||||||
"/css/dist/skins/skin-purple.min.css": "/css/dist/skins/skin-purple.min.css?id=cf6c8c340420724b02d6e787ef9bded5",
|
"/css/dist/skins/skin-purple.min.css": "/css/dist/skins/skin-purple.min.css?id=cf6c8c340420724b02d6e787ef9bded5",
|
||||||
"/css/dist/skins/skin-purple-dark.min.css": "/css/dist/skins/skin-purple-dark.min.css?id=ac9929237d506367832e8fee426ff396",
|
"/css/dist/skins/skin-purple-dark.min.css": "/css/dist/skins/skin-purple-dark.min.css?id=7fb8cf2421ad272b41393fdf5844559f",
|
||||||
"/css/dist/skins/skin-orange.min.css": "/css/dist/skins/skin-orange.min.css?id=268041e902b019730c23ee3875838005",
|
"/css/dist/skins/skin-orange.min.css": "/css/dist/skins/skin-orange.min.css?id=268041e902b019730c23ee3875838005",
|
||||||
"/css/dist/skins/skin-orange-dark.min.css": "/css/dist/skins/skin-orange-dark.min.css?id=9a474f38641582dc07bc004b44e2849e",
|
"/css/dist/skins/skin-orange-dark.min.css": "/css/dist/skins/skin-orange-dark.min.css?id=03075904b967308132b810bc0205ab1c",
|
||||||
"/css/dist/skins/skin-contrast.min.css": "/css/dist/skins/skin-contrast.min.css?id=f0fbbb0ac729ea092578fb05ca615460"
|
"/css/dist/skins/skin-contrast.min.css": "/css/dist/skins/skin-contrast.min.css?id=f0fbbb0ac729ea092578fb05ca615460"
|
||||||
}
|
}
|
||||||
|
|
|
@ -70,7 +70,7 @@
|
||||||
|
|
||||||
&.btn-primary, .btn-primary:link {
|
&.btn-primary, .btn-primary:link {
|
||||||
background-color: darken(@black, 10%);
|
background-color: darken(@black, 10%);
|
||||||
border-color: darken(@black, 20%);
|
border-color: #FFF;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -245,7 +245,6 @@ body {
|
||||||
}
|
}
|
||||||
.btn-primary:hover {
|
.btn-primary:hover {
|
||||||
background-color: var(--button-primary);
|
background-color: var(--button-primary);
|
||||||
color: var(--link)!important;
|
|
||||||
}
|
}
|
||||||
#componentsTable>tbody>tr>td>nobr>a>i.fa {
|
#componentsTable>tbody>tr>td>nobr>a>i.fa {
|
||||||
color: var(--text-main);
|
color: var(--text-main);
|
||||||
|
|
|
@ -236,7 +236,6 @@ body {
|
||||||
}
|
}
|
||||||
.btn-primary:hover {
|
.btn-primary:hover {
|
||||||
background-color: var(--button-primary);
|
background-color: var(--button-primary);
|
||||||
color: var(--link)!important;
|
|
||||||
}
|
}
|
||||||
#componentsTable>tbody>tr>td>nobr>a>i.fa {
|
#componentsTable>tbody>tr>td>nobr>a>i.fa {
|
||||||
color: var(--text-main);
|
color: var(--text-main);
|
||||||
|
|
|
@ -243,7 +243,6 @@ a:link.btn-default{
|
||||||
}
|
}
|
||||||
.btn-primary:hover {
|
.btn-primary:hover {
|
||||||
background-color: var(--button-primary);
|
background-color: var(--button-primary);
|
||||||
color: var(--link)!important;
|
|
||||||
}
|
}
|
||||||
#componentsTable>tbody>tr>td>nobr>a>i.fa {
|
#componentsTable>tbody>tr>td>nobr>a>i.fa {
|
||||||
color: var(--text-main);
|
color: var(--text-main);
|
||||||
|
|
|
@ -246,7 +246,6 @@ body {
|
||||||
}
|
}
|
||||||
.btn-primary:hover {
|
.btn-primary:hover {
|
||||||
background-color: var(--button-primary);
|
background-color: var(--button-primary);
|
||||||
color: var(--link)!important;
|
|
||||||
}
|
}
|
||||||
#componentsTable>tbody>tr>td>nobr>a>i.fa {
|
#componentsTable>tbody>tr>td>nobr>a>i.fa {
|
||||||
color: var(--text-main);
|
color: var(--text-main);
|
||||||
|
|
|
@ -247,7 +247,6 @@ body {
|
||||||
}
|
}
|
||||||
.btn-primary:hover {
|
.btn-primary:hover {
|
||||||
background-color: var(--button-primary);
|
background-color: var(--button-primary);
|
||||||
color: var(--link)!important;
|
|
||||||
}
|
}
|
||||||
#componentsTable>tbody>tr>td>nobr>a>i.fa {
|
#componentsTable>tbody>tr>td>nobr>a>i.fa {
|
||||||
color: var(--text-main);
|
color: var(--text-main);
|
||||||
|
|
|
@ -55,7 +55,7 @@
|
||||||
|
|
||||||
&.btn-primary, .btn-primary:link {
|
&.btn-primary, .btn-primary:link {
|
||||||
background-color: var(--button-default);
|
background-color: var(--button-default);
|
||||||
border-color: var(--button-default);
|
border-color: #000000;
|
||||||
color: #545454;
|
color: #545454;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,7 @@ return [
|
||||||
'update' => [
|
'update' => [
|
||||||
'error' => 'Asset was not updated, please try again',
|
'error' => 'Asset was not updated, please try again',
|
||||||
'success' => 'Asset updated successfully.',
|
'success' => 'Asset updated successfully.',
|
||||||
|
'encrypted_warning' => 'Asset updated successfully, but encrypted custom fields were not due to permissions',
|
||||||
'nothing_updated' => 'No fields were selected, so nothing was updated.',
|
'nothing_updated' => 'No fields were selected, so nothing was updated.',
|
||||||
'no_assets_selected' => 'No assets were selected, so nothing was updated.',
|
'no_assets_selected' => 'No assets were selected, so nothing was updated.',
|
||||||
'assets_do_not_exist_or_are_invalid' => 'Selected assets cannot be updated.',
|
'assets_do_not_exist_or_are_invalid' => 'Selected assets cannot be updated.',
|
||||||
|
|
|
@ -245,6 +245,7 @@ return [
|
||||||
'select_all' => 'Select All',
|
'select_all' => 'Select All',
|
||||||
'search' => 'Search',
|
'search' => 'Search',
|
||||||
'select_category' => 'Select a Category',
|
'select_category' => 'Select a Category',
|
||||||
|
'select_datasource' => 'Select a Datasource',
|
||||||
'select_department' => 'Select a Department',
|
'select_department' => 'Select a Department',
|
||||||
'select_depreciation' => 'Select a Depreciation Type',
|
'select_depreciation' => 'Select a Depreciation Type',
|
||||||
'select_location' => 'Select a Location',
|
'select_location' => 'Select a Location',
|
||||||
|
|
|
@ -306,6 +306,7 @@
|
||||||
<label style="grid-area: source-title">DataSource</label>
|
<label style="grid-area: source-title">DataSource</label>
|
||||||
<select style="grid-area: source-field" x-model="option.datasource">
|
<select style="grid-area: source-field" x-model="option.datasource">
|
||||||
<optgroup label="Asset">
|
<optgroup label="Asset">
|
||||||
|
<option value="" disabled>{{ trans('general.select_datasource') }}</option>
|
||||||
<option value="asset_tag">{{trans('admin/hardware/table.asset_tag')}}</option>
|
<option value="asset_tag">{{trans('admin/hardware/table.asset_tag')}}</option>
|
||||||
<option value="name">{{trans('admin/hardware/form.name')}}</option>
|
<option value="name">{{trans('admin/hardware/form.name')}}</option>
|
||||||
<option value="serial">{{trans('admin/hardware/table.serial')}}</option>
|
<option value="serial">{{trans('admin/hardware/table.serial')}}</option>
|
||||||
|
|
|
@ -5,10 +5,12 @@ namespace Tests\Feature\Api\Assets;
|
||||||
use App\Models\Asset;
|
use App\Models\Asset;
|
||||||
use App\Models\AssetModel;
|
use App\Models\AssetModel;
|
||||||
use App\Models\Company;
|
use App\Models\Company;
|
||||||
|
use App\Models\CustomField;
|
||||||
use App\Models\Location;
|
use App\Models\Location;
|
||||||
use App\Models\Statuslabel;
|
use App\Models\Statuslabel;
|
||||||
use App\Models\Supplier;
|
use App\Models\Supplier;
|
||||||
use App\Models\User;
|
use App\Models\User;
|
||||||
|
use Illuminate\Support\Facades\Crypt;
|
||||||
use Illuminate\Testing\Fluent\AssertableJson;
|
use Illuminate\Testing\Fluent\AssertableJson;
|
||||||
use Tests\TestCase;
|
use Tests\TestCase;
|
||||||
|
|
||||||
|
@ -479,4 +481,55 @@ class AssetStoreTest extends TestCase
|
||||||
$json->has('messages.company_id')->etc();
|
$json->has('messages.company_id')->etc();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testEncryptedCustomFieldCanBeStored()
|
||||||
|
{
|
||||||
|
$this->markIncompleteIfMySQL('Custom Fields tests do not work on MySQL');
|
||||||
|
|
||||||
|
$status = Statuslabel::factory()->create();
|
||||||
|
$field = CustomField::factory()->testEncrypted()->create();
|
||||||
|
$superuser = User::factory()->superuser()->create();
|
||||||
|
$assetData = Asset::factory()->hasEncryptedCustomField($field)->make();
|
||||||
|
|
||||||
|
$response = $this->actingAsForApi($superuser)
|
||||||
|
->postJson(route('api.assets.store'), [
|
||||||
|
$field->db_column_name() => 'This is encrypted field',
|
||||||
|
'model_id' => $assetData->model->id,
|
||||||
|
'status_id' => $status->id,
|
||||||
|
'asset_tag' => '1234',
|
||||||
|
])
|
||||||
|
->assertStatusMessageIs('success')
|
||||||
|
->assertOk()
|
||||||
|
->json();
|
||||||
|
|
||||||
|
$asset = Asset::findOrFail($response['payload']['id']);
|
||||||
|
$this->assertEquals('This is encrypted field', Crypt::decrypt($asset->{$field->db_column_name()}));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testPermissionNeededToStoreEncryptedField()
|
||||||
|
{
|
||||||
|
// @todo:
|
||||||
|
$this->markTestIncomplete();
|
||||||
|
|
||||||
|
$status = Statuslabel::factory()->create();
|
||||||
|
$field = CustomField::factory()->testEncrypted()->create();
|
||||||
|
$normal_user = User::factory()->editAssets()->create();
|
||||||
|
$assetData = Asset::factory()->hasEncryptedCustomField($field)->make();
|
||||||
|
|
||||||
|
$response = $this->actingAsForApi($normal_user)
|
||||||
|
->postJson(route('api.assets.store'), [
|
||||||
|
$field->db_column_name() => 'Some Other Value Entirely!',
|
||||||
|
'model_id' => $assetData->model->id,
|
||||||
|
'status_id' => $status->id,
|
||||||
|
'asset_tag' => '1234',
|
||||||
|
])
|
||||||
|
// @todo: this is 403 unauthorized
|
||||||
|
->assertStatusMessageIs('success')
|
||||||
|
->assertOk()
|
||||||
|
->assertMessagesAre('Asset updated successfully, but encrypted custom fields were not due to permissions')
|
||||||
|
->json();
|
||||||
|
|
||||||
|
$asset = Asset::findOrFail($response['payload']['id']);
|
||||||
|
$this->assertEquals('This is encrypted field', Crypt::decrypt($asset->{$field->db_column_name()}));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
55
tests/Feature/Api/Assets/AssetUpdateTest.php
Normal file
55
tests/Feature/Api/Assets/AssetUpdateTest.php
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Tests\Feature\Api\Assets;
|
||||||
|
|
||||||
|
use App\Models\Asset;
|
||||||
|
use App\Models\CustomField;
|
||||||
|
use App\Models\User;
|
||||||
|
use Illuminate\Support\Facades\Crypt;
|
||||||
|
use Tests\TestCase;
|
||||||
|
|
||||||
|
class AssetUpdateTest extends TestCase
|
||||||
|
{
|
||||||
|
public function testEncryptedCustomFieldCanBeUpdated()
|
||||||
|
{
|
||||||
|
$this->markIncompleteIfMySQL('Custom Fields tests do not work on MySQL');
|
||||||
|
|
||||||
|
$field = CustomField::factory()->testEncrypted()->create();
|
||||||
|
$asset = Asset::factory()->hasEncryptedCustomField($field)->create();
|
||||||
|
$superuser = User::factory()->superuser()->create();
|
||||||
|
|
||||||
|
$this->actingAsForApi($superuser)
|
||||||
|
->patchJson(route('api.assets.update', $asset->id), [
|
||||||
|
$field->db_column_name() => 'This is encrypted field'
|
||||||
|
])
|
||||||
|
->assertStatusMessageIs('success')
|
||||||
|
->assertOk();
|
||||||
|
|
||||||
|
$asset->refresh();
|
||||||
|
$this->assertEquals('This is encrypted field', Crypt::decrypt($asset->{$field->db_column_name()}));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testPermissionNeededToUpdateEncryptedField()
|
||||||
|
{
|
||||||
|
$this->markIncompleteIfMySQL('Custom Fields tests do not work on MySQL');
|
||||||
|
|
||||||
|
$field = CustomField::factory()->testEncrypted()->create();
|
||||||
|
$asset = Asset::factory()->hasEncryptedCustomField($field)->create();
|
||||||
|
$normal_user = User::factory()->editAssets()->create();
|
||||||
|
|
||||||
|
$asset->{$field->db_column_name()} = Crypt::encrypt("encrypted value should not change");
|
||||||
|
$asset->save();
|
||||||
|
|
||||||
|
// test that a 'normal' user *cannot* change the encrypted custom field
|
||||||
|
$this->actingAsForApi($normal_user)
|
||||||
|
->patchJson(route('api.assets.update', $asset->id), [
|
||||||
|
$field->db_column_name() => 'Some Other Value Entirely!'
|
||||||
|
])
|
||||||
|
->assertStatusMessageIs('success')
|
||||||
|
->assertOk()
|
||||||
|
->assertMessagesAre('Asset updated successfully, but encrypted custom fields were not due to permissions');
|
||||||
|
|
||||||
|
$asset->refresh();
|
||||||
|
$this->assertEquals("encrypted value should not change", Crypt::decrypt($asset->{$field->db_column_name()}));
|
||||||
|
}
|
||||||
|
}
|
13
tests/Support/CanSkipTests.php
Normal file
13
tests/Support/CanSkipTests.php
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Tests\Support;
|
||||||
|
|
||||||
|
trait CanSkipTests
|
||||||
|
{
|
||||||
|
public function markIncompleteIfMySQL($message = 'Test skipped due to database driver being MySQL.')
|
||||||
|
{
|
||||||
|
if (config('database.default') === 'mysql') {
|
||||||
|
$this->markTestIncomplete($message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -87,5 +87,18 @@ trait CustomTestMacros
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
TestResponse::macro(
|
||||||
|
'assertMessagesAre',
|
||||||
|
function (string $message) {
|
||||||
|
Assert::assertEquals(
|
||||||
|
$message,
|
||||||
|
$this['messages'],
|
||||||
|
"Response messages was not {$message}"
|
||||||
|
);
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@ use Illuminate\Foundation\Testing\LazilyRefreshDatabase;
|
||||||
use Illuminate\Foundation\Testing\TestCase as BaseTestCase;
|
use Illuminate\Foundation\Testing\TestCase as BaseTestCase;
|
||||||
use RuntimeException;
|
use RuntimeException;
|
||||||
use Tests\Support\AssertsAgainstSlackNotifications;
|
use Tests\Support\AssertsAgainstSlackNotifications;
|
||||||
|
use Tests\Support\CanSkipTests;
|
||||||
use Tests\Support\CustomTestMacros;
|
use Tests\Support\CustomTestMacros;
|
||||||
use Tests\Support\InteractsWithAuthentication;
|
use Tests\Support\InteractsWithAuthentication;
|
||||||
use Tests\Support\InitializesSettings;
|
use Tests\Support\InitializesSettings;
|
||||||
|
@ -14,6 +15,7 @@ use Tests\Support\InitializesSettings;
|
||||||
abstract class TestCase extends BaseTestCase
|
abstract class TestCase extends BaseTestCase
|
||||||
{
|
{
|
||||||
use AssertsAgainstSlackNotifications;
|
use AssertsAgainstSlackNotifications;
|
||||||
|
use CanSkipTests;
|
||||||
use CreatesApplication;
|
use CreatesApplication;
|
||||||
use CustomTestMacros;
|
use CustomTestMacros;
|
||||||
use InteractsWithAuthentication;
|
use InteractsWithAuthentication;
|
||||||
|
|
Loading…
Reference in a new issue