Merge branch 'master' into chore/migrate-textarea-helper

This commit is contained in:
snipe 2025-02-10 23:47:13 +00:00 committed by GitHub
commit b4ea75f34f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
403 changed files with 3936 additions and 2163 deletions

View file

@ -11,7 +11,7 @@ MYSQL_ROOT_PASSWORD=changeme1234
# REQUIRED: BASIC APP SETTINGS # REQUIRED: BASIC APP SETTINGS
# -------------------------------------------- # --------------------------------------------
APP_ENV=develop APP_ENV=develop
APP_DEBUG=false APP_DEBUG=true
# please regenerate the APP_KEY value by calling `docker-compose run --rm snipeit bash` and then `php artisan key:generate --show` and then copy paste the value here # please regenerate the APP_KEY value by calling `docker-compose run --rm snipeit bash` and then `php artisan key:generate --show` and then copy paste the value here
APP_KEY=base64:3ilviXqB9u6DX1NRcyWGJ+sjySF+H18CPDGb3+IVwMQ= APP_KEY=base64:3ilviXqB9u6DX1NRcyWGJ+sjySF+H18CPDGb3+IVwMQ=
APP_URL=http://localhost:8000 APP_URL=http://localhost:8000
@ -158,7 +158,7 @@ RESET_PASSWORD_LINK_EXPIRES=900
# -------------------------------------------- # --------------------------------------------
# OPTIONAL: MISC # OPTIONAL: MISC
# -------------------------------------------- # --------------------------------------------
LOG_CHANNEL=stderr LOG_CHANNEL=single
LOG_MAX_DAYS=10 LOG_MAX_DAYS=10
APP_LOCKED=false APP_LOCKED=false
APP_CIPHER=AES-256-CBC APP_CIPHER=AES-256-CBC

View file

@ -73,7 +73,7 @@ RUN mkdir -p /var/www/.composer && chown apache /var/www/.composer
# Install dependencies # Install dependencies
USER apache USER apache
RUN COMPOSER_CACHE_DIR=/dev/null composer install --no-dev --working-dir=/var/www/html RUN COMPOSER_CACHE_DIR=/dev/null composer install --working-dir=/var/www/html
USER root USER root

View file

@ -65,7 +65,7 @@ class ResetDemoSettings extends Command
$settings->thumbnail_max_h = '30'; $settings->thumbnail_max_h = '30';
$settings->locale = 'en-US'; $settings->locale = 'en-US';
$settings->version_footer = 'on'; $settings->version_footer = 'on';
$settings->support_footer = null; $settings->support_footer = 'on';
$settings->saml_enabled = '0'; $settings->saml_enabled = '0';
$settings->saml_sp_x509cert = null; $settings->saml_sp_x509cert = null;
$settings->saml_idp_metadata = null; $settings->saml_idp_metadata = null;

28
app/Events/NoteAdded.php Normal file
View file

@ -0,0 +1,28 @@
<?php
namespace App\Events;
use App\Models\User;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Queue\SerializesModels;
class NoteAdded
{
use Dispatchable, SerializesModels;
public $itemNoteAddedOn;
public $note;
public $noteAddedBy;
/**
* Create a new event instance.
*
* @return void
*/
public function __construct($itemNoteAddedOn, User $noteAddedBy, $note)
{
$this->itemNoteAddedOn = $itemNoteAddedOn;
$this->note = $note;
$this->noteAddedBy = $noteAddedBy;
}
}

View file

@ -184,7 +184,9 @@ class IconHelper
return 'fa-regular fa-id-card'; return 'fa-regular fa-id-card';
case 'department' : case 'department' :
return 'fa-solid fa-building-user'; return 'fa-solid fa-building-user';
case 'note':
case 'notes':
return 'fas fa-sticky-note';
} }
} }
} }

View file

@ -51,15 +51,15 @@ class AccessoriesFilesController extends Controller
} }
return redirect()->route('accessories.show', $accessory->id)->with('success', trans('general.file_upload_success')); return redirect()->route('accessories.show', $accessory->id)->withFragment('files')->with('success', trans('general.file_upload_success'));
} }
return redirect()->route('accessories.show', $accessory->id)->with('error', trans('general.no_files_uploaded')); return redirect()->route('accessories.show', $accessory->id)->withFragment('files')->with('error', trans('general.no_files_uploaded'));
} }
// Prepare the error message // Prepare the error message
return redirect()->route('accessories.index') return redirect()->route('accessories.index')->with('error', trans('admin/accessories/message.does_not_exist'));
->with('error', trans('general.file_does_not_exist'));
} }
/** /**
@ -72,30 +72,27 @@ class AccessoriesFilesController extends Controller
*/ */
public function destroy($accessoryId = null, $fileId = null) : RedirectResponse public function destroy($accessoryId = null, $fileId = null) : RedirectResponse
{ {
$accessory = Accessory::find($accessoryId); if ($accessory = Accessory::find($accessoryId)) {
// the asset is valid
if (isset($accessory->id)) {
$this->authorize('update', $accessory); $this->authorize('update', $accessory);
$log = Actionlog::find($fileId);
// Remove the file if one exists if ($log = Actionlog::find($fileId)) {
if (Storage::exists('accessories/'.$log->filename)) {
try { if (Storage::exists('private_uploads/accessories/'.$log->filename)) {
Storage::delete('accessories/'.$log->filename); try {
} catch (\Exception $e) { Storage::delete('private_uploads/accessories/' . $log->filename);
Log::debug($e); $log->delete();
return redirect()->back()->withFragment('files')->with('success', trans('admin/hardware/message.deletefile.success'));
} catch (\Exception $e) {
Log::debug($e);
return redirect()->route('accessories.index')->with('error', trans('general.file_does_not_exist'));
}
} }
} }
return redirect()->route('accessories.show', ['accessory' => $accessory])->withFragment('files')->with('error', trans('general.log_record_not_found'));
$log->delete();
return redirect()->back()
->with('success', trans('admin/hardware/message.deletefile.success'));
} }
// Redirect to the licence management page return redirect()->route('accessories.index')->with('error', trans('admin/accessories/message.does_not_exist'));
return redirect()->route('accessories.index')->with('error', trans('general.file_does_not_exist'));
} }
/** /**
@ -125,10 +122,11 @@ class AccessoriesFilesController extends Controller
} }
} }
return redirect()->route('accessories.show', ['accessory' => $accessory])->with('error', trans('general.log_record_not_found')); return redirect()->route('accessories.show', ['accessory' => $accessory])->withFragment('files')->with('error', trans('general.log_record_not_found'));
} }
return redirect()->route('accessories.index')->with('error', trans('general.file_not_found')); return redirect()->route('accessories.index')->with('error', trans('admin/accessories/message.does_not_exist'));
} }
} }

View file

@ -40,10 +40,13 @@ class ActionlogController extends Controller
public function getStoredEula($filename) : Response | BinaryFileResponse | RedirectResponse public function getStoredEula($filename) : Response | BinaryFileResponse | RedirectResponse
{ {
$this->authorize('view', \App\Models\Asset::class); $this->authorize('view', \App\Models\Asset::class);
$file = config('app.private_uploads').'/eula-pdfs/'.$filename;
if (config('filesystems.default') == 's3_private') {
return redirect()->away(Storage::disk('s3_private')->temporaryUrl('private_uploads/eula-pdfs/'.$filename, now()->addMinutes(5)));
}
if (Storage::exists('private_uploads/eula-pdfs/'.$filename)) { if (Storage::exists('private_uploads/eula-pdfs/'.$filename)) {
return response()->download($file); return response()->download(config('app.private_uploads').'/eula-pdfs/'.$filename);
} }
return redirect()->back()->with('error', trans('general.file_does_not_exist')); return redirect()->back()->with('error', trans('general.file_does_not_exist'));

View file

@ -9,6 +9,7 @@ use App\Http\Controllers\Controller;
use App\Models\AssetModel; use App\Models\AssetModel;
use App\Models\Actionlog; use App\Models\Actionlog;
use App\Http\Requests\UploadFileRequest; use App\Http\Requests\UploadFileRequest;
use App\Http\Transformers\AssetModelsTransformer;
use Illuminate\Http\JsonResponse; use Illuminate\Http\JsonResponse;
use Illuminate\Support\Facades\Log; use Illuminate\Support\Facades\Log;
use Symfony\Component\HttpFoundation\StreamedResponse; use Symfony\Component\HttpFoundation\StreamedResponse;
@ -68,37 +69,15 @@ class AssetModelFilesController extends Controller
/** /**
* List the files for an asset. * List the files for an asset.
* *
* @param int $assetModelId * @param int $assetmodel
* @since [v7.0.12] * @since [v7.0.12]
* @author [r-xyz] * @author [r-xyz]
*/ */
public function list($assetModelId = null) : JsonResponse public function list($assetmodel_id) : JsonResponse | array
{ {
// Start by checking if the asset being acted upon exists $assetmodel = AssetModel::with('uploads')->find($assetmodel_id);
if (! $assetModel = AssetModel::find($assetModelId)) { $this->authorize('view', $assetmodel);
return response()->json(Helper::formatStandardApiResponse('error', null, trans('admin/models/message.does_not_exist')), 404); return (new AssetModelsTransformer)->transformAssetModelFiles($assetmodel, $assetmodel->uploads()->count());
}
// the asset is valid
if (isset($assetModel->id)) {
$this->authorize('view', $assetModel);
// Check that there are some uploads on this asset that can be listed
if ($assetModel->uploads->count() > 0) {
$files = array();
foreach ($assetModel->uploads as $upload) {
array_push($files, $upload);
}
// Give the list of files back to the user
return response()->json(Helper::formatStandardApiResponse('success', $files, trans('admin/models/message.upload.success')));
}
// There are no files.
return response()->json(Helper::formatStandardApiResponse('success', array(), trans('admin/models/message.upload.success')));
}
// Send back an error message
return response()->json(Helper::formatStandardApiResponse('error', null, trans('admin/models/message.download.error')), 500);
} }
/** /**

View file

@ -9,12 +9,14 @@ use App\Http\Transformers\ImportsTransformer;
use App\Models\Asset; use App\Models\Asset;
use App\Models\Company; use App\Models\Company;
use App\Models\Import; use App\Models\Import;
use Illuminate\Http\UploadedFile;
use Illuminate\Support\Facades\Artisan; use Illuminate\Support\Facades\Artisan;
use Illuminate\Database\Eloquent\JsonEncodingException; use Illuminate\Database\Eloquent\JsonEncodingException;
use Illuminate\Support\Facades\Request; use Illuminate\Support\Facades\Request;
use Illuminate\Support\Facades\Session; use Illuminate\Support\Facades\Session;
use Illuminate\Support\Facades\Storage; use Illuminate\Support\Facades\Storage;
use League\Csv\Reader; use League\Csv\Reader;
use Onnov\DetectEncoding\EncodingDetector;
use Symfony\Component\HttpFoundation\File\Exception\FileException; use Symfony\Component\HttpFoundation\File\Exception\FileException;
use Illuminate\Support\Facades\Log; use Illuminate\Support\Facades\Log;
use Illuminate\Http\JsonResponse; use Illuminate\Http\JsonResponse;
@ -45,6 +47,8 @@ class ImportController extends Controller
$path = config('app.private_uploads').'/imports'; $path = config('app.private_uploads').'/imports';
$results = []; $results = [];
$import = new Import; $import = new Import;
$detector = new EncodingDetector();
foreach ($files as $file) { foreach ($files as $file) {
if (! in_array($file->getMimeType(), [ if (! in_array($file->getMimeType(), [
'application/vnd.ms-excel', 'application/vnd.ms-excel',
@ -55,7 +59,6 @@ class ImportController extends Controller
'text/comma-separated-values', 'text/comma-separated-values',
'text/tsv', ])) { 'text/tsv', ])) {
$results['error'] = 'File type must be CSV. Uploaded file is '.$file->getMimeType(); $results['error'] = 'File type must be CSV. Uploaded file is '.$file->getMimeType();
return response()->json(Helper::formatStandardApiResponse('error', null, $results['error']), 422); return response()->json(Helper::formatStandardApiResponse('error', null, $results['error']), 422);
} }
@ -63,7 +66,25 @@ class ImportController extends Controller
if (! ini_get('auto_detect_line_endings')) { if (! ini_get('auto_detect_line_endings')) {
ini_set('auto_detect_line_endings', '1'); ini_set('auto_detect_line_endings', '1');
} }
$file_contents = $file->getContent(); //TODO - this *does* load the whole file in RAM, but we need that to be able to 'iconv' it?
$encoding = $detector->getEncoding($file_contents);
$reader = null;
if (strcasecmp($encoding, 'UTF-8') != 0) {
$transliterated = iconv($encoding, 'UTF-8', $file_contents);
if ($transliterated !== false) {
$tmpname = tempnam(sys_get_temp_dir(), '');
$tmpresults = file_put_contents($tmpname, $transliterated);
if ($tmpresults !== false) {
$transliterated = null; //save on memory?
$newfile = new UploadedFile($tmpname, $file->getClientOriginalName(), null, null, true); //WARNING: this is enabling 'test mode' - which is gross, but otherwise the file won't be treated as 'uploaded'
if ($newfile->isValid()) {
$file = $newfile;
}
}
}
}
$reader = Reader::createFromFileObject($file->openFile('r')); //file pointer leak? $reader = Reader::createFromFileObject($file->openFile('r')); //file pointer leak?
$file_contents = null; //try to save on memory, I guess?
try { try {
$import->header_row = $reader->fetchOne(0); $import->header_row = $reader->fetchOne(0);

View file

@ -0,0 +1,43 @@
<?php
namespace App\Http\Controllers\Api;
use App\Events\NoteAdded;
use App\Helpers\Helper;
use App\Http\Controllers\Controller;
use App\Models\Asset;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Validation\Rule;
class NotesController extends Controller
{
public function store(Request $request)
{
$validated = $request->validate([
'note' => 'required|string|max:500',
'type' => [
'required',
Rule::in(['asset']),
],
]);
// This can be made dynamic by using $request->input('type') to determine which model type to add the note to.
// For now, we are only placing this on Assets
$item = Asset::findOrFail($request->input("id"));
$this->authorize('update', $item);
event(new NoteAdded($item, Auth::user(), $validated['note']));
return response()->json(Helper::formatStandardApiResponse('success'));
}
public function update(Request $request)
{
}
public function destroy(Request $request)
{
}
}

View file

@ -44,10 +44,10 @@ class AssetModelsFilesController extends Controller
$model->logUpload($file_name, $request->get('notes')); $model->logUpload($file_name, $request->get('notes'));
} }
return redirect()->back()->with('success', trans('general.file_upload_success')); return redirect()->back()->withFragment('files')->with('success', trans('general.file_upload_success'));
} }
return redirect()->back()->with('error', trans('admin/hardware/message.upload.nofiles')); return redirect()->back()->withFragment('files')->with('error', trans('admin/hardware/message.upload.nofiles'));
} }
/** /**
@ -119,11 +119,10 @@ class AssetModelsFilesController extends Controller
} }
$log->delete(); $log->delete();
return redirect()->back()->with('success', trans('admin/hardware/message.deletefile.success')); return redirect()->back()->withFragment('files')->with('success', trans('admin/hardware/message.deletefile.success'));
} }
return redirect()->back() return redirect()->back()->withFragment('files')->with('success', trans('admin/hardware/message.deletefile.success'));
->with('success', trans('admin/hardware/message.deletefile.success'));
} }
// Redirect to the hardware management page // Redirect to the hardware management page

View file

@ -45,7 +45,7 @@ class AssetFilesController extends Controller
$asset->logUpload($file_name, $request->get('notes')); $asset->logUpload($file_name, $request->get('notes'));
} }
return redirect()->back()->with('success', trans('admin/hardware/message.upload.success')); return redirect()->back()->withFragment('files')->with('success', trans('admin/hardware/message.upload.success'));
} }
return redirect()->back()->with('error', trans('admin/hardware/message.upload.nofiles')); return redirect()->back()->with('error', trans('admin/hardware/message.upload.nofiles'));
@ -97,25 +97,19 @@ class AssetFilesController extends Controller
*/ */
public function destroy($assetId = null, $fileId = null) : RedirectResponse public function destroy($assetId = null, $fileId = null) : RedirectResponse
{ {
$asset = Asset::find($assetId); if ($asset = Asset::find($assetId)) {
$this->authorize('update', $asset);
$rel_path = 'private_uploads/assets';
// the asset is valid
if (isset($asset->id)) {
$this->authorize('update', $asset); $this->authorize('update', $asset);
$log = Actionlog::find($fileId); $rel_path = 'private_uploads/assets';
if ($log) {
if ($log = Actionlog::find($fileId)) {
if (Storage::exists($rel_path.'/'.$log->filename)) { if (Storage::exists($rel_path.'/'.$log->filename)) {
Storage::delete($rel_path.'/'.$log->filename); Storage::delete($rel_path.'/'.$log->filename);
} }
$log->delete(); $log->delete();
return redirect()->back()->withFragment('files')->with('success', trans('admin/hardware/message.deletefile.success'));
return redirect()->back()->with('success', trans('admin/hardware/message.deletefile.success'));
} }
return redirect()->back() return redirect()->route('hardware.show', ['hardware' => $asset])->with('error', trans('general.log_record_not_found'));
->with('success', trans('admin/hardware/message.deletefile.success'));
} }
return redirect()->route('hardware.index')->with('error', trans('admin/hardware/message.does_not_exist')); return redirect()->route('hardware.index')->with('error', trans('admin/hardware/message.does_not_exist'));

View file

@ -535,7 +535,7 @@ class AssetsController extends Controller
{ {
$settings = Setting::getSettings(); $settings = Setting::getSettings();
if ($settings->qr_code == '1') { if (($settings->qr_code === '1') && ($settings->label2_2d_type !== 'none')) {
$asset = Asset::withTrashed()->find($assetId); $asset = Asset::withTrashed()->find($assetId);
if ($asset) { if ($asset) {
$size = Helper::barcodeDimensions($settings->label2_2d_type); $size = Helper::barcodeDimensions($settings->label2_2d_type);
@ -865,8 +865,8 @@ class AssetsController extends Controller
public function quickScan() public function quickScan()
{ {
$this->authorize('audit', Asset::class); $this->authorize('audit', Asset::class);
$dt = Carbon::now()->addMonths(12)->toDateString(); $settings = Setting::getSettings();
$dt = Carbon::now()->addMonths($settings->audit_interval)->toDateString();
return view('hardware/quickscan')->with('next_audit_date', $dt); return view('hardware/quickscan')->with('next_audit_date', $dt);
} }
@ -883,7 +883,6 @@ class AssetsController extends Controller
$this->authorize('audit', Asset::class); $this->authorize('audit', Asset::class);
$dt = Carbon::now()->addMonths($settings->audit_interval)->toDateString(); $dt = Carbon::now()->addMonths($settings->audit_interval)->toDateString();
$asset = Asset::findOrFail($id); $asset = Asset::findOrFail($id);
return view('hardware/audit')->with('asset', $asset)->with('next_audit_date', $dt)->with('locations_list'); return view('hardware/audit')->with('asset', $asset)->with('next_audit_date', $dt)->with('locations_list');
} }

View file

@ -103,22 +103,24 @@ class ResetPasswordController extends Controller
], $messages); ], $messages);
} }
if ($user->ldap_import != '1') {
// set the response // set the response
$response = $broker->reset( $response = $broker->reset(
$this->credentials($request), function ($user, $password) { $this->credentials($request), function ($user, $password) {
$this->resetPassword($user, $password); $this->resetPassword($user, $password);
}); });
// Check if the password reset above actually worked // Check if the password reset above actually worked
if ($response == \Password::PASSWORD_RESET) { if ($response == \Password::PASSWORD_RESET) {
Log::debug('Password reset for '.$user->username.' worked'); Log::debug('Password reset for ' . $user->username . ' worked');
return redirect()->guest('login')->with('success', trans('passwords.reset')); return redirect()->guest('login')->with('success', trans('passwords.reset'));
}
Log::debug('Password reset for ' . $user->username . ' FAILED - this user exists but the token is not valid');
return redirect()->back()->withInput($request->only('email'))->with('success', trans('passwords.reset'));
} }
Log::debug('Password reset for '.$user->username.' FAILED - this user exists but the token is not valid');
return redirect()->back()->withInput($request->only('email'))->with('success', trans('passwords.reset'));
} }

View file

@ -50,7 +50,7 @@ class ComponentsFilesController extends Controller
} }
return redirect()->route('components.show', $component->id)->with('success', trans('general.file_upload_success')); return redirect()->route('components.show', $component->id)->withFragment('files')->with('success', trans('general.file_upload_success'));
} }
@ -91,7 +91,7 @@ class ComponentsFilesController extends Controller
$log->delete(); $log->delete();
return redirect()->back() return redirect()->back()->withFragment('files')
->with('success', trans('admin/hardware/message.deletefile.success')); ->with('success', trans('admin/hardware/message.deletefile.success'));
} }

View file

@ -48,7 +48,7 @@ class ConsumablesFilesController extends Controller
} }
return redirect()->route('consumables.show', $consumable->id)->with('success', trans('general.file_upload_success')); return redirect()->route('consumables.show', $consumable->id)->withFragment('files')->with('success', trans('general.file_upload_success'));
} }
@ -89,7 +89,7 @@ class ConsumablesFilesController extends Controller
$log->delete(); $log->delete();
return redirect()->back() return redirect()->back()->withFragment('files')
->with('success', trans('admin/hardware/message.deletefile.success')); ->with('success', trans('admin/hardware/message.deletefile.success'));
} }

View file

@ -32,7 +32,8 @@ class ModalController extends Controller
'statuslabel', 'statuslabel',
'supplier', 'supplier',
'upload-file', 'upload-file',
'user', 'user',
'add-note',
]; ];

View file

@ -99,9 +99,13 @@ class ProfileController extends Controller
* User change email page. * User change email page.
* *
*/ */
public function password() : View public function password() : View | RedirectResponse
{ {
$user = auth()->user(); $user = auth()->user();
if ($user->ldap_import=='1') {
return redirect()->route('account')->with('error', trans('admin/users/message.error.password_ldap'));
}
return view('account/change-password', compact('user')); return view('account/change-password', compact('user'));
} }
@ -116,7 +120,7 @@ class ProfileController extends Controller
$user = auth()->user(); $user = auth()->user();
if ($user->ldap_import == '1') { if ($user->ldap_import == '1') {
return redirect()->route('account.password.index')->with('error', trans('admin/users/message.error.password_ldap')); return redirect()->route('account')->with('error', trans('admin/users/message.error.password_ldap'));
} }
$rules = [ $rules = [

View file

@ -11,6 +11,7 @@ use App\Models\AssetModel;
use App\Models\Category; use App\Models\Category;
use App\Models\AssetMaintenance; use App\Models\AssetMaintenance;
use App\Models\CheckoutAcceptance; use App\Models\CheckoutAcceptance;
use App\Models\Company;
use App\Models\CustomField; use App\Models\CustomField;
use App\Models\Depreciation; use App\Models\Depreciation;
use App\Models\License; use App\Models\License;
@ -18,6 +19,7 @@ use App\Models\ReportTemplate;
use App\Models\Setting; use App\Models\Setting;
use App\Notifications\CheckoutAssetNotification; use App\Notifications\CheckoutAssetNotification;
use Carbon\Carbon; use Carbon\Carbon;
use Illuminate\Database\Eloquent\Relations\MorphTo;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use Illuminate\Http\Response; use Illuminate\Http\Response;
use Illuminate\Support\Facades\Mail; use Illuminate\Support\Facades\Mail;
@ -1109,28 +1111,31 @@ class ReportsController extends Controller
$this->authorize('reports.view'); $this->authorize('reports.view');
$showDeleted = $deleted == 'deleted'; $showDeleted = $deleted == 'deleted';
/** $query = CheckoutAcceptance::pending()
* Get all assets with pending checkout acceptances ->where('checkoutable_type', 'App\Models\Asset')
*/ ->with([
if($showDeleted) { 'checkoutable' => function (MorphTo $query) {
$acceptances = CheckoutAcceptance::pending()->where('checkoutable_type', 'App\Models\Asset')->withTrashed()->with(['assignedTo' , 'checkoutable.assignedTo', 'checkoutable.model'])->get(); $query->morphWith([
} else { AssetModel::class => ['model'],
$acceptances = CheckoutAcceptance::pending()->where('checkoutable_type', 'App\Models\Asset')->with(['assignedTo' => function ($query) { Company::class => ['company'],
$query->withTrashed(); Asset::class => ['assignedTo'],
}, 'checkoutable.assignedTo', 'checkoutable.model'])->get(); ])->with('model.category');
},
'assignedTo' => function($query){
$query->withTrashed();
}
]);
if ($showDeleted) {
$query->withTrashed();
} }
$assetsForReport = $acceptances $assetsForReport = $query->get()
->filter(function ($acceptance) { ->map(function ($acceptance) {
$acceptance_checkoutable_flag = false; return [
if ($acceptance->checkoutable){ 'assetItem' => $acceptance->checkoutable,
$acceptance_checkoutable_flag = $acceptance->checkoutable->checkedOutToUser(); 'acceptance' => $acceptance,
} ];
return $acceptance->checkoutable_type == 'App\Models\Asset' && $acceptance_checkoutable_flag;
})
->map(function($acceptance) {
return ['assetItem' => $acceptance->checkoutable, 'acceptance' => $acceptance];
}); });
return view('reports/unaccepted_assets', compact('assetsForReport','showDeleted' )); return view('reports/unaccepted_assets', compact('assetsForReport','showDeleted' ));

View file

@ -192,6 +192,7 @@ class SettingsController extends Controller
$settings->next_auto_tag_base = 1; $settings->next_auto_tag_base = 1;
$settings->auto_increment_assets = $request->input('auto_increment_assets', 0); $settings->auto_increment_assets = $request->input('auto_increment_assets', 0);
$settings->auto_increment_prefix = $request->input('auto_increment_prefix'); $settings->auto_increment_prefix = $request->input('auto_increment_prefix');
$settings->zerofill_count = $request->input('zerofill_count') ?: 0;
if ((! $user->isValid()) || (! $settings->isValid())) { if ((! $user->isValid()) || (! $settings->isValid())) {
return redirect()->back()->withInput()->withErrors($user->getErrors())->withErrors($settings->getErrors()); return redirect()->back()->withInput()->withErrors($user->getErrors())->withErrors($settings->getErrors());

View file

@ -70,7 +70,7 @@ class BulkUsersController extends Controller
// bulk password reset, just do the thing // bulk password reset, just do the thing
} elseif ($request->input('bulk_actions') == 'bulkpasswordreset') { } elseif ($request->input('bulk_actions') == 'bulkpasswordreset') {
foreach ($users as $user) { foreach ($users as $user) {
if (($user->activated == '1') && ($user->email != '')) { if (($user->activated == '1') && ($user->email != '') && ($user->ldap_import != '1')) {
$credentials = ['email' => $user->email]; $credentials = ['email' => $user->email];
Password::sendResetLink($credentials/* , function (Message $message) { Password::sendResetLink($credentials/* , function (Message $message) {
$message->subject($this->getEmailSubject()); // TODO - I'm not sure if we still need this, but this second parameter is no longer accepted in later Laravel versions. $message->subject($this->getEmailSubject()); // TODO - I'm not sure if we still need this, but this second parameter is no longer accepted in later Laravel versions.

View file

@ -56,7 +56,7 @@ class UserFilesController extends Controller
$logActions[] = $logAction; $logActions[] = $logAction;
} }
// dd($logActions); // dd($logActions);
return redirect()->back()->with('success', trans('admin/users/message.upload.success')); return redirect()->back()->withFragment('files')->with('success', trans('admin/users/message.upload.success'));
} }
return redirect()->back()->with('error', trans('admin/users/message.upload.nofiles')); return redirect()->back()->with('error', trans('admin/users/message.upload.nofiles'));
@ -87,7 +87,7 @@ class UserFilesController extends Controller
if (Storage::exists($rel_path.'/'.$filename)) { if (Storage::exists($rel_path.'/'.$filename)) {
Storage::delete($rel_path.'/'.$filename); Storage::delete($rel_path.'/'.$filename);
return redirect()->back()->with('success', trans('admin/users/message.deletefile.success')); return redirect()->back()->withFragment('files')->with('success', trans('admin/users/message.deletefile.success'));
} }
} }

View file

@ -62,7 +62,7 @@ class SettingsSamlRequest extends FormRequest
$custom_privateKey = ''; $custom_privateKey = '';
$custom_x509certNew = ''; $custom_x509certNew = '';
if (! empty($this->input('saml_custom_settings'))) { if (! empty($this->input('saml_custom_settings'))) {
$req_custom_settings = preg_split('/\r\n|\r|\n/', $this->input('saml_custom_settings')); $req_custom_settings = preg_split('/\r\n|\r|\n/', $this->input('saml_custom_settings', ''));
$custom_settings = []; $custom_settings = [];
foreach ($req_custom_settings as $custom_setting) { foreach ($req_custom_settings as $custom_setting) {

View file

@ -46,8 +46,6 @@ class UploadFileRequest extends Request
$extension = $file->getClientOriginalExtension(); $extension = $file->getClientOriginalExtension();
$file_name = $name_prefix.'-'.str_random(8).'-'.str_slug(basename($file->getClientOriginalName(), '.'.$extension)).'.'.$file->guessExtension(); $file_name = $name_prefix.'-'.str_random(8).'-'.str_slug(basename($file->getClientOriginalName(), '.'.$extension)).'.'.$file->guessExtension();
Log::debug("Your filetype IS: ".$file->getMimeType());
// Check for SVG and sanitize it // Check for SVG and sanitize it
if ($file->getMimeType() === 'image/svg+xml') { if ($file->getMimeType() === 'image/svg+xml') {
Log::debug('This is an SVG'); Log::debug('This is an SVG');
@ -66,7 +64,6 @@ class UploadFileRequest extends Request
} else { } else {
$put_results = Storage::put($dirname.$file_name, file_get_contents($file)); $put_results = Storage::put($dirname.$file_name, file_get_contents($file));
Log::debug("Here are the '$put_results' (should be 0 or 1 or true or false or something?)");
} }
return $file_name; return $file_name;
} }

View file

@ -87,6 +87,41 @@ class AssetModelsTransformer
return $array; return $array;
} }
public function transformAssetModelFiles($assetmodel, $total)
{
$array = [];
foreach ($assetmodel->uploads as $file) {
$array[] = self::transformAssetModelFile($file, $assetmodel);
}
return (new DatatablesTransformer)->transformDatatables($array, $total);
}
public function transformAssetModelFile($file, $assetmodel)
{
$array = [
'id' => (int) $file->id,
'filename' => e($file->filename),
'url' => route('show/modelfile', [$assetmodel->id, $file->id]),
'created_by' => ($file->adminuser) ? [
'id' => (int) $file->adminuser->id,
'name'=> e($file->adminuser->present()->fullName),
] : null,
'created_at' => Helper::getFormattedDateObject($file->created_at, 'datetime'),
'updated_at' => Helper::getFormattedDateObject($file->updated_at, 'datetime'),
'deleted_at' => Helper::getFormattedDateObject($file->deleted_at, 'datetime'),
];
$permissions_array['available_actions'] = [
'delete' => (Gate::allows('update', AssetModel::class) && ($assetmodel->deleted_at == '')),
];
$array += $permissions_array;
return $array;
}
public function transformAssetModelsDatatable($assetmodels) public function transformAssetModelsDatatable($assetmodels)
{ {
return (new DatatablesTransformer)->transformDatatables($assetmodels); return (new DatatablesTransformer)->transformDatatables($assetmodels);

View file

@ -61,7 +61,7 @@ class DepreciationReportTransformer
/** /**
* Override the previously set null values if there is a valid model and associated depreciation * Override the previously set null values if there is a valid model and associated depreciation
*/ */
if (($asset->model) && ($asset->model->depreciation)) { if (($asset->model) && ($asset->model->depreciation) && ($asset->model->depreciation->months !== 0)) {
$depreciated_value = Helper::formatCurrencyOutput($asset->getDepreciatedValue()); $depreciated_value = Helper::formatCurrencyOutput($asset->getDepreciatedValue());
$monthly_depreciation =Helper::formatCurrencyOutput($asset->purchase_cost / $asset->model->depreciation->months); $monthly_depreciation =Helper::formatCurrencyOutput($asset->purchase_cost / $asset->model->depreciation->months);
$diff = Helper::formatCurrencyOutput(($asset->purchase_cost - $asset->getDepreciatedValue())); $diff = Helper::formatCurrencyOutput(($asset->purchase_cost - $asset->getDepreciatedValue()));

View file

@ -39,6 +39,7 @@ abstract class Importer
* @var array * @var array
*/ */
private $defaultFieldMap = [ private $defaultFieldMap = [
'id' => 'id',
'asset_tag' => 'asset tag', 'asset_tag' => 'asset tag',
'activated' => 'activated', 'activated' => 'activated',
'category' => 'category', 'category' => 'category',

View file

@ -456,14 +456,13 @@ class ItemImporter extends Importer
{ {
if (empty($asset_location)) { if (empty($asset_location)) {
$this->log('No location given, so none created.'); $this->log('No location given, so none created.');
return null; return null;
} }
$location = Location::where(['name' => $asset_location])->first(); $location = Location::where(['name' => $asset_location])->first();
if ($location) { if ($location) {
$this->log('Location '.$asset_location.' already exists'); $this->log('Location '.$asset_location.' already exists');
return $location->id; return $location->id;
} }
// No matching locations in the collection, create a new one. // No matching locations in the collection, create a new one.

View file

@ -38,8 +38,16 @@ class LocationImporter extends ItemImporter
{ {
$editingLocation = false; $editingLocation = false;
$location = Location::where('name', '=', $this->findCsvMatch($row, 'name'))->first(); $location = Location::where('name', '=', $this->findCsvMatch($row, 'name'))->first();
if ($this->findCsvMatch($row, 'id')!='') {
// Override location if an ID was given
\Log::debug('Finding location by ID: '.$this->findCsvMatch($row, 'id'));
$location = Location::find($this->findCsvMatch($row, 'id'));
}
if ($location) { if ($location) {
if (! $this->updating) { if (! $this->updating) {
$this->log('A matching Location '.$this->item['name'].' already exists'); $this->log('A matching Location '.$this->item['name'].' already exists');
@ -95,6 +103,7 @@ class LocationImporter extends ItemImporter
} else { } else {
Log::debug($location->getErrors()); Log::debug($location->getErrors());
$this->logError($location, 'Location "'.$this->item['name'].'"');
return $location->errors; return $location->errors;
} }

View file

@ -106,7 +106,13 @@ class CheckoutableListener
} }
} }
} catch (ClientException $e) { } catch (ClientException $e) {
Log::error("ClientException caught during checkin notification: " . $e->getMessage()); if (strpos($e->getMessage(), 'channel_not_found') !== false) {
Log::warning(Setting::getSettings()->webhook_selected." notification failed: " . $e->getMessage());
return redirect()->back()->with('warning', ucfirst(Setting::getSettings()->webhook_selected) .trans('admin/settings/message.webhook.webhook_channel_not_found') );
}
else {
Log::error("ClientException caught during checkin notification: " . $e->getMessage());
}
return redirect()->back()->with('warning', ucfirst(Setting::getSettings()->webhook_selected) .trans('admin/settings/message.webhook.webhook_fail') ); return redirect()->back()->with('warning', ucfirst(Setting::getSettings()->webhook_selected) .trans('admin/settings/message.webhook.webhook_fail') );
} catch (Exception $e) { } catch (Exception $e) {
Log::error(ucfirst(Setting::getSettings()->webhook_selected) . ' webhook notification failed:', [ Log::error(ucfirst(Setting::getSettings()->webhook_selected) . ' webhook notification failed:', [
@ -156,7 +162,7 @@ class CheckoutableListener
$ccEmails = array_filter($adminCcEmailsArray); $ccEmails = array_filter($adminCcEmailsArray);
$mailable = $this->getCheckinMailType($event); $mailable = $this->getCheckinMailType($event);
$notifiable = $this->getNotifiables($event); $notifiable = $this->getNotifiables($event);
if ($event->checkedOutTo->locale){ if ($event->checkedOutTo?->locale) {
$mailable->locale($event->checkedOutTo->locale); $mailable->locale($event->checkedOutTo->locale);
} }
// Send email notifications // Send email notifications
@ -196,8 +202,14 @@ class CheckoutableListener
} }
} }
} catch (ClientException $e) { } catch (ClientException $e) {
Log::error("ClientException caught during checkin notification: " . $e->getMessage()); if (strpos($e->getMessage(), 'channel_not_found') !== false) {
return redirect()->back()->with('warning', ucfirst(Setting::getSettings()->webhook_selected) .trans('admin/settings/message.webhook.webhook_fail')); Log::warning(Setting::getSettings()->webhook_selected." notification failed: " . $e->getMessage());
return redirect()->back()->with('warning', ucfirst(Setting::getSettings()->webhook_selected) .trans('admin/settings/message.webhook.webhook_channel_not_found') );
}
else {
Log::error("ClientException caught during checkin notification: " . $e->getMessage());
return redirect()->back()->with('warning', ucfirst(Setting::getSettings()->webhook_selected) . trans('admin/settings/message.webhook.webhook_fail'));
}
} catch (Exception $e) { } catch (Exception $e) {
Log::error(ucfirst(Setting::getSettings()->webhook_selected) . ' webhook notification failed:', [ Log::error(ucfirst(Setting::getSettings()->webhook_selected) . ' webhook notification failed:', [
'error' => $e->getMessage(), 'error' => $e->getMessage(),

View file

@ -17,6 +17,7 @@ use App\Events\ItemAccepted;
use App\Events\ItemDeclined; use App\Events\ItemDeclined;
use App\Events\LicenseCheckedIn; use App\Events\LicenseCheckedIn;
use App\Events\LicenseCheckedOut; use App\Events\LicenseCheckedOut;
use App\Events\NoteAdded;
use App\Models\Actionlog; use App\Models\Actionlog;
use App\Models\User; use App\Models\User;
use App\Models\LicenseSeat; use App\Models\LicenseSeat;
@ -128,6 +129,23 @@ class LogListener
} }
/**
* Note is added to action log
*
*/
public function onNoteAdded(NoteAdded $event)
{
$logaction = new Actionlog();
$logaction->item_id = $event->itemNoteAddedOn->id;
$logaction->item_type = get_class($event->itemNoteAddedOn);
$logaction->note = $event->note; //this is the received alphanumeric text from the box
$logaction->created_by = $event->noteAddedBy->id;
$logaction->action_type = 'note_added';
$logaction->save();
}
/** /**
* Register the listeners for the subscriber. * Register the listeners for the subscriber.
* *
@ -141,6 +159,7 @@ class LogListener
'CheckoutAccepted', 'CheckoutAccepted',
'CheckoutDeclined', 'CheckoutDeclined',
'UserMerged', 'UserMerged',
'NoteAdded',
]; ];
foreach ($list as $event) { foreach ($list as $event) {

View file

@ -329,6 +329,7 @@ class Importer extends Component
]; ];
$this->locations_fields = [ $this->locations_fields = [
'id' => trans('general.id'),
'name' => trans('general.item_name_var', ['item' => trans('general.location')]), 'name' => trans('general.item_name_var', ['item' => trans('general.location')]),
'address' => trans('general.address'), 'address' => trans('general.address'),
'address2' => trans('general.importer.address2'), 'address2' => trans('general.importer.address2'),
@ -400,7 +401,6 @@ class Importer extends Component
'requestable', 'requestable',
'Requestable', 'Requestable',
], ],
'gravatar' => 'gravatar' =>
[ [
'gravatar', 'gravatar',

View file

@ -159,7 +159,7 @@ class SlackSettingsForm extends Component
]); ]);
try { try {
$test = $webhook->post($this->webhook_endpoint, ['body' => $payload]); $test = $webhook->post($this->webhook_endpoint, ['body' => $payload, ['headers' => ['Content-Type' => 'application/json']]]);
if(($test->getStatusCode() == 302)||($test->getStatusCode() == 301)){ if(($test->getStatusCode() == 302)||($test->getStatusCode() == 301)){
return session()->flash('error' , trans('admin/settings/message.webhook.error_redirect', ['endpoint' => $this->webhook_endpoint])); return session()->flash('error' , trans('admin/settings/message.webhook.error_redirect', ['endpoint' => $this->webhook_endpoint]));

View file

@ -69,7 +69,7 @@ class Actionlog extends SnipeModel
'company' => ['name'], 'company' => ['name'],
'adminuser' => ['first_name','last_name','username', 'email'], 'adminuser' => ['first_name','last_name','username', 'email'],
'user' => ['first_name','last_name','username', 'email'], 'user' => ['first_name','last_name','username', 'email'],
'assets' => ['asset_tag','name'], 'assets' => ['asset_tag','name', 'serial'],
]; ];
/** /**

View file

@ -35,7 +35,7 @@ class CheckoutAcceptance extends Model
/** /**
* The resource that was is out * The resource that was is out
* *
* @return Illuminate\Database\Eloquent\Relations\MorphTo * @return \Illuminate\Database\Eloquent\Relations\MorphTo
*/ */
public function checkoutable() public function checkoutable()
{ {

View file

@ -307,7 +307,7 @@ class CustomField extends Model
public function formatFieldValuesAsArray() public function formatFieldValuesAsArray()
{ {
$result = []; $result = [];
$arr = preg_split('/\\r\\n|\\r|\\n/', $this->field_values); $arr = preg_split('/\\r\\n|\\r|\\n/', $this->field_values ?? '');
if (($this->element != 'checkbox') && ($this->element != 'radio')) { if (($this->element != 'checkbox') && ($this->element != 'radio')) {
$result[''] = 'Select '.strtolower($this->format); $result[''] = 'Select '.strtolower($this->format);

View file

@ -79,7 +79,7 @@ class CheckinAssetNotification extends Notification
$fields = [ $fields = [
trans('general.administrator') => '<'.$admin->present()->viewUrl().'|'.$admin->present()->fullName().'>', trans('general.administrator') => '<'.$admin->present()->viewUrl().'|'.$admin->present()->fullName().'>',
trans('general.status') => $item->assetstatus->name, trans('general.status') => $item->assetstatus?->name,
trans('general.location') => ($item->location) ? $item->location->name : '', trans('general.location') => ($item->location) ? $item->location->name : '',
]; ];
@ -106,9 +106,9 @@ class CheckinAssetNotification extends Notification
->title(trans('mail.Asset_Checkin_Notification')) ->title(trans('mail.Asset_Checkin_Notification'))
->addStartGroupToSection('activityText') ->addStartGroupToSection('activityText')
->fact(htmlspecialchars_decode($item->present()->name), '', 'activityText') ->fact(htmlspecialchars_decode($item->present()->name), '', 'activityText')
->fact(trans('mail.checked_into'), $item->location->name ? $item->location->name : '') ->fact(trans('mail.checked_into'), ($item->location) ? $item->location->name : '')
->fact(trans('mail.Asset_Checkin_Notification') . " by ", $admin->present()->fullName()) ->fact(trans('mail.Asset_Checkin_Notification') . " by ", $admin->present()->fullName())
->fact(trans('admin/hardware/form.status'), $item->assetstatus->name) ->fact(trans('admin/hardware/form.status'), $item->assetstatus?->name)
->fact(trans('mail.notes'), $note ?: ''); ->fact(trans('mail.notes'), $note ?: '');
} }
@ -116,9 +116,9 @@ class CheckinAssetNotification extends Notification
$message = trans('mail.Asset_Checkin_Notification'); $message = trans('mail.Asset_Checkin_Notification');
$details = [ $details = [
trans('mail.asset') => htmlspecialchars_decode($item->present()->name), trans('mail.asset') => htmlspecialchars_decode($item->present()->name),
trans('mail.checked_into') => $item->location->name ? $item->location->name : '', trans('mail.checked_into') => ($item->location) ? $item->location->name : '',
trans('mail.Asset_Checkin_Notification')." by " => $admin->present()->fullName(), trans('mail.Asset_Checkin_Notification')." by " => $admin->present()->fullName(),
trans('admin/hardware/form.status') => $item->assetstatus->name, trans('admin/hardware/form.status') => $item->assetstatus?->name,
trans('mail.notes') => $note ?: '', trans('mail.notes') => $note ?: '',
]; ];
@ -142,8 +142,8 @@ class CheckinAssetNotification extends Notification
Section::create( Section::create(
KeyValue::create( KeyValue::create(
trans('mail.checked_into') ?: '', trans('mail.checked_into') ?: '',
$item->location->name ? $item->location->name : '', ($item->location) ? $item->location->name : '',
trans('admin/hardware/form.status').": ".$item->assetstatus->name, trans('admin/hardware/form.status').": ".$item->assetstatus?->name,
) )
->onClick(route('hardware.show', $item->id)) ->onClick(route('hardware.show', $item->id))
) )

View file

@ -48,7 +48,7 @@ class AssetObserver
$changed = []; $changed = [];
foreach ($asset->getRawOriginal() as $key => $value) { foreach ($asset->getRawOriginal() as $key => $value) {
if ($asset->getRawOriginal()[$key] != $asset->getAttributes()[$key]) { if ((array_key_exists($key, $asset->getAttributes())) && ($asset->getRawOriginal()[$key] != $asset->getAttributes()[$key])) {
$changed[$key]['old'] = $asset->getRawOriginal()[$key]; $changed[$key]['old'] = $asset->getRawOriginal()[$key];
$changed[$key]['new'] = $asset->getAttributes()[$key]; $changed[$key]['new'] = $asset->getAttributes()[$key];
} }
@ -80,7 +80,7 @@ class AssetObserver
{ {
if ($settings = Setting::getSettings()) { if ($settings = Setting::getSettings()) {
$tag = $asset->asset_tag; $tag = $asset->asset_tag;
$prefix = $settings->auto_increment_prefix; $prefix = (string)($settings->auto_increment_prefix ?? '');
$number = substr($tag, strlen($prefix)); $number = substr($tag, strlen($prefix));
// IF - auto_increment_assets is on, AND (there is no prefix OR the prefix matches the start of the tag) // IF - auto_increment_assets is on, AND (there is no prefix OR the prefix matches the start of the tag)
// AND the rest of the string after the prefix is all digits, THEN... // AND the rest of the string after the prefix is all digits, THEN...

View file

@ -46,7 +46,7 @@ class ActionlogPresenter extends Presenter
return 'fa-solid fa-mobile-screen'; return 'fa-solid fa-mobile-screen';
} }
if ($this->action_type == 'create new') { if ($this->action_type == 'create') {
return 'fa-solid fa-user-plus'; return 'fa-solid fa-user-plus';
} }
@ -70,7 +70,7 @@ class ActionlogPresenter extends Presenter
} }
// Everything else // Everything else
if ($this->action_type == 'create new') { if ($this->action_type == 'create') {
return 'fa-solid fa-plus'; return 'fa-solid fa-plus';
} }
@ -98,6 +98,10 @@ class ActionlogPresenter extends Presenter
return 'fa-solid fa-rotate-right'; return 'fa-solid fa-rotate-right';
} }
if ($this->action_type == 'note_added') {
return 'fas fa-sticky-note';
}
return 'fa-solid fa-rotate-right'; return 'fa-solid fa-rotate-right';
} }

View file

@ -209,7 +209,7 @@ class Saml
} }
} }
$custom_settings = preg_split('/\r\n|\r|\n/', $setting->saml_custom_settings); $custom_settings = preg_split('/\r\n|\r|\n/', $setting->saml_custom_settings ?? '');
if ($custom_settings) { if ($custom_settings) {
foreach ($custom_settings as $custom_setting) { foreach ($custom_settings as $custom_setting) {
$split = explode('=', $custom_setting, 2); $split = explode('=', $custom_setting, 2);

View file

@ -116,12 +116,9 @@ class Label implements View
} }
} }
if ($template->getSupport2DBarcode()) { if ($template->getSupport2DBarcode()) {
$barcode2DType = $settings->label2_2d_type; $barcode2DType = $settings->label2_2d_type;
$barcode2DType = ($barcode2DType == 'default') ? if (($barcode2DType != 'none') && (!is_null($barcode2DType))) {
$settings->barcode_type :
$barcode2DType;
if (($barcode2DType != 'none') && (!is_null($barcode2DType))) {
switch ($settings->label2_2d_target) { switch ($settings->label2_2d_target) {
case 'ht_tag': case 'ht_tag':
$barcode2DTarget = route('ht/assetTag', $asset->asset_tag); $barcode2DTarget = route('ht/assetTag', $asset->asset_tag);

View file

@ -20,6 +20,7 @@
"php": "^8.1", "php": "^8.1",
"ext-curl": "*", "ext-curl": "*",
"ext-fileinfo": "*", "ext-fileinfo": "*",
"ext-iconv": "*",
"ext-json": "*", "ext-json": "*",
"ext-mbstring": "*", "ext-mbstring": "*",
"ext-pdo": "*", "ext-pdo": "*",
@ -55,6 +56,7 @@
"nunomaduro/collision": "^7.0", "nunomaduro/collision": "^7.0",
"okvpn/clock-lts": "^1.0", "okvpn/clock-lts": "^1.0",
"onelogin/php-saml": "^3.4", "onelogin/php-saml": "^3.4",
"onnov/detect-encoding": "^2.0",
"osa-eg/laravel-teams-notification": "^2.1", "osa-eg/laravel-teams-notification": "^2.1",
"paragonie/constant_time_encoding": "^2.3", "paragonie/constant_time_encoding": "^2.3",
"paragonie/sodium_compat": "^1.19", "paragonie/sodium_compat": "^1.19",

67
composer.lock generated
View file

@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically" "This file is @generated automatically"
], ],
"content-hash": "0750e3a427347b2a56a05a8b9b533d48", "content-hash": "2a6e7f5e039ee2f40605aefc5c5baf08",
"packages": [ "packages": [
{ {
"name": "alek13/slack", "name": "alek13/slack",
@ -5574,6 +5574,70 @@
], ],
"time": "2024-05-30T15:14:26+00:00" "time": "2024-05-30T15:14:26+00:00"
}, },
{
"name": "onnov/detect-encoding",
"version": "v2.0.0",
"source": {
"type": "git",
"url": "https://github.com/onnov/detect-encoding.git",
"reference": "6a8159ac3e6178ae043244b9d66a9b2701121e07"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/onnov/detect-encoding/zipball/6a8159ac3e6178ae043244b9d66a9b2701121e07",
"reference": "6a8159ac3e6178ae043244b9d66a9b2701121e07",
"shasum": ""
},
"require": {
"ext-iconv": "*",
"php": ">=7.3"
},
"require-dev": {
"infection/infection": "*",
"phpbench/phpbench": "*",
"phpcompatibility/php-compatibility": "*",
"phpmd/phpmd": "*",
"phpstan/phpstan": "*",
"phpstan/phpstan-strict-rules": "*",
"phpunit/phpunit": "*",
"roave/backward-compatibility-check": "*",
"squizlabs/php_codesniffer": "*"
},
"type": "library",
"autoload": {
"psr-4": {
"Onnov\\DetectEncoding\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "onnov",
"email": "oblnn@yandex.ru"
}
],
"description": "Text encoding definition class instead of mb_detect_encoding. Defines: utf-8, windows-1251, koi8-r, iso-8859-5, ibm866, .....",
"homepage": "https://github.com/onnov/detect-encoding",
"keywords": [
"cyrillic",
"encoding",
"ibm866",
"iconv",
"iso-8859-5",
"koi8-r",
"mb_detect_encoding",
"utf-8",
"windows-1251"
],
"support": {
"issues": "https://github.com/onnov/detect-encoding/issues",
"source": "https://github.com/onnov/detect-encoding/tree/v2.0.0"
},
"time": "2021-01-04T14:29:34+00:00"
},
{ {
"name": "osa-eg/laravel-teams-notification", "name": "osa-eg/laravel-teams-notification",
"version": "v2.1.2", "version": "v2.1.2",
@ -16570,6 +16634,7 @@
"php": "^8.1", "php": "^8.1",
"ext-curl": "*", "ext-curl": "*",
"ext-fileinfo": "*", "ext-fileinfo": "*",
"ext-iconv": "*",
"ext-json": "*", "ext-json": "*",
"ext-mbstring": "*", "ext-mbstring": "*",
"ext-pdo": "*" "ext-pdo": "*"

View file

@ -172,7 +172,7 @@ return [
| More info: https://bootstrap-table.com/docs/extensions/cookie/#cookiestorage | More info: https://bootstrap-table.com/docs/extensions/cookie/#cookiestorage
*/ */
'bs_table_storage' => env('BS_TABLE_STORAGE', 'cookieStorage'), 'bs_table_storage' => env('BS_TABLE_STORAGE', 'localStorage'),
/* /*

View file

@ -1,10 +1,10 @@
<?php <?php
return array ( return array (
'app_version' => 'v7.1.15', 'app_version' => 'v7.1.16',
'full_app_version' => 'v7.1.15 - build 16052-g25bfd3e84', 'full_app_version' => 'v7.1.16 - build 16564-gfb857ccf5',
'build_version' => '16052', 'build_version' => '16564',
'prerelease_version' => '', 'prerelease_version' => '',
'hash_version' => 'g25bfd3e84', 'hash_version' => 'gfb857ccf5',
'full_hash' => 'v7.1.15-105-g25bfd3e84', 'full_hash' => 'v7.1.16-510-gfb857ccf5',
'branch' => 'master', 'branch' => 'master',
); );

View file

@ -103,6 +103,7 @@ php artisan migrate --force
php artisan config:clear php artisan config:clear
php artisan config:cache php artisan config:cache
touch /var/www/html/storage/logs/laravel.log
chown -R apache:root /var/www/html/storage/logs/laravel.log chown -R apache:root /var/www/html/storage/logs/laravel.log
export APACHE_LOG_DIR=/var/log/apache2 export APACHE_LOG_DIR=/var/log/apache2

16
package-lock.json generated
View file

@ -15,7 +15,7 @@
"bootstrap-colorpicker": "^2.5.3", "bootstrap-colorpicker": "^2.5.3",
"bootstrap-datepicker": "^1.10.0", "bootstrap-datepicker": "^1.10.0",
"bootstrap-less": "^3.3.8", "bootstrap-less": "^3.3.8",
"bootstrap-table": "1.23.5", "bootstrap-table": "1.24.0",
"canvas-confetti": "^1.9.3", "canvas-confetti": "^1.9.3",
"chart.js": "^2.9.4", "chart.js": "^2.9.4",
"clipboard": "^2.0.11", "clipboard": "^2.0.11",
@ -31,7 +31,7 @@
"less-loader": "^6.0", "less-loader": "^6.0",
"list.js": "^1.5.0", "list.js": "^1.5.0",
"morris.js": "github:morrisjs/morris.js", "morris.js": "github:morrisjs/morris.js",
"papaparse": "5.4.1", "papaparse": "5.5.1",
"select2": "4.0.13", "select2": "4.0.13",
"sheetjs": "^2.0.0", "sheetjs": "^2.0.0",
"signature_pad": "^4.2.0", "signature_pad": "^4.2.0",
@ -3705,9 +3705,9 @@
"license": "MIT" "license": "MIT"
}, },
"node_modules/bootstrap-table": { "node_modules/bootstrap-table": {
"version": "1.23.5", "version": "1.24.0",
"resolved": "https://registry.npmjs.org/bootstrap-table/-/bootstrap-table-1.23.5.tgz", "resolved": "https://registry.npmjs.org/bootstrap-table/-/bootstrap-table-1.24.0.tgz",
"integrity": "sha512-9WByoSpJvA73gi2YYIlX6IWR74oZtBmSixul/Th8FTBtBd/kZRpbKESGTjhA3BA3AYTnfyY8Iy1KeRWPlV2GWQ==", "integrity": "sha512-dyRf5PQwTgFHj9yjuPXa+GIf4JpuQhsgD1CJrOqhw40qI2gTb3mJfRdoBc7iF2bqzOl+k0RnbAlhSPbGe4VS+w==",
"peerDependencies": { "peerDependencies": {
"jquery": "3" "jquery": "3"
} }
@ -8368,9 +8368,9 @@
"license": "(MIT AND Zlib)" "license": "(MIT AND Zlib)"
}, },
"node_modules/papaparse": { "node_modules/papaparse": {
"version": "5.4.1", "version": "5.5.1",
"resolved": "https://registry.npmjs.org/papaparse/-/papaparse-5.4.1.tgz", "resolved": "https://registry.npmjs.org/papaparse/-/papaparse-5.5.1.tgz",
"integrity": "sha512-HipMsgJkZu8br23pW15uvo6sib6wne/4woLZPlFf3rpDyMe9ywEXUsuD7+6K9PRkJlVT51j/sCOYDKGGS3ZJrw==" "integrity": "sha512-EuEKUhyxrHVozD7g3/ztsJn6qaKse8RPfR6buNB2dMJvdtXNhcw8jccVi/LxNEY3HVrV6GO6Z4OoeCG9Iy9wpA=="
}, },
"node_modules/param-case": { "node_modules/param-case": {
"version": "3.0.4", "version": "3.0.4",

View file

@ -35,7 +35,7 @@
"bootstrap-colorpicker": "^2.5.3", "bootstrap-colorpicker": "^2.5.3",
"bootstrap-datepicker": "^1.10.0", "bootstrap-datepicker": "^1.10.0",
"bootstrap-less": "^3.3.8", "bootstrap-less": "^3.3.8",
"bootstrap-table": "1.23.5", "bootstrap-table": "1.24.0",
"canvas-confetti": "^1.9.3", "canvas-confetti": "^1.9.3",
"chart.js": "^2.9.4", "chart.js": "^2.9.4",
"clipboard": "^2.0.11", "clipboard": "^2.0.11",
@ -51,7 +51,7 @@
"less-loader": "^6.0", "less-loader": "^6.0",
"list.js": "^1.5.0", "list.js": "^1.5.0",
"morris.js": "github:morrisjs/morris.js", "morris.js": "github:morrisjs/morris.js",
"papaparse": "5.4.1", "papaparse": "5.5.1",
"select2": "4.0.13", "select2": "4.0.13",
"sheetjs": "^2.0.0", "sheetjs": "^2.0.0",
"signature_pad": "^4.2.0", "signature_pad": "^4.2.0",

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
public/js/dist/all.js vendored

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -1,25 +1,25 @@
{ {
"/js/build/app.js": "/js/build/app.js?id=65d7af7b9fa7fd0e05737526a0d1d282", "/js/build/app.js": "/js/build/app.js?id=eeefb5463df4ea2a4cbae72c96006e10",
"/css/dist/skins/skin-black-dark.css": "/css/dist/skins/skin-black-dark.css?id=06c13e817cc022028b3f4a33c0ca303a", "/css/dist/skins/skin-black-dark.css": "/css/dist/skins/skin-black-dark.css?id=d34ae2483cbe2c77478c45f4006eba55",
"/css/dist/skins/_all-skins.css": "/css/dist/skins/_all-skins.css?id=e71ef4171dee5da63af390966ac60ffc", "/css/dist/skins/_all-skins.css": "/css/dist/skins/_all-skins.css?id=b1c78591f51b52beab05b52f407ad6e6",
"/css/build/overrides.css": "/css/build/overrides.css?id=776ca1fc6f89c40adc7050439f107f50", "/css/build/overrides.css": "/css/build/overrides.css?id=4f85f2e6fd839b8812dd68d001aae4a3",
"/css/build/app.css": "/css/build/app.css?id=81072cf10a543742f928390c9a40791d", "/css/build/app.css": "/css/build/app.css?id=50f697122a35791df98a58bcf0665220",
"/css/build/AdminLTE.css": "/css/build/AdminLTE.css?id=4ea0068716c1bb2434d87a16d51b98c9", "/css/build/AdminLTE.css": "/css/build/AdminLTE.css?id=a67bd93bed52e6a29967fe472de66d6c",
"/css/dist/skins/skin-yellow.css": "/css/dist/skins/skin-yellow.css?id=7b315b9612b8fde8f9c5b0ddb6bba690", "/css/dist/skins/skin-yellow.css": "/css/dist/skins/skin-yellow.css?id=fc7adb943668ac69fe4b646625a7571f",
"/css/dist/skins/skin-yellow-dark.css": "/css/dist/skins/skin-yellow-dark.css?id=ea22079836a432d7f46a5d390c445e13", "/css/dist/skins/skin-yellow-dark.css": "/css/dist/skins/skin-yellow-dark.css?id=53edc92eb2d272744bc7404ec259930e",
"/css/dist/skins/skin-red.css": "/css/dist/skins/skin-red.css?id=44bf834f2110504a793dadec132a5898", "/css/dist/skins/skin-red.css": "/css/dist/skins/skin-red.css?id=b9a74ec0cd68f83e7480d5ae39919beb",
"/css/dist/skins/skin-red-dark.css": "/css/dist/skins/skin-red-dark.css?id=05cc02539441b717012c4efc3303192f", "/css/dist/skins/skin-red-dark.css": "/css/dist/skins/skin-red-dark.css?id=cdbb4f543fb448f03617c7ed9d2cbec3",
"/css/dist/skins/skin-purple.css": "/css/dist/skins/skin-purple.css?id=6fe68325d5356197672c27bc77cedcb4", "/css/dist/skins/skin-purple.css": "/css/dist/skins/skin-purple.css?id=cf6c8c340420724b02d6e787ef9bded5",
"/css/dist/skins/skin-purple-dark.css": "/css/dist/skins/skin-purple-dark.css?id=fca90dff303e17dc2991ca395c7f7fa8", "/css/dist/skins/skin-purple-dark.css": "/css/dist/skins/skin-purple-dark.css?id=cfa51820f16533fd62b3c3d720e368ec",
"/css/dist/skins/skin-orange.css": "/css/dist/skins/skin-orange.css?id=6f0563e726c2fe4fab4026daaa5bfdf2", "/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=71b7731f7ae692eada36b9b08a2e04a9", "/css/dist/skins/skin-orange-dark.css": "/css/dist/skins/skin-orange-dark.css?id=98bd6927e46418c642fdd33fe56f4f26",
"/css/dist/skins/skin-green.css": "/css/dist/skins/skin-green.css?id=0a82a6ae6bb4e58fe62d162c4fb50397", "/css/dist/skins/skin-green.css": "/css/dist/skins/skin-green.css?id=b48f4d8af0e1ca5621c161e93951109f",
"/css/dist/skins/skin-green-dark.css": "/css/dist/skins/skin-green-dark.css?id=bb302302d9566adf783a2b7dc31e840c", "/css/dist/skins/skin-green-dark.css": "/css/dist/skins/skin-green-dark.css?id=16dc04eb54142bd3c32c2768d365d988",
"/css/dist/skins/skin-contrast.css": "/css/dist/skins/skin-contrast.css?id=da6c7997d9de2f8329142399f0ce50da", "/css/dist/skins/skin-contrast.css": "/css/dist/skins/skin-contrast.css?id=f0fbbb0ac729ea092578fb05ca615460",
"/css/dist/skins/skin-blue.css": "/css/dist/skins/skin-blue.css?id=f677207c6cf9678eb539abecb408c374", "/css/dist/skins/skin-blue.css": "/css/dist/skins/skin-blue.css?id=392cc93cfc0be0349bab9697669dd091",
"/css/dist/skins/skin-blue-dark.css": "/css/dist/skins/skin-blue-dark.css?id=6ea836d8126de101081c49abbdb89417", "/css/dist/skins/skin-blue-dark.css": "/css/dist/skins/skin-blue-dark.css?id=18787b3f00a3be7be38ee4e26cbd2a07",
"/css/dist/skins/skin-black.css": "/css/dist/skins/skin-black.css?id=76482123f6c70e866d6b971ba91de7bb", "/css/dist/skins/skin-black.css": "/css/dist/skins/skin-black.css?id=1f33ca3d860461c1127ec465ab3ebb6b",
"/css/dist/all.css": "/css/dist/all.css?id=7ecc2067a5edde786df1acd2775ba035", "/css/dist/all.css": "/css/dist/all.css?id=baad37c1b095168a326c5bb16b0feb38",
"/css/dist/signature-pad.css": "/css/dist/signature-pad.css?id=6a89d3cd901305e66ced1cf5f13147f7", "/css/dist/signature-pad.css": "/css/dist/signature-pad.css?id=6a89d3cd901305e66ced1cf5f13147f7",
"/css/dist/signature-pad.min.css": "/css/dist/signature-pad.min.css?id=6a89d3cd901305e66ced1cf5f13147f7", "/css/dist/signature-pad.min.css": "/css/dist/signature-pad.min.css?id=6a89d3cd901305e66ced1cf5f13147f7",
"/js/select2/i18n/af.js": "/js/select2/i18n/af.js?id=4f6fcd73488ce79fae1b7a90aceaecde", "/js/select2/i18n/af.js": "/js/select2/i18n/af.js?id=4f6fcd73488ce79fae1b7a90aceaecde",
@ -90,26 +90,26 @@
"/css/webfonts/fa-solid-900.woff2": "/css/webfonts/fa-solid-900.woff2?id=109ad919b74a62a8a223361da1651bbc", "/css/webfonts/fa-solid-900.woff2": "/css/webfonts/fa-solid-900.woff2?id=109ad919b74a62a8a223361da1651bbc",
"/css/webfonts/fa-v4compatibility.ttf": "/css/webfonts/fa-v4compatibility.ttf?id=53c2e50ef821f7b8dd514611d5e0772c", "/css/webfonts/fa-v4compatibility.ttf": "/css/webfonts/fa-v4compatibility.ttf?id=53c2e50ef821f7b8dd514611d5e0772c",
"/css/webfonts/fa-v4compatibility.woff2": "/css/webfonts/fa-v4compatibility.woff2?id=331c85bd61ffa93af09273d1bc2add5a", "/css/webfonts/fa-v4compatibility.woff2": "/css/webfonts/fa-v4compatibility.woff2?id=331c85bd61ffa93af09273d1bc2add5a",
"/js/dist/bootstrap-table-locale-all.min.js": "/js/dist/bootstrap-table-locale-all.min.js?id=c5445e15be5ce91a9ffef05e08ad6898", "/js/dist/bootstrap-table-locale-all.min.js": "/js/dist/bootstrap-table-locale-all.min.js?id=02dfc50d5b951dc6d260bd508968d319",
"/js/dist/bootstrap-table-en-US.min.js": "/js/dist/bootstrap-table-en-US.min.js?id=0f6e85ae692d03a3b11cab445ff263ab", "/js/dist/bootstrap-table-en-US.min.js": "/js/dist/bootstrap-table-en-US.min.js?id=1c350eabf064c309f67d6779e5cc4afa",
"/css/dist/skins/_all-skins.min.css": "/css/dist/skins/_all-skins.min.css?id=e71ef4171dee5da63af390966ac60ffc", "/css/dist/skins/_all-skins.min.css": "/css/dist/skins/_all-skins.min.css?id=b1c78591f51b52beab05b52f407ad6e6",
"/css/dist/skins/skin-black-dark.min.css": "/css/dist/skins/skin-black-dark.min.css?id=06c13e817cc022028b3f4a33c0ca303a", "/css/dist/skins/skin-black-dark.min.css": "/css/dist/skins/skin-black-dark.min.css?id=d34ae2483cbe2c77478c45f4006eba55",
"/css/dist/skins/skin-black.min.css": "/css/dist/skins/skin-black.min.css?id=76482123f6c70e866d6b971ba91de7bb", "/css/dist/skins/skin-black.min.css": "/css/dist/skins/skin-black.min.css?id=1f33ca3d860461c1127ec465ab3ebb6b",
"/css/dist/skins/skin-blue-dark.min.css": "/css/dist/skins/skin-blue-dark.min.css?id=6ea836d8126de101081c49abbdb89417", "/css/dist/skins/skin-blue-dark.min.css": "/css/dist/skins/skin-blue-dark.min.css?id=18787b3f00a3be7be38ee4e26cbd2a07",
"/css/dist/skins/skin-blue.min.css": "/css/dist/skins/skin-blue.min.css?id=f677207c6cf9678eb539abecb408c374", "/css/dist/skins/skin-blue.min.css": "/css/dist/skins/skin-blue.min.css?id=392cc93cfc0be0349bab9697669dd091",
"/css/dist/skins/skin-contrast.min.css": "/css/dist/skins/skin-contrast.min.css?id=da6c7997d9de2f8329142399f0ce50da", "/css/dist/skins/skin-contrast.min.css": "/css/dist/skins/skin-contrast.min.css?id=f0fbbb0ac729ea092578fb05ca615460",
"/css/dist/skins/skin-green-dark.min.css": "/css/dist/skins/skin-green-dark.min.css?id=bb302302d9566adf783a2b7dc31e840c", "/css/dist/skins/skin-green-dark.min.css": "/css/dist/skins/skin-green-dark.min.css?id=16dc04eb54142bd3c32c2768d365d988",
"/css/dist/skins/skin-green.min.css": "/css/dist/skins/skin-green.min.css?id=0a82a6ae6bb4e58fe62d162c4fb50397", "/css/dist/skins/skin-green.min.css": "/css/dist/skins/skin-green.min.css?id=b48f4d8af0e1ca5621c161e93951109f",
"/css/dist/skins/skin-orange-dark.min.css": "/css/dist/skins/skin-orange-dark.min.css?id=71b7731f7ae692eada36b9b08a2e04a9", "/css/dist/skins/skin-orange-dark.min.css": "/css/dist/skins/skin-orange-dark.min.css?id=98bd6927e46418c642fdd33fe56f4f26",
"/css/dist/skins/skin-orange.min.css": "/css/dist/skins/skin-orange.min.css?id=6f0563e726c2fe4fab4026daaa5bfdf2", "/css/dist/skins/skin-orange.min.css": "/css/dist/skins/skin-orange.min.css?id=268041e902b019730c23ee3875838005",
"/css/dist/skins/skin-purple-dark.min.css": "/css/dist/skins/skin-purple-dark.min.css?id=fca90dff303e17dc2991ca395c7f7fa8", "/css/dist/skins/skin-purple-dark.min.css": "/css/dist/skins/skin-purple-dark.min.css?id=cfa51820f16533fd62b3c3d720e368ec",
"/css/dist/skins/skin-purple.min.css": "/css/dist/skins/skin-purple.min.css?id=6fe68325d5356197672c27bc77cedcb4", "/css/dist/skins/skin-purple.min.css": "/css/dist/skins/skin-purple.min.css?id=cf6c8c340420724b02d6e787ef9bded5",
"/css/dist/skins/skin-red-dark.min.css": "/css/dist/skins/skin-red-dark.min.css?id=05cc02539441b717012c4efc3303192f", "/css/dist/skins/skin-red-dark.min.css": "/css/dist/skins/skin-red-dark.min.css?id=cdbb4f543fb448f03617c7ed9d2cbec3",
"/css/dist/skins/skin-red.min.css": "/css/dist/skins/skin-red.min.css?id=44bf834f2110504a793dadec132a5898", "/css/dist/skins/skin-red.min.css": "/css/dist/skins/skin-red.min.css?id=b9a74ec0cd68f83e7480d5ae39919beb",
"/css/dist/skins/skin-yellow-dark.min.css": "/css/dist/skins/skin-yellow-dark.min.css?id=ea22079836a432d7f46a5d390c445e13", "/css/dist/skins/skin-yellow-dark.min.css": "/css/dist/skins/skin-yellow-dark.min.css?id=53edc92eb2d272744bc7404ec259930e",
"/css/dist/skins/skin-yellow.min.css": "/css/dist/skins/skin-yellow.min.css?id=7b315b9612b8fde8f9c5b0ddb6bba690", "/css/dist/skins/skin-yellow.min.css": "/css/dist/skins/skin-yellow.min.css?id=fc7adb943668ac69fe4b646625a7571f",
"/css/dist/bootstrap-table.css": "/css/dist/bootstrap-table.css?id=c384582a6ba08903af353be861ffe74e", "/css/dist/bootstrap-table.css": "/css/dist/bootstrap-table.css?id=ceded08e0cc745a83c13647035b03406",
"/js/build/vendor.js": "/js/build/vendor.js?id=89dffa552c6e3abe3a2aac6c9c7b466b", "/js/build/vendor.js": "/js/build/vendor.js?id=89dffa552c6e3abe3a2aac6c9c7b466b",
"/js/dist/bootstrap-table.js": "/js/dist/bootstrap-table.js?id=b4c3069f1a292527a96c058b77b28d69", "/js/dist/bootstrap-table.js": "/js/dist/bootstrap-table.js?id=61285c8ac5ea7b46002ea8c451c94e60",
"/js/dist/all.js": "/js/dist/all.js?id=21e041dec60e0785db6d64961b13a9b0" "/js/dist/all.js": "/js/dist/all.js?id=ba1c5e26a7d391ad40d699be7bea633e"
} }

View file

@ -28,7 +28,7 @@ $(function () {
var baseUrl = $('meta[name="baseUrl"]').attr('content'); var baseUrl = $('meta[name="baseUrl"]').attr('content');
//handle modal-add-interstitial calls //handle modal-add-interstitial calls
var model, select, refreshSelector; var model, select, refreshSelector, hasnopayload;
if($('#createModal').length == 0) { if($('#createModal').length == 0) {
$('body').append('<div class="modal fade" id="createModal"></div><!-- /.modal -->'); $('body').append('<div class="modal fade" id="createModal"></div><!-- /.modal -->');
@ -40,6 +40,7 @@ $(function () {
select = link.data("select"); select = link.data("select");
refreshSelector = link.data("refresh"); refreshSelector = link.data("refresh");
hasnopayload = link.data("hasnopayload");
$('#createModal').load(link.attr('href'),function () { $('#createModal').load(link.attr('href'),function () {
@ -122,11 +123,13 @@ $(function () {
$('#modal_error_msg').html(error_message).show(); $('#modal_error_msg').html(error_message).show();
return false; return false;
} }
var id = result.payload.id; if(!hasnopayload) {
var name = result.payload.name || (result.payload.first_name + " " + result.payload.last_name); var id = result.payload.id;
if(!id || !name) { var name = result.payload.name || (result.payload.first_name + " " + result.payload.last_name);
console.error("Could not find resulting name or ID from modal-create. Name: "+name+", id: "+id); if (!id || !name) {
return false; console.error("Could not find resulting name or ID from modal-create. Name: " + name + ", id: " + id);
return false;
}
} }
$('#createModal').modal('hide'); $('#createModal').modal('hide');
$('#createModal').html(""); $('#createModal').html("");

View file

@ -1159,3 +1159,8 @@ input[type="radio"]:checked::before {
filter: brightness(70%); filter: brightness(70%);
font-size: 70%; font-size: 70%;
} }
/** this is needed to override ekko-lightboxes card view styles **/
.bootstrap-table .fixed-table-container .table tbody tr .card-view {
display: table-row !important;
}

View file

@ -70,7 +70,6 @@ return [
'footer_text' => 'crwdns1987:0crwdne1987:0', 'footer_text' => 'crwdns1987:0crwdne1987:0',
'footer_text_help' => 'crwdns1988:0crwdne1988:0', 'footer_text_help' => 'crwdns1988:0crwdne1988:0',
'general_settings' => 'crwdns1297:0crwdne1297:0', 'general_settings' => 'crwdns1297:0crwdne1297:0',
'general_settings_keywords' => 'crwdns12084:0crwdne12084:0',
'general_settings_help' => 'crwdns6341:0crwdne6341:0', 'general_settings_help' => 'crwdns6341:0crwdne6341:0',
'generate_backup' => 'crwdns1427:0crwdne1427:0', 'generate_backup' => 'crwdns1427:0crwdne1427:0',
'google_workspaces' => 'crwdns12080:0crwdne12080:0', 'google_workspaces' => 'crwdns12080:0crwdne12080:0',
@ -154,7 +153,6 @@ return [
'php' => 'crwdns1120:0crwdne1120:0', 'php' => 'crwdns1120:0crwdne1120:0',
'php_info' => 'crwdns12298:0crwdne12298:0', 'php_info' => 'crwdns12298:0crwdne12298:0',
'php_overview' => 'crwdns6367:0crwdne6367:0', 'php_overview' => 'crwdns6367:0crwdne6367:0',
'php_overview_keywords' => 'crwdns6369:0crwdne6369:0',
'php_overview_help' => 'crwdns6371:0crwdne6371:0', 'php_overview_help' => 'crwdns6371:0crwdne6371:0',
'php_gd_info' => 'crwdns833:0crwdne833:0', 'php_gd_info' => 'crwdns833:0crwdne833:0',
'php_gd_warning' => 'crwdns834:0crwdne834:0', 'php_gd_warning' => 'crwdns834:0crwdne834:0',
@ -231,7 +229,6 @@ return [
'update' => 'crwdns840:0crwdne840:0', 'update' => 'crwdns840:0crwdne840:0',
'value' => 'crwdns841:0crwdne841:0', 'value' => 'crwdns841:0crwdne841:0',
'brand' => 'crwdns1433:0crwdne1433:0', 'brand' => 'crwdns1433:0crwdne1433:0',
'brand_keywords' => 'crwdns6397:0crwdne6397:0',
'brand_help' => 'crwdns6399:0crwdne6399:0', 'brand_help' => 'crwdns6399:0crwdne6399:0',
'web_brand' => 'crwdns5916:0crwdne5916:0', 'web_brand' => 'crwdns5916:0crwdne5916:0',
'about_settings_title' => 'crwdns1434:0crwdne1434:0', 'about_settings_title' => 'crwdns1434:0crwdne1434:0',
@ -319,21 +316,17 @@ return [
'filter_by_keyword' => 'crwdns6431:0crwdne6431:0', 'filter_by_keyword' => 'crwdns6431:0crwdne6431:0',
'security' => 'crwdns6433:0crwdne6433:0', 'security' => 'crwdns6433:0crwdne6433:0',
'security_title' => 'crwdns6435:0crwdne6435:0', 'security_title' => 'crwdns6435:0crwdne6435:0',
'security_keywords' => 'crwdns6437:0crwdne6437:0',
'security_help' => 'crwdns6439:0crwdne6439:0', 'security_help' => 'crwdns6439:0crwdne6439:0',
'groups_keywords' => 'crwdns6441:0crwdne6441:0',
'groups_help' => 'crwdns6443:0crwdne6443:0', 'groups_help' => 'crwdns6443:0crwdne6443:0',
'localization' => 'crwdns6445:0crwdne6445:0', 'localization' => 'crwdns6445:0crwdne6445:0',
'localization_title' => 'crwdns6447:0crwdne6447:0', 'localization_title' => 'crwdns6447:0crwdne6447:0',
'localization_keywords' => 'crwdns6449:0crwdne6449:0',
'localization_help' => 'crwdns6451:0crwdne6451:0', 'localization_help' => 'crwdns6451:0crwdne6451:0',
'notifications' => 'crwdns6453:0crwdne6453:0', 'notifications' => 'crwdns6453:0crwdne6453:0',
'notifications_help' => 'crwdns11363:0crwdne11363:0', 'notifications_help' => 'crwdns11363:0crwdne11363:0',
'asset_tags_help' => 'crwdns6457:0crwdne6457:0', 'asset_tags_help' => 'crwdns6457:0crwdne6457:0',
'labels' => 'crwdns6459:0crwdne6459:0', 'labels' => 'crwdns6459:0crwdne6459:0',
'labels_title' => 'crwdns6461:0crwdne6461:0', 'labels_title' => 'crwdns6461:0crwdne6461:0',
'labels_help' => 'crwdns6463:0crwdne6463:0', 'labels_help' => 'crwdns12840:0crwdne12840:0',
'purge_keywords' => 'crwdns6467:0crwdne6467:0',
'purge_help' => 'crwdns6469:0crwdne6469:0', 'purge_help' => 'crwdns6469:0crwdne6469:0',
'ldap_extension_warning' => 'crwdns6471:0crwdne6471:0', 'ldap_extension_warning' => 'crwdns6471:0crwdne6471:0',
'ldap_ad' => 'crwdns6473:0crwdne6473:0', 'ldap_ad' => 'crwdns6473:0crwdne6473:0',
@ -362,12 +355,14 @@ return [
'label2_2d_type' => 'crwdns11745:0crwdne11745:0', 'label2_2d_type' => 'crwdns11745:0crwdne11745:0',
'label2_2d_type_help' => 'crwdns11747:0crwdne11747:0', 'label2_2d_type_help' => 'crwdns11747:0crwdne11747:0',
'label2_2d_target' => 'crwdns11749:0crwdne11749:0', 'label2_2d_target' => 'crwdns11749:0crwdne11749:0',
'label2_2d_target_help' => 'crwdns11751:0crwdne11751:0', 'label2_2d_target_help' => 'crwdns12832:0crwdne12832:0',
'label2_fields' => 'crwdns11753:0crwdne11753:0', 'label2_fields' => 'crwdns11753:0crwdne11753:0',
'label2_fields_help' => 'crwdns11755:0crwdne11755:0', 'label2_fields_help' => 'crwdns11755:0crwdne11755:0',
'help_asterisk_bold' => 'crwdns11757:0crwdne11757:0', 'help_asterisk_bold' => 'crwdns11757:0crwdne11757:0',
'help_blank_to_use' => 'crwdns11759:0crwdne11759:0', 'help_blank_to_use' => 'crwdns11759:0crwdne11759:0',
'help_default_will_use' => 'crwdns12828:0crwdne12828:0', 'help_default_will_use' => 'crwdns12834:0crwdne12834:0',
'asset_id' => 'crwdns12836:0crwdne12836:0',
'data' => 'crwdns12838:0crwdne12838:0',
'default' => 'crwdns11763:0crwdne11763:0', 'default' => 'crwdns11763:0crwdne11763:0',
'none' => 'crwdns11765:0crwdne11765:0', 'none' => 'crwdns11765:0crwdne11765:0',
'google_callback_help' => 'crwdns11615:0crwdne11615:0', 'google_callback_help' => 'crwdns11615:0crwdne11615:0',
@ -389,4 +384,17 @@ return [
'due_checkin_days_help' => 'crwdns12682:0crwdne12682:0', 'due_checkin_days_help' => 'crwdns12682:0crwdne12682:0',
'no_groups' => 'crwdns12760:0crwdne12760:0', 'no_groups' => 'crwdns12760:0crwdne12760:0',
/* Keywords for settings overview help */
'keywords' => [
'brand' => 'crwdns12842:0crwdne12842:0',
'general_settings' => 'crwdns12844:0crwdne12844:0',
'groups' => 'crwdns12846:0crwdne12846:0',
'labels' => 'crwdns12848:0crwdne12848:0',
'localization' => 'crwdns12850:0crwdne12850:0',
'php_overview' => 'crwdns12852:0crwdne12852:0',
'purge' => 'crwdns12854:0crwdne12854:0',
'security' => 'crwdns12856:0crwdne12856:0',
],
]; ];

View file

@ -45,5 +45,6 @@ return [
'error' => 'crwdns11381:0crwdne11381:0', 'error' => 'crwdns11381:0crwdne11381:0',
'error_redirect' => 'crwdns11843:0crwdne11843:0', 'error_redirect' => 'crwdns11843:0crwdne11843:0',
'error_misc' => 'crwdns11383:0crwdne11383:0', 'error_misc' => 'crwdns11383:0crwdne11383:0',
'webhook_fail' => 'crwdns12830:0crwdne12830:0',
] ]
]; ];

View file

@ -216,6 +216,12 @@ return [
'no_results' => 'crwdns1074:0crwdne1074:0', 'no_results' => 'crwdns1074:0crwdne1074:0',
'no' => 'crwdns1075:0crwdne1075:0', 'no' => 'crwdns1075:0crwdne1075:0',
'notes' => 'crwdns1076:0crwdne1076:0', 'notes' => 'crwdns1076:0crwdne1076:0',
'note_added' => 'crwdns12858:0crwdne12858:0',
'add_note' => 'crwdns12860:0crwdne12860:0',
'note_edited' => 'crwdns12862:0crwdne12862:0',
'edit_note' => 'crwdns12864:0crwdne12864:0',
'note_deleted' => 'crwdns12866:0crwdne12866:0',
'delete_note' => 'crwdns12868:0crwdne12868:0',
'order_number' => 'crwdns1829:0crwdne1829:0', 'order_number' => 'crwdns1829:0crwdne1829:0',
'only_deleted' => 'crwdns10520:0crwdne10520:0', 'only_deleted' => 'crwdns10520:0crwdne10520:0',
'page_menu' => 'crwdns1276:0crwdne1276:0', 'page_menu' => 'crwdns1276:0crwdne1276:0',
@ -566,5 +572,8 @@ return [
'import_asset_tag_exists' => 'crwdns12692:0crwdne12692:0', 'import_asset_tag_exists' => 'crwdns12692:0crwdne12692:0',
'countries_manually_entered_help' => 'crwdns12702:0crwdne12702:0', 'countries_manually_entered_help' => 'crwdns12702:0crwdne12702:0',
'accessories_assigned' => 'crwdns12800:0crwdne12800:0', 'accessories_assigned' => 'crwdns12800:0crwdne12800:0',
'user_managed_passwords' => 'crwdns12870:0crwdne12870:0',
'user_managed_passwords_disallow' => 'crwdns12872:0crwdne12872:0',
'user_managed_passwords_allow' => 'crwdns12874:0crwdne12874:0',
]; ];

View file

@ -70,7 +70,6 @@ return [
'footer_text' => 'Additional Footer Text ', 'footer_text' => 'Additional Footer Text ',
'footer_text_help' => 'This text will appear in the right-side footer. Links are allowed using <a href="https://help.github.com/articles/github-flavored-markdown/">Github flavored markdown</a>. Line breaks, headers, images, etc may result in unpredictable results.', 'footer_text_help' => 'This text will appear in the right-side footer. Links are allowed using <a href="https://help.github.com/articles/github-flavored-markdown/">Github flavored markdown</a>. Line breaks, headers, images, etc may result in unpredictable results.',
'general_settings' => 'Algemene instellings', 'general_settings' => 'Algemene instellings',
'general_settings_keywords' => 'company support, signature, acceptance, email format, username format, images, per page, thumbnail, eula, gravatar, tos, dashboard, privacy',
'general_settings_help' => 'Default EULA and more', 'general_settings_help' => 'Default EULA and more',
'generate_backup' => 'Genereer rugsteun', 'generate_backup' => 'Genereer rugsteun',
'google_workspaces' => 'Google Workspaces', 'google_workspaces' => 'Google Workspaces',
@ -154,7 +153,6 @@ return [
'php' => 'PHP weergawe', 'php' => 'PHP weergawe',
'php_info' => 'PHP info', 'php_info' => 'PHP info',
'php_overview' => 'PHP', 'php_overview' => 'PHP',
'php_overview_keywords' => 'phpinfo, system, info',
'php_overview_help' => 'PHP System info', 'php_overview_help' => 'PHP System info',
'php_gd_info' => 'Jy moet php-gd installeer om QR-kodes te vertoon, sien installeringsinstruksies.', 'php_gd_info' => 'Jy moet php-gd installeer om QR-kodes te vertoon, sien installeringsinstruksies.',
'php_gd_warning' => 'PHP Image Processing en GD plugin is NIE geïnstalleer nie.', 'php_gd_warning' => 'PHP Image Processing en GD plugin is NIE geïnstalleer nie.',
@ -231,7 +229,6 @@ return [
'update' => 'Opdateer instellings', 'update' => 'Opdateer instellings',
'value' => 'waarde', 'value' => 'waarde',
'brand' => 'Handelsmerk', 'brand' => 'Handelsmerk',
'brand_keywords' => 'footer, logo, print, theme, skin, header, colors, color, css',
'brand_help' => 'Logo, Site Name', 'brand_help' => 'Logo, Site Name',
'web_brand' => 'Web Branding Type', 'web_brand' => 'Web Branding Type',
'about_settings_title' => 'Oor instellings', 'about_settings_title' => 'Oor instellings',
@ -319,21 +316,17 @@ return [
'filter_by_keyword' => 'Filter by setting keyword', 'filter_by_keyword' => 'Filter by setting keyword',
'security' => 'Security', 'security' => 'Security',
'security_title' => 'Update Security Settings', 'security_title' => 'Update Security Settings',
'security_keywords' => 'password, passwords, requirements, two factor, two-factor, common passwords, remote login, logout, authentication',
'security_help' => 'Two-factor, Password Restrictions', 'security_help' => 'Two-factor, Password Restrictions',
'groups_keywords' => 'permissions, permission groups, authorization',
'groups_help' => 'Account permission groups', 'groups_help' => 'Account permission groups',
'localization' => 'Localization', 'localization' => 'Localization',
'localization_title' => 'Update Localization Settings', 'localization_title' => 'Update Localization Settings',
'localization_keywords' => 'localization, currency, local, locale, time zone, timezone, international, internatinalization, language, languages, translation',
'localization_help' => 'Language, date display', 'localization_help' => 'Language, date display',
'notifications' => 'Notifications', 'notifications' => 'Notifications',
'notifications_help' => 'Email Alerts & Audit Settings', 'notifications_help' => 'Email Alerts & Audit Settings',
'asset_tags_help' => 'Incrementing and prefixes', 'asset_tags_help' => 'Incrementing and prefixes',
'labels' => 'Labels', 'labels' => 'Labels',
'labels_title' => 'Update Label Settings', 'labels_title' => 'Update Label Settings',
'labels_help' => 'Label sizes &amp; settings', 'labels_help' => 'Barcodes &amp; label settings',
'purge_keywords' => 'permanently delete',
'purge_help' => 'Verwyder verwyderde rekords', 'purge_help' => 'Verwyder verwyderde rekords',
'ldap_extension_warning' => 'It does not look like the LDAP extension is installed or enabled on this server. You can still save your settings, but you will need to enable the LDAP extension for PHP before LDAP syncing or login will work.', 'ldap_extension_warning' => 'It does not look like the LDAP extension is installed or enabled on this server. You can still save your settings, but you will need to enable the LDAP extension for PHP before LDAP syncing or login will work.',
'ldap_ad' => 'LDAP/AD', 'ldap_ad' => 'LDAP/AD',
@ -362,12 +355,14 @@ return [
'label2_2d_type' => '2D Barcode Type', 'label2_2d_type' => '2D Barcode Type',
'label2_2d_type_help' => 'Format for 2D barcodes', 'label2_2d_type_help' => 'Format for 2D barcodes',
'label2_2d_target' => '2D Barcode Target', 'label2_2d_target' => '2D Barcode Target',
'label2_2d_target_help' => 'The URL the 2D barcode points to when scanned', 'label2_2d_target_help' => 'The data that will be contained in the 2D barcode',
'label2_fields' => 'Field Definitions', 'label2_fields' => 'Field Definitions',
'label2_fields_help' => 'Fields can be added, removed, and reordered in the left column. For each field, multiple options for Label and DataSource can be added, removed, and reordered in the right column.', 'label2_fields_help' => 'Fields can be added, removed, and reordered in the left column. For each field, multiple options for Label and DataSource can be added, removed, and reordered in the right column.',
'help_asterisk_bold' => 'Text entered as <code>**text**</code> will be displayed as bold', 'help_asterisk_bold' => 'Text entered as <code>**text**</code> will be displayed as bold',
'help_blank_to_use' => 'Leave blank to use the value from <code>:setting_name</code>', 'help_blank_to_use' => 'Leave blank to use the value from <code>:setting_name</code>',
'help_default_will_use' => '<br>Note that the value of the barcodes must comply with the respective barcode spec in order to be successfully generated. Please see <a href="https://snipe-it.readme.io/docs/barcodes">the documentation <i class="fa fa-external-link"></i></a> for more details. ', 'help_default_will_use' => '<code>:default</code> will use the value from <code>:setting_name</code>. <br>Note that the value of the barcodes must comply with the respective barcode spec in order to be successfully generated. Please see <a href="https://snipe-it.readme.io/docs/barcodes">the documentation <i class="fa fa-external-link"></i></a> for more details. ',
'asset_id' => 'Asset ID',
'data' => 'Data',
'default' => 'Default', 'default' => 'Default',
'none' => 'None', 'none' => 'None',
'google_callback_help' => 'This should be entered as the callback URL in your Google OAuth app settings in your organization&apos;s <strong><a href="https://console.cloud.google.com/" target="_blank">Google developer console <i class="fa fa-external-link" aria-hidden="true"></i></a></strong>.', 'google_callback_help' => 'This should be entered as the callback URL in your Google OAuth app settings in your organization&apos;s <strong><a href="https://console.cloud.google.com/" target="_blank">Google developer console <i class="fa fa-external-link" aria-hidden="true"></i></a></strong>.',
@ -389,4 +384,17 @@ return [
'due_checkin_days_help' => 'How many days before the expected checkin of an asset should it be listed in the "Due for checkin" page?', 'due_checkin_days_help' => 'How many days before the expected checkin of an asset should it be listed in the "Due for checkin" page?',
'no_groups' => 'No groups have been created yet. Visit <code>Admin Settings > Permission Groups</code> to add one.', 'no_groups' => 'No groups have been created yet. Visit <code>Admin Settings > Permission Groups</code> to add one.',
/* Keywords for settings overview help */
'keywords' => [
'brand' => 'footer, logo, print, theme, skin, header, colors, color, css',
'general_settings' => 'company support, signature, acceptance, email format, username format, images, per page, thumbnail, eula, gravatar, tos, dashboard, privacy',
'groups' => 'permissions, permission groups, authorization',
'labels' => 'labels, barcodes, barcode, sheets, print, upc, qr, 1d, 2d',
'localization' => 'localization, currency, local, locale, time zone, timezone, international, internatinalization, language, languages, translation',
'php_overview' => 'phpinfo, system, info',
'purge' => 'permanently delete',
'security' => 'password, passwords, requirements, two factor, two-factor, common passwords, remote login, logout, authentication',
],
]; ];

View file

@ -45,5 +45,6 @@ return [
'error' => 'Something went wrong. :app responded with: :error_message', 'error' => 'Something went wrong. :app responded with: :error_message',
'error_redirect' => 'ERROR: 301/302 :endpoint returns a redirect. For security reasons, we dont follow redirects. Please use the actual endpoint.', 'error_redirect' => 'ERROR: 301/302 :endpoint returns a redirect. For security reasons, we dont follow redirects. Please use the actual endpoint.',
'error_misc' => 'Something went wrong. :( ', 'error_misc' => 'Something went wrong. :( ',
'webhook_fail' => ' webhook notification failed: Check to make sure the URL is still valid.',
] ]
]; ];

Some files were not shown because too many files have changed in this diff Show more