Compare commits
148 Commits
v8.0.0
...
fix_s3_bac
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
93014d7f34 | ||
|
|
759e3794df | ||
|
|
c50b14763f | ||
|
|
369a68fe57 | ||
|
|
83855d44d0 | ||
|
|
6f847294ed | ||
|
|
d556d1c6e7 | ||
|
|
3bb94e98f0 | ||
|
|
8f5f6f3502 | ||
|
|
b3792bfa00 | ||
|
|
40f7257723 | ||
|
|
8486256142 | ||
|
|
7f36750e33 | ||
|
|
de046db106 | ||
|
|
eb1d27a5bc | ||
|
|
cc0b9f404a | ||
|
|
70332696c6 | ||
|
|
7a9b5d61b0 | ||
|
|
5876259893 | ||
|
|
8755c54edc | ||
|
|
014f3b7652 | ||
|
|
3a2579b205 | ||
|
|
149474bfe3 | ||
|
|
b2b768dede | ||
|
|
a9ed9e2a7f | ||
|
|
ce8523b00a | ||
|
|
7076a68d35 | ||
|
|
112112d258 | ||
|
|
3928c8afe9 | ||
|
|
23ce54e80c | ||
|
|
646e3e8df5 | ||
|
|
30c4e9dbf7 | ||
|
|
27fc30a881 | ||
|
|
8ac7cda4ee | ||
|
|
6f04d314a8 | ||
|
|
1051b1d16d | ||
|
|
115bb94704 | ||
|
|
25807cc62f | ||
|
|
cd1d1b2d3e | ||
|
|
6dcd3bfd30 | ||
|
|
b8799f8038 | ||
|
|
a0dc056da8 | ||
|
|
27aeb518ff | ||
|
|
dc619bb0dc | ||
|
|
245a16c377 | ||
|
|
de3c1d159f | ||
|
|
af6d9e4a00 | ||
|
|
8c8af3062e | ||
|
|
2ff47edb94 | ||
|
|
d923d29bad | ||
|
|
899119ae2d | ||
|
|
e031de8e49 | ||
|
|
a81c520d93 | ||
|
|
8352e81228 | ||
|
|
fd0174ff32 | ||
|
|
cc26aa02b2 | ||
|
|
616f3558dd | ||
|
|
d6e266cec1 | ||
|
|
31516d7f24 | ||
|
|
e79af255aa | ||
|
|
5b0d7f4064 | ||
|
|
2f6af10c5d | ||
|
|
afabda9235 | ||
|
|
1618c9ae8e | ||
|
|
5344ef4a1a | ||
|
|
16420b1e00 | ||
|
|
62f66e724e | ||
|
|
9b0ea51d35 | ||
|
|
992214fc66 | ||
|
|
93dab12461 | ||
|
|
ea0f105180 | ||
|
|
5b6da0c1e8 | ||
|
|
4d7655bbe1 | ||
|
|
5e3855ee5b | ||
|
|
e01226a174 | ||
|
|
f9ccf32af4 | ||
|
|
2c5170a218 | ||
|
|
15f842e2dc | ||
|
|
46b31dfe14 | ||
|
|
d88c79366c | ||
|
|
de330a47cd | ||
|
|
ecd7dc2094 | ||
|
|
510946e0eb | ||
|
|
37e4a13979 | ||
|
|
c73d64cdbc | ||
|
|
4a0410d969 | ||
|
|
668b9f8fb9 | ||
|
|
037d2d9e84 | ||
|
|
bce2007b97 | ||
|
|
09a5e5b1bd | ||
|
|
7b4f4b6b7f | ||
|
|
5c66334017 | ||
|
|
ae82051b73 | ||
|
|
c3a2e81afd | ||
|
|
18c7cbbbbb | ||
|
|
3718f08c72 | ||
|
|
b7821a69b6 | ||
|
|
8049f21068 | ||
|
|
8140110bf9 | ||
|
|
a4587f6322 | ||
|
|
163e19f1e9 | ||
|
|
8a40c3ecb4 | ||
|
|
d949a9689f | ||
|
|
27a7c6fd10 | ||
|
|
4d55a67628 | ||
|
|
9d453226bd | ||
|
|
cd26694767 | ||
|
|
a26cc2ced1 | ||
|
|
1fd81d17a3 | ||
|
|
134045f1ec | ||
|
|
b6b6a3eec7 | ||
|
|
b62714d702 | ||
|
|
271bcc66bf | ||
|
|
ced560daa9 | ||
|
|
b395c9130a | ||
|
|
ed46a757fa | ||
|
|
6a8a41b389 | ||
|
|
4800f4c853 | ||
|
|
c79ff49c85 | ||
|
|
e88bba51bb | ||
|
|
f97211f6cd | ||
|
|
027c2b3627 | ||
|
|
4c43a06eee | ||
|
|
25c8449e86 | ||
|
|
13e1f4a127 | ||
|
|
ed96fd766c | ||
|
|
77635c3737 | ||
|
|
b937b7e767 | ||
|
|
7cbb3f7e07 | ||
|
|
7e9c564d0b | ||
|
|
fc88b2487f | ||
|
|
e94ee48f74 | ||
|
|
6a4a5d1380 | ||
|
|
ab9e9b66d2 | ||
|
|
c15c338ffd | ||
|
|
d1197d015c | ||
|
|
ce31ce477e | ||
|
|
78f9292555 | ||
|
|
4e7c6bd2cf | ||
|
|
70aed45bfe | ||
|
|
e2805f4033 | ||
|
|
d254a40e0a | ||
|
|
fdcb891cbb | ||
|
|
16d322d70e | ||
|
|
2163312997 | ||
|
|
0dfb71cfe5 | ||
|
|
99526cfc2c | ||
|
|
bdb0e6c2a3 |
@@ -3271,6 +3271,33 @@
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "addex12",
|
||||
"name": "Adugna Gizaw",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/18550946?v=4",
|
||||
"profile": "https://orbalia.pythonanywhere.com/",
|
||||
"contributions": [
|
||||
"translation"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "jostrander",
|
||||
"name": "Jesse Ostrander",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/760989?v=4",
|
||||
"profile": "https://github.com/jostrander",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "azmcnutt",
|
||||
"name": "James M",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/31522486?v=4",
|
||||
"profile": "https://github.com/azmcnutt",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ APP_DEBUG=true
|
||||
APP_KEY=base64:3ilviXqB9u6DX1NRcyWGJ+sjySF+H18CPDGb3+IVwMQ=
|
||||
APP_URL=http://localhost:8000
|
||||
APP_TIMEZONE='UTC'
|
||||
APP_LOCALE=en
|
||||
APP_LOCALE=en-US
|
||||
MAX_RESULTS=500
|
||||
|
||||
# --------------------------------------------
|
||||
|
||||
@@ -99,7 +99,7 @@ PASSPORT_COOKIE_NAME='snipeit_passport_token'
|
||||
COOKIE_DOMAIN=null
|
||||
SECURE_COOKIES=false
|
||||
API_TOKEN_EXPIRATION_YEARS=15
|
||||
BS_TABLE_STORAGE=cookieStorage
|
||||
BS_TABLE_STORAGE=localStorage
|
||||
BS_TABLE_DEEPLINK=true
|
||||
|
||||
# --------------------------------------------
|
||||
|
||||
2
.github/workflows/tests-mysql.yml
vendored
2
.github/workflows/tests-mysql.yml
vendored
@@ -67,7 +67,7 @@ jobs:
|
||||
run: |
|
||||
php artisan key:generate
|
||||
php artisan migrate --force
|
||||
php artisan passport:install
|
||||
php artisan passport:install --no-interaction
|
||||
chmod -R 777 storage bootstrap/cache
|
||||
|
||||
- name: Execute tests (Unit and Feature tests) via PHPUnit
|
||||
|
||||
2
.github/workflows/tests-postgres.yml
vendored
2
.github/workflows/tests-postgres.yml
vendored
@@ -65,7 +65,7 @@ jobs:
|
||||
run: |
|
||||
php artisan key:generate
|
||||
php artisan migrate --force
|
||||
php artisan passport:install
|
||||
php artisan passport:install --no-interaction
|
||||
chmod -R 777 storage bootstrap/cache
|
||||
|
||||
- name: Execute tests (Unit and Feature tests) via PHPUnit
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"DOC2": "In other words, what you see locally are the requirements for your _current_ install",
|
||||
"DOC3": "Please don't rely on these versions for planning upgrades unless you've fetched the most recent version",
|
||||
"DOC4": "You should really just ignore it and run upgrade.php. Really",
|
||||
"php_min_version": "8.1.0",
|
||||
"php_min_version": "8.2.0",
|
||||
"php_max_major_minor": "8.4",
|
||||
"php_max_wontwork": "8.5.0",
|
||||
"current_snipeit_version": "8.0"
|
||||
|
||||
@@ -53,7 +53,7 @@ Thanks goes to all of these wonderful people ([emoji key](https://github.com/ken
|
||||
| [<img src="https://avatars.githubusercontent.com/u/55590532?v=4" width="110px;"/><br /><sub>squintfox</sub>](https://github.com/squintfox)<br />[💻](https://github.com/snipe/snipe-it/commits?author=squintfox "Code") | [<img src="https://avatars.githubusercontent.com/u/1380084?v=4" width="110px;"/><br /><sub>Jeff Clay</sub>](https://github.com/jeffclay)<br />[💻](https://github.com/snipe/snipe-it/commits?author=jeffclay "Code") | [<img src="https://avatars.githubusercontent.com/u/52716446?v=4" width="110px;"/><br /><sub>Phil J R</sub>](https://github.com/PP-JN-RL)<br />[💻](https://github.com/snipe/snipe-it/commits?author=PP-JN-RL "Code") | [<img src="https://avatars.githubusercontent.com/u/1496725?v=4" width="110px;"/><br /><sub>i_virus</sub>](https://www.corelight.com/)<br />[💻](https://github.com/snipe/snipe-it/commits?author=chandanchowdhury "Code") | [<img src="https://avatars.githubusercontent.com/u/1020541?v=4" width="110px;"/><br /><sub>Paul Grime</sub>](https://github.com/gitgrimbo)<br />[💻](https://github.com/snipe/snipe-it/commits?author=gitgrimbo "Code") | [<img src="https://avatars.githubusercontent.com/u/922815?v=4" width="110px;"/><br /><sub>Lee Porte</sub>](https://leeporte.co.uk)<br />[💻](https://github.com/snipe/snipe-it/commits?author=LeePorte "Code") | [<img src="https://avatars.githubusercontent.com/u/23613427?v=4" width="110px;"/><br /><sub>BRYAN </sub>](https://github.com/bryanlopezinc)<br />[💻](https://github.com/snipe/snipe-it/commits?author=bryanlopezinc "Code") [⚠️](https://github.com/snipe/snipe-it/commits?author=bryanlopezinc "Tests") |
|
||||
| [<img src="https://avatars.githubusercontent.com/u/64061710?v=4" width="110px;"/><br /><sub>U-H-T</sub>](https://github.com/U-H-T)<br />[💻](https://github.com/snipe/snipe-it/commits?author=U-H-T "Code") | [<img src="https://avatars.githubusercontent.com/u/5395363?v=4" width="110px;"/><br /><sub>Matt Tyree</sub>](https://github.com/Tyree)<br />[📖](https://github.com/snipe/snipe-it/commits?author=Tyree "Documentation") | [<img src="https://avatars.githubusercontent.com/u/292081?v=4" width="110px;"/><br /><sub>Florent Bervas</sub>](http://spoontux.net)<br />[💻](https://github.com/snipe/snipe-it/commits?author=FlorentDotMe "Code") | [<img src="https://avatars.githubusercontent.com/u/4498077?v=4" width="110px;"/><br /><sub>Daniel Albertsen</sub>](https://ditscheri.com)<br />[💻](https://github.com/snipe/snipe-it/commits?author=dbakan "Code") | [<img src="https://avatars.githubusercontent.com/u/100710244?v=4" width="110px;"/><br /><sub>r-xyz</sub>](https://github.com/r-xyz)<br />[💻](https://github.com/snipe/snipe-it/commits?author=r-xyz "Code") | [<img src="https://avatars.githubusercontent.com/u/47491036?v=4" width="110px;"/><br /><sub>Steven Mainor</sub>](https://github.com/DrekiDegga)<br />[💻](https://github.com/snipe/snipe-it/commits?author=DrekiDegga "Code") | [<img src="https://avatars.githubusercontent.com/u/65785975?v=4" width="110px;"/><br /><sub>arne-kroeger</sub>](https://github.com/arne-kroeger)<br />[💻](https://github.com/snipe/snipe-it/commits?author=arne-kroeger "Code") |
|
||||
| [<img src="https://avatars.githubusercontent.com/u/167117705?v=4" width="110px;"/><br /><sub>Glukose1</sub>](https://github.com/Glukose1)<br />[💻](https://github.com/snipe/snipe-it/commits?author=Glukose1 "Code") | [<img src="https://avatars.githubusercontent.com/u/1197791?v=4" width="110px;"/><br /><sub>Scarzy</sub>](https://github.com/Scarzy)<br />[💻](https://github.com/snipe/snipe-it/commits?author=Scarzy "Code") | [<img src="https://avatars.githubusercontent.com/u/37372069?v=4" width="110px;"/><br /><sub>setpill</sub>](https://github.com/setpill)<br />[💻](https://github.com/snipe/snipe-it/commits?author=setpill "Code") | [<img src="https://avatars.githubusercontent.com/u/3755203?v=4" width="110px;"/><br /><sub>swift2512</sub>](https://github.com/swift2512)<br />[🐛](https://github.com/snipe/snipe-it/issues?q=author%3Aswift2512 "Bug reports") | [<img src="https://avatars.githubusercontent.com/u/6136439?v=4" width="110px;"/><br /><sub>Darren Rainey</sub>](https://darrenraineys.co.uk)<br />[💻](https://github.com/snipe/snipe-it/commits?author=DarrenRainey "Code") | [<img src="https://avatars.githubusercontent.com/u/133033121?v=4" width="110px;"/><br /><sub>maciej-poleszczyk</sub>](https://github.com/maciej-poleszczyk)<br />[💻](https://github.com/snipe/snipe-it/commits?author=maciej-poleszczyk "Code") | [<img src="https://avatars.githubusercontent.com/u/143394709?v=4" width="110px;"/><br /><sub>Sebastian Groß</sub>](https://github.com/sgross-emlix)<br />[💻](https://github.com/snipe/snipe-it/commits?author=sgross-emlix "Code") |
|
||||
| [<img src="https://avatars.githubusercontent.com/u/41107778?v=4" width="110px;"/><br /><sub>Anouar Touati</sub>](https://github.com/AnouarTouati)<br />[💻](https://github.com/snipe/snipe-it/commits?author=AnouarTouati "Code") | [<img src="https://avatars.githubusercontent.com/u/25596663?v=4" width="110px;"/><br /><sub>aHVzY2g</sub>](https://github.com/aHVzY2g)<br />[💻](https://github.com/snipe/snipe-it/commits?author=aHVzY2g "Code") | [<img src="https://avatars.githubusercontent.com/u/13408130?v=4" width="110px;"/><br /><sub>林博仁 Buo-ren Lin</sub>](https://brlin.me)<br />[💻](https://github.com/snipe/snipe-it/commits?author=brlin-tw "Code") |
|
||||
| [<img src="https://avatars.githubusercontent.com/u/41107778?v=4" width="110px;"/><br /><sub>Anouar Touati</sub>](https://github.com/AnouarTouati)<br />[💻](https://github.com/snipe/snipe-it/commits?author=AnouarTouati "Code") | [<img src="https://avatars.githubusercontent.com/u/25596663?v=4" width="110px;"/><br /><sub>aHVzY2g</sub>](https://github.com/aHVzY2g)<br />[💻](https://github.com/snipe/snipe-it/commits?author=aHVzY2g "Code") | [<img src="https://avatars.githubusercontent.com/u/13408130?v=4" width="110px;"/><br /><sub>林博仁 Buo-ren Lin</sub>](https://brlin.me)<br />[💻](https://github.com/snipe/snipe-it/commits?author=brlin-tw "Code") | [<img src="https://avatars.githubusercontent.com/u/18550946?v=4" width="110px;"/><br /><sub>Adugna Gizaw</sub>](https://orbalia.pythonanywhere.com/)<br />[🌍](#translation-addex12 "Translation") | [<img src="https://avatars.githubusercontent.com/u/760989?v=4" width="110px;"/><br /><sub>Jesse Ostrander</sub>](https://github.com/jostrander)<br />[💻](https://github.com/snipe/snipe-it/commits?author=jostrander "Code") | [<img src="https://avatars.githubusercontent.com/u/31522486?v=4" width="110px;"/><br /><sub>James M</sub>](https://github.com/azmcnutt)<br />[💻](https://github.com/snipe/snipe-it/commits?author=azmcnutt "Code") |
|
||||
<!-- ALL-CONTRIBUTORS-LIST:END -->
|
||||
|
||||
This project follows the [all-contributors](https://github.com/kentcdodds/all-contributors) specification. Contributions of any kind welcome!
|
||||
|
||||
@@ -40,7 +40,6 @@ autoconf \
|
||||
libc-dev \
|
||||
libldap-common \
|
||||
pkg-config \
|
||||
libmcrypt-dev \
|
||||
php8.3-dev \
|
||||
ca-certificates \
|
||||
unzip \
|
||||
@@ -51,11 +50,6 @@ dnsutils \
|
||||
RUN curl -L -O https://github.com/pear/pearweb_phars/raw/master/go-pear.phar
|
||||
RUN php go-pear.phar
|
||||
|
||||
RUN pecl install mcrypt
|
||||
|
||||
RUN bash -c "echo extension=/usr/lib/php/20210902/mcrypt.so > /etc/php/8.3/mods-available/mcrypt.ini"
|
||||
|
||||
RUN phpenmod mcrypt
|
||||
RUN phpenmod gd
|
||||
RUN phpenmod bcmath
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
This is a FOSS project for asset management in IT Operations. Knowing who has which laptop, when it was purchased in order to depreciate it correctly, handling software licenses, etc.
|
||||
|
||||
It is built on [Laravel 10](http://laravel.com).
|
||||
It is built on [Laravel 11](http://laravel.com).
|
||||
|
||||
Snipe-IT is actively developed and we [release quite frequently](https://github.com/snipe/snipe-it/releases). ([Check out the live demo here](https://snipeitapp.com/demo/).)
|
||||
|
||||
@@ -94,6 +94,8 @@ Since the release of the JSON REST API, several third-party developers have been
|
||||
- [SnipeAgent](https://github.com/ReticentRobot/SnipeAgent) by [@ReticentRobot](https://github.com/ReticentRobot) - Windows agent for Snipe-IT.
|
||||
- [Gate Pass Generator](https://github.com/cha7uraAE/snipe-it-gate-pass-system) by [@cha7uraAE](https://github.com/cha7uraAE) - A Streamlit application for generating gate passes based on hardware data from a Snipe-IT API.
|
||||
|
||||
We also have a handful of [Google Apps scripts](https://github.com/grokability/google-apps-scripts-for-snipe-it) to help with various tasks.
|
||||
|
||||
-----
|
||||
|
||||
### Join the Community!
|
||||
|
||||
@@ -125,6 +125,10 @@ class LdapSync extends Command
|
||||
*/
|
||||
$attributes = array_values(array_filter($ldap_map));
|
||||
|
||||
if (Setting::getSettings()->is_ad === 1 && is_null($ldap_map['active_flag'])) {
|
||||
$attributes[] = 'useraccountcontrol';
|
||||
}
|
||||
|
||||
$results = Ldap::findLdapUsers($search_base, -1, $filter, $attributes);
|
||||
|
||||
} catch (\Exception $e) {
|
||||
@@ -357,9 +361,15 @@ class LdapSync extends Command
|
||||
// (Specifically, we don't handle a value of '0.0' correctly)
|
||||
$raw_value = @$results[$i][$ldap_map["active_flag"]][0];
|
||||
$filter_var = filter_var($raw_value, FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE);
|
||||
|
||||
$boolean_cast = (bool) $raw_value;
|
||||
|
||||
$user->activated = $filter_var ?? $boolean_cast; // if filter_var() was true or false, use that. If it's null, use the $boolean_cast
|
||||
|
||||
if (Setting::getSettings()->ldap_invert_active_flag === 1) {
|
||||
// Because ldap_active_flag is set, if filter_var is true or boolean_cast is true, then user is suspended
|
||||
$user->activated = !($filter_var ?? $boolean_cast);
|
||||
}else{
|
||||
$user->activated = $filter_var ?? $boolean_cast; // if filter_var() was true or false, use that. If it's null, use the $boolean_cast
|
||||
}
|
||||
|
||||
} elseif (array_key_exists('useraccountcontrol', $results[$i])) {
|
||||
// ....otherwise, (ie if no 'active' LDAP flag is defined), IF the UAC setting exists,
|
||||
@@ -424,8 +434,12 @@ class LdapSync extends Command
|
||||
$item['note'] = $item['createorupdate'];
|
||||
$item['status'] = 'success';
|
||||
if ($item['createorupdate'] === 'created' && $ldap_default_group) {
|
||||
$user->groups()->attach($ldap_default_group);
|
||||
// Check if the relationship already exists
|
||||
if (!$user->groups()->where('group_id', $ldap_default_group)->exists()) {
|
||||
$user->groups()->attach($ldap_default_group);
|
||||
}
|
||||
}
|
||||
|
||||
//updates assets location based on user's location
|
||||
if ($user->wasChanged('location_id')) {
|
||||
foreach ($user->assets as $asset) {
|
||||
|
||||
@@ -1,157 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use App\LegacyEncrypter\McryptEncrypter;
|
||||
use App\Models\Asset;
|
||||
use App\Models\CustomField;
|
||||
use App\Models\Setting;
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
|
||||
class RecryptFromMcrypt extends Command
|
||||
{
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'snipeit:legacy-recrypt
|
||||
{--force : Force a re-crypt of encrypted data from MCRYPT.}';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'This command allows upgrading users to de-encrypt their deprecated mcrypt encrypted fields and re-encrypt them using the current OpenSSL encryption.';
|
||||
|
||||
/**
|
||||
* Create a new command instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
|
||||
// Check and see if they have a legacy app key listed in their .env
|
||||
// If not, we can try to use the current APP_KEY if looks like it's old
|
||||
$legacy_key = env('LEGACY_APP_KEY');
|
||||
$key_parts = explode(':', $legacy_key);
|
||||
$legacy_cipher = env('LEGACY_CIPHER', 'rijndael-256');
|
||||
$errors = [];
|
||||
|
||||
if (! $legacy_key) {
|
||||
$this->error('ERROR: You do not have a LEGACY_APP_KEY set in your .env file. Please locate your old APP_KEY and ADD a line to your .env file like: LEGACY_APP_KEY=YOUR_OLD_APP_KEY');
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Do some basic legacy app key length checks
|
||||
if (strlen($legacy_key) == 32) {
|
||||
$legacy_length_check = true;
|
||||
} elseif (array_key_exists('1', $key_parts) && (strlen($key_parts[1]) == 44)) {
|
||||
$legacy_key = base64_decode($key_parts[1], true);
|
||||
$legacy_length_check = true;
|
||||
} else {
|
||||
$legacy_length_check = false;
|
||||
}
|
||||
|
||||
// Check that the app key is 32 characters
|
||||
if ($legacy_length_check === true) {
|
||||
$this->comment('INFO: Your LEGACY_APP_KEY looks correct. Okay to continue.');
|
||||
} else {
|
||||
$this->error('ERROR: Your LEGACY_APP_KEY is not the correct length (32 characters or base64 followed by 44 characters for later versions). Please locate your old APP_KEY and use that as your LEGACY_APP_KEY in your .env file to continue.');
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->error('================================!!!! WARNING !!!!================================');
|
||||
$this->error('================================!!!! WARNING !!!!================================');
|
||||
$this->comment("This tool will attempt to decrypt your old Snipe-IT (mcrypt, now deprecated) encrypted data and re-encrypt it using OpenSSL. \n\nYou should only continue if you have backed up any and all old APP_KEYs and have backed up your data.");
|
||||
|
||||
$force = ($this->option('force')) ? true : false;
|
||||
|
||||
if ($force || ($this->confirm('Are you SURE you wish to continue?'))) {
|
||||
$backup_file = 'backups/env-backups/'.'app_key-'.date('Y-m-d-gis');
|
||||
|
||||
try {
|
||||
Storage::disk('local')->put($backup_file, 'APP_KEY: '.config('app.key'));
|
||||
Storage::disk('local')->append($backup_file, 'LEGACY_APP_KEY: '.$legacy_key);
|
||||
} catch (\Exception $e) {
|
||||
$this->info('WARNING: Could not backup app keys');
|
||||
}
|
||||
|
||||
if ($legacy_cipher) {
|
||||
$mcrypter = new McryptEncrypter($legacy_key, $legacy_cipher);
|
||||
} else {
|
||||
$mcrypter = new McryptEncrypter($legacy_key);
|
||||
}
|
||||
$settings = Setting::getSettings();
|
||||
|
||||
if ($settings->ldap_pword == '') {
|
||||
$this->comment('INFO: No LDAP password found. Skipping... ');
|
||||
} else {
|
||||
$decrypted_ldap_pword = $mcrypter->decrypt($settings->ldap_pword);
|
||||
$settings->ldap_pword = Crypt::encrypt($decrypted_ldap_pword);
|
||||
$settings->save();
|
||||
}
|
||||
/** @var CustomField[] $custom_fields */
|
||||
$custom_fields = CustomField::where('field_encrypted', '=', 1)->get();
|
||||
$this->comment('INFO: Retrieving encrypted custom fields...');
|
||||
|
||||
$query = Asset::withTrashed();
|
||||
|
||||
foreach ($custom_fields as $custom_field) {
|
||||
$this->comment('FIELD TO RECRYPT: '.$custom_field->name.' ('.$custom_field->db_column.')');
|
||||
$query->orWhereNotNull($custom_field->db_column);
|
||||
}
|
||||
|
||||
// Get all assets with a value in any of the fields that were encrypted
|
||||
/** @var Asset[] $assets */
|
||||
$assets = $query->get();
|
||||
|
||||
$bar = $this->output->createProgressBar(count($assets));
|
||||
|
||||
foreach ($assets as $asset) {
|
||||
foreach ($custom_fields as $encrypted_field) {
|
||||
$columnName = $encrypted_field->db_column;
|
||||
|
||||
// Make sure the value isn't null
|
||||
if ($asset->{$columnName} != '') {
|
||||
// Try to decrypt the payload using the legacy app key
|
||||
try {
|
||||
$decrypted_field = $mcrypter->decrypt($asset->{$columnName});
|
||||
$asset->{$columnName} = Crypt::encrypt($decrypted_field);
|
||||
$this->comment($decrypted_field);
|
||||
} catch (\Exception $e) {
|
||||
$errors[] = ' - ERROR: Could not decrypt field ['.$encrypted_field->name.']: '.$e->getMessage();
|
||||
}
|
||||
}
|
||||
}
|
||||
$asset->save();
|
||||
$bar->advance();
|
||||
}
|
||||
|
||||
$bar->finish();
|
||||
|
||||
if (count($errors) > 0) {
|
||||
$this->comment("\n\n");
|
||||
$this->error("The decrypter encountered some errors: \n");
|
||||
foreach ($errors as $error) {
|
||||
$this->error($error);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -64,28 +64,43 @@ class SendAcceptanceReminder extends Command
|
||||
->groupBy(function($item) {
|
||||
return $item['acceptance']->assignedTo ? $item['acceptance']->assignedTo->id : '';
|
||||
});
|
||||
$no_email_list= [];
|
||||
|
||||
foreach($unacceptedAssetGroups as $unacceptedAssetGroup) {
|
||||
// The [0] is weird, but it allows for the item_count to work and grabs the appropriate info for each user.
|
||||
// Collapsing and flattening the collection doesn't work above.
|
||||
$acceptance = $unacceptedAssetGroup[0]['acceptance'];
|
||||
|
||||
$locale = $acceptance->assignedTo?->locale;
|
||||
$email = $acceptance->assignedTo?->email;
|
||||
|
||||
if(!$email){
|
||||
$this->info($acceptance->assignedTo?->present()->fullName().' has no email address.');
|
||||
$no_email_list[] = [
|
||||
'id' => $acceptance->assignedTo?->id,
|
||||
'name' => $acceptance->assignedTo?->present()->fullName(),
|
||||
];
|
||||
} else {
|
||||
$count++;
|
||||
}
|
||||
$item_count = $unacceptedAssetGroup->count();
|
||||
|
||||
if ($locale && $email) {
|
||||
Mail::to($email)->send((new UnacceptedAssetReminderMail($acceptance, $item_count))->locale($locale));
|
||||
|
||||
} elseif ($email) {
|
||||
Mail::to($email)->send((new UnacceptedAssetReminderMail($acceptance, $item_count)));
|
||||
}
|
||||
$count++;
|
||||
|
||||
}
|
||||
|
||||
$this->info($count.' users notified.');
|
||||
$headers = ['ID', 'Name'];
|
||||
$rows = [];
|
||||
|
||||
foreach ($no_email_list as $user) {
|
||||
$rows[] = [$user['id'], $user['name']];
|
||||
}
|
||||
$this->info("The following users do not have an email address:");
|
||||
$this->table($headers, $rows);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -2,13 +2,12 @@
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use App\Mail\SendUpcomingAuditMail;
|
||||
use App\Models\Asset;
|
||||
use App\Models\Recipients\AlertRecipient;
|
||||
use App\Models\Setting;
|
||||
use App\Notifications\SendUpcomingAuditNotification;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Support\Facades\Mail;
|
||||
|
||||
class SendUpcomingAuditReport extends Command
|
||||
{
|
||||
@@ -48,19 +47,19 @@ class SendUpcomingAuditReport extends Command
|
||||
$today = Carbon::now();
|
||||
$interval_date = $today->copy()->addDays($interval);
|
||||
|
||||
$assets = Asset::whereNull('deleted_at')->DueOrOverdueForAudit($settings)->orderBy('assets.next_audit_date', 'desc')->get();
|
||||
$this->info($assets->count().' assets must be audited in on or before '.$interval_date.' is deadline');
|
||||
$assets = Asset::whereNull('deleted_at')->dueOrOverdueForAudit($settings)->orderBy('assets.next_audit_date', 'desc')->get();
|
||||
$this->info($assets->count() . ' assets must be audited in on or before ' . $interval_date . ' is deadline');
|
||||
|
||||
|
||||
if (($assets) && ($assets->count() > 0) && ($settings->alert_email != '')) {
|
||||
if ((count($assets) !== 0) && ($assets->count() > 0) && ($settings->alert_email != '')) {
|
||||
// Send a rollup to the admin, if settings dictate
|
||||
$recipients = collect(explode(',', $settings->alert_email))->map(function ($item) {
|
||||
return new AlertRecipient($item);
|
||||
});
|
||||
$recipients = collect(explode(',', $settings->alert_email))
|
||||
->map(fn($item) => trim($item))
|
||||
->all();
|
||||
|
||||
$this->info('Sending Admin SendUpcomingAuditNotification to: '.$settings->alert_email);
|
||||
\Notification::send($recipients, new SendUpcomingAuditNotification($assets, $settings->audit_warning_days));
|
||||
|
||||
$this->info('Sending Admin SendUpcomingAuditNotification to: ' . $settings->alert_email);
|
||||
Mail::to($recipients)->send(new SendUpcomingAuditMail($assets, $settings->audit_warning_days));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ namespace App\Console;
|
||||
use App\Console\Commands\ImportLocations;
|
||||
use App\Console\Commands\ReEncodeCustomFieldNames;
|
||||
use App\Console\Commands\RestoreDeletedUsers;
|
||||
use App\Models\Setting;
|
||||
use Illuminate\Console\Scheduling\Schedule;
|
||||
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
|
||||
|
||||
@@ -18,12 +19,14 @@ class Kernel extends ConsoleKernel
|
||||
*/
|
||||
protected function schedule(Schedule $schedule)
|
||||
{
|
||||
$schedule->command('snipeit:inventory-alerts')->daily();
|
||||
$schedule->command('snipeit:expiring-alerts')->daily();
|
||||
$schedule->command('snipeit:expected-checkin')->daily();
|
||||
if(Setting::getSettings()->alerts_enabled === 1) {
|
||||
$schedule->command('snipeit:inventory-alerts')->daily();
|
||||
$schedule->command('snipeit:expiring-alerts')->daily();
|
||||
$schedule->command('snipeit:expected-checkin')->daily();
|
||||
$schedule->command('snipeit:upcoming-audits')->daily();
|
||||
}
|
||||
$schedule->command('snipeit:backup')->weekly();
|
||||
$schedule->command('backup:clean')->daily();
|
||||
$schedule->command('snipeit:upcoming-audits')->daily();
|
||||
$schedule->command('auth:clear-resets')->everyFifteenMinutes();
|
||||
$schedule->command('saml:clear_expired_nonces')->weekly();
|
||||
}
|
||||
|
||||
@@ -77,6 +77,18 @@ class AssetModelsController extends Controller
|
||||
$assetmodels->onlyTrashed();
|
||||
}
|
||||
|
||||
if ($request->filled('name')) {
|
||||
$assetmodels = $assetmodels->where('models.name', '=', $request->input('name'));
|
||||
}
|
||||
|
||||
if ($request->filled('model_number')) {
|
||||
$assetmodels = $assetmodels->where('models.model_number', '=', $request->input('model_number'));
|
||||
}
|
||||
|
||||
if ($request->filled('notes')) {
|
||||
$assetmodels = $assetmodels->where('models.notes', '=', $request->input('notes'));
|
||||
}
|
||||
|
||||
if ($request->filled('category_id')) {
|
||||
$assetmodels = $assetmodels->where('models.category_id', '=', $request->input('category_id'));
|
||||
}
|
||||
|
||||
@@ -66,25 +66,41 @@ class ImportController extends Controller
|
||||
if (! ini_get('auto_detect_line_endings')) {
|
||||
ini_set('auto_detect_line_endings', '1');
|
||||
}
|
||||
$file_contents = $file->getContent(); //TODO - this *does* load the whole file in RAM, but we need that to be able to 'iconv' it?
|
||||
$encoding = $detector->getEncoding($file_contents);
|
||||
$reader = null;
|
||||
if (strcasecmp($encoding, 'UTF-8') != 0) {
|
||||
$transliterated = iconv($encoding, 'UTF-8', $file_contents);
|
||||
if ($transliterated !== false) {
|
||||
$tmpname = tempnam(sys_get_temp_dir(), '');
|
||||
$tmpresults = file_put_contents($tmpname, $transliterated);
|
||||
if ($tmpresults !== false) {
|
||||
if (function_exists('iconv')) {
|
||||
$file_contents = $file->getContent(); //TODO - this *does* load the whole file in RAM, but we need that to be able to 'iconv' it?
|
||||
$encoding = $detector->getEncoding($file_contents);
|
||||
\Log::warning("Discovered encoding: $encoding in uploaded CSV");
|
||||
$reader = null;
|
||||
if (strcasecmp($encoding, 'UTF-8') != 0) {
|
||||
$transliterated = false;
|
||||
try {
|
||||
$transliterated = iconv(strtoupper($encoding), 'UTF-8', $file_contents);
|
||||
} catch (\Exception $e) {
|
||||
$transliterated = false; //blank out the partially-decoded string
|
||||
return response()->json(
|
||||
Helper::formatStandardApiResponse(
|
||||
'error',
|
||||
null,
|
||||
trans('admin/hardware/message.import.transliterate_failure', ["encoding" => $encoding])
|
||||
),
|
||||
422
|
||||
);
|
||||
}
|
||||
if ($transliterated !== false) {
|
||||
$tmpname = tempnam(sys_get_temp_dir(), '');
|
||||
$tmpresults = file_put_contents($tmpname, $transliterated);
|
||||
$transliterated = null; //save on memory?
|
||||
$newfile = new UploadedFile($tmpname, $file->getClientOriginalName(), null, null, true); //WARNING: this is enabling 'test mode' - which is gross, but otherwise the file won't be treated as 'uploaded'
|
||||
if ($newfile->isValid()) {
|
||||
$file = $newfile;
|
||||
if ($tmpresults !== false) {
|
||||
$newfile = new UploadedFile($tmpname, $file->getClientOriginalName(), null, null, true); //WARNING: this is enabling 'test mode' - which is gross, but otherwise the file won't be treated as 'uploaded'
|
||||
if ($newfile->isValid()) {
|
||||
$file = $newfile;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
$file_contents = null; //try to save on memory, I guess?
|
||||
}
|
||||
$reader = Reader::createFromFileObject($file->openFile('r')); //file pointer leak?
|
||||
$file_contents = null; //try to save on memory, I guess?
|
||||
|
||||
try {
|
||||
$import->header_row = $reader->fetchOne(0);
|
||||
|
||||
@@ -290,10 +290,12 @@ class StatuslabelsController extends Controller
|
||||
|
||||
/**
|
||||
* Returns a boolean response based on whether the status label
|
||||
* is one that is deployable.
|
||||
* is one that is deployable or pending.
|
||||
*
|
||||
* This is used by the hardware create/edit view to determine whether
|
||||
* we should provide a dropdown of users for them to check the asset out to.
|
||||
* we should provide a dropdown of users for them to check the asset out to,
|
||||
* and whether we show a warning that the asset will be checked in if it's already
|
||||
* assigned but the status is changed to one that isn't pending or deployable
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v4.0]
|
||||
@@ -301,7 +303,7 @@ class StatuslabelsController extends Controller
|
||||
public function checkIfDeployable($id) : string
|
||||
{
|
||||
$statuslabel = Statuslabel::findOrFail($id);
|
||||
if ($statuslabel->getStatuslabelType() == 'deployable') {
|
||||
if (($statuslabel->getStatuslabelType() == 'pending') || ($statuslabel->getStatuslabelType() == 'deployable')) {
|
||||
return '1';
|
||||
}
|
||||
|
||||
|
||||
@@ -71,12 +71,12 @@ class AssetFilesController extends Controller
|
||||
try {
|
||||
return StorageHelper::showOrDownloadFile($file, $log->filename);
|
||||
} catch (\Exception $e) {
|
||||
return redirect()->route('hardware.show', ['hardware' => $asset])->with('error', trans('general.file_not_found'));
|
||||
return redirect()->route('hardware.show', $asset)->with('error', trans('general.file_not_found'));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return redirect()->route('hardware.show', ['hardware' => $asset])->with('error', trans('general.log_record_not_found'));
|
||||
return redirect()->route('hardware.show', $asset)->with('error', trans('general.log_record_not_found'));
|
||||
|
||||
|
||||
}
|
||||
@@ -102,7 +102,7 @@ class AssetFilesController extends Controller
|
||||
return redirect()->back()->withFragment('files')->with('success', trans('admin/hardware/message.deletefile.success'));
|
||||
}
|
||||
|
||||
return redirect()->route('hardware.show', ['hardware' => $asset])->with('error', trans('general.log_record_not_found'));
|
||||
return redirect()->route('hardware.show', $asset)->with('error', trans('general.log_record_not_found'));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -340,15 +340,14 @@ class AssetsController extends Controller
|
||||
|
||||
$status = Statuslabel::find($request->input('status_id'));
|
||||
|
||||
// This is a non-deployable status label - we should check the asset back in.
|
||||
if (($status && $status->getStatuslabelType() != 'deployable') && ($target = $asset->assignedTo)) {
|
||||
|
||||
// This is an archived or undeployable - we should check the asset back in.
|
||||
// Pending is allowed here
|
||||
if (($status) && (($status->getStatuslabelType() != 'pending') && ($status->getStatuslabelType() != 'deployable')) && ($target = $asset->assignedTo)) {
|
||||
$originalValues = $asset->getRawOriginal();
|
||||
$asset->assigned_to = null;
|
||||
$asset->assigned_type = null;
|
||||
$asset->accepted = null;
|
||||
|
||||
event(new CheckoutableCheckedIn($asset, $target, auth()->user(), 'Checkin on asset update', date('Y-m-d H:i:s'), $originalValues));
|
||||
event(new CheckoutableCheckedIn($asset, $target, auth()->user(), 'Checkin on asset update with '.$status->getStatuslabelType().' status', date('Y-m-d H:i:s'), $originalValues));
|
||||
}
|
||||
|
||||
if ($asset->assigned_to == '') {
|
||||
|
||||
@@ -358,7 +358,11 @@ class BulkAssetsController extends Controller
|
||||
* to someone/something.
|
||||
*/
|
||||
if ($request->filled('status_id')) {
|
||||
$updated_status = Statuslabel::find($request->input('status_id'));
|
||||
try {
|
||||
$updated_status = Statuslabel::findOrFail($request->input('status_id'));
|
||||
} catch (ModelNotFoundException $e) {
|
||||
return redirect($bulk_back_url)->with('error', trans('admin/statuslabels/message.does_not_exist'));
|
||||
}
|
||||
|
||||
// We cannot assign a non-deployable status type if the asset is already assigned.
|
||||
// This could probably be added to a form request.
|
||||
@@ -366,7 +370,7 @@ class BulkAssetsController extends Controller
|
||||
// Otherwise we need to make sure the status type is still a deployable one.
|
||||
if (
|
||||
($asset->assigned_to == '')
|
||||
|| ($updated_status->deployable == '1') && ($asset->assetstatus->deployable == '1')
|
||||
|| ($updated_status->deployable == '1') && ($asset->assetstatus?->deployable == '1')
|
||||
) {
|
||||
$this->update_array['status_id'] = $updated_status->id;
|
||||
}
|
||||
|
||||
@@ -206,6 +206,7 @@ class LoginController extends Controller
|
||||
$user->password = bcrypt($request->input('password'));
|
||||
}
|
||||
|
||||
$user->last_login = \Carbon::now();
|
||||
$user->email = $ldap_attr['email'];
|
||||
$user->first_name = $ldap_attr['firstname'];
|
||||
$user->last_name = $ldap_attr['lastname']; //FIXME (or TODO?) - do we need to map additional fields that we now support? E.g. country, phone, etc.
|
||||
@@ -432,6 +433,7 @@ class LoginController extends Controller
|
||||
|
||||
if (Google2FA::verifyKey($user->two_factor_secret, $secret)) {
|
||||
$user->two_factor_enrolled = 1;
|
||||
$user->last_login = \Carbon::now();
|
||||
$user->saveQuietly();
|
||||
$request->session()->put('2fa_authed', $user->id);
|
||||
|
||||
|
||||
@@ -40,7 +40,7 @@ class DashboardController extends Controller
|
||||
|
||||
if ((! file_exists(storage_path().'/oauth-private.key')) || (! file_exists(storage_path().'/oauth-public.key'))) {
|
||||
Artisan::call('migrate', ['--force' => true]);
|
||||
\Artisan::call('passport:install');
|
||||
Artisan::call('passport:install', ['--no-interaction' => true]);
|
||||
}
|
||||
|
||||
return view('dashboard')->with('asset_stats', $asset_stats)->with('counts', $counts);
|
||||
|
||||
@@ -100,7 +100,7 @@ class LocationsController extends Controller
|
||||
public function edit(Location $location) : View | RedirectResponse
|
||||
{
|
||||
$this->authorize('update', Location::class);
|
||||
return view('locations/edit');
|
||||
return view('locations/edit')->with('item', $location);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -266,7 +266,7 @@ class ReportsController extends Controller
|
||||
|
||||
$actionlogs = Actionlog::with('item', 'user', 'target', 'location', 'adminuser')
|
||||
->orderBy('created_at', 'DESC')
|
||||
->chunk(20, function ($actionlogs) use ($handle) {
|
||||
->chunk(500, function ($actionlogs) use ($handle) {
|
||||
$executionTime = microtime(true) - $_SERVER['REQUEST_TIME_FLOAT'];
|
||||
Log::debug('Walking results: '.$executionTime);
|
||||
$count = 0;
|
||||
@@ -748,7 +748,7 @@ class ReportsController extends Controller
|
||||
}
|
||||
|
||||
Log::debug($assets->toSql());
|
||||
$assets->orderBy('assets.id', 'ASC')->chunk(20, function ($assets) use ($handle, $customfields, $request) {
|
||||
$assets->orderBy('assets.id', 'ASC')->chunk(500, function ($assets) use ($handle, $customfields, $request) {
|
||||
|
||||
$executionTime = microtime(true) - $_SERVER['REQUEST_TIME_FLOAT'];
|
||||
Log::debug('Walking results: '.$executionTime);
|
||||
@@ -1175,18 +1175,13 @@ class ReportsController extends Controller
|
||||
}
|
||||
$email = $assetItem->assignedTo?->email;
|
||||
$locale = $assetItem->assignedTo?->locale;
|
||||
// Only send notification if assigned
|
||||
if ($locale && $email) {
|
||||
Mail::to($email)->send((new CheckoutAssetMail($assetItem, $assetItem->assignedTo, $logItem->user, $acceptance, $logItem->note))->locale($locale));
|
||||
|
||||
} elseif ($email) {
|
||||
Mail::to($email)->send((new CheckoutAssetMail($assetItem, $assetItem->assignedTo, $logItem->user, $acceptance, $logItem->note)));
|
||||
}
|
||||
|
||||
if ($email == ''){
|
||||
if (is_null($email) || $email === '') {
|
||||
return redirect()->route('reports/unaccepted_assets')->with('error', trans('general.no_email'));
|
||||
}
|
||||
|
||||
Mail::to($email)->send((new CheckoutAssetMail($assetItem, $assetItem->assignedTo, $logItem->user, $acceptance, $logItem->note, firstTimeSending: false))->locale($locale));
|
||||
|
||||
return redirect()->route('reports/unaccepted_assets')->with('success', trans('admin/reports/general.reminder_sent'));
|
||||
}
|
||||
|
||||
|
||||
3
app/Http/Controllers/SettingsController.php
Executable file → Normal file
3
app/Http/Controllers/SettingsController.php
Executable file → Normal file
@@ -256,7 +256,7 @@ class SettingsController extends Controller
|
||||
Artisan::call('migrate', ['--force' => true]);
|
||||
if ((! file_exists(storage_path().'/oauth-private.key')) || (! file_exists(storage_path().'/oauth-public.key'))) {
|
||||
Artisan::call('migrate', ['--path' => 'vendor/laravel/passport/database/migrations', '--force' => true]);
|
||||
Artisan::call('passport:install');
|
||||
Artisan::call('passport:install', ['--no-interaction' => true]);
|
||||
}
|
||||
|
||||
return view('setup/migrate')
|
||||
@@ -851,6 +851,7 @@ class SettingsController extends Controller
|
||||
$setting->ldap_auth_filter_query = $request->input('ldap_auth_filter_query');
|
||||
$setting->ldap_version = $request->input('ldap_version', 3);
|
||||
$setting->ldap_active_flag = $request->input('ldap_active_flag');
|
||||
$setting->ldap_invert_active_flag = $request->input('ldap_invert_active_flag');
|
||||
$setting->ldap_emp_num = $request->input('ldap_emp_num');
|
||||
$setting->ldap_email = $request->input('ldap_email');
|
||||
$setting->ldap_manager = $request->input('ldap_manager');
|
||||
|
||||
@@ -26,9 +26,9 @@ class StoreNotificationSettings extends FormRequest
|
||||
return [
|
||||
'alert_email' => 'email_array|nullable',
|
||||
'admin_cc_email' => 'email_array|nullable',
|
||||
'alert_threshold' => 'numeric|nullable|gt:0',
|
||||
'alert_threshold' => 'numeric|nullable',
|
||||
'alert_interval' => 'numeric|nullable|gt:0',
|
||||
'audit_warning_days' => 'numeric|nullable|gt:0',
|
||||
'audit_warning_days' => 'numeric|nullable',
|
||||
'due_checkin_days' => 'numeric|nullable|gt:0',
|
||||
'audit_interval' => 'numeric|nullable|gt:0',
|
||||
];
|
||||
|
||||
@@ -1,81 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\LegacyEncrypter;
|
||||
|
||||
use Illuminate\Contracts\Encryption\DecryptException;
|
||||
|
||||
abstract class BaseEncrypter
|
||||
{
|
||||
/**
|
||||
* The encryption key.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $key;
|
||||
|
||||
/**
|
||||
* Create a MAC for the given value.
|
||||
*
|
||||
* @param string $iv
|
||||
* @param string $value
|
||||
* @return string
|
||||
*/
|
||||
protected function hash($iv, $value)
|
||||
{
|
||||
return hash_hmac('sha256', $iv.$value, $this->key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the JSON array from the given payload.
|
||||
*
|
||||
* @param string $payload
|
||||
* @return array
|
||||
*
|
||||
* @throws \Illuminate\Contracts\Encryption\DecryptException
|
||||
*/
|
||||
protected function getJsonPayload($payload)
|
||||
{
|
||||
$payload = json_decode(base64_decode($payload), true);
|
||||
|
||||
// If the payload is not valid JSON or does not have the proper keys set we will
|
||||
// assume it is invalid and bail out of the routine since we will not be able
|
||||
// to decrypt the given value. We'll also check the MAC for this encryption.
|
||||
if (! $payload || $this->invalidPayload($payload)) {
|
||||
throw new DecryptException('The payload is invalid.');
|
||||
}
|
||||
|
||||
if (! $this->validMac($payload)) {
|
||||
throw new DecryptException('The MAC is invalid.');
|
||||
}
|
||||
|
||||
return $payload;
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify that the encryption payload is valid.
|
||||
*
|
||||
* @param array|mixed $data
|
||||
* @return bool
|
||||
*/
|
||||
protected function invalidPayload($data)
|
||||
{
|
||||
return ! is_array($data) || ! isset($data['iv']) || ! isset($data['value']) || ! isset($data['mac']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the MAC for the given payload is valid.
|
||||
*
|
||||
* @param array $payload
|
||||
* @return bool
|
||||
*
|
||||
* @throws \RuntimeException
|
||||
*/
|
||||
protected function validMac(array $payload)
|
||||
{
|
||||
$bytes = random_bytes(16);
|
||||
|
||||
$calcMac = hash_hmac('sha256', $this->hash($payload['iv'], $payload['value']), $bytes, true);
|
||||
|
||||
return hash_equals(hash_hmac('sha256', $payload['mac'], $bytes, true), $calcMac);
|
||||
}
|
||||
}
|
||||
@@ -1,214 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\LegacyEncrypter;
|
||||
|
||||
use Exception;
|
||||
use Illuminate\Contracts\Encryption\DecryptException;
|
||||
use Illuminate\Contracts\Encryption\Encrypter as EncrypterContract;
|
||||
use Illuminate\Contracts\Encryption\EncryptException;
|
||||
use RuntimeException;
|
||||
|
||||
/**
|
||||
* @deprecated since version 5.1. Use Illuminate\Encryption\Encrypter.
|
||||
*/
|
||||
class McryptEncrypter extends BaseEncrypter implements EncrypterContract
|
||||
{
|
||||
/**
|
||||
* The algorithm used for encryption.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $cipher;
|
||||
|
||||
/**
|
||||
* The block size of the cipher.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $block;
|
||||
|
||||
/**
|
||||
* Create a new encrypter instance.
|
||||
*
|
||||
* @param string $key
|
||||
* @param string $cipher
|
||||
* @return void
|
||||
*
|
||||
* @throws \RuntimeException
|
||||
*/
|
||||
public function __construct($key, $cipher = MCRYPT_RIJNDAEL_128)
|
||||
{
|
||||
$key = (string) $key;
|
||||
|
||||
if (static::supported($key, $cipher)) {
|
||||
$this->key = $key;
|
||||
$this->cipher = $cipher;
|
||||
$this->block = mcrypt_get_iv_size($this->cipher, MCRYPT_MODE_CBC);
|
||||
} else {
|
||||
throw new RuntimeException('The only supported ciphers are MCRYPT_RIJNDAEL_128 and MCRYPT_RIJNDAEL_256.');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the given key and cipher combination is valid.
|
||||
*
|
||||
* @param string $key
|
||||
* @param string $cipher
|
||||
* @return bool
|
||||
*/
|
||||
public static function supported($key, $cipher)
|
||||
{
|
||||
return defined('MCRYPT_RIJNDAEL_128') &&
|
||||
($cipher === MCRYPT_RIJNDAEL_128 || $cipher === MCRYPT_RIJNDAEL_256);
|
||||
}
|
||||
|
||||
/**
|
||||
* Encrypt the given value.
|
||||
*
|
||||
* @param string $value
|
||||
* @return string
|
||||
*
|
||||
* @throws \Illuminate\Contracts\Encryption\EncryptException
|
||||
*/
|
||||
public function encrypt($value, $serialize = true)
|
||||
{
|
||||
$iv = mcrypt_create_iv($this->getIvSize(), $this->getRandomizer());
|
||||
|
||||
$value = base64_encode($this->padAndMcrypt($value, $iv));
|
||||
|
||||
// Once we have the encrypted value we will go ahead base64_encode the input
|
||||
// vector and create the MAC for the encrypted value so we can verify its
|
||||
// authenticity. Then, we'll JSON encode the data in a "payload" array.
|
||||
$mac = $this->hash($iv = base64_encode($iv), $value);
|
||||
|
||||
$json = json_encode(compact('iv', 'value', 'mac'));
|
||||
|
||||
if (! is_string($json)) {
|
||||
throw new EncryptException('Could not encrypt the data.');
|
||||
}
|
||||
|
||||
return base64_encode($json);
|
||||
}
|
||||
|
||||
/**
|
||||
* Pad and use mcrypt on the given value and input vector.
|
||||
*
|
||||
* @param string $value
|
||||
* @param string $iv
|
||||
* @return string
|
||||
*/
|
||||
protected function padAndMcrypt($value, $iv)
|
||||
{
|
||||
$value = $this->addPadding(serialize($value));
|
||||
|
||||
return mcrypt_encrypt($this->cipher, $this->key, $value, MCRYPT_MODE_CBC, $iv);
|
||||
}
|
||||
|
||||
/**
|
||||
* Decrypt the given value.
|
||||
*
|
||||
* @param string $payload
|
||||
* @return string
|
||||
*/
|
||||
public function decrypt($payload, $unserialize = true)
|
||||
{
|
||||
$payload = $this->getJsonPayload($payload);
|
||||
|
||||
// We'll go ahead and remove the PKCS7 padding from the encrypted value before
|
||||
// we decrypt it. Once we have the de-padded value, we will grab the vector
|
||||
// and decrypt the data, passing back the unserialized from of the value.
|
||||
$value = base64_decode($payload['value']);
|
||||
|
||||
$iv = base64_decode($payload['iv']);
|
||||
|
||||
return unserialize($this->stripPadding($this->mcryptDecrypt($value, $iv)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Run the mcrypt decryption routine for the value.
|
||||
*
|
||||
* @param string $value
|
||||
* @param string $iv
|
||||
* @return string
|
||||
*
|
||||
* @throws \Illuminate\Contracts\Encryption\DecryptException
|
||||
*/
|
||||
protected function mcryptDecrypt($value, $iv)
|
||||
{
|
||||
try {
|
||||
return mcrypt_decrypt($this->cipher, $this->key, $value, MCRYPT_MODE_CBC, $iv);
|
||||
} catch (Exception $e) {
|
||||
throw new DecryptException($e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add PKCS7 padding to a given value.
|
||||
*
|
||||
* @param string $value
|
||||
* @return string
|
||||
*/
|
||||
protected function addPadding($value)
|
||||
{
|
||||
$pad = $this->block - (strlen($value) % $this->block);
|
||||
|
||||
return $value.str_repeat(chr($pad), $pad);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the padding from the given value.
|
||||
*
|
||||
* @param string $value
|
||||
* @return string
|
||||
*/
|
||||
protected function stripPadding($value)
|
||||
{
|
||||
$pad = ord($value[($len = strlen($value)) - 1]);
|
||||
|
||||
return $this->paddingIsValid($pad, $value) ? substr($value, 0, $len - $pad) : $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the given padding for a value is valid.
|
||||
*
|
||||
* @param string $pad
|
||||
* @param string $value
|
||||
* @return bool
|
||||
*/
|
||||
protected function paddingIsValid($pad, $value)
|
||||
{
|
||||
$beforePad = strlen($value) - $pad;
|
||||
|
||||
return substr($value, $beforePad) == str_repeat(substr($value, -1), $pad);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the IV size for the cipher.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
protected function getIvSize()
|
||||
{
|
||||
return mcrypt_get_iv_size($this->cipher, MCRYPT_MODE_CBC);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the random data source available for the OS.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
protected function getRandomizer()
|
||||
{
|
||||
if (defined('MCRYPT_DEV_URANDOM')) {
|
||||
return MCRYPT_DEV_URANDOM;
|
||||
}
|
||||
|
||||
if (defined('MCRYPT_DEV_RANDOM')) {
|
||||
return MCRYPT_DEV_RANDOM;
|
||||
}
|
||||
|
||||
mt_srand();
|
||||
|
||||
return MCRYPT_RAND;
|
||||
}
|
||||
}
|
||||
@@ -115,7 +115,7 @@ class CheckoutableListener
|
||||
}
|
||||
return redirect()->back()->with('warning', ucfirst(Setting::getSettings()->webhook_selected) .trans('admin/settings/message.webhook.webhook_fail') );
|
||||
} catch (Exception $e) {
|
||||
Log::error(ucfirst(Setting::getSettings()->webhook_selected) . ' webhook notification failed:', [
|
||||
Log::warning(ucfirst(Setting::getSettings()->webhook_selected) . ' webhook notification failed:', [
|
||||
'error' => $e->getMessage(),
|
||||
'webhook_endpoint' => Setting::getSettings()->webhook_endpoint,
|
||||
'event' => $event,
|
||||
@@ -211,7 +211,7 @@ class CheckoutableListener
|
||||
return redirect()->back()->with('warning', ucfirst(Setting::getSettings()->webhook_selected) . trans('admin/settings/message.webhook.webhook_fail'));
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
Log::error(ucfirst(Setting::getSettings()->webhook_selected) . ' webhook notification failed:', [
|
||||
Log::warning(ucfirst(Setting::getSettings()->webhook_selected) . ' webhook notification failed:', [
|
||||
'error' => $e->getMessage(),
|
||||
'webhook_endpoint' => Setting::getSettings()->webhook_endpoint,
|
||||
'event' => $event,
|
||||
|
||||
@@ -12,11 +12,11 @@ class CategoryEditForm extends Component
|
||||
|
||||
public $originalSendCheckInEmailValue;
|
||||
|
||||
public $requireAcceptance;
|
||||
public bool $requireAcceptance;
|
||||
|
||||
public $sendCheckInEmail;
|
||||
public bool $sendCheckInEmail;
|
||||
|
||||
public $useDefaultEula;
|
||||
public bool $useDefaultEula;
|
||||
|
||||
public function mount()
|
||||
{
|
||||
|
||||
@@ -20,10 +20,12 @@ class CheckoutAssetMail extends Mailable
|
||||
{
|
||||
use Queueable, SerializesModels;
|
||||
|
||||
private bool $firstTimeSending;
|
||||
|
||||
/**
|
||||
* Create a new message instance.
|
||||
*/
|
||||
public function __construct(Asset $asset, $checkedOutTo, User $checkedOutBy, $acceptance, $note)
|
||||
public function __construct(Asset $asset, $checkedOutTo, User $checkedOutBy, $acceptance, $note, bool $firstTimeSending = true)
|
||||
{
|
||||
$this->item = $asset;
|
||||
$this->admin = $checkedOutBy;
|
||||
@@ -36,6 +38,8 @@ class CheckoutAssetMail extends Mailable
|
||||
$this->last_checkout = '';
|
||||
$this->expected_checkin = '';
|
||||
|
||||
$this->firstTimeSending = $firstTimeSending;
|
||||
|
||||
if ($this->item->last_checkout) {
|
||||
$this->last_checkout = Helper::getFormattedDateObject($this->item->last_checkout, 'date',
|
||||
false);
|
||||
@@ -56,7 +60,7 @@ class CheckoutAssetMail extends Mailable
|
||||
|
||||
return new Envelope(
|
||||
from: $from,
|
||||
subject: trans('mail.Asset_Checkout_Notification'),
|
||||
subject: $this->getSubject(),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -107,4 +111,13 @@ class CheckoutAssetMail extends Mailable
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
private function getSubject(): string
|
||||
{
|
||||
if ($this->firstTimeSending) {
|
||||
return trans('mail.Asset_Checkout_Notification');
|
||||
}
|
||||
|
||||
return trans('mail.unaccepted_asset_reminder');
|
||||
}
|
||||
}
|
||||
|
||||
65
app/Mail/SendUpcomingAuditMail.php
Normal file
65
app/Mail/SendUpcomingAuditMail.php
Normal file
@@ -0,0 +1,65 @@
|
||||
<?php
|
||||
|
||||
namespace App\Mail;
|
||||
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Mail\Mailable;
|
||||
use Illuminate\Mail\Mailables\Address;
|
||||
use Illuminate\Mail\Mailables\Content;
|
||||
use Illuminate\Mail\Mailables\Envelope;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
class SendUpcomingAuditMail extends Mailable
|
||||
{
|
||||
use Queueable, SerializesModels;
|
||||
|
||||
/**
|
||||
* Create a new message instance.
|
||||
*/
|
||||
public function __construct($params, $threshold)
|
||||
{
|
||||
$this->assets = $params;
|
||||
$this->threshold = $threshold;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the message envelope.
|
||||
*/
|
||||
public function envelope(): Envelope
|
||||
{
|
||||
$from = new Address(config('mail.from.address'), config('mail.from.name'));
|
||||
|
||||
return new Envelope(
|
||||
from: $from,
|
||||
subject: trans_choice('mail.upcoming-audits', $this->assets->count(), ['count' => $this->assets->count(), 'threshold' => $this->threshold]),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the message content definition.
|
||||
*/
|
||||
public function content(): Content
|
||||
{
|
||||
|
||||
|
||||
return new Content(
|
||||
|
||||
markdown: 'notifications.markdown.upcoming-audits',
|
||||
with: [
|
||||
'assets' => $this->assets,
|
||||
'threshold' => $this->threshold,
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the attachments for the message.
|
||||
*
|
||||
* @return array<int, \Illuminate\Mail\Mailables\Attachment>
|
||||
*/
|
||||
public function attachments(): array
|
||||
{
|
||||
return [];
|
||||
}
|
||||
}
|
||||
@@ -19,9 +19,10 @@ class UnacceptedAssetReminderMail extends Mailable
|
||||
*/
|
||||
public function __construct($checkout_info, $count)
|
||||
{
|
||||
|
||||
$this->count = $count;
|
||||
$this->target = $checkout_info['acceptance']?->assignedTo;
|
||||
$this->acceptance = $checkout_info['acceptance'];
|
||||
$this->target = $checkout_info?->assignedTo;
|
||||
$this->acceptance = $checkout_info;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -293,16 +293,22 @@ class Actionlog extends SnipeModel
|
||||
public function daysUntilNextAudit($monthInterval = 12, $asset = null)
|
||||
{
|
||||
$now = Carbon::now();
|
||||
$last_audit_date = $this->created_at;
|
||||
$next_audit = $last_audit_date->addMonth($monthInterval);
|
||||
$next_audit_days = $now->diffInDays($next_audit);
|
||||
$last_audit_date = $this->created_at; // this is the action log's created at, not the asset itself
|
||||
$next_audit = $last_audit_date->addMonth($monthInterval); // this actually *modifies* the $last_audit_date
|
||||
$next_audit_days = round($now->diffInDays($next_audit, true));
|
||||
$override_default_next = $next_audit;
|
||||
|
||||
// Override the default setting for interval if the asset has its own next audit date
|
||||
if (($asset) && ($asset->next_audit_date)) {
|
||||
$override_default_next = \Carbon::parse($asset->next_audit_date);
|
||||
$next_audit_days = $override_default_next->diffInDays($now);
|
||||
$override_default_next = Carbon::parse($asset->next_audit_date);
|
||||
$next_audit_days = round($override_default_next->diffInDays($now, true));
|
||||
}
|
||||
|
||||
// Show as negative number if the next audit date is before the audit date we're looking at
|
||||
if ($this->created_at > $override_default_next) {
|
||||
$next_audit_days = '-'.$next_audit_days;
|
||||
}
|
||||
|
||||
return $next_audit_days;
|
||||
}
|
||||
|
||||
|
||||
@@ -234,7 +234,7 @@ class AssetModel extends SnipeModel
|
||||
*/
|
||||
public function adminuser()
|
||||
{
|
||||
return $this->belongsTo(\App\Models\User::class, 'created_by');
|
||||
return $this->belongsTo(\App\Models\User::class, 'created_by')->withTrashed();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -149,11 +149,6 @@ class CustomField extends Model
|
||||
return true;
|
||||
}
|
||||
|
||||
// This is just a dumb thing we have to include because Laraval/Doctrine doesn't
|
||||
// play well with enums or a table that EVER had enums. :(
|
||||
$platform = Schema::getConnection()->getDoctrineSchemaManager()->getDatabasePlatform();
|
||||
$platform->registerDoctrineTypeMapping('enum', 'string');
|
||||
|
||||
// Rename the field if the name has changed
|
||||
Schema::table(self::$table_name, function ($table) use ($custom_field) {
|
||||
$table->renameColumn($custom_field->convertUnicodeDbSlug($custom_field->getOriginal('name')), $custom_field->convertUnicodeDbSlug());
|
||||
|
||||
@@ -90,12 +90,6 @@ class AssetMaintenancesPresenter extends Presenter
|
||||
'searchable' => true,
|
||||
'sortable' => true,
|
||||
'title' => trans('admin/asset_maintenances/form.asset_maintenance_type'),
|
||||
], [
|
||||
'field' => 'title',
|
||||
'searchable' => true,
|
||||
'sortable' => true,
|
||||
'switchable' => false,
|
||||
'title' => trans('admin/asset_maintenances/form.title'),
|
||||
], [
|
||||
'field' => 'start_date',
|
||||
'searchable' => true,
|
||||
|
||||
@@ -140,8 +140,8 @@ class Label implements View
|
||||
$barcode2DTarget = $asset->serial;
|
||||
break;
|
||||
case 'hardware_id':
|
||||
default:
|
||||
$barcode2DTarget = route('hardware.show', ['hardware' => $asset->id]);
|
||||
default:
|
||||
$barcode2DTarget = route('hardware.show', $asset);
|
||||
break;
|
||||
}
|
||||
$assetData->put('barcode2d', (object)[
|
||||
|
||||
@@ -105,4 +105,17 @@ $config = [
|
||||
// (by default, the PUBLIC_FILESYSTEM DISK is 'local_public', in the public/uploads directory)
|
||||
$config['disks']['public'] = $config['disks'][env('PUBLIC_FILESYSTEM_DISK','local_public')];
|
||||
|
||||
// Handle the 'backup' disk for S3 consideration
|
||||
if (env('PRIVATE_FILESYSTEM_DISK') == 's3_private') {
|
||||
$config['disks']['backup']['driver'] = 's3';
|
||||
$config['disks']['backup']['key'] = $config['disks']['s3_private']['key'];
|
||||
$config['disks']['backup']['secret'] = $config['disks']['s3_private']['secret'];
|
||||
$config['disks']['backup']['region'] = $config['disks']['s3_private']['region'];
|
||||
$config['disks']['backup']['bucket'] = $config['disks']['s3_private']['bucket'];
|
||||
$config['disks']['backup']['url'] = $config['disks']['s3_private']['url'];
|
||||
$config['disks']['backup']['root'] = $config['disks']['s3_private']['root'];
|
||||
$config['disks']['backup']['visibility'] = 'private';
|
||||
}
|
||||
|
||||
|
||||
return $config;
|
||||
@@ -1,10 +1,10 @@
|
||||
<?php
|
||||
return array (
|
||||
'app_version' => 'v8.0.0',
|
||||
'full_app_version' => 'v8.0.0 - build 16962-g982cfeca32',
|
||||
'build_version' => '16962',
|
||||
'app_version' => 'v8.0.2',
|
||||
'full_app_version' => 'v8.0.2 - build 17048-g44dd06161',
|
||||
'build_version' => '17048',
|
||||
'prerelease_version' => '',
|
||||
'hash_version' => 'g982cfeca32',
|
||||
'full_hash' => 'v8.0.0-172-g982cfeca32',
|
||||
'branch' => 'master',
|
||||
);
|
||||
'hash_version' => 'g44dd06161',
|
||||
'full_hash' => 'v8.0.2-54-g44dd06161',
|
||||
'branch' => 'develop',
|
||||
);
|
||||
@@ -27,6 +27,10 @@ class CheckoutAcceptanceFactory extends Factory
|
||||
public function configure(): static
|
||||
{
|
||||
return $this->afterCreating(function (CheckoutAcceptance $acceptance) {
|
||||
if ($acceptance->checkoutable instanceof Asset) {
|
||||
$this->createdAssociatedActionLogEntry($acceptance);
|
||||
}
|
||||
|
||||
if ($acceptance->checkoutable instanceof Asset && $acceptance->assignedTo instanceof User) {
|
||||
$acceptance->checkoutable->update([
|
||||
'assigned_to' => $acceptance->assigned_to_id,
|
||||
@@ -51,4 +55,23 @@ class CheckoutAcceptanceFactory extends Factory
|
||||
'declined_at' => null,
|
||||
]);
|
||||
}
|
||||
|
||||
public function accepted()
|
||||
{
|
||||
return $this->state([
|
||||
'accepted_at' => now()->subDay(),
|
||||
'declined_at' => null,
|
||||
]);
|
||||
}
|
||||
|
||||
private function createdAssociatedActionLogEntry(CheckoutAcceptance $acceptance): void
|
||||
{
|
||||
$acceptance->checkoutable->assetlog()->create([
|
||||
'action_type' => 'checkout',
|
||||
'target_id' => $acceptance->assigned_to_id,
|
||||
'target_type' => get_class($acceptance->assignedTo),
|
||||
'item_id' => $acceptance->checkoutable_id,
|
||||
'item_type' => $acceptance->checkoutable_type,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::table('settings', function (Blueprint $table) {
|
||||
$table->boolean('ldap_invert_active_flag')->default(false);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('settings', function (Blueprint $table) {
|
||||
$table->dropColumn('ldap_invert_active_flag');
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -13,4 +13,8 @@ return [
|
||||
'no_depreciations_warning' => '<strong>Warning: </strong>
|
||||
You do not currently have any depreciations set up.
|
||||
Please set up at least one depreciation to view the depreciation report.',
|
||||
'depreciation_method' => 'Depreciation Method',
|
||||
'linear_depreciation' => 'Linear (Default)',
|
||||
'half_1' => 'Half-year convention, always applied',
|
||||
'half_2' => 'Half-year convention, applied with condition',
|
||||
];
|
||||
|
||||
@@ -56,7 +56,7 @@ return [
|
||||
'asset_location_update_actual' => 'Update only actual location',
|
||||
'asset_not_deployable' => 'That asset status is not deployable. This asset cannot be checked out.',
|
||||
'asset_not_deployable_checkin' => 'That asset status is not deployable. Using this status label will checkin the asset.',
|
||||
'asset_deployable' => 'That status is deployable. This asset can be checked out.',
|
||||
'asset_deployable' => 'This asset can be checked out.',
|
||||
'processing_spinner' => 'Processing... (This might take a bit of time on large files)',
|
||||
'optional_infos' => 'Optional Information',
|
||||
'order_details' => 'Order Related Information',
|
||||
|
||||
@@ -66,6 +66,7 @@ return [
|
||||
'file_already_deleted' => 'The file selected was already deleted',
|
||||
'header_row_has_malformed_characters' => 'One or more attributes in the header row contain malformed UTF-8 characters',
|
||||
'content_row_has_malformed_characters' => 'One or more attributes in the first row of content contain malformed UTF-8 characters',
|
||||
'transliterate_failure' => 'Transliteration from :encoding to UTF-8 failed due to invalid characters in input'
|
||||
],
|
||||
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ return [
|
||||
'info' => 'Select the options you want for your asset report.',
|
||||
'deleted_user' => 'Deleted user',
|
||||
'send_reminder' => 'Send reminder',
|
||||
'cannot_send_reminder' => 'User has been deleted or does not have an email address so cannot receive a reminder',
|
||||
'reminder_sent' => 'Reminder sent',
|
||||
'acceptance_deleted' => 'Acceptance request deleted',
|
||||
'acceptance_request' => 'Acceptance request',
|
||||
|
||||
@@ -42,6 +42,7 @@ return [
|
||||
'confirm_purge' => 'Confirm Purge',
|
||||
'confirm_purge_help' => 'Enter the text "DELETE" in the box below to purge your deleted records. This action cannot be undone and will PERMANENTLY delete all soft-deleted items and users. (You should make a backup first, just to be safe.)',
|
||||
'custom_css' => 'Custom CSS',
|
||||
'custom_css_placeholder' => 'Add your custom CSS',
|
||||
'custom_css_help' => 'Enter any custom CSS overrides you would like to use. Do not include the <style></style> tags.',
|
||||
'custom_forgot_pass_url' => 'Custom Password Reset URL',
|
||||
'custom_forgot_pass_url_help' => 'This replaces the built-in forgotten password URL on the login screen, useful to direct people to internal or hosted LDAP password reset functionality. It will effectively disable local user forgotten password functionality.',
|
||||
@@ -69,6 +70,7 @@ return [
|
||||
'favicon_size' => 'Favicons should be square images, 16x16 pixels.',
|
||||
'footer_text' => 'Additional Footer Text ',
|
||||
'footer_text_help' => 'This text will appear in the right-side footer. Links are allowed using <a href="https://help.github.com/articles/github-flavored-markdown/">Github flavored markdown</a>. Line breaks, headers, images, etc may result in unpredictable results.',
|
||||
'footer_text_placeholder' => 'Optional footer text',
|
||||
'general_settings' => 'General Settings',
|
||||
'general_settings_help' => 'Default EULA and more',
|
||||
'generate_backup' => 'Generate Backup',
|
||||
@@ -118,6 +120,8 @@ return [
|
||||
'ldap_version' => 'LDAP Version',
|
||||
'ldap_active_flag' => 'LDAP Active Flag',
|
||||
'ldap_activated_flag_help' => 'This value is used to determine whether a synced user can login to Snipe-IT. <strong>It does not affect the ability to check items in or out to them</strong>, and should be the <strong>attribute name</strong> within your AD/LDAP, <strong>not the value</strong>. <br><br>If this field is set to a field name that does not exist in your AD/LDAP, or the value in the AD/LDAP field is set to <code>0</code> or <code>false</code>, <strong>user login will be disabled</strong>. If the value in the AD/LDAP field is set to <code>1</code> or <code>true</code> or <em>any other text</em> means the user can log in. When the field is blank in your AD, we respect the <code>userAccountControl</code> attribute, which usually allows non-suspended users to log in.',
|
||||
'ldap_invert_active_flag' => 'LDAP Invert Active Flag',
|
||||
'ldap_invert_active_flag_help' => 'If enabled: when the value returned by LDAP Active Flag is <code>0</code> or <code>false</code> the user account will be active.',
|
||||
'ldap_emp_num' => 'LDAP Employee Number',
|
||||
'ldap_email' => 'LDAP Email',
|
||||
'ldap_test' => 'Test LDAP',
|
||||
@@ -132,6 +136,7 @@ return [
|
||||
'login_user_agent' => 'User Agent',
|
||||
'login_help' => 'List of attempted logins',
|
||||
'login_note' => 'Login Note',
|
||||
'login_note_placeholder' => "If you do not have a login or have found a device belonging to this company, please call technical support at 888-555-1212. Thank you.",
|
||||
'login_note_help' => 'Optionally include a few sentences on your login screen, for example to assist people who have found a lost or stolen device. This field accepts <a href="https://help.github.com/articles/github-flavored-markdown/">Github flavored markdown</a>',
|
||||
'login_remote_user_text' => 'Remote User login options',
|
||||
'login_remote_user_enabled_text' => 'Enable Login with Remote User Header',
|
||||
@@ -345,6 +350,8 @@ return [
|
||||
'setup_migration_create_user' => 'Next: Create User',
|
||||
'ldap_settings_link' => 'LDAP Settings Page',
|
||||
'slack_test' => 'Test <i class="fab fa-slack"></i> Integration',
|
||||
'status_label_name' => 'Status Label Name',
|
||||
'super_admin_only' => 'Super Admin Only',
|
||||
'label2_enable' => 'New Label Engine',
|
||||
'label2_enable_help' => 'Switch to the new label engine. <b>Note: You will need to save this setting before setting others.</b>',
|
||||
'label2_template' => 'Template',
|
||||
@@ -378,6 +385,7 @@ return [
|
||||
'database_driver' => 'Database Driver',
|
||||
'bs_table_storage' => 'Table Storage',
|
||||
'timezone' => 'Timezone',
|
||||
'test_mail' => 'Test Mail',
|
||||
'profile_edit' => 'Edit Profile',
|
||||
'profile_edit_help' => 'Allow users to edit their own profiles.',
|
||||
'default_avatar' => 'Upload custom default avatar',
|
||||
@@ -387,6 +395,15 @@ return [
|
||||
'due_checkin_days' => 'Due For Checkin Warning',
|
||||
'due_checkin_days_help' => 'How many days before the expected checkin of an asset should it be listed in the "Due for checkin" page?',
|
||||
'no_groups' => 'No groups have been created yet. Visit <code>Admin Settings > Permission Groups</code> to add one.',
|
||||
'text' => 'Text',
|
||||
|
||||
|
||||
'logo_option_types' => [
|
||||
'text' => 'Text',
|
||||
'logo' => 'Logo',
|
||||
'logo_and_text' => 'Logo and Text',
|
||||
],
|
||||
|
||||
|
||||
|
||||
/* Keywords for settings overview help */
|
||||
|
||||
@@ -599,5 +599,6 @@ return [
|
||||
'generic_model_not_found' => 'That :model was not found or you do not have permission to access it',
|
||||
'deleted_models' => 'Deleted Asset Models',
|
||||
'deleted_users' => 'Deleted Users',
|
||||
'cost_each' => ':amount each',
|
||||
|
||||
];
|
||||
|
||||
@@ -26,9 +26,9 @@
|
||||
<livewire:category-edit-form
|
||||
:default-eula-text="$snipeSettings->default_eula_text"
|
||||
:eula-text="old('eula_text', $item->eula_text)"
|
||||
:require-acceptance="old('require_acceptance', $item->require_acceptance)"
|
||||
:send-check-in-email="old('checkin_email', $item->checkin_email)"
|
||||
:use-default-eula="old('use_default_eula', $item->use_default_eula)"
|
||||
:require-acceptance="(bool) old('require_acceptance', $item->require_acceptance)"
|
||||
:send-check-in-email="(bool) old('checkin_email', $item->checkin_email)"
|
||||
:use-default-eula="(bool) old('use_default_eula', $item->use_default_eula)"
|
||||
/>
|
||||
|
||||
@include ('partials.forms.edit.image-upload', ['image_path' => app('categories_upload_path')])
|
||||
|
||||
@@ -87,7 +87,7 @@
|
||||
<div class="form-group">
|
||||
<div class="col-sm-10 col-md-offset-2">
|
||||
<label class="form-control">
|
||||
{{ Form::checkbox('match_firstnamelastname', '1', old('match_firstnamelastname')) }}
|
||||
<input type="checkbox" name="match_firstnamelastname" value="1" @checked(old('match_firstnamelastname'))>
|
||||
<!-- enclosing span needed for the checkbox CSS to work properly, since there's HTML in the label text -->
|
||||
<span>
|
||||
{!! trans('admin/hardware/general.csv_import_match_f-l') !!}
|
||||
@@ -100,7 +100,7 @@
|
||||
<div class="form-group">
|
||||
<div class="col-sm-10 col-md-offset-2">
|
||||
<label class="form-control">
|
||||
{{ Form::checkbox('match_flastname', '1', old('match_flastname')) }}
|
||||
<input type="checkbox" name="match_flastname" value="1" @checked(old('match_flastname'))>
|
||||
<!-- enclosing span needed for the checkbox CSS to work properly, since there's HTML in the label text -->
|
||||
<span>
|
||||
{!! trans('admin/hardware/general.csv_import_match_initial_last') !!}
|
||||
@@ -113,7 +113,7 @@
|
||||
<div class="form-group">
|
||||
<div class="col-sm-10 col-md-offset-2">
|
||||
<label class="form-control">
|
||||
{{ Form::checkbox('match_firstname', '1', old('match_firstname')) }}
|
||||
<input type="checkbox" name="match_firstname" value="1" @checked(old('match_firstname'))>
|
||||
<!-- enclosing span needed for the checkbox CSS to work properly, since there's HTML in the label text -->
|
||||
<span>
|
||||
{!! trans('admin/hardware/general.csv_import_match_first') !!}
|
||||
@@ -126,7 +126,7 @@
|
||||
<div class="form-group">
|
||||
<div class="col-sm-10 col-md-offset-2">
|
||||
<label class="form-control">
|
||||
{{ Form::checkbox('match_email', '1', old('match_email')) }}
|
||||
<input type="checkbox" name="match_email" value="1" @checked(old('match_email'))>
|
||||
<!-- enclosing span needed for the checkbox CSS to work properly, since there's HTML in the label text -->
|
||||
<span>
|
||||
{!! trans('admin/hardware/general.csv_import_match_email') !!}
|
||||
@@ -139,7 +139,7 @@
|
||||
<div class="form-group">
|
||||
<div class="col-sm-10 col-md-offset-2">
|
||||
<label class="form-control">
|
||||
{{ Form::checkbox('match_username', '1', old('match_username')) }}
|
||||
<input type="checkbox" name="match_username" value="1" @checked(old('match_username'))>
|
||||
<!-- enclosing span needed for the checkbox CSS to work properly, since there's HTML in the label text -->
|
||||
<span>
|
||||
{!! trans('admin/hardware/general.csv_import_match_username') !!}
|
||||
|
||||
@@ -1211,7 +1211,7 @@
|
||||
<a href="{{ route('components.show', $component->id) }}">{{ $component->name }}</a>
|
||||
</td>
|
||||
<td>{{ $component->pivot->assigned_qty }}</td>
|
||||
<td>{{ Helper::formatCurrencyOutput($component->purchase_cost) }} each</td>
|
||||
<td>{{ trans('general.cost_each', ['amount' => Helper::formatCurrencyOutput($component->purchase_cost)]) }} </td>
|
||||
<td>{{ $component->serial }}</td>
|
||||
<td>
|
||||
<a href="{{ route('components.checkin.show', $component->pivot->id) }}" class="btn btn-sm bg-purple hidden-print" data-tooltip="true">{{ trans('general.checkin') }}</a>
|
||||
|
||||
@@ -68,7 +68,7 @@
|
||||
</div>
|
||||
<div class="col-md-7">
|
||||
<label class="form-control">
|
||||
{{ Form::Checkbox('reassignable', '1', old('reassignable', $item->id ? $item->reassignable : '1'),array('aria-label'=>'reassignable')) }}
|
||||
<input type="checkbox" name="reassignable" value="1" aria-label="reassignable" @checked(old('reassignable', $item->id ? $item->reassignable : '1'))>
|
||||
{{ trans('general.yes') }}
|
||||
</label>
|
||||
</div>
|
||||
@@ -124,7 +124,7 @@
|
||||
<div class="col-md-3 control-label"><strong>{{ trans('admin/licenses/form.maintained') }}</strong></div>
|
||||
<div class="col-md-7">
|
||||
<label class="form-control">
|
||||
{{ Form::Checkbox('maintained', '1', old('maintained', $item->maintained),array('aria-label'=>'maintained')) }}
|
||||
<input type="checkbox" name="maintained" value="1" aria-label="maintained" @checked(old('maintained', $item->maintained))>
|
||||
{{ trans('general.yes') }}
|
||||
</label>
|
||||
</div>
|
||||
|
||||
@@ -23,12 +23,25 @@
|
||||
<div class="col-md-9 col-md-offset-3">
|
||||
@if ($defaultEulaText!='')
|
||||
<label class="form-control">
|
||||
{{ Form::checkbox('use_default_eula', '1', $useDefaultEula, ['wire:model.live' => 'useDefaultEula', 'aria-label'=>'use_default_eula']) }}
|
||||
<input
|
||||
type="checkbox"
|
||||
name="use_default_eula"
|
||||
value="1"
|
||||
wire:model.live="useDefaultEula"
|
||||
aria-label="use_default_eula"
|
||||
/>
|
||||
<span>{!! trans('admin/categories/general.use_default_eula') !!}</span>
|
||||
</label>
|
||||
@else
|
||||
<label class="form-control form-control--disabled">
|
||||
{{ Form::checkbox('use_default_eula', '0', $useDefaultEula, ['wire:model.live' => 'useDefaultEula', 'class'=>'disabled','disabled' => 'disabled', 'aria-label'=>'use_default_eula']) }}
|
||||
<input
|
||||
type="checkbox"
|
||||
name="use_default_eula"
|
||||
value="0"
|
||||
wire:model.live="useDefaultEula"
|
||||
aria-label="use_default_eula"
|
||||
disabled
|
||||
/>
|
||||
<span>{!! trans('admin/categories/general.use_default_eula_disabled') !!}</span>
|
||||
</label>
|
||||
@endif
|
||||
@@ -39,7 +52,13 @@
|
||||
<div class="form-group">
|
||||
<div class="col-md-9 col-md-offset-3">
|
||||
<label class="form-control">
|
||||
{{ Form::checkbox('require_acceptance', '1', $requireAcceptance, ['wire:model.live' => 'requireAcceptance', 'aria-label'=>'require_acceptance']) }}
|
||||
<input
|
||||
type="checkbox"
|
||||
name="require_acceptance"
|
||||
value="1"
|
||||
wire:model.live="requireAcceptance"
|
||||
aria-label="require_acceptance"
|
||||
/>
|
||||
{{ trans('admin/categories/general.require_acceptance') }}
|
||||
</label>
|
||||
</div>
|
||||
@@ -49,7 +68,14 @@
|
||||
<div class="form-group">
|
||||
<div class="col-md-9 col-md-offset-3">
|
||||
<label class="form-control">
|
||||
{{ Form::checkbox('checkin_email', '1', $sendCheckInEmail, ['wire:model.live' => 'sendCheckInEmail', 'aria-label'=>'checkin_email', 'disabled' => $this->sendCheckInEmailDisabled]) }}
|
||||
<input
|
||||
type="checkbox"
|
||||
name="checkin_email"
|
||||
value="1"
|
||||
wire:model.live="sendCheckInEmail"
|
||||
aria-label="checkin_email"
|
||||
@disabled($this->sendCheckInEmailDisabled)
|
||||
/>
|
||||
{{ trans('admin/categories/general.checkin_email') }}
|
||||
</label>
|
||||
@if ($this->shouldDisplayEmailMessage)
|
||||
|
||||
@@ -10,8 +10,15 @@
|
||||
<div class="col-md-3">
|
||||
@if ($fieldset_id)
|
||||
<label class="form-control">
|
||||
|
||||
{{ Form::checkbox('add_default_values', 1, old('add_default_values', $add_default_values), ['data-livewire-component' => $this->getId(), 'id' => 'add_default_values', 'wire:model.live' => 'add_default_values', 'disabled' => $this->fields->isEmpty()]) }}
|
||||
<input
|
||||
type="checkbox"
|
||||
name="add_default_values"
|
||||
value="1"
|
||||
id="add_default_values"
|
||||
wire:model.live="add_default_values"
|
||||
data-livewire-component="{{ $this->getId() }}"
|
||||
@disabled($this->fields->isEmpty())
|
||||
/>
|
||||
{{ trans('admin/models/general.add_default_values') }}
|
||||
</label>
|
||||
@endif
|
||||
|
||||
@@ -164,7 +164,7 @@
|
||||
</li>
|
||||
@endif
|
||||
|
||||
@if ($model->created_by)
|
||||
@if ($model->adminuser)
|
||||
<li>{{ trans('general.created_by') }}:
|
||||
{{ $model->adminuser->present()->name() }}
|
||||
</li>
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
@php
|
||||
$checkin = Helper::getFormattedDateObject($asset->expected_checkin, 'date');
|
||||
@endphp
|
||||
| [{{ $asset->present()->name }}]({{ route('hardware.show', ['hardware' => $asset->id]) }}) | [{{ $asset->assignedTo->present()->fullName }}]({{ route($asset->targetShowRoute().'.show', [$asset->assignedTo->id]) }}) | {{ $checkin['formatted'] }}
|
||||
| [{{ $asset->present()->name }}]({{ route('hardware.show', $asset) }}) | [{{ $asset->assignedTo->present()->fullName }}]({{ route($asset->targetShowRoute().'.show', [$asset->assignedTo->id]) }}) | {{ $checkin['formatted'] }}
|
||||
@endforeach
|
||||
@endcomponent
|
||||
|
||||
|
||||
@@ -29,7 +29,16 @@
|
||||
data_export_options = $(this).attr('data-export-options');
|
||||
export_options = data_export_options ? JSON.parse(data_export_options) : {};
|
||||
export_options['htmlContent'] = false; // this is already the default; but let's be explicit about it
|
||||
export_options['jspdf']= {"orientation": "l"};
|
||||
export_options['jspdf'] = {
|
||||
"orientation": "l",
|
||||
"autotable": {
|
||||
"styles": {
|
||||
overflow: 'linebreak'
|
||||
},
|
||||
tableWidth: 'wrap'
|
||||
}
|
||||
};
|
||||
// tableWidth: 'wrap',
|
||||
// the following callback method is necessary to prevent XSS vulnerabilities
|
||||
// (this is taken from Bootstrap Tables's default wrapper around jQuery Table Export)
|
||||
export_options['onCellHtmlData'] = function (cell, rowIndex, colIndex, htmlData) {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<div class="form-group {{ $errors->has('email') ? ' has-error' : '' }}">
|
||||
<label for="email" class="col-md-3 col-xs-12 control-label">{{ trans('admin/suppliers/table.email') }}</label>
|
||||
<div class="col-md-8 col-xs-12">
|
||||
<input type="text" name="email" id="email" value="{{ old('email', ($item->email ?? $user->email)) }}" class="form-control" maxlength="191" style="width:100%; display:flex;">
|
||||
<input type="text" name="email" id="email" value="{{ old('email', $item->email) }}" class="form-control" maxlength="191" style="width:100%; display:flex;">
|
||||
{!! $errors->first('email', '<span class="alert-msg" aria-hidden="true"><i class="fas fa-times" aria-hidden="true"></i> :message</span>') !!}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<div class="form-group{{ $errors->has('image_delete') ? ' has-error' : '' }}">
|
||||
<div class="col-md-9 col-md-offset-3">
|
||||
<label class="form-control">
|
||||
{{ Form::checkbox('image_delete', '1', old('image_delete'), ['aria-label'=>'image_delete']) }}
|
||||
<input type="checkbox" name="image_delete" value="1" @checked(old('image_delete')) aria-label="image_delete">
|
||||
{{ trans('general.image_delete') }}
|
||||
{!! $errors->first('image_delete', '<span class="alert-msg">:message</span>') !!}
|
||||
</label>
|
||||
|
||||
@@ -47,7 +47,7 @@
|
||||
|
||||
<div class="col-md-9 col-md-offset-3">
|
||||
<label id="{{ $logoId }}-deleteCheckbox" for="{{ $logoClearVariable }}" style="font-weight: normal" class="form-control">
|
||||
{{ Form::checkbox($logoClearVariable, '1', old($logoClearVariable)) }}
|
||||
<input type="checkbox" name="{{ $logoClearVariable }}" value="1" @checked(old($logoClearVariable))>
|
||||
Remove current {{ ucwords(str_replace('_', ' ', $logoVariable)) }} image
|
||||
</label>
|
||||
</div>
|
||||
|
||||
@@ -35,13 +35,12 @@
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="col-sm-1" data-field="file" data-visible="false" data-formatter="auditImageFormatter">{{ trans('admin/hardware/table.image') }}</th>
|
||||
<th class="col-sm-2" data-field="created_at" data-formatter="dateDisplayFormatter" data-sortable="true" data-searchable="true">{{ trans('general.audit') }}</th>
|
||||
<th class="col-sm-2" data-field="created_by" data-sortable="true" data-searchable="true" data-formatter="usersLinkObjFormatter">{{ trans('general.admin') }}</th>
|
||||
<th class="col-sm-2" data-field="created_by" data-sortable="true" data-searchable="true" data-formatter="usersLinkObjFormatter">{{ trans('general.created_by') }}</th>
|
||||
<th class="col-sm-2" data-field="item" data-sortable="true" data-searchable="true" data-formatter="polymorphicItemFormatter">{{ trans('general.item') }}</th>
|
||||
<th class="col-sm-1" data-field="location" data-sortable="true" data-searchable="true" data-formatter="locationsLinkObjFormatter">{{ trans('general.location') }}</th>
|
||||
<th class="col-sm-2" data-field="created_at" data-formatter="dateDisplayFormatter" data-sortable="true" data-searchable="true">{{ trans('general.last_audit') }}</th>
|
||||
<th class="col-sm-2" data-field="next_audit_date" data-formatter="dateDisplayFormatter">{{ trans('general.next_audit_date') }}</th>
|
||||
<th class="col-sm-1" data-field="days_to_next_audit">{{ trans('general.days_to_next_audit') }}</th>
|
||||
|
||||
<th class="col-sm-2" data-field="note" data-sortable="true" data-searchable="true">{{ trans('general.notes') }}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
@@ -93,152 +93,152 @@
|
||||
</label>
|
||||
|
||||
<label class="form-control">
|
||||
{{ Form::checkbox('id', '1', $template->checkmarkValue('id')) }}
|
||||
<input type="checkbox" name="id" value="1" @checked($template->checkmarkValue('id')) />
|
||||
{{ trans('general.id') }}
|
||||
</label>
|
||||
|
||||
<label class="form-control">
|
||||
{{ Form::checkbox('company', '1', $template->checkmarkValue('company')) }}
|
||||
<input type="checkbox" name="company" value="1" @checked($template->checkmarkValue('company')) />
|
||||
{{ trans('general.company') }}
|
||||
</label>
|
||||
|
||||
<label class="form-control">
|
||||
{{ Form::checkbox('asset_tag', '1', $template->checkmarkValue('asset_tag')) }}
|
||||
<input type="checkbox" name="asset_tag" value="1" @checked($template->checkmarkValue('asset_tag')) />
|
||||
{{ trans('general.asset_tag') }}
|
||||
</label>
|
||||
|
||||
<label class="form-control">
|
||||
{{ Form::checkbox('asset_name', '1', $template->checkmarkValue('asset_name')) }}
|
||||
<input type="checkbox" name="asset_name" value="1" @checked($template->checkmarkValue('asset_name')) />
|
||||
{{ trans('admin/hardware/form.name') }}
|
||||
</label>
|
||||
|
||||
<label class="form-control">
|
||||
{{ Form::checkbox('manufacturer', '1', $template->checkmarkValue('manufacturer')) }}
|
||||
<input type="checkbox" name="manufacturer" value="1" @checked($template->checkmarkValue('manufacturer')) />
|
||||
{{ trans('general.manufacturer') }}
|
||||
</label>
|
||||
|
||||
<label class="form-control">
|
||||
{{ Form::checkbox('model', '1', $template->checkmarkValue('model')) }}
|
||||
<input type="checkbox" name="model" value="1" @checked($template->checkmarkValue('model')) />
|
||||
{{ trans('general.asset_models') }}
|
||||
</label>
|
||||
|
||||
<label class="form-control">
|
||||
{{ Form::checkbox('category', '1', $template->checkmarkValue('category')) }}
|
||||
<input type="checkbox" name="category" value="1" @checked($template->checkmarkValue('category')) />
|
||||
{{ trans('general.category') }}
|
||||
</label>
|
||||
|
||||
<label class="form-control">
|
||||
{{ Form::checkbox('serial', '1', $template->checkmarkValue('serial')) }}
|
||||
<input type="checkbox" name="serial" value="1" @checked($template->checkmarkValue('serial')) />
|
||||
{{ trans('admin/hardware/table.serial') }}
|
||||
</label>
|
||||
|
||||
<label class="form-control">
|
||||
{{ Form::checkbox('purchase_date', '1', $template->checkmarkValue('purchase_date')) }}
|
||||
<input type="checkbox" name="purchase_date" value="1" @checked($template->checkmarkValue('purchase_date')) />
|
||||
{{ trans('admin/licenses/table.purchase_date') }}
|
||||
</label>
|
||||
|
||||
<label class="form-control">
|
||||
{{ Form::checkbox('purchase_cost', '1', $template->checkmarkValue('purchase_cost')) }}
|
||||
<input type="checkbox" name="purchase_cost" value="1" @checked($template->checkmarkValue('purchase_cost')) />
|
||||
{{ trans('admin/hardware/form.cost') }}
|
||||
</label>
|
||||
|
||||
<label class="form-control">
|
||||
{{ Form::checkbox('eol', '1', $template->checkmarkValue('eol')) }}
|
||||
<input type="checkbox" name="eol" value="1" @checked($template->checkmarkValue('eol')) />
|
||||
{{ trans('admin/hardware/form.eol_date') }}
|
||||
</label>
|
||||
|
||||
<label class="form-control">
|
||||
{{ Form::checkbox('order', '1', $template->checkmarkValue('order')) }}
|
||||
<input type="checkbox" name="order" value="1" @checked($template->checkmarkValue('order')) />
|
||||
{{ trans('admin/hardware/form.order') }}
|
||||
</label>
|
||||
|
||||
<label class="form-control">
|
||||
{{ Form::checkbox('supplier', '1', $template->checkmarkValue('supplier')) }}
|
||||
<input type="checkbox" name="supplier" value="1" @checked($template->checkmarkValue('supplier')) />
|
||||
{{ trans('general.suppliers') }}
|
||||
</label>
|
||||
|
||||
<label class="form-control">
|
||||
{{ Form::checkbox('location', '1', $template->checkmarkValue('location')) }}
|
||||
<input type="checkbox" name="location" value="1" @checked($template->checkmarkValue('location')) />
|
||||
{{ trans('general.location') }}
|
||||
</label>
|
||||
|
||||
<label class="form-control" style="margin-left: 25px;">
|
||||
{{ Form::checkbox('location_address', '1', $template->checkmarkValue('location_address')) }}
|
||||
<input type="checkbox" name="location_address" value="1" @checked($template->checkmarkValue('location_address')) />
|
||||
{{ trans('general.address') }}
|
||||
</label>
|
||||
|
||||
<label class="form-control">
|
||||
{{ Form::checkbox('rtd_location', '1', $template->checkmarkValue('rtd_location')) }}
|
||||
<input type="checkbox" name="rtd_location" value="1" @checked($template->checkmarkValue('rtd_location')) />
|
||||
{{ trans('admin/hardware/form.default_location') }}
|
||||
</label>
|
||||
|
||||
<label class="form-control" style="margin-left: 25px;">
|
||||
{{ Form::checkbox('rtd_location_address', '1', $template->checkmarkValue('rtd_location_address')) }}
|
||||
<input type="checkbox" name="rtd_location_address" value="1" @checked($template->checkmarkValue('rtd_location_address')) />
|
||||
{{ trans('general.address') }}
|
||||
</label>
|
||||
|
||||
<label class="form-control">
|
||||
{{ Form::checkbox('status', '1', $template->checkmarkValue('status')) }}
|
||||
<input type="checkbox" name="status" value="1" @checked($template->checkmarkValue('status')) />
|
||||
{{ trans('general.status') }}
|
||||
</label>
|
||||
|
||||
<label class="form-control">
|
||||
{{ Form::checkbox('warranty', '1', $template->checkmarkValue('warranty')) }}
|
||||
<input type="checkbox" name="warranty" value="1" @checked($template->checkmarkValue('warranty')) />
|
||||
{{ trans('admin/hardware/form.warranty') }}
|
||||
</label>
|
||||
|
||||
<label class="form-control">
|
||||
{{ Form::checkbox('depreciation', '1', $template->checkmarkValue('depreciation')) }}
|
||||
<input type="checkbox" name="depreciation" value="1" @checked($template->checkmarkValue('depreciation')) />
|
||||
{{ trans('general.depreciation') }}
|
||||
</label>
|
||||
|
||||
<label class="form-control">
|
||||
{{ Form::checkbox('checkout_date', '1', $template->checkmarkValue('checkout_date')) }}
|
||||
<input type="checkbox" name="checkout_date" value="1" @checked($template->checkmarkValue('checkout_date')) />
|
||||
{{ trans('admin/hardware/table.checkout_date') }}
|
||||
</label>
|
||||
|
||||
<label class="form-control">
|
||||
{{ Form::checkbox('checkin_date', '1', $template->checkmarkValue('checkin_date')) }}
|
||||
<input type="checkbox" name="checkin_date" value="1" @checked($template->checkmarkValue('checkin_date')) />
|
||||
{{ trans('admin/hardware/table.last_checkin_date') }}
|
||||
</label>
|
||||
|
||||
<label class="form-control">
|
||||
{{ Form::checkbox('expected_checkin', '1', $template->checkmarkValue('expected_checkin')) }}
|
||||
<input type="checkbox" name="expected_checkin" value="1" @checked($template->checkmarkValue('expected_checkin')) />
|
||||
{{ trans('admin/hardware/form.expected_checkin') }}
|
||||
</label>
|
||||
|
||||
<label class="form-control">
|
||||
{{ Form::checkbox('created_at', '1', $template->checkmarkValue('created_at')) }}
|
||||
<input type="checkbox" name="created_at" value="1" @checked($template->checkmarkValue('created_at')) />
|
||||
{{ trans('general.created_at') }}
|
||||
</label>
|
||||
|
||||
<label class="form-control">
|
||||
{{ Form::checkbox('updated_at', '1', $template->checkmarkValue('updated_at')) }}
|
||||
<input type="checkbox" name="updated_at" value="1" @checked($template->checkmarkValue('updated_at')) />
|
||||
{{ trans('general.updated_at') }}
|
||||
</label>
|
||||
|
||||
<label class="form-control">
|
||||
{{ Form::checkbox('deleted_at', '1', $template->checkmarkValue('deleted_at')) }}
|
||||
<input type="checkbox" name="deleted_at" value="1" @checked($template->checkmarkValue('deleted_at')) />
|
||||
{{ trans('general.deleted') }}
|
||||
</label>
|
||||
|
||||
<label class="form-control">
|
||||
{{ Form::checkbox('last_audit_date', '1', $template->checkmarkValue('last_audit_date')) }}
|
||||
<input type="checkbox" name="last_audit_date" value="1" @checked($template->checkmarkValue('last_audit_date')) />
|
||||
{{ trans('general.last_audit') }}
|
||||
</label>
|
||||
|
||||
<label class="form-control">
|
||||
{{ Form::checkbox('next_audit_date', '1', $template->checkmarkValue('next_audit_date')) }}
|
||||
<input type="checkbox" name="next_audit_date" value="1" @checked($template->checkmarkValue('next_audit_date')) />
|
||||
{{ trans('general.next_audit_date') }}
|
||||
</label>
|
||||
|
||||
<label class="form-control">
|
||||
{{ Form::checkbox('notes', '1', $template->checkmarkValue('notes')) }}
|
||||
<input type="checkbox" name="notes" value="1" @checked($template->checkmarkValue('notes')) />
|
||||
{{ trans('general.notes') }}
|
||||
</label>
|
||||
|
||||
<label class="form-control" style="margin-left: 25px;">
|
||||
{{ Form::checkbox('url', '1', $template->checkmarkValue('url')) }}
|
||||
<input type="checkbox" name="url" value="1" @checked($template->checkmarkValue('url')) />
|
||||
{{ trans('general.url') }}
|
||||
</label>
|
||||
|
||||
@@ -248,64 +248,64 @@
|
||||
<h2>{{ trans('general.checked_out_to_fields') }}: </h2>
|
||||
|
||||
<label class="form-control">
|
||||
{{ Form::checkbox('assigned_to', '1', $template->checkmarkValue('assigned_to')) }}
|
||||
<input type="checkbox" name="assigned_to" value="1" @checked($template->checkmarkValue('assigned_to')) />
|
||||
{{ trans('admin/licenses/table.assigned_to') }}
|
||||
</label>
|
||||
|
||||
<label class="form-control">
|
||||
{{ Form::checkbox('username', '1', $template->checkmarkValue('username')) }}
|
||||
<input type="checkbox" name="username" value="1" @checked($template->checkmarkValue('username')) />
|
||||
{{ trans('admin/users/table.username') }}
|
||||
</label>
|
||||
|
||||
<label class="form-control">
|
||||
{{ Form::checkbox('employee_num', '1', $template->checkmarkValue('employee_num')) }}
|
||||
<input type="checkbox" name="employee_num" value="1" @checked($template->checkmarkValue('employee_num')) />
|
||||
{{ trans('general.employee_number') }}
|
||||
</label>
|
||||
|
||||
<label class="form-control">
|
||||
{{ Form::checkbox('manager', '1', $template->checkmarkValue('manager')) }}
|
||||
<input type="checkbox" name="manager" value="1" @checked($template->checkmarkValue('manager')) />
|
||||
{{ trans('admin/users/table.manager') }}
|
||||
</label>
|
||||
|
||||
<label class="form-control">
|
||||
{{ Form::checkbox('department', '1', $template->checkmarkValue('department')) }}
|
||||
<input type="checkbox" name="department" value="1" @checked($template->checkmarkValue('department')) />
|
||||
{{ trans('general.department') }}
|
||||
</label>
|
||||
|
||||
<label class="form-control">
|
||||
{{ Form::checkbox('title', '1', $template->checkmarkValue('title')) }}
|
||||
<input type="checkbox" name="title" value="1" @checked($template->checkmarkValue('title')) />
|
||||
{{ trans('admin/users/table.title') }}
|
||||
</label>
|
||||
|
||||
<!-- new -->
|
||||
|
||||
<label class="form-control">
|
||||
{{ Form::checkbox('phone', '1', $template->checkmarkValue('phone')) }}
|
||||
<input type="checkbox" name="phone" value="1" @checked($template->checkmarkValue('phone')) />
|
||||
{{ trans('admin/users/table.phone') }}
|
||||
</label>
|
||||
|
||||
<label class="form-control">
|
||||
{{ Form::checkbox('user_address', '1', $template->checkmarkValue('user_address')) }}
|
||||
<input type="checkbox" name="user_address" value="1" @checked($template->checkmarkValue('user_address')) />
|
||||
{{ trans('general.address') }}
|
||||
</label>
|
||||
|
||||
<label class="form-control">
|
||||
{{Form::checkbox('user_city', '1', $template->checkmarkValue('user_city'))}}
|
||||
<input type="checkbox" name="user_city" value="1" @checked($template->checkmarkValue('user_city')) />
|
||||
{{ trans('general.city') }}
|
||||
</label>
|
||||
|
||||
<label class="form-control">
|
||||
{{Form::checkbox('user_state', '1', $template->checkmarkValue('user_state'))}}
|
||||
<input type="checkbox" name="user_state" value="1" @checked($template->checkmarkValue('user_state')) />
|
||||
{{ trans('general.state') }}
|
||||
</label>
|
||||
|
||||
<label class="form-control">
|
||||
{{Form::checkbox('user_country', '1', $template->checkmarkValue('user_country'))}}
|
||||
<input type="checkbox" name="user_country" value="1" @checked($template->checkmarkValue('user_country')) />
|
||||
{{ trans('general.country') }}
|
||||
</label>
|
||||
|
||||
<label class="form-control">
|
||||
{{Form::checkbox('user_zip', '1', $template->checkmarkValue('user_zip'))}}
|
||||
<input type="checkbox" name="user_zip" value="1" @checked($template->checkmarkValue('user_zip')) />
|
||||
{{ trans('general.zip') }}
|
||||
</label>
|
||||
|
||||
@@ -318,7 +318,7 @@
|
||||
@foreach ($customfields as $customfield)
|
||||
|
||||
<label class="form-control">
|
||||
{{ Form::checkbox($customfield->db_column_name(), '1', $template->checkmarkValue($customfield->db_column_name())) }}
|
||||
<input type="checkbox" name="{{ $customfield->db_column_name() }}" value="1" @checked($template->checkmarkValue($customfield->db_column_name())) />
|
||||
{{ $customfield->name }}
|
||||
</label>
|
||||
|
||||
@@ -549,13 +549,13 @@
|
||||
|
||||
<div class="col-md-9 col-md-offset-3">
|
||||
<label class="form-control">
|
||||
{{ Form::checkbox('exclude_archived', '1', $template->checkmarkValue('exclude_archived', '0')) }}
|
||||
<input type="checkbox" name="exclude_archived" value="1" @checked($template->checkmarkValue('exclude_archived', '0')) />
|
||||
{{ trans('general.exclude_archived') }}
|
||||
</label>
|
||||
</div>
|
||||
<div class="col-md-9 col-md-offset-3">
|
||||
<label class="form-control">
|
||||
{{ Form::checkbox('use_bom', '1', $template->checkmarkValue('use_bom', '0')) }}
|
||||
<input type="checkbox" name="use_bom" value="1" @checked($template->checkmarkValue('use_bom', '0')) />
|
||||
{{ trans('general.bom_remark') }}
|
||||
</label>
|
||||
</div>
|
||||
|
||||
@@ -68,7 +68,7 @@
|
||||
@foreach ($assetsForReport as $item)
|
||||
@if ($item['assetItem'])
|
||||
<tr @if($item['acceptance']->trashed()) style="text-decoration: line-through" @endif>
|
||||
<td>{{ $item['acceptance']->created_at }}</td>
|
||||
<td>{{ Helper::getFormattedDateObject($item['acceptance']->created_at, 'datetime', false) }}</td>
|
||||
<td>{{ ($item['assetItem']->company) ? $item['assetItem']->company->name : '' }}</td>
|
||||
<td>{!! $item['assetItem']->model->category->present()->nameUrl() !!}</td>
|
||||
<td>{!! $item['assetItem']->present()->modelUrl() !!}</td>
|
||||
@@ -79,13 +79,18 @@
|
||||
<nobr>
|
||||
@if(!$item['acceptance']->trashed())
|
||||
<form method="post" class="white-space: nowrap;" action="{{ route('reports/unaccepted_assets_sent_reminder') }}">
|
||||
@if ($item['acceptance']->assignedTo)
|
||||
@if (($item['acceptance']->assignedTo) && ($item['acceptance']->assignedTo->email))
|
||||
@csrf
|
||||
<input type="hidden" name="acceptance_id" value="{{ $item['acceptance']->id }}">
|
||||
<button class="btn btn-sm btn-warning" data-tooltip="true" data-title="{{ trans('admin/reports/general.send_reminder') }}">
|
||||
<i class="fa fa-repeat" aria-hidden="true"></i>
|
||||
</button>
|
||||
|
||||
@else
|
||||
<span data-tooltip="true" data-title="{{ trans('admin/reports/general.cannot_send_reminder') }}">
|
||||
<a class="btn btn-sm btn-warning disabled" href="#">
|
||||
<i class="fa fa-repeat" aria-hidden="true"></i>
|
||||
</a>
|
||||
</span>
|
||||
@endif
|
||||
<a href="{{ route('reports/unaccepted_assets_delete', ['acceptanceId' => $item['acceptance']->id]) }}" class="btn btn-sm btn-danger delete-asset" data-tooltip="true" data-toggle="modal" data-content="{{ trans('general.delete_confirm', ['item' =>trans('admin/reports/general.acceptance_request')]) }}" data-title="{{ trans('general.delete') }}" onClick="return false;"><i class="fa fa-trash"></i></a>
|
||||
</form>
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
<div class="form-group {{ $errors->has('alerts_enabled') ? 'error' : '' }}">
|
||||
<div class="col-md-9 col-md-offset-3">
|
||||
<label class="form-control">
|
||||
{{ Form::checkbox('alerts_enabled', '1', old('alerts_enabled', $setting->alerts_enabled)) }}
|
||||
<input type="checkbox" name="alerts_enabled" value="1" @checked(old('alerts_enabled', $setting->alerts_enabled))>
|
||||
{{ trans('admin/settings/general.alerts_enabled') }}
|
||||
</label>
|
||||
</div>
|
||||
@@ -55,7 +55,7 @@
|
||||
<div class="form-group {{ $errors->has('show_alerts_in_menu') ? 'error' : '' }}">
|
||||
<div class="col-md-9 col-md-offset-3">
|
||||
<label class="form-control">
|
||||
{{ Form::checkbox('show_alerts_in_menu', '1', old('show_alerts_in_menu', $setting->show_alerts_in_menu)) }}
|
||||
<input type="checkbox" name="show_alerts_in_menu" value="1" @checked(old('show_alerts_in_menu', $setting->show_alerts_in_menu))>
|
||||
{{ trans('admin/settings/general.show_alerts_in_menu') }}
|
||||
</label>
|
||||
</div>
|
||||
|
||||
@@ -47,7 +47,7 @@
|
||||
</div>
|
||||
<div class="col-md-7">
|
||||
<label class="form-control">
|
||||
{{ Form::checkbox('auto_increment_assets', '1', old('auto_increment_assets', $setting->auto_increment_assets),array('aria-label'=>'auto_increment_assets')) }}
|
||||
<input type="checkbox" name="auto_increment_assets" value="1" @checked(old('auto_increment_assets', $setting->auto_increment_assets)) aria-label="auto_increment_assets">
|
||||
{{ trans('admin/settings/general.enabled') }}
|
||||
</label>
|
||||
</div>
|
||||
|
||||
@@ -68,7 +68,9 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@php
|
||||
$optionTypes = trans('admin/settings/general.logo_option_types');
|
||||
@endphp
|
||||
|
||||
<!-- Branding -->
|
||||
<div class="form-group {{ $errors->has('brand') ? 'error' : '' }}">
|
||||
@@ -76,8 +78,13 @@
|
||||
<label for="brand">{{ trans('admin/settings/general.web_brand') }}</label>
|
||||
</div>
|
||||
<div class="col-md-9">
|
||||
{!! Form::select('brand', array('1'=>'Text','2'=>'Logo','3'=>'Logo + Text'), old('brand', $setting->brand), array('class' => 'form-control select2', 'style'=>'width: 150px ;')) !!}
|
||||
{!! $errors->first('brand', '<span class="alert-msg" aria-hidden="true">:message</span>') !!}
|
||||
<select name="brand" id="brand" class="form-control select2 minimumResultsForSearch" style="width: 150px;">
|
||||
@foreach($optionTypes as $value => $label)
|
||||
<option value="{{ $value }}" {{ old('brand', $setting->brand) == $value ? 'selected' : '' }}>
|
||||
{{ $label }}
|
||||
</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -135,7 +142,7 @@
|
||||
|
||||
<div class="col-md-9 col-md-offset-3">
|
||||
<label class="form-control">
|
||||
{{ Form::checkbox('restore_default_avatar', '1', old('restore_default_avatar', $setting->restore_default_avatar)) }}
|
||||
<input type="checkbox" name="restore_default_avatar" value="1" @checked(old('restore_default_avatar', $setting->restore_default_avatar)) />
|
||||
<span>{!! trans('admin/settings/general.restore_default_avatar', ['default_avatar'=> Storage::disk('public')->url('default.png')]) !!}</span>
|
||||
</label>
|
||||
<p class="help-block">
|
||||
@@ -152,7 +159,7 @@
|
||||
</div>
|
||||
<div class="col-md-9">
|
||||
<label class="form-control">
|
||||
{{ Form::checkbox('load_remote', '1', old('load_remote', $setting->load_remote)) }}
|
||||
<input type="checkbox" name="load_remote" value="1" @checked(old('load_remote', $setting->load_remote)) />
|
||||
{{ trans('general.yes') }}
|
||||
{!! $errors->first('load_remote', '<span class="alert-msg" aria-hidden="true">:message</span>') !!}
|
||||
</label>
|
||||
@@ -172,7 +179,7 @@
|
||||
</div>
|
||||
<div class="col-md-9">
|
||||
<label class="form-control">
|
||||
{{ Form::checkbox('logo_print_assets', '1', old('logo_print_assets', $setting->logo_print_assets),array('aria-label'=>'logo_print_assets')) }}
|
||||
<input type="checkbox" name="logo_print_assets" value="1" @checked(old('logo_print_assets', $setting->logo_print_assets)) aria-label="logo_print_assets"/>
|
||||
{{ trans('admin/settings/general.logo_print_assets_help') }}
|
||||
</label>
|
||||
|
||||
@@ -187,7 +194,7 @@
|
||||
</div>
|
||||
<div class="col-md-9">
|
||||
<label class="form-control">
|
||||
{{ Form::checkbox('show_url_in_emails', '1', old('show_url_in_emails', $setting->show_url_in_emails),array('aria-label'=>'show_url_in_emails')) }}
|
||||
<input type="checkbox" name="show_url_in_emails" value="1" @checked(old('show_url_in_emails', $setting->show_url_in_emails)) aria-label="show_url_in_emails" />
|
||||
{{ trans('general.yes') }}
|
||||
</label>
|
||||
<p class="help-block">{{ trans('admin/settings/general.show_url_in_emails_help_text') }}</p>
|
||||
@@ -228,7 +235,7 @@
|
||||
</div>
|
||||
<div class="col-md-9">
|
||||
<label class="form-control">
|
||||
{{ Form::checkbox('allow_user_skin', '1', old('allow_user_skin', $setting->allow_user_skin)) }}
|
||||
<input type="checkbox" name="allow_user_skin" value="1" @checked(old('allow_user_skin', $setting->allow_user_skin))/>
|
||||
{{ trans('general.yes') }}
|
||||
</label>
|
||||
<p class="help-block">{{ trans('admin/settings/general.allow_user_skin_help_text') }}</p>
|
||||
@@ -272,10 +279,10 @@
|
||||
</div>
|
||||
<div class="col-md-9">
|
||||
@if (config('app.lock_passwords')===true)
|
||||
{!! Form::select('support_footer', array('on'=>'Enabled','off'=>'Disabled','admin'=>'Superadmin Only'), old('support_footer', $setting->support_footer), ['class' => 'form-control select2 disabled', 'style'=>'width: 150px ;', 'disabled' => 'disabled']) !!}
|
||||
{!! Form::select('support_footer', array('on'=>trans('admin/settings/general.enabled'),'off'=>trans('admin/settings/general.two_factor_disabled'),'admin'=>trans('admin/settings/general.super_admin_only')), old('support_footer', $setting->support_footer), ['class' => 'form-control select2 disabled', 'style'=>'width: 150px ;', 'disabled' => 'disabled']) !!}
|
||||
<p class="text-warning"><i class="fas fa-lock"></i> {{ trans('general.feature_disabled') }}</p>
|
||||
@else
|
||||
{!! Form::select('support_footer', array('on'=>'Enabled','off'=>'Disabled','admin'=>'Superadmin Only'), old('support_footer', $setting->support_footer), array('class' => 'form-control select2', 'style'=>'width: 150px ;')) !!}
|
||||
{!! Form::select('support_footer', array('on'=>trans('admin/settings/general.enabled'),'off'=>trans('admin/settings/general.two_factor_disabled'),'admin'=>trans('admin/settings/general.super_admin_only')), old('support_footer', $setting->support_footer), array('class' => 'form-control select2', 'style'=>'width: 150px ;')) !!}
|
||||
@endif
|
||||
|
||||
|
||||
@@ -291,10 +298,10 @@
|
||||
</div>
|
||||
<div class="col-md-9">
|
||||
@if (config('app.lock_passwords')===true)
|
||||
{!! Form::select('version_footer', array('on'=>'Enabled','off'=>'Disabled','admin'=>'Superadmin Only'), old('version_footer', $setting->version_footer), ['class' => 'form-control select2 disabled', 'style'=>'width: 150px ;', 'disabled' => 'disabled']) !!}
|
||||
{!! Form::select('version_footer', array('on'=>trans('admin/settings/general.enabled'),'off'=>trans('admin/settings/general.two_factor_disabled'),'admin'=>trans('admin/settings/general.super_admin_only')), old('version_footer', $setting->version_footer), ['class' => 'form-control select2 disabled', 'style'=>'width: 150px ;', 'disabled' => 'disabled']) !!}
|
||||
<p class="text-warning"><i class="fas fa-lock"></i> {{ trans('general.feature_disabled') }}</p>
|
||||
@else
|
||||
{!! Form::select('version_footer', array('on'=>'Enabled','off'=>'Disabled','admin'=>'Superadmin Only'), old('version_footer', $setting->version_footer), array('class' => 'form-control select2', 'style'=>'width: 150px ;')) !!}
|
||||
{!! Form::select('version_footer', array('on'=>trans('admin/settings/general.enabled'),'off'=>trans('admin/settings/general.two_factor_disabled'),'admin'=>trans('admin/settings/general.super_admin_only')), old('version_footer', $setting->version_footer), array('class' => 'form-control select2', 'style'=>'width: 150px ;')) !!}
|
||||
@endif
|
||||
|
||||
<p class="help-block">{{ trans('admin/settings/general.version_footer_help') }}</p>
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
</div>
|
||||
<div class="col-md-9">
|
||||
<label class="form-control">
|
||||
{{ Form::checkbox('full_multiple_companies_support', '1', old('full_multiple_companies_support', $setting->full_multiple_companies_support),array('aria-label'=>'full_multiple_companies_support')) }}
|
||||
<input type="checkbox" name="full_multiple_companies_support" value="1" @checked(old('full_multiple_companies_support', $setting->full_multiple_companies_support)) aria-label="full_multiple_companies_support" />
|
||||
{{ trans('admin/settings/general.full_multiple_companies_support_text') }}
|
||||
</label>
|
||||
{!! $errors->first('full_multiple_companies_support', '<span class="alert-msg" aria-hidden="true">:message</span>') !!}
|
||||
@@ -64,7 +64,7 @@
|
||||
</div>
|
||||
<div class="col-md-9">
|
||||
<label class="form-control">
|
||||
{{ Form::checkbox('require_accept_signature', '1', old('require_accept_signature', $setting->require_accept_signature)) }}
|
||||
<input type="checkbox" name="require_accept_signature" value="1" @checked(old('require_accept_signature', $setting->require_accept_signature)) />
|
||||
{{ trans('general.yes') }}
|
||||
</label>
|
||||
{!! $errors->first('require_accept_signature', '<span class="alert-msg" aria-hidden="true">:message</span>') !!}
|
||||
@@ -136,7 +136,7 @@
|
||||
</div>
|
||||
<div class="col-md-9">
|
||||
<label class="form-control">
|
||||
{{ Form::checkbox('show_images_in_email', '1', old('show_images_in_email', $setting->show_images_in_email)) }}
|
||||
<input type="checkbox" name="show_images_in_email" value="1" @checked(old('show_images_in_email', $setting->show_images_in_email)) />
|
||||
{{ trans('general.yes') }}
|
||||
{!! $errors->first('show_images_in_email', '<span class="alert-msg" aria-hidden="true">:message</span>') !!}
|
||||
</label>
|
||||
@@ -152,7 +152,7 @@
|
||||
</div>
|
||||
<div class="col-md-9">
|
||||
<label class="form-control">
|
||||
{{ Form::checkbox('unique_serial', '1', old('unique_serial', $setting->unique_serial),array('class' => 'minimal')) }}
|
||||
<input type="checkbox" name="unique_serial" value="1" @checked(old('unique_serial', $setting->unique_serial)) />
|
||||
{{ trans('general.yes') }}
|
||||
{!! $errors->first('unique_serial', '<span class="alert-msg" aria-hidden="true">:message</span>') !!}
|
||||
</label>
|
||||
@@ -245,11 +245,11 @@
|
||||
<div class="col-md-9">
|
||||
@if (config('app.lock_passwords'))
|
||||
|
||||
<textarea class="form-control disabled" name="login_note" placeholder="If you do not have a login or have found a device belonging to this company, please call technical support at 888-555-1212. Thank you." rows="2" aria-label="login_note" readonly>{{ old('login_note', $setting->login_note) }}</textarea>
|
||||
<textarea class="form-control disabled" name="login_note" placeholder="{{trans('admin/settings/general.login_note_placeholder')}}" rows="2" aria-label="login_note" readonly>{{ old('login_note', $setting->login_note) }}</textarea>
|
||||
{!! $errors->first('login_note', '<span class="alert-msg" aria-hidden="true">:message</span>') !!}
|
||||
<p class="text-warning"><i class="fas fa-lock"></i> {{ trans('general.feature_disabled') }}</p>
|
||||
@else
|
||||
<textarea class="form-control" name="login_note" aria-label="login_note" placeholder="If you do not have a login or have found a device belonging to this company, please call technical support at 888-555-1212. Thank you." rows="2">{{ old('login_note', $setting->login_note) }}</textarea>
|
||||
<textarea class="form-control" name="login_note" aria-label="login_note" placeholder="{{trans('admin/settings/general.login_note_placeholder')}}" rows="2">{{ old('login_note', $setting->login_note) }}</textarea>
|
||||
{!! $errors->first('login_note', '<span class="alert-msg" aria-hidden="true">:message</span>') !!}
|
||||
@endif
|
||||
<p class="help-block">{!! trans('admin/settings/general.login_note_help') !!}</p>
|
||||
@@ -259,7 +259,7 @@
|
||||
<!-- Mail test -->
|
||||
<div class="form-group">
|
||||
<div class="col-md-3">
|
||||
<label for="login_note">Test Mail</label>
|
||||
<label for="login_note">{{trans('admin/settings/general.test_mail')}}</label>
|
||||
</div>
|
||||
<div class="col-md-9" id="mailtestrow">
|
||||
<a class="btn btn-default btn-sm pull-left" id="mailtest" style="margin-right: 10px;">
|
||||
@@ -311,7 +311,7 @@
|
||||
<div class="col-md-9">
|
||||
|
||||
<label class="form-control">
|
||||
{{ Form::checkbox('show_archived_in_list', '1', old('show_archived_in_list', $setting->show_archived_in_list),array('aria-label'=>'show_archived_in_list')) }}
|
||||
<input type="checkbox" name="show_archived_in_list" value="1" @checked(old('show_archived_in_list', $setting->show_archived_in_list)) aria-label="show_archived_in_list" />
|
||||
{{ trans('admin/settings/general.show_archived_in_list_text') }}
|
||||
</label>
|
||||
{!! $errors->first('show_archived_in_list', '<span class="alert-msg" aria-hidden="true">:message</span>') !!}
|
||||
@@ -325,7 +325,7 @@
|
||||
</div>
|
||||
<div class="col-md-9">
|
||||
<label class="form-control">
|
||||
{{ Form::checkbox('show_assigned_assets', '1', old('show_assigned_assets', $setting->show_assigned_assets),array('class' => 'minimal')) }}
|
||||
<input type="checkbox" name="show_assigned_assets" value="1" @checked(old('show_assigned_assets', $setting->show_assigned_assets)) />
|
||||
{{ trans('general.yes') }}
|
||||
</label>
|
||||
<p class="help-block">{{ trans('admin/settings/general.show_assigned_assets_help') }}</p>
|
||||
@@ -340,15 +340,19 @@
|
||||
</div>
|
||||
<div class="col-md-9">
|
||||
<label class="form-control">
|
||||
{{ Form::checkbox('show_in_model_list[]', 'image', old('show_in_model_list', $snipeSettings->modellistCheckedValue('image')),array('class' => 'minimal', 'aria-label'=>'show_in_model_list' )) }} {{ trans('general.image') }}
|
||||
<input type="checkbox" name="show_in_model_list[]" value="image" @checked(old('show_in_model_list', $snipeSettings->modellistCheckedValue('image'))) aria-label="show_in_model_list"/>
|
||||
{{ trans('general.image') }}
|
||||
</label>
|
||||
<label class="form-control">
|
||||
{{ Form::checkbox('show_in_model_list[]', 'category', old('show_in_model_list', $snipeSettings->modellistCheckedValue('category')),array('class' => 'minimal', 'aria-label'=>'show_in_model_list' )) }} {{ trans('general.category') }}
|
||||
<input type="checkbox" name="show_in_model_list[]" value="category" @checked(old('show_in_model_list', $snipeSettings->modellistCheckedValue('category'))) aria-label="show_in_model_list"/>
|
||||
{{ trans('general.category') }}
|
||||
</label>
|
||||
<label class="form-control">
|
||||
{{ Form::checkbox('show_in_model_list[]', 'manufacturer', old('show_in_model_list', $snipeSettings->modellistCheckedValue('manufacturer')),array('class' => 'minimal', 'aria-label'=>'show_in_model_list' )) }} {{ trans('general.manufacturer') }} </label>
|
||||
<input type="checkbox" name="show_in_model_list[]" value="manufacturer" @checked(old('show_in_model_list', $snipeSettings->modellistCheckedValue('manufacturer'))) aria-label="show_in_model_list"/>
|
||||
{{ trans('general.manufacturer') }} </label>
|
||||
<label class="form-control">
|
||||
{{ Form::checkbox('show_in_model_list[]', 'model_number', old('show_in_model_list', $snipeSettings->modellistCheckedValue('model_number')),array('class' => 'minimal', 'aria-label'=>'show_in_model_list' )) }} {{ trans('general.model_no') }}
|
||||
<input type="checkbox" name="show_in_model_list[]" value="model_number" @checked(old('show_in_model_list', $snipeSettings->modellistCheckedValue('model_number'))) aria-label="show_in_model_list"/>
|
||||
{{ trans('general.model_no') }}
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
@@ -370,13 +374,13 @@
|
||||
<!-- Depreciation method -->
|
||||
<div class="form-group {{ $errors->has('depreciation_method') ? 'error' : '' }}">
|
||||
<div class="col-md-3">
|
||||
<label for="depreciation_method">{{ trans('Depreciation method') }}</label>
|
||||
<label for="depreciation_method">{{ trans('admin/depreciations/general.depreciation_method') }}</label>
|
||||
</div>
|
||||
<div class="col-md-9">
|
||||
{{ Form::select('depreciation_method', array(
|
||||
'default' => 'Linear (default)',
|
||||
'half_1' => 'Half-year convention, always applied',
|
||||
'half_2' => 'Half-year convention, applied with condition',
|
||||
'default' => trans('admin/depreciations/general.linear_depreciation'),
|
||||
'half_1' => trans('admin/depreciations/general.half_1'),
|
||||
'half_2' => trans('admin/depreciations/general.half_2'),
|
||||
), old('username_format', $setting->depreciation_method), ['class' =>'select2', 'style' => 'width: 80%']) }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -54,7 +54,7 @@
|
||||
<div class="col-md-8 col-md-offset-3">
|
||||
<label class="form-control{{ (config('app.lock_passwords')===true) ? ' form-control--disabled': '' }}">
|
||||
<span class="sr-only">{{ trans('admin/settings/general.pwd_secure_uncommon') }}</span>
|
||||
{{ Form::checkbox('google_login', '1', old('google_login', $setting->google_login),array('aria-label'=>'google_login', (config('app.lock_passwords')===true) ? 'disabled': '')) }}
|
||||
<input type="checkbox" name="google_login" value="1" @checked(old('google_login', $setting->google_login)) @disabled(config('app.lock_passwords')) aria-label="google_login">
|
||||
{{ trans('admin/settings/general.enable_google_login') }}
|
||||
</label>
|
||||
<p class="help-block">{{ trans('admin/settings/general.enable_google_login_help') }}</p>
|
||||
|
||||
@@ -144,7 +144,7 @@
|
||||
<div class="form-group">
|
||||
<div class="col-md-9 col-md-offset-3">
|
||||
<label class="form-control">
|
||||
{{ Form::checkbox('alt_barcode_enabled', '1', old('alt_barcode_enabled', $setting->alt_barcode_enabled),array( 'aria-label'=>'alt_barcode_enabled')) }}
|
||||
<input type="checkbox" name="alt_barcode_enabled" value="1" @checked(old('alt_barcode_enabled', $setting->alt_barcode_enabled)) aria-label="alt_barcode_enabled"/>
|
||||
{{ trans('admin/settings/general.display_alt_barcode') }}
|
||||
</label>
|
||||
</div>
|
||||
@@ -189,7 +189,7 @@
|
||||
<div class="form-group">
|
||||
<div class="col-md-9 col-md-offset-3">
|
||||
<label class="form-control">
|
||||
{{ Form::checkbox('qr_code', '1', old('qr_code', $setting->qr_code),array('aria-label'=>'qr_code')) }}
|
||||
<input type="checkbox" name="qr_code" value="1" @checked(old('qr_code', $setting->qr_code)) aria-label="qr_code" />
|
||||
{{ trans('admin/settings/general.display_qr') }}
|
||||
</label>
|
||||
</div>
|
||||
@@ -480,23 +480,23 @@
|
||||
</div>
|
||||
<div class="col-md-9">
|
||||
<label class="form-control">
|
||||
{{ Form::checkbox('labels_display_name', '1', old('labels_display_name', $setting->labels_display_name),['class' => 'minimal', 'aria-label'=>'labels_display_name']) }}
|
||||
<input type="checkbox" name="labels_display_name" value="1" @checked(old('labels_display_name', $setting->labels_display_name)) aria-label="labels_display_name" />
|
||||
{{ trans('admin/hardware/form.name') }}
|
||||
</label>
|
||||
<label class="form-control">
|
||||
{{ Form::checkbox('labels_display_serial', '1', old('labels_display_serial', $setting->labels_display_serial),['class' => 'minimal', 'aria-label'=>'labels_display_serial']) }}
|
||||
<input type="checkbox" name="labels_display_serial" value="1" @checked(old('labels_display_serial', $setting->labels_display_serial)) aria-label="labels_display_serial" />
|
||||
{{ trans('admin/hardware/form.serial') }}
|
||||
</label>
|
||||
<label class="form-control">
|
||||
{{ Form::checkbox('labels_display_tag', '1', old('labels_display_tag', $setting->labels_display_tag),['class' => 'minimal', 'aria-label'=>'labels_display_tag']) }}
|
||||
<input type="checkbox" name="labels_display_tag" value="1" @checked(old('labels_display_tag', $setting->labels_display_tag)) aria-label="labels_display_tag" />
|
||||
{{ trans('admin/hardware/form.tag') }}
|
||||
</label>
|
||||
<label class="form-control">
|
||||
{{ Form::checkbox('labels_display_model', '1', old('labels_display_model', $setting->labels_display_model),['class' => 'minimal', 'aria-label'=>'labels_display_model']) }}
|
||||
<input type="checkbox" name="labels_display_model" value="1" @checked(old('labels_display_model', $setting->labels_display_model)) aria-label="labels_display_model" />
|
||||
{{ trans('admin/hardware/form.model') }}
|
||||
</label>
|
||||
<label class="form-control">
|
||||
{{ Form::checkbox('labels_display_company_name', '1', old('labels_display_company_name', $setting->labels_display_company_name),['class' => 'minimal', 'aria-label'=>'labels_display_company_name']) }}
|
||||
<input type="checkbox" name="labels_display_company_name" value="1" @checked(old('labels_display_company_name', $setting->labels_display_company_name)) aria-label="labels_display_company_name"/>
|
||||
{{ trans('admin/companies/table.name') }}
|
||||
</label>
|
||||
</div> <!--/.col-md-9-->
|
||||
|
||||
@@ -75,7 +75,7 @@
|
||||
<div class="col-md-8">
|
||||
|
||||
<label class="form-control">
|
||||
{{ Form::checkbox('ldap_enabled', '1', old('ldap_enabled', $setting->ldap_enabled)) }}
|
||||
<input type="checkbox" name="ldap_enabled" value="1" id="ldap_enabled" @checked(old('ldap_enabled', $setting->ldap_enabled)) />
|
||||
{{ trans('admin/settings/general.ldap_enabled') }}
|
||||
</label>
|
||||
|
||||
@@ -96,7 +96,7 @@
|
||||
</div>
|
||||
<div class="col-md-8">
|
||||
<label class="form-control">
|
||||
{{ Form::checkbox('is_ad', '1', old('is_ad', $setting->is_ad)) }}
|
||||
<input type="checkbox" name="is_ad" value="1" id="is_ad" @checked(old('is_ad', $setting->is_ad))/>
|
||||
{{ trans('admin/settings/general.is_ad') }}
|
||||
</label>
|
||||
@error('is_ad')
|
||||
@@ -122,7 +122,7 @@
|
||||
</div>
|
||||
<div class="col-md-8">
|
||||
<label class="form-control">
|
||||
{{ Form::checkbox('ldap_pw_sync', '1', old('ldap_pw_sync', $setting->ldap_pw_sync)) }}
|
||||
<input type="checkbox" name="ldap_pw_sync" value="1" id="ldap_pw_sync" @checked(old('ldap_pw_sync', $setting->ldap_pw_sync)) />
|
||||
{{ trans('general.yes') }}
|
||||
</label>
|
||||
|
||||
@@ -255,7 +255,7 @@
|
||||
</div>
|
||||
<div class="col-md-8">
|
||||
<label class="form-control">
|
||||
{{ Form::checkbox('ldap_tls', '1', old('ldap_tls', $setting->ldap_tls)) }}
|
||||
<input type="checkbox" name="ldap_tls" value="1" id="ldap_tls" @checked(old('ldap_tls', $setting->ldap_tls)) />
|
||||
{{ trans('admin/settings/general.ldap_tls_help') }}
|
||||
</label>
|
||||
@error('ldap_tls')
|
||||
@@ -281,7 +281,7 @@
|
||||
</div>
|
||||
<div class="col-md-8">
|
||||
<label class="form-control">
|
||||
{{ Form::checkbox('ldap_server_cert_ignore', '1', old('ldap_server_cert_ignore', $setting->ldap_server_cert_ignore)) }}
|
||||
<input type="checkbox" name="ldap_server_cert_ignore" value="1" id="ldap_server_cert_ignore" @checked(old('ldap_server_cert_ignore', $setting->ldap_server_cert_ignore)) />
|
||||
{{ trans('admin/settings/general.ldap_server_cert_ignore') }}
|
||||
</label>
|
||||
@error('ldap_server_cert_ignore')
|
||||
@@ -554,6 +554,32 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- LDAP invert active flag -->
|
||||
<div class="form-group">
|
||||
<div class="col-md-3">
|
||||
{{ Form::label('ldap_invert_active_flag', trans('admin/settings/general.ldap_invert_active_flag')) }}
|
||||
</div>
|
||||
<div class="col-md-8">
|
||||
<label class="form-control">
|
||||
<input type="checkbox" name="ldap_invert_active_flag" value="1" id="ldap_invert_active_flag" @checked(old('ldap_invert_active_flag', $setting->ldap_invert_active_flag)) />
|
||||
<p class="help-block">{!! trans('admin/settings/general.ldap_invert_active_flag_help') !!}</p>
|
||||
</label>
|
||||
@error('ldap_invert_active_flag')
|
||||
<span class="alert-msg">
|
||||
<x-icon type="x" />
|
||||
{{ $message }}
|
||||
</span>
|
||||
@enderror
|
||||
|
||||
@if (config('app.lock_passwords')===true)
|
||||
<p class="text-warning">
|
||||
<x-icon type="locked" />
|
||||
{{ trans('general.feature_disabled') }}
|
||||
</p>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- LDAP emp number -->
|
||||
<div class="form-group {{ $errors->has('ldap_emp_num') ? 'error' : '' }}">
|
||||
<div class="col-md-3">
|
||||
|
||||
@@ -52,7 +52,7 @@
|
||||
<div class="col-md-9">
|
||||
|
||||
<label class="form-control{{ config('app.lock_passwords') === true ? ' form-control--disabled': '' }}">
|
||||
{{ Form::checkbox('saml_enabled', '1', old('saml_enabled', $setting->saml_enabled), ['class' => config('app.lock_passwords') === true ? 'disabled ': '', config('app.lock_passwords') === true ? 'disabled ': '', ]) }}
|
||||
<input type="checkbox" name="saml_enabled" value="1" @checked(old('saml_enabled', $setting->saml_enabled)) @disabled(config('app.lock_passwords')) @class(['disabled' => config('app.lock_passwords')])/>
|
||||
{{ trans('admin/settings/general.saml_enabled') }}
|
||||
</label>
|
||||
|
||||
@@ -146,7 +146,7 @@
|
||||
</div>
|
||||
<div class="col-md-9">
|
||||
<label class="form-control{{ config('app.lock_passwords') === true ? ' form-control--disabled': '' }}">
|
||||
{{ Form::checkbox('saml_forcelogin', '1', old('saml_forcelogin', $setting->saml_forcelogin),['class' => $setting->demoMode, $setting->demoMode]) }}
|
||||
<input type="checkbox" name="saml_forcelogin" value="1" @checked(old('saml_forcelogin', $setting->saml_forcelogin)) @disabled(config('app.lock_passwords')) @class(['disabled' => config('app.lock_passwords')]) />
|
||||
{{ trans('admin/settings/general.saml_forcelogin') }}
|
||||
</label>
|
||||
<p class="help-block">{{ trans('admin/settings/general.saml_forcelogin_help') }}</p>
|
||||
@@ -162,7 +162,7 @@
|
||||
</div>
|
||||
<div class="col-md-9">
|
||||
<label class="form-control{{ config('app.lock_passwords') === true ? ' form-control--disabled': '' }}">
|
||||
{{ Form::checkbox('saml_slo', '1', old('saml_slo', $setting->saml_slo),['class' => 'minimal '. $setting->demoMode, $setting->demoMode]) }}
|
||||
<input type="checkbox" name="saml_slo" value="1" @checked(old('saml_slo', $setting->saml_slo)) @disabled(config('app.lock_passwords')) @class(['minimal', 'disabled' => config('app.lock_passwords')])/>
|
||||
{{ trans('admin/settings/general.saml_slo') }}
|
||||
</label>
|
||||
<p class="help-block">{{ trans('admin/settings/general.saml_slo_help') }}</p>
|
||||
|
||||
@@ -83,27 +83,27 @@
|
||||
<div class="col-md-9">
|
||||
<label class="form-control">
|
||||
<span class="sr-only">{{ trans('admin/settings/general.pwd_secure_uncommon') }}</span>
|
||||
{{ Form::checkbox('pwd_secure_uncommon', '1', old('pwd_secure_uncommon', $setting->pwd_secure_uncommon),array( 'aria-label'=>'pwd_secure_uncommon')) }}
|
||||
<input type="checkbox" name="pwd_secure_uncommon" value="1" @checked(old('pwd_secure_uncommon', $setting->pwd_secure_uncommon)) aria-label="pwd_secure_uncommon"/>
|
||||
{{ trans('admin/settings/general.pwd_secure_uncommon') }}
|
||||
</label>
|
||||
<label class="form-control">
|
||||
{{ Form::checkbox("pwd_secure_complexity['disallow_same_pwd_as_user_fields']", 'disallow_same_pwd_as_user_fields', old('disallow_same_pwd_as_user_fields', strpos($setting->pwd_secure_complexity, 'disallow_same_pwd_as_user_fields')!==false), array('aria-label'=>'pwd_secure_complexity')) }}
|
||||
<input type="checkbox" name="pwd_secure_complexity['disallow_same_pwd_as_user_fields']" value="disallow_same_pwd_as_user_fields" @checked(old('disallow_same_pwd_as_user_fields', strpos($setting->pwd_secure_complexity, 'disallow_same_pwd_as_user_fields')!==false)) aria-label="pwd_secure_complexity"/>
|
||||
{{ trans('admin/settings/general.pwd_secure_complexity_disallow_same_pwd_as_user_fields') }}
|
||||
</label>
|
||||
<label class="form-control">
|
||||
{{ Form::checkbox("pwd_secure_complexity['letters']", 'letters', old('pwd_secure_uncommon', strpos($setting->pwd_secure_complexity, 'letters')!==false), array('aria-label'=>'pwd_secure_complexity')) }}
|
||||
<input type="checkbox" name="pwd_secure_complexity['letters']" value="letters" @checked(old('pwd_secure_uncommon', strpos($setting->pwd_secure_complexity, 'letters')!==false)) aria-label="pwd_secure_complexity"/>
|
||||
{{ trans('admin/settings/general.pwd_secure_complexity_letters') }}
|
||||
</label>
|
||||
<label class="form-control">
|
||||
{{ Form::checkbox("pwd_secure_complexity['numbers']", 'numbers', old('pwd_secure_uncommon', strpos($setting->pwd_secure_complexity, 'numbers')!==false), array('aria-label'=>'pwd_secure_complexity')) }}
|
||||
<input type="checkbox" name="pwd_secure_complexity['numbers']" value="numbers" @checked(old('pwd_secure_uncommon', strpos($setting->pwd_secure_complexity, 'numbers')!==false)) aria-label="pwd_secure_complexity"/>
|
||||
{{ trans('admin/settings/general.pwd_secure_complexity_numbers') }}
|
||||
</label>
|
||||
<label class="form-control">
|
||||
{{ Form::checkbox("pwd_secure_complexity['symbols']", 'symbols', old('pwd_secure_uncommon', strpos($setting->pwd_secure_complexity, 'symbols')!==false), array('aria-label'=>'pwd_secure_complexity')) }}
|
||||
<input type="checkbox" name="pwd_secure_complexity['symbols']" value="symbols" @checked(old('pwd_secure_uncommon', strpos($setting->pwd_secure_complexity, 'symbols')!==false)) aria-label="pwd_secure_complexity"/>
|
||||
{{ trans('admin/settings/general.pwd_secure_complexity_symbols') }}
|
||||
</label>
|
||||
<label class="form-control">
|
||||
{{ Form::checkbox("pwd_secure_complexity['case_diff']", 'case_diff', old('pwd_secure_uncommon', strpos($setting->pwd_secure_complexity, 'case_diff')!==false), array('aria-label'=>'pwd_secure_complexity')) }}
|
||||
<input type="checkbox" name="pwd_secure_complexity['case_diff']" value="case_diff" @checked(old('pwd_secure_uncommon', strpos($setting->pwd_secure_complexity, 'case_diff')!==false)) aria-label="pwd_secure_complexity"/>
|
||||
{{ trans('admin/settings/general.pwd_secure_complexity_case_diff') }}
|
||||
</label>
|
||||
|
||||
@@ -129,7 +129,7 @@
|
||||
<p class="text-warning"><i class="fas fa-lock"></i> {{ trans('general.feature_disabled') }}</p>
|
||||
@else
|
||||
<label class="form-control">
|
||||
{{ Form::checkbox('login_remote_user_enabled', '1', old('login_remote_user_enabled', $setting->login_remote_user_enabled),array('aria-label'=>'login_remote_user')) }}
|
||||
<input type="checkbox" name="login_remote_user_enabled" value="1" @checked(old('login_remote_user_enabled', $setting->login_remote_user_enabled)) aria-label="login_remote_user"/>
|
||||
<label for="login_remote_user_enabled">{{ trans('admin/settings/general.login_remote_user_enabled_text') }}</label>
|
||||
</label>
|
||||
|
||||
@@ -158,7 +158,7 @@
|
||||
<!-- Disable other logins mechanism -->
|
||||
<label class="form-control">
|
||||
|
||||
{{ Form::checkbox('login_common_disabled', '1', old('login_common_disabled', $setting->login_common_disabled),array('aria-label'=>'login_common_disabled')) }}
|
||||
<input type="checkbox" name="login_common_disabled" value="1" @checked(old('login_common_disabled', $setting->login_common_disabled)) aria-label="login_common_disabled"/>
|
||||
{{ trans('admin/settings/general.login_common_disabled_text') }}
|
||||
</label>
|
||||
{!! $errors->first('login_common_disabled', '<span class="alert-msg" aria-hidden="true">:message</span>') !!}
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
<div class="form-group">
|
||||
<div class=" col-md-9 col-md-offset-3">
|
||||
<label class="form-control">
|
||||
{{ Form::checkbox('null_department_id', '1', false) }}
|
||||
<input type="checkbox" name="null_department_id" value="1" />
|
||||
{{ trans_choice('general.set_users_field_to_null', count($users), ['field' => trans('general.department'), 'user_count' => count($users)]) }}
|
||||
</label>
|
||||
</div>
|
||||
@@ -55,7 +55,7 @@
|
||||
<div class="form-group">
|
||||
<div class=" col-md-9 col-md-offset-3">
|
||||
<label class="form-control">
|
||||
{{ Form::checkbox('null_location_id', '1', false) }}
|
||||
<input type="checkbox" name="null_location_id" value="1" />
|
||||
{{ trans_choice('general.set_users_field_to_null', count($users), ['field' => trans('general.location'), 'user_count' => count($users)]) }}
|
||||
</label>
|
||||
</div>
|
||||
@@ -69,7 +69,7 @@
|
||||
<div class="form-group">
|
||||
<div class=" col-md-9 col-md-offset-3">
|
||||
<label class="form-control">
|
||||
{{ Form::checkbox('null_company_id', '1', false) }}
|
||||
<input type="checkbox" name="null_company_id" value="1" />
|
||||
{{ trans_choice('general.set_users_field_to_null', count($users), ['field' => trans('general.company'), 'user_count' => count($users)]) }}
|
||||
</label>
|
||||
</div>
|
||||
@@ -83,7 +83,7 @@
|
||||
<div class="form-group">
|
||||
<div class=" col-md-9 col-md-offset-3">
|
||||
<label class="form-control">
|
||||
{{ Form::checkbox('null_manager_id', '1', false) }}
|
||||
<input type="checkbox" name="null_manager_id" value="1" />
|
||||
{{ trans_choice('general.set_users_field_to_null', count($users), ['field' => trans('admin/users/table.manager'), 'user_count' => count($users)]) }}
|
||||
</label>
|
||||
</div>
|
||||
@@ -102,7 +102,7 @@
|
||||
<div class="form-group">
|
||||
<div class=" col-md-9 col-md-offset-3">
|
||||
<label class="form-control">
|
||||
{{ Form::checkbox('null_locale', '1', false) }}
|
||||
<input type="checkbox" name="null_locale" value="1" />
|
||||
{{ trans_choice('general.set_users_field_to_null', count($users), ['field' => trans('general.language'), 'user_count' => count($users)]) }}
|
||||
</label>
|
||||
</div>
|
||||
@@ -246,7 +246,7 @@
|
||||
</div>
|
||||
<div class="col-md-5">
|
||||
<label class="form-control">
|
||||
{{ Form::checkbox('null_start_date', '1', false) }}
|
||||
<input type="checkbox" name="null_start_date" value="1" />
|
||||
{{ trans_choice('general.set_to_null', count($users),['selection_count' => count($users)]) }}
|
||||
</label>
|
||||
</div>
|
||||
@@ -264,7 +264,7 @@
|
||||
</div>
|
||||
<div class="col-md-5">
|
||||
<label class="form-control">
|
||||
{{ Form::checkbox('null_end_date', '1', false) }}
|
||||
<input type="checkbox" name="null_end_date" value="1" />
|
||||
{{ trans_choice('general.set_to_null', count($users),['selection_count' => count($users)]) }}
|
||||
</label>
|
||||
</div>
|
||||
|
||||
@@ -213,7 +213,7 @@
|
||||
@elseif ($user->id === Auth::user()->id)
|
||||
<!-- disallow the user from editing their own login status -->
|
||||
<label class="form-control form-control--disabled">
|
||||
{{ Form::checkbox('activated', '1', old('activated', $user->activated), ['disabled' => true, 'checked'=> 'checked', 'aria-label'=>'update_real_loc']) }}
|
||||
<input type="checkbox" name="activated" value="1" checked disabled aria-label="activated">
|
||||
{{ trans('admin/users/general.activated_help_text') }}
|
||||
</label>
|
||||
<p class="text-warning">{{ trans('admin/users/general.activated_disabled_help_text') }}</p>
|
||||
@@ -259,7 +259,7 @@
|
||||
<div class="col-md-8 col-md-offset-3">
|
||||
<label class="form-control form-control--disabled">
|
||||
|
||||
{{ Form::checkbox('email_user', '1', old('email_user'), ['id' => "email_user_checkbox", 'aria-label'=>'email_user']) }}
|
||||
<input type="checkbox" name="email_user" value="1" id="email_user_checkbox" @checked(old('email_user')) aria-label="email_user">
|
||||
|
||||
{{ trans('admin/users/general.email_user_creds_on_create') }}
|
||||
</label>
|
||||
|
||||
@@ -126,7 +126,7 @@ Route::group(
|
||||
|
||||
// Redirect old legacy /asset_id/view urls to the resource route version
|
||||
Route::get('{assetId}/view', function ($assetId) {
|
||||
return redirect()->route('hardware.show', ['hardware' => $assetId]);
|
||||
return redirect()->route('hardware.show', $assetId);
|
||||
});
|
||||
|
||||
Route::get('{asset}/qr_code',
|
||||
|
||||
21
snipeit.sh
21
snipeit.sh
@@ -428,7 +428,7 @@ case $distro in
|
||||
progress
|
||||
|
||||
echo "* Installing Apache httpd, PHP, MariaDB and other requirements."
|
||||
PACKAGES="mariadb-server mariadb-client apache2 libapache2-mod-php8.2 php8.2 php8.2-mcrypt php8.2-curl php8.2-mysql php8.2-gd php8.2-ldap php8.2-zip php8.2-mbstring php8.2-xml php8.2-bcmath curl git unzip"
|
||||
PACKAGES="mariadb-server mariadb-client apache2 libapache2-mod-php8.2 php8.2 php8.2-curl php8.2-mysql php8.2-gd php8.2-ldap php8.2-zip php8.2-mbstring php8.2-xml php8.2-bcmath curl git unzip"
|
||||
install_packages
|
||||
|
||||
echo "* Configuring Apache."
|
||||
@@ -465,7 +465,7 @@ case $distro in
|
||||
progress
|
||||
|
||||
echo "* Installing Apache httpd, PHP, MariaDB and other requirements."
|
||||
PACKAGES="mariadb-server mariadb-client apache2 libapache2-mod-php8.2 php8.2 php8.2-mcrypt php8.2-curl php8.2-mysql php8.2-gd php8.2-ldap php8.2-zip php8.2-mbstring php8.2-xml php8.2-bcmath curl git unzip"
|
||||
PACKAGES="mariadb-server mariadb-client apache2 libapache2-mod-php8.2 php8.2 php8.2-curl php8.2-mysql php8.2-gd php8.2-ldap php8.2-zip php8.2-mbstring php8.2-xml php8.2-bcmath curl git unzip"
|
||||
install_packages
|
||||
|
||||
echo "* Configuring Apache."
|
||||
@@ -502,7 +502,7 @@ case $distro in
|
||||
progress
|
||||
|
||||
echo "* Installing Apache httpd, PHP, MariaDB and other requirements."
|
||||
PACKAGES="mariadb-server mariadb-client apache2 libapache2-mod-php8.2 php8.2 php8.2-mcrypt php8.2-curl php8.2-mysql php8.2-gd php8.2-ldap php8.2-zip php8.2-mbstring php8.2-xml php8.2-bcmath curl git unzip"
|
||||
PACKAGES="mariadb-server mariadb-client apache2 libapache2-mod-php8.2 php8.2 php8.2-curl php8.2-mysql php8.2-gd php8.2-ldap php8.2-zip php8.2-mbstring php8.2-xml php8.2-bcmath curl git unzip"
|
||||
install_packages
|
||||
|
||||
echo "* Configuring Apache."
|
||||
@@ -543,7 +543,7 @@ case $distro in
|
||||
progress
|
||||
|
||||
echo "* Installing Apache httpd, PHP, MariaDB and other requirements."
|
||||
PACKAGES="cron mariadb-server mariadb-client apache2 libapache2-mod-php php php-mcrypt php-curl php-mysql php-gd php-ldap php-zip php-mbstring php-xml php-bcmath curl git unzip"
|
||||
PACKAGES="cron mariadb-server mariadb-client apache2 libapache2-mod-php php php-curl php-mysql php-gd php-ldap php-zip php-mbstring php-xml php-bcmath curl git unzip"
|
||||
install_packages
|
||||
|
||||
echo "* Configuring Apache."
|
||||
@@ -584,7 +584,7 @@ case $distro in
|
||||
progress
|
||||
|
||||
echo "* Installing Apache httpd, PHP, MariaDB and other requirements."
|
||||
PACKAGES="cron mariadb-server mariadb-client apache2 libapache2-mod-php8.2 php8.2 php8.2-mcrypt php8.2-curl php8.2-mysql php8.2-gd php8.2-ldap php8.2-zip php8.2-mbstring php8.2-xml php8.2-bcmath curl git unzip"
|
||||
PACKAGES="cron mariadb-server mariadb-client apache2 libapache2-mod-php8.2 php8.2 php8.2-curl php8.2-mysql php8.2-gd php8.2-ldap php8.2-zip php8.2-mbstring php8.2-xml php8.2-bcmath curl git unzip"
|
||||
install_packages
|
||||
|
||||
echo "* Configuring Apache."
|
||||
@@ -628,7 +628,7 @@ case $distro in
|
||||
progress
|
||||
|
||||
echo "* Installing Apache httpd, PHP, MariaDB and other requirements."
|
||||
PACKAGES="cron mariadb-server mariadb-client apache2 libapache2-mod-php8.28.2 php8.2 php8.2-mcrypt php8.2-curl php8.2-mysql php8.2-gd php8.2-ldap php8.2-zip php8.2-mbstring php8.2-xml php8.2-bcmath curl git unzip"
|
||||
PACKAGES="cron mariadb-server mariadb-client apache2 libapache2-mod-php8.28.2 php8.2 php8.2-curl php8.2-mysql php8.2-gd php8.2-ldap php8.2-zip php8.2-mbstring php8.2-xml php8.2-bcmath curl git unzip"
|
||||
install_packages
|
||||
|
||||
echo "* Configuring Apache."
|
||||
@@ -688,12 +688,11 @@ EOL
|
||||
progress
|
||||
|
||||
echo "* Installing Apache httpd, PHP, MariaDB and other requirements."
|
||||
PACKAGES="mariadb-server mariadb-client apache2 libapache2-mod-php8.2 php8.2 php8.2-mcrypt php8.2-curl php8.2-mysql php8.2-gd php8.2-ldap php8.2-zip php8.2-mbstring php8.2-xml php8.2-bcmath curl git unzip"
|
||||
PACKAGES="mariadb-server mariadb-client apache2 libapache2-mod-php8.2 php8.2 php8.2-curl php8.2-mysql php8.2-gd php8.2-ldap php8.2-zip php8.2-mbstring php8.2-xml php8.2-bcmath curl git unzip"
|
||||
install_packages
|
||||
|
||||
echo "* Configuring Apache."
|
||||
create_virtualhost
|
||||
log "phpenmod mcrypt"
|
||||
log "phpenmod mbstring"
|
||||
log "a2enmod rewrite"
|
||||
log "a2ensite $APP_NAME.conf"
|
||||
@@ -728,7 +727,7 @@ EOL
|
||||
amazon-linux-extras install -y php8.2
|
||||
|
||||
echo "* Installing Apache httpd, PHP, MariaDB and other requirements."
|
||||
PACKAGES="httpd mariadb-server git unzip php php-mysqlnd php-bcmath php-embedded php-gd php-mbstring php-mcrypt php-ldap php-json php-simplexml php-process php-zip php-sodium"
|
||||
PACKAGES="httpd mariadb-server git unzip php php-mysqlnd php-bcmath php-embedded php-gd php-mbstring php-ldap php-json php-simplexml php-process php-zip php-sodium"
|
||||
install_packages
|
||||
|
||||
echo "* Configuring Apache."
|
||||
@@ -769,7 +768,7 @@ EOL
|
||||
log "yum-config-manager --enable remi-php82"
|
||||
|
||||
echo "* Installing Apache httpd, PHP, MariaDB and other requirements."
|
||||
PACKAGES="httpd mariadb-server git unzip php php-mysqlnd php-bcmath php-embedded php-gd php-mbstring php-mcrypt php-ldap php-json php-simplexml php-process php-zip"
|
||||
PACKAGES="httpd mariadb-server git unzip php php-mysqlnd php-bcmath php-embedded php-gd php-mbstring php-ldap php-json php-simplexml php-process php-zip"
|
||||
install_packages
|
||||
|
||||
echo "* Configuring Apache."
|
||||
@@ -812,7 +811,7 @@ EOL
|
||||
progress
|
||||
|
||||
echo "* Installing Apache httpd, PHP, MariaDB and other requirements."
|
||||
PACKAGES="httpd mariadb-server git unzip php php-mysqlnd php-bcmath php-embedded php-gd php-mbstring php-mcrypt php-ldap php-json php-simplexml php-process php-zip"
|
||||
PACKAGES="httpd mariadb-server git unzip php php-mysqlnd php-bcmath php-embedded php-gd php-mbstring php-ldap php-json php-simplexml php-process php-zip"
|
||||
install_packages
|
||||
|
||||
echo "* Configuring Apache."
|
||||
|
||||
36
tests/Feature/Assets/Ui/AssetLabelTest.php
Normal file
36
tests/Feature/Assets/Ui/AssetLabelTest.php
Normal file
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Feature\Assets\Ui;
|
||||
|
||||
use App\Models\Accessory;
|
||||
use App\Models\Actionlog;
|
||||
use App\Models\Asset;
|
||||
use App\Models\User;
|
||||
use Tests\TestCase;
|
||||
|
||||
class AssetLabelTest extends TestCase
|
||||
{
|
||||
public function testUserWithPermissionsCanAccessPage()
|
||||
{
|
||||
$assets = Asset::factory()->count(20)->create();
|
||||
$id_array = $assets->pluck('id')->toArray();
|
||||
|
||||
$this->actingAs(User::factory()->viewAssets()->create())->post('/hardware/bulkedit', [
|
||||
'ids' => $id_array,
|
||||
'bulk_actions' => 'labels',
|
||||
])->assertStatus(200);
|
||||
}
|
||||
|
||||
public function testRedirectOfNoAssetsSelected()
|
||||
{
|
||||
$id_array = [];
|
||||
$this->actingAs(User::factory()->viewAssets()->create())
|
||||
->from(route('hardware.index'))
|
||||
->post('/hardware/bulkedit', [
|
||||
'ids' => $id_array,
|
||||
'bulk_actions' => 'Labels',
|
||||
])->assertStatus(302)
|
||||
->assertRedirect(route('hardware.index'));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -43,9 +43,13 @@ class SendAcceptanceReminderTest extends TestCase
|
||||
CheckoutAcceptance::factory()->pending()->create([
|
||||
'assigned_to_id' => $userA->id,
|
||||
]);
|
||||
|
||||
$headers = ['ID', 'Name'];
|
||||
$rows = [
|
||||
[$userA->id, $userA->present()->fullName()],
|
||||
];
|
||||
$this->artisan('snipeit:acceptance-reminder')
|
||||
->expectsOutput($userA->present()->fullName().' has no email address.')
|
||||
->expectsOutput("The following users do not have an email address:")
|
||||
->expectsTable($headers, $rows)
|
||||
->assertExitCode(0);
|
||||
|
||||
Mail::assertNotSent(UnacceptedAssetReminderMail::class);
|
||||
|
||||
@@ -45,4 +45,24 @@ class ImportTest extends TestCase
|
||||
]);
|
||||
$this->assertEquals($evil_string, $results->json()['files'][0]['first_row'][0]);
|
||||
}
|
||||
|
||||
public function testStoreInternationalAssetMisparse(): void
|
||||
{
|
||||
$evil_maker = function ($arr) {
|
||||
$results = '';
|
||||
foreach ($arr as $thing) {
|
||||
$results .= chr($thing);
|
||||
}
|
||||
return $results;
|
||||
};
|
||||
|
||||
// 0xC0 makes it 'not unicode', and 0xFF makes it 'likely WINDOWS-1251', and 0x98 at the end makes it 'not-valid-Windows-1251'
|
||||
$evil_content = $evil_maker([0xC0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x01, 0x02, 0x03, 0x98]);
|
||||
|
||||
$this->actingAsForApi(User::factory()->superuser()->create());
|
||||
$results = $this->post(route('api.imports.store'), ['files' => [UploadedFile::fake()->createWithContent("myname.csv", $evil_content)]])
|
||||
->assertStatus(422)
|
||||
->assertStatusMessageIs('error')
|
||||
->assertMessagesAre(trans('admin/hardware/message.import.transliterate_failure', ["encoding" => "windows-1251"]));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ class UpdateLicenseTest extends TestCase
|
||||
public function testPageRenders()
|
||||
{
|
||||
$this->actingAs(User::factory()->superuser()->create())
|
||||
->get(route('licenses.update', License::factory()->create()->id))
|
||||
->get(route('licenses.edit', License::factory()->create()->id))
|
||||
->assertOk();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,7 +10,10 @@ class CategoryEditFormTest extends TestCase
|
||||
{
|
||||
public function testTheComponentCanRender()
|
||||
{
|
||||
Livewire::test(CategoryEditForm::class)->assertStatus(200);
|
||||
Livewire::test(CategoryEditForm::class, [
|
||||
'sendCheckInEmail' => true,
|
||||
'useDefaultEula' => true,
|
||||
])->assertStatus(200);
|
||||
}
|
||||
|
||||
public function testSendEmailCheckboxIsCheckedOnLoadWhenSendEmailIsExistingSetting()
|
||||
|
||||
@@ -21,7 +21,7 @@ class UpdateLocationsTest extends TestCase
|
||||
public function testPageRenders()
|
||||
{
|
||||
$this->actingAs(User::factory()->superuser()->create())
|
||||
->get(route('locations.update', Location::factory()->create()))
|
||||
->get(route('locations.edit', Location::factory()->create()))
|
||||
->assertOk();
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,108 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Feature\Notifications\Email;
|
||||
|
||||
use App\Mail\CheckoutAssetMail;
|
||||
use App\Models\CheckoutAcceptance;
|
||||
use App\Models\User;
|
||||
use Illuminate\Support\Facades\Mail;
|
||||
use PHPUnit\Framework\Attributes\DataProvider;
|
||||
use Tests\TestCase;
|
||||
|
||||
class AssetAcceptanceReminderTest extends TestCase
|
||||
{
|
||||
protected function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
Mail::fake();
|
||||
}
|
||||
|
||||
public function testMustHavePermissionToSendReminder()
|
||||
{
|
||||
$checkoutAcceptance = CheckoutAcceptance::factory()->pending()->create();
|
||||
$userWithoutPermission = User::factory()->create();
|
||||
|
||||
$this->actingAs($userWithoutPermission)
|
||||
->post($this->routeFor($checkoutAcceptance))
|
||||
->assertForbidden();
|
||||
|
||||
Mail::assertNotSent(CheckoutAssetMail::class);
|
||||
}
|
||||
|
||||
public function testReminderNotSentIfAcceptanceDoesNotExist()
|
||||
{
|
||||
$this->actingAs(User::factory()->canViewReports()->create())
|
||||
->post(route('reports/unaccepted_assets_sent_reminder', [
|
||||
'acceptance_id' => 999999,
|
||||
]));
|
||||
|
||||
Mail::assertNotSent(CheckoutAssetMail::class);
|
||||
}
|
||||
|
||||
public function testReminderNotSentIfAcceptanceAlreadyAccepted()
|
||||
{
|
||||
$checkoutAcceptanceAlreadyAccepted = CheckoutAcceptance::factory()->accepted()->create();
|
||||
|
||||
$this->actingAs(User::factory()->canViewReports()->create())
|
||||
->post($this->routeFor($checkoutAcceptanceAlreadyAccepted));
|
||||
|
||||
Mail::assertNotSent(CheckoutAssetMail::class);
|
||||
}
|
||||
|
||||
public static function CheckoutAcceptancesToUsersWithoutEmailAddresses()
|
||||
{
|
||||
yield 'User with null email address' => [
|
||||
function () {
|
||||
return CheckoutAcceptance::factory()
|
||||
->pending()
|
||||
->forAssignedTo(['email' => null])
|
||||
->create();
|
||||
}
|
||||
];
|
||||
|
||||
yield 'User with empty string email address' => [
|
||||
function () {
|
||||
return CheckoutAcceptance::factory()
|
||||
->pending()
|
||||
->forAssignedTo(['email' => ''])
|
||||
->create();
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
#[DataProvider('CheckoutAcceptancesToUsersWithoutEmailAddresses')]
|
||||
public function testUserWithoutEmailAddressHandledGracefully($callback)
|
||||
{
|
||||
$checkoutAcceptance = $callback();
|
||||
|
||||
$this->actingAs(User::factory()->canViewReports()->create())
|
||||
->post($this->routeFor($checkoutAcceptance))
|
||||
// check we didn't crash...
|
||||
->assertRedirect();
|
||||
|
||||
Mail::assertNotSent(CheckoutAssetMail::class);
|
||||
}
|
||||
|
||||
public function testReminderIsSentToUser()
|
||||
{
|
||||
$checkoutAcceptance = CheckoutAcceptance::factory()->pending()->create();
|
||||
|
||||
$this->actingAs(User::factory()->canViewReports()->create())
|
||||
->post($this->routeFor($checkoutAcceptance))
|
||||
->assertRedirect(route('reports/unaccepted_assets'));
|
||||
|
||||
Mail::assertSent(CheckoutAssetMail::class, 1);
|
||||
Mail::assertSent(CheckoutAssetMail::class, function (CheckoutAssetMail $mail) use ($checkoutAcceptance) {
|
||||
return $mail->hasTo($checkoutAcceptance->assignedTo->email)
|
||||
&& $mail->hasSubject(trans('mail.unaccepted_asset_reminder'));
|
||||
});
|
||||
}
|
||||
|
||||
private function routeFor(CheckoutAcceptance $checkoutAcceptance): string
|
||||
{
|
||||
return route('reports/unaccepted_assets_sent_reminder', [
|
||||
'acceptance_id' => $checkoutAcceptance->id,
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,7 @@ namespace Tests\Feature\Notifications\Email;
|
||||
|
||||
use App\Mail\ExpiringAssetsMail;
|
||||
use App\Mail\ExpiringLicenseMail;
|
||||
use App\Mail\SendUpcomingAuditMail;
|
||||
use App\Models\Asset;
|
||||
use App\Models\License;
|
||||
use App\Models\Setting;
|
||||
@@ -88,4 +89,38 @@ class ExpiringAlertsNotificationTest extends TestCase
|
||||
return $mail->licenses->contains($expiredLicense) || $mail->licenses->contains($notExpiringLicense);
|
||||
});
|
||||
}
|
||||
|
||||
public function testAuditWarningThresholdEmailNotification()
|
||||
{
|
||||
$this->markIncompleteIfSqlite();
|
||||
Mail::fake();
|
||||
$this->settings->enableAlertEmail('admin@example.com');
|
||||
$this->settings->setAuditWarningDays(15);
|
||||
|
||||
$alert_email = Setting::first()->alert_email;
|
||||
|
||||
$upcomingAuditableAsset = Asset::factory()->create([
|
||||
'next_audit_date' => now()->addDays(14)->format('Y-m-d'),
|
||||
'deleted_at' => null,
|
||||
]);
|
||||
|
||||
$overDueForAuditableAsset = Asset::factory()->create([
|
||||
'next_audit_date' => now()->subDays(1)->format('Y-m-d'),
|
||||
'deleted_at' => null,
|
||||
]);
|
||||
|
||||
$notAuditableAsset = Asset::factory()->create([
|
||||
'next_audit_date' => now()->addDays(30)->format('Y-m-d'),
|
||||
'deleted_at' => null,
|
||||
]);
|
||||
|
||||
$this->artisan('snipeit:upcoming-audits')->assertExitCode(0);
|
||||
|
||||
Mail::assertSent(SendUpcomingAuditMail::class, function($mail) use ($alert_email, $upcomingAuditableAsset, $overDueForAuditableAsset) {
|
||||
return $mail->hasTo($alert_email) && ($mail->assets->contains($upcomingAuditableAsset) && $mail->assets->contains($overDueForAuditableAsset));
|
||||
});
|
||||
Mail::assertNotSent(SendUpcomingAuditMail::class, function($mail) use ($alert_email, $notAuditableAsset) {
|
||||
return $mail->hasTo($alert_email) && $mail->assets->contains($notAuditableAsset);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -32,6 +32,12 @@ class Settings
|
||||
'alert_threshold' => $days,
|
||||
]);
|
||||
}
|
||||
public function setAuditWarningDays(int $days): Settings
|
||||
{
|
||||
return $this->update([
|
||||
'audit_warning_days' => $days,
|
||||
]);
|
||||
}
|
||||
public function disableAlertEmail(): Settings
|
||||
{
|
||||
return $this->update([
|
||||
|
||||
@@ -7,9 +7,7 @@ use App\Models\Asset;
|
||||
use App\Models\AssetModel;
|
||||
use App\Models\Category;
|
||||
use Carbon\Carbon;
|
||||
use App\Notifications\CheckoutAssetNotification;
|
||||
use Illuminate\Support\Facades\Mail;
|
||||
use Illuminate\Support\Facades\Notification;
|
||||
use Tests\TestCase;
|
||||
|
||||
class NotificationTest extends TestCase
|
||||
@@ -33,8 +31,8 @@ class NotificationTest extends TestCase
|
||||
|
||||
Mail::fake();
|
||||
$asset->checkOut($user, $admin->id);
|
||||
Mail::assertSent(CheckoutAssetMail::class, function ($mail) use ($user) {
|
||||
return $mail->hasTo($user->email);
|
||||
Mail::assertSent(CheckoutAssetMail::class, function (CheckoutAssetMail $mail) use ($user) {
|
||||
return $mail->hasTo($user->email) && $mail->hasSubject(trans('mail.Asset_Checkout_Notification'));
|
||||
});
|
||||
}
|
||||
public function testDefaultEulaIsSentWhenSetInCategory()
|
||||
|
||||
252
upgrade.php
252
upgrade.php
@@ -1,4 +1,9 @@
|
||||
<?php
|
||||
|
||||
$error_icon = "\e[91m✘\e[0m";
|
||||
$success_icon = "\e[92m√\e[0m";
|
||||
$info_icon = "\e[93mⓘ\e[0m";
|
||||
|
||||
(PHP_SAPI !== 'cli' || isset($_SERVER['HTTP_USER_AGENT'])) && die('Access denied.');
|
||||
|
||||
// We define this because we can't reliably use file_get_contents because some
|
||||
@@ -25,7 +30,7 @@ function url_get_contents ($Url) {
|
||||
$output = curl_exec($ch);
|
||||
curl_close($ch);
|
||||
if ($output === false) {
|
||||
print("Error retrieving PHP requirements!\n");
|
||||
print("\e[91mError retrieving PHP requirements!\e[39m\n");
|
||||
print("Error was: " . curl_error($ch) . "\n");
|
||||
print("Try enabling allow_url_fopen in php.ini, or fixing your curl/OpenSSL setup, or try rerunning with --skip-php-compatibility-checks");
|
||||
return '{}';
|
||||
@@ -38,6 +43,7 @@ $skip_php_checks = false;
|
||||
$branch = 'master';
|
||||
$branch_override = false;
|
||||
$no_interactive = false;
|
||||
$skip_backup = false;
|
||||
|
||||
// Check for branch or other overrides
|
||||
if ($argc > 1){
|
||||
@@ -46,6 +52,9 @@ if ($argc > 1){
|
||||
case '--skip-php-compatibility-checks':
|
||||
$skip_php_checks = true;
|
||||
break;
|
||||
case '--skip-backup':
|
||||
$skip_backup = true;
|
||||
break;
|
||||
case '--branch':
|
||||
$arg++;
|
||||
$branch = $argv[$arg];
|
||||
@@ -62,7 +71,7 @@ if ($argc > 1){
|
||||
}
|
||||
}
|
||||
|
||||
echo "--------------------------------------------------------\n";
|
||||
echo "\e[95m--------------------------------------------------------\n";
|
||||
echo "WELCOME TO THE SNIPE-IT UPGRADER! \n";
|
||||
echo "--------------------------------------------------------\n\n";
|
||||
echo "This script will attempt to: \n\n";
|
||||
@@ -71,8 +80,9 @@ echo "- check your PHP version and extension requirements \n";
|
||||
echo "- check directory permissions \n";
|
||||
echo "- do a git pull to bring you to the latest version \n";
|
||||
echo "- run composer install to get your vendors up to date \n";
|
||||
echo "- run a backup \n";
|
||||
echo "- run migrations to get your schema up to date \n";
|
||||
echo "- clear out old cache settings\n\n";
|
||||
echo "- clear out old cache settings\e[39m\n\n";
|
||||
|
||||
|
||||
// Fetching most current upgrade requirements from github. Read more here: https://github.com/snipe/snipe-it/pull/14127
|
||||
@@ -81,29 +91,29 @@ $upgrade_requirements_raw = url_get_contents($remote_requirements_file);
|
||||
$upgrade_requirements = json_decode($upgrade_requirements_raw, true);
|
||||
if (! $upgrade_requirements) {
|
||||
if(!$skip_php_checks){
|
||||
echo "\nERROR: Failed to retrieve remote requirements from $remote_requirements_file\n\n";
|
||||
echo "\n\e[91mERROR: Failed to retrieve remote requirements from $remote_requirements_file \e[39m\n\n";
|
||||
if ($branch_override){
|
||||
echo "NOTE: You passed a custom branch: $branch\n";
|
||||
echo " If the above URL doesn't work, that may be why. Please check you branch spelling/existence\n\n";
|
||||
echo "\e[93mNOTE: You passed a custom branch: $branch\n";
|
||||
echo "If the above URL doesn't work, that may be why. Please check the branch spelling/existence\e[39m\n\n";
|
||||
}
|
||||
|
||||
if (json_last_error()) {
|
||||
print "JSON DECODE ERROR DETECTED:\n";
|
||||
print "\e[91mJSON DECODE ERROR DETECTED:\n";
|
||||
print json_last_error_msg() . "\n\n";
|
||||
print "Raw curl output:\n";
|
||||
print $upgrade_requirements_raw . "\n\n";
|
||||
print $upgrade_requirements_raw . "\e[39m\n\n";
|
||||
}
|
||||
|
||||
echo "We suggest correcting this, but if you can't, please verify that your requirements conform to those at that url.\n\n";
|
||||
echo " -- DANGER -- DO AT YOUR OWN RISK --\n";
|
||||
echo " IF YOU ARE SURE, re-run this script with --skip-php-compatibility-checks to skip this check.\n";
|
||||
echo " -- DANGER -- THIS COULD BREAK YOUR INSTALLATION";
|
||||
die("Exiting.\n\n");
|
||||
echo "\e[93mWe suggest correcting this, but if you can't, please verify that your requirements conform to those at that url.\n\n";
|
||||
echo "\e[91m-- DANGER -- DO AT YOUR OWN RISK --\n";
|
||||
echo "IF YOU ARE SURE, re-run this script with --skip-php-compatibility-checks to skip this check.\n";
|
||||
echo "-- DANGER -- THIS COULD BREAK YOUR INSTALLATION\e[39m\n\n";
|
||||
die("Aborting upgrade.\n\n");
|
||||
}
|
||||
echo "NOTICE: Unable to fetch upgrade requirements, but continuing because you passed --skip-php-compatibility-checks...\n";
|
||||
echo "\e[93mNOTICE: Unable to fetch upgrade requirements, but continuing because you passed --skip-php-compatibility-checks...e[39m\n";
|
||||
}
|
||||
|
||||
echo "Launching using branch: $branch\n";
|
||||
echo "Launching using branch: $branch\e[39m\n";
|
||||
|
||||
if($upgrade_requirements){
|
||||
$php_min_works = $upgrade_requirements['php_min_version'];
|
||||
@@ -133,22 +143,22 @@ if ((strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') || (!function_exists('posix_get
|
||||
$username = $pwu_data['name'];
|
||||
|
||||
if (($username=='root') || ($username=='admin')) {
|
||||
die("\nERROR: This script should not be run as root/admin. Exiting.\n\n");
|
||||
die("\n".$error_icon."ERROR: This script should not be run as root/admin. Exiting.\n\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
echo "--------------------------------------------------------\n";
|
||||
echo "\e[95m--------------------------------------------------------\n";
|
||||
echo "STEP 1: Checking .env file: \n";
|
||||
echo "- Your .env is located at ".getcwd()."/.env \n";
|
||||
echo "--------------------------------------------------------\n\n";
|
||||
echo "--------------------------------------------------------\e[39m\\n\n";
|
||||
|
||||
|
||||
// Check the .env looks ok
|
||||
$env = file('.env');
|
||||
if (! $env){
|
||||
echo "\n!!!!!!!!!!!!!!!!!!!!!!!!!! .ENV FILE ERROR !!!!!!!!!!!!!!!!!!!!!!!!!!\n";
|
||||
echo "\n\e[91m!!!!!!!!!!!!!!!!!!!!!!!!!! .ENV FILE ERROR !!!!!!!!!!!!!!!!!!!!!!!!!!\n";
|
||||
echo "Your .env file doesn't seem to exist in this directory or isn't readable! Please look into that.\n";
|
||||
exit(1);
|
||||
}
|
||||
@@ -198,32 +208,32 @@ foreach ($env as $line_num => $line) {
|
||||
|
||||
if ($env_key == 'APP_KEY') {
|
||||
if (($env_value=='') || (strlen($env_value) < 20)) {
|
||||
$env_bad .= "✘ APP_KEY ERROR in your .env on line #'.{$show_line_num}.': Your APP_KEY should not be blank. Run `php artisan key:generate` to generate one.\n";
|
||||
$env_bad .= $error_icon." APP_KEY ERROR in your .env on line #'.{$show_line_num}.': Your APP_KEY should not be blank. Run `php artisan key:generate` to generate one.\n";
|
||||
} else {
|
||||
$env_good .= "√ Your APP_KEY is not blank. \n";
|
||||
$env_good .= $success_icon." Your APP_KEY is not blank. \n";
|
||||
}
|
||||
}
|
||||
|
||||
if ($env_key == 'APP_URL') {
|
||||
|
||||
if (($env_value!="null") && ($env_value!="")) {
|
||||
$env_good .= '√ Your APP_URL is not null or blank. It is set to '.$env_value."\n";
|
||||
$env_good .= $success_icon.' Your APP_URL is not null or blank. It is set to '.$env_value."\n";
|
||||
|
||||
if (!str_begins(trim($env_value), 'http://') && (!str_begins($env_value, 'https://'))) {
|
||||
$env_bad .= '✘ APP_URL ERROR in your .env on line #'.$show_line_num.': Your APP_URL should start with https:// or http://!! It is currently set to: '.$env_value;
|
||||
$env_bad .= $error_icon.' APP_URL ERROR in your .env on line #'.$show_line_num.': Your APP_URL should start with https:// or http://!! It is currently set to: '.$env_value;
|
||||
} else {
|
||||
$env_good .= '√ Your APP_URL is set to '.$env_value.' and starts with the protocol (https:// or http://)'."\n";
|
||||
$env_good .= $success_icon.' Your APP_URL is set to '.$env_value.' and starts with the protocol (https:// or http://)'."\n";
|
||||
}
|
||||
|
||||
if (str_ends(trim($env_value), "/")) {
|
||||
$env_bad .= '✘ APP_URL ERROR in your .env on line #'.$show_line_num.': Your APP_URL should NOT end with a trailing slash. It is currently set to: '.$env_value;
|
||||
$env_bad .= $error_icon.' APP_URL ERROR in your .env on line #'.$show_line_num.': Your APP_URL should NOT end with a trailing slash. It is currently set to: '.$env_value;
|
||||
} else {
|
||||
$env_good .= '√ Your APP_URL ('.$env_value.') does not have a trailing slash.'."\n";
|
||||
$env_good .= $success_icon.' Your APP_URL ('.$env_value.') does not have a trailing slash.'."\n";
|
||||
}
|
||||
|
||||
|
||||
} else {
|
||||
$env_bad .= "✘ APP_URL ERROR in your .env on line #".$show_line_num.": Your APP_URL CANNOT be set to null or left blank.\n";
|
||||
$env_bad .= $error_icon." APP_URL ERROR in your .env on line #".$show_line_num.": Your APP_URL CANNOT be set to null or left blank.\n";
|
||||
}
|
||||
|
||||
}
|
||||
@@ -237,34 +247,34 @@ echo $env_good;
|
||||
|
||||
if ($env_bad !='') {
|
||||
|
||||
echo "!!!!!!!!!!!!!!!!!!!!!!!!!! .ENV FILE ERROR !!!!!!!!!!!!!!!!!!!!!!!!!!\n";
|
||||
echo "Your .env file is misconfigured. Upgrade cannot continue.\n";
|
||||
echo "\e[91m!!!!!!!!!!!!!!!!!!!!!!!!!! .ENV FILE ERROR !!!!!!!!!!!!!!!!!!!!!!!!!!\n";
|
||||
echo "\e[91mYour .env file is misconfigured. Upgrade cannot continue.\n";
|
||||
echo "--------------------------------------------------------\n\n";
|
||||
echo $env_bad;
|
||||
echo "\n\n--------------------------------------------------------\n";
|
||||
echo "!!!!!!!!!!!!!!!!!!!!!!!!! ABORTING THE UPGRADER !!!!!!!!!!!!!!!!!!!!!!\n";
|
||||
echo "Please correct the issues above in ".getcwd()."/.env and try again.\n";
|
||||
echo "--------------------------------------------------------\n";
|
||||
echo "\e[91m!!!!!!!!!!!!!!!!!!!!!!!!! ABORTING THE UPGRADER !!!!!!!!!!!!!!!!!!!!!!\n";
|
||||
echo "\e[91mPlease correct the issues above in ".getcwd()."/.env and try again.\n";
|
||||
echo "\e[91m--------------------------------------------------------\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
if(!$skip_php_checks){
|
||||
echo "\n--------------------------------------------------------\n";
|
||||
echo "STEP 2: Checking PHP requirements: (Required PHP >=". $php_min_works. " - <".$php_max_wontwork.") \n";
|
||||
echo "--------------------------------------------------------\n\n";
|
||||
echo "\n\e[95m--------------------------------------------------------\n";
|
||||
echo "STEP 2: Checking PHP requirements: (Required PHP >=". $php_min_works. " - <".$php_max_wontwork.")\n";
|
||||
echo "--------------------------------------------------------\e[39m\n\n";
|
||||
|
||||
if ((version_compare(phpversion(), $php_min_works, '>=')) && (version_compare(phpversion(), $php_max_wontwork, '<'))) {
|
||||
|
||||
echo "√ Current PHP version: (" . phpversion() . ") is at least " . $php_min_works . " and less than ".$php_max_wontwork."! Continuing... \n";
|
||||
echo $success_icon." Current PHP version: (" . phpversion() . ") is at least " . $php_min_works . " and less than ".$php_max_wontwork."! Continuing... \n";
|
||||
echo sprintf("FYI: The php.ini used by this PHP is: %s\n\n", get_cfg_var('cfg_file_path'));
|
||||
|
||||
} else {
|
||||
echo "!!!!!!!!!!!!!!!!!!!!!!!!! PHP VERSION ERROR !!!!!!!!!!!!!!!!!!!!!!!!!\n";
|
||||
echo "\e[91m!!!!!!!!!!!!!!!!!!!!!!!!! PHP VERSION ERROR !!!!!!!!!!!!!!!!!!!!!!!!!\n";
|
||||
echo "This version of PHP (".phpversion().") is NOT compatible with Snipe-IT.\n";
|
||||
echo "Snipe-IT requires PHP versions between ".$php_min_works." and ".$php_max_wontwork.".\n";
|
||||
echo "Please install a compatible version of PHP and re-run this script again. \n";
|
||||
echo "!!!!!!!!!!!!!!!!!!!!!!!!! ABORTING THE UPGRADER !!!!!!!!!!!!!!!!!!!!!!\n";
|
||||
echo "\e[91m!!!!!!!!!!!!!!!!!!!!!!!!! ABORTING THE UPGRADER !!!!!!!!!!!!!!!!!!!!!!\n";
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
@@ -318,7 +328,7 @@ foreach ($required_exts_array as $required_ext) {
|
||||
foreach ($require_either as $require_either_value) {
|
||||
|
||||
if (in_array($require_either_value, $loaded_exts_array)) {
|
||||
$ext_installed .= '√ '.$require_either_value." is installed!\n";
|
||||
$ext_installed .= $success_icon.' '.$require_either_value." is installed!\n";
|
||||
$has_one_required_ext = true;
|
||||
break;
|
||||
}
|
||||
@@ -326,20 +336,20 @@ foreach ($required_exts_array as $required_ext) {
|
||||
|
||||
// If no match, add it to the string for errors
|
||||
if (!$has_one_required_ext) {
|
||||
$ext_missing .= '✘ MISSING PHP EXTENSION: '.str_replace("|", " OR ", $required_ext)."\n";
|
||||
$ext_missing .= $error_icon.' MISSING PHP EXTENSION: '.str_replace("|", " OR ", $required_ext)."\n";
|
||||
break;
|
||||
}
|
||||
|
||||
// If this isn't an either/or option, just add it to the string of errors conventionally
|
||||
} elseif (!in_array($required_ext, $recommended_exts_array)){
|
||||
$ext_missing .= '✘ MISSING PHP EXTENSION: '.$required_ext."\n";
|
||||
$ext_missing .= $error_icon.' 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!
|
||||
} else {
|
||||
$ext_installed .= '√ '.$required_ext." is installed!\n";
|
||||
$ext_installed .= $success_icon.' '.$required_ext." is installed!\n";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -350,15 +360,15 @@ if ($ext_missing!='') {
|
||||
echo "--------------------------------------------------------\n";
|
||||
|
||||
foreach ($loaded_exts_array as $loaded_ext) {
|
||||
echo "- ".$loaded_ext."\n";
|
||||
echo $success_icon.' '.$loaded_ext."\n";
|
||||
}
|
||||
|
||||
echo "--------------------- !! ERROR !! ----------------------\n";
|
||||
echo "\e[91m--------------------- !! ERROR !! ----------------------\n";
|
||||
echo $ext_missing;
|
||||
echo "--------------------------------------------------------\n";
|
||||
echo "ABORTING THE INSTALLER \n";
|
||||
echo "Please install the extensions above and re-run this script.\n";
|
||||
echo "--------------------------------------------------------\n";
|
||||
echo "\e[91m--------------------------------------------------------\n";
|
||||
echo "\e[91mABORTING THE INSTALLER \n";
|
||||
echo "\e[91mPlease install the extensions above and re-run this script.\n";
|
||||
echo "\e[91m--------------------------------------------------------\n";
|
||||
exit(1);
|
||||
} else {
|
||||
echo $ext_installed."\n";
|
||||
@@ -367,9 +377,9 @@ if ($ext_missing!='') {
|
||||
|
||||
|
||||
|
||||
echo "--------------------------------------------------------\n";
|
||||
echo "\e[95m--------------------------------------------------------\n";
|
||||
echo "STEP 3: Checking directory permissions: \n";
|
||||
echo "--------------------------------------------------------\n\n";
|
||||
echo "--------------------------------------------------------\e[39m\n\n";
|
||||
|
||||
|
||||
$writable_dirs_array =
|
||||
@@ -395,9 +405,9 @@ $dirs_not_writable = '';
|
||||
// Loop through the directories that need to be writable
|
||||
foreach ($writable_dirs_array as $writable_dir) {
|
||||
if (is_writable($writable_dir)) {
|
||||
$dirs_writable .= '√ '.getcwd().'/'.$writable_dir." is writable \n";
|
||||
$dirs_writable .= $success_icon.' '.getcwd().'/'.$writable_dir." is writable \n";
|
||||
} else {
|
||||
$dirs_not_writable .= '✘ PERMISSIONS ERROR: '.getcwd().'/'.$writable_dir." is NOT writable\n";
|
||||
$dirs_not_writable .= $error_icon.' PERMISSIONS ERROR: '.getcwd().'/'.$writable_dir." is NOT writable\n";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -405,44 +415,24 @@ echo $dirs_writable."\n";
|
||||
|
||||
// Print out a useful error message
|
||||
if ($dirs_not_writable!='') {
|
||||
echo "--------------------------------------------------------\n";
|
||||
echo "The following directories/files do not seem writable: \n";
|
||||
echo "--------------------------------------------------------\n";
|
||||
echo "\e[91m--------------------------------------------------------\n";
|
||||
echo "\eThe following directories/files do not seem writable: \n";
|
||||
echo "\e--------------------------------------------------------\e[39m\n";
|
||||
|
||||
echo $dirs_not_writable;
|
||||
|
||||
echo "--------------------- !! ERROR !! ----------------------\n";
|
||||
echo "Please check the permissions on the directories above and re-run this script.\n";
|
||||
echo "------------------------- :( ---------------------------\n\n";
|
||||
echo "\e[91m--------------------- !! ERROR !! ----------------------\n";
|
||||
echo "\ePlease check the permissions on the directories above and re-run this script.\n";
|
||||
echo "\e------------------------- :( ---------------------------\e[39m\n\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
echo "--------------------------------------------------------\n";
|
||||
echo "STEP 4: Backing up database: \n";
|
||||
echo "--------------------------------------------------------\n\n";
|
||||
$backup = exec('php artisan snipeit:backup', $backup_results, $return_code);
|
||||
echo '-- ' . implode("\n", $backup_results) . "\n\n";
|
||||
if ($return_code > 0) {
|
||||
die("Something went wrong with your backup. Aborting!\n\n");
|
||||
}
|
||||
unset($return_code);
|
||||
|
||||
echo "--------------------------------------------------------\n";
|
||||
echo "STEP 5: Putting application into maintenance mode: \n";
|
||||
echo "--------------------------------------------------------\n\n";
|
||||
exec('php artisan down', $down_results, $return_code);
|
||||
echo '-- ' . implode("\n", $down_results) . "\n";
|
||||
if ($return_code > 0) {
|
||||
die("Something went wrong with downing you site. This can't be good. Please investigate the error. Aborting!n\n");
|
||||
}
|
||||
unset($return_code);
|
||||
|
||||
|
||||
echo "--------------------------------------------------------\n";
|
||||
echo "STEP 6: Pulling latest from Git (".$branch." branch): \n";
|
||||
echo "--------------------------------------------------------\n\n";
|
||||
echo "\e[95m--------------------------------------------------------\n";
|
||||
echo "STEP 4: Pulling latest from Git (".$branch." branch): \n";
|
||||
echo "--------------------------------------------------------\e[39m\n\n";
|
||||
$git_version = shell_exec('git --version');
|
||||
|
||||
if ((strpos('git version', $git_version)) === false) {
|
||||
@@ -466,9 +456,9 @@ if ((strpos('git version', $git_version)) === false) {
|
||||
}
|
||||
|
||||
|
||||
echo "--------------------------------------------------------\n";
|
||||
echo "STEP 7: Cleaning up old cached files:\n";
|
||||
echo "--------------------------------------------------------\n\n";
|
||||
echo "\e[95m--------------------------------------------------------\n";
|
||||
echo "STEP 5: Cleaning up old cached files:\n";
|
||||
echo "--------------------------------------------------------\e[39m\n\n";
|
||||
|
||||
// Build an array of the files we generally want to delete because they
|
||||
// can cause issues with funky caching
|
||||
@@ -481,39 +471,28 @@ $unused_files = [
|
||||
|
||||
foreach ($unused_files as $unused_file) {
|
||||
if (file_exists($unused_file)) {
|
||||
echo "√ Deleting ".$unused_file.". It is no longer used.\n";
|
||||
echo $success_icon." Deleting ".$unused_file.". It is no longer used.\n";
|
||||
@unlink($unused_file);
|
||||
} else {
|
||||
echo "√ No ".$unused_file.", so nothing to delete.\n";
|
||||
echo $success_icon." No ".$unused_file.", so nothing to delete.\n";
|
||||
}
|
||||
}
|
||||
echo "\n";
|
||||
|
||||
$config_clear = shell_exec('php artisan config:clear');
|
||||
$cache_clear = shell_exec('php artisan cache:clear');
|
||||
$route_clear = shell_exec('php artisan route:clear');
|
||||
$view_clear = shell_exec('php artisan view:clear');
|
||||
echo '-- '.$config_clear;
|
||||
echo '-- '.$cache_clear;
|
||||
echo '-- '.$route_clear;
|
||||
echo '-- '.$view_clear;
|
||||
echo "\n";
|
||||
|
||||
echo "--------------------------------------------------------\n";
|
||||
echo "STEP 8: Updating composer dependencies:\n";
|
||||
echo "\e[95m--------------------------------------------------------\n";
|
||||
echo "STEP 6: Updating composer dependencies:\n";
|
||||
echo "(This may take a moment.)\n";
|
||||
echo "--------------------------------------------------------\n\n";
|
||||
echo "--------------------------------------------------------\e[39m\n\n";
|
||||
echo "-- Running the app in ".$app_environment." mode.\n";
|
||||
|
||||
// Composer install
|
||||
if (file_exists('composer.phar')) {
|
||||
echo "√ Local composer.phar detected, so we'll use that.\n\n";
|
||||
echo $success_icon." Local composer.phar detected, so we'll use that.\n\n";
|
||||
echo "-- Updating local composer.phar\n\n";
|
||||
$composer_update = shell_exec('php composer.phar self-update');
|
||||
echo $composer_update."\n\n";
|
||||
|
||||
|
||||
|
||||
// Use --no-dev only if we are in production mode.
|
||||
// This will cause errors otherwise, if the user is in develop or local for their APP_ENV
|
||||
if ($app_environment == 'production') {
|
||||
@@ -521,10 +500,9 @@ if (file_exists('composer.phar')) {
|
||||
} else {
|
||||
$composer = shell_exec('php composer.phar install --prefer-source');
|
||||
}
|
||||
|
||||
$composer_dump = shell_exec('php composer.phar dump');
|
||||
|
||||
|
||||
|
||||
} else {
|
||||
|
||||
echo "-- We couldn't find a local composer.phar. No worries, trying globally.\n";
|
||||
@@ -541,48 +519,87 @@ if (file_exists('composer.phar')) {
|
||||
$composer_dump = shell_exec('composer dump');
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
echo $composer_dump."\n";
|
||||
echo $composer;
|
||||
|
||||
$config_clear = shell_exec('php artisan config:clear');
|
||||
$cache_clear = shell_exec('php artisan cache:clear');
|
||||
$route_clear = shell_exec('php artisan route:clear');
|
||||
$view_clear = shell_exec('php artisan view:clear');
|
||||
echo $success_icon.' '.trim($config_clear)."\n";
|
||||
echo $success_icon.' '.trim($cache_clear)."\n";
|
||||
echo $success_icon.' '.trim($route_clear)."\n";
|
||||
echo $success_icon.' '.trim($view_clear)."\n";
|
||||
echo "\n";
|
||||
|
||||
echo "--------------------------------------------------------\n";
|
||||
echo "\e[95m--------------------------------------------------------\n";
|
||||
echo "STEP 7: Putting application into maintenance mode: \n";
|
||||
echo "--------------------------------------------------------\e[39m\n\n";
|
||||
exec('php artisan down', $down_results, $return_code);
|
||||
echo '-- ' . implode("\n", $down_results) . "\n";
|
||||
if ($return_code > 0) {
|
||||
die("Something went wrong with downing your site. This can't be good. Please investigate the error. Aborting!\n\n");
|
||||
}
|
||||
unset($return_code);
|
||||
|
||||
|
||||
echo "\e[95m--------------------------------------------------------\n";
|
||||
echo "STEP 8: Backing up database: \n";
|
||||
echo "--------------------------------------------------------\e[39m\n\n";
|
||||
|
||||
if (!$skip_backup) {
|
||||
$backup = exec('php artisan snipeit:backup', $backup_results, $return_code);
|
||||
|
||||
if ($return_code > 0) {
|
||||
die($error_icon." Something went wrong with your backup. Aborting!\n\n");
|
||||
} else {
|
||||
echo '-- ' . implode("\n", $backup_results) . "\n\n";
|
||||
}
|
||||
unset($return_code);
|
||||
} else {
|
||||
echo "Upgrade was run with --skip-backup, so no backup will be run.\n\n";
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
echo "\e[95m--------------------------------------------------------\n";
|
||||
echo "STEP 9: Migrating database:\n";
|
||||
echo "--------------------------------------------------------\n\n";
|
||||
echo "--------------------------------------------------------\e[39m\n\n";
|
||||
|
||||
$migrations = shell_exec('php artisan migrate --force');
|
||||
echo $migrations."\n";
|
||||
|
||||
|
||||
echo "--------------------------------------------------------\n";
|
||||
echo "\e[95m--------------------------------------------------------\n";
|
||||
echo "STEP 10: Checking for OAuth keys:\n";
|
||||
echo "--------------------------------------------------------\n\n";
|
||||
echo "--------------------------------------------------------\e[39m\n\n";
|
||||
|
||||
|
||||
if ((!file_exists('storage/oauth-public.key')) || (!file_exists('storage/oauth-private.key'))) {
|
||||
echo "- No OAuth keys detected. Running passport install now.\n\n";
|
||||
$passport = shell_exec('php artisan passport:install');
|
||||
echo $info_icon." No OAuth keys detected. Running passport install now.\n\n";
|
||||
$passport = shell_exec('php artisan passport:install --no-interaction');
|
||||
echo $passport;
|
||||
} else {
|
||||
echo "√ OAuth keys detected. Skipping passport install.\n\n";
|
||||
echo $success_icon." OAuth keys detected. Skipping passport install.\n\n";
|
||||
}
|
||||
|
||||
|
||||
echo "--------------------------------------------------------\n";
|
||||
echo "\e[95m--------------------------------------------------------\n";
|
||||
echo "STEP 11: Taking application out of maintenance mode:\n";
|
||||
echo "--------------------------------------------------------\n\n";
|
||||
echo "--------------------------------------------------------\e[39m\n\n";
|
||||
|
||||
$up = shell_exec('php artisan up');
|
||||
echo '-- '.$up."\n";
|
||||
echo $success_icon.' '.trim($up)."\n\n";
|
||||
|
||||
|
||||
|
||||
echo "---------------------- FINISHED! -----------------------\n";
|
||||
echo "\e[92m---------------------- FINISHED! -----------------------\n";
|
||||
echo "All done! Clear your browser cookies and re-login to use \n";
|
||||
echo "your upgraded Snipe-IT!\n";
|
||||
echo "--------------------------------------------------------\n\n";
|
||||
echo "--------------------------------------------------------\e[39m\n\n";
|
||||
|
||||
|
||||
function str_begins($haystack, $needle) {
|
||||
@@ -592,6 +609,3 @@ function str_begins($haystack, $needle) {
|
||||
function str_ends($haystack, $needle) {
|
||||
return (substr_compare($haystack, $needle, -strlen($needle)) === 0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user