Compare commits
45 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| b9e19468e5 | |||
| 5b68a321a6 | |||
| 37568ae9ec | |||
| 32ad9050cf | |||
| 01a832169c | |||
| 3c6883489c | |||
| bcad49ce79 | |||
| b5acca89d7 | |||
| e52919cf1b | |||
| 29f3a5c48f | |||
| 134e8e6fb9 | |||
| 714576be45 | |||
| 5128992940 | |||
| 0291323502 | |||
| e0f6f9b839 | |||
| f1a6308002 | |||
| b999c50a2e | |||
| e3906b245c | |||
| 9ca20e4964 | |||
| 456a74d88c | |||
| 799c059070 | |||
| c62d43a778 | |||
| b725bd0fae | |||
| e0644dbbf6 | |||
| 5b6925b00c | |||
| df17a859bf | |||
| 24c43056ba | |||
| 606b7e905d | |||
| d73ddad477 | |||
| 9a39cf721e | |||
| 7410b16835 | |||
| 8994f3e15e | |||
| d23f1a77ca | |||
| e955c983a3 | |||
| b09e7d19b3 | |||
| 2fa17ac185 | |||
| 3b1e46f72b | |||
| 0c1a1de2a2 | |||
| 20c9ae5818 | |||
| eed41e4549 | |||
| b750f4754f | |||
| c17a06792a | |||
| 4f76cc6cfb | |||
| b905154373 | |||
| 004ecad059 |
@@ -0,0 +1,40 @@
|
||||
# Description
|
||||
|
||||
Please include a summary of the change and which issue is fixed. Please also include relevant motivation and context, providing screenshots where practical. List any dependencies that are required for this change.
|
||||
|
||||
Fixes # (issue)
|
||||
|
||||
## Type of change
|
||||
|
||||
Please delete options that are not relevant.
|
||||
|
||||
- [ ] Bug fix (non-breaking change which fixes an issue)
|
||||
- [ ] New feature (non-breaking change which adds functionality)
|
||||
- [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected)
|
||||
- [ ] This change requires a documentation update
|
||||
|
||||
# How Has This Been Tested?
|
||||
|
||||
Please describe the tests that you ran to verify your changes. Provide instructions so we can reproduce. Please also list any relevant details for your test configuration
|
||||
|
||||
- [ ] Test A
|
||||
- [ ] Test B
|
||||
|
||||
**Test Configuration**:
|
||||
* PHP version:
|
||||
* MySQL version
|
||||
* Webserver version
|
||||
* OS version
|
||||
|
||||
|
||||
# Checklist:
|
||||
|
||||
- [ ] I have read the Contributing documentation available here: https://snipe-it.readme.io/docs/contributing-overview
|
||||
- [ ] I have formatted this PR according to the project guidelines: https://snipe-it.readme.io/docs/contributing-overview#pull-request-guidelines
|
||||
- [ ] My code follows the style guidelines of this project
|
||||
- [ ] I have performed a self-review of my own code
|
||||
- [ ] I have commented my code, particularly in hard-to-understand areas
|
||||
- [ ] I have made corresponding changes to the documentation
|
||||
- [ ] My changes generate no new warnings
|
||||
- [ ] I have added tests that prove my fix is effective or that my feature works
|
||||
- [ ] New and existing unit tests pass locally with my changes
|
||||
@@ -0,0 +1,95 @@
|
||||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use App\Models\LicenseSeat;
|
||||
use Illuminate\Console\Command;
|
||||
use App\Models\User;
|
||||
use App\Models\License;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class CheckinLicensesFromAllUsers extends Command
|
||||
{
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'snipeit:checkin-from-all {--license_id=} {--notify}';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Checks in licenses from all users';
|
||||
|
||||
/**
|
||||
* Create a new command instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
|
||||
$license_id = $this->option('license_id');
|
||||
$notify = $this->option('notify');
|
||||
|
||||
if (!$license_id) {
|
||||
$this->error('ERROR: License ID is required.');
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
if (!$license = License::where('id','=',$license_id)->first()) {
|
||||
$this->error('Invalid license ID');
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->info('Checking in ALL seats for '.$license->name);
|
||||
|
||||
|
||||
$licenseSeats = LicenseSeat::where('license_id', '=', $license_id)
|
||||
->whereNotNull('assigned_to')
|
||||
->with('user')
|
||||
->get();
|
||||
|
||||
$this->info(' There are ' .$licenseSeats->count(). ' seats checked out: ');
|
||||
|
||||
if (!$notify) {
|
||||
$this->info('No mail will be sent.');
|
||||
}
|
||||
|
||||
foreach ($licenseSeats as $seat) {
|
||||
$this->info($seat->user->username .' has a license seat for '.$license->name);
|
||||
$seat->assigned_to = null;
|
||||
|
||||
if ($seat->save()) {
|
||||
|
||||
// Override the email address so we don't notify on checkin
|
||||
if (!$notify) {
|
||||
$seat->user->email = null;
|
||||
}
|
||||
|
||||
// Log the checkin
|
||||
$seat->logCheckin($seat->user, 'Checked in via cli tool');
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -124,7 +124,16 @@ class LdapSync extends Command
|
||||
|
||||
// Grab subsets based on location-specific DNs, and overwrite location for these users.
|
||||
foreach ($ldap_ou_locations as $ldap_loc) {
|
||||
$location_users = Ldap::findLdapUsers($ldap_loc["ldap_ou"]);
|
||||
try {
|
||||
$location_users = Ldap::findLdapUsers($ldap_loc["ldap_ou"]);
|
||||
} catch (\Exception $e) { // FIXME: this is stolen from line 77 or so above
|
||||
if ($this->option('json_summary')) {
|
||||
$json_summary = [ "error" => true, "error_message" => trans('admin/users/message.error.ldap_could_not_search')." Location: ".$ldap_loc['name']." (ID: ".$ldap_loc['id'].") cannot connect to \"".$ldap_loc["ldap_ou"]."\" - ".$e->getMessage(), "summary" => [] ];
|
||||
$this->info(json_encode($json_summary));
|
||||
}
|
||||
LOG::info($e);
|
||||
return [];
|
||||
}
|
||||
$usernames = array();
|
||||
for ($i = 0; $i < $location_users["count"]; $i++) {
|
||||
|
||||
@@ -187,8 +196,33 @@ class LdapSync extends Command
|
||||
|
||||
// Sync activated state for Active Directory.
|
||||
if ( array_key_exists('useraccountcontrol', $results[$i]) ) {
|
||||
/* The following is _probably_ the correct logic, but we can't use it because
|
||||
some users may have been dependent upon the previous behavior, and this
|
||||
could cause additional access to be available to users they don't want
|
||||
to allow to log in.
|
||||
|
||||
$useraccountcontrol = $results[$i]['useraccountcontrol'][0];
|
||||
if(
|
||||
// based on MS docs at: https://support.microsoft.com/en-us/help/305144/how-to-use-useraccountcontrol-to-manipulate-user-account-properties
|
||||
($useraccountcontrol & 0x200) && // is a NORMAL_ACCOUNT
|
||||
!($useraccountcontrol & 0x02) && // *and* _not_ ACCOUNTDISABLE
|
||||
!($useraccountcontrol & 0x10) // *and* _not_ LOCKOUT
|
||||
) {
|
||||
$user->activated = 1;
|
||||
} else {
|
||||
$user->activated = 0;
|
||||
} */
|
||||
$enabled_accounts = [
|
||||
'512', '544', '66048', '66080', '262656', '262688', '328192', '328224', '4260352'
|
||||
'512', // 0x200 NORMAL_ACCOUNT
|
||||
'544', // 0x220 NORMAL_ACCOUNT, PASSWD_NOTREQD
|
||||
'66048', // 0x10200 NORMAL_ACCOUNT, DONT_EXPIRE_PASSWORD
|
||||
'66080', // 0x10220 NORMAL_ACCOUNT, PASSWD_NOTREQD, DONT_EXPIRE_PASSWORD
|
||||
'262656', // 0x40200 NORMAL_ACCOUNT, SMARTCARD_REQUIRED
|
||||
'262688', // 0x40220 NORMAL_ACCOUNT, PASSWD_NOTREQD, SMARTCARD_REQUIRED
|
||||
'328192', // 0x50200 NORMAL_ACCOUNT, SMARTCARD_REQUIRED, DONT_EXPIRE_PASSWORD
|
||||
'328224', // 0x50220 NORMAL_ACCOUNT, PASSWD_NOT_REQD, SMARTCARD_REQUIRED, DONT_EXPIRE_PASSWORD
|
||||
'4260352',// 0x410200 NORMAL_ACCOUNT, DONT_EXPIRE_PASSWORD, DONT_REQ_PREAUTH
|
||||
'1049088',// 0x100200 NORMAL_ACCOUNT, NOT_DELEGATED
|
||||
];
|
||||
$user->activated = ( in_array($results[$i]['useraccountcontrol'][0], $enabled_accounts) ) ? 1 : 0;
|
||||
}
|
||||
@@ -239,7 +273,7 @@ class LdapSync extends Command
|
||||
}
|
||||
}
|
||||
} else if ($this->option('json_summary')) {
|
||||
$json_summary = [ "error" => false, "error_message" => "", "summary" => $summary ];
|
||||
$json_summary = [ "error" => false, "error_message" => "", "summary" => $summary ]; // hardcoding the error to false and the error_message to blank seems a bit weird
|
||||
$this->info(json_encode($json_summary));
|
||||
} else {
|
||||
return $summary;
|
||||
|
||||
@@ -6,6 +6,7 @@ use Illuminate\Http\Request;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Company;
|
||||
use App\Models\Consumable;
|
||||
use App\Models\User;
|
||||
use App\Http\Transformers\ConsumablesTransformer;
|
||||
use App\Helpers\Helper;
|
||||
|
||||
@@ -157,7 +158,7 @@ class ConsumablesController extends Controller
|
||||
return response()->json(Helper::formatStandardApiResponse('success', null, trans('admin/consumables/message.delete.success')));
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* Returns a JSON response containing details on the users associated with this consumable.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
@@ -196,4 +197,55 @@ class ConsumablesController extends Controller
|
||||
$data = array('total' => $consumableCount, 'rows' => $rows);
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checkout a consumable
|
||||
*
|
||||
* @author [A. Gutierrez] [<andres@baller.tv>]
|
||||
* @param int $id
|
||||
* @since [v4.9.5]
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function checkout(Request $request, $id)
|
||||
{
|
||||
// Check if the consumable exists
|
||||
if (is_null($consumable = Consumable::find($id))) {
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, trans('admin/consumables/message.does_not_exist')));
|
||||
}
|
||||
|
||||
$this->authorize('checkout', $consumable);
|
||||
|
||||
if ($consumable->qty > 0) {
|
||||
|
||||
// Check if the user exists
|
||||
$assigned_to = $request->input('assigned_to');
|
||||
if (is_null($user = User::find($assigned_to))) {
|
||||
// Return error message
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, 'No user found'));
|
||||
}
|
||||
|
||||
// Update the consumable data
|
||||
$consumable->assigned_to = e($assigned_to);
|
||||
|
||||
$consumable->users()->attach($consumable->id, [
|
||||
'consumable_id' => $consumable->id,
|
||||
'user_id' => $user->id,
|
||||
'assigned_to' => $assigned_to
|
||||
]);
|
||||
|
||||
// Log checkout event
|
||||
$logaction = $consumable->logCheckout(e($request->input('note')), $user);
|
||||
$data['log_id'] = $logaction->id;
|
||||
$data['eula'] = $consumable->getEula();
|
||||
$data['first_name'] = $user->first_name;
|
||||
$data['item_name'] = $consumable->name;
|
||||
$data['checkout_date'] = $logaction->created_at;
|
||||
$data['note'] = $logaction->note;
|
||||
$data['require_acceptance'] = $consumable->requireAcceptance();
|
||||
|
||||
return response()->json(Helper::formatStandardApiResponse('success', null, trans('admin/consumables/message.checkout.success')));
|
||||
}
|
||||
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, 'No consumables remaining'));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -209,7 +209,7 @@ class StatuslabelsController extends Controller
|
||||
{
|
||||
$this->authorize('view', Statuslabel::class);
|
||||
$this->authorize('index', Asset::class);
|
||||
$assets = Asset::where('status_id','=',$id);
|
||||
$assets = Asset::where('status_id','=',$id)->with('assignedTo');
|
||||
|
||||
$allowed_columns = [
|
||||
'id',
|
||||
|
||||
@@ -102,7 +102,7 @@ class ReportsController extends Controller
|
||||
|
||||
$depreciations = Depreciation::get();
|
||||
// Grab all the assets
|
||||
$assets = Asset::with( 'assignedTo', 'assetstatus', 'defaultLoc', 'location', 'assetlog', 'company', 'model.category', 'model.depreciation')
|
||||
$assets = Asset::with( 'assignedTo', 'assetstatus', 'defaultLoc', 'location', 'company', 'model.category', 'model.depreciation')
|
||||
->orderBy('created_at', 'DESC')->get();
|
||||
|
||||
return view('reports/depreciation', compact('assets'))->with('depreciations',$depreciations);
|
||||
|
||||
@@ -435,6 +435,10 @@ class UsersController extends Controller
|
||||
if ($request->filled('department_id')) {
|
||||
$update_array['department_id'] = $request->input('department_id');
|
||||
}
|
||||
if ($request->filled('city')) {
|
||||
$update_array['city'] = $request->input('city');
|
||||
}
|
||||
|
||||
if ($request->filled('company_id')) {
|
||||
$update_array['company_id'] = $request->input('company_id');
|
||||
}
|
||||
|
||||
@@ -106,7 +106,7 @@ class SecurityHeaders
|
||||
$csp_policy[] = "connect-src 'self'";
|
||||
$csp_policy[] = "object-src 'none'";
|
||||
$csp_policy[] = "font-src 'self' data:";
|
||||
$csp_policy[] = "img-src 'self' data: gravatar.com";
|
||||
$csp_policy[] = "img-src 'self' data: gravatar.com maps.google.com maps.gstatic.com *.googleapis.com";
|
||||
$csp_policy = join(';', $csp_policy);
|
||||
$response->headers->set('Content-Security-Policy', $csp_policy);
|
||||
}
|
||||
|
||||
@@ -63,6 +63,10 @@ abstract class Importer
|
||||
'full_name' => 'full name',
|
||||
'email' => 'email',
|
||||
'username' => 'username',
|
||||
'address' => 'address',
|
||||
'city' => 'city',
|
||||
'state' => 'state',
|
||||
'country' => 'country',
|
||||
'jobtitle' => 'job title',
|
||||
'employee_num' => 'employee number',
|
||||
'phone_number' => 'phone number',
|
||||
|
||||
@@ -47,6 +47,10 @@ class UserImporter extends ItemImporter
|
||||
$this->item['email'] = $this->findCsvMatch($row, 'email');
|
||||
$this->item['phone'] = $this->findCsvMatch($row, 'phone_number');
|
||||
$this->item['jobtitle'] = $this->findCsvMatch($row, 'jobtitle');
|
||||
$this->item['address'] = $this->findCsvMatch($row, 'address');
|
||||
$this->item['city'] = $this->findCsvMatch($row, 'city');
|
||||
$this->item['state'] = $this->findCsvMatch($row, 'state');
|
||||
$this->item['country'] = $this->findCsvMatch($row, 'country');
|
||||
$this->item['activated'] = ($this->fetchHumanBoolean($this->findCsvMatch($row, 'activated')) == 1) ? '1' : 0;
|
||||
|
||||
\Log::debug('UserImporter.php Activated: '.$this->findCsvMatch($row, 'activated'));
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
| licensed to email | license_email | License |
|
||||
| licensed to name | license_name | License |
|
||||
| maintained | maintained | License |
|
||||
| manager_id | | User |
|
||||
| manager_id | | User |
|
||||
| manufacturer | manufacturer | All |
|
||||
| model name | asset_model | Asset |
|
||||
| model number | model_number | Asset |
|
||||
@@ -34,4 +34,8 @@
|
||||
| User Related Fields | assigned_to | Asset |
|
||||
| name | | |
|
||||
| username | | |
|
||||
| address | address | User |
|
||||
| city | city | User |
|
||||
| state | state | User |
|
||||
| country | country | User |
|
||||
|
||||
|
||||
+3
-3
@@ -265,13 +265,13 @@ class Ldap extends Model
|
||||
$search_results = ldap_search($ldapconn, $base_dn, '('.$filter.')');
|
||||
|
||||
if (!$search_results) {
|
||||
return redirect()->route('users.index')->with('error', trans('admin/users/message.error.ldap_could_not_search').ldap_error($ldapconn));
|
||||
return redirect()->route('users.index')->with('error', trans('admin/users/message.error.ldap_could_not_search').ldap_error($ldapconn)); // FIXME this is never called in any routed context - only from the Artisan command. So this redirect will never work.
|
||||
}
|
||||
|
||||
// Get results from page
|
||||
$results = ldap_get_entries($ldapconn, $search_results);
|
||||
if (!$results) {
|
||||
return redirect()->route('users.index')->with('error', trans('admin/users/message.error.ldap_could_not_get_entries').ldap_error($ldapconn));
|
||||
return redirect()->route('users.index')->with('error', trans('admin/users/message.error.ldap_could_not_get_entries').ldap_error($ldapconn)); // FIXME this is never called in any routed context - only from the Artisan command. So this redirect will never work.
|
||||
}
|
||||
|
||||
// Add results to result set
|
||||
@@ -286,7 +286,7 @@ class Ldap extends Model
|
||||
// Clean up after search
|
||||
$result_set['count'] = $global_count;
|
||||
$results = $result_set;
|
||||
ldap_control_paged_result($ldapconn, 0);
|
||||
@ldap_control_paged_result($ldapconn, 0);
|
||||
|
||||
return $results;
|
||||
|
||||
|
||||
+19
-4
@@ -41,8 +41,9 @@ trait Loggable
|
||||
$settings = Setting::getSettings();
|
||||
$log = new Actionlog;
|
||||
$log = $this->determineLogItemType($log);
|
||||
if(Auth::user())
|
||||
if (Auth::user()) {
|
||||
$log->user_id = Auth::user()->id;
|
||||
}
|
||||
|
||||
if (!isset($target)) {
|
||||
throw new \Exception('All checkout logs require a target.');
|
||||
@@ -144,7 +145,11 @@ trait Loggable
|
||||
|
||||
$log->location_id = null;
|
||||
$log->note = $note;
|
||||
$log->user_id = Auth::user()->id;
|
||||
|
||||
if (Auth::user()) {
|
||||
$log->user_id = Auth::user()->id;
|
||||
}
|
||||
|
||||
$log->logaction('checkin from');
|
||||
|
||||
$params = [
|
||||
@@ -160,14 +165,24 @@ trait Loggable
|
||||
$checkinClass = null;
|
||||
|
||||
if (method_exists($target, 'notify')) {
|
||||
$target->notify(new static::$checkinClass($params));
|
||||
try {
|
||||
$target->notify(new static::$checkinClass($params));
|
||||
} catch (\Exception $e) {
|
||||
\Log::debug($e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Send to the admin, if settings dictate
|
||||
$recipient = new \App\Models\Recipients\AdminRecipient();
|
||||
|
||||
if (($settings->admin_cc_email!='') && (static::$checkinClass!='')) {
|
||||
$recipient->notify(new static::$checkinClass($params));
|
||||
try {
|
||||
$recipient->notify(new static::$checkinClass($params));
|
||||
} catch (\Exception $e) {
|
||||
\Log::debug($e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return $log;
|
||||
|
||||
@@ -379,6 +379,18 @@ class User extends SnipeModel implements AuthenticatableContract, CanResetPasswo
|
||||
} elseif ($format=='firstname') {
|
||||
$username = str_slug($first_name);
|
||||
}
|
||||
elseif ($format=='firstinitial.lastname') {
|
||||
$username = str_slug(substr($first_name, 0, 1). '.' . str_slug($last_name));
|
||||
}
|
||||
elseif ($format=='lastname_firstinitial') {
|
||||
$username = str_slug($last_name).'_'.str_slug(substr($first_name, 0, 1));
|
||||
}
|
||||
elseif ($format=='firstnamelastname') {
|
||||
$username = str_slug($first_name) . str_slug($last_name);
|
||||
}
|
||||
elseif ($format=='firstnamelastinitial') {
|
||||
$username = str_slug(($first_name.substr($last_name, 0, 1)));
|
||||
}
|
||||
}
|
||||
|
||||
$user['first_name'] = $first_name;
|
||||
|
||||
@@ -76,10 +76,18 @@ class CheckinLicenseNotification extends Notification
|
||||
$botname = ($this->settings->slack_botname) ? $this->settings->slack_botname : 'Snipe-Bot' ;
|
||||
|
||||
|
||||
$fields = [
|
||||
'To' => '<'.$target->present()->viewUrl().'|'.$target->present()->fullName().'>',
|
||||
'By' => '<'.$admin->present()->viewUrl().'|'.$admin->present()->fullName().'>',
|
||||
];
|
||||
if ($admin) {
|
||||
$fields = [
|
||||
'To' => '<'.$target->present()->viewUrl().'|'.$target->present()->fullName().'>',
|
||||
'By' => '<'.$admin->present()->viewUrl().'|'.$admin->present()->fullName().'>',
|
||||
];
|
||||
} else {
|
||||
$fields = [
|
||||
'To' => '<'.$target->present()->viewUrl().'|'.$target->present()->fullName().'>',
|
||||
'By' => 'CLI tool',
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
+6
-6
@@ -1,10 +1,10 @@
|
||||
<?php
|
||||
return array (
|
||||
'app_version' => 'v4.9.4',
|
||||
'full_app_version' => 'v4.9.4 - build 4437-g799a93c46',
|
||||
'build_version' => '4437',
|
||||
'app_version' => 'v4.9.5',
|
||||
'full_app_version' => 'v4.9.5 - build 4482-g5b68a321a',
|
||||
'build_version' => '4482',
|
||||
'prerelease_version' => '',
|
||||
'hash_version' => 'g799a93c46',
|
||||
'full_hash' => 'v4.9.4-41-g799a93c46',
|
||||
'hash_version' => 'g5b68a321a',
|
||||
'full_hash' => 'v4.9.5-44-g5b68a321a',
|
||||
'branch' => 'master',
|
||||
);
|
||||
);
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Vendored
+27
-27
File diff suppressed because one or more lines are too long
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"/js/build/vue.js": "/js/build/vue.js?id=461ae9803574a5a52d43",
|
||||
"/js/build/vue.js": "/js/build/vue.js?id=aff26ce7202625817ca1",
|
||||
"/css/AdminLTE.css": "/css/AdminLTE.css?id=56b8066cfbc70df10545",
|
||||
"/css/app.css": "/css/app.css?id=407edb63cc6b6dc62405",
|
||||
"/css/overrides.css": "/css/overrides.css?id=d1fe6296eb548247a5ad",
|
||||
@@ -18,7 +18,7 @@
|
||||
"/css/skins/skin-blue-dark.css": "/css/skins/skin-blue-dark.css?id=d25c77d9c6f4cfe2efd4",
|
||||
"/css/skins/skin-orange-dark.css": "/css/skins/skin-orange-dark.css?id=abc219c1fed59cecb860",
|
||||
"/css/skins/skin-orange.css": "/css/skins/skin-orange.css?id=59664dbd286988d2a438",
|
||||
"/js/build/vue.js.map": "/js/build/vue.js.map?id=1760ae00d44238e44172",
|
||||
"/js/build/vue.js.map": "/js/build/vue.js.map?id=41a870ef3b9b5c6688ca",
|
||||
"/css/AdminLTE.css.map": "/css/AdminLTE.css.map?id=5a2d6f3c59191ce716e2",
|
||||
"/css/app.css.map": "/css/app.css.map?id=96b5c985e860716e6a16",
|
||||
"/css/overrides.css.map": "/css/overrides.css.map?id=f3e3cf42859eb4a28a7b",
|
||||
@@ -38,7 +38,7 @@
|
||||
"/css/skins/skin-orange-dark.css.map": "/css/skins/skin-orange-dark.css.map?id=68b998638217fd08ef29",
|
||||
"/css/skins/skin-orange.css.map": "/css/skins/skin-orange.css.map?id=f90fda3cc0a48c048a9e",
|
||||
"/css/dist/all.css": "/css/dist/all.css?id=0491555899142b86167d",
|
||||
"/js/dist/all.js": "/js/dist/all.js?id=4513ccdd4533b52922a8",
|
||||
"/js/dist/all.js": "/js/dist/all.js?id=5ac062af7b26fb838213",
|
||||
"/css/build/all.css": "/css/build/all.css?id=0491555899142b86167d",
|
||||
"/js/build/all.js": "/js/build/all.js?id=4513ccdd4533b52922a8"
|
||||
"/js/build/all.js": "/js/build/all.js?id=5ac062af7b26fb838213"
|
||||
}
|
||||
|
||||
@@ -169,6 +169,10 @@
|
||||
{id: 'manager_first_name', text: 'Manager First Name' },
|
||||
{id: 'manager_last_name', text: 'Manager Last Name' },
|
||||
{id: 'activated', text: 'Activated' },
|
||||
{id: 'address', text: 'Address' },
|
||||
{id: 'city', text: 'City' },
|
||||
{id: 'state', text: 'State' },
|
||||
{id: 'country', text: 'Country' },
|
||||
|
||||
],
|
||||
customFields: this.customFields,
|
||||
|
||||
@@ -88,6 +88,9 @@
|
||||
'firstname_lastname_underscore_format' => 'First Name Last Name (jane_smith@example.com)',
|
||||
'lastnamefirstinitial_format' => 'Last Name First Initial (smithj@example.com)',
|
||||
'first' => 'First',
|
||||
'firstnamelastname' => 'First Name Last Name (janesmith@example.com)',
|
||||
'lastname_firstinitial' => 'Last Name First Initial (smith_j@example.com)',
|
||||
'firstinitial.lastname' => 'First Initial Last Name (j.smith@example.com)', 'first' => 'First',
|
||||
'first_name' => 'First Name',
|
||||
'first_name_format' => 'First Name (jane@example.com)',
|
||||
'files' => 'Files',
|
||||
|
||||
@@ -8,6 +8,7 @@ return array(
|
||||
'owner_doesnt_match_asset' => 'The asset you are trying to associate with this license is owned by somene other than the person selected in the assigned to dropdown.',
|
||||
'assoc_users' => 'This license is currently checked out to a user and cannot be deleted. Please check the license in first, and then try deleting again. ',
|
||||
'select_asset_or_person' => 'You must select an asset or a user, but not both.',
|
||||
'not_found' => 'License not found',
|
||||
|
||||
|
||||
'create' => array(
|
||||
|
||||
@@ -88,6 +88,11 @@
|
||||
'firstname_lastname_underscore_format' => 'First Name Last Name (jane_smith@example.com)',
|
||||
'lastnamefirstinitial_format' => 'Last Name First Initial (smithj@example.com)',
|
||||
'first' => 'First',
|
||||
'firstnamelastname' => 'First Name Last Name (janesmith@example.com)',
|
||||
'lastname_firstinitial' => 'Last Name First Initial (smith_j@example.com)',
|
||||
'firstinitial.lastname' => 'First Initial Last Name (j.smith@example.com)',
|
||||
'firstnamelastinitial' => 'First Name Last Initial (janes@example.com)',
|
||||
'first' => 'First',
|
||||
'first_name' => 'First Name',
|
||||
'first_name_format' => 'First Name (jane@example.com)',
|
||||
'files' => 'Files',
|
||||
|
||||
@@ -469,7 +469,10 @@ Form::macro('username_format', function ($name = "username_format", $selected =
|
||||
'filastname' => trans('general.filastname_format'),
|
||||
'lastnamefirstinitial' => trans('general.lastnamefirstinitial_format'),
|
||||
'firstname_lastname' => trans('general.firstname_lastname_underscore_format'),
|
||||
|
||||
'firstinitial.lastname' => trans('general.firstinitial.lastname'),
|
||||
'lastname_firstinitial' => trans('general.lastname_firstinitial'),
|
||||
'firstnamelastname' => trans('general.firstnamelastname'),
|
||||
'firstnamelastinitial' => trans('general.firstnamelastinitial')
|
||||
);
|
||||
|
||||
$select = '<select name="'.$name.'" class="'.$class.'" style="width: 100%" aria-label="'.$name.'">';
|
||||
|
||||
@@ -829,6 +829,7 @@
|
||||
|
||||
|
||||
<script src="{{ url(mix('js/dist/all.js')) }}" nonce="{{ csrf_token() }}"></script>
|
||||
<script src="/js/pGenerator.jquery.js"></script>
|
||||
|
||||
@section('moar_scripts')
|
||||
@show
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
{{-- See snipeit_modals.js for what powers this --}}
|
||||
<script src="/js/pGenerator.jquery.js"></script>
|
||||
|
||||
|
||||
<script nonce="{{ csrf_token() }}">
|
||||
$(document).ready(function () {
|
||||
|
||||
$('#genPassword').pGenerator({
|
||||
window.setTimeout(function () {
|
||||
$('#modal-genPassword').pGenerator({
|
||||
'bind': 'click',
|
||||
'passwordElement': '#modal-password',
|
||||
'displayElement': '#generated-password',
|
||||
'displayElement': '#modal-generated-password',
|
||||
'passwordLength': 16,
|
||||
'uppercase': true,
|
||||
'lowercase': true,
|
||||
@@ -17,13 +17,14 @@
|
||||
$('#modal-password_confirmation').val($('#modal-password').val());
|
||||
}
|
||||
});
|
||||
});
|
||||
}, 1000);
|
||||
</script>
|
||||
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
|
||||
<h2 class="modal-title">{{ trans('admin/users/table.createuser') }}</h4>
|
||||
<h2 class="modal-title">{{ trans('admin/users/table.createuser') }}</h2>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<form action="{{ route('api.users.store') }}" onsubmit="return false">
|
||||
@@ -47,14 +48,14 @@
|
||||
<div class="dynamic-form-row">
|
||||
<div class="col-md-4 col-xs-12"><label for="modal-password">{{ trans('admin/users/table.password') }}:</label></div>
|
||||
<div class="col-md-8 col-xs-12 required"><input type='password' name="password" id='modal-password' class="form-control">
|
||||
<a href="#" class="left" id="genPassword">Generate</a>
|
||||
<a href="#" class="left" id="modal-genPassword">Generate</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="dynamic-form-row">
|
||||
<div class="col-md-4 col-xs-12"><label for="modal-password_confirmation">{{ trans('admin/users/table.password_confirm') }}:</label></div>
|
||||
<div class="col-md-8 col-xs-12 required"><input type='password' name="password_confirmation" id='modal-password_confirmation' class="form-control">
|
||||
<div id="generated-password"></div>
|
||||
<div id="modal-generated-password"></div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
}'>
|
||||
<thead>
|
||||
<tr>
|
||||
<th data-field="company" data-sortable="false" data-visible="false">{{ trans('admin/companies/table.title') }}</th>
|
||||
<th data-field="company" data-sortable="false" data-visible="false" data-formatter="companiesLinkObjFormatter">{{ trans('admin/companies/table.title') }}</th>
|
||||
<th data-sortable="true" data-field="id" data-visible="false">{{ trans('general.id') }}</th>
|
||||
<th data-sortable="false" data-field="asset_name" data-formatter="assetNameLinkFormatter">{{ trans('admin/asset_maintenances/table.asset_name') }}</th>
|
||||
<th data-sortable="false" data-field="supplier" data-formatter="suppliersLinkObjFormatter">{{ trans('general.supplier') }}</th>
|
||||
|
||||
@@ -55,6 +55,15 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- City -->
|
||||
<div class="form-group{{ $errors->has('city') ? ' has-error' : '' }}">
|
||||
<label class="col-md-3 control-label" for="city">{{ trans('general.city') }}</label>
|
||||
<div class="col-md-4">
|
||||
<input class="form-control" type="text" name="city" id="city" aria-label="city" />
|
||||
{!! $errors->first('city', '<span class="alert-msg" aria-hidden="true">:message</span>') !!}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- activated -->
|
||||
<div class="form-group">
|
||||
<div class="col-sm-3 control-label">
|
||||
|
||||
@@ -610,7 +610,6 @@
|
||||
@stop
|
||||
|
||||
@section('moar_scripts')
|
||||
<script src="{{ asset('js/pGenerator.jquery.js') }}"></script>
|
||||
|
||||
<script nonce="{{ csrf_token() }}">
|
||||
$(document).ready(function() {
|
||||
|
||||
@@ -142,11 +142,31 @@
|
||||
<td class="text-nowrap">{{ trans('admin/users/table.name') }}</td>
|
||||
<td>{{ $user->present()->fullName() }}</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td class="text-nowrap">{{ trans('admin/users/table.username') }}</td>
|
||||
<td>{{ $user->username }}</td>
|
||||
</tr>
|
||||
@if (($user->address) || ($user->city) || ($user->state) || ($user->country))
|
||||
<tr>
|
||||
<td class="text-nowrap">{{ trans('general.address') }}</td>
|
||||
<td>
|
||||
@if ($user->address)
|
||||
{{ $user->address }} <br>
|
||||
@endif
|
||||
@if ($user->city)
|
||||
{{ $user->city }}
|
||||
@endif
|
||||
@if ($user->state)
|
||||
{{ $user->state }}
|
||||
@endif
|
||||
@if ($user->country)
|
||||
{{ $user->country }}
|
||||
@endif
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
@endif
|
||||
<tr>
|
||||
<td class="text-nowrap">{{ trans('general.groups') }}</td>
|
||||
<td>
|
||||
@@ -285,6 +305,13 @@
|
||||
|
||||
@endif
|
||||
|
||||
@if ($user->notes)
|
||||
<tr>
|
||||
<td class="text-nowrap">{{ trans('admin/users/table.notes') }}</td>
|
||||
<td>{{ $user->notes }}</td>
|
||||
</tr>
|
||||
@endif
|
||||
|
||||
|
||||
</table>
|
||||
</div>
|
||||
@@ -297,7 +324,7 @@
|
||||
<a href="{{ route('users.edit', $user->id) }}" style="width: 100%;" class="btn btn-sm btn-primary hidden-print">{{ trans('admin/users/general.edit') }}</a>
|
||||
</div>
|
||||
@endcan
|
||||
|
||||
|
||||
@can('create', $user)
|
||||
<div class="col-md-12" style="padding-top: 5px;">
|
||||
<a href="{{ route('clone/user', $user->id) }}" style="width: 100%;" class="btn btn-sm btn-primary hidden-print">{{ trans('admin/users/general.clone') }}</a>
|
||||
|
||||
+16
-7
@@ -189,7 +189,6 @@ Route::group(['prefix' => 'v1','namespace' => 'Api', 'middleware' => 'api'], fun
|
||||
|
||||
|
||||
/*--- Consumables API ---*/
|
||||
|
||||
Route::resource('consumables', 'ConsumablesController',
|
||||
[
|
||||
'names' =>
|
||||
@@ -204,12 +203,22 @@ Route::group(['prefix' => 'v1','namespace' => 'Api', 'middleware' => 'api'], fun
|
||||
'parameters' => ['consumable' => 'consumable_id']
|
||||
]
|
||||
); // Consumables resource
|
||||
Route::get('consumables/view/{id}/users',
|
||||
[
|
||||
'as' => 'api.consumables.showUsers',
|
||||
'uses' => 'ConsumablesController@getDataView'
|
||||
]
|
||||
);
|
||||
|
||||
Route::group(['prefix' => 'consumables'], function () {
|
||||
Route::get('view/{id}/users',
|
||||
[
|
||||
'as' => 'api.consumables.showUsers',
|
||||
'uses' => 'ConsumablesController@getDataView'
|
||||
]
|
||||
);
|
||||
|
||||
Route::post('{consumable}/checkout',
|
||||
[
|
||||
'as' => 'api.consumables.checkout',
|
||||
'uses' => 'ConsumablesController@checkout'
|
||||
]
|
||||
);
|
||||
});
|
||||
|
||||
/*--- Depreciations API ---*/
|
||||
|
||||
|
||||
+29
-2
@@ -74,7 +74,7 @@ class UserTest extends BaseTest
|
||||
public function testFirstInitialUnderscoreLastName()
|
||||
{
|
||||
$fullname = "Natalia Allanovna Romanova-O'Shostakova";
|
||||
$expected_username = 'natalia_allanovna-romanova-oshostakova';
|
||||
$expected_username = 'n_allanovna-romanova-oshostakova';
|
||||
$user = User::generateFormattedNameFromFullName('firstname_lastname', $fullname);
|
||||
$this->assertEquals($expected_username, $user['username']);
|
||||
}
|
||||
@@ -86,6 +86,33 @@ class UserTest extends BaseTest
|
||||
$user = User::generateFormattedNameFromFullName('firstname_lastname', $fullname);
|
||||
$this->assertEquals($expected_username, $user['username']);
|
||||
}
|
||||
|
||||
public function firstInitialDotLastname()
|
||||
{
|
||||
$fullname = "Natalia Allanovna Romanova-O'Shostakova";
|
||||
$expected_username = 'n.allanovnaromanovaoshostakova';
|
||||
$user = User::generateFormattedNameFromFullName('firstinitial.lastname', $fullname);
|
||||
$this->assertEquals($expected_username, $user['username']);
|
||||
}
|
||||
public function lastNameUnderscoreFirstInitial()
|
||||
{
|
||||
$fullname = "Natalia Allanovna Romanova-O'Shostakova";
|
||||
$expected_username = 'allanovnaromanovaoshostakova_n';
|
||||
$user = User::generateFormattedNameFromFullName('lastname_firstinitial', $fullname);
|
||||
$this->assertEquals($expected_username, $user['username']);
|
||||
}
|
||||
public function firstNameLastName()
|
||||
{
|
||||
$fullname = "Natalia Allanovna Romanova-O'Shostakova";
|
||||
$expected_username = 'nataliaallanovnaromanovaoshostakova';
|
||||
$user = User::generateFormattedNameFromFullName('firstnamelastname', $fullname);
|
||||
$this->assertEquals($expected_username, $user['username']);
|
||||
}
|
||||
public function firstNameLastInitial()
|
||||
{
|
||||
$fullname = "Natalia Allanovna Romanova-O'Shostakova";
|
||||
$expected_username = 'nataliaa';
|
||||
$user = User::generateFormattedNameFromFullName('firstnamelastinitial', $fullname);
|
||||
$this->assertEquals($expected_username, $user['username']);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user