Merge branch 'develop'

This commit is contained in:
snipe 2017-09-29 15:59:40 -07:00
commit 6bc3f194ec
38 changed files with 179 additions and 59 deletions

View file

@ -63,7 +63,13 @@ ENCRYPT=false
COOKIE_NAME=snipeit_session
COOKIE_DOMAIN=null
SECURE_COOKIES=false
# --------------------------------------------
# OPTIONAL: SECURITY HEADER SETTINGS
# --------------------------------------------
REFERRER_POLICY=strict-origin
DISABLE_CSP=false
# --------------------------------------------

View file

@ -12,20 +12,27 @@
#### Please confirm you have done the following before posting your bug report:
- [ ] I have enabled debug mode
- [ ] I have enabled debug mode
- [ ] I have read [checked the Common Issues page](https://snipe-it.readme.io/docs/common-issues)
-----
#### Please provide answers to these questions before posting your bug report:
#### Provide answers to these questions:
- Is this a fresh install or an upgrade?
- Version of Snipe-IT you're running
- Version of PHP you're running
- Version of MySQL/MariaDB you're running
- What OS and web server you're running Snipe-IT on
- What method you used to install Snipe-IT (install.sh, manual installation, docker, etc)
- WITH DEBUG TURNED ON, if you're getting an error in your browser, include that error
- What specific Snipe-IT page you're on, and what specific element you're interacting with to trigger the error
- If a stacktrace is provided in the error, include that too.
- Any errors that appear in your browser's error console.
- Confirm whether the error is [reproduceable on the demo](https://snipeitapp.com/demo).
- Confirm whether the error is reproduceable on the demo: https://snipeitapp.com/demo.
- Include any additional information you can find in `app/storage/logs` and your webserver's logs.
- Include what you've done so far in the installation, and if you got any error messages along the way.
- Indicate whether or not you've manually edited any data directly in the database
Please do not post an issue without answering the related questions above. If you have opened a different issue and already answered these questions, answer them again, once for every ticket. It will be next to impossible for us to help you.
https://snipe-it.readme.io/docs/getting-help

View file

@ -334,15 +334,14 @@ class LicensesController extends Controller
if ($licenseSeat->save()) {
$licenseSeat->logCheckout($request->input('note'), $target);
$data['license_id'] =$licenseSeat->license_id;
$data['license_id'] = $licenseSeat->license_id;
$data['note'] = $request->input('note');
// Redirect to the new asset page
return redirect()->route("licenses.index")->with('success', trans('admin/licenses/message.checkout.success'));
}
// Redirect to the asset management page with error
return redirect()->to("admin/licenses/{$asset_id}/checkout")->with('error', trans('admin/licenses/message.create.error'))->with('license', new License);
return redirect()->route("licenses.index")->with('error', trans('admin/licenses/message.checkout.error'));
}

View file

@ -20,6 +20,7 @@ class Kernel extends HttpKernel
\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,
\App\Http\Middleware\CheckForSetup::class,
\Fideloper\Proxy\TrustProxies::class,

View file

@ -0,0 +1,35 @@
<?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.disable_csp')=='true')) {
$response = $next($request);
return $response;
}
$policy[] = "default-src 'self'";
$policy[] = "style-src 'self' 'unsafe-inline' oss.maxcdn.com";
$policy[] = "script-src 'self' oss.mafxcdn.com cdnjs.cloudflare.com 'nonce-".csrf_token()."'";
$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;
}
}

View file

@ -33,8 +33,8 @@ class AssetsTransformer
'model_number' => ($asset->model) ? e($asset->model->model_number) : null,
'status_label' => ($asset->assetstatus) ? [
'id' => (int) $asset->assetstatus->id,
'name'=> e($asset->assetstatus->name),
'status_type' => e($asset->assetstatus->getStatuslabelType()),
'name'=> e($asset->present()->statusText),
'status_meta' => e($asset->present()->statusMeta),
] : null,
'category' => ($asset->model->category) ? [
'id' => (int) $asset->model->category->id,

View file

@ -325,6 +325,24 @@ class AssetPresenter extends Presenter
return $interval;
}
/**
* @return string
* This handles the status label "meta" status of "deployed" if
* it's assigned. Should maybe deprecate.
*/
public function statusMeta()
{
if ($this->model->assignedTo) {
return strtolower(trans('general.deployed'));
}
return $this->model->assetstatus->getStatuslabelType();
}
/**
* @return string
* This handles the status label "meta" status of "deployed" if
* it's assigned. Should maybe deprecate.
*/
public function statusText()
{
if ($this->model->assignedTo) {
@ -332,6 +350,7 @@ class AssetPresenter extends Presenter
}
return $this->model->assetstatus->name;
}
/**
* Date the warantee expires.
* @return false|string

View file

@ -152,7 +152,7 @@ class LicensePresenter extends Presenter
*/
public function fullName()
{
return 'poop';
return $this->name;
}

View file

@ -169,6 +169,24 @@ return [
'referrer_policy' => env('REFERRER_POLICY', 'strict-origin'),
/*
|--------------------------------------------------------------------------
| CSP
|--------------------------------------------------------------------------
|
| Disable the content security policy that restricts what scripts, images
| and styles can load. (This should be left as false if you don't know
| what this means.)
|
| Read more: https://www.w3.org/TR/CSP/
| Read more: https://content-security-policy.com
|
*/
'disable_csp' => env('DISABLE_CSP', false),
/*
|--------------------------------------------------------------------------

View file

@ -5,10 +5,12 @@
RewriteEngine On
# Uncomment these two lines to force SSL redirect
# Uncomment these two lines to force SSL redirect in Apache
# RewriteCond %{HTTPS} off
# RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
# Redirect Trailing Slashes If Not A Folder...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)/$ /$1 [L,R=301]
@ -21,4 +23,11 @@
# Handle Authorization Header
RewriteCond %{HTTP:Authorization} .
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
# Security Headers
# Header set Strict-Transport-Security "max-age=2592000" env=HTTPS
# Header set X-XSS-Protection "1; mode=block"
# Header set X-Content-Type-Options nosniff
# Header set X-Permitted-Cross-Domain-Policies "master-only"
</IfModule>

View file

@ -94,7 +94,7 @@
@section('moar_scripts')
<script src="{{ asset('js/signature_pad.min.js') }}"></script>
<script>
<script nonce="{{ csrf_token() }}">
var wrapper = document.getElementById("signature-pad"),
clearButton = wrapper.querySelector("[data-action=clear]"),
saveButton = wrapper.querySelector("[data-action=save]"),

View file

@ -16,9 +16,9 @@
@stop
@section('moar_scripts')
<script>
<script nonce="{{ csrf_token() }}">
new Vue({
el: "#app",
});
</script>
@endsection
@endsection

View file

@ -149,7 +149,7 @@
@section('moar_scripts')
<script>
<script nonce="{{ csrf_token() }}">
$( "a[name='Request']").click(function(event) {
// event.preventDefault();

View file

@ -58,7 +58,7 @@
@section('moar_scripts')
@include ('partials.bootstrap-table', ['exportFile' => 'maintenances-export', 'search' => true])
<script>
<script nonce="{{ csrf_token() }}">
function maintenanceActions(value, row) {
var actions = '<nobr>';
if ((row) && (row.available_actions.update === true)) {

View file

@ -134,7 +134,7 @@
@stop
@section('moar_scripts')
<script>
<script nonce="{{ csrf_token() }}">
$(document).ready(function(){
// Only display the custom format field if it's a custom format validation type

View file

@ -82,7 +82,7 @@
@stop
@section('moar_scripts')
<script>
<script nonce="{{ csrf_token() }}">
var fixHelperModified = function(e, tr) {
var $originals = tr.children();
var $helper = tr.clone();

View file

@ -253,7 +253,7 @@
@endif
<script>
<script nonce="{{ csrf_token() }}">

View file

@ -108,7 +108,7 @@
@stop
@section('moar_scripts')
<script>
<script nonce="{{ csrf_token() }}">
$(function() {
$('#assigned_to').on("change",function () {
// console.warn("Model Id has changed!");

View file

@ -154,7 +154,7 @@
@stop
@section('moar_scripts')
<script>
<script nonce="{{ csrf_token() }}">
$(function() {
$('#assigned_user').on("change",function () {
var userid = $('#assigned_user option:selected').val();

View file

@ -160,7 +160,7 @@
@stop
@section('moar_scripts')
<script>
<script nonce="{{ csrf_token() }}">

View file

@ -190,7 +190,7 @@
@endif
</div></div></div>
<script>
<script nonce="{{ csrf_token() }}">
$(document).ready(function(){
$('#generate-password').pGenerator({

View file

@ -125,7 +125,7 @@
@section('moar_scripts')
<script>
<script nonce="{{ csrf_token() }}">
$("#audit-form").submit(function (event) {
$('#audited-div').show();

View file

@ -87,8 +87,8 @@
&nbsp; &nbsp;</span>
</span>
@endif
<a href="{{ route('statuslabels.show', $asset->assetstatus->id) }}">{{ $asset->present()->statusText() }}</a>
<label class="label label-default">{{ $asset->assetstatus->getStatuslabelType() }}</label>
<a href="{{ route('statuslabels.show', $asset->assetstatus->id) }}">{{ $asset->assetstatus->name }}</a>
<label class="label label-default">{{ $asset->present()->statusMeta }}</label>
</td>
</tr>
@endif
@ -703,7 +703,7 @@
@section('moar_scripts')
@include ('partials.bootstrap-table', ['simple_view' => true])
<script>
<script nonce="{{ csrf_token() }}">
$(document).delegate('*[data-toggle="lightbox"]', 'click', function(event) {
event.preventDefault();
$(this).ekkoLightbox();

View file

@ -83,7 +83,7 @@
@stop
@section('moar_scripts')
<script>
<script nonce="{{ csrf_token() }}">
new Vue({
el: '#app'
});

View file

@ -27,13 +27,13 @@
<meta name="csrf-token" content="{{ csrf_token() }}">
<script>
<script nonce="{{ csrf_token() }}">
window.Laravel = { csrfToken: '{{ csrf_token() }}' };
</script>
<style>
<style nonce="{{ csrf_token() }}">
@if ($snipeSettings)
@if ($snipeSettings->header_color)
.main-header .navbar, .main-header .logo {
@ -70,7 +70,7 @@
<script>
<script nonce="{{ csrf_token() }}">
window.snipeit = {
settings: {
"per_page": {{ $snipeSettings->per_page }}
@ -382,17 +382,17 @@
<li{!! (Request::query('status') == 'Deployed' ? ' class="active"' : '') !!}>
<a href="{{ url('hardware?status=Deployed') }}"><i class="fa fa-circle-o text-blue"></i>@lang('general.deployed')
<a href="{{ url('hardware?status=Deployed') }}"><i class="fa fa-circle-o text-blue"></i>All @lang('general.deployed')
</a>
</li>
<li{!! (Request::query('status') == 'RTD' ? ' class="active"' : '') !!}>
<a href="{{ url('hardware?status=RTD') }}">
<i class="fa fa-circle-o text-green"></i>
@lang('general.ready_to_deploy')</a>
All @lang('general.ready_to_deploy')</a>
</li>
<li{!! (Request::query('status') == 'Pending' ? ' class="active"' : '') !!}><a href="{{ url('hardware?status=Pending') }}"><i class="fa fa-circle-o text-orange"></i>@lang('general.pending')</a></li>
<li{!! (Request::query('status') == 'Undeployable' ? ' class="active"' : '') !!} ><a href="{{ url('hardware?status=Undeployable') }}"><i class="fa fa-times text-red"></i>@lang('general.undeployable')</a></li>
<li{!! (Request::query('status') == 'Archived' ? ' class="active"' : '') !!}><a href="{{ url('hardware?status=Archived') }}"><i class="fa fa-times text-red"></i>@lang('admin/hardware/general.archived')</a></li>
<li{!! (Request::query('status') == 'Pending' ? ' class="active"' : '') !!}><a href="{{ url('hardware?status=Pending') }}"><i class="fa fa-circle-o text-orange"></i>All @lang('general.pending')</a></li>
<li{!! (Request::query('status') == 'Undeployable' ? ' class="active"' : '') !!} ><a href="{{ url('hardware?status=Undeployable') }}"><i class="fa fa-times text-red"></i>All @lang('general.undeployable')</a></li>
<li{!! (Request::query('status') == 'Archived' ? ' class="active"' : '') !!}><a href="{{ url('hardware?status=Archived') }}"><i class="fa fa-times text-red"></i>All @lang('admin/hardware/general.archived')</a></li>
<li{!! (Request::query('status') == 'Requestable' ? ' class="active"' : '') !!}><a href="{{ url('hardware?status=Requestable') }}"><i class="fa fa-check text-blue"></i> @lang('admin/hardware/general.requestable')</a></li>
<li class="divider">&nbsp;</li>
@ -661,8 +661,8 @@
<script src="{{ url(mix('js/dist/all.js')) }}"></script>
<script>
<script src="{{ url(mix('js/dist/all.js')) }}" nonce="{{ csrf_token() }}"></script>
<script nonce="{{ csrf_token() }}">
$(function () {
var datepicker = $.fn.datepicker.noConflict(); // return $.fn.datepicker to previously assigned value
$.fn.bootstrapDP = datepicker;
@ -677,14 +677,18 @@
@section('moar_scripts')
@show
<script>
<script nonce="{{ csrf_token() }}">
$(function () {
$('[data-toggle="tooltip"]').tooltip();
})
$(document).on('click', '[data-toggle="lightbox"]', function(event) {
event.preventDefault();
$(this).ekkoLightbox();
});
</script>
@if ((Session::get('topsearch')=='true') || (Request::is('/')))
<script>
<script nonce="{{ csrf_token() }}">
$("#tagSearch").focus();
</script>
@endif

View file

@ -13,7 +13,7 @@
<script>
<script nonce="{{ csrf_token() }}">
window.snipeit = {
settings: {
"per_page": 20
@ -118,9 +118,9 @@
</div>
</div>
</div>
<script src="{{ url(mix('js/dist/all.js')) }}"></script>
<script src="{{ url(mix('js/dist/all.js')) }}" nonce="{{ csrf_token() }}"></script>
<script>
<script nonce="{{ csrf_token() }}">
$(function () {
$(".select2").select2();
});

View file

@ -62,7 +62,7 @@
@if (!$item->id)
@section('moar_scripts')
<script>
<script nonce="{{ csrf_token() }}">
var $eventSelect = $(".parent");
$eventSelect.on("change", function () { parent_details($eventSelect.val()); });

View file

@ -1,7 +1,7 @@
<script src="/js/pGenerator.jquery.js"></script>
<script>
<script nonce="{{ csrf_token() }}">
$(document).ready(function () {
$('#genPassword').pGenerator({

View file

@ -13,7 +13,7 @@
<script src="{{ asset('js/extensions/toolbar/bootstrap-table-toolbar.js') }}"></script>
@endif
<script>
<script nonce="{{ csrf_token() }}">
$('.snipe-table').bootstrapTable({
classes: 'table table-responsive table-no-bordered',
undefinedText: '',
@ -139,8 +139,30 @@ $('.snipe-table').bootstrapTable({
// Use this when we're introspecting into a column object and need to link
function genericColumnObjLinkFormatter(destination) {
return function (value,row) {
if ((value) && (value.status_type)) {
return '<a href="{{ url('/') }}/' + destination + '/' + value.id + '"> ' + value.name + '</a> ' + '<label class="label label-default">'+ value.status_type + '</label>';
if ((value) && (value.status_meta)) {
var text_color;
var icon_style;
switch (value.status_meta) {
case 'deployed':
text_color = 'blue';
icon_style = 'fa-circle';
break;
case 'deployable':
text_color = 'green';
icon_style = 'fa-circle';
break;
case 'pending':
text_color = 'orange';
icon_style = 'fa-circle';
break;
default:
text_color = 'red';
icon_style = 'fa-times';
}
return '<a href="{{ url('/') }}/' + destination + '/' + value.id + '" data-tooltip="true" title="'+ value.status_meta + '"> <i class="fa ' + icon_style + ' text-' + text_color + '"></i> ' + value.name + '</a> ';
} else if ((value) && (value.name)) {
return '<a href="{{ url('/') }}/' + destination + '/' + value.id + '"> ' + value.name + '</a>';
}

View file

@ -24,7 +24,7 @@
@stop
@section('moar_scripts')
<script>
<script nonce="{{ csrf_token() }}">
new Vue({
el: "#app",
});

View file

@ -146,7 +146,7 @@
@section('moar_scripts')
<!-- bootstrap color picker -->
<script>
<script nonce="{{ csrf_token() }}">
//color picker with addon
$(".header-color").colorpicker();
// toggle the disabled state of asset id prefix

View file

@ -199,7 +199,7 @@
@section('moar_scripts')
<!-- bootstrap color picker -->
<script>
<script nonce="{{ csrf_token() }}">
//color picker with addon
$(".header-color").colorpicker();
// toggle the disabled state of asset id prefix

View file

@ -372,7 +372,7 @@
@stop
@section('moar_scripts')
<script>
<script nonce="{{ csrf_token() }}">
$("#ldaptest").click(function(){
$("#ldaptestrow").removeClass('success');
$("#ldaptestrow").removeClass('danger');

View file

@ -57,7 +57,7 @@
@section('moar_scripts')
<!-- bootstrap color picker -->
<script>
<script nonce="{{ csrf_token() }}">
//color picker with addon
$(".color").colorpicker();
</script>

View file

@ -54,7 +54,7 @@
@section('moar_scripts')
@include ('partials.bootstrap-table', ['exportFile' => 'statuslabels-export', 'search' => true])
<script>
<script nonce="{{ csrf_token() }}">
function colorSqFormatter(value, row) {
if (value) {
return '<span class="label" style="background-color: ' + value + ';">&nbsp;</span> ' + value;

View file

@ -553,7 +553,7 @@
@stop
@section('moar_scripts')
<script>
<script nonce="{{ csrf_token() }}">
$(document).ready(function() {
$('#email').on('keyup',function(){
@ -570,7 +570,7 @@ $(document).ready(function() {
});
</script>
<script>
<script nonce="{{ csrf_token() }}">
$('tr.header-row input:radio').click(function() {
value = $(this).attr('value');
$(this).parent().parent().siblings().each(function() {
@ -585,7 +585,7 @@ $('.header-name').click(function() {
<script src="{{ asset('js/pGenerator.jquery.js') }}"></script>
<script>
<script nonce="{{ csrf_token() }}">
$(document).ready(function(){

View file

@ -86,7 +86,7 @@
'columns' => \App\Presenters\UserPresenter::dataTableLayout()
])
<script>
<script nonce="{{ csrf_token() }}">
function groupsFormatter(value) {

View file

@ -491,7 +491,7 @@
@section('moar_scripts')
@include ('partials.bootstrap-table', ['simple_view' => true])
<script>
<script nonce="{{ csrf_token() }}">
$(function () {
//binds to onchange event of your input field
var uploadedFileSize = 0;