snipe-it/app/Http/Transformers/ActionlogsTransformer.php

351 lines
17 KiB
PHP
Raw Normal View History

2017-05-23 14:31:04 -07:00
<?php
namespace App\Http\Transformers;
use App\Helpers\Helper;
2017-05-23 14:31:04 -07:00
use App\Models\Actionlog;
use App\Models\Asset;
use App\Models\CustomField;
2017-08-25 18:40:20 -07:00
use App\Models\Setting;
2023-12-05 11:50:43 -08:00
use App\Models\Statuslabel;
use App\Models\Company;
use App\Models\Supplier;
use App\Models\Location;
use App\Models\AssetModel;
2017-05-23 14:31:04 -07:00
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Contracts\Encryption\DecryptException;
use Illuminate\Support\Facades\Crypt;
use Illuminate\Support\Facades\Gate;
use Illuminate\Support\Facades\Log;
2017-05-23 14:31:04 -07:00
class ActionlogsTransformer
{
public function transformActionlogs (Collection $actionlogs, $total)
{
$array = array();
2017-08-25 18:40:20 -07:00
$settings = Setting::getSettings();
2017-05-23 14:31:04 -07:00
foreach ($actionlogs as $actionlog) {
2017-08-25 18:40:20 -07:00
$array[] = self::transformActionlog($actionlog, $settings);
2017-05-23 14:31:04 -07:00
}
return (new DatatablesTransformer)->transformDatatables($array, $total);
}
private function clean_field($value)
{
// This object stuff is weird, and is used to make up for the fact that
// older data can get strangely formatted if an asset existed,
// then a new custom field is added, and the asset is saved again.
// It can result in funnily-formatted strings like:
//
// {"_snipeit_right_sized_fault_tolerant_localareanetwo_1":
// {"old":null,"new":{"value":"1579490695972","_snipeit_new_field_2":2,"_snipeit_new_field_3":"Monday, 20 January 2020 2:24:55 PM"}}
// so we have to walk down that next level
if(is_object($value) && isset($value->value)) {
return $this->clean_field($value->value);
}
return is_scalar($value) || is_null($value) ? e($value) : e(json_encode($value));
}
2017-08-25 18:40:20 -07:00
public function transformActionlog (Actionlog $actionlog, $settings = null)
2017-05-23 14:31:04 -07:00
{
2018-05-02 14:13:06 -07:00
$icon = $actionlog->present()->icon();
static $custom_fields = false;
if ($custom_fields === false) {
$custom_fields = CustomField::all();
}
2018-05-02 14:13:06 -07:00
if ($actionlog->filename!='') {
$icon = Helper::filetype_icon($actionlog->filename);
2018-05-02 14:13:06 -07:00
}
// This is necessary since we can't escape special characters within a JSON object
if (($actionlog->log_meta) && ($actionlog->log_meta!='')) {
$meta_array = json_decode($actionlog->log_meta);
2023-08-24 10:40:44 -07:00
$clean_meta = [];
if ($meta_array) {
foreach ($meta_array as $fieldname => $fieldata) {
$clean_meta[$fieldname]['old'] = $this->clean_field($fieldata->old);
$clean_meta[$fieldname]['new'] = $this->clean_field($fieldata->new);
// this is a custom field
if (str_starts_with($fieldname, '_snipeit_')) {
foreach ($custom_fields as $custom_field) {
if ($custom_field->db_column == $fieldname) {
if ($custom_field->field_encrypted == '1') {
// Unset these fields. We need to decrypt them, since even if the decrypted value
// didn't change, their value in the DB will, so we have to compare the unencrypted version
// to see if the values actually did change
unset($clean_meta[$fieldname]);
unset($clean_meta[$fieldname]);
$enc_old = '';
$enc_new = '';
if ($this->clean_field($fieldata->old!='')) {
try {
$enc_old = Crypt::decryptString($this->clean_field($fieldata->old));
} catch (\Exception $e) {
Log::debug('Could not decrypt old field value - maybe the key changed?');
}
}
if ($this->clean_field($fieldata->new!='')) {
try {
$enc_new = Crypt::decryptString($this->clean_field($fieldata->new));
} catch (\Exception $e) {
Log::debug('Could not decrypt new field value - maybe the key changed?');
}
}
if ($enc_old != $enc_new) {
$clean_meta[$fieldname]['old'] = "************";
$clean_meta[$fieldname]['new'] = "************";
// Display the changes if the user is an admin or superadmin
if (Gate::allows('admin')) {
$clean_meta[$fieldname]['old'] = ($enc_old) ? unserialize($enc_old): '';
$clean_meta[$fieldname]['new'] = ($enc_new) ? unserialize($enc_new): '';
}
}
}
}
}
}
}
}
$clean_meta= $this->changedInfo($clean_meta);
}
$file_url = '';
if($actionlog->filename!='') {
if ($actionlog->action_type == 'accepted') {
$file_url = route('log.storedeula.download', ['filename' => $actionlog->filename]);
} else {
if ($actionlog->item) {
if ($actionlog->itemType() == 'asset') {
$file_url = route('show/assetfile', ['assetId' => $actionlog->item->id, 'fileId' => $actionlog->id]);
Squashed commit of the following: commit 147fcfb8ebc4ceeea96d803d6a455abeba54f45a Merge: 58a3d09b5 fdcc17ca2 Author: snipe <snipe@snipe.net> Date: Tue Oct 22 15:12:55 2024 +0100 Merge pull request #15676 from Toreg87/fixes/api_create_user_fmcs Fix user creation with FullMultipleCompanySupport enabled over API commit 58a3d09b5fd7ffa979bfb9553cacbb24ae452462 Merge: 30a06a594 867fa2f36 Author: snipe <snipe@snipe.net> Date: Tue Oct 22 14:55:42 2024 +0100 Merge pull request #15703 from marcusmoore/bug/sc-27188 Linked accessory files in activity report commit 30a06a594289571097e2d30901546bc9a17b4bac Merge: 6c6af78e0 ce3086317 Author: snipe <snipe@snipe.net> Date: Tue Oct 22 11:47:06 2024 +0100 Merge pull request #15693 from marcusmoore/chore/remove-parallel-testing Removed brianium/paratest commit 6c6af78e0840fc4f134e5bbb7965f21f4adcc0e1 Merge: 9b06bbb6c 3f79fd7ea Author: snipe <snipe@snipe.net> Date: Tue Oct 22 11:46:04 2024 +0100 Merge pull request #15705 from marcusmoore/tests/icon-component-test Added test to ensure icon component does not end in newline commit 3f79fd7ea744bd18134785c37b87a2f4bcff0347 Author: Marcus Moore <contact@marcusmoore.io> Date: Mon Oct 21 17:07:40 2024 -0700 Add test to ensure icon component does not end in newline commit 9b06bbb6c37fcea9b6202ad9fb2b4d952210dd01 Merge: 46ad1d072 d7f70146f Author: snipe <snipe@snipe.net> Date: Mon Oct 21 22:38:26 2024 +0100 Merge pull request #15704 from marcusmoore/bug/remove-extra-icon Removed second icon in accessory file list commit ce30863177e499a29f395c9c88ce9c67bd669a74 Author: Marcus Moore <contact@marcusmoore.io> Date: Mon Oct 21 13:57:04 2024 -0700 Remove brianium/paratest dependency commit d7f70146f4a886795ddb118cc2f71bbadded72dc Author: Marcus Moore <contact@marcusmoore.io> Date: Mon Oct 21 13:48:25 2024 -0700 Remove extra icon in accessory file upload list commit 867fa2f36e02bdfe0ee74ae98b590fd013f6fc7a Author: Marcus Moore <contact@marcusmoore.io> Date: Mon Oct 21 12:40:24 2024 -0700 Display file in activity report for accessories commit 0933a2d4ea6d5babd6ef3e0e2f8350c2e088648d Author: Marcus Moore <contact@marcusmoore.io> Date: Thu Oct 17 18:01:48 2024 -0700 Remove --parallel flag commit 46ad1d072f5c45d20c1b078d2b3f84a3a0f36632 Merge: bcb4bd9eb 3cf746d7d Author: snipe <snipe@snipe.net> Date: Thu Oct 17 15:29:47 2024 +0100 Merge pull request #15680 from uberbrady/bulk_checkout_to_bulk_actions Bulk checkout to bulk actions commit bcb4bd9eb4e419e8a125a7dccd3e79c39dc13e21 Merge: 250037540 f50ccbcc4 Author: snipe <snipe@snipe.net> Date: Thu Oct 17 10:20:13 2024 +0100 Merge pull request #15683 from Toreg87/fixes/outdated_comment Fix outdated comment in CompanyableTrait commit f50ccbcc492db6c98cabf6dc6752dd99ab82bce7 Author: Tobias Regnery <tobias.regnery@gmail.com> Date: Thu Oct 17 11:07:28 2024 +0200 Fix outdated comment in CompanyableTrait As of commit 5800e8d the user model uses CompanyableTrait so remove this clearly outdated comment commit 3cf746d7df83ef3e7cfa45c602fc182ebe8f11e3 Author: Brady Wetherington <bwetherington@grokability.com> Date: Wed Oct 16 23:13:32 2024 +0100 Rework the bulk checkout to not change how all checkouts work commit 6b7af802af41c92a36e77605415869c9e72ec192 Author: Brady Wetherington <bwetherington@grokability.com> Date: Thu Oct 10 13:28:23 2024 +0100 Add 'bulk checkout' as one of the bulk actions in the bulk actions toolbar commit fdcc17ca2c33d38a7af505c99d9547e014f5f783 Author: Tobias Regnery <tobias.regnery@gmail.com> Date: Wed Oct 16 11:18:24 2024 +0200 Fix user creation with FullMultipleCompanySupport enabled over API It is currently possible as a non-superuser to create a new user or patch an existing user with arbitrary company over the API if FullMultipleCompanySupport is enabled. Altough a highly unlikely scenario as the user needs permission to create API keys and new users, it is a bug that should get fixed. Add a call to getIdForCurrentUser() to normalize the company_id if FullMultipleCompanySupport is enabled. Signed-off-by: snipe <snipe@snipe.net>
2024-10-22 07:43:19 -07:00
} elseif ($actionlog->itemType() == 'accessory') {
$file_url = route('show.accessoryfile', ['accessoryId' => $actionlog->item->id, 'fileId' => $actionlog->id]);
} elseif ($actionlog->itemType() == 'license') {
$file_url = route('show.licensefile', ['licenseId' => $actionlog->item->id, 'fileId' => $actionlog->id]);
} elseif ($actionlog->itemType() == 'user') {
$file_url = route('show/userfile', ['userId' => $actionlog->item->id, 'fileId' => $actionlog->id]);
}
}
}
}
$array = [
2017-08-25 18:40:20 -07:00
'id' => (int) $actionlog->id,
2018-05-02 14:13:06 -07:00
'icon' => $icon,
'file' => ($actionlog->filename!='')
?
2018-05-02 14:13:06 -07:00
[
'url' => $file_url,
2018-05-02 14:13:06 -07:00
'filename' => $actionlog->filename,
] : null,
2017-05-23 14:31:04 -07:00
'item' => ($actionlog->item) ? [
'id' => (int) $actionlog->item->id,
'name' => ($actionlog->itemType()=='user') ? e($actionlog->item->getFullNameAttribute()) : e($actionlog->item->getDisplayNameAttribute()),
2017-05-23 14:31:04 -07:00
'type' => e($actionlog->itemType()),
2022-11-17 12:57:53 -08:00
'serial' =>e($actionlog->item->serial) ? e($actionlog->item->serial) : null
2017-05-23 14:31:04 -07:00
] : null,
2017-08-25 18:40:20 -07:00
'location' => ($actionlog->location) ? [
'id' => (int) $actionlog->location->id,
'name' => e($actionlog->location->name),
2017-08-25 18:40:20 -07:00
] : null,
'created_at' => Helper::getFormattedDateObject($actionlog->created_at, 'datetime'),
2017-05-23 14:31:04 -07:00
'updated_at' => Helper::getFormattedDateObject($actionlog->updated_at, 'datetime'),
'next_audit_date' => ($actionlog->itemType()=='asset') ? Helper::getFormattedDateObject($actionlog->calcNextAuditDate(null, $actionlog->item), 'date'): null,
2017-08-25 18:40:20 -07:00
'days_to_next_audit' => $actionlog->daysUntilNextAudit($settings->audit_interval, $actionlog->item),
2017-05-23 14:31:04 -07:00
'action_type' => $actionlog->present()->actionType(),
'admin' => ($actionlog->adminuser) ? [
'id' => (int) $actionlog->adminuser->id,
'name' => e($actionlog->adminuser->getFullNameAttribute()),
'first_name'=> e($actionlog->adminuser->first_name),
'last_name'=> e($actionlog->adminuser->last_name)
] : null,
'created_by' => ($actionlog->adminuser) ? [
'id' => (int) $actionlog->adminuser->id,
'name' => e($actionlog->adminuser->getFullNameAttribute()),
'first_name'=> e($actionlog->adminuser->first_name),
'last_name'=> e($actionlog->adminuser->last_name)
2017-05-23 14:31:04 -07:00
] : null,
'target' => ($actionlog->target) ? [
'id' => (int) $actionlog->target->id,
'name' => ($actionlog->targetType()=='user') ? e($actionlog->target->getFullNameAttribute()) : e($actionlog->target->getDisplayNameAttribute()),
'type' => e($actionlog->targetType()),
] : null,
'note' => ($actionlog->note) ? Helper::parseEscapedMarkedownInline($actionlog->note): null,
'signature_file' => ($actionlog->accept_signature) ? route('log.signature.view', ['filename' => $actionlog->accept_signature ]) : null,
'log_meta' => ((isset($clean_meta)) && (is_array($clean_meta))) ? $clean_meta: null,
'remote_ip' => ($actionlog->remote_ip) ?? null,
'user_agent' => ($actionlog->user_agent) ?? null,
'action_source' => ($actionlog->action_source) ?? null,
'action_date' => ($actionlog->action_date) ? Helper::getFormattedDateObject($actionlog->action_date, 'datetime'): Helper::getFormattedDateObject($actionlog->created_at, 'datetime'),
2017-05-23 14:31:04 -07:00
];
// Log::info("Clean Meta is: ".print_r($clean_meta,true));
//dd($array);
2017-05-23 14:31:04 -07:00
return $array;
}
2018-05-02 14:13:06 -07:00
public function transformCheckedoutActionlog (Collection $accessories_checkout, $total)
2017-05-23 14:31:04 -07:00
{
$array = array();
foreach ($accessories_checkout as $user) {
2017-05-23 14:31:04 -07:00
$array[] = (new UsersTransformer)->transformUser($user);
}
return (new DatatablesTransformer)->transformDatatables($array, $total);
}
/**
* This takes the ids of the changed attributes and returns the names instead for the history view of an Asset
*
* @param array $clean_meta
* @return array
*/
2023-08-23 00:40:59 -07:00
public function changedInfo(array $clean_meta)
{
static $location = false;
static $supplier = false;
static $model = false;
static $status = false;
static $company = false;
if ($location === false) {
$location = Location::select('id', 'name')->withTrashed()->get();
}
if ($supplier === false) {
$supplier = Supplier::select('id', 'name')->withTrashed()->get();
}
if ($model === false) {
$model = AssetModel::select('id', 'name')->withTrashed()->get();
}
if ($status === false) {
$status = Statuslabel::select('id', 'name')->withTrashed()->get();
}
if ($company === false) {
$company = Company::select('id', 'name')->get();
}
if(array_key_exists('rtd_location_id',$clean_meta)) {
$oldRtd = $location->find($clean_meta['rtd_location_id']['old']);
$oldRtdName = $oldRtd ? e($oldRtd->name) : trans('general.deleted');
$newRtd = $location->find($clean_meta['rtd_location_id']['new']);
$newRtdName = $newRtd ? e($newRtd->name) : trans('general.deleted');
$clean_meta['rtd_location_id']['old'] = $clean_meta['rtd_location_id']['old'] ? "[id: ".$clean_meta['rtd_location_id']['old']."] ". $oldRtdName : '';
$clean_meta['rtd_location_id']['new'] = $clean_meta['rtd_location_id']['new'] ? "[id: ".$clean_meta['rtd_location_id']['new']."] ". $newRtdName : '';
$clean_meta[trans('admin/hardware/form.default_location')] = $clean_meta['rtd_location_id'];
unset($clean_meta['rtd_location_id']);
}
if (array_key_exists('location_id', $clean_meta)) {
$oldLocation = $location->find($clean_meta['location_id']['old']);
$oldLocationName = $oldLocation ? e($oldLocation->name) : trans('general.deleted');
$newLocation = $location->find($clean_meta['location_id']['new']);
$newLocationName = $newLocation ? e($newLocation->name) : trans('general.deleted');
$clean_meta['location_id']['old'] = $clean_meta['location_id']['old'] ? "[id: ".$clean_meta['location_id']['old']."] ". $oldLocationName : '';
$clean_meta['location_id']['new'] = $clean_meta['location_id']['new'] ? "[id: ".$clean_meta['location_id']['new']."] ". $newLocationName : '';
$clean_meta[trans('admin/locations/message.current_location')] = $clean_meta['location_id'];
unset($clean_meta['location_id']);
}
if(array_key_exists('model_id', $clean_meta)) {
2023-08-23 00:38:58 -07:00
$oldModel = $model->find($clean_meta['model_id']['old']);
$oldModelName = $oldModel ? e($oldModel->name) : trans('admin/models/message.deleted');
$newModel = $model->find($clean_meta['model_id']['new']);
$newModelName = $newModel ? e($newModel->name) : trans('admin/models/message.deleted');
$clean_meta['model_id']['old'] = "[id: ".$clean_meta['model_id']['old']."] ".$oldModelName;
$clean_meta['model_id']['new'] = "[id: ".$clean_meta['model_id']['new']."] ".$newModelName; /** model is required at asset creation */
2023-08-23 00:38:58 -07:00
$clean_meta[trans('admin/hardware/form.model')] = $clean_meta['model_id'];
unset($clean_meta['model_id']);
}
if(array_key_exists('company_id', $clean_meta)) {
$oldCompany = $company->find($clean_meta['company_id']['old']);
$oldCompanyName = $oldCompany ? e($oldCompany->name) : trans('admin/company/message.deleted');
$newCompany = $company->find($clean_meta['company_id']['new']);
$newCompanyName = $newCompany ? e($newCompany->name) : trans('admin/company/message.deleted');
$clean_meta['company_id']['old'] = $clean_meta['company_id']['old'] ? "[id: ".$clean_meta['company_id']['old']."] ". $oldCompanyName : trans('general.unassigned');
$clean_meta['company_id']['new'] = $clean_meta['company_id']['new'] ? "[id: ".$clean_meta['company_id']['new']."] ". $newCompanyName : trans('general.unassigned');
$clean_meta[trans('general.company')] = $clean_meta['company_id'];
unset($clean_meta['company_id']);
}
if(array_key_exists('supplier_id', $clean_meta)) {
$oldSupplier = $supplier->find($clean_meta['supplier_id']['old']);
$oldSupplierName = $oldSupplier ? e($oldSupplier->name) : trans('admin/suppliers/message.deleted');
$newSupplier = $supplier->find($clean_meta['supplier_id']['new']);
$newSupplierName = $newSupplier ? e($newSupplier->name) : trans('admin/suppliers/message.deleted');
$clean_meta['supplier_id']['old'] = $clean_meta['supplier_id']['old'] ? "[id: ".$clean_meta['supplier_id']['old']."] ". $oldSupplierName : trans('general.unassigned');
$clean_meta['supplier_id']['new'] = $clean_meta['supplier_id']['new'] ? "[id: ".$clean_meta['supplier_id']['new']."] ". $newSupplierName : trans('general.unassigned');
$clean_meta[trans('general.supplier')] = $clean_meta['supplier_id'];
unset($clean_meta['supplier_id']);
}
2023-12-05 11:50:43 -08:00
if(array_key_exists('status_id', $clean_meta)) {
$oldStatus = $status->find($clean_meta['status_id']['old']);
$oldStatusName = $oldStatus ? e($oldStatus->name) : trans('admin/statuslabels/message.deleted_label');
$newStatus = $status->find($clean_meta['status_id']['new']);
$newStatusName = $newStatus ? e($newStatus->name) : trans('admin/statuslabels/message.deleted_label');
2023-12-05 11:56:54 -08:00
$clean_meta['status_id']['old'] = $clean_meta['status_id']['old'] ? "[id: ".$clean_meta['status_id']['old']."] ". $oldStatusName : trans('general.unassigned');
$clean_meta['status_id']['new'] = $clean_meta['status_id']['new'] ? "[id: ".$clean_meta['status_id']['new']."] ". $newStatusName : trans('general.unassigned');
$clean_meta[trans('general.status_label')] = $clean_meta['status_id'];
2023-12-05 11:50:43 -08:00
unset($clean_meta['status_id']);
}
if(array_key_exists('asset_eol_date', $clean_meta)) {
$clean_meta[trans('admin/hardware/form.eol_date')] = $clean_meta['asset_eol_date'];
unset($clean_meta['asset_eol_date']);
}
return $clean_meta;
}
2017-05-23 14:31:04 -07:00
Squashed commit of the following: commit 147fcfb8ebc4ceeea96d803d6a455abeba54f45a Merge: 58a3d09b5 fdcc17ca2 Author: snipe <snipe@snipe.net> Date: Tue Oct 22 15:12:55 2024 +0100 Merge pull request #15676 from Toreg87/fixes/api_create_user_fmcs Fix user creation with FullMultipleCompanySupport enabled over API commit 58a3d09b5fd7ffa979bfb9553cacbb24ae452462 Merge: 30a06a594 867fa2f36 Author: snipe <snipe@snipe.net> Date: Tue Oct 22 14:55:42 2024 +0100 Merge pull request #15703 from marcusmoore/bug/sc-27188 Linked accessory files in activity report commit 30a06a594289571097e2d30901546bc9a17b4bac Merge: 6c6af78e0 ce3086317 Author: snipe <snipe@snipe.net> Date: Tue Oct 22 11:47:06 2024 +0100 Merge pull request #15693 from marcusmoore/chore/remove-parallel-testing Removed brianium/paratest commit 6c6af78e0840fc4f134e5bbb7965f21f4adcc0e1 Merge: 9b06bbb6c 3f79fd7ea Author: snipe <snipe@snipe.net> Date: Tue Oct 22 11:46:04 2024 +0100 Merge pull request #15705 from marcusmoore/tests/icon-component-test Added test to ensure icon component does not end in newline commit 3f79fd7ea744bd18134785c37b87a2f4bcff0347 Author: Marcus Moore <contact@marcusmoore.io> Date: Mon Oct 21 17:07:40 2024 -0700 Add test to ensure icon component does not end in newline commit 9b06bbb6c37fcea9b6202ad9fb2b4d952210dd01 Merge: 46ad1d072 d7f70146f Author: snipe <snipe@snipe.net> Date: Mon Oct 21 22:38:26 2024 +0100 Merge pull request #15704 from marcusmoore/bug/remove-extra-icon Removed second icon in accessory file list commit ce30863177e499a29f395c9c88ce9c67bd669a74 Author: Marcus Moore <contact@marcusmoore.io> Date: Mon Oct 21 13:57:04 2024 -0700 Remove brianium/paratest dependency commit d7f70146f4a886795ddb118cc2f71bbadded72dc Author: Marcus Moore <contact@marcusmoore.io> Date: Mon Oct 21 13:48:25 2024 -0700 Remove extra icon in accessory file upload list commit 867fa2f36e02bdfe0ee74ae98b590fd013f6fc7a Author: Marcus Moore <contact@marcusmoore.io> Date: Mon Oct 21 12:40:24 2024 -0700 Display file in activity report for accessories commit 0933a2d4ea6d5babd6ef3e0e2f8350c2e088648d Author: Marcus Moore <contact@marcusmoore.io> Date: Thu Oct 17 18:01:48 2024 -0700 Remove --parallel flag commit 46ad1d072f5c45d20c1b078d2b3f84a3a0f36632 Merge: bcb4bd9eb 3cf746d7d Author: snipe <snipe@snipe.net> Date: Thu Oct 17 15:29:47 2024 +0100 Merge pull request #15680 from uberbrady/bulk_checkout_to_bulk_actions Bulk checkout to bulk actions commit bcb4bd9eb4e419e8a125a7dccd3e79c39dc13e21 Merge: 250037540 f50ccbcc4 Author: snipe <snipe@snipe.net> Date: Thu Oct 17 10:20:13 2024 +0100 Merge pull request #15683 from Toreg87/fixes/outdated_comment Fix outdated comment in CompanyableTrait commit f50ccbcc492db6c98cabf6dc6752dd99ab82bce7 Author: Tobias Regnery <tobias.regnery@gmail.com> Date: Thu Oct 17 11:07:28 2024 +0200 Fix outdated comment in CompanyableTrait As of commit 5800e8d the user model uses CompanyableTrait so remove this clearly outdated comment commit 3cf746d7df83ef3e7cfa45c602fc182ebe8f11e3 Author: Brady Wetherington <bwetherington@grokability.com> Date: Wed Oct 16 23:13:32 2024 +0100 Rework the bulk checkout to not change how all checkouts work commit 6b7af802af41c92a36e77605415869c9e72ec192 Author: Brady Wetherington <bwetherington@grokability.com> Date: Thu Oct 10 13:28:23 2024 +0100 Add 'bulk checkout' as one of the bulk actions in the bulk actions toolbar commit fdcc17ca2c33d38a7af505c99d9547e014f5f783 Author: Tobias Regnery <tobias.regnery@gmail.com> Date: Wed Oct 16 11:18:24 2024 +0200 Fix user creation with FullMultipleCompanySupport enabled over API It is currently possible as a non-superuser to create a new user or patch an existing user with arbitrary company over the API if FullMultipleCompanySupport is enabled. Altough a highly unlikely scenario as the user needs permission to create API keys and new users, it is a bug that should get fixed. Add a call to getIdForCurrentUser() to normalize the company_id if FullMultipleCompanySupport is enabled. Signed-off-by: snipe <snipe@snipe.net>
2024-10-22 07:43:19 -07:00
}