Merge remote-tracking branch 'origin/develop'

This commit is contained in:
snipe 2023-02-22 12:24:52 -08:00
commit 225b6ef310
15 changed files with 205 additions and 23 deletions

View file

@ -2837,6 +2837,15 @@
"contributions": [
"code"
]
},
{
"login": "AndrewSav",
"name": "Andrew Savinykh",
"avatar_url": "https://avatars.githubusercontent.com/u/658865?v=4",
"profile": "https://github.com/AndrewSav",
"contributions": [
"code"
]
}
]
}

View file

@ -1,5 +1,5 @@
![Build Status](https://app.chipperci.com/projects/0e5f8979-31eb-4ee6-9abf-050b76ab0383/status/master) [![Crowdin](https://d322cqt584bo4o.cloudfront.net/snipe-it/localized.svg)](https://crowdin.com/project/snipe-it) [![Docker Pulls](https://img.shields.io/docker/pulls/snipe/snipe-it.svg)](https://hub.docker.com/r/snipe/snipe-it/) [![Twitter Follow](https://img.shields.io/twitter/follow/snipeitapp.svg?style=social)](https://twitter.com/snipeitapp) [![Codacy Badge](https://api.codacy.com/project/badge/Grade/553ce52037fc43ea99149785afcfe641)](https://www.codacy.com/app/snipe/snipe-it?utm_source=github.com&utm_medium=referral&utm_content=snipe/snipe-it&utm_campaign=Badge_Grade)
[![All Contributors](https://img.shields.io/badge/all_contributors-312-orange.svg?style=flat-square)](#contributors) [![Discord](https://badgen.net/badge/icon/discord?icon=discord&label)](https://discord.gg/yZFtShAcKk) [![huntr](https://cdn.huntr.dev/huntr_security_badge_mono.svg)](https://huntr.dev)
[![All Contributors](https://img.shields.io/badge/all_contributors-313-orange.svg?style=flat-square)](#contributors) [![Discord](https://badgen.net/badge/icon/discord?icon=discord&label)](https://discord.gg/yZFtShAcKk) [![huntr](https://cdn.huntr.dev/huntr_security_badge_mono.svg)](https://huntr.dev)
## Snipe-IT - Open Source Asset Management System
@ -140,7 +140,7 @@ Thanks goes to all of these wonderful people ([emoji key](https://github.com/ken
| [<img src="https://avatars.githubusercontent.com/u/97299851?v=4" width="110px;"/><br /><sub>Christian Weirich</sub>](https://github.com/chrisweirich)<br />[💻](https://github.com/snipe/snipe-it/commits?author=chrisweirich "Code") | [<img src="https://avatars.githubusercontent.com/u/1294403?v=4" width="110px;"/><br /><sub>denzfarid</sub>](https://github.com/denzfarid)<br /> | [<img src="https://avatars.githubusercontent.com/u/94018771?v=4" width="110px;"/><br /><sub>ntbutler-nbcs</sub>](https://github.com/ntbutler-nbcs)<br />[💻](https://github.com/snipe/snipe-it/commits?author=ntbutler-nbcs "Code") | [<img src="https://avatars.githubusercontent.com/u/172697?v=4" width="110px;"/><br /><sub>Naveen</sub>](https://naveensrinivasan.dev)<br />[💻](https://github.com/snipe/snipe-it/commits?author=naveensrinivasan "Code") | [<img src="https://avatars.githubusercontent.com/u/55674383?v=4" width="110px;"/><br /><sub>Mike Roquemore</sub>](https://github.com/mikeroq)<br />[💻](https://github.com/snipe/snipe-it/commits?author=mikeroq "Code") | [<img src="https://avatars.githubusercontent.com/u/7991086?v=4" width="110px;"/><br /><sub>Daniel Reeder</sub>](https://github.com/reederda)<br />[🌍](#translation-reederda "Translation") [🌍](#translation-reederda "Translation") [💻](https://github.com/snipe/snipe-it/commits?author=reederda "Code") | [<img src="https://avatars.githubusercontent.com/u/109422491?v=4" width="110px;"/><br /><sub>vickyjaura183</sub>](https://github.com/vickyjaura183)<br />[💻](https://github.com/snipe/snipe-it/commits?author=vickyjaura183 "Code") |
| [<img src="https://avatars.githubusercontent.com/u/32363424?v=4" width="110px;"/><br /><sub>Peace</sub>](https://github.com/julian-piehl)<br />[💻](https://github.com/snipe/snipe-it/commits?author=julian-piehl "Code") | [<img src="https://avatars.githubusercontent.com/u/231528?v=4" width="110px;"/><br /><sub>Kyle Gordon</sub>](https://github.com/kylegordon)<br />[💻](https://github.com/snipe/snipe-it/commits?author=kylegordon "Code") | [<img src="https://avatars.githubusercontent.com/u/53009155?v=4" width="110px;"/><br /><sub>Katharina Drexel</sub>](http://www.bfh.ch)<br />[💻](https://github.com/snipe/snipe-it/commits?author=sunflowerbofh "Code") | [<img src="https://avatars.githubusercontent.com/u/1931963?v=4" width="110px;"/><br /><sub>David Sferruzza</sub>](https://david.sferruzza.fr/)<br />[💻](https://github.com/snipe/snipe-it/commits?author=dsferruzza "Code") | [<img src="https://avatars.githubusercontent.com/u/19511639?v=4" width="110px;"/><br /><sub>Rick Nelson</sub>](https://github.com/rnelsonee)<br />[💻](https://github.com/snipe/snipe-it/commits?author=rnelsonee "Code") | [<img src="https://avatars.githubusercontent.com/u/94169344?v=4" width="110px;"/><br /><sub>BasO12</sub>](https://github.com/BasO12)<br />[💻](https://github.com/snipe/snipe-it/commits?author=BasO12 "Code") | [<img src="https://avatars.githubusercontent.com/u/111710123?v=4" width="110px;"/><br /><sub>Vautia</sub>](https://github.com/Vautia)<br />[💻](https://github.com/snipe/snipe-it/commits?author=Vautia "Code") |
| [<img src="https://avatars.githubusercontent.com/u/28321?v=4" width="110px;"/><br /><sub>Chris Hartjes</sub>](http://www.littlehart.net/atthekeyboard)<br />[💻](https://github.com/snipe/snipe-it/commits?author=chartjes "Code") | [<img src="https://avatars.githubusercontent.com/u/2404584?v=4" width="110px;"/><br /><sub>geo-chen</sub>](https://github.com/geo-chen)<br />[💻](https://github.com/snipe/snipe-it/commits?author=geo-chen "Code") | [<img src="https://avatars.githubusercontent.com/u/6006620?v=4" width="110px;"/><br /><sub>Phan Nguyen</sub>](https://github.com/nh314)<br />[💻](https://github.com/snipe/snipe-it/commits?author=nh314 "Code") | [<img src="https://avatars.githubusercontent.com/u/115993812?v=4" width="110px;"/><br /><sub>Iisakki Jaakkola</sub>](https://github.com/StarlessNights)<br />[💻](https://github.com/snipe/snipe-it/commits?author=StarlessNights "Code") | [<img src="https://avatars.githubusercontent.com/u/22633385?v=4" width="110px;"/><br /><sub>Ikko Ashimine</sub>](https://bandism.net/)<br />[💻](https://github.com/snipe/snipe-it/commits?author=eltociear "Code") | [<img src="https://avatars.githubusercontent.com/u/56871540?v=4" width="110px;"/><br /><sub>Lukas Fehling</sub>](https://github.com/lukasfehling)<br />[💻](https://github.com/snipe/snipe-it/commits?author=lukasfehling "Code") | [<img src="https://avatars.githubusercontent.com/u/1975990?v=4" width="110px;"/><br /><sub>Fernando Almeida</sub>](https://github.com/fernando-almeida)<br />[💻](https://github.com/snipe/snipe-it/commits?author=fernando-almeida "Code") |
| [<img src="https://avatars.githubusercontent.com/u/116301219?v=4" width="110px;"/><br /><sub>akemidx</sub>](https://github.com/akemidx)<br />[💻](https://github.com/snipe/snipe-it/commits?author=akemidx "Code") | [<img src="https://avatars.githubusercontent.com/u/144778?v=4" width="110px;"/><br /><sub>Oguz Bilgic</sub>](http://oguz.site)<br />[💻](https://github.com/snipe/snipe-it/commits?author=oguzbilgic "Code") | [<img src="https://avatars.githubusercontent.com/u/9262438?v=4" width="110px;"/><br /><sub>Scooter Crawford</sub>](https://github.com/scoo73r)<br />[💻](https://github.com/snipe/snipe-it/commits?author=scoo73r "Code") | [<img src="https://avatars.githubusercontent.com/u/5957345?v=4" width="110px;"/><br /><sub>subdriven</sub>](https://github.com/subdriven)<br />[💻](https://github.com/snipe/snipe-it/commits?author=subdriven "Code") |
| [<img src="https://avatars.githubusercontent.com/u/116301219?v=4" width="110px;"/><br /><sub>akemidx</sub>](https://github.com/akemidx)<br />[💻](https://github.com/snipe/snipe-it/commits?author=akemidx "Code") | [<img src="https://avatars.githubusercontent.com/u/144778?v=4" width="110px;"/><br /><sub>Oguz Bilgic</sub>](http://oguz.site)<br />[💻](https://github.com/snipe/snipe-it/commits?author=oguzbilgic "Code") | [<img src="https://avatars.githubusercontent.com/u/9262438?v=4" width="110px;"/><br /><sub>Scooter Crawford</sub>](https://github.com/scoo73r)<br />[💻](https://github.com/snipe/snipe-it/commits?author=scoo73r "Code") | [<img src="https://avatars.githubusercontent.com/u/5957345?v=4" width="110px;"/><br /><sub>subdriven</sub>](https://github.com/subdriven)<br />[💻](https://github.com/snipe/snipe-it/commits?author=subdriven "Code") | [<img src="https://avatars.githubusercontent.com/u/658865?v=4" width="110px;"/><br /><sub>Andrew Savinykh</sub>](https://github.com/AndrewSav)<br />[💻](https://github.com/snipe/snipe-it/commits?author=AndrewSav "Code") |
<!-- ALL-CONTRIBUTORS-LIST:END -->
This project follows the [all-contributors](https://github.com/kentcdodds/all-contributors) specification. Contributions of any kind welcome!

View file

@ -56,7 +56,7 @@ class CheckoutLicenseToAllUsers extends Command
return false;
}
$users = User::whereNull('deleted_at')->with('licenses')->get();
$users = User::whereNull('deleted_at')->where('autoassign_licenses', '==', 1)->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. ');

View file

@ -121,6 +121,7 @@ class UsersController extends Controller
$user->created_by = Auth::user()->id;
$user->start_date = $request->input('start_date', null);
$user->end_date = $request->input('end_date', null);
$user->autoassign_licenses= $request->input('autoassign_licenses', 1);
// Strip out the superuser permission if the user isn't a superadmin
$permissions_array = $request->input('permission');
@ -274,6 +275,7 @@ class UsersController extends Controller
$user->website = $request->input('website', null);
$user->start_date = $request->input('start_date', null);
$user->end_date = $request->input('end_date', null);
$user->autoassign_licenses = $request->input('autoassign_licenses', 1);
// Update the location of any assets checked out to this user
Asset::where('assigned_type', User::class)

View file

@ -368,7 +368,7 @@ class License extends Depreciable
*/
public function assignedusers()
{
return $this->belongsToMany(\App\Models\User::class, 'license_seats', 'assigned_to', 'license_id');
return $this->belongsToMany(\App\Models\User::class, 'license_seats', 'license_id', 'assigned_to');
}
/**

View file

@ -285,7 +285,7 @@ class User extends SnipeModel implements AuthenticatableContract, AuthorizableCo
*/
public function assets()
{
return $this->morphMany(\App\Models\Asset::class, 'assigned', 'assigned_type', 'assigned_to')->withTrashed();
return $this->morphMany(\App\Models\Asset::class, 'assigned', 'assigned_type', 'assigned_to')->withTrashed()->orderBy('id');
}
/**
@ -313,7 +313,7 @@ class User extends SnipeModel implements AuthenticatableContract, AuthorizableCo
public function accessories()
{
return $this->belongsToMany(\App\Models\Accessory::class, 'accessories_users', 'assigned_to', 'accessory_id')
->withPivot('id', 'created_at', 'note')->withTrashed();
->withPivot('id', 'created_at', 'note')->withTrashed()->orderBy('accessory_id');
}
/**

View file

@ -61,12 +61,13 @@
"nunomaduro/collision": "^5.4",
"onelogin/php-saml": "^3.4",
"paragonie/constant_time_encoding": "^2.3",
"symfony/polyfill-mbstring": "^1.22",
"paragonie/sodium_compat": "^1.19",
"phpdocumentor/reflection-docblock": "^5.1",
"phpspec/prophecy": "^1.10",
"pragmarx/google2fa-laravel": "^1.3",
"rollbar/rollbar-laravel": "^7.0",
"spatie/laravel-backup": "^6.16",
"symfony/polyfill-mbstring": "^1.22",
"tecnickcom/tc-lib-barcode": "^1.15",
"unicodeveloper/laravel-password": "^1.0",
"watson/validating": "^6.1"

87
composer.lock generated
View file

@ -4,7 +4,6 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "9bd2bbbd4b08d23336364da3d3a4561a",
"packages": [
{
"name": "alek13/slack",
@ -6299,6 +6298,92 @@
},
"time": "2020-10-15T08:29:30+00:00"
},
{
"name": "paragonie/sodium_compat",
"version": "v1.19.0",
"source": {
"type": "git",
"url": "https://github.com/paragonie/sodium_compat.git",
"reference": "cb15e403ecbe6a6cc515f855c310eb6b1872a933"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/paragonie/sodium_compat/zipball/cb15e403ecbe6a6cc515f855c310eb6b1872a933",
"reference": "cb15e403ecbe6a6cc515f855c310eb6b1872a933",
"shasum": ""
},
"require": {
"paragonie/random_compat": ">=1",
"php": "^5.2.4|^5.3|^5.4|^5.5|^5.6|^7|^8"
},
"require-dev": {
"phpunit/phpunit": "^3|^4|^5|^6|^7|^8|^9"
},
"suggest": {
"ext-libsodium": "PHP < 7.0: Better performance, password hashing (Argon2i), secure memory management (memzero), and better security.",
"ext-sodium": "PHP >= 7.0: Better performance, password hashing (Argon2i), secure memory management (memzero), and better security."
},
"type": "library",
"autoload": {
"files": [
"autoload.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"ISC"
],
"authors": [
{
"name": "Paragon Initiative Enterprises",
"email": "security@paragonie.com"
},
{
"name": "Frank Denis",
"email": "jedisct1@pureftpd.org"
}
],
"description": "Pure PHP implementation of libsodium; uses the PHP extension if it exists",
"keywords": [
"Authentication",
"BLAKE2b",
"ChaCha20",
"ChaCha20-Poly1305",
"Chapoly",
"Curve25519",
"Ed25519",
"EdDSA",
"Edwards-curve Digital Signature Algorithm",
"Elliptic Curve Diffie-Hellman",
"Poly1305",
"Pure-PHP cryptography",
"RFC 7748",
"RFC 8032",
"Salpoly",
"Salsa20",
"X25519",
"XChaCha20-Poly1305",
"XSalsa20-Poly1305",
"Xchacha20",
"Xsalsa20",
"aead",
"cryptography",
"ecdh",
"elliptic curve",
"elliptic curve cryptography",
"encryption",
"libsodium",
"php",
"public-key cryptography",
"secret-key cryptography",
"side-channel resistant"
],
"support": {
"issues": "https://github.com/paragonie/sodium_compat/issues",
"source": "https://github.com/paragonie/sodium_compat/tree/v1.19.0"
},
"time": "2022-09-26T03:40:35+00:00"
},
{
"name": "phenx/php-font-lib",
"version": "0.5.4",

View file

@ -0,0 +1,32 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class AddsShouldAutoassignBoolToUsersTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('users', function (Blueprint $table) {
$table->boolean('autoassign_licenses')->nullable(false)->default(1);
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('users', function (Blueprint $table) {
$table->dropColumn('autoassign_licenses');
});
}
}

View file

@ -19,6 +19,8 @@ return [
'print_assigned' => 'Print All Assigned',
'email_assigned' => 'Email List of All Assigned',
'user_notified' => 'User has been emailed a list of their currently assigned items.',
'auto_assign_label' => 'Include this user when auto-assigning eligible licenses',
'auto_assign_help' => 'Skip this user in auto assignment of licenses',
'software_user' => 'Software Checked out to :name',
'send_email_help' => 'You must provide an email address for this user to send them credentials. Emailing credentials can only be done on user creation. Passwords are stored in a one-way hash and cannot be retrieved once saved.',
'view_user' => 'View User :name',
@ -41,4 +43,9 @@ return [
'remote' => 'Remote',
'remote_help' => 'This can be useful if you need to filter by remote users who never or rarely come into your physical locations.',
'not_remote_label' => 'This is not a remote user',
];
'create_user' => 'Create a user',
'create_user_page_explanation' => 'This is the account information you will use to access the site for the first time.',
'email_credentials' => 'Email credentials',
'email_credentials_text' => 'Email my credentials to the email address above',
'next_save_user' => 'Next: Save User',
];

View file

@ -9,9 +9,18 @@
## {{ $assets->count() }} {{ trans('general.assets') }}
<table width="100%">
<tr><th align="left">{{ trans('mail.name') }} </th><th align="left">{{ trans('mail.asset_tag') }}</th><th align="left">{{ trans('admin/hardware/table.serial') }}</th></tr>
<tr><th align="left">{{ trans('mail.name') }} </th><th align="left">{{ trans('mail.asset_tag') }}</th><th align="left">{{ trans('admin/hardware/table.serial') }}</th> <th></th> </tr>
@foreach($assets as $asset)
<tr><td>{{ $asset->present()->name }}</td><td> {{ $asset->asset_tag }} </td><td> {{ $asset->serial }} </td></tr>
<tr>
<td>{{ $asset->present()->name }}</td>
<td> {{ $asset->asset_tag }} </td>
<td> {{ $asset->serial }} </td>
@if (($snipeSettings->show_images_in_email =='1') && $asset->getImageUrl())
<td>
<img src="{{ asset($asset->getImageUrl()) }}" alt="Asset" style="max-width: 64px;">
</td>
@endif
</tr>
@endforeach
</table>
@endif
@ -20,9 +29,16 @@
## {{ $accessories->count() }} {{ trans('general.accessories') }}
<table width="100%">
<tr><th align="left">{{ trans('mail.name') }} </th></tr>
<tr><th align="left">{{ trans('mail.name') }} </th> <th></th> </tr>
@foreach($accessories as $accessory)
<tr><td>{{ $accessory->name }}</td></tr>
<tr>
<td>{{ $accessory->name }}</td>
@if (($snipeSettings->show_images_in_email =='1') && $accessory->getImageUrl())
<td>
<img src="{{ asset($accessory->getImageUrl()) }}" alt="Accessory" style="max-width: 64px;">
</td>
@endif
</tr>
@endforeach
</table>
@endif
@ -33,7 +49,9 @@
<table width="100%">
<tr><th align="left"{{ trans('mail.name') }} </th></tr>
@foreach($licenses as $license)
<tr><td>{{ $license->name }}</td></tr>
<tr>
<td>{{ $license->name }}</td>
</tr>
@endforeach
</table>
@endif

View file

@ -1,15 +1,14 @@
@extends('layouts/setup')
{{-- TODO: Translate --}}
{{-- Page title --}}
{{ trans('admin/user/table.createuser') }}
@section('title')
Create a User ::
{{ trans('admin/user/general.create_user') }} ::
@parent
@stop
{{-- Page content --}}
@section('content')
<p> This is the account information you'll use to access the site for the first time. </p>
<p>{{ trans('admin/user/general.create_user_page_explanation') }}</p>
<form action="{{ route('setup.user.save') }}" method="POST">
{{ csrf_field() }}
@ -157,10 +156,10 @@ Create a User ::
<!-- Email credentials -->
<div class="form-group col-lg-12">
<label>Email credentials</label>
<label>{{ trans('admin/user/general.email_credentials') }}</label>
<div class="checkbox">
<label>
<input type="checkbox" value="1" name="email_creds">Email my credentials to the email address above
<input type="checkbox" value="1" name="email_creds">{{ trans('admin/user/general.email_credentials_text') }}
</label>
</div>
</div>
@ -168,7 +167,7 @@ Create a User ::
@stop
@section('button')
<button class="btn btn-primary">Next: Save User</button>
<button class="btn btn-primary">{{ trans('admin/user/general.next_save_user') }}</button>
</form>
@parent
@stop

View file

@ -384,6 +384,19 @@
</div>
</div>
<!-- Auto Assign checkbox -->
<div class="form-group">
<div class="col-md-7 col-md-offset-3">
<label for="autoassign_licenses">
<input type="checkbox" value="1" name="autoassign_licenses" class="minimal" {{ (old('autoassign_licenses', $user->autoassign_licenses)) == '1' ? ' checked="checked"' : '' }} aria-label="autoassign_licenses">
{{ trans('admin/users/general.auto_assign_label') }}
</label>
<p class="help-block">{{ trans('admin/users/general.auto_assign_help') }}
</p>
</div>
</div>
<!-- Location -->
@include ('partials.forms.edit.location-select', ['translated_name' => trans('general.location'), 'fieldname' => 'location_id'])

View file

@ -1162,6 +1162,17 @@ Route::group(['prefix' => 'v1', 'middleware' => ['api', 'throttle:api']], functi
)->name('api.activity.index');
}); // end reports api routes
/**
* Version API routes
*/
Route::get('/version', function () {
return response()->json(
[
'version' => config('version.app_version'),
], 200);
}); // end version api routes
Route::fallback(function () {
return response()->json(
@ -1172,5 +1183,4 @@ Route::group(['prefix' => 'v1', 'middleware' => ['api', 'throttle:api']], functi
], 404);
}); // end fallback routes
}); // end API routes

View file

@ -176,6 +176,10 @@ $required_exts_array =
'zip',
];
$recommended_exts_array =
[
'sodium', //note that extensions need to be in BOTH the $required_exts_array and this one to be 'optional'
];
$ext_missing = '';
$ext_installed = '';
@ -205,8 +209,10 @@ foreach ($required_exts_array as $required_ext) {
}
// If this isn't an either/or option, just add it to the string of errors conventionally
} else {
} elseif (!in_array($required_ext, $recommended_exts_array)){
$ext_missing .= '✘ MISSING PHP EXTENSION: '.$required_ext."\n";
} else {
$ext_installed .= '- '.$required_ext." is *NOT* installed, but is recommended...\n";
}
// The required extension string was found in the array of installed extensions - yay!