Merge remote-tracking branch 'origin/develop'

This commit is contained in:
snipe 2021-01-26 12:20:57 -08:00
commit 01d3606c42
40 changed files with 234 additions and 61 deletions

View file

@ -1,6 +1,6 @@
FROM alpine:3.12
# Apache + PHP
RUN apk add --update --no-cache \
RUN apk add --no-cache \
apache2 \
php7 \
php7-common \

View file

@ -25,6 +25,7 @@ class Handler extends ExceptionHandler
\Illuminate\Session\TokenMismatchException::class,
\Illuminate\Validation\ValidationException::class,
\Intervention\Image\Exception\NotSupportedException::class,
\League\OAuth2\Server\Exception\OAuthServerException::class,
];
/**

View file

@ -189,8 +189,8 @@ class LoginController extends Controller
return redirect()->back()->withInput()->withErrors($validator);
}
$this->maxLoginAttempts = config('auth.throttle.max_attempts');
$this->lockoutTime = config('auth.throttle.lockout_duration');
$this->maxLoginAttempts = config('auth.passwords.users.throttle.max_attempts');
$this->lockoutTime = config('auth.passwords.users.throttle.lockout_duration');
if ($lockedOut = $this->hasTooManyLoginAttempts($request)) {
$this->fireLockoutEvent($request);
@ -452,8 +452,8 @@ class LoginController extends Controller
*/
protected function hasTooManyLoginAttempts(Request $request)
{
$lockoutTime = config('auth.throttle.lockout_duration');
$maxLoginAttempts = config('auth.throttle.max_attempts');
$lockoutTime = config('auth.passwords.users.throttle.lockout_duration');
$maxLoginAttempts = config('auth.passwords.users.throttle.max_attempts');
return $this->limiter()->tooManyAttempts(
$this->throttleKey($request),

View file

@ -0,0 +1,23 @@
<?php
namespace App\Http\Controllers;
use Illuminate\Routing\Controller as BaseController;
/**
* This controller provide the healthz route for
* the Snipe-IT Asset Management application.
*
* @version v1.0
*/
class HealthController extends BaseController
{
/**
* Returns a fixed JSON content ({ "status": "ok"}) which indicate the app is up and running
*/
public function get() {
return response()->json([
"status" => "ok"
]);
}
}

View file

@ -633,6 +633,14 @@ class ReportsController extends Controller
$assets->whereBetween('assets.expected_checkin', [$request->input('expected_checkin_start'), $request->input('expected_checkin_end')]);
}
if (($request->filled('last_audit_start')) && ($request->filled('last_audit_end'))) {
$assets->whereBetween('assets.last_audit_date', [$request->input('last_audit_start'), $request->input('last_audit_end')]);
}
if (($request->filled('next_audit_start')) && ($request->filled('next_audit_end'))) {
$assets->whereBetween('assets.next_audit_date', [$request->input('next_audit_start'), $request->input('next_audit_end')]);
}
$assets->orderBy('assets.created_at', 'ASC')->chunk(20, function($assets) use($handle, $customfields, $request) {
$executionTime = microtime(true) - $_SERVER["REQUEST_TIME_FLOAT"];

View file

@ -14,6 +14,7 @@ class Kernel extends HttpKernel
* @var array
*/
protected $middleware = [
\App\Http\Middleware\NoSessionStore::class,
\Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode::class,
\Illuminate\Session\Middleware\StartSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,

View file

@ -27,7 +27,7 @@ class CheckForSetup
}
} else {
if (!($request->is('setup*')) && !($request->is('.env'))) {
if (!($request->is('setup*')) && !($request->is('.env')) && !($request->is('health'))) {
return redirect(url('/').'/setup');
}

View file

@ -0,0 +1,29 @@
<?php
namespace App\Http\Middleware;
use Closure;
class NoSessionStore
{
protected $except = [
'health'
];
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
foreach ($this->except as $except) {
if ($request->is($except)) {
config()->set('session.driver', 'array');
}
}
return $next($request);
}
}

View file

@ -12,5 +12,6 @@ class VerifyCsrfToken extends BaseVerifier
* @var array
*/
protected $except = [
'health'
];
}

View file

@ -287,7 +287,10 @@ class CustomField extends Model
{
$arr = preg_split("/\\r\\n|\\r|\\n/", $this->field_values);
if (($this->element!='checkbox') && ($this->element!='checkbox')) {
$result[''] = 'Select '.strtolower($this->format);
}
for ($x = 0; $x < count($arr); $x++) {
$arr_parts = explode('|', $arr[$x]);

View file

@ -103,7 +103,10 @@ return [
'email' => 'auth.emails.password',
'table' => 'password_resets',
'expire' => env('RESET_PASSWORD_LINK_EXPIRES', 900),
'throttle' => env('LOGIN_MAX_ATTEMPTS', 60),
'throttle' => [
'max_attempts' => env('LOGIN_MAX_ATTEMPTS', 5),
'lockout_duration' => env('LOGIN_LOCKOUT_DURATION', 60)
],
],
],

View file

@ -0,0 +1,41 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class FixBadLdapServerUrlForV5 extends Migration
{
/**
* Under v4 and previous versions of Snipe-IT, we permitted users to incorrectly specify LDAP URL's in their settings, and Snipe-IT
* would silently permit that.
*
* v5's LDAP system is not so lenient, and requires either ldap:// or ldaps:// in front of the server's URL. This migration tries
* to find misconfigured LDAP URL's and prepend 'ldap://' to them. (That's what we assumed if we *didn't* see ldaps://)
*/
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
// UPDATE settings SET ldap_server = CONCAT('ldap://',ldap_server) WHERE ldap_server NOT LIKE 'ldap://%' AND ldap_server NOT LIKE 'ldaps://%'
$settings = App\Models\Setting::where("ldap_server","not like","ldap://%")->where("ldap_server","not like","ldaps://%");
foreach($settings->get() AS $setting) { // we don't formally support having multiple settings records, but just in case they come up...
$setting->ldap_server = "ldap://".$setting->ldap_server;
$setting->save();
}
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
// Since previous versions supported ldap:// URL's just fine, we don't need to migrate these changes back out on rollback.
}
}

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.

View file

@ -7,27 +7,27 @@
"/css/dist/skins/skin-red.css": "/css/dist/skins/skin-red.css?id=9f62f7b52ce7bc11ddfd",
"/css/dist/skins/skin-contrast.css": "/css/dist/skins/skin-contrast.css?id=cf23e72b9c963c5ab23a",
"/css/dist/skins/skin-green.css": "/css/dist/skins/skin-green.css?id=77ce26763889742cbb58",
"/css/dist/skins/skin-green-dark.css": "/css/dist/skins/skin-green-dark.css?id=b0e148606607e0b37024",
"/css/dist/skins/skin-green-dark.css": "/css/dist/skins/skin-green-dark.css?id=26495da663d45d22a6a3",
"/css/dist/skins/skin-black.css": "/css/dist/skins/skin-black.css?id=87b54289d2c1370974d1",
"/css/dist/skins/skin-black-dark.css": "/css/dist/skins/skin-black-dark.css?id=1d7bbdce51b6f4499215",
"/css/dist/skins/skin-red-dark.css": "/css/dist/skins/skin-red-dark.css?id=c9e2feba8a06c5b23311",
"/css/dist/skins/skin-black-dark.css": "/css/dist/skins/skin-black-dark.css?id=e236b946c22e46b3e140",
"/css/dist/skins/skin-red-dark.css": "/css/dist/skins/skin-red-dark.css?id=a0354af13a9e5f1fd9e4",
"/css/dist/skins/skin-purple.css": "/css/dist/skins/skin-purple.css?id=3e904c2867143e27aebf",
"/css/dist/skins/skin-purple-dark.css": "/css/dist/skins/skin-purple-dark.css?id=da3b392add13bd3a718a",
"/css/dist/skins/skin-purple-dark.css": "/css/dist/skins/skin-purple-dark.css?id=491f44eecee65bbd8c4a",
"/css/dist/skins/skin-yellow.css": "/css/dist/skins/skin-yellow.css?id=11813086909e31b3d753",
"/css/dist/skins/skin-yellow-dark.css": "/css/dist/skins/skin-yellow-dark.css?id=9ef2dc916a64083f9c1c",
"/css/dist/skins/skin-blue-dark.css": "/css/dist/skins/skin-blue-dark.css?id=775e088af6b1151ec134",
"/css/dist/skins/skin-orange-dark.css": "/css/dist/skins/skin-orange-dark.css?id=3f1d75db372eb87d8d51",
"/css/dist/skins/skin-yellow-dark.css": "/css/dist/skins/skin-yellow-dark.css?id=c6961dc48135f991c756",
"/css/dist/skins/skin-blue-dark.css": "/css/dist/skins/skin-blue-dark.css?id=f53016b009b4adab0ac0",
"/css/dist/skins/skin-orange-dark.css": "/css/dist/skins/skin-orange-dark.css?id=1c319a5b2494db9c85a3",
"/css/dist/skins/skin-orange.css": "/css/dist/skins/skin-orange.css?id=d1cda85cbff0723be5f7",
"/css/dist/all.css": "/css/dist/all.css?id=fc64989106daf3be016b",
"/css/blue.png": "/css/blue.png?id=4c85d6a97173123bd14a",
"/css/blue@2x.png": "/css/blue@2x.png?id=62c67c6a822439e8a4ac",
"/css/dist/skins/skin-green-dark.min.css": "/css/dist/skins/skin-green-dark.min.css?id=b0e148606607e0b37024",
"/css/dist/skins/skin-black-dark.min.css": "/css/dist/skins/skin-black-dark.min.css?id=1d7bbdce51b6f4499215",
"/css/dist/skins/skin-blue-dark.min.css": "/css/dist/skins/skin-blue-dark.min.css?id=775e088af6b1151ec134",
"/css/dist/skins/skin-yellow-dark.min.css": "/css/dist/skins/skin-yellow-dark.min.css?id=9ef2dc916a64083f9c1c",
"/css/dist/skins/skin-red-dark.min.css": "/css/dist/skins/skin-red-dark.min.css?id=c9e2feba8a06c5b23311",
"/css/dist/skins/skin-purple-dark.min.css": "/css/dist/skins/skin-purple-dark.min.css?id=da3b392add13bd3a718a",
"/css/dist/skins/skin-orange-dark.min.css": "/css/dist/skins/skin-orange-dark.min.css?id=3f1d75db372eb87d8d51",
"/css/dist/skins/skin-green-dark.min.css": "/css/dist/skins/skin-green-dark.min.css?id=26495da663d45d22a6a3",
"/css/dist/skins/skin-black-dark.min.css": "/css/dist/skins/skin-black-dark.min.css?id=e236b946c22e46b3e140",
"/css/dist/skins/skin-blue-dark.min.css": "/css/dist/skins/skin-blue-dark.min.css?id=f53016b009b4adab0ac0",
"/css/dist/skins/skin-yellow-dark.min.css": "/css/dist/skins/skin-yellow-dark.min.css?id=c6961dc48135f991c756",
"/css/dist/skins/skin-red-dark.min.css": "/css/dist/skins/skin-red-dark.min.css?id=a0354af13a9e5f1fd9e4",
"/css/dist/skins/skin-purple-dark.min.css": "/css/dist/skins/skin-purple-dark.min.css?id=491f44eecee65bbd8c4a",
"/css/dist/skins/skin-orange-dark.min.css": "/css/dist/skins/skin-orange-dark.min.css?id=1c319a5b2494db9c85a3",
"/css/dist/skins/skin-contrast.min.css": "/css/dist/skins/skin-contrast.min.css?id=cf23e72b9c963c5ab23a",
"/css/dist/signature-pad.css": "/css/dist/signature-pad.css?id=6a89d3cd901305e66ced",
"/css/build/signature-pad.min.css": "/css/build/signature-pad.min.css?id=d41d8cd98f00b204e980",

View file

@ -159,7 +159,7 @@ body {
}
.box-body, .box-footer, .box-header {
background-color: var(--back-sub);
color: var(--text-main);
color: var(--header);
}
.btn-default{
background-color: var(--back-main);
@ -211,6 +211,10 @@ body {
background-color: var(--back-main);
color: var(--text-main);
}
.form-control[disabled], .form-control[readonly], fieldset[disabled] .form-control{
background-color: var(--back-main);
color: var(--text-main);
}
h1, h2, h3, h4, h5, h6, p {
color: var(--text-main);
}
@ -306,13 +310,12 @@ input[type=text], input[type=search] {
a {
color: var(--link);
&:link {
color: var(--link);
}
color: var(--header) }
&:hover {
color: var(--light-link);
}
&:visited {
color: var(--link);
color: var(--header)
}
}

View file

@ -154,7 +154,7 @@ body {
}
.box-body, .box-footer, .box-header {
background-color: var(--back-sub);
color: var(--text-main);
color: var(--header);
}
.btn-default{
background-color: var(--back-main);
@ -206,6 +206,10 @@ body {
background-color: var(--back-main);
color: var(--text-main);
}
.form-control[disabled], .form-control[readonly], fieldset[disabled] .form-control{
background-color: var(--back-main);
color: var(--text-main);
}
h1, h2, h3, h4, h5, h6, p {
color: var(--text-main);
}
@ -301,13 +305,12 @@ input[type=text], input[type=search] {
a {
color: var(--link);
&:link {
color: var(--link);
}
color: var(--header) }
&:hover {
color: var(--light-link);
}
&:visited {
color: var(--link);
color: var(--header)
}
}

View file

@ -163,7 +163,7 @@ body {
}
.box-body, .box-footer, .box-header {
background-color: var(--back-sub);
color: var(--text-main);
color: var(--header);
}
.btn-default{
background-color: var(--back-main);
@ -222,6 +222,10 @@ body {
background-color: var(--back-main);
color: var(--text-main);
}
.form-control[disabled], .form-control[readonly], fieldset[disabled] .form-control{
background-color: var(--back-main);
color: var(--text-main);
}
h1, h2, h3, h4, h5, h6, p {
color: var(--text-main);
}
@ -322,13 +326,12 @@ li.select2-results__option{
a {
color: var(--link);
&:link {
color: var(--link);
}
color: var(--header) }
&:hover {
color: var(--light-link);
}
&:visited {
color: var(--link);
color: var(--header)
}
}

View file

@ -159,7 +159,7 @@ body {
}
.box-body, .box-footer, .box-header {
background-color: var(--back-sub);
color: var(--text-main);
color: var(--header);
}
.btn-default{
background-color: var(--back-main);
@ -211,6 +211,10 @@ body {
background-color: var(--back-main);
color: var(--text-main);
}
.form-control[disabled], .form-control[readonly], fieldset[disabled] .form-control{
background-color: var(--back-main);
color: var(--text-main);
}
h1, h2, h3, h4, h5, h6, p {
color: var(--text-main);
}
@ -306,13 +310,12 @@ input[type=text], input[type=search] {
a {
color: var(--link);
&:link {
color: var(--link);
}
color: var(--header) }
&:hover {
color: var(--light-link);
}
&:visited {
color: var(--link);
color: var(--header)
}
}

View file

@ -159,7 +159,7 @@ body {
}
.box-body, .box-footer, .box-header {
background-color: var(--back-sub);
color: var(--text-main);
color: var(--header);
}
.btn-default{
background-color: var(--back-main);
@ -211,6 +211,10 @@ body {
background-color: var(--back-main);
color: var(--text-main);
}
.form-control[disabled], .form-control[readonly], fieldset[disabled] .form-control{
background-color: var(--back-main);
color: var(--text-main);
}
h1, h2, h3, h4, h5, h6, p {
color: var(--text-main);
}
@ -306,13 +310,12 @@ input[type=text], input[type=search] {
a {
color: var(--link);
&:link {
color: var(--link);
}
color: var(--header) }
&:hover {
color: var(--light-link);
}
&:visited {
color: var(--link);
color: var(--header)
}
}

View file

@ -153,7 +153,7 @@ body {
}
.box-body, .box-footer, .box-header {
background-color: var(--back-sub);
color: var(--text-main);
color: var(--header);
}
.btn-default{
background-color: var(--back-main);
@ -205,6 +205,10 @@ body {
background-color: var(--back-main);
color: var(--text-main);
}
.form-control[disabled], .form-control[readonly], fieldset[disabled] .form-control{
background-color: var(--back-main);
color: var(--text-main);
}
h1, h2, h3, h4, h5, h6, p {
color: var(--text-main);
}
@ -306,13 +310,12 @@ input[type=text], input[type=search] {
a {
color: var(--link);
&:link {
color: var(--link);
}
color: var(--header) }
&:hover {
color: var(--light-link);
}
&:visited {
color: var(--link);
color: var(--header)
}
}

View file

@ -153,7 +153,7 @@ body {
}
.box-body, .box-footer, .box-header {
background-color: var(--back-sub);
color: var(--text-main);
color: var(--header);
}
.btn-default{
background-color: var(--back-main);
@ -205,6 +205,10 @@ body {
background-color: var(--back-main);
color: var(--text-main);
}
.form-control[disabled], .form-control[readonly], fieldset[disabled] .form-control{
background-color: var(--back-main);
color: var(--text-main);
}
h1, h2, h3, h4, h5, h6, p {
color: var(--text-main);
}
@ -306,13 +310,12 @@ input[type=text], input[type=search] {
a {
color: var(--link);
&:link {
color: var(--link);
}
color: var(--header) }
&:hover {
color: var(--light-link);
}
&:visited {
color: var(--link);
color: var(--header)
}
}

View file

@ -67,7 +67,7 @@
{{ Form::label('checkout_at', trans('admin/hardware/form.checkout_date'), array('class' => 'col-md-3 control-label')) }}
<div class="col-md-8">
<div class="input-group date col-md-7" data-provide="datepicker" data-date-format="yyyy-mm-dd" data-date-end-date="0d">
<input type="text" class="form-control" placeholder="{{ trans('general.select_date') }}" name="checkout_at" id="checkout_at" value="{{ old('checkout_at') }}">
<input type="text" class="form-control" placeholder="{{ trans('general.select_date') }}" name="checkout_at" id="checkout_at" value="{{ old('checkout_at', date('Y-m-d')) }}">
<span class="input-group-addon"><i class="fa fa-calendar" aria-hidden="true"></i></span>
</div>
{!! $errors->first('checkout_at', '<span class="alert-msg" aria-hidden="true"><i class="fa fa-times" aria-hidden="true"></i> :message</span>') !!}

View file

@ -66,15 +66,14 @@
</div>
@include ('partials.forms.edit.status', [ 'required' => 'true'])
@if (!$item->id)
@include ('partials.forms.checkout-selector', ['user_select' => 'true','asset_select' => 'true', 'location_select' => 'true', 'style' => 'display:none;'])
@include ('partials.forms.edit.user-select', ['translated_name' => trans('admin/hardware/form.checkout_to'), 'fieldname' => 'assigned_user', 'style' => 'display:none;', 'required' => 'false'])
@include ('partials.forms.edit.asset-select', ['translated_name' => trans('admin/hardware/form.checkout_to'), 'fieldname' => 'assigned_asset', 'style' => 'display:none;', 'required' => 'false'])
@include ('partials.forms.edit.location-select', ['translated_name' => trans('admin/hardware/form.checkout_to'), 'fieldname' => 'assigned_location', 'style' => 'display:none;', 'required' => 'false'])
@elseif (($item->assignedTo) && ($item->deleted_at==''))
<!-- This is an asset and it's currently deployed, so let them edit the expected checkin date -->
@include ('partials.forms.edit.datepicker', ['translated_name' => trans('admin/hardware/form.expected_checkin'),'fieldname' => 'expected_checkin'])
@endif
@include ('partials.forms.edit.name', ['translated_name' => trans('admin/hardware/form.name')])

View file

@ -21,7 +21,8 @@
<div>
<label>
<input type="checkbox" value="1" name="{{ $field->db_column_name() }}[]" class="minimal" {{ Request::old($field->db_column_name()) != '' ? ' checked="checked"' : '' }}> key: {{ $key }} value: {{ $value }}
<input type="checkbox" value="1" name="{{ $field->db_column_name() }}[]" class="minimal" {{ Request::old($field->db_column_name()) != '' ? ' checked="checked"' : '' }}>
{{ $value }}
</label>
</div>
@endforeach

View file

@ -0,0 +1,12 @@
<!-- Datepicker -->
<div class="form-group{{ $errors->has($fieldname) ? ' has-error' : '' }}">
{{ Form::label($fieldname, $translated_name, array('class' => 'col-md-3 control-label')) }}
<div class="input-group col-md-3">
<div class="input-group date" data-provide="datepicker" data-date-format="yyyy-mm-dd" data-autoclose="true">
<input type="text" class="form-control" placeholder="{{ trans('general.select_date') }}" name="{{ $fieldname }}" id="{{ $fieldname }}" value="{{ old($fieldname, ($item->{$fieldname}) ? $item->{$fieldname}->format('Y-m-d') : '') }}">
<span class="input-group-addon"><i class="fa fa-calendar" aria-hidden="true"></i></span>
</div>
{!! $errors->first($fieldname, '<span class="alert-msg" aria-hidden="true"><i class="fa fa-times" aria-hidden="true"></i> :message</span>') !!}
</div>
</div>

View file

@ -316,7 +316,25 @@
</div>
</div>
<!-- Last Audit Date -->
<div class="form-group last_audit-range">
<label for="last_audit_start" class="col-md-3 control-label">{{ trans('general.last_audit') }}</label>
<div class="input-daterange input-group col-md-6" id="datepicker">
<input type="text" class="input-sm form-control" name="last_audit_start" aria-label="last_audit_start">
<span class="input-group-addon">to</span>
<input type="text" class="input-sm form-control" name="last_audit_end" aria-label="last_audit_end">
</div>
</div>
<!-- Next Audit Date -->
<div class="form-group next_audit-range">
<label for="next_audit_start" class="col-md-3 control-label">{{ trans('general.next_audit_date') }}</label>
<div class="input-daterange input-group col-md-6" id="datepicker">
<input type="text" class="input-sm form-control" name="next_audit_start" aria-label="nex_audit_start">
<span class="input-group-addon">to</span>
<input type="text" class="input-sm form-control" name="next_audit_end" aria-label="next_audit_end">
</div>
</div>
<div class="col-md-9 col-md-offset-3">
<label>
@ -356,6 +374,19 @@
format: 'yyyy-mm-dd'
});
$('.last_audit-range .input-daterange').datepicker({
clearBtn: true,
todayHighlight: true,
endDate:'0d',
format: 'yyyy-mm-dd'
});
$('.next_audit-range .input-daterange').datepicker({
clearBtn: true,
todayHighlight: true,
format: 'yyyy-mm-dd'
});
// Check-all / Uncheck all
$(function () {
var checkAll = $('input.all');

View file

@ -464,5 +464,4 @@ Route::group(['middleware' => 'web'], function () {
Auth::routes();
Route::get('/health', [ 'as' => 'health', 'uses' => 'HealthController@get']);