mirror of
https://github.com/snipe/snipe-it.git
synced 2024-11-09 23:24:06 -08:00
Merge branch 'develop' into snipeit_v7_laravel10
This commit is contained in:
commit
3500217f94
73
.github/workflows/tests.yml
vendored
Normal file
73
.github/workflows/tests.yml
vendored
Normal file
|
@ -0,0 +1,73 @@
|
||||||
|
name: Tests
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- master
|
||||||
|
- develop
|
||||||
|
pull_request:
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
tests:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
services:
|
||||||
|
mysql:
|
||||||
|
image: mysql:5.7
|
||||||
|
env:
|
||||||
|
MYSQL_ALLOW_EMPTY_PASSWORD: yes
|
||||||
|
MYSQL_DATABASE: snipeit
|
||||||
|
ports:
|
||||||
|
- 33306:3306
|
||||||
|
options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=3
|
||||||
|
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
php-version:
|
||||||
|
- "7.4"
|
||||||
|
- "8.0"
|
||||||
|
- "8.1.1"
|
||||||
|
|
||||||
|
name: PHP ${{ matrix.php-version }}
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: shivammathur/setup-php@v2
|
||||||
|
with:
|
||||||
|
php-version: "${{ matrix.php-version }}"
|
||||||
|
coverage: none
|
||||||
|
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
|
||||||
|
- name: Get Composer Cache Directory
|
||||||
|
id: composer-cache
|
||||||
|
run: |
|
||||||
|
echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT
|
||||||
|
- uses: actions/cache@v3
|
||||||
|
with:
|
||||||
|
path: ${{ steps.composer-cache.outputs.dir }}
|
||||||
|
key: ${{ runner.os }}-${{ matrix.php-version }}-composer-${{ hashFiles('**/composer.lock') }}
|
||||||
|
restore-keys: |
|
||||||
|
${{ runner.os }}-composer-
|
||||||
|
|
||||||
|
- name: Copy .env
|
||||||
|
run: |
|
||||||
|
cp -v .env.testing.example .env
|
||||||
|
cp -v .env.testing.example .env.testing
|
||||||
|
|
||||||
|
- name: Install Dependencies
|
||||||
|
run: composer install -q --no-ansi --no-interaction --no-scripts --no-progress --prefer-dist
|
||||||
|
|
||||||
|
- name: Generate key
|
||||||
|
run: php artisan key:generate
|
||||||
|
|
||||||
|
- name: Directory Permissions
|
||||||
|
run: chmod -R 777 storage bootstrap/cache
|
||||||
|
|
||||||
|
- name: Execute tests (Unit and Feature tests) via PHPUnit
|
||||||
|
env:
|
||||||
|
DB_CONNECTION: mysql
|
||||||
|
DB_DATABASE: snipeit
|
||||||
|
DB_PORT: ${{ job.services.mysql.ports[3306] }}
|
||||||
|
DB_USERNAME: root
|
||||||
|
run: php artisan test --parallel
|
|
@ -75,7 +75,6 @@ class UsersController extends Controller
|
||||||
|
|
||||||
])->with('manager', 'groups', 'userloc', 'company', 'department', 'assets', 'licenses', 'accessories', 'consumables', 'createdBy',)
|
])->with('manager', 'groups', 'userloc', 'company', 'department', 'assets', 'licenses', 'accessories', 'consumables', 'createdBy',)
|
||||||
->withCount('assets as assets_count', 'licenses as licenses_count', 'accessories as accessories_count', 'consumables as consumables_count');
|
->withCount('assets as assets_count', 'licenses as licenses_count', 'accessories as accessories_count', 'consumables as consumables_count');
|
||||||
$users = Company::scopeCompanyables($users);
|
|
||||||
|
|
||||||
|
|
||||||
if ($request->filled('activated')) {
|
if ($request->filled('activated')) {
|
||||||
|
@ -272,6 +271,8 @@ class UsersController extends Controller
|
||||||
$users = $users->withTrashed();
|
$users = $users->withTrashed();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$users = Company::scopeCompanyables($users);
|
||||||
|
|
||||||
$total = $users->count();
|
$total = $users->count();
|
||||||
$users = $users->skip($offset)->take($limit)->get();
|
$users = $users->skip($offset)->take($limit)->get();
|
||||||
|
|
||||||
|
|
|
@ -286,6 +286,7 @@ class AssetModelsController extends Controller
|
||||||
return view('models/edit')
|
return view('models/edit')
|
||||||
->with('depreciation_list', Helper::depreciationList())
|
->with('depreciation_list', Helper::depreciationList())
|
||||||
->with('item', $model)
|
->with('item', $model)
|
||||||
|
->with('model_id', $model_to_clone->id)
|
||||||
->with('clone_model', $model_to_clone);
|
->with('clone_model', $model_to_clone);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -82,7 +82,6 @@ class Asset extends Depreciable
|
||||||
'location_id' => 'integer',
|
'location_id' => 'integer',
|
||||||
'rtd_company_id' => 'integer',
|
'rtd_company_id' => 'integer',
|
||||||
'supplier_id' => 'integer',
|
'supplier_id' => 'integer',
|
||||||
'byod' => 'boolean',
|
|
||||||
'created_at' => 'datetime',
|
'created_at' => 'datetime',
|
||||||
'updated_at' => 'datetime',
|
'updated_at' => 'datetime',
|
||||||
'deleted_at' => 'datetime',
|
'deleted_at' => 'datetime',
|
||||||
|
@ -105,6 +104,7 @@ class Asset extends Depreciable
|
||||||
'purchase_cost' => 'numeric|nullable|gte:0',
|
'purchase_cost' => 'numeric|nullable|gte:0',
|
||||||
'supplier_id' => 'exists:suppliers,id|nullable',
|
'supplier_id' => 'exists:suppliers,id|nullable',
|
||||||
'asset_eol_date' => 'date|max:10|min:10|nullable',
|
'asset_eol_date' => 'date|max:10|min:10|nullable',
|
||||||
|
'byod' => 'boolean',
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -69,15 +69,12 @@ class User extends SnipeModel implements AuthenticatableContract, AuthorizableCo
|
||||||
];
|
];
|
||||||
|
|
||||||
protected $casts = [
|
protected $casts = [
|
||||||
'activated' => 'boolean',
|
|
||||||
'manager_id' => 'integer',
|
'manager_id' => 'integer',
|
||||||
'location_id' => 'integer',
|
'location_id' => 'integer',
|
||||||
'company_id' => 'integer',
|
'company_id' => 'integer',
|
||||||
'vip' => 'boolean',
|
|
||||||
'created_at' => 'datetime',
|
'created_at' => 'datetime',
|
||||||
'updated_at' => 'datetime',
|
'updated_at' => 'datetime',
|
||||||
'deleted_at' => 'datetime',
|
'deleted_at' => 'datetime',
|
||||||
'autoassign_licenses' => 'boolean',
|
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -103,6 +100,9 @@ class User extends SnipeModel implements AuthenticatableContract, AuthorizableCo
|
||||||
'state' => 'min:2|max:191|nullable',
|
'state' => 'min:2|max:191|nullable',
|
||||||
'country' => 'min:2|max:191|nullable',
|
'country' => 'min:2|max:191|nullable',
|
||||||
'zip' => 'max:10|nullable',
|
'zip' => 'max:10|nullable',
|
||||||
|
'vip' => 'boolean',
|
||||||
|
'remote' => 'boolean',
|
||||||
|
'activated' => 'boolean',
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -69,7 +69,7 @@ return [
|
||||||
'mysql' => [
|
'mysql' => [
|
||||||
'driver' => 'mysql',
|
'driver' => 'mysql',
|
||||||
'host' => env('DB_HOST', 'localhost'),
|
'host' => env('DB_HOST', 'localhost'),
|
||||||
'port' => env('DB_PORT', '3306'),
|
'port' => env('DB_PORT', 3306),
|
||||||
'database' => env('DB_DATABASE', 'forge'),
|
'database' => env('DB_DATABASE', 'forge'),
|
||||||
'username' => env('DB_USERNAME', 'forge'),
|
'username' => env('DB_USERNAME', 'forge'),
|
||||||
'password' => env('DB_PASSWORD', ''),
|
'password' => env('DB_PASSWORD', ''),
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
<?php
|
<?php
|
||||||
return array (
|
return array (
|
||||||
'app_version' => 'v6.1.2',
|
'app_version' => 'v6.2.0-pre',
|
||||||
'full_app_version' => 'v6.1.2 - build 10938-g32747cafd',
|
'full_app_version' => 'v6.2.0-pre - build 11391-g319cb2305',
|
||||||
'build_version' => '10938',
|
'build_version' => '11391',
|
||||||
'prerelease_version' => '',
|
'prerelease_version' => '',
|
||||||
'hash_version' => 'g32747cafd',
|
'hash_version' => 'g319cb2305',
|
||||||
'full_hash' => 'v6.1.2-89-g32747cafd',
|
'full_hash' => 'v6.2.0-pre-451-g319cb2305',
|
||||||
'branch' => 'develop',
|
'branch' => 'develop',
|
||||||
);
|
);
|
20
package-lock.json
generated
20
package-lock.json
generated
|
@ -5,7 +5,7 @@
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@fortawesome/fontawesome-free": "^6.4.0",
|
"@fortawesome/fontawesome-free": "^6.4.2",
|
||||||
"acorn": "^8.9.0",
|
"acorn": "^8.9.0",
|
||||||
"acorn-import-assertions": "^1.9.0",
|
"acorn-import-assertions": "^1.9.0",
|
||||||
"admin-lte": "^2.4.18",
|
"admin-lte": "^2.4.18",
|
||||||
|
@ -26,7 +26,7 @@
|
||||||
"jquery-ui-bundle": "^1.12.1",
|
"jquery-ui-bundle": "^1.12.1",
|
||||||
"jquery.iframe-transport": "^1.0.0",
|
"jquery.iframe-transport": "^1.0.0",
|
||||||
"jspdf-autotable": "^3.5.30",
|
"jspdf-autotable": "^3.5.30",
|
||||||
"less": "^4.1.2",
|
"less": "^4.2.0",
|
||||||
"less-loader": "^6.0",
|
"less-loader": "^6.0",
|
||||||
"list.js": "^1.5.0",
|
"list.js": "^1.5.0",
|
||||||
"morris.js": "github:morrisjs/morris.js",
|
"morris.js": "github:morrisjs/morris.js",
|
||||||
|
@ -1810,9 +1810,10 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@fortawesome/fontawesome-free": {
|
"node_modules/@fortawesome/fontawesome-free": {
|
||||||
"version": "6.4.0",
|
"version": "6.4.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-free/-/fontawesome-free-6.4.2.tgz",
|
||||||
|
"integrity": "sha512-m5cPn3e2+FDCOgi1mz0RexTUvvQibBebOUlUlW0+YrMjDTPkiJ6VTKukA1GRsvRw+12KyJndNjj0O4AgTxm2Pg==",
|
||||||
"hasInstallScript": true,
|
"hasInstallScript": true,
|
||||||
"license": "(CC-BY-4.0 AND OFL-1.1 AND MIT)",
|
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=6"
|
"node": ">=6"
|
||||||
}
|
}
|
||||||
|
@ -2620,9 +2621,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/alpinejs": {
|
"node_modules/alpinejs": {
|
||||||
"version": "3.12.3",
|
"version": "3.13.0",
|
||||||
"resolved": "https://registry.npmjs.org/alpinejs/-/alpinejs-3.12.3.tgz",
|
"resolved": "https://registry.npmjs.org/alpinejs/-/alpinejs-3.13.0.tgz",
|
||||||
"integrity": "sha512-fLz2dfYQ3xCk7Ip8LiIpV2W+9brUyex2TAE7Z0BCvZdUDklJE+n+a8gCgLWzfZ0GzZNZu7HUP8Z0z6Xbm6fsSA==",
|
"integrity": "sha512-7FYR1Yz3evIjlJD1mZ3SYWSw+jlOmQGeQ1QiSufSQ6J84XMQFkzxm6OobiZ928SfqhGdoIp2SsABNsS4rXMMJw==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@vue/reactivity": "~3.1.1"
|
"@vue/reactivity": "~3.1.1"
|
||||||
}
|
}
|
||||||
|
@ -7457,8 +7458,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/less": {
|
"node_modules/less": {
|
||||||
"version": "4.1.3",
|
"version": "4.2.0",
|
||||||
"license": "Apache-2.0",
|
"resolved": "https://registry.npmjs.org/less/-/less-4.2.0.tgz",
|
||||||
|
"integrity": "sha512-P3b3HJDBtSzsXUl0im2L7gTO5Ubg8mEN6G8qoTS77iXxXX4Hvu4Qj540PZDvQ8V6DmX6iXo98k7Md0Cm1PrLaA==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"copy-anything": "^2.0.1",
|
"copy-anything": "^2.0.1",
|
||||||
"parse-node-version": "^1.0.1",
|
"parse-node-version": "^1.0.1",
|
||||||
|
|
|
@ -24,7 +24,7 @@
|
||||||
"vue-template-compiler": "2.4.4"
|
"vue-template-compiler": "2.4.4"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@fortawesome/fontawesome-free": "^6.4.0",
|
"@fortawesome/fontawesome-free": "^6.4.2",
|
||||||
"acorn": "^8.9.0",
|
"acorn": "^8.9.0",
|
||||||
"acorn-import-assertions": "^1.9.0",
|
"acorn-import-assertions": "^1.9.0",
|
||||||
"admin-lte": "^2.4.18",
|
"admin-lte": "^2.4.18",
|
||||||
|
@ -45,7 +45,7 @@
|
||||||
"jquery-ui-bundle": "^1.12.1",
|
"jquery-ui-bundle": "^1.12.1",
|
||||||
"jquery.iframe-transport": "^1.0.0",
|
"jquery.iframe-transport": "^1.0.0",
|
||||||
"jspdf-autotable": "^3.5.30",
|
"jspdf-autotable": "^3.5.30",
|
||||||
"less": "^4.1.2",
|
"less": "^4.2.0",
|
||||||
"less-loader": "^6.0",
|
"less-loader": "^6.0",
|
||||||
"list.js": "^1.5.0",
|
"list.js": "^1.5.0",
|
||||||
"morris.js": "github:morrisjs/morris.js",
|
"morris.js": "github:morrisjs/morris.js",
|
||||||
|
|
BIN
public/css/dist/all.css
vendored
BIN
public/css/dist/all.css
vendored
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
public/js/dist/all-defer.js
vendored
BIN
public/js/dist/all-defer.js
vendored
Binary file not shown.
|
@ -18,22 +18,22 @@
|
||||||
"/css/dist/skins/skin-green.css": "/css/dist/skins/skin-green.css?id=b48f4d8af0e1ca5621c161e93951109f",
|
"/css/dist/skins/skin-green.css": "/css/dist/skins/skin-green.css?id=b48f4d8af0e1ca5621c161e93951109f",
|
||||||
"/css/dist/skins/skin-contrast.css": "/css/dist/skins/skin-contrast.css?id=f0fbbb0ac729ea092578fb05ca615460",
|
"/css/dist/skins/skin-contrast.css": "/css/dist/skins/skin-contrast.css?id=f0fbbb0ac729ea092578fb05ca615460",
|
||||||
"/css/dist/skins/skin-red.css": "/css/dist/skins/skin-red.css?id=b9a74ec0cd68f83e7480d5ae39919beb",
|
"/css/dist/skins/skin-red.css": "/css/dist/skins/skin-red.css?id=b9a74ec0cd68f83e7480d5ae39919beb",
|
||||||
"/css/dist/all.css": "/css/dist/all.css?id=c5f8982eb14ba2c7e0c0fec60519afc6",
|
"/css/dist/all.css": "/css/dist/all.css?id=829410b57e28448fef5c57beda0861e3",
|
||||||
"/css/dist/signature-pad.css": "/css/dist/signature-pad.css?id=6a89d3cd901305e66ced1cf5f13147f7",
|
"/css/dist/signature-pad.css": "/css/dist/signature-pad.css?id=6a89d3cd901305e66ced1cf5f13147f7",
|
||||||
"/css/dist/signature-pad.min.css": "/css/dist/signature-pad.min.css?id=6a89d3cd901305e66ced1cf5f13147f7",
|
"/css/dist/signature-pad.min.css": "/css/dist/signature-pad.min.css?id=6a89d3cd901305e66ced1cf5f13147f7",
|
||||||
"/css/webfonts/fa-brands-400.ttf": "/css/webfonts/fa-brands-400.ttf?id=e2e2b1797606a266ed55549f5bb5a179",
|
"/css/webfonts/fa-brands-400.ttf": "/css/webfonts/fa-brands-400.ttf?id=a656b2d865fe379d8851757e8e4001ef",
|
||||||
"/css/webfonts/fa-brands-400.woff2": "/css/webfonts/fa-brands-400.woff2?id=fe912d1c4a7e0e1db87a64eb7e54c945",
|
"/css/webfonts/fa-brands-400.woff2": "/css/webfonts/fa-brands-400.woff2?id=a6761c03f9c021aeb9754283755b660e",
|
||||||
"/css/webfonts/fa-regular-400.ttf": "/css/webfonts/fa-regular-400.ttf?id=31a6b5ecfc8d018d0e3a294f0c80e9e9",
|
"/css/webfonts/fa-regular-400.ttf": "/css/webfonts/fa-regular-400.ttf?id=75a44676b684c784508452a53867e8da",
|
||||||
"/css/webfonts/fa-regular-400.woff2": "/css/webfonts/fa-regular-400.woff2?id=bf8eabe300a00a3adb0293596987abc4",
|
"/css/webfonts/fa-regular-400.woff2": "/css/webfonts/fa-regular-400.woff2?id=c612044da7f7b81ab8f2cadf94964208",
|
||||||
"/css/webfonts/fa-solid-900.ttf": "/css/webfonts/fa-solid-900.ttf?id=cd687455c6d6c058e2e9f84f409e2965",
|
"/css/webfonts/fa-solid-900.ttf": "/css/webfonts/fa-solid-900.ttf?id=3867ccc7ab681d3c27d1e97a792b46d3",
|
||||||
"/css/webfonts/fa-solid-900.woff2": "/css/webfonts/fa-solid-900.woff2?id=eea38615e7b5dbbaf88c263f2230cc32",
|
"/css/webfonts/fa-solid-900.woff2": "/css/webfonts/fa-solid-900.woff2?id=7f63d634454e771396bce3e09dfcdbc5",
|
||||||
"/css/webfonts/fa-v4compatibility.ttf": "/css/webfonts/fa-v4compatibility.ttf?id=6ebbf5afc34f54463abc2b81ca637364",
|
"/css/webfonts/fa-v4compatibility.ttf": "/css/webfonts/fa-v4compatibility.ttf?id=70ad875b2378eb850254f01dec991ade",
|
||||||
"/css/webfonts/fa-v4compatibility.woff2": "/css/webfonts/fa-v4compatibility.woff2?id=67b8a78b7e80e805cfa4ee0421895ba4",
|
"/css/webfonts/fa-v4compatibility.woff2": "/css/webfonts/fa-v4compatibility.woff2?id=d36941873b661076f146b0221f13497d",
|
||||||
"/css/dist/bootstrap-table.css": "/css/dist/bootstrap-table.css?id=281bcfe26549412d128f695234961081",
|
"/css/dist/bootstrap-table.css": "/css/dist/bootstrap-table.css?id=281bcfe26549412d128f695234961081",
|
||||||
"/js/build/vendor.js": "/js/build/vendor.js?id=8ac1d250496313e93744790e5138305d",
|
"/js/build/vendor.js": "/js/build/vendor.js?id=8ac1d250496313e93744790e5138305d",
|
||||||
"/js/dist/bootstrap-table.js": "/js/dist/bootstrap-table.js?id=df78f0c4cc93c29c02a41144590f6350",
|
"/js/dist/bootstrap-table.js": "/js/dist/bootstrap-table.js?id=df78f0c4cc93c29c02a41144590f6350",
|
||||||
"/js/dist/all.js": "/js/dist/all.js?id=b487452bd6bef7fa6201586415d383f2",
|
"/js/dist/all.js": "/js/dist/all.js?id=b487452bd6bef7fa6201586415d383f2",
|
||||||
"/js/dist/all-defer.js": "/js/dist/all-defer.js?id=7829a391ab2f89926465398bebb7df8d",
|
"/js/dist/all-defer.js": "/js/dist/all-defer.js?id=07e52318da2cdf3171c4d88113f25fb6",
|
||||||
"/css/dist/skins/skin-green.min.css": "/css/dist/skins/skin-green.min.css?id=b48f4d8af0e1ca5621c161e93951109f",
|
"/css/dist/skins/skin-green.min.css": "/css/dist/skins/skin-green.min.css?id=b48f4d8af0e1ca5621c161e93951109f",
|
||||||
"/css/dist/skins/skin-green-dark.min.css": "/css/dist/skins/skin-green-dark.min.css?id=44f9320d0739f419c9246f7f39395b02",
|
"/css/dist/skins/skin-green-dark.min.css": "/css/dist/skins/skin-green-dark.min.css?id=44f9320d0739f419c9246f7f39395b02",
|
||||||
"/css/dist/skins/skin-black.min.css": "/css/dist/skins/skin-black.min.css?id=1f33ca3d860461c1127ec465ab3ebb6b",
|
"/css/dist/skins/skin-black.min.css": "/css/dist/skins/skin-black.min.css?id=1f33ca3d860461c1127ec465ab3ebb6b",
|
||||||
|
|
|
@ -15,15 +15,15 @@
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-3">
|
<div class="col-md-12">
|
||||||
|
|
||||||
<label class="btn btn-default">
|
<label class="btn btn-default btn-block">
|
||||||
{{ trans('button.select_file') }}
|
{{ trans('button.select_files') }}
|
||||||
<input type="file" name="file[]" multiple="true" class="js-uploadFile" id="uploadFile" data-maxsize="{{ Helper::file_upload_max_size() }}" accept="image/*,.csv,.zip,.rar,.doc,.docx,.xls,.xlsx,.xml,.lic,.xlsx,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,application/vnd.ms-excel,text/plain,.pdf,application/rtf,application/json" style="display:none" required>
|
<input type="file" name="file[]" multiple="true" class="js-uploadFile" id="uploadFile" data-maxsize="{{ Helper::file_upload_max_size() }}" accept="image/*,.csv,.zip,.rar,.doc,.docx,.xls,.xlsx,.xml,.lic,.xlsx,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,application/vnd.ms-excel,text/plain,.pdf,application/rtf,application/json" style="display:none" required>
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-9">
|
<div class="col-md-12">
|
||||||
<span id="uploadFile-info"></span>
|
<span id="uploadFile-info"></span>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-12">
|
<div class="col-md-12">
|
||||||
|
|
|
@ -34,7 +34,8 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Custom Fieldset -->
|
<!-- Custom Fieldset -->
|
||||||
@livewire('custom-field-set-default-values-for-model',["model_id" => $item->id])
|
<!-- If $item->id is null we are cloning the model and we need the $model_id variable -->
|
||||||
|
@livewire('custom-field-set-default-values-for-model',["model_id" => $item->id ?? $model_id ?? null ])
|
||||||
|
|
||||||
@include ('partials.forms.edit.notes')
|
@include ('partials.forms.edit.notes')
|
||||||
@include ('partials.forms.edit.requestable', ['requestable_text' => trans('admin/models/general.requestable')])
|
@include ('partials.forms.edit.requestable', ['requestable_text' => trans('admin/models/general.requestable')])
|
||||||
|
|
|
@ -18,6 +18,15 @@
|
||||||
.checkbox label {
|
.checkbox label {
|
||||||
padding-right: 40px;
|
padding-right: 40px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Don't make the password field *look* readonly - this is for usability, so admins don't think they can't edit this field.
|
||||||
|
*/
|
||||||
|
.form-control[readonly] {
|
||||||
|
background-color: white;
|
||||||
|
color: #555555;
|
||||||
|
cursor:text;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
@if ((!function_exists('ldap_connect')) || (!function_exists('ldap_set_option')) || (!function_exists('ldap_bind')))
|
@if ((!function_exists('ldap_connect')) || (!function_exists('ldap_set_option')) || (!function_exists('ldap_bind')))
|
||||||
|
@ -34,10 +43,12 @@
|
||||||
@endif
|
@endif
|
||||||
|
|
||||||
|
|
||||||
{{ Form::open(['method' => 'POST', 'files' => false, 'autocomplete' => 'false', 'class' => 'form-horizontal', 'role' => 'form']) }}
|
{{ Form::open(['method' => 'POST', 'files' => false, 'autocomplete' => 'off', 'class' => 'form-horizontal', 'role' => 'form']) }}
|
||||||
<!-- CSRF Token -->
|
<!-- CSRF Token -->
|
||||||
{{csrf_field()}}
|
{{csrf_field()}}
|
||||||
|
|
||||||
|
<input type="hidden" name="username" value="{{ Request::old('username', $user->username) }}">
|
||||||
|
|
||||||
<!-- this is a hack to prevent Chrome from trying to autocomplete fields -->
|
<!-- this is a hack to prevent Chrome from trying to autocomplete fields -->
|
||||||
<input type="text" name="prevent_autofill" id="prevent_autofill" value="" style="display:none;" />
|
<input type="text" name="prevent_autofill" id="prevent_autofill" value="" style="display:none;" />
|
||||||
<input type="password" name="password_fake" id="password_fake" value="" style="display:none;" />
|
<input type="password" name="password_fake" id="password_fake" value="" style="display:none;" />
|
||||||
|
@ -54,7 +65,6 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="box-body">
|
<div class="box-body">
|
||||||
|
|
||||||
|
|
||||||
<div class="col-md-11 col-md-offset-1">
|
<div class="col-md-11 col-md-offset-1">
|
||||||
|
|
||||||
<!-- Enable LDAP -->
|
<!-- Enable LDAP -->
|
||||||
|
@ -230,7 +240,7 @@
|
||||||
{{ Form::label('ldap_uname', trans('admin/settings/general.ldap_uname')) }}
|
{{ Form::label('ldap_uname', trans('admin/settings/general.ldap_uname')) }}
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-8">
|
<div class="col-md-8">
|
||||||
{{ Form::text('ldap_uname', Request::old('ldap_uname', $setting->ldap_uname), ['class' => 'form-control','placeholder' => trans('general.example') .'binduser@example.com', $setting->demoMode]) }}
|
{{ Form::text('ldap_uname', Request::old('ldap_uname', $setting->ldap_uname), ['class' => 'form-control','autocomplete' => 'off', 'placeholder' => trans('general.example') .'binduser@example.com', $setting->demoMode]) }}
|
||||||
{!! $errors->first('ldap_uname', '<span class="alert-msg" aria-hidden="true">:message</span>') !!}
|
{!! $errors->first('ldap_uname', '<span class="alert-msg" aria-hidden="true">:message</span>') !!}
|
||||||
@if (config('app.lock_passwords')===true)
|
@if (config('app.lock_passwords')===true)
|
||||||
<p class="text-warning"><i class="fas fa-lock" aria-hidden="true"></i> {{ trans('general.feature_disabled') }}</p>
|
<p class="text-warning"><i class="fas fa-lock" aria-hidden="true"></i> {{ trans('general.feature_disabled') }}</p>
|
||||||
|
@ -244,7 +254,7 @@
|
||||||
{{ Form::label('ldap_pword', trans('admin/settings/general.ldap_pword')) }}
|
{{ Form::label('ldap_pword', trans('admin/settings/general.ldap_pword')) }}
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-8">
|
<div class="col-md-8">
|
||||||
{{ Form::password('ldap_pword', ['class' => 'form-control','placeholder' => trans('general.example') .' binduserpassword', $setting->demoMode]) }}
|
{{ Form::password('ldap_pword', ['class' => 'form-control', 'autocomplete' => 'off', 'onfocus' => "this.removeAttribute('readonly');", $setting->demoMode, ' readonly']) }}
|
||||||
{!! $errors->first('ldap_pword', '<span class="alert-msg" aria-hidden="true">:message</span>') !!}
|
{!! $errors->first('ldap_pword', '<span class="alert-msg" aria-hidden="true">:message</span>') !!}
|
||||||
@if (config('app.lock_passwords')===true)
|
@if (config('app.lock_passwords')===true)
|
||||||
<p class="text-warning"><i class="fas fa-lock" aria-hidden="true"></i> {{ trans('general.feature_disabled') }}</p>
|
<p class="text-warning"><i class="fas fa-lock" aria-hidden="true"></i> {{ trans('general.feature_disabled') }}</p>
|
||||||
|
@ -538,7 +548,7 @@
|
||||||
<input type="text" name="ldaptest_user" id="ldaptest_user" class="form-control" placeholder="LDAP username">
|
<input type="text" name="ldaptest_user" id="ldaptest_user" class="form-control" placeholder="LDAP username">
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-4">
|
<div class="col-md-4">
|
||||||
<input type="password" name="ldaptest_password" id="ldaptest_password" class="form-control" placeholder="LDAP password">
|
<input type="password" name="ldaptest_password" id="ldaptest_password" class="form-control" placeholder="LDAP password" autocomplete="off" readonly onfocus="this.removeAttribute('readonly');">
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-3">
|
<div class="col-md-3">
|
||||||
<a class="btn btn-default btn-sm" id="ldaptestlogin" style="margin-right: 10px;">{{ trans('admin/settings/general.ldap_test') }}</a>
|
<a class="btn btn-default btn-sm" id="ldaptestlogin" style="margin-right: 10px;">{{ trans('admin/settings/general.ldap_test') }}</a>
|
||||||
|
|
68
tests/Feature/Api/Users/UpdateUserApiTest.php
Normal file
68
tests/Feature/Api/Users/UpdateUserApiTest.php
Normal file
|
@ -0,0 +1,68 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Tests\Feature\Api\Users;
|
||||||
|
|
||||||
|
use App\Models\User;
|
||||||
|
use Tests\Support\InteractsWithSettings;
|
||||||
|
use Tests\TestCase;
|
||||||
|
use Tests\Support\InteractsWithAuthentication;
|
||||||
|
|
||||||
|
|
||||||
|
class UpdateUserApiTest extends TestCase
|
||||||
|
{
|
||||||
|
use InteractsWithSettings;
|
||||||
|
use InteractsWithAuthentication;
|
||||||
|
|
||||||
|
public function testApiUsersCanBeActivatedWithNumber()
|
||||||
|
{
|
||||||
|
$admin = User::factory()->superuser()->create();
|
||||||
|
$user = User::factory()->create(['activated' => 0]);
|
||||||
|
|
||||||
|
$this->actingAsForApi($admin)
|
||||||
|
->patch(route('api.users.update', $user), [
|
||||||
|
'activated' => 1,
|
||||||
|
]);
|
||||||
|
|
||||||
|
$this->assertEquals(1, $user->refresh()->activated);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testApiUsersCanBeActivatedWithBooleanTrue()
|
||||||
|
{
|
||||||
|
$admin = User::factory()->superuser()->create();
|
||||||
|
$user = User::factory()->create(['activated' => false]);
|
||||||
|
|
||||||
|
$this->actingAsForApi($admin)
|
||||||
|
->patch(route('api.users.update', $user), [
|
||||||
|
'activated' => true,
|
||||||
|
]);
|
||||||
|
|
||||||
|
$this->assertEquals(1, $user->refresh()->activated);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testApiUsersCanBeDeactivatedWithNumber()
|
||||||
|
{
|
||||||
|
$admin = User::factory()->superuser()->create();
|
||||||
|
$user = User::factory()->create(['activated' => true]);
|
||||||
|
|
||||||
|
$this->actingAsForApi($admin)
|
||||||
|
->patch(route('api.users.update', $user), [
|
||||||
|
'activated' => 0,
|
||||||
|
]);
|
||||||
|
|
||||||
|
$this->assertEquals(0, $user->refresh()->activated);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testApiUsersCanBeDeactivatedWithBooleanFalse()
|
||||||
|
{
|
||||||
|
$admin = User::factory()->superuser()->create();
|
||||||
|
$user = User::factory()->create(['activated' => true]);
|
||||||
|
|
||||||
|
$this->actingAsForApi($admin)
|
||||||
|
->patch(route('api.users.update', $user), [
|
||||||
|
'activated' => false,
|
||||||
|
]);
|
||||||
|
|
||||||
|
$this->assertEquals(0, $user->refresh()->activated);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
namespace Tests\Feature\Api\Users;
|
namespace Tests\Feature\Api\Users;
|
||||||
|
|
||||||
|
use App\Models\Company;
|
||||||
use App\Models\User;
|
use App\Models\User;
|
||||||
use Laravel\Passport\Passport;
|
use Laravel\Passport\Passport;
|
||||||
use Tests\Support\InteractsWithSettings;
|
use Tests\Support\InteractsWithSettings;
|
||||||
|
@ -83,4 +84,67 @@ class UsersSearchTest extends TestCase
|
||||||
'Expected deleted user does not appear in results'
|
'Expected deleted user does not appear in results'
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testUsersScopedToCompanyWhenMultipleFullCompanySupportEnabled()
|
||||||
|
{
|
||||||
|
$this->settings->enableMultipleFullCompanySupport();
|
||||||
|
|
||||||
|
$companyA = Company::factory()
|
||||||
|
->has(User::factory(['first_name' => 'Company A', 'last_name' => 'User']))
|
||||||
|
->create();
|
||||||
|
|
||||||
|
Company::factory()
|
||||||
|
->has(User::factory(['first_name' => 'Company B', 'last_name' => 'User']))
|
||||||
|
->create();
|
||||||
|
|
||||||
|
$response = $this->actingAsForApi(User::factory()->for($companyA)->viewUsers()->create())
|
||||||
|
->getJson(route('api.users.index'))
|
||||||
|
->assertOk();
|
||||||
|
|
||||||
|
$results = collect($response->json('rows'));
|
||||||
|
|
||||||
|
$this->assertTrue(
|
||||||
|
$results->pluck('name')->contains(fn($text) => str_contains($text, 'Company A')),
|
||||||
|
'User index does not contain expected user'
|
||||||
|
);
|
||||||
|
$this->assertFalse(
|
||||||
|
$results->pluck('name')->contains(fn($text) => str_contains($text, 'Company B')),
|
||||||
|
'User index contains unexpected user from another company'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testUsersScopedToCompanyDuringSearchWhenMultipleFullCompanySupportEnabled()
|
||||||
|
{
|
||||||
|
$this->settings->enableMultipleFullCompanySupport();
|
||||||
|
|
||||||
|
$companyA = Company::factory()
|
||||||
|
->has(User::factory(['first_name' => 'Company A', 'last_name' => 'User']))
|
||||||
|
->create();
|
||||||
|
|
||||||
|
Company::factory()
|
||||||
|
->has(User::factory(['first_name' => 'Company B', 'last_name' => 'User']))
|
||||||
|
->create();
|
||||||
|
|
||||||
|
$response = $this->actingAsForApi(User::factory()->for($companyA)->viewUsers()->create())
|
||||||
|
->getJson(route('api.users.index', [
|
||||||
|
'deleted' => 'false',
|
||||||
|
'company_id' => null,
|
||||||
|
'search' => 'user',
|
||||||
|
'order' => 'asc',
|
||||||
|
'offset' => '0',
|
||||||
|
'limit' => '20',
|
||||||
|
]))
|
||||||
|
->assertOk();
|
||||||
|
|
||||||
|
$results = collect($response->json('rows'));
|
||||||
|
|
||||||
|
$this->assertTrue(
|
||||||
|
$results->pluck('name')->contains(fn($text) => str_contains($text, 'Company A')),
|
||||||
|
'User index does not contain expected user'
|
||||||
|
);
|
||||||
|
$this->assertFalse(
|
||||||
|
$results->pluck('name')->contains(fn($text) => str_contains($text, 'Company B')),
|
||||||
|
'User index contains unexpected user from another company'
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,10 +10,10 @@ class UpdateUserTest extends TestCase
|
||||||
{
|
{
|
||||||
use InteractsWithSettings;
|
use InteractsWithSettings;
|
||||||
|
|
||||||
public function testUsersCanBeActivated()
|
public function testUsersCanBeActivatedWithNumber()
|
||||||
{
|
{
|
||||||
$admin = User::factory()->superuser()->create();
|
$admin = User::factory()->superuser()->create();
|
||||||
$user = User::factory()->create(['activated' => false]);
|
$user = User::factory()->create(['activated' => 0]);
|
||||||
|
|
||||||
$this->actingAs($admin)
|
$this->actingAs($admin)
|
||||||
->put(route('users.update', $user), [
|
->put(route('users.update', $user), [
|
||||||
|
@ -22,10 +22,25 @@ class UpdateUserTest extends TestCase
|
||||||
'activated' => 1,
|
'activated' => 1,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$this->assertTrue($user->refresh()->activated);
|
$this->assertEquals(1, $user->refresh()->activated);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testUsersCanBeDeactivated()
|
public function testUsersCanBeActivatedWithBooleanTrue()
|
||||||
|
{
|
||||||
|
$admin = User::factory()->superuser()->create();
|
||||||
|
$user = User::factory()->create(['activated' => false]);
|
||||||
|
|
||||||
|
$this->actingAs($admin)
|
||||||
|
->put(route('users.update', $user), [
|
||||||
|
'first_name' => $user->first_name,
|
||||||
|
'username' => $user->username,
|
||||||
|
'activated' => true,
|
||||||
|
]);
|
||||||
|
|
||||||
|
$this->assertEquals(1, $user->refresh()->activated);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testUsersCanBeDeactivatedWithNumber()
|
||||||
{
|
{
|
||||||
$admin = User::factory()->superuser()->create();
|
$admin = User::factory()->superuser()->create();
|
||||||
$user = User::factory()->create(['activated' => true]);
|
$user = User::factory()->create(['activated' => true]);
|
||||||
|
@ -34,12 +49,25 @@ class UpdateUserTest extends TestCase
|
||||||
->put(route('users.update', $user), [
|
->put(route('users.update', $user), [
|
||||||
'first_name' => $user->first_name,
|
'first_name' => $user->first_name,
|
||||||
'username' => $user->username,
|
'username' => $user->username,
|
||||||
// checkboxes that are not checked are
|
'activated' => 0,
|
||||||
// not included in the request payload
|
|
||||||
// 'activated' => 0,
|
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$this->assertFalse($user->refresh()->activated);
|
$this->assertEquals(0, $user->refresh()->activated);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testUsersCanBeDeactivatedWithBooleanFalse()
|
||||||
|
{
|
||||||
|
$admin = User::factory()->superuser()->create();
|
||||||
|
$user = User::factory()->create(['activated' => true]);
|
||||||
|
|
||||||
|
$this->actingAs($admin)
|
||||||
|
->put(route('users.update', $user), [
|
||||||
|
'first_name' => $user->first_name,
|
||||||
|
'username' => $user->username,
|
||||||
|
'activated' => false,
|
||||||
|
]);
|
||||||
|
|
||||||
|
$this->assertEquals(0, $user->refresh()->activated);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testUsersUpdatingThemselvesDoNotDeactivateTheirAccount()
|
public function testUsersUpdatingThemselvesDoNotDeactivateTheirAccount()
|
||||||
|
@ -50,12 +78,8 @@ class UpdateUserTest extends TestCase
|
||||||
->put(route('users.update', $admin), [
|
->put(route('users.update', $admin), [
|
||||||
'first_name' => $admin->first_name,
|
'first_name' => $admin->first_name,
|
||||||
'username' => $admin->username,
|
'username' => $admin->username,
|
||||||
// checkboxes that are disabled are not
|
|
||||||
// included in the request payload
|
|
||||||
// even if they are checked
|
|
||||||
// 'activated' => 0,
|
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$this->assertTrue($admin->refresh()->activated);
|
$this->assertEquals(1, $admin->refresh()->activated);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue