Compare commits

...

42 Commits

Author SHA1 Message Date
snipe daf748e531 Bumped hash 2020-07-17 12:32:01 -07:00
snipe 799a93c46a Allow for email/username search on users 2020-07-17 12:11:32 -07:00
snipe 34aa12e229 Merge pull request #8239 from snipe/fixes/api_rtd_to_location_on_create
Set location_id to rtd_location_id on asset creation
2020-07-16 17:44:13 -07:00
snipe 897757bd04 Removed added line for location 2020-07-16 17:43:44 -07:00
snipe c7125c3937 Set location_id to rtd_location_id on asset creation 2020-07-16 16:34:39 -07:00
snipe 81a6332889 Removed license ID from seats table cookie info
This typically wouldn’t be necessary, since most people would want to view the same *types* of data across licenses
2020-07-14 13:55:38 -07:00
snipe 6e563f6e4b Merge branch 'master' of https://github.com/snipe/snipe-it 2020-07-13 21:16:54 -07:00
snipe 5320f5c67c Disallow non-super users from editing their own permissions 2020-07-13 21:16:45 -07:00
snipe 7f69ae953b Merge pull request #8227 from snipe/fix_select2_ajax_pulldowns
Changes how we do AJAX calls via Select2 for dynamic drop-down menus
2020-07-13 21:16:00 -07:00
Brady Wetherington 17f6fbabfa Switch to 'items' to maintain compatbility with other internal API's 2020-07-13 21:12:03 -07:00
snipe c79f8c1baf Merge pull request #8207 from EDVLeer/patch-1
Update snipeit.sh
2020-07-13 17:42:16 -07:00
Brady Wetherington e7a820f7c9 Changes how we do AJAX calls via Select2 for dynamic drop-down menus 2020-07-13 17:14:31 -07:00
snipe 12c92e30b7 Show whether or not the user was imported via LDAP in the view page 2020-07-10 16:21:27 -07:00
snipe fd10b755b0 Removed the sr-only tag in table headers
It was breaking Bootstrap Tables column selector :(
2020-07-10 11:30:01 -07:00
snipe dbbb7680d9 A few more fixes for the cli
Do not check out a piece of software if it’s already been checked out to the user
2020-07-09 21:12:50 -07:00
snipe cf0dd5bbad Small fixes for cli tool 2020-07-09 20:43:13 -07:00
snipe 25e53d8c7f Merge pull request #8216 from snipe/features/checkout_license_to_all_users
Added CLI tool to checkout license to all users
2020-07-09 20:27:01 -07:00
snipe 89d433b41a Removed duplicate seat call 2020-07-09 20:26:02 -07:00
snipe e2570ada6f CLI tool to checkout a license to ALL users 2020-07-09 20:04:05 -07:00
snipe 45afe725a1 Only try to get the company if there is an auth’d user
(Needed for command line tools, where no Auth::user() is present)
2020-07-09 20:03:47 -07:00
EDVLeer 536401fe0f Update snipeit.sh
Ubuntu 20.04
2020-07-07 08:21:36 +02:00
snipe ec6ed256fb Bumped minor version 2020-07-06 18:45:43 -07:00
snipe 2aaa7bed2d Merge pull request #8183 from snipe/features/merge_users
Added merge utility
2020-06-25 18:37:41 -07:00
snipe cc9f1577a4 Removed unused use directives 2020-06-25 17:43:53 -07:00
snipe ab1fe8be0c Added merge utility 2020-06-25 17:42:39 -07:00
snipe 339bdddc38 Fix for Vue js not loading due to CSP :( 2020-06-25 11:00:33 -07:00
snipe 35b9cf4b70 Fixed missing db prefix on scopeDueOrOverdueForAudit 2020-06-23 02:41:59 -07:00
snipe 7ccb41371e Removed unoptimized images directive
securityheaders.com is claiming it’s onrecognized, even though I got that directive from their site, so… whatever. ¯\_(ツ)_/¯
2020-06-23 01:09:39 -07:00
snipe 2e60a457bf Dumb fix for feature-policy being dumb. 2020-06-23 01:07:00 -07:00
snipe 2390d2160b Merge pull request #8164 from snipe/features/additional_security_headers
Additional security headers
2020-06-23 00:27:47 -07:00
snipe 00b051b8c7 Added a few more comments 2020-06-23 00:26:09 -07:00
snipe 05b3a9ad7e Config variable for HSTS 2020-06-22 23:17:27 -07:00
snipe 4fb880384f Changed comment 2020-06-22 22:37:14 -07:00
snipe 43042ad841 Consolidated ReferrerPolicy into new SecurityHeaders file 2020-06-22 22:35:59 -07:00
snipe a716382ac4 Removed CSP middleware (it’s added in the general header) 2020-06-22 22:33:37 -07:00
snipe 36c8f7f4f1 Additional security headers 2020-06-22 22:31:01 -07:00
snipe b42801f6ae Merge pull request #8163 from snipe/fixes/fix-for-css-on-column-selector
Fixed weird padlock display in asset listing with encrypted custom fields
2020-06-22 20:47:35 -07:00
snipe 946129f206 Made quote style consistent 2020-06-22 20:45:20 -07:00
snipe b941ef1e08 Pulled CSS font awesome styles out of the blade and into overrides.css 2020-06-22 20:41:40 -07:00
snipe d1aa11ec89 Fix for weird padlock display in asset listing with encrypted custom fields 2020-06-22 20:29:19 -07:00
snipe de4934f21d Merge pull request #8162 from Godmartinz/godfreymartinez-ghi-font-size-of-qr_text
Fixed #8161 and #8114 - font-size for labels used static values in blade instead of using values from settings
2020-06-22 17:28:38 -07:00
Godfrey M b10076b015 corrected an error where font-size for labels were static in settings. 2020-06-22 17:04:39 -07:00
40 changed files with 510 additions and 239 deletions
+1
View File
@@ -71,6 +71,7 @@ ALLOW_IFRAMING=false
REFERRER_POLICY=same-origin
ENABLE_CSP=false
CORS_ALLOWED_ORIGINS=null
ENABLE_HSTS=false
# --------------------------------------------
# OPTIONAL: CACHE SETTINGS
+1
View File
@@ -0,0 +1 @@
v6.11.3
@@ -0,0 +1,112 @@
<?php
namespace App\Console\Commands;
use App\Models\LicenseSeat;
use Illuminate\Console\Command;
use App\Models\User;
use App\Models\License;
use Illuminate\Database\Eloquent\Model;
class CheckoutLicenseToAllUsers extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'snipeit:checkout-to-all {--license_id=} {--notify}';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Command description';
/**
* Create a new command instance.
*
* @return void
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
*
* @return mixed
*/
public function handle()
{
$license_id = $this->option('license_id');
$notify = $this->option('notify');
if (!$license_id) {
$this->error('ERROR: License ID is required.');
return false;
}
if (!$license = License::where('id','=',$license_id)->with('assignedusers')->first()) {
$this->error('Invalid license ID');
return false;
}
$users = User::whereNull('deleted_at')->with('licenses')->get();
if ($users->count() > $license->getAvailSeatsCountAttribute()) {
$this->info('You do not have enough free seats to complete this task, so we will check out as many as we can. ');
}
$this->info('Checking out '.$users->count().' of '.$license->getAvailSeatsCountAttribute().' seats for '.$license->name);
if (!$notify) {
$this->info('No mail will be sent.');
}
foreach ($users as $user) {
// Check to make sure this user doesn't already have this license checked out
// to them
if ($user->licenses->where('id', '=', $license_id)->count()) {
$this->info($user->username .' already has this license checked out to them. Skipping... ');
continue;
}
// If the license is valid, check that there is an available seat
if ($license->availCount()->count() < 1) {
$this->error('ERROR: No available seats');
return false;
}
$this->info($license->availCount()->count().' seats left');
// Get the seat ID
$licenseSeat = $license->freeSeat();
// Update the seat with checkout info,
$licenseSeat->assigned_to = $user->id;
if ($licenseSeat->save()) {
// Temporarily null the user's email address so we don't send mail if we're not supposed to
if (!$notify) {
$user->email = null;
}
// Log the checkout
$licenseSeat->logCheckout('Checked out via cli tool', $user);
$this->info('License '.$license_id.' seat '.$licenseSeat->id.' checked out to '.$user->username);
}
}
}
}
@@ -0,0 +1,109 @@
<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
use App\Models\User;
use Carbon\Carbon;
class MergeUsersByUsername extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'snipeit:merge-users';
/**
* The console command description.
*
* @var string
*/
protected $description = 'This command allows you to merge the history of users. It looks for users without an email address as their username and merges them into the version that does have an email username.';
/**
* Create a new command instance.
*
* @return void
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
*
* @return mixed
*/
public function handle()
{
// Get the list of users who have an email address as their username
$users = User::where('username', 'LIKE', '%@%')->whereNull('deleted_at')->get();
foreach ($users as $user) {
$parts = explode("@", $user->username);
$bad_users = User::where('username', '=', $parts[0])->whereNull('deleted_at')->with('assets', 'manager', 'userlog', 'licenses', 'consumables', 'accessories', 'managedLocations')->get();
foreach ($bad_users as $bad_user) {
$this->info($bad_user->username.' ('.$bad_user->id.') will be merged into '.$user->username.' ('.$user->id.') ');
// Walk the list of assets
foreach ($bad_user->assets as $asset) {
$this->info( 'Updating asset '.$asset->asset_tag.' '.$asset->id.' to user '.$user->id);
$asset->assigned_to = $user->id;
$asset->save();
}
// Walk the list of licenses
foreach ($bad_user->licenses as $license) {
$this->info( 'Updating license '.$license->name.' '.$license->id.' to user '.$user->id);
$bad_user->licenses()->updateExistingPivot($license->id, ['assigned_to' => $user->id]);
}
// Walk the list of consumables
foreach ($bad_user->consumables as $consumable) {
$this->info( 'Updating consumable '.$consumable->id.' to user '.$user->id);
$bad_user->consumables()->updateExistingPivot($consumable->id, ['assigned_to' => $user->id]);
}
// Walk the list of accessories
foreach ($bad_user->accessories as $accessory) {
$this->info( 'Updating accessory '.$accessory->id.' to user '.$user->id);
$bad_user->accessories()->updateExistingPivot($accessory->id, ['assigned_to' => $user->id]);
}
// Walk the list of logs
foreach ($bad_user->userlog as $log) {
$this->info( 'Updating action log record '.$log->id.' to user '.$user->id);
$log->target_id = $user->id;
$log->save();
}
// Update any manager IDs
$this->info( 'Updating managed user records to user '.$user->id);
User::where('manager_id', '=', $bad_user->id)->update(['manager_id' => $user->id]);
// Update location manager IDs
foreach ($bad_user->managedLocations as $managedLocation) {
$this->info( 'Updating managed location record '.$managedLocation->name.' to manager '.$user->id);
$managedLocation->manager_id = $user->id;
$managedLocation->save();
}
// Mark the user as deleted
$this->info( 'Marking the user as deleted');
$bad_user->deleted_at = Carbon::now()->timestamp;
$bad_user->save();
}
}
}
}
@@ -453,6 +453,7 @@ class AssetsController extends Controller
$asset->supplier_id = $request->get('supplier_id', 0);
$asset->requestable = $request->get('requestable', 0);
$asset->rtd_location_id = $request->get('rtd_location_id', null);
$asset->location_id = $request->get('rtd_location_id', null);
// Update custom fields in the database.
// Validation for these fields is handled through the AssetRequest form request
@@ -76,6 +76,14 @@ class UsersController extends Controller
$users = $users->where('users.location_id', '=', $request->input('location_id'));
}
if ($request->filled('email')) {
$users = $users->where('users.email', '=', $request->input('email'));
}
if ($request->filled('username')) {
$users = $users->where('users.username', '=', $request->input('username'));
}
if ($request->filled('group_id')) {
$users = $users->ByGroup($request->get('group_id'));
}
@@ -137,6 +137,7 @@ class AssetsController extends Controller
$asset->supplier_id = request('supplier_id', 0);
$asset->requestable = request('requestable', 0);
$asset->rtd_location_id = request('rtd_location_id', null);
if ($asset->assigned_to=='') {
$asset->location_id = $request->input('rtd_location_id', null);
+6
View File
@@ -240,6 +240,12 @@ class UsersController extends Controller
if ($user->id == $request->input('manager_id')) {
return redirect()->back()->withInput()->with('error', 'You cannot be your own manager.');
}
// If the user isn't a superuser, don't let them edit their own permissions
if ((!Auth::user()->isSuperUser()) && ($user->id == Auth::user()->id)) {
return redirect()->back()->withInput()->with('error', 'You cannot edit your own permissions. Please contact an administrator.');
}
$this->authorize('update', $user);
// Figure out of this user was an admin before this edit
$orig_permissions_array = $user->decodePermissions();
+2 -5
View File
@@ -17,15 +17,12 @@ class Kernel extends HttpKernel
\Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode::class,
\Illuminate\Session\Middleware\StartSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\App\Http\Middleware\FrameGuard::class,
\App\Http\Middleware\XssProtectHeader::class,
\App\Http\Middleware\ReferrerPolicyHeader::class,
\App\Http\Middleware\ContentSecurityPolicyHeader::class,
\App\Http\Middleware\NosniffGuard::class,
\Fideloper\Proxy\TrustProxies::class,
\App\Http\Middleware\CheckForSetup::class,
\App\Http\Middleware\CheckForDebug::class,
\Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
\App\Http\Middleware\SecurityHeaders::class,
];
/**
@@ -1,35 +0,0 @@
<?php
namespace App\Http\Middleware;
use Closure;
class ContentSecurityPolicyHeader
{
/**
* Handle the given request and get the response.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return \Illuminate\Http\Response
*/
public function handle($request, Closure $next)
{
if ((config('app.debug')=='true') || (config('app.enable_csp')!='true')) {
$response = $next($request);
return $response;
}
$policy[] = "default-src 'self'";
$policy[] = "style-src 'self' 'unsafe-inline' oss.maxcdn.com";
$policy[] = "script-src 'self' 'unsafe-inline' 'unsafe-eval' cdnjs.cloudflare.com";
$policy[] = "connect-src 'self'";
$policy[] = "object-src 'none'";
$policy[] = "font-src 'self' data:";
$policy[] = "img-src 'self' data: gravatar.com";
$policy = join(';', $policy);
$response = $next($request);
$response->headers->set('Content-Security-Policy', $policy);
return $response;
}
}
-24
View File
@@ -1,24 +0,0 @@
<?php
namespace App\Http\Middleware;
use Closure;
class FrameGuard
{
/**
* Handle the given request and get the response.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return \Illuminate\Http\Response
*/
public function handle($request, Closure $next)
{
$response = $next($request);
if (config('app.allow_iframing') == false) {
$response->headers->set('X-Frame-Options', 'SAMEORIGIN', false);
}
return $response;
}
}
-21
View File
@@ -1,21 +0,0 @@
<?php
namespace App\Http\Middleware;
use Closure;
class NosniffGuard
{
/**
* Handle the given request and get the response.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return \Illuminate\Http\Response
*/
public function handle($request, Closure $next)
{
$response = $next($request);
$response->headers->set('X-Content-Type-Options', 'nosniff', false);
return $response;
}
}
@@ -1,21 +0,0 @@
<?php
namespace App\Http\Middleware;
use Closure;
class ReferrerPolicyHeader
{
/**
* Handle the given request and get the response.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return \Illuminate\Http\Response
*/
public function handle($request, Closure $next)
{
$response = $next($request);
$response->headers->set('Referrer-Policy', config('app.referrer_policy'));
return $response;
}
}
+122
View File
@@ -0,0 +1,122 @@
<?php
namespace App\Http\Middleware;
use Closure;
class SecurityHeaders
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
// See https://securityheaders.com/
private $unwantedHeaderList = [
'X-Powered-By',
'Server',
];
public function handle($request, Closure $next)
{
$this->removeUnwantedHeaders($this->unwantedHeaderList);
$response = $next($request);
$response->headers->set('X-Content-Type-Options', 'nosniff');
$response->headers->set('X-XSS-Protection', '1; mode=block');
// Ugh. Feature-Policy is dumb and clumsy and mostly irrelevant for Snipe-IT,
// since we don't provide any way to IFRAME anything in in the first place.
// There is currently no easy way to default ALL THE THINGS to 'none', but
// security audits will still ding you if you don't have this header, even
// though we don't allow IFRAMING in the first place.
//
// So for security and compliance sake, here we are. Sigh.
//
// See also:
// - https://developers.google.com/web/updates/2018/06/feature-policy
// - https://scotthelme.co.uk/a-new-security-header-feature-policy/
// - https://github.com/w3c/webappsec-feature-policy/issues/189
$feature_policy[] = "accelerometer 'none'";
$feature_policy[] = "ambient-light-sensor 'none'";
$feature_policy[] = "animations 'none'";
$feature_policy[] = "autoplay 'none'";
$feature_policy[] = "battery 'none'";
$feature_policy[] = "camera 'none'";
$feature_policy[] = "display-capture 'none'";
$feature_policy[] = "document-domain 'none'";
$feature_policy[] = "encrypted-media 'none'";
$feature_policy[] = "fullscreen 'none'";
$feature_policy[] = "geolocation 'none'";
$feature_policy[] = "gyroscope 'none'";
$feature_policy[] = "legacy-image-formats 'none'";
$feature_policy[] = "magnetometer 'none'";
$feature_policy[] = "microphone 'none'";
$feature_policy[] = "midi 'none'";
$feature_policy[] = "oversized-images 'none'";
$feature_policy[] = "payment 'none'";
$feature_policy[] = "picture-in-picture 'none'";
$feature_policy[] = "publickey-credentials 'none'";
$feature_policy[] = "sync-xhr 'none'";
$feature_policy[] = "unsized-media 'none'";
$feature_policy[] = "usb 'none'";
$feature_policy[] = "vibrate 'none'";
$feature_policy[] = "wake-lock 'none'";
$feature_policy[] = "xr-spatial-tracking 'none'";
$feature_policy = join(';', $feature_policy);
$response->headers->set('Feature-Policy', $feature_policy);
// Defaults to same-origin if REFERRER_POLICY is not set in the .env
$response->headers->set('Referrer-Policy', config('app.referrer_policy'));
// The .env var ALLOW_IFRAMING defaults to false (which disallows IFRAMING)
// if not present, but some unique cases require this to be enabled.
// For example, some IT depts have IFRAMED Snipe-IT into their IT portal
// for convenience so while it is normally disallowed, there is
// an override that exists.
if (config('app.allow_iframing') == false) {
$response->headers->set('X-Frame-Options', 'DENY');
}
// This defaults to false to maintain backwards compatibility for
// people who are not running Snipe-IT over TLS (shame, shame, shame!)
// Seriously though, please run Snipe-IT over TLS. Let's Encrypt is free.
// https://letsencrypt.org
if (config('app.enable_hsts') === true) {
$response->headers->set('Strict-Transport-Security', 'max-age=31536000; includeSubDomains');
}
// We have to exclude debug mode here because debugbar pulls from a CDN or two
// and it will break things.
if ((config('app.debug')!='true') || (config('app.enable_csp')=='true')) {
$csp_policy[] = "default-src 'self'";
$csp_policy[] = "style-src 'self' 'unsafe-inline'";
$csp_policy[] = "script-src 'self' 'unsafe-inline' 'unsafe-eval'";
$csp_policy[] = "connect-src 'self'";
$csp_policy[] = "object-src 'none'";
$csp_policy[] = "font-src 'self' data:";
$csp_policy[] = "img-src 'self' data: gravatar.com";
$csp_policy = join(';', $csp_policy);
$response->headers->set('Content-Security-Policy', $csp_policy);
}
return $response;
}
private function removeUnwantedHeaders($headerList)
{
foreach ($headerList as $header)
header_remove($header);
}
}
-22
View File
@@ -1,22 +0,0 @@
<?php
namespace App\Http\Middleware;
use Closure;
class XssProtectHeader
{
/**
* Handle the given request and get the response.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return \Illuminate\Http\Response
*/
public function handle($request, Closure $next)
{
$mode = '1;mode=block';
$response = $next($request);
$response->headers->set('X-XSS-Protection', $mode);
return $response;
}
}
+1 -1
View File
@@ -878,7 +878,7 @@ class Asset extends Depreciable
$interval = $settings->audit_warning_days ?? 0;
return $query->whereNotNull('assets.next_audit_date')
->whereRaw("DATE_SUB(assets.next_audit_date, INTERVAL $interval DAY) <= '".Carbon::now()."'")
->whereRaw("DATE_SUB(".DB::getTablePrefix()."assets.next_audit_date, INTERVAL $interval DAY) <= '".Carbon::now()."'")
->where('assets.archived', '=', 0)
->NotArchived();
}
+6 -3
View File
@@ -128,9 +128,12 @@ final class Company extends SnipeModel
} elseif (!static::isFullMultipleCompanySupportEnabled()) {
return true;
} else {
$current_user_company_id = Auth::user()->company_id;
$companyable_company_id = $companyable->company_id;
return ($current_user_company_id == null || $current_user_company_id == $companyable_company_id || Auth::user()->isSuperUser());
if (Auth::user()) {
$current_user_company_id = Auth::user()->company_id;
$companyable_company_id = $companyable->company_id;
return ($current_user_company_id == null || $current_user_company_id == $companyable_company_id || Auth::user()->isSuperUser());
}
}
}
+1 -1
View File
@@ -237,7 +237,7 @@ class User extends SnipeModel implements AuthenticatableContract, CanResetPasswo
*/
public function userlog()
{
return $this->hasMany('\App\Models\Actionlog', 'target_id')->orderBy('created_at', 'DESC')->withTrashed();
return $this->hasMany('\App\Models\Actionlog', 'target_id')->where('target_type', '=', 'App\Models\User')->orderBy('created_at', 'DESC')->withTrashed();
}
/**
+5 -2
View File
@@ -268,8 +268,11 @@ class AssetPresenter extends Presenter
"searchable" => true,
"sortable" => true,
"switchable" => true,
"title" => ($field->field_encrypted=='1') ?'<i class="fa fa-lock"></i> '.$field->name : $field->name,
"formatter" => "customFieldsFormatter"
"title" => $field->name,
"formatter"=> 'customFieldsFormatter',
"escape" => true,
"class" => ($field->field_encrypted=='1') ? 'css-padlock' : '',
"visible" => true,
];
}
+23 -9
View File
@@ -197,19 +197,33 @@ return [
/*
|--------------------------------------------------------------------------
| ALLOW I-FRAMING
|--------------------------------------------------------------------------
|
| Normal users will never need to edit this. This option lets you run
| Snipe-IT within an I-Frame, which is normally disabled by default for
| security reasons, to prevent clickjacking. It should normally be set to false.
|
*/
|--------------------------------------------------------------------------
| ALLOW I-FRAMING
|--------------------------------------------------------------------------
|
| Normal users will never need to edit this. This option lets you run
| Snipe-IT within an I-Frame, which is normally disabled by default for
| security reasons, to prevent clickjacking. It should normally be set to false.
|
*/
'allow_iframing' => env('ALLOW_IFRAMING', false),
/*
|--------------------------------------------------------------------------
| ENABLE HTTP Strict Transport Security (HSTS)
|--------------------------------------------------------------------------
|
| This is set to default false for backwards compatibilty but should be
| set to true if the hosting environment allows it.
|
| See https://scotthelme.co.uk/hsts-the-missing-link-in-tls/
|
*/
'enable_hsts' => env('ENABLE_HSTS', false),
/*
|--------------------------------------------------------------------------
| REFERRER-POLICY
+5 -5
View File
@@ -1,10 +1,10 @@
<?php
return array (
'app_version' => 'v4.9.3',
'full_app_version' => 'v4.9.3 - build 4395-g9a2440dc4',
'build_version' => '4395',
'app_version' => 'v4.9.4',
'full_app_version' => 'v4.9.4 - build 4437-g799a93c46',
'build_version' => '4437',
'prerelease_version' => '',
'hash_version' => 'g9a2440dc4',
'full_hash' => 'v4.9.3-42-g9a2440dc4',
'hash_version' => 'g799a93c46',
'full_hash' => 'v4.9.4-41-g799a93c46',
'branch' => 'master',
);
File diff suppressed because one or more lines are too long
+1 -1
View File
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+2 -2
View File
@@ -9487,7 +9487,7 @@ $(document).ready(function () {
var answer = {
results: data.items,
pagination: {
more: "true" //(params.page < data.page_count)
more: data.pagination.more
}
};
@@ -9737,7 +9737,7 @@ $(function () {
var answer = {
results: data.items,
pagination: {
more: "true" //(params.page < data.page_count)
more: data.pagination.more
}
};
File diff suppressed because one or more lines are too long
+1 -1
View File
File diff suppressed because one or more lines are too long
+7 -7
View File
@@ -2,7 +2,7 @@
"/js/build/vue.js": "/js/build/vue.js?id=461ae9803574a5a52d43",
"/css/AdminLTE.css": "/css/AdminLTE.css?id=56b8066cfbc70df10545",
"/css/app.css": "/css/app.css?id=407edb63cc6b6dc62405",
"/css/overrides.css": "/css/overrides.css?id=014ba62bc420467fd405",
"/css/overrides.css": "/css/overrides.css?id=d1fe6296eb548247a5ad",
"/css/skins/skin-blue.css": "/css/skins/skin-blue.css?id=c28283a1d468e2337428",
"/css/skins/skin-red.css": "/css/skins/skin-red.css?id=079dd6c501fa9ea60a98",
"/css/skins/skin-contrast.css": "/css/skins/skin-contrast.css?id=62e14190151e9efc9995",
@@ -18,10 +18,10 @@
"/css/skins/skin-blue-dark.css": "/css/skins/skin-blue-dark.css?id=d25c77d9c6f4cfe2efd4",
"/css/skins/skin-orange-dark.css": "/css/skins/skin-orange-dark.css?id=abc219c1fed59cecb860",
"/css/skins/skin-orange.css": "/css/skins/skin-orange.css?id=59664dbd286988d2a438",
"/js/build/vue.js.map": "/js/build/vue.js.map?id=edafd9b8d5c4f4218518",
"/js/build/vue.js.map": "/js/build/vue.js.map?id=1760ae00d44238e44172",
"/css/AdminLTE.css.map": "/css/AdminLTE.css.map?id=5a2d6f3c59191ce716e2",
"/css/app.css.map": "/css/app.css.map?id=96b5c985e860716e6a16",
"/css/overrides.css.map": "/css/overrides.css.map?id=fe0a3186bd85efc442ca",
"/css/overrides.css.map": "/css/overrides.css.map?id=f3e3cf42859eb4a28a7b",
"/css/skins/skin-blue.css.map": "/css/skins/skin-blue.css.map?id=129b9523e6ffd5683230",
"/css/skins/skin-red.css.map": "/css/skins/skin-red.css.map?id=292dfa49bf2b6f23fa59",
"/css/skins/skin-contrast.css.map": "/css/skins/skin-contrast.css.map?id=bf37f812f0b6a109b5ce",
@@ -37,8 +37,8 @@
"/css/skins/skin-blue-dark.css.map": "/css/skins/skin-blue-dark.css.map?id=32784cb5d02773eb0e69",
"/css/skins/skin-orange-dark.css.map": "/css/skins/skin-orange-dark.css.map?id=68b998638217fd08ef29",
"/css/skins/skin-orange.css.map": "/css/skins/skin-orange.css.map?id=f90fda3cc0a48c048a9e",
"/css/dist/all.css": "/css/dist/all.css?id=32f6e6a70fdaa03a0d88",
"/js/dist/all.js": "/js/dist/all.js?id=bf5cd2065e997d7692e0",
"/css/build/all.css": "/css/build/all.css?id=32f6e6a70fdaa03a0d88",
"/js/build/all.js": "/js/build/all.js?id=bf5cd2065e997d7692e0"
"/css/dist/all.css": "/css/dist/all.css?id=0491555899142b86167d",
"/js/dist/all.js": "/js/dist/all.js?id=4513ccdd4533b52922a8",
"/css/build/all.css": "/css/build/all.css?id=0491555899142b86167d",
"/js/build/all.js": "/js/build/all.js?id=4513ccdd4533b52922a8"
}
+1 -1
View File
@@ -224,7 +224,7 @@ $(document).ready(function () {
var answer = {
results: data.items,
pagination: {
more: "true" //(params.page < data.page_count)
more: data.pagination.more
}
};
+1 -1
View File
@@ -74,7 +74,7 @@ $(function () {
var answer = {
results: data.items,
pagination: {
more: "true" //(params.page < data.page_count)
more: data.pagination.more
}
};
+69
View File
@@ -465,3 +465,72 @@ h4 {
border-top: 1px solid #dddddd;
display: table-cell;
}
/**
COLUMN SELECTOR ICONS
-----------------------------
This is kind of weird, but it is necessary to prevent the column-selector code from barfing, since
any HTML used in the UserPresenter "title" attribute breaks the column selector HTML.
Instead, we use CSS to add the icon into the table header, which leaves the column selector
"title" text as-is.
See https://github.com/snipe/snipe-it/issues/7989
*/
th.css-barcode > .th-inner,
th.css-license > .th-inner,
th.css-consumable > .th-inner,
th.css-accessory > .th-inner
{
font-size: 0px;
line-height: 4!important;
text-align: left;
text-rendering: auto;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
th.css-padlock > .th-inner::before,
th.css-barcode > .th-inner::before,
th.css-license > .th-inner::before,
th.css-consumable > .th-inner::before,
th.css-accessory > .th-inner::before
{
display: inline-block;
font: normal normal normal 14px/1 FontAwesome;
font-size: 20px;
}
th.css-padlock > .th-inner::before
{
content: "\f023";
padding-right: 2px;
}
th.css-barcode > .th-inner::before
{
content: "\f02a";
}
th.css-license > .th-inner::before
{
content: "\f0c7";
}
th.css-consumable > .th-inner::before
{
content: "\f043";
}
th.css-accessory > .th-inner::before
{
content: "\f11c";
}
@@ -276,7 +276,7 @@ View Assets for {{ $user->present()->fullName() }}
}'>
<thead>
<tr>
<th data-switchable="true" data-visible="true" data-field="icon" style="width: 40px;" class="hidden-xs" data-formatter="iconFormatter"><span class="sr-only">Icon</span></th>
<th data-switchable="true" data-visible="true" data-field="icon" style="width: 40px;" class="hidden-xs" data-formatter="iconFormatter">Icon</th>
<th data-switchable="true" data-visible="true" class="col-sm-3" data-field="created_at" data-formatter="dateDisplayFormatter">{{ trans('general.date') }}</th>
<th data-switchable="true" data-visible="true" class="col-sm-3" data-field="admin" data-formatter="usersLinkObjFormatter">{{ trans('general.admin') }}</th>
<th data-switchable="true" data-visible="true" class="col-sm-3" data-field="action_type">{{ trans('general.action') }}</th>
+3 -3
View File
@@ -57,11 +57,11 @@ $qr_size = ($settings->alt_barcode_enabled=='1') && ($settings->alt_barcode!='')
width: 100%;
}
.qr_text {
width: 100%;
height: auto;
width: {{ $settings->labels_width }}in;
height: {{ $settings->labels_height }}in;
padding-top: {{$settings->labels_display_bgutter}}in;
font-family: arial, helvetica, sans-serif;
font-size: x-small;
font-size: {{$settings->labels_fontsize}};
padding-right: .01in;
overflow: hidden !important;
display: inline;
+2 -2
View File
@@ -995,7 +995,7 @@
data-cookie-id-table="assetHistory">
<thead>
<tr>
<th data-field="icon" data-visible="true" style="width: 40px;" class="hidden-xs" data-formatter="iconFormatter"><span class="sr-only">Icon</span></th>
<th data-visible="true" style="width: 40px;" class="hidden-xs">Icon</th>
<th class="col-sm-2" data-visible="true" data-field="created_at" data-formatter="dateDisplayFormatter">{{ trans('general.date') }}</th>
<th class="col-sm-1" data-visible="true" data-field="admin" data-formatter="usersLinkObjFormatter">{{ trans('general.admin') }}</th>
<th class="col-sm-1" data-visible="true" data-field="action_type">{{ trans('general.action') }}</th>
@@ -1039,7 +1039,7 @@
data-cookie-id-table="assetFileHistory">
<thead>
<tr>
<th data-visible="true" data-field="icon"><span class="sr-only">Icon</span></th>
<th data-visible="true" data-field="icon">Icon</th>
<th class="col-md-2" data-searchable="true" data-visible="true" data-field="notes">{{ trans('general.notes') }}</th>
<th class="col-md-2" data-searchable="true" data-visible="true" data-field="image">{{ trans('general.image') }}</th>
<th class="col-md-2" data-searchable="true" data-visible="true" data-field="filename">{{ trans('general.file_name') }}</th>
+4 -4
View File
@@ -326,9 +326,9 @@
<table
data-columns="{{ \App\Presenters\LicensePresenter::dataTableLayoutSeats() }}"
data-cookie-id-table="seatsTable-{{ $license->id }}"
data-id-table="seatsTable-{{ $license->id }}"
id="seatsTable-{{$license->id}}"
data-cookie-id-table="seatsTable"
data-id-table="seatsTable"
id="seatsTable"
data-pagination="true"
data-search="false"
data-side-pagination="server"
@@ -375,7 +375,7 @@
}'>
<thead>
<tr>
<th data-visible="true" aria-hidden="true"><span class="sr-only">Icon</span></th>
<th data-visible="true" aria-hidden="true">Icon</th>
<th class="col-md-4" data-field="file_name" data-visible="true" data-sortable="true" data-switchable="true">{{ trans('general.file_name') }}</th>
<th class="col-md-4" data-field="notes" data-visible="true" data-sortable="true" data-switchable="true">{{ trans('general.notes') }}</th>
<th class="col-md-2" data-field="created_at" data-visible="true" data-sortable="true" data-switchable="true">{{ trans('general.created_at') }}</th>
+1 -1
View File
@@ -37,7 +37,7 @@
<thead>
<tr>
<th data-field="icon" style="width: 40px;" class="hidden-xs" data-formatter="iconFormatter"><span class="sr-only">Icon</span></th>
<th data-field="icon" style="width: 40px;" class="hidden-xs" data-formatter="iconFormatter">Icon</th>
<th class="col-sm-3" data-searchable="false" data-sortable="true" data-field="created_at" data-formatter="dateDisplayFormatter">{{ trans('general.date') }}</th>
<th class="col-sm-2" data-field="admin" data-formatter="usersLinkObjFormatter">{{ trans('general.admin') }}</th>
<th class="col-sm-2" data-field="action_type">{{ trans('general.action') }}</th>
-60
View File
@@ -15,66 +15,6 @@
@section('header_right')
<style>
/**
This is kind of weird, but it is necessary to prevent the column-selector code from barfing, since
any HTML used in the UserPresenter "title" attribute breaks the column selector HTML.
Instead, we use CSS to add the icon into the table header, which leaves the column selector
"title" text as-is.
See https://github.com/snipe/snipe-it/issues/7989
*/
th.css-barcode > .th-inner,
th.css-license > .th-inner,
th.css-consumable > .th-inner,
th.css-accessory > .th-inner
{
font-size: 0px;
line-height: 4!important;
text-align: left;
text-rendering: auto;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
th.css-barcode > .th-inner::before,
th.css-license > .th-inner::before,
th.css-consumable > .th-inner::before,
th.css-accessory > .th-inner::before
{
display: inline-block;
font: normal normal normal 14px/1 FontAwesome;
font-size: 20px;
}
th.css-barcode > .th-inner::before
{
content: "\f02a";
}
th.css-license > .th-inner::before
{
content: "\f0c7";
}
th.css-consumable > .th-inner::before
{
content: "\f043";
}
th.css-accessory > .th-inner::before
{
content: "\f11c";
}
</style>
@can('create', \App\Models\User::class)
@if ($snipeSettings->ldap_enabled == 1)
<a href="{{ route('ldap/user') }}" class="btn btn-default pull-right"><span class="fa fa-sitemap"></span> LDAP Sync</a>
+8 -1
View File
@@ -244,6 +244,13 @@
<td class="text-nowrap">{{ trans('general.login_enabled') }}</td>
<td>{{ ($user->activated=='1') ? trans('general.yes') : trans('general.no') }}</td>
</tr>
@if ($user->ldap_import!='1')
<tr>
<td class="text-nowrap">LDAP</td>
<td>{{ trans('general.yes') }}</td>
</tr>
@endif
@if ($user->activated=='1')
<tr>
@@ -522,7 +529,7 @@
}'>
<thead>
<tr>
<th data-field="icon" style="width: 40px;" class="hidden-xs" data-formatter="iconFormatter"><span class="sr-only">Icon</span></th>
<th data-field="icon" style="width: 40px;" class="hidden-xs" data-formatter="iconFormatter">Icon</th>
<th class="col-sm-3" data-field="created_at" data-formatter="dateDisplayFormatter" data-sortable="true">{{ trans('general.date') }}</th>
<th class="col-sm-2" data-field="admin" data-formatter="usersLinkObjFormatter">{{ trans('general.admin') }}</th>
<th class="col-sm-2" data-field="action_type">{{ trans('general.action') }}</th>
+1 -1
View File
@@ -422,7 +422,7 @@ case $distro in
fi
;;
ubuntu)
if [ "$version" == "18.04" ]; then
if [ "$version" -ge "18.04" ]; then
# Install for Ubuntu 18.04
tzone=$(cat /etc/timezone)